1#![allow(unused_imports)]
6
7use anyhow::Result;
8use spark_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
9use spark_runtime::kernel_args::{KernelLaunch, div_ceil};
10
11use crate::layers::moe;
12use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
13
14use super::*;
15
16pub fn conv1d_update(
24 gpu: &dyn GpuBackend,
25 kernel: KernelHandle,
26 conv_state: DevicePtr,
27 input: DevicePtr,
28 weight: &DenseWeight,
29 output: DevicePtr,
30 d_inner: u32,
31 d_conv: u32,
32 batch_size: u32,
33 stream: u64,
34) -> Result<()> {
35 let bias_ptr = DevicePtr::NULL;
36 KernelLaunch::new(gpu, kernel)
37 .grid([div_ceil(d_inner, 256), batch_size, 1])
38 .block([256, 1, 1])
39 .arg_ptr(conv_state)
40 .arg_ptr(input)
41 .arg_ptr(weight.weight)
42 .arg_ptr(bias_ptr)
43 .arg_ptr(output)
44 .arg_u32(batch_size)
45 .arg_u32(d_inner)
46 .arg_u32(d_conv)
47 .launch(stream)
48}
49
50#[allow(clippy::too_many_arguments)]
58pub fn conv1d_update_l2norm(
59 gpu: &dyn GpuBackend,
60 kernel: KernelHandle,
61 conv_state: DevicePtr,
62 input: DevicePtr,
63 weight: &DenseWeight,
64 output: DevicePtr,
65 d_inner: u32,
66 d_conv: u32,
67 batch_size: u32,
68 qk_channels: u32,
69 head_dim: u32,
70 l2_eps: f32,
71 stream: u64,
72) -> Result<()> {
73 let bias_ptr = DevicePtr::NULL;
74 KernelLaunch::new(gpu, kernel)
75 .grid([div_ceil(d_inner, 256), batch_size, 1])
76 .block([256, 1, 1])
77 .arg_ptr(conv_state)
78 .arg_ptr(input)
79 .arg_ptr(weight.weight)
80 .arg_ptr(bias_ptr)
81 .arg_ptr(output)
82 .arg_u32(batch_size)
83 .arg_u32(d_inner)
84 .arg_u32(d_conv)
85 .arg_u32(qk_channels)
86 .arg_u32(head_dim)
87 .arg_f32(l2_eps)
88 .launch(stream)
89}
90
91#[allow(clippy::too_many_arguments)]
105pub fn conv1d_update_l2norm_strided(
106 gpu: &dyn GpuBackend,
107 kernel: KernelHandle,
108 conv_state: DevicePtr,
109 input: DevicePtr,
110 weight: &DenseWeight,
111 output: DevicePtr,
112 d_inner: u32,
113 d_conv: u32,
114 batch_size: u32,
115 qk_channels: u32,
116 head_dim: u32,
117 l2_eps: f32,
118 input_stride: u32,
119 output_stride: u32,
120 stream: u64,
121) -> Result<()> {
122 let bias_ptr = DevicePtr::NULL;
123 KernelLaunch::new(gpu, kernel)
124 .grid([div_ceil(d_inner, 256), batch_size, 1])
125 .block([256, 1, 1])
126 .arg_ptr(conv_state)
127 .arg_ptr(input)
128 .arg_ptr(weight.weight)
129 .arg_ptr(bias_ptr)
130 .arg_ptr(output)
131 .arg_u32(batch_size)
132 .arg_u32(d_inner)
133 .arg_u32(d_conv)
134 .arg_u32(qk_channels)
135 .arg_u32(head_dim)
136 .arg_f32(l2_eps)
137 .arg_u32(input_stride)
138 .arg_u32(output_stride)
139 .launch(stream)
140}
141
142#[allow(clippy::too_many_arguments)]
155pub fn gdn_verify_fused_conv_k2(
156 gpu: &dyn GpuBackend,
157 kernel: KernelHandle,
158 conv_state: DevicePtr,
159 new_input: DevicePtr,
160 weight: &DenseWeight,
161 output: DevicePtr,
162 conv_state_inter: DevicePtr,
163 d_inner: u32,
164 d_conv: u32,
165 qk_channels: u32,
166 head_dim: u32,
167 input_stride: u32,
168 output_stride: u32,
169 l2_eps: f32,
170 stream: u64,
171) -> Result<()> {
172 KernelLaunch::new(gpu, kernel)
173 .grid([div_ceil(d_inner, 256), 1, 1])
174 .block([256, 1, 1])
175 .arg_ptr(conv_state)
176 .arg_ptr(new_input)
177 .arg_ptr(weight.weight)
178 .arg_ptr(output)
179 .arg_ptr(conv_state_inter)
180 .arg_u32(d_inner)
181 .arg_u32(d_conv)
182 .arg_u32(qk_channels)
183 .arg_u32(head_dim)
184 .arg_u32(input_stride)
185 .arg_u32(output_stride)
186 .arg_f32(l2_eps)
187 .launch(stream)
188}
189
190#[allow(clippy::too_many_arguments)]
219pub fn gdn_verify_fused_conv_kn_batched(
220 gpu: &dyn GpuBackend,
221 kernel: KernelHandle,
222 conv_state: DevicePtr,
223 new_input: DevicePtr,
224 weight: &DenseWeight,
225 output: DevicePtr,
226 conv_state_inter: DevicePtr,
227 num_tokens: u32,
228 d_inner: u32,
229 d_conv: u32,
230 qk_channels: u32,
231 head_dim: u32,
232 input_stride: u32,
233 output_stride: u32,
234 inter_stride: u32,
235 l2_eps: f32,
236 n_seq: u32,
237 conv_state_seq_stride: u32,
238 input_seq_stride: u32,
239 output_seq_stride: u32,
240 inter_seq_stride: u32,
241 stream: u64,
242) -> Result<()> {
243 KernelLaunch::new(gpu, kernel)
244 .grid([div_ceil(d_inner, 256), n_seq, 1])
245 .block([256, 1, 1])
246 .arg_ptr(conv_state)
247 .arg_ptr(new_input)
248 .arg_ptr(weight.weight)
249 .arg_ptr(output)
250 .arg_ptr(conv_state_inter)
251 .arg_u32(num_tokens)
252 .arg_u32(d_inner)
253 .arg_u32(d_conv)
254 .arg_u32(qk_channels)
255 .arg_u32(head_dim)
256 .arg_u32(input_stride)
257 .arg_u32(output_stride)
258 .arg_u32(inter_stride)
259 .arg_f32(l2_eps)
260 .arg_u32(conv_state_seq_stride)
261 .arg_u32(input_seq_stride)
262 .arg_u32(output_seq_stride)
263 .arg_u32(inter_seq_stride)
264 .launch(stream)
265}
266
267#[allow(clippy::too_many_arguments)]
268pub fn gdn_verify_fused_conv_kn(
269 gpu: &dyn GpuBackend,
270 kernel: KernelHandle,
271 conv_state: DevicePtr,
272 new_input: DevicePtr,
273 weight: &DenseWeight,
274 output: DevicePtr,
275 conv_state_inter: DevicePtr,
276 num_tokens: u32,
277 d_inner: u32,
278 d_conv: u32,
279 qk_channels: u32,
280 head_dim: u32,
281 input_stride: u32,
282 output_stride: u32,
283 inter_stride: u32,
284 l2_eps: f32,
285 stream: u64,
286) -> Result<()> {
287 KernelLaunch::new(gpu, kernel)
288 .grid([div_ceil(d_inner, 256), 1, 1])
289 .block([256, 1, 1])
290 .arg_ptr(conv_state)
291 .arg_ptr(new_input)
292 .arg_ptr(weight.weight)
293 .arg_ptr(output)
294 .arg_ptr(conv_state_inter)
295 .arg_u32(num_tokens)
296 .arg_u32(d_inner)
297 .arg_u32(d_conv)
298 .arg_u32(qk_channels)
299 .arg_u32(head_dim)
300 .arg_u32(input_stride)
301 .arg_u32(output_stride)
302 .arg_u32(inter_stride)
303 .arg_f32(l2_eps)
304 .launch(stream)
305}
306
307#[allow(clippy::too_many_arguments)]
318pub fn gdn_verify_fused_norm_k2(
319 gpu: &dyn GpuBackend,
320 kernel: KernelHandle,
321 gdn_out: DevicePtr,
322 deint: DevicePtr,
323 weight: &DenseWeight,
324 output: DevicePtr,
325 num_v_heads: u32,
326 hidden_size: u32,
327 eps: f32,
328 deint_stride: u32,
329 z_offset: u32,
330 out_stride: u32,
331 stream: u64,
332) -> Result<()> {
333 KernelLaunch::new(gpu, kernel)
334 .grid([num_v_heads, 2, 1])
335 .block([hidden_size, 1, 1])
336 .arg_ptr(gdn_out)
337 .arg_ptr(deint)
338 .arg_ptr(weight.weight)
339 .arg_ptr(output)
340 .arg_u32(hidden_size)
341 .arg_f32(eps)
342 .arg_u32(deint_stride)
343 .arg_u32(z_offset)
344 .arg_u32(out_stride)
345 .launch(stream)
346}
347
348#[allow(clippy::too_many_arguments)]
357pub fn conv1d_update_prefill(
358 gpu: &dyn GpuBackend,
359 kernel: KernelHandle,
360 conv1d_prefill_tp_k: KernelHandle,
361 conv_state: DevicePtr,
362 input: DevicePtr,
363 weight: &DenseWeight,
364 bias: DevicePtr,
365 output: DevicePtr,
366 d_inner: u32,
367 d_conv: u32,
368 seq_len: u32,
369 input_stride: u32,
370 output_stride: u32,
371 stream: u64,
372) -> Result<()> {
373 let tp =
388 std::env::var("ATLAS_CONV1D_TP").ok().as_deref() != Some("0") && conv1d_prefill_tp_k.0 != 0;
389 let (k, grid, block) = if tp {
390 (
391 conv1d_prefill_tp_k,
392 [div_ceil(d_inner, 32), div_ceil(seq_len, 64), 1],
393 [32u32, 8u32, 1u32],
394 )
395 } else {
396 (kernel, [div_ceil(d_inner, 256), 1, 1], [256u32, 1u32, 1u32])
397 };
398 KernelLaunch::new(gpu, k)
399 .grid(grid)
400 .block(block)
401 .arg_ptr(conv_state)
402 .arg_ptr(input)
403 .arg_ptr(weight.weight)
404 .arg_ptr(bias)
405 .arg_ptr(output)
406 .arg_u32(d_inner)
407 .arg_u32(d_conv)
408 .arg_u32(seq_len)
409 .arg_u32(input_stride)
410 .arg_u32(output_stride)
411 .launch(stream)
412}
413
414#[allow(clippy::too_many_arguments)]
421pub fn mamba2_ssm_prefill(
422 gpu: &dyn GpuBackend,
423 kernel: KernelHandle,
424 h_state: DevicePtr,
425 x: DevicePtr,
426 b_proj: DevicePtr,
427 c_proj: DevicePtr,
428 dt_raw: DevicePtr,
429 a_log: DevicePtr,
430 d_param: DevicePtr,
431 dt_bias: DevicePtr,
432 output: DevicePtr,
433 batch_size: u32,
434 seq_len: u32,
435 num_heads: u32,
436 head_dim: u32,
437 state_size: u32,
438 n_groups: u32,
439 dt_min: f32,
440 dt_max: f32,
441 x_stride: u32,
442 bc_stride: u32,
443 dt_stride: u32,
444 y_stride: u32,
445 stream: u64,
446) -> Result<()> {
447 KernelLaunch::new(gpu, kernel)
448 .grid([num_heads, batch_size, 1])
449 .block([state_size, 1, 1])
450 .arg_ptr(h_state)
451 .arg_ptr(x)
452 .arg_ptr(b_proj)
453 .arg_ptr(c_proj)
454 .arg_ptr(dt_raw)
455 .arg_ptr(a_log)
456 .arg_ptr(d_param)
457 .arg_ptr(dt_bias)
458 .arg_ptr(output)
459 .arg_u32(batch_size)
460 .arg_u32(seq_len)
461 .arg_u32(num_heads)
462 .arg_u32(head_dim)
463 .arg_u32(state_size)
464 .arg_u32(n_groups)
465 .arg_f32(dt_min)
466 .arg_f32(dt_max)
467 .arg_u32(x_stride)
468 .arg_u32(bc_stride)
469 .arg_u32(dt_stride)
470 .arg_u32(y_stride)
471 .launch(stream)
472}
473
474#[allow(clippy::too_many_arguments)]
477pub fn mamba2_ssm_prefill_persistent(
478 gpu: &dyn GpuBackend,
479 kernel: KernelHandle,
480 h_state: DevicePtr,
481 x: DevicePtr,
482 b_proj: DevicePtr,
483 c_proj: DevicePtr,
484 dt_raw: DevicePtr,
485 a_log: DevicePtr,
486 d_param: DevicePtr,
487 dt_bias: DevicePtr,
488 output: DevicePtr,
489 batch_size: u32,
490 seq_len: u32,
491 num_heads: u32,
492 head_dim: u32,
493 state_size: u32,
494 n_groups: u32,
495 dt_min: f32,
496 dt_max: f32,
497 x_stride: u32,
498 bc_stride: u32,
499 dt_stride: u32,
500 y_stride: u32,
501 stream: u64,
502) -> Result<()> {
503 let smem = head_dim * (state_size + 1) * 4 + head_dim * 4 + state_size * 4 + state_size * 4;
510 const SUB: u32 = 4;
512 KernelLaunch::new(gpu, kernel)
513 .grid([num_heads, batch_size, 1])
514 .block([head_dim * SUB, 1, 1])
515 .shared_mem(smem)
516 .arg_ptr(h_state)
517 .arg_ptr(x)
518 .arg_ptr(b_proj)
519 .arg_ptr(c_proj)
520 .arg_ptr(dt_raw)
521 .arg_ptr(a_log)
522 .arg_ptr(d_param)
523 .arg_ptr(dt_bias)
524 .arg_ptr(output)
525 .arg_u32(batch_size)
526 .arg_u32(seq_len)
527 .arg_u32(num_heads)
528 .arg_u32(head_dim)
529 .arg_u32(state_size)
530 .arg_u32(n_groups)
531 .arg_f32(dt_min)
532 .arg_f32(dt_max)
533 .arg_u32(x_stride)
534 .arg_u32(bc_stride)
535 .arg_u32(dt_stride)
536 .arg_u32(y_stride)
537 .launch(stream)
538}
539
540