1use anyhow::Result;
7use spark_runtime::gpu::{GpuBackend, KernelHandle};
8use spark_runtime::kv_cache::KvCacheDtype;
9
10use super::init_arch_gates::{ArchProbes, gated as gate, present};
14use super::types::{HeadGateActivation, Qwen3AttentionLayer};
15use crate::layers::FfnComponent;
16use crate::layers::fp8_calibration::Fp8KvCalibration;
17use crate::weight_map::{AttentionWeights, DenseWeight, QuantWeight, QuantizedWeight};
18
19impl Qwen3AttentionLayer {
20 pub fn new(
21 input_norm: DenseWeight,
22 attn: AttentionWeights,
23 post_attn_norm: DenseWeight,
24 ffn: FfnComponent,
25 attn_layer_idx: usize,
26 q_nvfp4: Option<QuantizedWeight>,
27 k_nvfp4: Option<QuantizedWeight>,
28 v_nvfp4: Option<QuantizedWeight>,
29 gpu: &dyn GpuBackend,
30 kv_dtype: KvCacheDtype,
31 fp8_calibration_tokens: usize,
32 config: &avarok_core::config::ModelConfig,
33 ) -> Result<Self> {
34 Self::new_with_gating(
35 input_norm,
36 attn,
37 post_attn_norm,
38 ffn,
39 attn_layer_idx,
40 q_nvfp4,
41 k_nvfp4,
42 v_nvfp4,
43 true,
44 gpu,
45 kv_dtype,
46 fp8_calibration_tokens,
47 config,
48 )
49 }
50
51 pub fn new_ungated(
52 input_norm: DenseWeight,
53 attn: AttentionWeights,
54 post_attn_norm: DenseWeight,
55 ffn: FfnComponent,
56 attn_layer_idx: usize,
57 q_nvfp4: Option<QuantizedWeight>,
58 k_nvfp4: Option<QuantizedWeight>,
59 v_nvfp4: Option<QuantizedWeight>,
60 gpu: &dyn GpuBackend,
61 kv_dtype: KvCacheDtype,
62 fp8_calibration_tokens: usize,
63 config: &avarok_core::config::ModelConfig,
64 ) -> Result<Self> {
65 Self::new_with_gating(
66 input_norm,
67 attn,
68 post_attn_norm,
69 ffn,
70 attn_layer_idx,
71 q_nvfp4,
72 k_nvfp4,
73 v_nvfp4,
74 false,
75 gpu,
76 kv_dtype,
77 fp8_calibration_tokens,
78 config,
79 )
80 }
81
82 #[allow(clippy::too_many_arguments)]
83 fn new_with_gating(
84 input_norm: DenseWeight,
85 attn: AttentionWeights,
86 post_attn_norm: DenseWeight,
87 ffn: FfnComponent,
88 attn_layer_idx: usize,
89 q_nvfp4: Option<QuantizedWeight>,
90 k_nvfp4: Option<QuantizedWeight>,
91 v_nvfp4: Option<QuantizedWeight>,
92 gated: bool,
93 gpu: &dyn GpuBackend,
94 kv_dtype: KvCacheDtype,
95 fp8_calibration_tokens: usize,
96 config: &avarok_core::config::ModelConfig,
97 ) -> Result<Self> {
98 let (reshape_mod, reshape_fn, decode_mod, decode_fn) =
99 super::init_kernel_dispatch::kernel_modules_for_dtype(kv_dtype, config.head_dim);
100 let probes = ArchProbes::from_config(config);
104 let mrope_interleaved = config.mrope_interleaved;
105 Ok(Self {
106 input_norm,
107 attn,
108 post_attn_norm,
109 ffn,
110 attn_layer_idx,
111 lora: None,
112 gated,
113 mrope_interleaved,
114 kv_dtype,
115 head_dim_override: None,
116 num_q_heads_override: None,
117 num_kv_heads_override: None,
118 sliding_window: None,
119 rope_theta_override: None,
120 rotary_dim_override: None,
121 rope_proportional: false,
122 attn_scale_override: None,
123 k_eq_v: false,
124 v_norm_weight: None,
125 head_gate_weight: None,
126 head_gate_activation: HeadGateActivation::Sigmoid,
127 sigmoid_gate_head_broadcast_k: super::super::try_kernel(
128 gpu,
129 "residual_add",
130 "sigmoid_gate_mul_head_broadcast",
131 ),
132 softplus_gate_head_broadcast_k: super::super::try_kernel(
133 gpu,
134 "residual_add",
135 "softplus_gate_mul_head_broadcast",
136 ),
137 yarn_inv_freq: spark_runtime::gpu::DevicePtr::NULL,
138 yarn_attention_factor: 1.0,
139 post_attn_out_norm: None,
140 post_ffn_out_norm: None,
141 layer_scalar: None,
142 moe_ffn: None,
143 shortcut_carry_out: None,
144 shortcut_carry_in: None,
145 pre_moe_norm: None,
146 post_moe_out_norm: None,
147 post_dense_ffn_norm: None,
148 sparse_v_threshold: 0.0,
149 q_weight: q_nvfp4.map(QuantWeight::Nvfp4),
150 k_weight: k_nvfp4.map(QuantWeight::Nvfp4),
151 v_weight: v_nvfp4.map(QuantWeight::Nvfp4),
152 o_weight: None,
153 o_dense_bf16: None,
154 mla: None,
155 hc: None,
161 qsa: None,
162 hc_pre_k: gate(probes.hyper_connection, gpu, "hyper_connection", "hc_pre"),
163 hc_post_k: gate(probes.hyper_connection, gpu, "hyper_connection", "hc_post"),
164 hc_expand_k: gate(
165 probes.hyper_connection,
166 gpu,
167 "hyper_connection",
168 "hc_expand",
169 ),
170 hc_head_k: gate(probes.hyper_connection, gpu, "hyper_connection", "hc_head"),
171 qkv_nvfp4_t: None,
172 q_nvfp4_t: None,
173 k_nvfp4_t: None,
174 v_nvfp4_t: None,
175 o_nvfp4_t: None,
176 q_fp8w_t: None,
177 k_fp8w_t: None,
178 v_fp8w_t: None,
179 o_fp8w_t: None,
180 w8a16_gemm_t_k: super::super::try_kernel(gpu, "w8a16_gemm_t", "w8a16_gemm_t"),
181 w8a16_gemm_t_pipelined_k: super::super::try_kernel(
182 gpu,
183 "w8a16_gemm_t",
184 "w8a16_gemm_t_pipelined",
185 ),
186 w8a16_gemm_t_m128_k: super::super::try_kernel(
187 gpu,
188 "w8a16_gemm_t_m128",
189 "w8a16_gemm_t_m128",
190 ),
191 per_token_group_quant_fp8_k: crate::layers::ops::Fp8ActQuant::resolve(gpu),
198 fp8_gemm_t_blockscaled_k: super::super::try_kernel(
199 gpu,
200 super::types_weights::W8A8_PREFILL_KERNELS[1].0,
201 super::types_weights::W8A8_PREFILL_KERNELS[1].1,
202 ),
203 fp8_act_scale_kmajor_k: super::super::try_kernel(
208 gpu,
209 "fp8_scale_transpose",
210 "fp8_act_scale_to_kmajor",
211 ),
212 rms_norm_k: gpu.kernel("norm", "rms_norm")?,
213 rms_norm_w_k: if crate::ships_vanilla_norm_weights(config) {
214 gpu.kernel("rms_norm_vanilla", "rms_norm_vanilla")?
215 } else {
216 gpu.kernel("norm", "rms_norm")?
217 },
218 rms_norm_w_warp_row_k: if crate::ships_vanilla_norm_weights(config) {
219 gpu.kernel("rms_norm_vanilla", "rms_norm_vanilla_warp_row")
220 .unwrap_or(KernelHandle(0))
221 } else {
222 KernelHandle(0)
223 },
224 norm_vanilla: crate::ships_vanilla_norm_weights(config),
225 rms_norm_residual_k: if crate::ships_vanilla_norm_weights(config) {
226 gpu.kernel("norm", "rms_norm_residual_vanilla")?
227 } else {
228 gpu.kernel("norm", "rms_norm_residual")?
229 },
230 dense_gemv_k: gpu.kernel("gemv", "dense_gemv_bf16")?,
231 dequant_q2_0_gn_k: super::super::try_kernel(
232 gpu,
233 "dequant_gguf_bf16",
234 "dequant_q2_0_gn_to_bf16",
235 ),
236 q2_0_mmq_nc_k: KernelHandle(0),
240 q2_0_mmq_wc_k: KernelHandle(0),
241 q4k_quant_act_k: KernelHandle(0),
242 q2_0_gemv_k: super::super::try_kernel(gpu, "q2_0_gemv_vec", "q2_0_gemv_vec"),
243 dense_gemv_batchm_k: gpu
244 .kernel("dense_gemv_bf16_batchm", "dense_gemv_bf16_batchm")
245 .unwrap_or(KernelHandle(0)),
246 w4a16_gemv_k: gpu.kernel("w4a16_gemv", "w4a16_gemv")?,
247 w4a16_gemv_sw_k: super::super::try_kernel(gpu, "w4a16_gemv", "w4a16_gemv_sw"),
248 w8a16_gemv_k: gpu.kernel("w8a16_gemv", "w8a16_gemv")?,
249 w8a16_gemv_batch4_k: super::super::try_kernel(
250 gpu,
251 "w8a16_gemv_batch4",
252 "w8a16_gemv_batch4",
253 ),
254 w8a16_gemv_batch16_k: super::super::try_kernel(
255 gpu,
256 "w8a16_gemv_batch4",
257 "w8a16_gemv_batch16",
258 ),
259 w8a16_gemv_batch4_strided_k: super::super::try_kernel(
260 gpu,
261 "w8a16_gemv_batch4",
262 "w8a16_gemv_batch4_strided",
263 ),
264 w8a16_gemv_batch16_strided_k: super::super::try_kernel(
265 gpu,
266 "w8a16_gemv_batch4",
267 "w8a16_gemv_batch16_strided",
268 ),
269 w8a16_gemm_m16_k: super::super::try_target_kernel(
270 gpu,
271 "w8a16_gemm_m16",
272 "w8a16_gemm_m16",
273 ),
274 w8a16_gemm_m16_strided_k: super::super::try_target_kernel(
275 gpu,
276 "w8a16_gemm_m16",
277 "w8a16_gemm_m16_strided",
278 ),
279 m16_tc: crate::layers::dense_ffn::m16_tc::m16_tc_levers().attn,
280 w8a16_gemv_ncol2_k: super::super::try_target_kernel(
281 gpu,
282 "w8a16_gemv_ncol",
283 "w8a16_gemv_batch16_ncol2",
284 ),
285 w8a16_gemv_ncol4_k: super::super::try_target_kernel(
286 gpu,
287 "w8a16_gemv_ncol",
288 "w8a16_gemv_batch16_ncol4",
289 ),
290 w8a16_gemv_ncol2_strided_k: super::super::try_target_kernel(
291 gpu,
292 "w8a16_gemv_ncol",
293 "w8a16_gemv_batch16_ncol2_strided",
294 ),
295 w8a16_gemv_ncol4_strided_k: super::super::try_target_kernel(
296 gpu,
297 "w8a16_gemv_ncol",
298 "w8a16_gemv_batch16_ncol4_strided",
299 ),
300 attn_ncol: super::attn_ncol_gemv::ncol_gemv_enabled()
301 .then(super::attn_ncol_gemv::ncol_gemv_width),
302 w8a16_gemm_k: super::super::try_kernel(gpu, "w8a16_gemm", "w8a16_gemm"),
303 w8a16_gemm_pipelined_k: super::super::try_kernel(
304 gpu,
305 "w8a16_gemm_pipelined",
306 "w8a16_gemm_pipelined",
307 ),
308 w4a16_gemv_dual_k: gpu.kernel("w4a16_gemv_fused", "w4a16_gemv_dual")?,
309 rope_k: gpu.kernel("rope", "rope_forward")?,
310 rope_strided_k: super::super::try_kernel(gpu, "rope", "rope_forward_strided"),
311 rms_norm_strided_k: super::super::try_kernel(gpu, "norm", "rms_norm_strided"),
312 rope_mrope_interleaved_k: super::super::try_kernel(
313 gpu,
314 "rope_mrope_interleaved",
315 "rope_forward_mrope_interleaved",
316 ),
317 rope_mrope_interleaved_k_only_k: super::super::try_kernel(
318 gpu,
319 "rope_mrope_interleaved",
320 "rope_forward_mrope_interleaved_k_only",
321 ),
322 rope_yarn_k: super::super::try_kernel(gpu, "rope", "rope_forward_yarn"),
323 rope_yarn_scaled_k: super::super::try_kernel(gpu, "rope", "rope_forward_yarn_scaled"),
324 rope_yarn_interleaved_k: super::super::try_kernel(
326 gpu,
327 "rope",
328 "rope_forward_yarn_interleaved",
329 ),
330 rope_yarn_interleaved_inv_k: super::super::try_kernel(
331 gpu,
332 "rope",
333 "rope_forward_yarn_interleaved_inv",
334 ),
335 rope_proportional_k: super::super::try_kernel(gpu, "rope", "rope_forward_proportional"),
336 reshape_cache_k: gpu.kernel(reshape_mod, reshape_fn)?,
337 fused_k_norm_rope_cache_write_bf16_k: super::super::try_target_kernel(
348 gpu,
349 "fused_k_norm_rope_cache",
350 "fused_k_norm_rope_cache_write_bf16",
351 ),
352 fused_k_norm_rope_mrope_cache_write_bf16_k: super::super::try_target_kernel(
354 gpu,
355 "fused_k_norm_rope_cache",
356 "fused_k_norm_rope_mrope_cache_write_bf16",
357 ),
358 reshape_and_cache_flash_v_only_k: super::super::try_kernel(
359 gpu,
360 "reshape_and_cache",
361 "reshape_and_cache_flash_v_only",
362 ),
363 fused_k_norm_rope_cache_write_fp8_kv_k: super::super::try_target_kernel(
373 gpu,
374 "reshape_and_cache_fused_k_fp8",
375 "fused_k_norm_rope_cache_write_fp8_kv",
376 ),
377 wht_bf16_k: super::super::try_kernel(gpu, "wht_bf16", "wht_bf16_inplace"),
378 wht_bf16_k_inv: super::super::try_kernel(gpu, "wht_bf16", "wht_bf16_inplace_inv"),
379 innerq_apply_q_k: super::super::try_kernel(
380 gpu,
381 "tq_plus_innerq_apply",
382 "tq_plus_innerq_apply_q",
383 ),
384 innerq_apply_k_k: super::super::try_kernel(
385 gpu,
386 "tq_plus_innerq_apply",
387 "tq_plus_innerq_apply_k",
388 ),
389 paged_decode_k: gpu.kernel(decode_mod, decode_fn)?,
390 paged_decode_512_k: match kv_dtype {
396 KvCacheDtype::Bf16 => gate(
397 probes.wide_head_dim,
398 gpu,
399 "paged_decode_attn_512",
400 "paged_decode_attn",
401 ),
402 KvCacheDtype::Turbo4 => gate(
403 probes.wide_head_dim,
404 gpu,
405 "paged_decode_turbo4_512",
406 "paged_decode_attn_turbo4",
407 ),
408 KvCacheDtype::Turbo8 => gate(
409 probes.wide_head_dim,
410 gpu,
411 "paged_decode_turbo8_512",
412 "paged_decode_attn_turbo8",
413 ),
414 KvCacheDtype::Turbo3 | KvCacheDtype::Turbo2 => gate(
415 probes.wide_head_dim,
416 gpu,
417 "paged_decode_turbo4_512",
418 "paged_decode_attn_turbo4",
419 ),
420 _ => gate(
421 probes.wide_head_dim,
422 gpu,
423 "paged_decode_attn_fp8_512",
424 "paged_decode_attn_fp8",
425 ),
426 },
427 paged_decode_mla_k: gate(probes.mla, gpu, "paged_decode_mla", "paged_decode_attn"),
428 mla_paged_decode_k: gate(
430 probes.mla,
431 gpu,
432 "mla_paged_decode",
433 "mla_paged_decode_nvfp4",
434 ),
435 mla_paged_decode_fp8_k: gate(
436 probes.mla,
437 gpu,
438 "mla_paged_decode_fp8",
439 "mla_paged_decode_fp8",
440 ),
441 mla_batched_gemv_k: gate(probes.mla, gpu, "mla_absorbed", "mla_batched_gemv"),
442 mla_q_rope_scatter_k: gate(probes.mla, gpu, "mla_absorbed", "mla_q_rope_scatter"),
443 mla_q_rope_writeback_k: gate(probes.mla, gpu, "mla_absorbed", "mla_q_rope_writeback"),
444 mla_cache_assemble_k: gate(probes.mla, gpu, "mla_absorbed", "mla_cache_assemble"),
445 mla_q_rope_extract_batched_k: gate(
446 probes.mla,
447 gpu,
448 "mla_absorbed",
449 "mla_q_rope_extract_batched",
450 ),
451 mla_q_rope_writeback_batched_k: gate(
452 probes.mla,
453 gpu,
454 "mla_absorbed",
455 "mla_q_rope_writeback_batched",
456 ),
457 mla_kv_assemble_batched_k: gate(
458 probes.mla,
459 gpu,
460 "mla_absorbed",
461 "mla_kv_assemble_batched",
462 ),
463 mla_cache_assemble_batched_k: gate(
464 probes.mla,
465 gpu,
466 "mla_absorbed",
467 "mla_cache_assemble_batched",
468 ),
469 prefill_attn_mla320_k: gate(
470 probes.mla,
471 gpu,
472 "mla_prefill_attn",
473 "mla_prefill_attn_320",
474 ),
475 grouped_gemm_mla_k: gate(probes.mla, gpu, "grouped_gemm_mla", "grouped_gemm_mla"),
476 mla_q_final_assemble_k: gate(
477 probes.mla,
478 gpu,
479 "mla_absorbed",
480 "mla_q_final_assemble_batched",
481 ),
482 mla_fused_prefill_k: gate(probes.mla, gpu, "mla_fused_prefill", "mla_fused_prefill"),
483 gemm_splitk_partial_k: super::super::try_kernel(
484 gpu,
485 "gemm_splitk",
486 "dense_gemm_splitk_partial",
487 ),
488 gemm_splitk_reduce_k: super::super::try_kernel(
489 gpu,
490 "gemm_splitk",
491 "dense_gemm_splitk_reduce",
492 ),
493 dense_gemm_tc_k: super::super::try_kernel(gpu, "gemm_tc", "dense_gemm_tc"),
494 paged_decode_splitk_k: match kv_dtype {
495 KvCacheDtype::Nvfp4 => {
496 Some(gpu.kernel("paged_decode_nvfp4", "paged_decode_attn_splitk_nvfp4")?)
497 }
498 KvCacheDtype::Turbo3
499 | KvCacheDtype::Turbo4
500 | KvCacheDtype::Turbo8
501 | KvCacheDtype::Bf16KTurbo3V
502 | KvCacheDtype::Bf16KTurbo4V
503 | KvCacheDtype::Bf16KTurbo2V
504 | KvCacheDtype::Fp8KTurbo3V
505 | KvCacheDtype::Fp8KTurbo4V
506 | KvCacheDtype::Fp8KTurbo2V
507 | KvCacheDtype::Turbo4KTurbo3V
508 | KvCacheDtype::Turbo4KTurbo8V
509 | KvCacheDtype::Turbo3KTurbo8V => None,
510 _ => Some(gpu.kernel("paged_decode_fp8", "paged_decode_attn_splitk_fp8")?),
511 },
512 paged_decode_reduce_k: match kv_dtype {
513 KvCacheDtype::Nvfp4 => {
514 Some(gpu.kernel("paged_decode_nvfp4", "paged_decode_attn_reduce_nvfp4")?)
515 }
516 KvCacheDtype::Turbo3
517 | KvCacheDtype::Turbo4
518 | KvCacheDtype::Turbo8
519 | KvCacheDtype::Bf16KTurbo3V
520 | KvCacheDtype::Bf16KTurbo4V
521 | KvCacheDtype::Bf16KTurbo2V
522 | KvCacheDtype::Fp8KTurbo3V
523 | KvCacheDtype::Fp8KTurbo4V
524 | KvCacheDtype::Fp8KTurbo2V
525 | KvCacheDtype::Turbo4KTurbo3V
526 | KvCacheDtype::Turbo4KTurbo8V
527 | KvCacheDtype::Turbo3KTurbo8V => None,
528 _ => Some(gpu.kernel("paged_decode_fp8", "paged_decode_attn_reduce_fp8")?),
529 },
530 paged_decode_bf16_gqa_k: present(super::super::try_target_kernel(
540 gpu,
541 "paged_decode_attn_bf16_gqa",
542 "paged_decode_attn_bf16_gqa",
543 )),
544 paged_decode_fp8_gqa_k: present(super::super::try_target_kernel(
545 gpu,
546 "paged_decode_attn_fp8_gqa",
547 "paged_decode_attn_fp8_gqa",
548 )),
549 paged_decode_splitk_hopper_k: present(super::super::try_target_kernel(
559 gpu,
560 "paged_decode_fp8_splitk_hopper",
561 "paged_decode_attn_splitk_fp8_hopper",
562 )),
563 paged_decode_reduce_hopper_k: present(super::super::try_target_kernel(
564 gpu,
565 "paged_decode_fp8_splitk_hopper",
566 "paged_decode_attn_reduce_fp8_hopper",
567 )),
568 paged_decode_splitk_bf16_hopper_k: present(super::super::try_target_kernel(
569 gpu,
570 "paged_decode_bf16_splitk_hopper",
571 "paged_decode_attn_splitk_bf16_hopper",
572 )),
573 paged_decode_reduce_bf16_hopper_k: present(super::super::try_target_kernel(
574 gpu,
575 "paged_decode_bf16_splitk_hopper",
576 "paged_decode_attn_reduce_bf16_hopper",
577 )),
578 residual_add_k: gpu.kernel("residual_add", "bf16_residual_add")?,
579 rms_norm_f32_in_k: KernelHandle(0),
581 sigmoid_gate_mul_k: gpu.kernel("residual_add", "sigmoid_gate_mul")?,
582 deinterleave_qg_k: gpu.kernel("ssm_preprocess", "deinterleave_qg")?,
583 w4a16_gemv_qg_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_qg")?,
584 residual_add_rms_norm_k: if crate::ships_vanilla_norm_weights(config) {
585 gpu.kernel("norm", "residual_add_rms_norm_vanilla")?
586 } else {
587 gpu.kernel("norm", "residual_add_rms_norm")?
588 },
589 residual_add_rms_norm_gatef32_k: crate::layers::try_kernel(
590 gpu,
591 "norm",
592 "residual_add_rms_norm_gatef32",
593 ),
594 w4a16_gemv_qg_batch2_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_qg_batch2")?,
595 w4a16_gemv_dual_batch2_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_dual_batch2")?,
596 w4a16_gemv_batch2_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch2")?,
597 w4a16_gemv_qg_batch3_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_qg_batch3")?,
598 w4a16_gemv_dual_batch3_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_dual_batch3")?,
599 w4a16_gemv_batch3_k: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch3")?,
600 w4a16_batchm: crate::layers::w4a16_gemv_tiers::W4a16BatchmTiers::resolve(gpu),
601 w4a16_gemm_k: gpu.kernel("w4a16", "w4a16_gemm")?,
602 w4a16_gemm_t_k: crate::layers::tgemm_kernel(gpu),
603 w4a16_gemm_t_k64_k: crate::layers::k64_kernel(gpu)?,
604 w4a16_gemm_t_k64_n64_k: crate::layers::k64_n64_kernel(gpu),
605 w4a16_gemm_t_m128_k: gpu.kernel("w4a16", "w4a16_gemm_t_m128")?,
606 w4a16_gemm_t_m128_bf16_k: super::super::try_kernel(
607 gpu,
608 "w4a16",
609 "w4a16_gemm_t_m128_bf16",
610 ),
611 w4a16_gemm_t_m128_v2_k: super::super::w4a16_v2_kernel(gpu),
612 w4a16_gemm_t_m128_v3_k: super::super::w4a16_v3_kernel(gpu),
613 dense_gemm_k: gpu.kernel("gemm", "dense_gemm_bf16")?,
614 dense_gemm_pipelined_k: super::super::try_kernel(
615 gpu,
616 "gemm",
617 "dense_gemm_bf16_pipelined",
618 ),
619 prefill_attn_k: gpu.kernel("inferspark_prefill", "inferspark_prefill")?,
620 prefill_attn_512_k: if probes.wide_head_dim {
626 crate::layers::ops::wide_prefill_kernel(gpu).0
627 } else {
628 spark_runtime::gpu::KernelHandle(0)
629 },
630 prefill_attn_512_is_tc: probes.wide_head_dim
632 && crate::layers::ops::wide_prefill_kernel(gpu).1 == 32,
633 csa_compress_k: gate(probes.compressed_attn, gpu, "csa_compress", "csa_compress"),
635 prefill_attn_compressed_k: gate(
636 probes.compressed_attn,
637 gpu,
638 "prefill_attn_compressed",
639 "prefill_attn_compressed",
640 ),
641 v4_comp_pool_filled: std::sync::atomic::AtomicU32::new(0),
642 v4_comp_prev_valid: std::sync::atomic::AtomicBool::new(false),
643 v4_decode_started: std::sync::atomic::AtomicBool::new(false),
644 v4_decode_first_pos: std::sync::atomic::AtomicU32::new(0),
645 prefill_attn_paged_512_k: gate(
646 probes.wide_head_dim,
647 gpu,
648 "inferspark_prefill_paged_512",
649 "inferspark_prefill_paged_512",
650 ),
651 prefill_attn_64_k: gpu.kernel("inferspark_prefill", "inferspark_prefill_64")?,
652 prefill_attn_paged_k: gpu.kernel("prefill_paged", "inferspark_prefill_paged")?,
653 prefill_attn_paged_fp8_k: gpu
654 .kernel("prefill_paged_fp8", "inferspark_prefill_paged_fp8")?,
655 prefill_attn_paged_nvfp4_k: gpu
656 .kernel("prefill_paged_nvfp4", "inferspark_prefill_paged_nvfp4")?,
657 prefill_attn_paged_turbo4_k: super::super::try_kernel(
658 gpu,
659 "prefill_paged_turbo4",
660 "inferspark_prefill_paged_turbo4",
661 ),
662 prefill_attn_paged_64_k: gpu.kernel("prefill_paged", "inferspark_prefill_paged_64")?,
663 prefill_attn_paged_fp8_64_k: gpu
664 .kernel("prefill_paged_fp8", "inferspark_prefill_paged_fp8_64")?,
665 prefill_attn_paged_nvfp4_64_k: gpu
666 .kernel("prefill_paged_nvfp4", "inferspark_prefill_paged_nvfp4_64")?,
667 prefill_attn_paged_turbo2_64_k: super::super::try_kernel(
668 gpu,
669 "prefill_paged_turbo2",
670 "inferspark_prefill_paged_turbo2",
671 ),
672 prefill_attn_paged_turbo3_64_k: super::super::try_kernel(
673 gpu,
674 "prefill_paged_turbo3",
675 "inferspark_prefill_paged_turbo3_64",
676 ),
677 prefill_attn_paged_turbo4_64_k: super::super::try_kernel(
678 gpu,
679 "prefill_paged_turbo4",
680 "inferspark_prefill_paged_turbo4_64",
681 ),
682 prefill_attn_paged_turbo8_64_k: super::super::try_kernel(
683 gpu,
684 "prefill_paged_turbo8",
685 "inferspark_prefill_paged_turbo8_64",
686 ),
687 prefill_attn_paged_bf16k_turbo3v_64_k: super::super::try_kernel(
692 gpu,
693 "prefill_paged_bf16k_turbo3v",
694 "inferspark_prefill_paged_bf16k_turbo3v_64",
695 ),
696 prefill_attn_paged_bf16k_turbo4v_64_k: super::super::try_kernel(
698 gpu,
699 "prefill_paged_bf16k_turbo4v",
700 "inferspark_prefill_paged_bf16k_turbo4v_64",
701 ),
702 prefill_attn_paged_bf16k_turbo2v_64_k: super::super::try_kernel(
704 gpu,
705 "prefill_paged_bf16k_turbo2v",
706 "inferspark_prefill_paged_bf16k_turbo2v_64",
707 ),
708 prefill_attn_paged_fp8k_turbo3v_64_k: super::super::try_kernel(
711 gpu,
712 "prefill_paged_fp8k_turbo3v",
713 "inferspark_prefill_paged_fp8k_turbo3v_64",
714 ),
715 prefill_attn_paged_fp8k_turbo4v_64_k: super::super::try_kernel(
716 gpu,
717 "prefill_paged_fp8k_turbo4v",
718 "inferspark_prefill_paged_fp8k_turbo4v_64",
719 ),
720 prefill_attn_paged_fp8k_turbo2v_64_k: super::super::try_kernel(
721 gpu,
722 "prefill_paged_fp8k_turbo2v",
723 "inferspark_prefill_paged_fp8k_turbo2v_64",
724 ),
725 prefill_attn_paged_turbo4k_turbo3v_64_k: super::super::try_kernel(
730 gpu,
731 "prefill_paged_turbo4k_turbo3v",
732 "inferspark_prefill_paged_turbo4k_turbo3v_64",
733 ),
734 prefill_attn_paged_turbo4k_turbo8v_64_k: super::super::try_kernel(
735 gpu,
736 "prefill_paged_turbo4k_turbo8v",
737 "inferspark_prefill_paged_turbo4k_turbo8v_64",
738 ),
739 prefill_attn_paged_turbo3k_turbo8v_64_k: super::super::try_kernel(
740 gpu,
741 "prefill_paged_turbo3k_turbo8v",
742 "inferspark_prefill_paged_turbo3k_turbo8v_64",
743 ),
744 prefill_attn_paged_batched_k: super::super::try_kernel(
746 gpu,
747 "inferspark_prefill_paged_batched",
748 "inferspark_prefill_paged_batched",
749 ),
750 prefill_attn_paged_fp8_batched_k: super::super::try_kernel(
751 gpu,
752 "inferspark_prefill_paged_fp8_batched",
753 "inferspark_prefill_paged_fp8_batched",
754 ),
755 prefill_attn_paged_nvfp4_batched_k: super::super::try_kernel(
756 gpu,
757 "inferspark_prefill_paged_nvfp4_batched",
758 "inferspark_prefill_paged_nvfp4_batched",
759 ),
760 prefill_attn_paged_batched_64_k: super::super::try_kernel(
761 gpu,
762 "inferspark_prefill_paged_batched",
763 "inferspark_prefill_paged_batched_64",
764 ),
765 prefill_attn_paged_fp8_batched_64_k: super::super::try_kernel(
766 gpu,
767 "inferspark_prefill_paged_fp8_batched",
768 "inferspark_prefill_paged_fp8_batched_64",
769 ),
770 prefill_attn_paged_nvfp4_batched_64_k: super::super::try_kernel(
771 gpu,
772 "inferspark_prefill_paged_nvfp4_batched",
773 "inferspark_prefill_paged_nvfp4_batched_64",
774 ),
775 deinterleave_qg_split_k: gpu.kernel("ssm_preprocess", "deinterleave_qg_split")?,
776 deinterleave_qg_split_qnorm_k: gpu
777 .kernel("ssm_preprocess", "deinterleave_qg_split_qnorm")?,
778 deinterleave_qg_split_qnorm_mrope_k: super::super::try_kernel(
779 gpu,
780 "ssm_preprocess",
781 "deinterleave_qg_split_qnorm_mrope",
782 ),
783 sigmoid_gate_mul_batched_k: gpu.kernel("residual_add", "sigmoid_gate_mul_batched")?,
784 q_fp8: None,
785 k_fp8: None,
786 v_fp8: None,
787 o_fp8: None,
788 fp8_gemm_k: gpu.kernel("w4a16", "fp8_gemm_t")?,
789 bf16_to_fp8_k: gpu.kernel("w4a16", "bf16_to_fp8")?,
790 fp8_fp8_gemm_k: gpu.kernel("w4a16", "fp8_fp8_gemm_t")?,
791 fp8_gemm_t_m128_k: gpu.kernel("w4a16", "fp8_gemm_t_m128")?,
792 fp8_fp8_gemm_t_m128_k: gpu.kernel("w4a16", "fp8_fp8_gemm_t_m128")?,
793 w4a4_gemm_k: crate::layers::try_kernel(gpu, "w4a4", "w4a4_gemm_mfast"),
794 quantize_nvfp4_k: crate::layers::try_kernel(
795 gpu,
796 "quantize_nvfp4",
797 "quantize_bf16_to_nvfp4",
798 ),
799 fp8_calibration: if fp8_calibration_tokens > 0
800 && crate::layers::fp8_calibration::dtype_runs_online_fp8_kv_calibration(kv_dtype)
801 {
802 Some(Fp8KvCalibration::new(
803 attn_layer_idx,
804 fp8_calibration_tokens,
805 config.fp8_kv_headroom,
806 gpu,
807 )?)
808 } else {
809 None
810 },
811 })
812 }
813}
814
815#[cfg(test)]
816mod fused_kv_probe_guard {
817 #[test]
833 fn fused_k_norm_rope_cache_is_probed_target_scoped() {
834 let src = include_str!("init.rs");
835 let mut offenders = Vec::new();
836 for (i, window) in src.match_indices("\"fused_k_norm_rope_cache\"") {
837 let _ = window;
838 let head = &src[..i];
840 let call = head.rfind("try_kernel(").map(|p| (p, "try_kernel"));
841 let tcall = head
842 .rfind("try_target_kernel(")
843 .map(|p| (p, "try_target_kernel"));
844 let chosen = match (call, tcall) {
845 (Some((a, _)), Some((b, n))) if b >= a => Some((b, n)),
846 (Some((a, n)), _) => Some((a, n)),
847 (None, t) => t,
848 };
849 match chosen {
850 Some((_, "try_target_kernel")) => {}
851 other => offenders.push(format!("{other:?} before byte {i}")),
852 }
853 }
854 assert!(
855 !offenders.is_empty() || src.contains("fused_k_norm_rope_cache"),
856 "guard found no lookups at all — it has stopped measuring anything"
857 );
858 assert!(
859 offenders.is_empty(),
860 "fused_k_norm_rope_cache probed without try_target_kernel: {offenders:?}"
861 );
862 }
863}