1use std::sync::OnceLock;
24
25use bytemuck::{Pod, Zeroable};
26
27pub const MATMUL_WGSL: &str = include_str!("matmul.wgsl");
28pub const MATMUL_WIDE_WGSL: &str = include_str!("matmul_wide.wgsl");
29pub const MATMUL_WIDE_NV_WGSL: &str = include_str!("matmul_wide_nv.wgsl");
30pub const MATMUL_F16W_WGSL: &str = include_str!("matmul_f16w.wgsl");
31pub const MATMUL_F16_COMPUTE_WGSL: &str = include_str!("matmul_f16_compute.wgsl");
32pub const MATMUL_COOP16_WGSL: &str = include_str!("matmul_coop16.wgsl");
33pub const MATMUL_COOP_F32_WGSL: &str = include_str!("matmul_coop_f32.wgsl");
34pub const MATMUL_COOP_F32_PORTABLE_WGSL: &str = include_str!("matmul_coop_f32_portable.wgsl");
35pub const MATMUL_COOP_F16_VULKAN_WGSL: &str = include_str!("matmul_coop_f16_vulkan.wgsl");
36pub const MATMUL_COOP_F16_VULKAN_WIDEN_WGSL: &str =
37 include_str!("matmul_coop_f16_vulkan_widen.wgsl");
38pub const MATMUL_COOP_F16_VULKAN_F32ACC_WGSL: &str =
39 include_str!("matmul_coop_f16_vulkan_f32acc.wgsl");
40pub const MATMUL_COOP_F16_VULKAN_WIDEN_F32ACC_WGSL: &str =
41 include_str!("matmul_coop_f16_vulkan_widen_f32acc.wgsl");
42pub const MATMUL_QKV_COOP_F16_VK_WGSL: &str = include_str!("matmul_qkv_coop_f16_vk.wgsl");
43pub const MATMUL_QKV_COOP_F16_VK_WIDEN_WGSL: &str =
44 include_str!("matmul_qkv_coop_f16_vk_widen.wgsl");
45pub const MATMUL_QKV_COOP_F16_VK_F32ACC_WGSL: &str =
46 include_str!("matmul_qkv_coop_f16_vk_f32acc.wgsl");
47pub const MATMUL_QKV_COOP_F16_VK_WIDEN_F32ACC_WGSL: &str =
48 include_str!("matmul_qkv_coop_f16_vk_widen_f32acc.wgsl");
49pub const CAST_F32_TO_F16_WGSL: &str = include_str!("cast_f32_to_f16.wgsl");
50pub const BINARY_WGSL: &str = include_str!("binary.wgsl");
51pub const UNARY_WGSL: &str = include_str!("unary.wgsl");
52pub const UNARY_F16_MIRROR_WGSL: &str = include_str!("unary_f16_mirror.wgsl");
53pub const COMPARE_WGSL: &str = include_str!("compare.wgsl");
54pub const WHERE_WGSL: &str = include_str!("where.wgsl");
55pub const FMA_WGSL: &str = include_str!("fma.wgsl");
56pub const REDUCE_WGSL: &str = include_str!("reduce.wgsl");
57pub const SOFTMAX_WGSL: &str = include_str!("softmax.wgsl");
58pub const SOFTMAX_CROSS_ENTROPY_WGSL: &str = include_str!("softmax_cross_entropy.wgsl");
59pub const LAYERNORM_WGSL: &str = include_str!("layernorm.wgsl");
60pub const RMS_NORM_BWD_WGSL: &str = include_str!("rms_norm_backward.wgsl");
61pub const LAYER_NORM_BWD_WGSL: &str = include_str!("layer_norm_backward.wgsl");
62pub const CUMSUM_BWD_WGSL: &str = include_str!("cumsum_backward.wgsl");
63pub const ROPE_BWD_WGSL: &str = include_str!("rope_backward.wgsl");
64pub const GATHER_BWD_WGSL: &str = include_str!("gather_backward.wgsl");
65pub const CUMSUM_WGSL: &str = include_str!("cumsum.wgsl");
66pub const FFT_GPU_WGSL: &str = include_str!("fft_gpu.wgsl");
67#[cfg(feature = "native-gpu-fft")]
70pub const FFT_GPU_BIG_WGSL: &str = include_str!("fft_gpu_big.wgsl");
71#[cfg(feature = "native-gpu-fft")]
74pub const FFT_GPU_R4_16K_WGSL: &str = include_str!("fft_gpu_r4_16k.wgsl");
75#[cfg(feature = "native-gpu-fft")]
77pub const FFT_GPU_MULTIROW_WGSL: &str = include_str!("fft_gpu_multirow.wgsl");
78pub const COPY_WGSL: &str = include_str!("copy.wgsl");
79pub const ELEMENTWISE_REGION_WGSL: &str = include_str!("elementwise_region.wgsl");
80pub const TRANSPOSE_WGSL: &str = include_str!("transpose.wgsl");
81pub const NARROW_WGSL: &str = include_str!("narrow.wgsl");
82pub const CONCAT_WGSL: &str = include_str!("concat.wgsl");
83pub const GATHER_WGSL: &str = include_str!("gather.wgsl");
84pub const GATHER_SPLIT_WGSL: &str = include_str!("gather_split.wgsl");
85pub const GATHER_AXIS_WGSL: &str = include_str!("gather_axis.wgsl");
86pub const ATTENTION_WGSL: &str = include_str!("attention.wgsl");
87pub const ATTENTION_BWD_WGSL: &str = include_str!("attention_bwd.wgsl");
88pub const ROPE_WGSL: &str = include_str!("rope.wgsl");
89pub const EXPAND_WGSL: &str = include_str!("expand.wgsl");
90pub const ARGMAX_WGSL: &str = include_str!("argmax.wgsl");
91pub const POOL2D_WGSL: &str = include_str!("pool2d.wgsl");
92pub const CONV2D_WGSL: &str = include_str!("conv2d.wgsl");
93pub const POOL1D_WGSL: &str = include_str!("pool1d.wgsl");
94pub const POOL3D_WGSL: &str = include_str!("pool3d.wgsl");
95pub const CONV1D_WGSL: &str = include_str!("conv1d.wgsl");
96pub const CONV3D_WGSL: &str = include_str!("conv3d.wgsl");
97pub const SCATTER_ADD_WGSL: &str = include_str!("scatter_add.wgsl");
98pub const TOPK_WGSL: &str = include_str!("topk.wgsl");
99pub const WELCH_PEAKS_GPU_WGSL: &str = include_str!("welch_peaks_gpu.wgsl");
100pub const UMAP_KNN_WGSL: &str = include_str!("umap_knn.wgsl");
101pub const GROUPED_MATMUL_WGSL: &str = include_str!("grouped_matmul.wgsl");
102pub const SAMPLE_WGSL: &str = include_str!("sample.wgsl");
103pub const SELECTIVE_SCAN_WGSL: &str = include_str!("selective_scan.wgsl");
104pub const MAMBA2_WGSL: &str = include_str!("mamba2.wgsl");
105pub const GRU_WGSL: &str = include_str!("gru.wgsl");
106pub const RNN_WGSL: &str = include_str!("rnn.wgsl");
107pub const DEQUANT_MATMUL_WGSL: &str = include_str!("dequant_matmul.wgsl");
108pub const DEQUANT_GGUF_WGSL: &str = include_str!("dequant_gguf.wgsl");
109pub const DEQUANT_GEMV_GGUF_WGSL: &str = include_str!("dequant_gemv_gguf.wgsl");
110pub const FUSED_RESIDUAL_LN_WGSL: &str = include_str!("fused_residual_ln.wgsl");
111pub const FUSED_RESIDUAL_LN_TEE_WGSL: &str = include_str!("fused_residual_ln_tee.wgsl");
112pub const FUSED_RESIDUAL_RMS_NORM_WGSL: &str = include_str!("fused_residual_rms_norm.wgsl");
113pub const MATMUL_QKV_WGSL: &str = include_str!("matmul_qkv.wgsl");
114pub const MATMUL_QKV_COOP_F32_WGSL: &str = include_str!("matmul_qkv_coop_f32.wgsl");
115
116#[repr(C)]
117#[derive(Debug, Clone, Copy, Pod, Zeroable)]
118pub struct MatmulParams {
119 pub m: u32,
120 pub k: u32,
121 pub n: u32,
122 pub a_off: u32,
123 pub b_off: u32,
124 pub c_off: u32,
125 pub batch: u32,
126 pub a_batch_stride: u32,
127 pub b_batch_stride: u32,
128 pub c_batch_stride: u32,
129 pub has_bias: u32,
130 pub bias_off: u32,
131 pub act_id: u32, pub _pad0: u32,
133 pub _pad1: u32,
134 pub _pad2: u32,
135}
136
137#[repr(C)]
139#[derive(Debug, Clone, Copy, Pod, Zeroable)]
140pub struct BinaryParams {
141 pub n: u32,
142 pub a_off: u32,
143 pub b_off: u32,
144 pub c_off: u32,
145 pub op: u32,
146 pub _p0: u32,
147 pub _p1: u32,
148 pub _p2: u32,
149}
150
151#[repr(C)]
153#[derive(Debug, Clone, Copy, Pod, Zeroable)]
154pub struct UnaryParams {
155 pub n: u32,
156 pub in_off: u32,
157 pub out_off: u32,
158 pub op: u32,
159 pub _p0: u32,
160 pub _p1: u32,
161 pub _p2: u32,
162 pub _p3: u32,
163}
164
165#[repr(C)]
167#[derive(Debug, Clone, Copy, Pod, Zeroable)]
168pub struct WhereParams {
169 pub n: u32,
170 pub cond_off: u32,
171 pub x_off: u32,
172 pub y_off: u32,
173 pub out_off: u32,
174 pub _p0: u32,
175 pub _p1: u32,
176 pub _p2: u32,
177}
178
179#[repr(C)]
181#[derive(Debug, Clone, Copy, Pod, Zeroable)]
182pub struct FmaParams {
183 pub n: u32,
184 pub a_off: u32,
185 pub b_off: u32,
186 pub c_off: u32,
187 pub out_off: u32,
188 pub _p0: u32,
189 pub _p1: u32,
190 pub _p2: u32,
191}
192
193#[repr(C)]
204pub struct ReduceParams {
205 pub outer: u32,
206 pub reduce_dim: u32,
207 pub inner: u32,
208 pub in_off: u32,
209 pub out_off: u32,
210 pub op: u32,
211 pub _p0: u32,
212 pub _p1: u32,
213}
214
215unsafe impl Pod for ReduceParams {}
218unsafe impl Zeroable for ReduceParams {}
219impl Copy for ReduceParams {}
220impl Clone for ReduceParams {
221 fn clone(&self) -> Self {
222 *self
223 }
224}
225impl std::fmt::Debug for ReduceParams {
226 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
227 write!(
228 f,
229 "ReduceParams {{ outer: {}, reduce_dim: {}, inner: {}, op: {} }}",
230 self.outer, self.reduce_dim, self.inner, self.op
231 )
232 }
233}
234
235#[repr(C)]
237#[derive(Debug, Clone, Copy, Pod, Zeroable)]
238pub struct SoftmaxParams {
239 pub outer: u32,
240 pub inner: u32,
241 pub in_off: u32,
242 pub out_off: u32,
243 pub _p0: u32,
244 pub _p1: u32,
245 pub _p2: u32,
246 pub _p3: u32,
247}
248
249#[repr(C)]
251#[derive(Debug, Clone, Copy, Pod, Zeroable)]
252pub struct SceParams {
253 pub outer: u32,
254 pub inner: u32,
255 pub logits_off: u32,
256 pub targets_off: u32,
257 pub out_off: u32,
258 pub _p0: u32,
259 pub _p1: u32,
260 pub _p2: u32,
261}
262
263#[repr(C)]
265#[derive(Debug, Clone, Copy, Pod, Zeroable)]
266pub struct LayerNormParams {
267 pub outer: u32,
268 pub inner: u32,
269 pub in_off: u32,
270 pub out_off: u32,
271 pub gamma_off: u32,
272 pub beta_off: u32,
273 pub eps_bits: u32, pub op: u32, }
276
277#[repr(C)]
289#[derive(Debug, Clone, Copy, Pod, Zeroable)]
290pub struct LayerNormBwdParams {
291 pub outer: u32,
292 pub inner: u32,
293 pub x_off: u32,
294 pub gamma_off: u32,
295 pub dy_off: u32,
296 pub out_off: u32,
297 pub eps_bits: u32,
298 pub scratch_off: u32,
299}
300
301#[repr(C)]
303#[derive(Debug, Clone, Copy, Pod, Zeroable)]
304pub struct RmsNormBwdParams {
305 pub outer: u32,
306 pub inner: u32,
307 pub x_off: u32,
308 pub gamma_off: u32,
309 pub beta_off: u32,
310 pub dy_off: u32,
311 pub out_off: u32,
312 pub eps_bits: u32,
313 pub wrt: u32,
314}
315
316#[repr(C)]
317#[derive(Debug, Clone, Copy, Pod, Zeroable)]
318pub struct CumsumBwdParams {
319 pub outer: u32,
320 pub inner: u32,
321 pub dy_off: u32,
322 pub dx_off: u32,
323 pub exclusive: u32,
324 pub _p0: u32,
325 pub _p1: u32,
326 pub _p2: u32,
327}
328
329#[repr(C)]
330#[derive(Debug, Clone, Copy, Pod, Zeroable)]
331pub struct RopeBwdParams {
332 pub batch: u32,
333 pub seq: u32,
334 pub hidden: u32,
335 pub head_dim: u32,
336 pub n_rot: u32,
337 pub dy_off: u32,
338 pub cos_off: u32,
339 pub sin_off: u32,
340 pub dx_off: u32,
341 pub cos_len: u32,
342}
343
344#[repr(C)]
345#[derive(Debug, Clone, Copy, Pod, Zeroable)]
346pub struct GatherBwdParams {
347 pub outer: u32,
348 pub axis_dim: u32,
349 pub num_idx: u32,
350 pub trailing: u32,
351 pub dy_off: u32,
352 pub idx_off: u32,
353 pub dst_off: u32,
354 pub _p0: u32,
355}
356
357#[repr(C)]
359#[derive(Debug, Clone, Copy, Pod, Zeroable)]
360pub struct CumsumParams {
361 pub outer: u32,
362 pub inner: u32,
363 pub in_off: u32,
364 pub out_off: u32,
365 pub exclusive: u32,
366 pub _p0: u32,
367 pub _p1: u32,
368 pub _p2: u32,
369}
370
371#[repr(C)]
373#[derive(Debug, Clone, Copy, Pod, Zeroable)]
374pub struct FftParams {
375 pub src_off: u32,
376 pub dst_off: u32,
377 pub n: u32,
378 pub log2n: u32,
379 pub inverse: u32,
380 pub norm_scale: f32,
381 pub _p1: u32,
382 pub _p2: u32,
383}
384
385#[repr(C)]
387#[derive(Debug, Clone, Copy, Pod, Zeroable)]
388pub struct FftGpuParams {
389 pub off: u32,
390 pub dst_off: u32,
391 pub n: u32,
392 pub log2n: u32,
393 pub inverse: u32,
394 pub norm_scale: f32,
395 pub outer: u32,
396 pub tile: u32,
397 pub inner_stages: u32,
398 pub q_or_hs: u32,
399}
400
401#[repr(C)]
412#[derive(Debug, Clone, Copy, Pod, Zeroable)]
413pub struct ElementwiseRegionParams {
414 pub len: u32,
415 pub num_inputs: u32,
416 pub num_steps: u32,
417 pub dst_off: u32,
418 pub input_offs: [u32; 16],
419 pub chain: [u32; 128], pub scalar_input_mask: u32,
421 pub prologue: u32,
422 pub out_n: u32,
423 pub out_c: u32,
424 pub out_h: u32,
425 pub out_w: u32,
426 pub prologue_input: u32,
427 pub input_modulus: [u32; 16],
428}
429
430#[repr(C)]
432#[derive(Debug, Clone, Copy, Pod, Zeroable)]
433pub struct BatchElementwiseRegionParams {
434 pub slice_len: u32,
435 pub num_batch: u32,
436 pub num_steps: u32,
437 pub base_dst_off: u32,
438 pub slice_elems: u32,
439 pub batch_input_offs: [u32; 64],
440 pub chain: [u32; 128],
441 pub scalar_input_mask: u32,
442 pub input_modulus: [u32; 16],
443}
444
445#[repr(C)]
447#[derive(Debug, Clone, Copy, Pod, Zeroable)]
448pub struct CopyParams {
449 pub n: u32,
450 pub in_off: u32,
451 pub out_off: u32,
452 pub _p0: u32,
453 pub _p1: u32,
454 pub _p2: u32,
455 pub _p3: u32,
456 pub _p4: u32,
457}
458
459#[repr(C)]
461#[derive(Debug, Clone, Copy, Pod, Zeroable)]
462pub struct TransposeParams {
463 pub rank: u32,
464 pub out_total: u32,
465 pub in_off: u32,
466 pub out_off: u32,
467 pub bucket_outermost: u32,
471 pub out_dim_0: u32,
473 pub _p2: u32,
474 pub _p3: u32,
475}
476
477#[repr(C)]
479#[derive(Debug, Clone, Copy, Pod, Zeroable)]
480pub struct NarrowConcatParams {
481 pub total: u32, pub outer: u32,
483 pub inner: u32,
484 pub axis_in_size: u32,
485 pub axis_out_size: u32,
486 pub start: u32,
487 pub in_off: u32,
488 pub out_off: u32,
489}
490
491#[repr(C)]
493#[derive(Debug, Clone, Copy, Pod, Zeroable)]
494pub struct GatherParams {
495 pub n_out: u32,
496 pub n_idx: u32,
497 pub dim: u32,
498 pub vocab: u32,
499 pub in_off: u32,
500 pub idx_off: u32,
501 pub out_off: u32,
502 pub _p0: u32,
503}
504
505#[repr(C)]
507#[derive(Debug, Clone, Copy, Pod, Zeroable)]
508pub struct GatherAxisParams {
509 pub total: u32,
510 pub outer: u32,
511 pub axis_dim: u32,
512 pub num_idx: u32,
513 pub trailing: u32,
514 pub table_off: u32,
515 pub idx_off: u32,
516 pub out_off: u32,
517}
518
519#[repr(C)]
533#[derive(Debug, Clone, Copy, Pod, Zeroable)]
534pub struct AttentionParams {
535 pub batch: u32,
536 pub heads: u32,
537 pub seq_q: u32,
538 pub seq_k: u32,
539 pub head_dim: u32,
540 pub q_off: u32,
541 pub k_off: u32,
542 pub v_off: u32,
543 pub out_off: u32,
544 pub mask_off: u32,
545 pub mask_kind: u32,
546 pub scale_bits: u32,
547 pub window: u32,
548 pub seq_q_stride: u32,
560 pub seq_k_stride: u32,
561 pub mask_batch_stride: u32,
562 pub mask_head_stride: u32,
563 pub kv_heads: u32,
566 pub _pad_mask_1: u32,
567 pub _pad_mask_2: u32,
568
569 pub q_batch_stride: u32,
574 pub q_head_stride: u32,
575 pub q_seq_stride: u32,
576 pub _pad_q: u32,
577
578 pub k_batch_stride: u32,
579 pub k_head_stride: u32,
580 pub k_seq_stride: u32,
581 pub _pad_k: u32,
582
583 pub v_batch_stride: u32,
584 pub v_head_stride: u32,
585 pub v_seq_stride: u32,
586 pub _pad_v: u32,
587
588 pub o_batch_stride: u32,
589 pub o_head_stride: u32,
590 pub o_seq_stride: u32,
591 pub _pad_o: u32,
592}
593
594#[repr(C)]
596#[derive(Debug, Clone, Copy, Pod, Zeroable)]
597pub struct AttentionBwdParams {
598 pub batch: u32,
599 pub heads: u32,
600 pub seq_q: u32,
601 pub seq_k: u32,
602 pub head_dim: u32,
603 pub q_off: u32,
604 pub k_off: u32,
605 pub v_off: u32,
606 pub dy_off: u32,
607 pub out_off: u32,
608 pub mask_off: u32,
609 pub mask_kind: u32,
610 pub scale_bits: u32,
611 pub window: u32,
612 pub wrt: u32,
613 pub seq_q_stride: u32,
614 pub seq_k_stride: u32,
615 pub mask_batch_stride: u32,
616 pub mask_head_stride: u32,
617 pub _pad_mask_0: u32,
618 pub _pad_mask_1: u32,
619 pub _pad_mask_2: u32,
620 pub q_batch_stride: u32,
621 pub q_head_stride: u32,
622 pub q_seq_stride: u32,
623 pub _pad_q: u32,
624 pub k_batch_stride: u32,
625 pub k_head_stride: u32,
626 pub k_seq_stride: u32,
627 pub _pad_k: u32,
628 pub v_batch_stride: u32,
629 pub v_head_stride: u32,
630 pub v_seq_stride: u32,
631 pub _pad_v: u32,
632 pub o_batch_stride: u32,
633 pub o_head_stride: u32,
634 pub o_seq_stride: u32,
635 pub _pad_o: u32,
636}
637
638#[repr(C)]
640#[derive(Debug, Clone, Copy, Pod, Zeroable)]
641pub struct RopeParams {
642 pub n_total: u32,
643 pub seq: u32,
644 pub head_dim: u32,
645 pub half: u32,
646 pub in_off: u32,
647 pub cos_off: u32,
648 pub sin_off: u32,
649 pub out_off: u32,
650 pub last_dim: u32,
651 pub batch: u32,
657 pub seq_stride: u32,
658 pub style: u32,
662 pub rot_half: u32,
667}
668
669#[repr(C)]
672#[derive(Debug, Clone, Copy, Pod, Zeroable)]
673pub struct ExpandParams {
674 pub rank: u32,
675 pub out_total: u32,
676 pub in_off: u32,
677 pub out_off: u32,
678 pub bucket_outermost: u32,
681 pub out_dim_0: u32,
683 pub _p2: u32,
684 pub _p3: u32,
685}
686
687#[repr(C)]
689#[derive(Debug, Clone, Copy, Pod, Zeroable)]
690pub struct ArgmaxParams {
691 pub outer: u32,
692 pub inner: u32,
693 pub in_off: u32,
694 pub out_off: u32,
695 pub _p0: u32,
696 pub _p1: u32,
697 pub _p2: u32,
698 pub _p3: u32,
699}
700
701#[repr(C)]
703#[derive(Debug, Clone, Copy, Pod, Zeroable)]
704pub struct Pool2dParams {
705 pub n: u32,
706 pub c: u32,
707 pub h: u32,
708 pub w: u32,
709 pub h_out: u32,
710 pub w_out: u32,
711 pub kh: u32,
712 pub kw: u32,
713 pub sh: u32,
714 pub sw: u32,
715 pub ph: u32,
716 pub pw: u32,
717 pub op: u32,
718 pub in_off: u32,
719 pub out_off: u32,
720 pub _p0: u32,
721 pub _p1: u32,
722 pub _p2: u32,
723}
724
725#[repr(C)]
727#[derive(Debug, Clone, Copy, Pod, Zeroable)]
728pub struct Conv2dParams {
729 pub n: u32,
730 pub c_in: u32,
731 pub c_out: u32,
732 pub h: u32,
733 pub w: u32,
734 pub h_out: u32,
735 pub w_out: u32,
736 pub kh: u32,
737 pub kw: u32,
738 pub sh: u32,
739 pub sw: u32,
740 pub ph: u32,
741 pub pw: u32,
742 pub dh: u32,
743 pub dw: u32,
744 pub groups: u32,
745 pub in_off: u32,
746 pub w_off: u32,
747 pub out_off: u32,
748}
749
750#[repr(C)]
752#[derive(Debug, Clone, Copy, Pod, Zeroable)]
753pub struct Pool1dParams {
754 pub n: u32,
755 pub c: u32,
756 pub l: u32,
757 pub l_out: u32,
758 pub kl: u32,
759 pub sl: u32,
760 pub pl: u32,
761 pub op: u32,
762 pub in_off: u32,
763 pub out_off: u32,
764 pub _p0: u32,
765 pub _p1: u32,
766 pub _p2: u32,
767 pub _p3: u32,
768 pub _p4: u32,
769 pub _p5: u32,
770}
771
772#[repr(C)]
774#[derive(Debug, Clone, Copy, Pod, Zeroable)]
775pub struct Pool3dParams {
776 pub n: u32,
777 pub c: u32,
778 pub d: u32,
779 pub h: u32,
780 pub w: u32,
781 pub d_out: u32,
782 pub h_out: u32,
783 pub w_out: u32,
784 pub kd: u32,
785 pub kh: u32,
786 pub kw: u32,
787 pub sd: u32,
788 pub sh: u32,
789 pub sw: u32,
790 pub pd: u32,
791 pub ph: u32,
792 pub pw: u32,
793 pub op: u32,
794 pub in_off: u32,
795 pub out_off: u32,
796 pub _p0: u32,
797 pub _p1: u32,
798}
799
800#[repr(C)]
802#[derive(Debug, Clone, Copy, Pod, Zeroable)]
803pub struct Conv1dParams {
804 pub n: u32,
805 pub c_in: u32,
806 pub c_out: u32,
807 pub l: u32,
808 pub l_out: u32,
809 pub kl: u32,
810 pub sl: u32,
811 pub pl: u32,
812 pub dl: u32,
813 pub groups: u32,
814 pub in_off: u32,
815 pub w_off: u32,
816 pub out_off: u32,
817 pub _p0: u32,
818 pub _p1: u32,
819 pub _p2: u32,
820}
821
822#[repr(C)]
824#[derive(Debug, Clone, Copy, Pod, Zeroable)]
825pub struct DequantGgufParams {
826 pub w_byte_off: u32,
827 pub dst_f32_off: u32,
828 pub scheme_id: u32,
829 pub num_blocks: u32,
830}
831
832#[repr(C)]
835#[derive(Debug, Clone, Copy, Pod, Zeroable)]
836pub struct DequantGemvGgufParams {
837 pub k: u32,
838 pub n: u32,
839 pub scheme_id: u32,
840 pub x_f32_off: u32,
841 pub w_byte_off: u32,
842 pub out_f32_off: u32,
843 pub _p0: u32,
844 pub _p1: u32,
845}
846
847#[repr(C)]
849#[derive(Debug, Clone, Copy, Pod, Zeroable)]
850pub struct DequantMatmulParams {
851 pub m: u32,
852 pub k: u32,
853 pub n: u32,
854 pub block_size: u32,
855 pub scheme_id: u32,
856 pub x_off: u32,
857 pub w_off: u32,
858 pub scale_off: u32,
859 pub zp_off: u32,
860 pub out_off: u32,
861 pub _p0: u32,
862 pub _p1: u32,
863}
864
865#[repr(C)]
867#[derive(Debug, Clone, Copy, Pod, Zeroable)]
868pub struct FusedResidualLnTeeParams {
869 pub outer: u32,
870 pub inner: u32,
871 pub in_off: u32,
872 pub residual_off: u32,
873 pub bias_off: u32,
874 pub gamma_off: u32,
875 pub beta_off: u32,
876 pub sum_off: u32,
877 pub ln_out_off: u32,
878 pub eps_bits: u32,
879 pub has_bias: u32,
880 pub _p0: u32,
881}
882
883#[repr(C)]
886#[derive(Debug, Clone, Copy, Pod, Zeroable)]
887pub struct MatmulQkvParams {
888 pub m: u32,
889 pub k: u32,
890 pub n: u32,
891 pub a_off: u32,
892 pub b_off: u32,
893 pub q_off: u32,
894 pub k_off: u32,
895 pub v_off: u32,
896 pub head_width: u32,
897 pub has_bias: u32,
898 pub bias_off: u32,
899 pub _p0: u32,
900 pub _p1: u32,
901 pub _p2: u32,
902 pub _p3: u32,
903 pub _p4: u32,
904}
905
906pub type FusedResidualRmsNormParams = FusedResidualLnParams;
908
909#[repr(C)]
911#[derive(Debug, Clone, Copy, Pod, Zeroable)]
912pub struct FusedResidualLnParams {
913 pub outer: u32,
914 pub inner: u32,
915 pub in_off: u32,
916 pub residual_off: u32,
917 pub bias_off: u32,
918 pub gamma_off: u32,
919 pub beta_off: u32,
920 pub out_off: u32,
921 pub eps_bits: u32,
922 pub has_bias: u32,
923 pub _p0: u32,
924 pub _p1: u32,
925}
926
927#[repr(C)]
929#[derive(Debug, Clone, Copy, Pod, Zeroable)]
930pub struct Mamba2Params {
931 pub batch: u32,
932 pub seq: u32,
933 pub heads: u32,
934 pub head_dim: u32,
935 pub state_size: u32,
936 pub x_off: u32,
937 pub dt_off: u32,
938 pub a_off: u32,
939 pub b_off: u32,
940 pub c_off: u32,
941 pub out_off: u32,
942 pub seq_stride: u32,
943 pub _p1: u32,
944 pub _p2: u32,
945 pub _p3: u32,
946 pub _p4: u32,
947}
948
949#[repr(C)]
951#[derive(Debug, Clone, Copy, Pod, Zeroable)]
952pub struct GruParams {
953 pub batch: u32,
954 pub seq: u32,
955 pub input_size: u32,
956 pub hidden: u32,
957 pub x_off: u32,
958 pub wih_off: u32,
959 pub whh_off: u32,
960 pub bih_off: u32,
961 pub bhh_off: u32,
962 pub out_off: u32,
963 pub seq_stride: u32,
964 pub _p1: u32,
965 pub _p2: u32,
966 pub _p3: u32,
967 pub _p4: u32,
968 pub _p5: u32,
969}
970
971#[repr(C)]
973#[derive(Debug, Clone, Copy, Pod, Zeroable)]
974pub struct RnnParams {
975 pub batch: u32,
976 pub seq: u32,
977 pub input_size: u32,
978 pub hidden: u32,
979 pub x_off: u32,
980 pub wih_off: u32,
981 pub whh_off: u32,
982 pub bias_off: u32,
983 pub out_off: u32,
984 pub seq_stride: u32,
985 pub relu: u32,
986 pub _p1: u32,
987 pub _p2: u32,
988 pub _p3: u32,
989 pub _p4: u32,
990 pub _p5: u32,
991}
992
993#[repr(C)]
995#[derive(Debug, Clone, Copy, Pod, Zeroable)]
996pub struct SelectiveScanParams {
997 pub batch: u32,
998 pub seq: u32,
999 pub hidden: u32,
1000 pub state_size: u32,
1001 pub x_off: u32,
1002 pub delta_off: u32,
1003 pub a_off: u32,
1004 pub b_off: u32,
1005 pub c_off: u32,
1006 pub out_off: u32,
1007 pub seq_stride: u32,
1011 pub _p1: u32,
1012 pub _p2: u32,
1013 pub _p3: u32,
1014 pub _p4: u32,
1015 pub _p5: u32,
1016}
1017
1018#[repr(C)]
1020#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1021pub struct SampleParams {
1022 pub outer: u32,
1023 pub inner: u32,
1024 pub in_off: u32,
1025 pub out_off: u32,
1026 pub top_k: u32,
1027 pub top_p_bits: u32,
1028 pub temp_bits: u32,
1029 pub seed_lo: u32,
1030 pub seed_hi: u32,
1031 pub _p0: u32,
1032 pub _p1: u32,
1033 pub _p2: u32,
1034}
1035
1036#[repr(C)]
1038#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1039pub struct GroupedMatmulParams {
1040 pub m: u32,
1041 pub k: u32,
1042 pub n: u32,
1043 pub num_experts: u32,
1044 pub in_off: u32,
1045 pub w_off: u32,
1046 pub idx_off: u32,
1047 pub out_off: u32,
1048}
1049
1050#[repr(C)]
1052#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1053pub struct TopKParams {
1054 pub outer: u32,
1055 pub inner: u32,
1056 pub k: u32,
1057 pub in_off: u32,
1058 pub out_off: u32,
1059 pub _p0: u32,
1060 pub _p1: u32,
1061 pub _p2: u32,
1062}
1063
1064#[repr(C)]
1066#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1067pub struct WelchPeaksGpuParams {
1068 pub spec_off: u32,
1069 pub dst_off: u32,
1070 pub welch_batch: u32,
1071 pub n_fft: u32,
1072 pub n_segments: u32,
1073 pub k: u32,
1074 pub n_bins: u32,
1075 pub _p0: u32,
1076 pub _p1: u32,
1077}
1078
1079#[repr(C)]
1081#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1082pub struct UmapKnnParams {
1083 pub n: u32,
1084 pub k: u32,
1085 pub pw_off: u32,
1086 pub out_off: u32,
1087 pub _p0: u32,
1088 pub _p1: u32,
1089 pub _p2: u32,
1090}
1091
1092#[repr(C)]
1094#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1095pub struct ScatterAddParams {
1096 pub op: u32, pub out_off: u32,
1098 pub upd_off: u32,
1099 pub idx_off: u32,
1100 pub out_total: u32,
1101 pub num_updates: u32,
1102 pub trailing: u32,
1103 pub out_dim: u32,
1104}
1105
1106#[repr(C)]
1108#[derive(Debug, Clone, Copy, Pod, Zeroable)]
1109pub struct Conv3dParams {
1110 pub n: u32,
1111 pub c_in: u32,
1112 pub c_out: u32,
1113 pub d: u32,
1114 pub h: u32,
1115 pub w: u32,
1116 pub d_out: u32,
1117 pub h_out: u32,
1118 pub w_out: u32,
1119 pub kd: u32,
1120 pub kh: u32,
1121 pub kw: u32,
1122 pub sd: u32,
1123 pub sh: u32,
1124 pub sw: u32,
1125 pub pd: u32,
1126 pub ph: u32,
1127 pub pw: u32,
1128 pub dd: u32,
1129 pub dh: u32,
1130 pub dw: u32,
1131 pub groups: u32,
1132 pub in_off: u32,
1133 pub w_off: u32,
1134 pub out_off: u32,
1135 pub _p0: u32,
1136}
1137
1138pub struct Kernel {
1140 pub pipeline: wgpu::ComputePipeline,
1141 pub bgl: wgpu::BindGroupLayout,
1142}
1143
1144impl Kernel {
1145 pub fn bind_two(
1146 &self,
1147 device: &wgpu::Device,
1148 arena: &wgpu::Buffer,
1149 uniform: &wgpu::Buffer,
1150 ) -> wgpu::BindGroup {
1151 device.create_bind_group(&wgpu::BindGroupDescriptor {
1152 label: Some("rlx-wgpu fft gpu bg"),
1153 layout: &self.bgl,
1154 entries: &[
1155 wgpu::BindGroupEntry {
1156 binding: 0,
1157 resource: arena.as_entire_binding(),
1158 },
1159 wgpu::BindGroupEntry {
1160 binding: 1,
1161 resource: uniform.as_entire_binding(),
1162 },
1163 ],
1164 })
1165 }
1166}
1167
1168#[allow(dead_code)]
1174fn build_kernel_4(
1177 device: &wgpu::Device,
1178 label: &'static str,
1179 wgsl: &str,
1180 entry_point: &'static str,
1181) -> Kernel {
1182 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1183 label: Some(label),
1184 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1185 });
1186 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1187 label: Some(label),
1188 entries: &[
1189 wgpu::BindGroupLayoutEntry {
1190 binding: 0,
1191 visibility: wgpu::ShaderStages::COMPUTE,
1192 ty: wgpu::BindingType::Buffer {
1193 ty: wgpu::BufferBindingType::Storage { read_only: false },
1194 has_dynamic_offset: false,
1195 min_binding_size: None,
1196 },
1197 count: None,
1198 },
1199 wgpu::BindGroupLayoutEntry {
1200 binding: 1,
1201 visibility: wgpu::ShaderStages::COMPUTE,
1202 ty: wgpu::BindingType::Buffer {
1203 ty: wgpu::BufferBindingType::Uniform,
1204 has_dynamic_offset: false,
1205 min_binding_size: None,
1206 },
1207 count: None,
1208 },
1209 wgpu::BindGroupLayoutEntry {
1210 binding: 2,
1211 visibility: wgpu::ShaderStages::COMPUTE,
1212 ty: wgpu::BindingType::Buffer {
1213 ty: wgpu::BufferBindingType::Storage { read_only: true },
1214 has_dynamic_offset: false,
1215 min_binding_size: None,
1216 },
1217 count: None,
1218 },
1219 wgpu::BindGroupLayoutEntry {
1220 binding: 3,
1221 visibility: wgpu::ShaderStages::COMPUTE,
1222 ty: wgpu::BindingType::Buffer {
1223 ty: wgpu::BufferBindingType::Storage { read_only: true },
1224 has_dynamic_offset: false,
1225 min_binding_size: None,
1226 },
1227 count: None,
1228 },
1229 ],
1230 });
1231 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1232 label: Some(label),
1233 bind_group_layouts: &[Some(&bgl)],
1234 immediate_size: 0,
1235 });
1236 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1237 label: Some(label),
1238 layout: Some(&layout),
1239 module: &module,
1240 entry_point: Some(entry_point),
1241 compilation_options: Default::default(),
1242 cache: None,
1243 });
1244 Kernel { pipeline, bgl }
1245}
1246
1247fn build_kernel_3(
1248 device: &wgpu::Device,
1249 label: &'static str,
1250 wgsl: &str,
1251 entry_point: &'static str,
1252) -> Kernel {
1253 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1254 label: Some(label),
1255 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1256 });
1257 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1258 label: Some(label),
1259 entries: &[
1260 wgpu::BindGroupLayoutEntry {
1261 binding: 0,
1262 visibility: wgpu::ShaderStages::COMPUTE,
1263 ty: wgpu::BindingType::Buffer {
1264 ty: wgpu::BufferBindingType::Storage { read_only: false },
1265 has_dynamic_offset: false,
1266 min_binding_size: None,
1267 },
1268 count: None,
1269 },
1270 wgpu::BindGroupLayoutEntry {
1271 binding: 1,
1272 visibility: wgpu::ShaderStages::COMPUTE,
1273 ty: wgpu::BindingType::Buffer {
1274 ty: wgpu::BufferBindingType::Uniform,
1275 has_dynamic_offset: false,
1276 min_binding_size: None,
1277 },
1278 count: None,
1279 },
1280 wgpu::BindGroupLayoutEntry {
1281 binding: 2,
1282 visibility: wgpu::ShaderStages::COMPUTE,
1283 ty: wgpu::BindingType::Buffer {
1284 ty: wgpu::BufferBindingType::Storage { read_only: true },
1285 has_dynamic_offset: false,
1286 min_binding_size: None,
1287 },
1288 count: None,
1289 },
1290 ],
1291 });
1292 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1293 label: Some(label),
1294 bind_group_layouts: &[Some(&bgl)],
1295 immediate_size: 0,
1296 });
1297 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1298 label: Some(label),
1299 layout: Some(&layout),
1300 module: &module,
1301 entry_point: Some(entry_point),
1302 compilation_options: Default::default(),
1303 cache: None,
1304 });
1305 Kernel { pipeline, bgl }
1306}
1307
1308fn build_kernel_ro_u_ro_rw(
1314 device: &wgpu::Device,
1315 label: &'static str,
1316 wgsl: &str,
1317 entry_point: &'static str,
1318) -> Kernel {
1319 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1320 label: Some(label),
1321 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1322 });
1323 let storage = |read_only: bool| wgpu::BindingType::Buffer {
1324 ty: wgpu::BufferBindingType::Storage { read_only },
1325 has_dynamic_offset: false,
1326 min_binding_size: None,
1327 };
1328 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1329 label: Some(label),
1330 entries: &[
1331 wgpu::BindGroupLayoutEntry {
1332 binding: 0,
1333 visibility: wgpu::ShaderStages::COMPUTE,
1334 ty: storage(true),
1335 count: None,
1336 },
1337 wgpu::BindGroupLayoutEntry {
1338 binding: 1,
1339 visibility: wgpu::ShaderStages::COMPUTE,
1340 ty: wgpu::BindingType::Buffer {
1341 ty: wgpu::BufferBindingType::Uniform,
1342 has_dynamic_offset: false,
1343 min_binding_size: None,
1344 },
1345 count: None,
1346 },
1347 wgpu::BindGroupLayoutEntry {
1348 binding: 2,
1349 visibility: wgpu::ShaderStages::COMPUTE,
1350 ty: storage(true),
1351 count: None,
1352 },
1353 wgpu::BindGroupLayoutEntry {
1354 binding: 3,
1355 visibility: wgpu::ShaderStages::COMPUTE,
1356 ty: storage(false),
1357 count: None,
1358 },
1359 ],
1360 });
1361 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1362 label: Some(label),
1363 bind_group_layouts: &[Some(&bgl)],
1364 immediate_size: 0,
1365 });
1366 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1367 label: Some(label),
1368 layout: Some(&layout),
1369 module: &module,
1370 entry_point: Some(entry_point),
1371 compilation_options: Default::default(),
1372 cache: None,
1373 });
1374 Kernel { pipeline, bgl }
1375}
1376
1377fn build_kernel_cast_f32_to_f16(
1381 device: &wgpu::Device,
1382 label: &'static str,
1383 wgsl: &str,
1384 entry_point: &'static str,
1385) -> Kernel {
1386 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1387 label: Some(label),
1388 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1389 });
1390 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1391 label: Some(label),
1392 entries: &[
1393 wgpu::BindGroupLayoutEntry {
1394 binding: 0,
1395 visibility: wgpu::ShaderStages::COMPUTE,
1396 ty: wgpu::BindingType::Buffer {
1397 ty: wgpu::BufferBindingType::Storage { read_only: false },
1398 has_dynamic_offset: false,
1399 min_binding_size: None,
1400 },
1401 count: None,
1402 },
1403 wgpu::BindGroupLayoutEntry {
1404 binding: 1,
1405 visibility: wgpu::ShaderStages::COMPUTE,
1406 ty: wgpu::BindingType::Buffer {
1407 ty: wgpu::BufferBindingType::Uniform,
1408 has_dynamic_offset: false,
1409 min_binding_size: None,
1410 },
1411 count: None,
1412 },
1413 wgpu::BindGroupLayoutEntry {
1414 binding: 2,
1415 visibility: wgpu::ShaderStages::COMPUTE,
1416 ty: wgpu::BindingType::Buffer {
1417 ty: wgpu::BufferBindingType::Storage { read_only: false },
1418 has_dynamic_offset: false,
1419 min_binding_size: None,
1420 },
1421 count: None,
1422 },
1423 ],
1424 });
1425 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1426 label: Some(label),
1427 bind_group_layouts: &[Some(&bgl)],
1428 immediate_size: 0,
1429 });
1430 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1431 label: Some(label),
1432 layout: Some(&layout),
1433 module: &module,
1434 entry_point: Some(entry_point),
1435 compilation_options: Default::default(),
1436 cache: None,
1437 });
1438 Kernel { pipeline, bgl }
1439}
1440
1441fn build_kernel_f32_rw_uniform_f16_rw(
1443 device: &wgpu::Device,
1444 label: &'static str,
1445 wgsl: &str,
1446 entry_point: &'static str,
1447) -> Kernel {
1448 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1449 label: Some(label),
1450 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1451 });
1452 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1453 label: Some(label),
1454 entries: &[
1455 wgpu::BindGroupLayoutEntry {
1456 binding: 0,
1457 visibility: wgpu::ShaderStages::COMPUTE,
1458 ty: wgpu::BindingType::Buffer {
1459 ty: wgpu::BufferBindingType::Storage { read_only: false },
1460 has_dynamic_offset: false,
1461 min_binding_size: None,
1462 },
1463 count: None,
1464 },
1465 wgpu::BindGroupLayoutEntry {
1466 binding: 1,
1467 visibility: wgpu::ShaderStages::COMPUTE,
1468 ty: wgpu::BindingType::Buffer {
1469 ty: wgpu::BufferBindingType::Uniform,
1470 has_dynamic_offset: false,
1471 min_binding_size: None,
1472 },
1473 count: None,
1474 },
1475 wgpu::BindGroupLayoutEntry {
1476 binding: 2,
1477 visibility: wgpu::ShaderStages::COMPUTE,
1478 ty: wgpu::BindingType::Buffer {
1479 ty: wgpu::BufferBindingType::Storage { read_only: false },
1480 has_dynamic_offset: false,
1481 min_binding_size: None,
1482 },
1483 count: None,
1484 },
1485 ],
1486 });
1487 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1488 label: Some(label),
1489 bind_group_layouts: &[Some(&bgl)],
1490 immediate_size: 0,
1491 });
1492 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1493 label: Some(label),
1494 layout: Some(&layout),
1495 module: &module,
1496 entry_point: Some(entry_point),
1497 compilation_options: Default::default(),
1498 cache: None,
1499 });
1500 Kernel { pipeline, bgl }
1501}
1502
1503fn build_kernel_coop_f16_vk(
1505 device: &wgpu::Device,
1506 label: &'static str,
1507 wgsl: &str,
1508 entry_point: &'static str,
1509) -> Kernel {
1510 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1511 label: Some(label),
1512 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1513 });
1514 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1515 label: Some(label),
1516 entries: &[
1517 wgpu::BindGroupLayoutEntry {
1518 binding: 0,
1519 visibility: wgpu::ShaderStages::COMPUTE,
1520 ty: wgpu::BindingType::Buffer {
1521 ty: wgpu::BufferBindingType::Storage { read_only: true },
1522 has_dynamic_offset: false,
1523 min_binding_size: None,
1524 },
1525 count: None,
1526 },
1527 wgpu::BindGroupLayoutEntry {
1528 binding: 1,
1529 visibility: wgpu::ShaderStages::COMPUTE,
1530 ty: wgpu::BindingType::Buffer {
1531 ty: wgpu::BufferBindingType::Storage { read_only: false },
1532 has_dynamic_offset: false,
1533 min_binding_size: None,
1534 },
1535 count: None,
1536 },
1537 wgpu::BindGroupLayoutEntry {
1538 binding: 2,
1539 visibility: wgpu::ShaderStages::COMPUTE,
1540 ty: wgpu::BindingType::Buffer {
1541 ty: wgpu::BufferBindingType::Uniform,
1542 has_dynamic_offset: false,
1543 min_binding_size: None,
1544 },
1545 count: None,
1546 },
1547 ],
1548 });
1549 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1550 label: Some(label),
1551 bind_group_layouts: &[Some(&bgl)],
1552 immediate_size: 0,
1553 });
1554 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1555 label: Some(label),
1556 layout: Some(&layout),
1557 module: &module,
1558 entry_point: Some(entry_point),
1559 compilation_options: Default::default(),
1560 cache: None,
1561 });
1562 Kernel { pipeline, bgl }
1563}
1564
1565fn try_build_kernel_coop_f16_vk(
1566 device: &wgpu::Device,
1567 label: &'static str,
1568 wgsl: &str,
1569 entry_point: &'static str,
1570) -> Option<Kernel> {
1571 std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
1572 build_kernel_coop_f16_vk(device, label, wgsl, entry_point)
1573 }))
1574 .ok()
1575}
1576
1577fn build_kernel(
1578 device: &wgpu::Device,
1579 label: &'static str,
1580 wgsl: &str,
1581 entry_point: &'static str,
1582) -> Kernel {
1583 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
1584 label: Some(label),
1585 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
1586 });
1587 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
1588 label: Some(label),
1589 entries: &[
1590 wgpu::BindGroupLayoutEntry {
1591 binding: 0,
1592 visibility: wgpu::ShaderStages::COMPUTE,
1593 ty: wgpu::BindingType::Buffer {
1594 ty: wgpu::BufferBindingType::Storage { read_only: false },
1595 has_dynamic_offset: false,
1596 min_binding_size: None,
1597 },
1598 count: None,
1599 },
1600 wgpu::BindGroupLayoutEntry {
1601 binding: 1,
1602 visibility: wgpu::ShaderStages::COMPUTE,
1603 ty: wgpu::BindingType::Buffer {
1604 ty: wgpu::BufferBindingType::Uniform,
1605 has_dynamic_offset: false,
1606 min_binding_size: None,
1607 },
1608 count: None,
1609 },
1610 ],
1611 });
1612 let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
1613 label: Some(label),
1614 bind_group_layouts: &[Some(&bgl)],
1615 immediate_size: 0,
1616 });
1617 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
1618 label: Some(label),
1619 layout: Some(&layout),
1620 module: &module,
1621 entry_point: Some(entry_point),
1622 compilation_options: Default::default(),
1623 cache: None,
1624 });
1625 Kernel { pipeline, bgl }
1626}
1627
1628static MATMUL: OnceLock<Kernel> = OnceLock::new();
1629static MATMUL_WIDE: OnceLock<Kernel> = OnceLock::new();
1630static MATMUL_WIDE_NV: OnceLock<Kernel> = OnceLock::new();
1631static MATMUL_F16W: OnceLock<Kernel> = OnceLock::new();
1632static MATMUL_F16_COMPUTE: OnceLock<Kernel> = OnceLock::new();
1633static MATMUL_COOP16: OnceLock<Kernel> = OnceLock::new();
1634static MATMUL_COOP_F32: OnceLock<Kernel> = OnceLock::new();
1635static MATMUL_COOP_F32_PORTABLE: OnceLock<Kernel> = OnceLock::new();
1636static MATMUL_COOP_F16_VULKAN: OnceLock<Kernel> = OnceLock::new();
1637static MATMUL_COOP_F16_VULKAN_WIDEN: OnceLock<Kernel> = OnceLock::new();
1638static MATMUL_COOP_F16_VULKAN_F32ACC: OnceLock<Option<Kernel>> = OnceLock::new();
1639static MATMUL_COOP_F16_VULKAN_WIDEN_F32ACC: OnceLock<Option<Kernel>> = OnceLock::new();
1640static CAST_F32_TO_F16: OnceLock<Kernel> = OnceLock::new();
1641static BINARY: OnceLock<Kernel> = OnceLock::new();
1642static UNARY: OnceLock<Kernel> = OnceLock::new();
1643static UNARY_F16_MIRROR: OnceLock<Kernel> = OnceLock::new();
1644static COMPARE: OnceLock<Kernel> = OnceLock::new();
1645static WHEREK: OnceLock<Kernel> = OnceLock::new();
1646static FMAK: OnceLock<Kernel> = OnceLock::new();
1647static REDUCE: OnceLock<Kernel> = OnceLock::new();
1648static SOFTMAX: OnceLock<Kernel> = OnceLock::new();
1649static SOFTMAX_CROSS_ENTROPY: OnceLock<Kernel> = OnceLock::new();
1650static LAYERNORM: OnceLock<Kernel> = OnceLock::new();
1651static RMS_NORM_BWD: OnceLock<Kernel> = OnceLock::new();
1652static RMS_NORM_BWD_PARAM: OnceLock<Kernel> = OnceLock::new();
1653static LAYER_NORM_BWD_INPUT: OnceLock<Kernel> = OnceLock::new();
1654static LAYER_NORM_BWD_GAMMA: OnceLock<Kernel> = OnceLock::new();
1655static LAYER_NORM_BWD_GAMMA_REDUCE: OnceLock<Kernel> = OnceLock::new();
1656static CUMSUM_BWD: OnceLock<Kernel> = OnceLock::new();
1657static ROPE_BWD: OnceLock<Kernel> = OnceLock::new();
1658static GATHER_BWD_ZERO: OnceLock<Kernel> = OnceLock::new();
1659static GATHER_BWD_ACC: OnceLock<Kernel> = OnceLock::new();
1660static CUMSUM: OnceLock<Kernel> = OnceLock::new();
1661static FFT_GPU_RADIX2: OnceLock<Kernel> = OnceLock::new();
1662#[cfg(feature = "native-gpu-fft")]
1663static FFT_GPU_RADIX2_BIG: OnceLock<Kernel> = OnceLock::new();
1664#[cfg(feature = "native-gpu-fft")]
1665static FFT_GPU_BIG_R2: OnceLock<Kernel> = OnceLock::new();
1666#[cfg(feature = "native-gpu-fft")]
1667static FFT_GPU_BIG_R4: OnceLock<Kernel> = OnceLock::new();
1668#[cfg(feature = "native-gpu-fft")]
1669static FFT_GPU_BIG_R8: OnceLock<Kernel> = OnceLock::new();
1670#[cfg(feature = "native-gpu-fft")]
1671static FFT_GPU_R4_16K: OnceLock<Kernel> = OnceLock::new();
1672#[cfg(feature = "native-gpu-fft")]
1673static FFT_GPU_MULTIROW: OnceLock<Kernel> = OnceLock::new();
1674static FFT_GPU_BITREV: OnceLock<Kernel> = OnceLock::new();
1675static FFT_GPU_INNER: OnceLock<Kernel> = OnceLock::new();
1676static FFT_GPU_OUTER_R4: OnceLock<Kernel> = OnceLock::new();
1677static FFT_GPU_OUTER_R2: OnceLock<Kernel> = OnceLock::new();
1678static COPY: OnceLock<Kernel> = OnceLock::new();
1679static ELEMENTWISE_REGION: OnceLock<Kernel> = OnceLock::new();
1680static ELEMENTWISE_REGION_SPATIAL: OnceLock<Kernel> = OnceLock::new();
1681static TRANSPOSE: OnceLock<Kernel> = OnceLock::new();
1682static NARROW: OnceLock<Kernel> = OnceLock::new();
1683static CONCAT: OnceLock<Kernel> = OnceLock::new();
1684static GATHER: OnceLock<Kernel> = OnceLock::new();
1685static GATHER_SPLIT: OnceLock<Kernel> = OnceLock::new();
1686static GATHER_AXIS: OnceLock<Kernel> = OnceLock::new();
1687static ATTENTION: OnceLock<Kernel> = OnceLock::new();
1688static ATTENTION_BWD: OnceLock<Kernel> = OnceLock::new();
1689static ROPE: OnceLock<Kernel> = OnceLock::new();
1690static EXPAND: OnceLock<Kernel> = OnceLock::new();
1691static ARGMAX: OnceLock<Kernel> = OnceLock::new();
1692static POOL2D: OnceLock<Kernel> = OnceLock::new();
1693static CONV2D: OnceLock<Kernel> = OnceLock::new();
1694static POOL1D: OnceLock<Kernel> = OnceLock::new();
1695static POOL3D: OnceLock<Kernel> = OnceLock::new();
1696static CONV1D: OnceLock<Kernel> = OnceLock::new();
1697static CONV3D: OnceLock<Kernel> = OnceLock::new();
1698static SCATTER_ADD: OnceLock<Kernel> = OnceLock::new();
1699static TOPK: OnceLock<Kernel> = OnceLock::new();
1700static WELCH_PEAKS_GPU: OnceLock<Kernel> = OnceLock::new();
1701static UMAP_KNN: OnceLock<Kernel> = OnceLock::new();
1702static GROUPED_MATMUL: OnceLock<Kernel> = OnceLock::new();
1703static SAMPLE: OnceLock<Kernel> = OnceLock::new();
1704static SELECTIVE_SCAN: OnceLock<Kernel> = OnceLock::new();
1705static MAMBA2: OnceLock<Kernel> = OnceLock::new();
1706static GRU: OnceLock<Kernel> = OnceLock::new();
1707static RNN: OnceLock<Kernel> = OnceLock::new();
1708static DEQUANT_MATMUL: OnceLock<Kernel> = OnceLock::new();
1709static DEQUANT_GGUF: OnceLock<Kernel> = OnceLock::new();
1710static DEQUANT_GEMV_GGUF: OnceLock<Kernel> = OnceLock::new();
1711static MATMUL_BT: OnceLock<Kernel> = OnceLock::new();
1712static FUSED_RESIDUAL_LN: OnceLock<Kernel> = OnceLock::new();
1713static FUSED_RESIDUAL_LN_TEE: OnceLock<Kernel> = OnceLock::new();
1714static FUSED_RESIDUAL_RMS_NORM: OnceLock<Kernel> = OnceLock::new();
1715static MATMUL_QKV: OnceLock<Kernel> = OnceLock::new();
1716static MATMUL_QKV_COOP_F32: OnceLock<Kernel> = OnceLock::new();
1717static MATMUL_QKV_COOP_F16_VK: OnceLock<Kernel> = OnceLock::new();
1718static MATMUL_QKV_COOP_F16_VK_WIDEN: OnceLock<Kernel> = OnceLock::new();
1719static MATMUL_QKV_COOP_F16_VK_F32ACC: OnceLock<Option<Kernel>> = OnceLock::new();
1720static MATMUL_QKV_COOP_F16_VK_WIDEN_F32ACC: OnceLock<Option<Kernel>> = OnceLock::new();
1721
1722pub fn matmul_kernel(device: &wgpu::Device) -> &'static Kernel {
1723 MATMUL.get_or_init(|| build_kernel(device, "rlx-wgpu matmul", MATMUL_WGSL, "matmul"))
1724}
1725pub fn matmul_wide_kernel(device: &wgpu::Device) -> &'static Kernel {
1726 MATMUL_WIDE.get_or_init(|| {
1727 build_kernel(
1728 device,
1729 "rlx-wgpu matmul_wide",
1730 MATMUL_WIDE_WGSL,
1731 "matmul_wide",
1732 )
1733 })
1734}
1735pub fn matmul_wide_nv_kernel(device: &wgpu::Device) -> &'static Kernel {
1737 MATMUL_WIDE_NV.get_or_init(|| {
1738 build_kernel(
1739 device,
1740 "rlx-wgpu matmul_wide_nv",
1741 MATMUL_WIDE_NV_WGSL,
1742 "matmul_wide_nv",
1743 )
1744 })
1745}
1746pub fn matmul_f16w_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1751 if !device.features().contains(wgpu::Features::SHADER_F16) {
1752 return None;
1753 }
1754 Some(MATMUL_F16W.get_or_init(|| {
1755 build_kernel_3(
1756 device,
1757 "rlx-wgpu matmul_f16w",
1758 MATMUL_F16W_WGSL,
1759 "matmul_f16w",
1760 )
1761 }))
1762}
1763pub fn matmul_f16_compute_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1767 if !device.features().contains(wgpu::Features::SHADER_F16) {
1768 return None;
1769 }
1770 Some(MATMUL_F16_COMPUTE.get_or_init(|| {
1771 build_kernel_3(
1772 device,
1773 "rlx-wgpu matmul_f16_compute",
1774 MATMUL_F16_COMPUTE_WGSL,
1775 "matmul_f16_compute",
1776 )
1777 }))
1778}
1779pub fn matmul_coop16_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1785 let feats = device.features();
1786 if !feats.contains(wgpu::Features::SHADER_F16)
1787 || !feats.contains(wgpu::Features::EXPERIMENTAL_COOPERATIVE_MATRIX)
1788 {
1789 return None;
1790 }
1791 Some(MATMUL_COOP16.get_or_init(|| {
1792 build_kernel_3(
1793 device,
1794 "rlx-wgpu matmul_coop16",
1795 MATMUL_COOP16_WGSL,
1796 "matmul_coop16",
1797 )
1798 }))
1799}
1800pub fn matmul_coop_f32_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1806 let feats = device.features();
1807 if !feats.contains(wgpu::Features::EXPERIMENTAL_COOPERATIVE_MATRIX) {
1808 return None;
1809 }
1810 Some(MATMUL_COOP_F32.get_or_init(|| {
1811 build_kernel(
1812 device,
1813 "rlx-wgpu matmul_coop_f32",
1814 MATMUL_COOP_F32_WGSL,
1815 "matmul_coop_f32",
1816 )
1817 }))
1818}
1819pub fn matmul_coop_f32_portable_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1821 let feats = device.features();
1822 if !feats.contains(wgpu::Features::EXPERIMENTAL_COOPERATIVE_MATRIX)
1823 || !crate::device::coop_f32_8x8_supported()
1824 {
1825 return None;
1826 }
1827 Some(MATMUL_COOP_F32_PORTABLE.get_or_init(|| {
1828 build_kernel(
1829 device,
1830 "rlx-wgpu matmul_coop_f32_portable",
1831 MATMUL_COOP_F32_PORTABLE_WGSL,
1832 "matmul_coop_f32_portable",
1833 )
1834 }))
1835}
1836fn coop_f16_vk_device_ready(device: &wgpu::Device) -> bool {
1837 if rlx_ir::env::flag("RLX_WGPU_COOP_F16_VK_DISABLE")
1842 || !rlx_ir::env::flag("RLX_WGPU_COOP_F16_VK_ENABLE")
1843 {
1844 return false;
1845 }
1846 device.features().contains(wgpu::Features::SHADER_F16)
1847 && device
1848 .features()
1849 .contains(wgpu::Features::EXPERIMENTAL_COOPERATIVE_MATRIX)
1850 && crate::device::coop_f16_16x16_supported()
1851 && crate::device::coop_discrete_backend()
1852}
1853
1854fn coop_f16_vk_f32acc_device_ready(device: &wgpu::Device) -> bool {
1855 coop_f16_vk_device_ready(device) && crate::device::coop_f16_16x16_f32_acc_supported()
1856}
1857
1858pub fn matmul_coop_f16_vulkan_f32acc_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1859 if !coop_f16_vk_f32acc_device_ready(device) {
1860 return None;
1861 }
1862 MATMUL_COOP_F16_VULKAN_F32ACC
1863 .get_or_init(|| {
1864 try_build_kernel_coop_f16_vk(
1865 device,
1866 "rlx-wgpu matmul_coop_f16_vulkan_f32acc",
1867 MATMUL_COOP_F16_VULKAN_F32ACC_WGSL,
1868 "matmul_coop_f16_vulkan_f32acc",
1869 )
1870 })
1871 .as_ref()
1872}
1873
1874pub fn matmul_coop_f16_vulkan_widen_f32acc_kernel(
1875 device: &wgpu::Device,
1876) -> Option<&'static Kernel> {
1877 if !coop_f16_vk_f32acc_device_ready(device) {
1878 return None;
1879 }
1880 MATMUL_COOP_F16_VULKAN_WIDEN_F32ACC
1881 .get_or_init(|| {
1882 try_build_kernel_coop_f16_vk(
1883 device,
1884 "rlx-wgpu matmul_coop_f16_vulkan_widen_f32acc",
1885 MATMUL_COOP_F16_VULKAN_WIDEN_F32ACC_WGSL,
1886 "matmul_coop_f16_vulkan_widen_f32acc",
1887 )
1888 })
1889 .as_ref()
1890}
1891
1892fn coop_f16_vk_use_f32acc(device: &wgpu::Device) -> bool {
1893 !rlx_ir::env::flag("RLX_WGPU_COOP_F16_VK_NO_F32ACC")
1894 && matmul_coop_f16_vulkan_f32acc_kernel(device).is_some()
1895}
1896
1897fn pick_coop_f16_vk_matmul(
1898 device: &wgpu::Device,
1899 n: u32,
1900 loadt: fn(&wgpu::Device) -> Option<&'static Kernel>,
1901 loadt_f32acc: fn(&wgpu::Device) -> Option<&'static Kernel>,
1902 widen: fn(&wgpu::Device) -> Option<&'static Kernel>,
1903 widen_f32acc: fn(&wgpu::Device) -> Option<&'static Kernel>,
1904) -> Option<&'static Kernel> {
1905 if coop_f16_vk_use_f32acc(device) {
1906 if coop_f16_vk_widen_b_load(n) {
1907 return widen_f32acc(device).or_else(|| loadt_f32acc(device));
1908 }
1909 return loadt_f32acc(device);
1910 }
1911 if coop_f16_vk_widen_b_load(n) {
1912 widen(device).or_else(|| loadt(device))
1913 } else {
1914 loadt(device)
1915 }
1916}
1917
1918pub fn matmul_coop_f16_vulkan_active_kernel(
1920 device: &wgpu::Device,
1921 n: u32,
1922) -> Option<&'static Kernel> {
1923 pick_coop_f16_vk_matmul(
1924 device,
1925 n,
1926 matmul_coop_f16_vulkan_kernel,
1927 matmul_coop_f16_vulkan_f32acc_kernel,
1928 matmul_coop_f16_vulkan_widen_kernel,
1929 matmul_coop_f16_vulkan_widen_f32acc_kernel,
1930 )
1931}
1932
1933pub fn matmul_coop_f16_vulkan_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1934 if !coop_f16_vk_device_ready(device) {
1935 return None;
1936 }
1937 Some(MATMUL_COOP_F16_VULKAN.get_or_init(|| {
1938 build_kernel_coop_f16_vk(
1939 device,
1940 "rlx-wgpu matmul_coop_f16_vulkan",
1941 MATMUL_COOP_F16_VULKAN_WGSL,
1942 "matmul_coop_f16_vulkan",
1943 )
1944 }))
1945}
1946pub const COOP_F16_VK_WIDEN_N: u32 = 768;
1948
1949pub fn coop_f16_vk_widen_b_load(n: u32) -> bool {
1951 n > COOP_F16_VK_WIDEN_N && !rlx_ir::env::flag("RLX_WGPU_COOP_F16_VK_LOAD_T")
1952}
1953
1954pub fn matmul_coop_f16_vulkan_widen_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1955 if !coop_f16_vk_device_ready(device) {
1956 return None;
1957 }
1958 Some(MATMUL_COOP_F16_VULKAN_WIDEN.get_or_init(|| {
1959 build_kernel_coop_f16_vk(
1960 device,
1961 "rlx-wgpu matmul_coop_f16_vulkan_widen",
1962 MATMUL_COOP_F16_VULKAN_WIDEN_WGSL,
1963 "matmul_coop_f16_vulkan_widen",
1964 )
1965 }))
1966}
1967pub fn coop_f16_vk_f32acc_available(device: &wgpu::Device) -> bool {
1968 matmul_coop_f16_vulkan_f32acc_kernel(device).is_some()
1969}
1970pub fn matmul_coop_f32_active_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1972 match crate::device::wgpu_device().map(|d| d.backend) {
1973 Some(wgpu::Backend::Metal) => matmul_coop_f32_kernel(device),
1974 Some(wgpu::Backend::Vulkan) | Some(wgpu::Backend::Dx12) => {
1975 matmul_coop_f32_portable_kernel(device)
1976 }
1977 _ => None,
1978 }
1979}
1980pub fn matmul_wide_active_kernel(device: &wgpu::Device) -> &'static Kernel {
1982 match crate::device::wgpu_device().map(|d| d.backend) {
1983 Some(wgpu::Backend::Vulkan) | Some(wgpu::Backend::Dx12) => matmul_wide_nv_kernel(device),
1984 _ => matmul_wide_kernel(device),
1985 }
1986}
1987pub fn cast_f32_to_f16_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
1992 if !device.features().contains(wgpu::Features::SHADER_F16) {
1993 return None;
1994 }
1995 Some(CAST_F32_TO_F16.get_or_init(|| {
1996 build_kernel_cast_f32_to_f16(
1997 device,
1998 "rlx-wgpu cast_f32_to_f16",
1999 CAST_F32_TO_F16_WGSL,
2000 "cast_f32_to_f16",
2001 )
2002 }))
2003}
2004pub fn binary_kernel(device: &wgpu::Device) -> &'static Kernel {
2005 BINARY.get_or_init(|| build_kernel(device, "rlx-wgpu binary", BINARY_WGSL, "binary"))
2006}
2007pub fn unary_kernel(device: &wgpu::Device) -> &'static Kernel {
2008 UNARY.get_or_init(|| build_kernel(device, "rlx-wgpu unary", UNARY_WGSL, "unary"))
2009}
2010pub fn unary_f16_mirror_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
2011 if !device.features().contains(wgpu::Features::SHADER_F16) {
2012 return None;
2013 }
2014 Some(UNARY_F16_MIRROR.get_or_init(|| {
2015 build_kernel_f32_rw_uniform_f16_rw(
2016 device,
2017 "rlx-wgpu unary_f16_mirror",
2018 UNARY_F16_MIRROR_WGSL,
2019 "unary_f16_mirror",
2020 )
2021 }))
2022}
2023pub fn compare_kernel(device: &wgpu::Device) -> &'static Kernel {
2024 COMPARE.get_or_init(|| build_kernel(device, "rlx-wgpu compare", COMPARE_WGSL, "compare"))
2025}
2026pub fn where_kernel(device: &wgpu::Device) -> &'static Kernel {
2027 WHEREK.get_or_init(|| build_kernel(device, "rlx-wgpu where", WHERE_WGSL, "where_select"))
2028}
2029pub fn fma_kernel(device: &wgpu::Device) -> &'static Kernel {
2030 FMAK.get_or_init(|| build_kernel(device, "rlx-wgpu fma", FMA_WGSL, "fma_main"))
2031}
2032pub fn reduce_kernel(device: &wgpu::Device) -> &'static Kernel {
2033 REDUCE.get_or_init(|| build_kernel(device, "rlx-wgpu reduce", REDUCE_WGSL, "reduce"))
2034}
2035pub fn softmax_kernel(device: &wgpu::Device) -> &'static Kernel {
2036 SOFTMAX.get_or_init(|| build_kernel(device, "rlx-wgpu softmax", SOFTMAX_WGSL, "softmax"))
2037}
2038pub fn softmax_cross_entropy_kernel(device: &wgpu::Device) -> &'static Kernel {
2039 SOFTMAX_CROSS_ENTROPY.get_or_init(|| {
2040 build_kernel(
2041 device,
2042 "rlx-wgpu softmax_cross_entropy",
2043 SOFTMAX_CROSS_ENTROPY_WGSL,
2044 "softmax_cross_entropy",
2045 )
2046 })
2047}
2048pub fn layernorm_kernel(device: &wgpu::Device) -> &'static Kernel {
2049 LAYERNORM.get_or_init(|| build_kernel(device, "rlx-wgpu layernorm", LAYERNORM_WGSL, "norm"))
2050}
2051pub fn rms_norm_backward_kernel(device: &wgpu::Device) -> &'static Kernel {
2052 RMS_NORM_BWD.get_or_init(|| {
2053 build_kernel(
2054 device,
2055 "rlx-wgpu rms_norm_bwd",
2056 RMS_NORM_BWD_WGSL,
2057 "rms_norm_bwd",
2058 )
2059 })
2060}
2061pub fn rms_norm_backward_param_kernel(device: &wgpu::Device) -> &'static Kernel {
2062 RMS_NORM_BWD_PARAM.get_or_init(|| {
2063 build_kernel(
2064 device,
2065 "rlx-wgpu rms_norm_bwd_param",
2066 RMS_NORM_BWD_WGSL,
2067 "rms_norm_bwd_param",
2068 )
2069 })
2070}
2071pub fn layer_norm_backward_input_kernel(device: &wgpu::Device) -> &'static Kernel {
2072 LAYER_NORM_BWD_INPUT.get_or_init(|| {
2073 build_kernel(
2074 device,
2075 "rlx-wgpu layer_norm_bwd_input",
2076 LAYER_NORM_BWD_WGSL,
2077 "layer_norm_bwd_input",
2078 )
2079 })
2080}
2081pub fn layer_norm_backward_gamma_partial_kernel(device: &wgpu::Device) -> &'static Kernel {
2082 LAYER_NORM_BWD_GAMMA.get_or_init(|| {
2083 build_kernel(
2084 device,
2085 "rlx-wgpu layer_norm_bwd_gamma_partial",
2086 LAYER_NORM_BWD_WGSL,
2087 "layer_norm_bwd_gamma_partial",
2088 )
2089 })
2090}
2091
2092pub fn layer_norm_backward_gamma_reduce_kernel(device: &wgpu::Device) -> &'static Kernel {
2093 LAYER_NORM_BWD_GAMMA_REDUCE.get_or_init(|| {
2094 build_kernel(
2095 device,
2096 "rlx-wgpu layer_norm_bwd_gamma_reduce",
2097 LAYER_NORM_BWD_WGSL,
2098 "layer_norm_bwd_gamma_reduce",
2099 )
2100 })
2101}
2102pub fn cumsum_backward_kernel(device: &wgpu::Device) -> &'static Kernel {
2103 CUMSUM_BWD
2104 .get_or_init(|| build_kernel(device, "rlx-wgpu cumsum_bwd", CUMSUM_BWD_WGSL, "cumsum_bwd"))
2105}
2106pub fn rope_backward_kernel(device: &wgpu::Device) -> &'static Kernel {
2107 ROPE_BWD.get_or_init(|| build_kernel(device, "rlx-wgpu rope_bwd", ROPE_BWD_WGSL, "rope_bwd"))
2108}
2109pub fn gather_backward_zero_kernel(device: &wgpu::Device) -> &'static Kernel {
2110 GATHER_BWD_ZERO.get_or_init(|| {
2111 build_kernel(
2112 device,
2113 "rlx-wgpu gather_bwd_zero",
2114 GATHER_BWD_WGSL,
2115 "gather_bwd_zero",
2116 )
2117 })
2118}
2119pub fn gather_backward_acc_kernel(device: &wgpu::Device) -> &'static Kernel {
2120 GATHER_BWD_ACC.get_or_init(|| {
2121 build_kernel(
2122 device,
2123 "rlx-wgpu gather_bwd_acc",
2124 GATHER_BWD_WGSL,
2125 "gather_bwd_acc",
2126 )
2127 })
2128}
2129pub fn cumsum_kernel(device: &wgpu::Device) -> &'static Kernel {
2130 CUMSUM.get_or_init(|| build_kernel(device, "rlx-wgpu cumsum", CUMSUM_WGSL, "cumsum"))
2131}
2132pub fn fft_gpu_radix2_full_kernel(device: &wgpu::Device) -> &'static Kernel {
2133 FFT_GPU_RADIX2.get_or_init(|| {
2134 build_kernel(
2135 device,
2136 "rlx-wgpu fft_radix2_full",
2137 FFT_GPU_WGSL,
2138 "fft_radix2_full",
2139 )
2140 })
2141}
2142#[cfg(feature = "native-gpu-fft")]
2144pub fn fft_gpu_radix2_full_big_kernel(device: &wgpu::Device) -> &'static Kernel {
2145 FFT_GPU_RADIX2_BIG.get_or_init(|| {
2146 build_kernel(
2147 device,
2148 "rlx-wgpu fft_radix2_full_big",
2149 FFT_GPU_WGSL,
2150 "fft_radix2_full_big",
2151 )
2152 })
2153}
2154#[cfg(feature = "native-gpu-fft")]
2158pub fn fft_gpu_big_r2_kernel(device: &wgpu::Device) -> &'static Kernel {
2159 FFT_GPU_BIG_R2.get_or_init(|| {
2160 build_kernel(
2161 device,
2162 "rlx-wgpu fft_radix2_big",
2163 FFT_GPU_BIG_WGSL,
2164 "fft_radix2_big",
2165 )
2166 })
2167}
2168#[cfg(feature = "native-gpu-fft")]
2169pub fn fft_gpu_big_r4_kernel(device: &wgpu::Device) -> &'static Kernel {
2170 FFT_GPU_BIG_R4.get_or_init(|| {
2171 build_kernel(
2172 device,
2173 "rlx-wgpu fft_radix4_big",
2174 FFT_GPU_BIG_WGSL,
2175 "fft_radix4_big",
2176 )
2177 })
2178}
2179#[cfg(feature = "native-gpu-fft")]
2180pub fn fft_gpu_big_r8_kernel(device: &wgpu::Device) -> &'static Kernel {
2181 FFT_GPU_BIG_R8.get_or_init(|| {
2182 build_kernel(
2183 device,
2184 "rlx-wgpu fft_radix8_big",
2185 FFT_GPU_BIG_WGSL,
2186 "fft_radix8_big",
2187 )
2188 })
2189}
2190#[cfg(feature = "native-gpu-fft")]
2192pub fn fft_gpu_r4_16k_kernel(device: &wgpu::Device) -> &'static Kernel {
2193 FFT_GPU_R4_16K.get_or_init(|| {
2194 build_kernel(
2195 device,
2196 "rlx-wgpu fft_radix4_16k",
2197 FFT_GPU_R4_16K_WGSL,
2198 "fft_radix4_16k",
2199 )
2200 })
2201}
2202#[cfg(feature = "native-gpu-fft")]
2204pub fn fft_gpu_multirow_kernel(device: &wgpu::Device) -> &'static Kernel {
2205 FFT_GPU_MULTIROW.get_or_init(|| {
2206 build_kernel(
2207 device,
2208 "rlx-wgpu fft_multirow",
2209 FFT_GPU_MULTIROW_WGSL,
2210 "fft_multirow",
2211 )
2212 })
2213}
2214pub fn fft_gpu_bit_reverse_kernel(device: &wgpu::Device) -> &'static Kernel {
2215 FFT_GPU_BITREV.get_or_init(|| {
2216 build_kernel(
2217 device,
2218 "rlx-wgpu fft_bit_reverse",
2219 FFT_GPU_WGSL,
2220 "fft_bit_reverse",
2221 )
2222 })
2223}
2224pub fn fft_gpu_inner_kernel(device: &wgpu::Device) -> &'static Kernel {
2225 FFT_GPU_INNER
2226 .get_or_init(|| build_kernel(device, "rlx-wgpu fft_inner", FFT_GPU_WGSL, "fft_inner"))
2227}
2228pub fn fft_gpu_outer_r4_kernel(device: &wgpu::Device) -> &'static Kernel {
2229 FFT_GPU_OUTER_R4.get_or_init(|| {
2230 build_kernel(
2231 device,
2232 "rlx-wgpu fft_outer_r4",
2233 FFT_GPU_WGSL,
2234 "fft_outer_r4",
2235 )
2236 })
2237}
2238pub fn fft_gpu_outer_r2_kernel(device: &wgpu::Device) -> &'static Kernel {
2239 FFT_GPU_OUTER_R2.get_or_init(|| {
2240 build_kernel(
2241 device,
2242 "rlx-wgpu fft_outer_r2",
2243 FFT_GPU_WGSL,
2244 "fft_outer_r2",
2245 )
2246 })
2247}
2248pub fn copy_kernel(device: &wgpu::Device) -> &'static Kernel {
2249 COPY.get_or_init(|| build_kernel(device, "rlx-wgpu copy", COPY_WGSL, "copy"))
2250}
2251pub fn elementwise_region_kernel(device: &wgpu::Device) -> &'static Kernel {
2252 ELEMENTWISE_REGION.get_or_init(|| {
2257 build_kernel_region(
2258 device,
2259 "rlx-wgpu elementwise_region",
2260 ELEMENTWISE_REGION_WGSL,
2261 "elementwise_region",
2262 )
2263 })
2264}
2265
2266pub fn elementwise_region_spatial_kernel(device: &wgpu::Device) -> &'static Kernel {
2267 ELEMENTWISE_REGION_SPATIAL.get_or_init(|| {
2268 build_kernel_region(
2269 device,
2270 "rlx-wgpu elementwise_region_spatial",
2271 ELEMENTWISE_REGION_WGSL,
2272 "elementwise_region_spatial",
2273 )
2274 })
2275}
2276
2277static BATCH_ELEMENTWISE_REGION: std::sync::OnceLock<Kernel> = std::sync::OnceLock::new();
2278
2279pub fn batch_elementwise_region_kernel(device: &wgpu::Device) -> &'static Kernel {
2280 BATCH_ELEMENTWISE_REGION.get_or_init(|| {
2281 build_kernel_region(
2282 device,
2283 "rlx-wgpu batch_elementwise_region",
2284 ELEMENTWISE_REGION_WGSL,
2285 "batch_elementwise_region",
2286 )
2287 })
2288}
2289
2290fn build_kernel_region(
2291 device: &wgpu::Device,
2292 label: &'static str,
2293 wgsl: &str,
2294 entry_point: &'static str,
2295) -> Kernel {
2296 let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
2297 label: Some(label),
2298 source: wgpu::ShaderSource::Wgsl(wgsl.into()),
2299 });
2300 let bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
2301 label: Some(label),
2302 entries: &[
2303 wgpu::BindGroupLayoutEntry {
2304 binding: 0,
2305 visibility: wgpu::ShaderStages::COMPUTE,
2306 ty: wgpu::BindingType::Buffer {
2307 ty: wgpu::BufferBindingType::Storage { read_only: false },
2308 has_dynamic_offset: false,
2309 min_binding_size: None,
2310 },
2311 count: None,
2312 },
2313 wgpu::BindGroupLayoutEntry {
2314 binding: 1,
2315 visibility: wgpu::ShaderStages::COMPUTE,
2316 ty: wgpu::BindingType::Buffer {
2317 ty: wgpu::BufferBindingType::Storage { read_only: true },
2319 has_dynamic_offset: false,
2320 min_binding_size: None,
2321 },
2322 count: None,
2323 },
2324 ],
2325 });
2326 let pl = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
2327 label: Some(label),
2328 bind_group_layouts: &[Some(&bgl)],
2329 immediate_size: 0,
2330 });
2331 let pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
2332 label: Some(label),
2333 layout: Some(&pl),
2334 module: &module,
2335 entry_point: Some(entry_point),
2336 compilation_options: Default::default(),
2337 cache: None,
2338 });
2339 Kernel { pipeline, bgl }
2340}
2341pub fn transpose_kernel(device: &wgpu::Device) -> &'static Kernel {
2342 TRANSPOSE
2343 .get_or_init(|| build_kernel_3(device, "rlx-wgpu transpose", TRANSPOSE_WGSL, "transpose"))
2344}
2345pub fn narrow_kernel(device: &wgpu::Device) -> &'static Kernel {
2346 NARROW.get_or_init(|| build_kernel(device, "rlx-wgpu narrow", NARROW_WGSL, "narrow"))
2347}
2348pub fn concat_kernel(device: &wgpu::Device) -> &'static Kernel {
2349 CONCAT.get_or_init(|| build_kernel(device, "rlx-wgpu concat", CONCAT_WGSL, "concat"))
2350}
2351pub fn gather_kernel(device: &wgpu::Device) -> &'static Kernel {
2352 GATHER.get_or_init(|| build_kernel(device, "rlx-wgpu gather", GATHER_WGSL, "gather"))
2353}
2354pub fn gather_split_kernel(device: &wgpu::Device) -> &'static Kernel {
2358 GATHER_SPLIT.get_or_init(|| {
2359 build_kernel_ro_u_ro_rw(device, "rlx-wgpu gather_split", GATHER_SPLIT_WGSL, "gather")
2360 })
2361}
2362pub fn gather_axis_kernel(device: &wgpu::Device) -> &'static Kernel {
2363 GATHER_AXIS.get_or_init(|| {
2364 build_kernel(
2365 device,
2366 "rlx-wgpu gather_axis",
2367 GATHER_AXIS_WGSL,
2368 "gather_axis",
2369 )
2370 })
2371}
2372pub fn attention_kernel(device: &wgpu::Device) -> &'static Kernel {
2373 ATTENTION
2374 .get_or_init(|| build_kernel(device, "rlx-wgpu attention", ATTENTION_WGSL, "attention"))
2375}
2376pub fn attention_bwd_kernel(device: &wgpu::Device) -> &'static Kernel {
2377 ATTENTION_BWD.get_or_init(|| {
2378 build_kernel(
2379 device,
2380 "rlx-wgpu attention_bwd",
2381 ATTENTION_BWD_WGSL,
2382 "attention_bwd",
2383 )
2384 })
2385}
2386pub fn rope_kernel(device: &wgpu::Device) -> &'static Kernel {
2387 ROPE.get_or_init(|| build_kernel(device, "rlx-wgpu rope", ROPE_WGSL, "rope"))
2388}
2389pub fn expand_kernel(device: &wgpu::Device) -> &'static Kernel {
2390 EXPAND.get_or_init(|| build_kernel_3(device, "rlx-wgpu expand", EXPAND_WGSL, "expand"))
2391}
2392pub fn argmax_kernel(device: &wgpu::Device) -> &'static Kernel {
2393 ARGMAX.get_or_init(|| build_kernel(device, "rlx-wgpu argmax", ARGMAX_WGSL, "argmax"))
2394}
2395pub fn pool2d_kernel(device: &wgpu::Device) -> &'static Kernel {
2396 POOL2D.get_or_init(|| build_kernel(device, "rlx-wgpu pool2d", POOL2D_WGSL, "pool2d"))
2397}
2398pub fn conv2d_kernel(device: &wgpu::Device) -> &'static Kernel {
2399 CONV2D.get_or_init(|| build_kernel(device, "rlx-wgpu conv2d", CONV2D_WGSL, "conv2d"))
2400}
2401pub fn pool1d_kernel(device: &wgpu::Device) -> &'static Kernel {
2402 POOL1D.get_or_init(|| build_kernel(device, "rlx-wgpu pool1d", POOL1D_WGSL, "pool1d"))
2403}
2404pub fn pool3d_kernel(device: &wgpu::Device) -> &'static Kernel {
2405 POOL3D.get_or_init(|| build_kernel(device, "rlx-wgpu pool3d", POOL3D_WGSL, "pool3d"))
2406}
2407pub fn conv1d_kernel(device: &wgpu::Device) -> &'static Kernel {
2408 CONV1D.get_or_init(|| build_kernel(device, "rlx-wgpu conv1d", CONV1D_WGSL, "conv1d"))
2409}
2410pub fn conv3d_kernel(device: &wgpu::Device) -> &'static Kernel {
2411 CONV3D.get_or_init(|| build_kernel(device, "rlx-wgpu conv3d", CONV3D_WGSL, "conv3d"))
2412}
2413pub fn scatter_add_kernel(device: &wgpu::Device) -> &'static Kernel {
2414 SCATTER_ADD.get_or_init(|| {
2415 build_kernel(
2416 device,
2417 "rlx-wgpu scatter_add",
2418 SCATTER_ADD_WGSL,
2419 "scatter_add",
2420 )
2421 })
2422}
2423pub fn topk_kernel(device: &wgpu::Device) -> &'static Kernel {
2424 TOPK.get_or_init(|| build_kernel(device, "rlx-wgpu topk", TOPK_WGSL, "topk"))
2425}
2426pub fn welch_peaks_gpu_kernel(device: &wgpu::Device) -> &'static Kernel {
2427 WELCH_PEAKS_GPU.get_or_init(|| {
2428 build_kernel(
2429 device,
2430 "rlx-wgpu welch_peaks_gpu",
2431 WELCH_PEAKS_GPU_WGSL,
2432 "welch_peaks_gpu",
2433 )
2434 })
2435}
2436pub fn umap_knn_kernel(device: &wgpu::Device) -> &'static Kernel {
2437 UMAP_KNN.get_or_init(|| build_kernel(device, "rlx-wgpu umap_knn", UMAP_KNN_WGSL, "umap_knn"))
2438}
2439pub fn grouped_matmul_kernel(device: &wgpu::Device) -> &'static Kernel {
2440 GROUPED_MATMUL.get_or_init(|| {
2441 build_kernel(
2442 device,
2443 "rlx-wgpu grouped_matmul",
2444 GROUPED_MATMUL_WGSL,
2445 "grouped_matmul",
2446 )
2447 })
2448}
2449pub fn sample_kernel(device: &wgpu::Device) -> &'static Kernel {
2450 SAMPLE.get_or_init(|| build_kernel(device, "rlx-wgpu sample", SAMPLE_WGSL, "sample"))
2451}
2452pub fn selective_scan_kernel(device: &wgpu::Device) -> &'static Kernel {
2453 SELECTIVE_SCAN.get_or_init(|| {
2454 build_kernel(
2455 device,
2456 "rlx-wgpu selective_scan",
2457 SELECTIVE_SCAN_WGSL,
2458 "selective_scan",
2459 )
2460 })
2461}
2462pub fn mamba2_kernel(device: &wgpu::Device) -> &'static Kernel {
2463 MAMBA2.get_or_init(|| build_kernel(device, "rlx-wgpu mamba2", MAMBA2_WGSL, "mamba2"))
2464}
2465pub fn gru_kernel(device: &wgpu::Device) -> &'static Kernel {
2466 GRU.get_or_init(|| build_kernel(device, "rlx-wgpu gru", GRU_WGSL, "gru"))
2467}
2468pub fn rnn_kernel(device: &wgpu::Device) -> &'static Kernel {
2469 RNN.get_or_init(|| build_kernel(device, "rlx-wgpu rnn", RNN_WGSL, "rnn"))
2470}
2471pub fn dequant_matmul_kernel(device: &wgpu::Device) -> &'static Kernel {
2472 DEQUANT_MATMUL.get_or_init(|| {
2473 build_kernel(
2474 device,
2475 "rlx-wgpu dequant_matmul",
2476 DEQUANT_MATMUL_WGSL,
2477 "dequant_matmul",
2478 )
2479 })
2480}
2481pub fn dequant_gguf_kernel(device: &wgpu::Device) -> &'static Kernel {
2482 DEQUANT_GGUF.get_or_init(|| {
2483 build_kernel_3(
2484 device,
2485 "rlx-wgpu dequant_gguf",
2486 DEQUANT_GGUF_WGSL,
2487 "dequant_gguf",
2488 )
2489 })
2490}
2491pub fn matmul_bt_kernel(device: &wgpu::Device) -> &'static Kernel {
2492 MATMUL_BT.get_or_init(|| build_kernel(device, "rlx-wgpu matmul_bt", MATMUL_WGSL, "matmul_bt"))
2493}
2494pub fn dequant_gemv_gguf_kernel(device: &wgpu::Device) -> &'static Kernel {
2495 DEQUANT_GEMV_GGUF.get_or_init(|| {
2496 build_kernel_ro_u_ro_rw(
2497 device,
2498 "rlx-wgpu dequant_gemv_gguf",
2499 DEQUANT_GEMV_GGUF_WGSL,
2500 "dequant_gemv",
2501 )
2502 })
2503}
2504pub fn fused_residual_ln_kernel(device: &wgpu::Device) -> &'static Kernel {
2505 FUSED_RESIDUAL_LN.get_or_init(|| {
2506 build_kernel(
2507 device,
2508 "rlx-wgpu fused_residual_ln",
2509 FUSED_RESIDUAL_LN_WGSL,
2510 "fused_residual_ln",
2511 )
2512 })
2513}
2514pub fn fused_residual_ln_tee_kernel(device: &wgpu::Device) -> &'static Kernel {
2515 FUSED_RESIDUAL_LN_TEE.get_or_init(|| {
2516 build_kernel(
2517 device,
2518 "rlx-wgpu fused_residual_ln_tee",
2519 FUSED_RESIDUAL_LN_TEE_WGSL,
2520 "fused_residual_ln_tee",
2521 )
2522 })
2523}
2524pub fn fused_residual_rms_norm_kernel(device: &wgpu::Device) -> &'static Kernel {
2525 FUSED_RESIDUAL_RMS_NORM.get_or_init(|| {
2526 build_kernel(
2527 device,
2528 "rlx-wgpu fused_residual_rms_norm",
2529 FUSED_RESIDUAL_RMS_NORM_WGSL,
2530 "fused_residual_rms_norm",
2531 )
2532 })
2533}
2534pub fn matmul_qkv_kernel(device: &wgpu::Device) -> &'static Kernel {
2535 MATMUL_QKV
2536 .get_or_init(|| build_kernel(device, "rlx-wgpu matmul_qkv", MATMUL_QKV_WGSL, "matmul_qkv"))
2537}
2538pub fn matmul_qkv_coop_f32_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
2539 if !device
2540 .features()
2541 .contains(wgpu::Features::EXPERIMENTAL_COOPERATIVE_MATRIX)
2542 {
2543 return None;
2544 }
2545 Some(MATMUL_QKV_COOP_F32.get_or_init(|| {
2546 build_kernel(
2547 device,
2548 "rlx-wgpu matmul_qkv_coop_f32",
2549 MATMUL_QKV_COOP_F32_WGSL,
2550 "matmul_qkv_coop_f32",
2551 )
2552 }))
2553}
2554pub fn matmul_qkv_coop_f16_vk_f32acc_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
2555 if !coop_f16_vk_f32acc_device_ready(device) {
2556 return None;
2557 }
2558 MATMUL_QKV_COOP_F16_VK_F32ACC
2559 .get_or_init(|| {
2560 try_build_kernel_coop_f16_vk(
2561 device,
2562 "rlx-wgpu matmul_qkv_coop_f16_vk_f32acc",
2563 MATMUL_QKV_COOP_F16_VK_F32ACC_WGSL,
2564 "matmul_qkv_coop_f16_vk_f32acc",
2565 )
2566 })
2567 .as_ref()
2568}
2569
2570pub fn matmul_qkv_coop_f16_vk_widen_f32acc_kernel(
2571 device: &wgpu::Device,
2572) -> Option<&'static Kernel> {
2573 if !coop_f16_vk_f32acc_device_ready(device) {
2574 return None;
2575 }
2576 MATMUL_QKV_COOP_F16_VK_WIDEN_F32ACC
2577 .get_or_init(|| {
2578 try_build_kernel_coop_f16_vk(
2579 device,
2580 "rlx-wgpu matmul_qkv_coop_f16_vk_widen_f32acc",
2581 MATMUL_QKV_COOP_F16_VK_WIDEN_F32ACC_WGSL,
2582 "matmul_qkv_coop_f16_vk_widen_f32acc",
2583 )
2584 })
2585 .as_ref()
2586}
2587
2588pub fn matmul_qkv_coop_f16_vk_active_kernel(
2589 device: &wgpu::Device,
2590 n: u32,
2591) -> Option<&'static Kernel> {
2592 pick_coop_f16_vk_matmul(
2593 device,
2594 n,
2595 matmul_qkv_coop_f16_vk_kernel,
2596 matmul_qkv_coop_f16_vk_f32acc_kernel,
2597 matmul_qkv_coop_f16_vk_widen_kernel,
2598 matmul_qkv_coop_f16_vk_widen_f32acc_kernel,
2599 )
2600}
2601
2602pub fn matmul_qkv_coop_f16_vk_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
2603 if !coop_f16_vk_device_ready(device) {
2604 return None;
2605 }
2606 Some(MATMUL_QKV_COOP_F16_VK.get_or_init(|| {
2607 build_kernel_coop_f16_vk(
2608 device,
2609 "rlx-wgpu matmul_qkv_coop_f16_vk",
2610 MATMUL_QKV_COOP_F16_VK_WGSL,
2611 "matmul_qkv_coop_f16_vk",
2612 )
2613 }))
2614}
2615pub fn matmul_qkv_coop_f16_vk_widen_kernel(device: &wgpu::Device) -> Option<&'static Kernel> {
2616 if !coop_f16_vk_device_ready(device) {
2617 return None;
2618 }
2619 Some(MATMUL_QKV_COOP_F16_VK_WIDEN.get_or_init(|| {
2620 build_kernel_coop_f16_vk(
2621 device,
2622 "rlx-wgpu matmul_qkv_coop_f16_vk_widen",
2623 MATMUL_QKV_COOP_F16_VK_WIDEN_WGSL,
2624 "matmul_qkv_coop_f16_vk_widen",
2625 )
2626 }))
2627}