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 fill_slots_from_block_table(
21 gpu: &dyn GpuBackend,
22 kernel: KernelHandle,
23 slots: DevicePtr,
24 block_table: DevicePtr,
25 start_pos: u32,
26 count: u32,
27 block_size: u32,
28 stream: u64,
29) -> Result<()> {
30 if count == 0 {
31 return Ok(());
32 }
33 KernelLaunch::new(gpu, kernel)
34 .grid([div_ceil(count, 256), 1, 1])
35 .block([256, 1, 1])
36 .arg_ptr(slots)
37 .arg_ptr(block_table)
38 .arg_u32(start_pos)
39 .arg_u32(count)
40 .arg_u32(block_size)
41 .launch(stream)
42}
43
44#[allow(clippy::too_many_arguments)]
56pub fn reshape_and_cache(
57 gpu: &dyn GpuBackend,
58 kernel: KernelHandle,
59 key: DevicePtr,
60 value: DevicePtr,
61 k_cache: DevicePtr,
62 v_cache: DevicePtr,
63 slot_mapping: DevicePtr,
64 num_tokens: u32,
65 num_kv_heads: u32,
66 head_dim: u32,
67 block_size: u32,
68 key_stride: u32,
69 value_stride: u32,
70 _cache_stride: u64,
71 stream: u64,
72) -> Result<()> {
73 KernelLaunch::new(gpu, kernel)
74 .grid([num_tokens, 1, 1])
75 .block([256, 1, 1])
76 .arg_ptr(key)
77 .arg_ptr(value)
78 .arg_ptr(k_cache)
79 .arg_ptr(v_cache)
80 .arg_ptr(slot_mapping)
81 .arg_u32(num_kv_heads)
82 .arg_u32(head_dim)
83 .arg_u32(block_size)
84 .arg_u32(key_stride)
85 .arg_u32(value_stride)
86 .launch(stream)
87}
88
89#[allow(clippy::too_many_arguments)]
95pub fn reshape_and_cache_flash_v_only(
96 gpu: &dyn GpuBackend,
97 kernel: KernelHandle,
98 value: DevicePtr,
99 v_cache: DevicePtr,
100 slot_mapping: DevicePtr,
101 num_tokens: u32,
102 num_kv_heads: u32,
103 head_dim: u32,
104 block_size: u32,
105 value_stride: u32,
106 stream: u64,
107) -> Result<()> {
108 KernelLaunch::new(gpu, kernel)
109 .grid([num_tokens, 1, 1])
110 .block([256, 1, 1])
111 .arg_ptr(value)
112 .arg_ptr(v_cache)
113 .arg_ptr(slot_mapping)
114 .arg_u32(num_kv_heads)
115 .arg_u32(head_dim)
116 .arg_u32(block_size)
117 .arg_u32(value_stride)
118 .launch(stream)
119}
120
121#[allow(clippy::too_many_arguments)]
130pub fn fused_k_norm_rope_cache_write_bf16(
131 gpu: &dyn GpuBackend,
132 kernel: KernelHandle,
133 k_in: DevicePtr,
134 k_norm_weight: DevicePtr,
135 positions: DevicePtr,
136 k_cache: DevicePtr,
137 slot_mapping: DevicePtr,
138 num_tokens: u32,
139 num_kv_heads: u32,
140 head_dim: u32,
141 rotary_dim: u32,
142 block_size: u32,
143 rms_eps: f32,
144 theta: f32,
145 stream: u64,
146) -> Result<()> {
147 KernelLaunch::new(gpu, kernel)
148 .grid([num_tokens, num_kv_heads, 1])
149 .block([head_dim, 1, 1])
150 .arg_ptr(k_in)
151 .arg_ptr(k_norm_weight)
152 .arg_ptr(positions)
153 .arg_ptr(k_cache)
154 .arg_ptr(slot_mapping)
155 .arg_u32(num_kv_heads)
156 .arg_u32(head_dim)
157 .arg_u32(rotary_dim)
158 .arg_u32(block_size)
159 .arg_f32(rms_eps)
160 .arg_f32(theta)
161 .launch(stream)
162}
163
164#[allow(clippy::too_many_arguments)]
168pub fn fused_k_norm_rope_cache_write_bf16_mrope(
169 gpu: &dyn GpuBackend,
170 kernel: KernelHandle,
171 k_in: DevicePtr,
172 k_norm_weight: DevicePtr,
173 pos_t: DevicePtr,
174 pos_h: DevicePtr,
175 pos_w: DevicePtr,
176 k_cache: DevicePtr,
177 slot_mapping: DevicePtr,
178 num_tokens: u32,
179 num_kv_heads: u32,
180 head_dim: u32,
181 rotary_dim: u32,
182 block_size: u32,
183 rms_eps: f32,
184 theta: f32,
185 stream: u64,
186) -> Result<()> {
187 KernelLaunch::new(gpu, kernel)
188 .grid([num_tokens, num_kv_heads, 1])
189 .block([head_dim, 1, 1])
190 .arg_ptr(k_in)
191 .arg_ptr(k_norm_weight)
192 .arg_ptr(pos_t)
193 .arg_ptr(pos_h)
194 .arg_ptr(pos_w)
195 .arg_ptr(k_cache)
196 .arg_ptr(slot_mapping)
197 .arg_u32(num_kv_heads)
198 .arg_u32(head_dim)
199 .arg_u32(rotary_dim)
200 .arg_u32(block_size)
201 .arg_f32(rms_eps)
202 .arg_f32(theta)
203 .launch(stream)
204}
205
206#[allow(clippy::too_many_arguments)]
209pub fn fused_k_norm_rope_cache_write_fp8(
210 gpu: &dyn GpuBackend,
211 kernel: KernelHandle,
212 k_in: DevicePtr,
213 k_norm_weight: DevicePtr,
214 positions: DevicePtr,
215 k_cache_fp8: DevicePtr,
216 slot_mapping: DevicePtr,
217 num_tokens: u32,
218 num_kv_heads: u32,
219 head_dim: u32,
220 rotary_dim: u32,
221 block_size: u32,
222 rms_eps: f32,
223 theta: f32,
224 inv_scale: f32,
225 stream: u64,
226) -> Result<()> {
227 KernelLaunch::new(gpu, kernel)
228 .grid([num_tokens, num_kv_heads, 1])
229 .block([head_dim, 1, 1])
230 .arg_ptr(k_in)
231 .arg_ptr(k_norm_weight)
232 .arg_ptr(positions)
233 .arg_ptr(k_cache_fp8)
234 .arg_ptr(slot_mapping)
235 .arg_u32(num_kv_heads)
236 .arg_u32(head_dim)
237 .arg_u32(rotary_dim)
238 .arg_u32(block_size)
239 .arg_f32(rms_eps)
240 .arg_f32(theta)
241 .arg_f32(inv_scale)
242 .launch(stream)
243}
244
245#[allow(clippy::too_many_arguments)]
257pub fn reshape_and_cache_bf16k_turbo3v(
258 gpu: &dyn GpuBackend,
259 kernel: KernelHandle,
260 key: DevicePtr,
261 value: DevicePtr,
262 k_cache: DevicePtr,
263 v_cache: DevicePtr,
264 slot_mapping: DevicePtr,
265 num_tokens: u32,
266 num_kv_heads: u32,
267 head_dim: u32,
268 block_size: u32,
269 key_stride: u32,
270 value_stride: u32,
271 k_block_stride_bytes: u64,
272 v_block_stride_bytes: u64,
273 v_data_section_bytes: u64,
274 stream: u64,
275) -> Result<()> {
276 KernelLaunch::new(gpu, kernel)
277 .grid([num_tokens, 1, 1])
278 .block([256, 1, 1])
279 .arg_ptr(key)
280 .arg_ptr(value)
281 .arg_ptr(k_cache)
282 .arg_ptr(v_cache)
283 .arg_ptr(slot_mapping)
284 .arg_u32(num_kv_heads)
285 .arg_u32(head_dim)
286 .arg_u32(block_size)
287 .arg_u32(key_stride)
288 .arg_u32(value_stride)
289 .arg_u64(k_block_stride_bytes)
290 .arg_u64(v_block_stride_bytes)
291 .arg_u64(v_data_section_bytes)
292 .launch(stream)
293}
294
295#[allow(clippy::too_many_arguments)]
306pub fn paged_decode_attn_bf16k_turbo3v(
307 gpu: &dyn GpuBackend,
308 kernel: KernelHandle,
309 q: DevicePtr,
310 k_cache: DevicePtr,
311 v_cache: DevicePtr,
312 output: DevicePtr,
313 block_tables: DevicePtr,
314 seq_lens: DevicePtr,
315 max_blocks_per_seq: u32,
316 num_seqs: u32,
317 num_q_heads: u32,
318 num_kv_heads: u32,
319 head_dim: u32,
320 block_size: u32,
321 inv_sqrt_d: f32,
322 q_stride: u32,
323 v_block_stride_bytes: u64,
324 v_data_section_bytes: u64,
325 sliding_window: u32,
326 stream: u64,
327) -> Result<()> {
328 KernelLaunch::new(gpu, kernel)
329 .grid([num_q_heads, num_seqs, 1])
330 .block([256, 1, 1])
331 .arg_ptr(q)
332 .arg_ptr(k_cache)
333 .arg_ptr(v_cache)
334 .arg_ptr(output)
335 .arg_ptr(block_tables)
336 .arg_ptr(seq_lens)
337 .arg_u32(max_blocks_per_seq)
338 .arg_u32(num_q_heads)
339 .arg_u32(num_kv_heads)
340 .arg_u32(head_dim)
341 .arg_u32(block_size)
342 .arg_f32(inv_sqrt_d)
343 .arg_u32(q_stride)
344 .arg_u64(v_block_stride_bytes)
345 .arg_u64(v_data_section_bytes)
346 .arg_u32(sliding_window)
347 .launch(stream)
348}
349
350#[allow(clippy::too_many_arguments)]
355pub fn reshape_and_cache_bf16k_turbo4v(
356 gpu: &dyn GpuBackend,
357 kernel: KernelHandle,
358 key: DevicePtr,
359 value: DevicePtr,
360 k_cache: DevicePtr,
361 v_cache: DevicePtr,
362 slot_mapping: DevicePtr,
363 num_tokens: u32,
364 num_kv_heads: u32,
365 head_dim: u32,
366 block_size: u32,
367 key_stride: u32,
368 value_stride: u32,
369 k_block_stride_bytes: u64,
370 v_block_stride_bytes: u64,
371 v_data_section_bytes: u64,
372 stream: u64,
373) -> Result<()> {
374 KernelLaunch::new(gpu, kernel)
375 .grid([num_tokens, 1, 1])
376 .block([256, 1, 1])
377 .arg_ptr(key)
378 .arg_ptr(value)
379 .arg_ptr(k_cache)
380 .arg_ptr(v_cache)
381 .arg_ptr(slot_mapping)
382 .arg_u32(num_kv_heads)
383 .arg_u32(head_dim)
384 .arg_u32(block_size)
385 .arg_u32(key_stride)
386 .arg_u32(value_stride)
387 .arg_u64(k_block_stride_bytes)
388 .arg_u64(v_block_stride_bytes)
389 .arg_u64(v_data_section_bytes)
390 .launch(stream)
391}
392
393#[allow(clippy::too_many_arguments)]
395pub fn reshape_and_cache_bf16k_turbo2v(
396 gpu: &dyn GpuBackend,
397 kernel: KernelHandle,
398 key: DevicePtr,
399 value: DevicePtr,
400 k_cache: DevicePtr,
401 v_cache: DevicePtr,
402 slot_mapping: DevicePtr,
403 num_tokens: u32,
404 num_kv_heads: u32,
405 head_dim: u32,
406 block_size: u32,
407 key_stride: u32,
408 value_stride: u32,
409 k_block_stride_bytes: u64,
410 v_block_stride_bytes: u64,
411 v_data_section_bytes: u64,
412 stream: u64,
413) -> Result<()> {
414 KernelLaunch::new(gpu, kernel)
415 .grid([num_tokens, 1, 1])
416 .block([256, 1, 1])
417 .arg_ptr(key)
418 .arg_ptr(value)
419 .arg_ptr(k_cache)
420 .arg_ptr(v_cache)
421 .arg_ptr(slot_mapping)
422 .arg_u32(num_kv_heads)
423 .arg_u32(head_dim)
424 .arg_u32(block_size)
425 .arg_u32(key_stride)
426 .arg_u32(value_stride)
427 .arg_u64(k_block_stride_bytes)
428 .arg_u64(v_block_stride_bytes)
429 .arg_u64(v_data_section_bytes)
430 .launch(stream)
431}
432
433#[allow(clippy::too_many_arguments)]
438pub fn paged_decode_attn_bf16k_turbo4v(
439 gpu: &dyn GpuBackend,
440 kernel: KernelHandle,
441 q: DevicePtr,
442 k_cache: DevicePtr,
443 v_cache: DevicePtr,
444 output: DevicePtr,
445 block_tables: DevicePtr,
446 seq_lens: DevicePtr,
447 max_blocks_per_seq: u32,
448 num_seqs: u32,
449 num_q_heads: u32,
450 num_kv_heads: u32,
451 head_dim: u32,
452 block_size: u32,
453 inv_sqrt_d: f32,
454 q_stride: u32,
455 v_block_stride_bytes: u64,
456 v_data_section_bytes: u64,
457 sliding_window: u32,
458 stream: u64,
459) -> Result<()> {
460 KernelLaunch::new(gpu, kernel)
461 .grid([num_q_heads, num_seqs, 1])
462 .block([256, 1, 1])
463 .arg_ptr(q)
464 .arg_ptr(k_cache)
465 .arg_ptr(v_cache)
466 .arg_ptr(output)
467 .arg_ptr(block_tables)
468 .arg_ptr(seq_lens)
469 .arg_u32(max_blocks_per_seq)
470 .arg_u32(num_q_heads)
471 .arg_u32(num_kv_heads)
472 .arg_u32(head_dim)
473 .arg_u32(block_size)
474 .arg_f32(inv_sqrt_d)
475 .arg_u32(q_stride)
476 .arg_u64(v_block_stride_bytes)
477 .arg_u64(v_data_section_bytes)
478 .arg_u32(sliding_window)
479 .launch(stream)
480}
481
482#[allow(clippy::too_many_arguments)]
484pub fn paged_decode_attn_bf16k_turbo2v(
485 gpu: &dyn GpuBackend,
486 kernel: KernelHandle,
487 q: DevicePtr,
488 k_cache: DevicePtr,
489 v_cache: DevicePtr,
490 output: DevicePtr,
491 block_tables: DevicePtr,
492 seq_lens: DevicePtr,
493 max_blocks_per_seq: u32,
494 num_seqs: u32,
495 num_q_heads: u32,
496 num_kv_heads: u32,
497 head_dim: u32,
498 block_size: u32,
499 inv_sqrt_d: f32,
500 q_stride: u32,
501 v_block_stride_bytes: u64,
502 v_data_section_bytes: u64,
503 sliding_window: u32,
504 stream: u64,
505) -> Result<()> {
506 KernelLaunch::new(gpu, kernel)
507 .grid([num_q_heads, num_seqs, 1])
508 .block([256, 1, 1])
509 .arg_ptr(q)
510 .arg_ptr(k_cache)
511 .arg_ptr(v_cache)
512 .arg_ptr(output)
513 .arg_ptr(block_tables)
514 .arg_ptr(seq_lens)
515 .arg_u32(max_blocks_per_seq)
516 .arg_u32(num_q_heads)
517 .arg_u32(num_kv_heads)
518 .arg_u32(head_dim)
519 .arg_u32(block_size)
520 .arg_f32(inv_sqrt_d)
521 .arg_u32(q_stride)
522 .arg_u64(v_block_stride_bytes)
523 .arg_u64(v_data_section_bytes)
524 .arg_u32(sliding_window)
525 .launch(stream)
526}
527
528pub fn reshape_and_cache_fp8(
531 gpu: &dyn GpuBackend,
532 kernel: KernelHandle,
533 key: DevicePtr,
534 value: DevicePtr,
535 k_cache: DevicePtr,
536 v_cache: DevicePtr,
537 slot_mapping: DevicePtr,
538 num_tokens: u32,
539 num_kv_heads: u32,
540 head_dim: u32,
541 block_size: u32,
542 k_scale: f32,
543 v_scale: f32,
544 key_stride: u32,
545 value_stride: u32,
546 cache_stride: u64,
547 stream: u64,
548) -> Result<()> {
549 KernelLaunch::new(gpu, kernel)
550 .grid([num_tokens, 1, 1])
551 .block([256, 1, 1])
552 .arg_ptr(key)
553 .arg_ptr(value)
554 .arg_ptr(k_cache)
555 .arg_ptr(v_cache)
556 .arg_ptr(slot_mapping)
557 .arg_u32(num_kv_heads)
558 .arg_u32(head_dim)
559 .arg_u32(block_size)
560 .arg_f32(k_scale)
561 .arg_f32(v_scale)
562 .arg_u32(key_stride)
563 .arg_u32(value_stride)
564 .arg_u64(cache_stride)
565 .launch(stream)
566}
567
568pub fn mla_batched_gemv(
583 gpu: &dyn GpuBackend,
584 kernel: KernelHandle,
585 input: DevicePtr,
586 weight: DevicePtr,
587 output: DevicePtr,
588 n_out: u32,
589 k: u32,
590 num_heads: u32,
591 input_stride: u32,
592 output_stride: u32,
593 stream: u64,
594) -> Result<()> {
595 KernelLaunch::new(gpu, kernel)
596 .grid([div_ceil(n_out, 8), num_heads, 1]) .block([256, 1, 1])
598 .arg_ptr(input)
599 .arg_ptr(weight)
600 .arg_ptr(output)
601 .arg_u32(n_out)
602 .arg_u32(k)
603 .arg_u32(input_stride)
604 .arg_u32(output_stride)
605 .launch(stream)
606}
607
608#[allow(clippy::too_many_arguments)]
610pub fn mla_q_rope_scatter(
611 gpu: &dyn GpuBackend,
612 kernel: KernelHandle,
613 q_full: DevicePtr,
614 q_absorbed_buf: DevicePtr,
615 q_rope_contiguous: DevicePtr,
616 nq: u32,
617 hd: u32,
618 nope: u32,
619 rope: u32,
620 kv_lora: u32,
621 mla_cache_dim: u32,
622 stream: u64,
623) -> Result<()> {
624 KernelLaunch::new(gpu, kernel)
625 .grid([1, 1, 1])
626 .block([256, 1, 1])
627 .arg_ptr(q_full)
628 .arg_ptr(q_absorbed_buf)
629 .arg_ptr(q_rope_contiguous)
630 .arg_u32(nq)
631 .arg_u32(hd)
632 .arg_u32(nope)
633 .arg_u32(rope)
634 .arg_u32(kv_lora)
635 .arg_u32(mla_cache_dim)
636 .launch(stream)
637}
638
639pub fn mla_q_rope_writeback(
641 gpu: &dyn GpuBackend,
642 kernel: KernelHandle,
643 q_rope_direct: DevicePtr,
644 q_absorbed_buf: DevicePtr,
645 nq: u32,
646 rope: u32,
647 kv_lora: u32,
648 mla_cache_dim: u32,
649 stream: u64,
650) -> Result<()> {
651 KernelLaunch::new(gpu, kernel)
652 .grid([1, 1, 1])
653 .block([256, 1, 1])
654 .arg_ptr(q_rope_direct)
655 .arg_ptr(q_absorbed_buf)
656 .arg_u32(nq)
657 .arg_u32(rope)
658 .arg_u32(kv_lora)
659 .arg_u32(mla_cache_dim)
660 .launch(stream)
661}
662
663pub fn mla_cache_assemble(
665 gpu: &dyn GpuBackend,
666 kernel: KernelHandle,
667 kv_latent: DevicePtr,
668 k_rope: DevicePtr,
669 k_cache: DevicePtr,
670 v_cache: DevicePtr,
671 kv_lora: u32,
672 rope: u32,
673 mla_cache_dim: u32,
674 stream: u64,
675) -> Result<()> {
676 KernelLaunch::new(gpu, kernel)
677 .grid([1, 1, 1])
678 .block([mla_cache_dim.max(256), 1, 1])
679 .arg_ptr(kv_latent)
680 .arg_ptr(k_rope)
681 .arg_ptr(k_cache)
682 .arg_ptr(v_cache)
683 .arg_u32(kv_lora)
684 .arg_u32(rope)
685 .arg_u32(mla_cache_dim)
686 .launch(stream)
687}
688
689#[allow(clippy::too_many_arguments)]
700pub fn mla_paged_decode_nvfp4(
701 gpu: &dyn GpuBackend,
702 kernel: KernelHandle,
703 q: DevicePtr,
704 k_cache: DevicePtr,
705 v_cache: DevicePtr,
706 o: DevicePtr,
707 block_tables: DevicePtr,
708 seq_lens: DevicePtr,
709 max_blocks_per_seq: u32,
710 num_q_heads: u32,
711 num_kv_heads: u32,
712 q_head_dim: u32,
713 kv_cache_dim: u32,
714 block_size: u32,
715 inv_sqrt_d: f32,
716 block_stride_bytes: u64,
717 data_section_bytes: u64,
718 num_seqs: u32,
719 stream: u64,
720) -> Result<()> {
721 KernelLaunch::new(gpu, kernel)
722 .grid([num_q_heads, num_seqs, 1])
723 .block([256, 1, 1])
724 .arg_ptr(q)
725 .arg_ptr(k_cache)
726 .arg_ptr(v_cache)
727 .arg_ptr(o)
728 .arg_ptr(block_tables)
729 .arg_ptr(seq_lens)
730 .arg_u32(max_blocks_per_seq)
731 .arg_u32(num_q_heads)
732 .arg_u32(num_kv_heads)
733 .arg_u32(q_head_dim)
734 .arg_u32(kv_cache_dim)
735 .arg_u32(block_size)
736 .arg_f32(inv_sqrt_d)
737 .arg_u64(block_stride_bytes)
738 .arg_u64(data_section_bytes)
739 .launch(stream)
740}
741
742#[allow(clippy::too_many_arguments)]
753pub fn mla_paged_decode_fp8(
754 gpu: &dyn GpuBackend,
755 kernel: KernelHandle,
756 q: DevicePtr,
757 k_cache: DevicePtr,
758 v_cache: DevicePtr,
759 o: DevicePtr,
760 block_tables: DevicePtr,
761 seq_lens: DevicePtr,
762 max_blocks_per_seq: u32,
763 num_q_heads: u32,
764 num_kv_heads: u32,
765 q_head_dim: u32,
766 kv_cache_dim: u32,
767 block_size: u32,
768 inv_sqrt_d: f32,
769 k_scale: f32,
770 v_scale: f32,
771 cache_stride: u64,
772 num_seqs: u32,
773 sliding_window: u32,
774 sinks: DevicePtr,
775 comp_pool: DevicePtr, comp_block_count: u32, stream: u64,
778) -> Result<()> {
779 KernelLaunch::new(gpu, kernel)
780 .grid([num_q_heads, num_seqs, 1])
781 .block([256, 1, 1])
782 .arg_ptr(q)
783 .arg_ptr(k_cache)
784 .arg_ptr(v_cache)
785 .arg_ptr(o)
786 .arg_ptr(block_tables)
787 .arg_ptr(seq_lens)
788 .arg_u32(max_blocks_per_seq)
789 .arg_u32(num_q_heads)
790 .arg_u32(num_kv_heads)
791 .arg_u32(q_head_dim)
792 .arg_u32(kv_cache_dim)
793 .arg_u32(block_size)
794 .arg_f32(inv_sqrt_d)
795 .arg_f32(k_scale)
796 .arg_f32(v_scale)
797 .arg_u64(cache_stride)
798 .arg_u32(sliding_window)
799 .arg_ptr(sinks)
800 .arg_ptr(comp_pool)
801 .arg_u32(comp_block_count)
802 .launch(stream)
803}
804
805