1#![allow(unused_imports)]
15
16use anyhow::Result;
17use metrale_gpu_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
18use metrale_gpu_runtime::kernel_args::{KernelLaunch, div_ceil};
19
20use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
21
22use super::*;
23
24#[path = "moe_grouped_a/topk.rs"]
26mod topk;
27pub use topk::{moe_topk_sigmoid_batched, moe_topk_softmax_batched, moe_topk_sqrtsoftplus_batched};
29#[path = "moe_grouped_a/fused_gate_up.rs"]
31mod fused_gate_up;
32pub use fused_gate_up::{
33 moe_w4a16_fused_gate_up_k64_m128, moe_w4a16_fused_gate_up_k64_n128,
34 moe_w4a16_fused_gate_up_n128,
35};
36
37pub fn moe_w4a16_grouped_gemm(
41 gpu: &dyn GpuBackend,
42 kernel: KernelHandle,
43 a: DevicePtr,
44 b_packed: DevicePtr,
45 b_scale: DevicePtr,
46 scale2: f32,
47 c: DevicePtr,
48 expert_offsets: DevicePtr,
49 num_experts: u32,
50 n: u32,
51 k: u32,
52 stream: u64,
53) -> Result<()> {
54 check_e4m3_grouped(
55 gpu,
56 kernel,
57 a,
58 expert_offsets,
59 DevicePtr::NULL,
60 num_experts,
61 k,
62 stream,
63 )?;
64 KernelLaunch::new(gpu, kernel)
65 .grid([num_experts, 1, 1])
66 .block([256, 1, 1])
67 .arg_ptr(a)
68 .arg_ptr(b_packed)
69 .arg_ptr(b_scale)
70 .arg_f32(scale2)
71 .arg_ptr(c)
72 .arg_ptr(expert_offsets)
73 .arg_u32(num_experts)
74 .arg_u32(n)
75 .arg_u32(k)
76 .launch(stream)
77}
78
79#[allow(clippy::too_many_arguments)]
84pub fn moe_w4a16_grouped_gemm_ptrtable_m256(
85 gpu: &dyn GpuBackend,
86 kernel: KernelHandle,
87 a: DevicePtr,
88 b_packed_ptrs: DevicePtr,
89 b_scale_ptrs: DevicePtr,
90 scale2_vals: DevicePtr,
91 c: DevicePtr,
92 expert_offsets: DevicePtr,
93 sorted_token_ids: DevicePtr,
94 num_experts: u32,
95 n_out: u32,
96 k: u32,
97 max_m_tiles: u32,
98 stream: u64,
99) -> Result<()> {
100 check_e4m3_grouped(
101 gpu,
102 kernel,
103 a,
104 expert_offsets,
105 sorted_token_ids,
106 num_experts,
107 k,
108 stream,
109 )?;
110 KernelLaunch::new(gpu, kernel)
111 .grid([n_tile_blocks(gpu, kernel, n_out)?, max_m_tiles, num_experts])
112 .block([512, 1, 1])
113 .arg_ptr(a)
114 .arg_ptr(b_packed_ptrs)
115 .arg_ptr(b_scale_ptrs)
116 .arg_ptr(scale2_vals)
117 .arg_ptr(c)
118 .arg_ptr(expert_offsets)
119 .arg_ptr(sorted_token_ids)
120 .arg_u32(num_experts)
121 .arg_u32(n_out)
122 .arg_u32(k)
123 .launch(stream)
124}
125
126#[allow(clippy::too_many_arguments)]
129pub fn moe_w4a16_grouped_gemm_ptrtable(
130 gpu: &dyn GpuBackend,
131 kernel: KernelHandle,
132 a: DevicePtr,
133 b_packed_ptrs: DevicePtr,
134 b_scale_ptrs: DevicePtr,
135 scale2_vals: DevicePtr,
136 c: DevicePtr,
137 expert_offsets: DevicePtr,
138 sorted_token_ids: DevicePtr,
139 num_experts: u32,
140 n_out: u32,
141 k: u32,
142 max_m_tiles: u32,
143 stream: u64,
144) -> Result<()> {
145 check_e4m3_grouped(
146 gpu,
147 kernel,
148 a,
149 expert_offsets,
150 sorted_token_ids,
151 num_experts,
152 k,
153 stream,
154 )?;
155 KernelLaunch::new(gpu, kernel)
156 .grid([n_tile_blocks(gpu, kernel, n_out)?, max_m_tiles, num_experts])
157 .block([128, 1, 1])
158 .arg_ptr(a)
159 .arg_ptr(b_packed_ptrs)
160 .arg_ptr(b_scale_ptrs)
161 .arg_ptr(scale2_vals)
162 .arg_ptr(c)
163 .arg_ptr(expert_offsets)
164 .arg_ptr(sorted_token_ids)
165 .arg_u32(num_experts)
166 .arg_u32(n_out)
167 .arg_u32(k)
168 .launch(stream)
169}
170
171#[allow(clippy::too_many_arguments)]
174pub fn moe_w4a16_grouped_gemm_ptrtable_n128(
175 gpu: &dyn GpuBackend,
176 kernel: KernelHandle,
177 a: DevicePtr,
178 b_packed_ptrs: DevicePtr,
179 b_scale_ptrs: DevicePtr,
180 scale2_vals: DevicePtr,
181 c: DevicePtr,
182 expert_offsets: DevicePtr,
183 sorted_token_ids: DevicePtr,
184 num_experts: u32,
185 n_out: u32,
186 k: u32,
187 max_m_tiles: u32,
188 stream: u64,
189) -> Result<()> {
190 check_e4m3_grouped(
191 gpu,
192 kernel,
193 a,
194 expert_offsets,
195 sorted_token_ids,
196 num_experts,
197 k,
198 stream,
199 )?;
200 KernelLaunch::new(gpu, kernel)
201 .grid([n_tile_blocks(gpu, kernel, n_out)?, max_m_tiles, num_experts])
202 .block([128, 1, 1])
203 .arg_ptr(a)
204 .arg_ptr(b_packed_ptrs)
205 .arg_ptr(b_scale_ptrs)
206 .arg_ptr(scale2_vals)
207 .arg_ptr(c)
208 .arg_ptr(expert_offsets)
209 .arg_ptr(sorted_token_ids)
210 .arg_u32(num_experts)
211 .arg_u32(n_out)
212 .arg_u32(k)
213 .launch(stream)
214}
215
216#[allow(clippy::too_many_arguments)]
220pub fn moe_fp8_grouped_gemm_ptrtable_n128(
221 gpu: &dyn GpuBackend,
222 kernel: KernelHandle,
223 a_fp8: DevicePtr,
224 b_packed_ptrs: DevicePtr,
225 b_scale_ptrs: DevicePtr,
226 scale2_vals: DevicePtr,
227 c: DevicePtr,
228 expert_offsets: DevicePtr,
229 sorted_token_ids: DevicePtr,
230 num_experts: u32,
231 n_out: u32,
232 k: u32,
233 max_m_tiles: u32,
234 stream: u64,
235) -> Result<()> {
236 KernelLaunch::new(gpu, kernel)
237 .grid([n_tile_blocks(gpu, kernel, n_out)?, max_m_tiles, num_experts])
238 .block([128, 1, 1])
239 .arg_ptr(a_fp8)
240 .arg_ptr(b_packed_ptrs)
241 .arg_ptr(b_scale_ptrs)
242 .arg_ptr(scale2_vals)
243 .arg_ptr(c)
244 .arg_ptr(expert_offsets)
245 .arg_ptr(sorted_token_ids)
246 .arg_u32(num_experts)
247 .arg_u32(n_out)
248 .arg_u32(k)
249 .launch(stream)
250}
251
252#[allow(clippy::too_many_arguments)]
255pub fn moe_w4a16_grouped_gemm_ptrtable_k64_n128(
256 gpu: &dyn GpuBackend,
257 kernel: KernelHandle,
258 a: DevicePtr,
259 b_packed_ptrs: DevicePtr,
260 b_scale_ptrs: DevicePtr,
261 scale2_vals: DevicePtr,
262 c: DevicePtr,
263 expert_offsets: DevicePtr,
264 sorted_token_ids: DevicePtr,
265 num_experts: u32,
266 n_out: u32,
267 k: u32,
268 max_m_tiles: u32,
269 stream: u64,
270) -> Result<()> {
271 check_e4m3_grouped(
272 gpu,
273 kernel,
274 a,
275 expert_offsets,
276 sorted_token_ids,
277 num_experts,
278 k,
279 stream,
280 )?;
281 KernelLaunch::new(gpu, kernel)
282 .grid([n_tile_blocks(gpu, kernel, n_out)?, max_m_tiles, num_experts])
283 .block([128, 1, 1])
284 .arg_ptr(a)
285 .arg_ptr(b_packed_ptrs)
286 .arg_ptr(b_scale_ptrs)
287 .arg_ptr(scale2_vals)
288 .arg_ptr(c)
289 .arg_ptr(expert_offsets)
290 .arg_ptr(sorted_token_ids)
291 .arg_u32(num_experts)
292 .arg_u32(n_out)
293 .arg_u32(k)
294 .launch(stream)
295}
296
297#[allow(clippy::too_many_arguments, dead_code)]
301pub fn moe_permute_tokens(
302 gpu: &dyn GpuBackend,
303 kernel: KernelHandle,
304 hidden_states: DevicePtr,
305 permuted: DevicePtr,
306 sorted_token_ids: DevicePtr,
307 hidden: u32,
308 total_expanded: u32,
309 stream: u64,
310) -> Result<()> {
311 let threads = hidden.clamp(1, 256);
312 KernelLaunch::new(gpu, kernel)
313 .grid([total_expanded, 1, 1])
314 .block([threads, 1, 1])
315 .arg_ptr(hidden_states)
316 .arg_ptr(permuted)
317 .arg_ptr(sorted_token_ids)
318 .arg_u32(hidden)
319 .arg_u32(total_expanded)
320 .launch(stream)
321}
322
323pub fn moe_silu_mul(
325 gpu: &dyn GpuBackend,
326 kernel: KernelHandle,
327 gate: DevicePtr,
328 up: DevicePtr,
329 output: DevicePtr,
330 total_elements: u32,
331 stream: u64,
332) -> Result<()> {
333 KernelLaunch::new(gpu, kernel)
334 .grid([div_ceil(total_elements, 256), 1, 1])
335 .block([256, 1, 1])
336 .arg_ptr(gate)
337 .arg_ptr(up)
338 .arg_ptr(output)
339 .arg_u32(total_elements)
340 .launch(stream)
341}