metrale_model_layers/layers/ops/
ssm_gdn_wyn.rs1#![allow(unused_imports)]
12
13use anyhow::Result;
14use metrale_gpu_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
15use metrale_gpu_runtime::kernel_args::{KernelLaunch, div_ceil};
16
17use crate::layers::moe;
18use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
19
20use super::*;
21
22#[allow(clippy::too_many_arguments)]
26pub fn gdn_decode_wy4(
27 gpu: &dyn GpuBackend,
28 kernel: KernelHandle,
29 h_state: DevicePtr,
30 query: DevicePtr,
31 key: DevicePtr,
32 value: DevicePtr,
33 gate: DevicePtr,
34 beta: DevicePtr,
35 output: DevicePtr,
36 h_state_inter0: DevicePtr,
37 h_state_inter1: DevicePtr,
38 h_state_inter2: DevicePtr,
39 batch_size: u32,
40 num_k_heads: u32,
41 num_v_heads: u32,
42 k_dim: u32,
43 v_dim: u32,
44 qk_stride: u32,
45 v_stride: u32,
46 gb_stride: u32,
47 state_is_table: bool,
54 stream: u64,
55) -> Result<()> {
56 anyhow::ensure!(
59 state_is_table || batch_size == 1,
60 "gdn_decode_wy4: contiguous state addressing is only valid at \
61 batch_size==1 (got {batch_size}) — the intermediates' pool stride is \
62 num_intermediates x h_state's, so sequence 1's Hi0 would land on \
63 sequence 0's Hi1. Stage pointer tables and pass state_is_table=true."
64 );
65 KernelLaunch::new(gpu, kernel)
66 .grid([num_v_heads, batch_size, 1])
67 .block([128, 1, 1])
68 .arg_ptr(h_state)
69 .arg_ptr(query)
70 .arg_ptr(key)
71 .arg_ptr(value)
72 .arg_ptr(gate)
73 .arg_ptr(beta)
74 .arg_ptr(output)
75 .arg_ptr(h_state_inter0)
76 .arg_ptr(h_state_inter1)
77 .arg_ptr(h_state_inter2)
78 .arg_u32(batch_size)
79 .arg_u32(num_k_heads)
80 .arg_u32(num_v_heads)
81 .arg_u32(k_dim)
82 .arg_u32(v_dim)
83 .arg_u32(qk_stride)
84 .arg_u32(v_stride)
85 .arg_u32(gb_stride)
86 .arg_u32(u32::from(state_is_table))
87 .launch(stream)
88}
89
90#[allow(clippy::too_many_arguments)]
99pub fn gdn_decode_wyn(
100 gpu: &dyn GpuBackend,
101 kernel: KernelHandle,
102 h_state: DevicePtr,
103 query: DevicePtr,
104 key: DevicePtr,
105 value: DevicePtr,
106 gate: DevicePtr,
107 beta: DevicePtr,
108 output: DevicePtr,
109 h_state_inter_base: DevicePtr,
110 inter_stride_floats: u32,
111 batch_size: u32,
112 num_k_heads: u32,
113 num_v_heads: u32,
114 k_dim: u32,
115 v_dim: u32,
116 qk_stride: u32,
117 v_stride: u32,
118 gb_stride: u32,
119 stream: u64,
120) -> Result<()> {
121 anyhow::ensure!(
125 batch_size == 1,
126 "gdn_decode_wyn: contiguous state addressing is only valid at batch_size==1 \
127 (got {batch_size}); port the wy4 `state_is_table` pointer-table form first"
128 );
129 KernelLaunch::new(gpu, kernel)
130 .grid([num_v_heads, batch_size, 1])
131 .block([128, 1, 1])
132 .arg_ptr(h_state)
133 .arg_ptr(query)
134 .arg_ptr(key)
135 .arg_ptr(value)
136 .arg_ptr(gate)
137 .arg_ptr(beta)
138 .arg_ptr(output)
139 .arg_ptr(h_state_inter_base)
140 .arg_u32(inter_stride_floats)
141 .arg_u32(batch_size)
142 .arg_u32(num_k_heads)
143 .arg_u32(num_v_heads)
144 .arg_u32(k_dim)
145 .arg_u32(v_dim)
146 .arg_u32(qk_stride)
147 .arg_u32(v_stride)
148 .arg_u32(gb_stride)
149 .launch(stream)
150}
151
152#[allow(clippy::too_many_arguments)]
167#[allow(dead_code)]
168pub fn gdn_decode_wyn_table(
169 gpu: &dyn GpuBackend,
170 kernel: KernelHandle,
171 h_tables: DevicePtr,
172 query: DevicePtr,
173 key: DevicePtr,
174 value: DevicePtr,
175 gate: DevicePtr,
176 beta: DevicePtr,
177 output: DevicePtr,
178 hi_tables: DevicePtr,
179 slab_entry_stride: u32,
180 batch_size: u32,
181 num_k_heads: u32,
182 num_v_heads: u32,
183 k_dim: u32,
184 v_dim: u32,
185 qk_stride: u32,
186 v_stride: u32,
187 gb_stride: u32,
188 stream: u64,
189) -> Result<()> {
190 anyhow::ensure!(
191 !h_tables.is_null() && !hi_tables.is_null(),
192 "gdn_decode_wyn_table: staged pointer tables are required (NULL table \
193 means upload_verify_wy_tables declined — run the per-sequence loop)"
194 );
195 KernelLaunch::new(gpu, kernel)
196 .grid([num_v_heads, batch_size, 1])
197 .block([128, 1, 1])
198 .arg_ptr(h_tables)
199 .arg_ptr(query)
200 .arg_ptr(key)
201 .arg_ptr(value)
202 .arg_ptr(gate)
203 .arg_ptr(beta)
204 .arg_ptr(output)
205 .arg_ptr(hi_tables)
206 .arg_u32(slab_entry_stride)
207 .arg_u32(batch_size)
208 .arg_u32(num_k_heads)
209 .arg_u32(num_v_heads)
210 .arg_u32(k_dim)
211 .arg_u32(v_dim)
212 .arg_u32(qk_stride)
213 .arg_u32(v_stride)
214 .arg_u32(gb_stride)
215 .launch(stream)
216}
217
218#[allow(clippy::too_many_arguments)]
222pub fn conv1d_update_chunk2(
223 gpu: &dyn GpuBackend,
224 kernel: KernelHandle,
225 conv_state: DevicePtr,
226 input: DevicePtr,
227 weight: &DenseWeight,
228 output: DevicePtr,
229 conv_state_intermediate: DevicePtr,
230 d_inner: u32,
231 d_conv: u32,
232 batch_size: u32,
233 stream: u64,
234) -> Result<()> {
235 let bias_ptr = DevicePtr::NULL;
236 KernelLaunch::new(gpu, kernel)
237 .grid([div_ceil(d_inner, 256), batch_size, 1])
238 .block([256, 1, 1])
239 .arg_ptr(conv_state)
240 .arg_ptr(input)
241 .arg_ptr(weight.weight)
242 .arg_ptr(bias_ptr)
243 .arg_ptr(output)
244 .arg_ptr(conv_state_intermediate)
245 .arg_u32(batch_size)
246 .arg_u32(d_inner)
247 .arg_u32(d_conv)
248 .launch(stream)
249}