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