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