1use anyhow::Result;
12use metrale_gpu_runtime::gpu::{GpuBackend, KernelHandle};
13
14use super::{DenseFfnLayer, DenseFfnWeights, FfnActivation, batch16_decode, gateup_fused, m16_tc};
15use crate::layers::ops;
16use crate::layers::w4a16_gemv_tiers::W4a16BatchmTiers;
17
18impl DenseFfnLayer {
19 pub fn new_with_activation(
20 weights: DenseFfnWeights,
21 activation: FfnActivation,
22 gpu: &dyn GpuBackend,
23 ) -> Result<Self> {
24 let act_mul = match activation {
25 FfnActivation::SiLU => gpu.kernel("moe_silu_mul", "moe_silu_mul")?,
26 FfnActivation::GeLU => gpu.kernel("gelu", "gelu_mul")?,
27 };
28 let gateup_fused = gateup_fused::ffn_gateup_fused();
31 let dense_gemv_bf16_k = super::try_kernel(gpu, "gemv", "dense_gemv_bf16");
34 let dense_gemm_bf16_k = super::try_kernel(gpu, "gemm", "dense_gemm_bf16");
35 let dense_gemm_tc_k = super::try_kernel(gpu, "gemm_tc", "dense_gemm_tc");
36
37 let layer = Self {
38 weights,
39 activation,
40 w4a16_gemv: gpu.kernel("w4a16_gemv", "w4a16_gemv")?,
41 w4a16_gemv_sw: super::try_kernel(gpu, "w4a16_gemv", "w4a16_gemv_sw"),
42 w4a16_gemv_dual: gpu.kernel("w4a16_gemv_fused", "w4a16_gemv_dual")?,
43 w4a16_gemv_silu_input: gpu.kernel("w4a16_gemv_fused", "w4a16_gemv_silu_input")?,
44 w4a16_gemv_dual_sw: super::try_kernel(gpu, "w4a16_gemv_fused", "w4a16_gemv_dual_sw"),
45 w4a16_gemv_silu_input_sw: super::try_kernel(
46 gpu,
47 "w4a16_gemv_fused",
48 "w4a16_gemv_silu_input_sw",
49 ),
50 w4a16_gemv_dual_batch2: gpu.kernel("w4a16_gemv", "w4a16_gemv_dual_batch2")?,
51 w4a16_gemv_dual_batch3: gpu.kernel("w4a16_gemv", "w4a16_gemv_dual_batch3")?,
52 w4a16_gemv_batch2: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch2")?,
53 w4a16_gemv_batch3: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch3")?,
54 w4a16_batchm: W4a16BatchmTiers::resolve(gpu),
55 w4a16_gemm: gpu.kernel("w4a16", "w4a16_gemm")?,
56 w4a16_gemm_t_m128_k: super::try_kernel(gpu, "w4a16", "w4a16_gemm_t_m128"),
57 w4a16_gemm_t_m128_v2_k: super::w4a16_v2_kernel(gpu),
58 w4a16_gemm_t_m128_bf16_k: super::try_kernel(gpu, "w4a16", "w4a16_gemm_t_m128_bf16"),
59 w4a16_gemm_t_m128_bf16_v2_k: super::try_kernel(
60 gpu,
61 "w4a16",
62 "w4a16_gemm_t_m128_bf16_v2",
63 ),
64 w4a16_gemm_t_k: super::tgemm_kernel(gpu),
65 int8_faith2_k: super::try_kernel(gpu, "w4a16", "int8_gemm_faith2"),
66 int8_faith5_k: super::try_kernel(gpu, "w4a16", "int8_gemm_i32acc"),
67 requant_w_int8_k: super::try_kernel(gpu, "w4a16", "requant_w_nvfp4_int8"),
68 requant_a_int8_k: super::try_kernel(gpu, "w4a16", "requant_a_bf16_int8"),
69 int8_gate: std::sync::OnceLock::new(),
70 int8_up: std::sync::OnceLock::new(),
71 int8_down: std::sync::OnceLock::new(),
72 w4a4_gemm_k: super::try_kernel(gpu, "w4a4", "w4a4_gemm"),
73 quantize_nvfp4_k: super::try_kernel(gpu, "quantize_nvfp4", "quantize_bf16_to_nvfp4"),
74 q4k_mmq_nc_k: super::try_kernel(gpu, "q4k_mmq", "metrale_q4k_mmq128_nc"),
75 q4k_mmq_wc_k: super::try_kernel(gpu, "q4k_mmq", "metrale_q4k_mmq128_wc"),
76 q4k_quant_act_k: super::try_kernel(gpu, "q4k_mmq", "metrale_q8_1_quantize_ds4_bf16"),
77 q4k_quant_w_k: super::try_kernel(gpu, "q4k_quantize", "q4k_quantize"),
78 dequant_nvfp4_bf16_k: super::try_kernel(
79 gpu,
80 "dequant_nvfp4_bf16",
81 "dequant_nvfp4_to_bf16",
82 ),
83 q4k_gate: std::sync::OnceLock::new(),
84 q4k_up: std::sync::OnceLock::new(),
85 q4k_down: std::sync::OnceLock::new(),
86 nvfp4_mmq_nc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq128_nc"),
87 nvfp4_mmq_wc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq128_wc"),
88 nvfp4_mmq16_nc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq16_nc"),
89 nvfp4_mmq16_wc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq16_wc"),
90 nvfp4_mmq32_nc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq32_nc"),
91 nvfp4_mmq32_wc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq32_wc"),
92 nvfp4_mmq64_nc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq64_nc"),
93 nvfp4_mmq64_wc_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_mmq64_wc"),
94 nvfp4_quant_act_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_quantize_bf16"),
95 nvfp4_repack_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_repack"),
96 nvfp4_silu_scaled_k: super::try_kernel(
97 gpu,
98 "nvfp4_mmq",
99 "metrale_nvfp4_silu_mul_scaled",
100 ),
101 nvfp4_silu_quant_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_silu_mul_quant"),
102 nvfp4_scale_k: super::try_kernel(gpu, "nvfp4_mmq", "metrale_nvfp4_scale_bf16"),
103 fp4mmq_gate: std::sync::OnceLock::new(),
104 fp4mmq_up: std::sync::OnceLock::new(),
105 fp4mmq_down: std::sync::OnceLock::new(),
106 w4a16_gemm_t_k64_k: super::k64_kernel(gpu).unwrap_or(KernelHandle(0)),
107 act_mul,
108 bf16_weights: None,
109 w8a8: None,
110 dense_gemv_bf16_k,
111 dense_gemm_bf16_k,
112 dense_gemm_tc_k,
113 fp8_weights: None,
114 w8a16_gemv_k: super::try_kernel(gpu, "w8a16_gemv", "w8a16_gemv"),
115 w8a16_gemm_k: super::try_kernel(gpu, "w8a16_gemm", "w8a16_gemm"),
116 w8a16_gemv_batch4_k: super::try_kernel(gpu, "w8a16_gemv_batch4", "w8a16_gemv_batch4"),
117 w8a16_gemv_batch16_k: super::try_kernel(gpu, "w8a16_gemv_batch4", "w8a16_gemv_batch16"),
118 batch16_enabled: batch16_decode::ffn_batch16_enabled(),
119 w8a16_gemm_m16_k: super::try_target_kernel(gpu, "w8a16_gemm_m16", "w8a16_gemm_m16"),
120 w8a16_gemm_m16_n64_k: super::try_target_kernel(
121 gpu,
122 "w8a16_gemm_m16",
123 "w8a16_gemm_m16_n64",
124 ),
125 m16_tc: m16_tc::m16_tc_levers().ffn,
126 m16_tc_n_tile: m16_tc::m16_tc_levers().ffn_n_tile,
127 w8a16_gemm_pipelined_k: super::try_kernel(
128 gpu,
129 "w8a16_gemm_pipelined",
130 "w8a16_gemm_pipelined",
131 ),
132 w8a16_gemv_dual_k: super::try_kernel(gpu, "w8a16_gemv_fused", "w8a16_gemv_dual"),
133 w8a16_gemv_silu_input_k: super::try_kernel(
134 gpu,
135 "w8a16_gemv_fused",
136 "w8a16_gemv_silu_input",
137 ),
138 w8a16_gemm_t_m128_k: super::try_kernel(gpu, "w8a16_gemm_t_m128", "w8a16_gemm_t_m128"),
139 per_token_group_quant_fp8_k: ops::Fp8ActQuant::resolve(gpu),
140 fp8_gemm_t_blockscaled_k: super::try_kernel(
141 gpu,
142 "fp8_gemm_t_blockscaled",
143 "fp8_gemm_t_blockscaled",
144 ),
145 fp8_act_scale_kmajor_k: super::try_kernel(
146 gpu,
147 "fp8_scale_transpose",
148 "fp8_act_scale_to_kmajor",
149 ),
150 fp8_gate_up_fused: None,
151 gateup_fused,
152 silu_mul_strided_k: if gateup_fused {
153 super::try_target_kernel(gpu, "silu_mul_strided", "silu_mul_strided")
154 } else {
155 KernelHandle(0)
156 },
157 lora: None,
158 q2_weights: None,
159 q2_0_gemv_k: super::try_kernel(gpu, "q2_0_gemv_vec", "q2_0_gemv_vec"),
160 q2_0_gemv_batchm_k: super::try_kernel(gpu, "q2_0_gemv_vec", "q2_0_gemv_vec_batchm"),
161 dequant_q2_0_gn_k: super::try_kernel(
162 gpu,
163 "dequant_gguf_bf16",
164 "dequant_q2_0_gn_to_bf16",
165 ),
166 q2_0_mmq_nc_k: KernelHandle(0),
169 q2_0_mmq_wc_k: KernelHandle(0),
170 };
171 Ok(layer)
172 }
173}