1use super::*;
6
7impl MoeLayer {
8 pub fn new(
9 weights: MoeWeights,
10 num_experts: usize,
11 gate_nvfp4: Option<QuantizedWeight>,
12 gpu: &dyn GpuBackend,
13 config: &atlas_core::config::ModelConfig,
14 ) -> Result<Self> {
15 Self::new_with_hash(weights, num_experts, gate_nvfp4, None, gpu, config)
16 }
17
18 #[allow(clippy::too_many_arguments)]
22 pub fn new_with_hash(
23 weights: MoeWeights,
24 num_experts: usize,
25 gate_nvfp4: Option<QuantizedWeight>,
26 tid2eid_dev: Option<DevicePtr>,
27 gpu: &dyn GpuBackend,
28 config: &atlas_core::config::ModelConfig,
29 ) -> Result<Self> {
30 anyhow::ensure!(
34 config.num_experts_per_tok <= num_experts && num_experts > 0,
35 "MoE config invalid: num_experts_per_tok={} must be in 1..={}",
36 config.num_experts_per_tok,
37 num_experts,
38 );
39 anyhow::ensure!(
44 config.num_experts_per_tok <= crate::layers::ops::MOE_TOPK_SIGMOID_MAX_TOP_K
45 && num_experts <= crate::layers::ops::MOE_TOPK_SIGMOID_MAX_EXPERTS,
46 "MoE config exceeds the routing kernels' fixed shared-memory bounds: \
47 num_experts_per_tok={} (max {}), num_experts={} (max {}). Raise \
48 MAX_TOP_K / MAX_EXPERTS in kernels/gb10/common/moe_topk_sigmoid.cu \
49 and their mirrors in layers::ops together.",
50 config.num_experts_per_tok,
51 crate::layers::ops::MOE_TOPK_SIGMOID_MAX_TOP_K,
52 num_experts,
53 crate::layers::ops::MOE_TOPK_SIGMOID_MAX_EXPERTS,
54 );
55 let gate_ptrs = build_ptr_table(&weights.experts, |e| &e.gate_proj, gpu)?;
56 let up_ptrs = build_ptr_table(&weights.experts, |e| &e.up_proj, gpu)?;
57 let down_ptrs = build_ptr_table(&weights.experts, |e| &e.down_proj, gpu)?;
58
59 let weights_correction_bias: Option<DevicePtr> =
64 weights.correction_bias.map(|dw| dw.weight);
65
66 let _ = num_experts;
67 let rms_norm_k = gpu.kernel("norm", "rms_norm")?;
68 Ok(Self {
69 weights,
70 experts_scale_kind: crate::weight_map::WeightQuantFormat::Nvfp4,
74 shared_experts_scale_kind: crate::weight_map::WeightQuantFormat::Nvfp4,
75 gate_nvfp4,
76 pre_expert_norm: None,
77 pre_expert_norm_k: rms_norm_k,
78 dense_gemv: gpu.kernel("gemv", "dense_gemv_bf16")?,
79 w4a16_gemv: gpu.kernel("w4a16_gemv", "w4a16_gemv")?,
80 w4a16_gemv_sw: super::super::try_kernel(gpu, "w4a16_gemv", "w4a16_gemv_sw"),
81 w4a16_gemm: gpu.kernel("w4a16", "w4a16_gemm")?,
82 dense_gemm: gpu.kernel("gemm", "dense_gemm_bf16")?,
83 dense_gemm_router: super::super::try_kernel(gpu, "gemm", "dense_gemm_bf16_router"),
84 dense_gemm_pipelined: super::super::try_kernel(
85 gpu,
86 "gemm",
87 "dense_gemm_bf16_pipelined",
88 ),
89 dense_gemm_f32out: super::super::try_kernel(gpu, "gemm", "dense_gemm_bf16_f32out"),
92 dense_gemm_f32in: super::super::try_kernel(gpu, "gemm", "dense_gemm_f32in_f32out"),
93 moe_topk_f32: super::super::try_kernel(gpu, "moe_topk", "moe_topk_softmax_f32"),
94 moe_expert_gate_up_shared: gpu
95 .kernel("moe_shared_expert_fused", "moe_expert_gate_up_shared")?,
96 moe_expert_silu_down_shared: gpu
97 .kernel("moe_shared_expert_fused", "moe_expert_silu_down_shared")?,
98 moe_topk: gpu.kernel("moe_topk", "moe_topk_softmax")?,
99 moe_weighted_sum_blend: gpu.kernel("moe_expert_gemv", "moe_weighted_sum_blend")?,
100 residual_add: gpu.kernel("residual_add", "bf16_residual_add")?,
101 moe_topk_batched: gpu.kernel("moe_topk", "moe_topk_softmax_batched")?,
102 moe_expert_gate_up_shared_batch2: gpu
103 .kernel("moe_fused_batch2", "moe_expert_gate_up_shared_batch2")?,
104 moe_expert_silu_down_shared_batch2: gpu
105 .kernel("moe_fused_batch2", "moe_expert_silu_down_shared_batch2")?,
106 moe_weighted_sum_blend_batch2: gpu
107 .kernel("moe_fused_batch2", "moe_weighted_sum_blend_batch2")?,
108 w4a16_gemv_batch2: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch2")?,
109 moe_expert_gate_up_shared_batch3: gpu
110 .kernel("moe_fused_batch3", "moe_expert_gate_up_shared_batch3")?,
111 moe_expert_silu_down_shared_batch3: gpu
112 .kernel("moe_fused_batch3", "moe_expert_silu_down_shared_batch3")?,
113 moe_weighted_sum_blend_batch3: gpu
114 .kernel("moe_fused_batch3", "moe_weighted_sum_blend_batch3")?,
115 w4a16_gemv_batch3: gpu.kernel("w4a16_gemv", "w4a16_gemv_batch3")?,
116 moe_expert_gate_up_shared_token_major: gpu
117 .kernel("moe_prefill", "moe_expert_gate_up_shared_prefill")?,
118 moe_expert_silu_down_shared_token_major: gpu
119 .kernel("moe_prefill", "moe_expert_silu_down_shared_prefill")?,
120 moe_weighted_sum_blend_token_major: gpu
121 .kernel("moe_prefill", "moe_weighted_sum_blend_prefill")?,
122 moe_decode_atomic_c4_silu_down_accum_k: super::super::try_kernel(
123 gpu,
124 "moe_decode_atomic_c4",
125 "moe_decode_atomic_c4_silu_down_accum",
126 ),
127 moe_decode_atomic_c4_finalize_k: super::super::try_kernel(
128 gpu,
129 "moe_decode_atomic_c4",
130 "moe_decode_atomic_c4_finalize",
131 ),
132 moe_sort_by_expert: gpu.kernel("moe", "moe_sort_by_expert")?,
133 moe_sorted_gate_up: gpu.kernel("moe_sorted", "moe_sorted_gate_up")?,
134 moe_sorted_silu_down: gpu.kernel("moe_sorted", "moe_sorted_silu_down")?,
135 moe_grouped_gemm: gpu.kernel("moe_w4a16", "moe_w4a16_grouped_gemm_ptrtable")?,
136 moe_grouped_gemm_k32: if std::env::var("ATLAS_MOE_GROUPED_K32").as_deref() == Ok("1") {
137 super::super::try_kernel(gpu, "moe_w4a16", "moe_w4a16_grouped_gemm_ptrtable_k32")
138 } else {
139 KernelHandle(0)
140 },
141 moe_grouped_gemm_m256: if std::env::var("ATLAS_MOE_GROUPED_M256").as_deref() == Ok("1")
142 {
143 super::super::try_kernel(gpu, "moe_w4a16", "moe_w4a16_grouped_gemm_ptrtable_m256")
144 } else {
145 KernelHandle(0)
146 },
147 moe_grouped_gemm_t: gpu.kernel("moe_w4a16", "moe_w4a16_grouped_gemm_ptrtable_t")?,
148 moe_grouped_gemm_t_k64: gpu
149 .kernel("moe_w4a16", "moe_w4a16_grouped_gemm_ptrtable_t_k64")?,
150 moe_fused_gate_up_t: gpu.kernel("moe_w4a16", "moe_w4a16_fused_gate_up_t")?,
151 moe_fused_gate_up_t_k64: gpu.kernel("moe_w4a16", "moe_w4a16_fused_gate_up_t_k64")?,
152 moe_grouped_gemm_e8m0: super::super::try_kernel(
155 gpu,
156 "moe_w4a16",
157 "moe_w4a16_grouped_gemm_ptrtable_e8m0",
158 ),
159 moe_grouped_gemm_t_e8m0: super::super::try_kernel(
160 gpu,
161 "moe_w4a16",
162 "moe_w4a16_grouped_gemm_ptrtable_t_e8m0",
163 ),
164 moe_grouped_gemm_t_k64_e8m0: super::super::try_kernel(
165 gpu,
166 "moe_w4a16",
167 "moe_w4a16_grouped_gemm_ptrtable_t_k64_e8m0",
168 ),
169 moe_fused_gate_up_t_e8m0: super::super::try_kernel(
170 gpu,
171 "moe_w4a16",
172 "moe_w4a16_fused_gate_up_t_e8m0",
173 ),
174 moe_fused_gate_up_t_k64_e8m0: super::super::try_kernel(
175 gpu,
176 "moe_w4a16",
177 "moe_w4a16_fused_gate_up_t_k64_e8m0",
178 ),
179 moe_fused_gate_up_t_k64_m128: super::super::try_kernel(
183 gpu,
184 "moe_w4a16",
185 "moe_w4a16_fused_gate_up_t_k64_m128",
186 ),
187 moe_fused_gate_up_t_k64_fp4: super::super::try_kernel(
191 gpu,
192 "moe_w4a16",
193 "moe_w4a16_fused_gate_up_t_k64_fp4",
194 ),
195 moe_fp8_grouped_gemm_t: gpu.kernel("moe_w4a16", "moe_fp8_grouped_gemm_ptrtable_t")?,
196 moe_fp8_grouped_gemm_k: super::super::try_kernel(
200 gpu,
201 "moe_fp8_grouped_gemm",
202 "moe_fp8_grouped_gemm",
203 ),
204 moe_build_tile_worklist_k: super::super::try_kernel(
207 gpu,
208 "moe",
209 "moe_build_tile_worklist",
210 ),
211 moe_w8a8_grouped_gemm_k: super::super::try_kernel(
212 gpu,
213 "moe_w8a8_grouped_gemm",
214 "moe_w8a8_grouped_gemm",
215 ),
216 moe_w8a8_grouped_gemm_pm4_k: super::super::try_kernel(
219 gpu,
220 "moe_w8a8_grouped_gemm",
221 "moe_w8a8_grouped_gemm_pm4",
222 ),
223 per_token_group_quant_fp8_k: super::super::try_kernel(
224 gpu,
225 "per_token_group_quant_fp8",
226 "per_token_group_quant_fp8",
227 ),
228 silu_mul_quant_fp8_k: super::super::try_kernel(
232 gpu,
233 "moe_silu_mul",
234 "silu_mul_quant_fp8",
235 ),
236 fp8_gemm_t_blockscaled_k: super::super::try_kernel(
237 gpu,
238 "fp8_gemm_t_blockscaled",
239 "fp8_gemm_t_blockscaled",
240 ),
241 moe_bf16_grouped_gemm_k: super::super::try_kernel(
242 gpu,
243 "moe_bf16_grouped_gemm",
244 "moe_bf16_grouped_gemm",
245 ),
246 moe_expert_gate_up_shared_bf16_k: super::super::try_kernel(
247 gpu,
248 "moe_shared_expert_fused_bf16",
249 "moe_expert_gate_up_shared_bf16",
250 ),
251 moe_expert_silu_down_shared_bf16_k: super::super::try_kernel(
252 gpu,
253 "moe_shared_expert_fused_bf16",
254 "moe_expert_silu_down_shared_bf16",
255 ),
256 moe_expert_gate_up_shared_bf16_batch2_k: super::super::try_kernel(
257 gpu,
258 "moe_shared_expert_fused_bf16_batch2",
259 "moe_expert_gate_up_shared_bf16_batch2",
260 ),
261 moe_expert_silu_down_shared_bf16_batch2_k: super::super::try_kernel(
262 gpu,
263 "moe_shared_expert_fused_bf16_batch2",
264 "moe_expert_silu_down_shared_bf16_batch2",
265 ),
266 w8a16_gemm_k: super::super::try_kernel(gpu, "w8a16_gemm", "w8a16_gemm"),
267 w8a16_gemm_pipelined_k: super::super::try_kernel(
268 gpu,
269 "w8a16_gemm_pipelined",
270 "w8a16_gemm_pipelined",
271 ),
272 moe_gate_topk_fused_k: super::super::try_kernel(
273 gpu,
274 "moe_gate_topk",
275 "moe_gate_topk_fused",
276 ),
277 w4a16_gemm_t: gpu.kernel("w4a16", "w4a16_gemm_t")?,
278 bf16_to_fp8_k: gpu.kernel("w4a16", "bf16_to_fp8")?,
279 fp8_gemm_k: gpu.kernel("w4a16", "fp8_gemm_t")?,
280 moe_silu_mul: gpu.kernel("moe_silu_mul", "moe_silu_mul")?,
281 moe_act_mul: gpu.kernel("moe_silu_mul", "moe_silu_mul")?, gelu_activation: false,
283 moe_unpermute_reduce: gpu.kernel("moe", "moe_unpermute_reduce_indexed")?,
284 moe_batched_blend: gpu.kernel("moe", "moe_batched_blend")?,
285 gate_ptrs,
286 up_ptrs,
287 down_ptrs,
288 gate_ptrs_t: None,
289 up_ptrs_t: None,
290 down_ptrs_t: None,
291 cutlass_grouped_host: None,
292 _cutlass_sfb_owned: Vec::new(),
293 down_t_scratch_packed: None,
294 down_t_scratch_scale: None,
295 moe_transpose_u8_batched_k: gpu
296 .kernel("moe_transpose_batched", "moe_transpose_u8_batched")?,
297 moe_expert_gate_up_shared_t_k: gpu
300 .kernel("moe_shared_expert_fused_t", "moe_expert_gate_up_shared_t")?,
301 moe_expert_silu_down_shared_t_k: gpu
302 .kernel("moe_shared_expert_fused_t", "moe_expert_silu_down_shared_t")?,
303 moe_expert_gate_up_shared_t_e8m0_k: super::super::try_kernel(
307 gpu,
308 "moe_shared_expert_fused_t",
309 "moe_expert_gate_up_shared_t_e8m0",
310 ),
311 moe_expert_silu_down_shared_t_e8m0_k: super::super::try_kernel(
312 gpu,
313 "moe_shared_expert_fused_t",
314 "moe_expert_silu_down_shared_t_e8m0",
315 ),
316 moe_topk_sqrtsoftplus_k: super::super::try_kernel(
319 gpu,
320 "moe_topk_sqrt",
321 "moe_topk_sqrtsoftplus",
322 ),
323 moe_topk_sqrtsoftplus_batched_k: super::super::try_kernel(
324 gpu,
325 "moe_topk_sqrt",
326 "moe_topk_sqrtsoftplus_batched",
327 ),
328 router_logits_n: (config.num_experts + config.zero_expert_num) as u32,
332 moe_topk_softmax_bias_k: super::super::try_kernel(
333 gpu,
334 "moe_topk_softmax_bias",
335 "moe_topk_softmax_bias",
336 ),
337 moe_topk_softmax_bias_batched_k: super::super::try_kernel(
338 gpu,
339 "moe_topk_softmax_bias",
340 "moe_topk_softmax_bias_batched",
341 ),
342 moe_zero_expert_add_k: super::super::try_kernel(
343 gpu,
344 "moe_topk_softmax_bias",
345 "moe_zero_expert_add",
346 ),
347 zero_accum_dev: gpu.alloc(16384 * 4)?,
350 moe_hash_route_k: super::super::try_kernel(gpu, "moe_hash_route", "moe_hash_route"),
351 moe_hash_route_batched_k: super::super::try_kernel(
352 gpu,
353 "moe_hash_route",
354 "moe_hash_route_batched",
355 ),
356 tid2eid_dev,
357 moe_expert_gate_up_shared_batch2_t_k: gpu.kernel(
358 "moe_shared_expert_fused_batch2_t",
359 "moe_expert_gate_up_shared_batch2_t",
360 )?,
361 moe_expert_silu_down_shared_batch2_t_k: gpu.kernel(
362 "moe_shared_expert_fused_batch2_t",
363 "moe_expert_silu_down_shared_batch2_t",
364 )?,
365 moe_expert_gate_up_shared_batch3_t_k: gpu.kernel(
366 "moe_shared_expert_fused_batch3_t",
367 "moe_expert_gate_up_shared_batch3_t",
368 )?,
369 moe_expert_silu_down_shared_batch3_t_k: gpu.kernel(
370 "moe_shared_expert_fused_batch3_t",
371 "moe_expert_silu_down_shared_batch3_t",
372 )?,
373 moe_expert_gate_up_shared_fp8_t_k: gpu.kernel(
374 "moe_shared_expert_fused_fp8_t",
375 "moe_expert_gate_up_shared_fp8_t",
376 )?,
377 moe_expert_silu_down_shared_fp8_t_k: gpu.kernel(
378 "moe_shared_expert_fused_fp8_t",
379 "moe_expert_silu_down_shared_fp8_t",
380 )?,
381 moe_expert_gate_up_shared_fp8_batch2_t_k: gpu.kernel(
382 "moe_shared_expert_fused_fp8_batch2_t",
383 "moe_expert_gate_up_shared_fp8_batch2_t",
384 )?,
385 moe_expert_silu_down_shared_fp8_batch2_t_k: gpu.kernel(
386 "moe_shared_expert_fused_fp8_batch2_t",
387 "moe_expert_silu_down_shared_fp8_batch2_t",
388 )?,
389 moe_expert_gate_up_shared_fp8_batch3_t_k: gpu.kernel(
390 "moe_shared_expert_fused_fp8_batch3_t",
391 "moe_expert_gate_up_shared_fp8_batch3_t",
392 )?,
393 moe_expert_silu_down_shared_fp8_batch3_t_k: gpu.kernel(
394 "moe_shared_expert_fused_fp8_batch3_t",
395 "moe_expert_silu_down_shared_fp8_batch3_t",
396 )?,
397 unified_layout: std::env::var("ATLAS_UNIFIED_MOE_LAYOUT")
398 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
399 .unwrap_or(false),
400 hybrid_layout: std::env::var("ATLAS_HYBRID_MOE_LAYOUT")
401 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
402 .unwrap_or(false),
403 nvfp4_gate_up_m128: std::env::var("ATLAS_NVFP4_GATE_UP_M128")
404 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
405 .unwrap_or(false),
406 gateup_fp4: std::env::var("ATLAS_HOLO_MOE_GATEUP_FP4")
408 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
409 .unwrap_or(false),
410 down_fp4: std::env::var("ATLAS_HOLO_MOE_DOWN_FP4")
411 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
412 .unwrap_or(false),
413 shared_gate_t: None,
414 shared_up_t: None,
415 shared_down_t: None,
416 gate_fp8: None,
417 shared_gate_fp8: None,
418 shared_up_fp8: None,
419 shared_down_fp8: None,
420 prefill_stream: gpu.create_stream()?,
421 event_a: gpu.create_event()?,
422 event_b: gpu.create_event()?,
423 moe_expert_gate_up_shared_fp8: gpu.kernel(
424 "moe_shared_expert_fused_fp8",
425 "moe_expert_gate_up_shared_fp8",
426 )?,
427 moe_expert_silu_down_shared_fp8: gpu.kernel(
428 "moe_shared_expert_fused_fp8",
429 "moe_expert_silu_down_shared_fp8",
430 )?,
431 moe_expert_gate_up_shared_fp8_batch2: gpu.kernel(
433 "moe_shared_expert_fused_fp8_batch2",
434 "moe_expert_gate_up_shared_fp8_batch2",
435 )?,
436 moe_expert_silu_down_shared_fp8_batch2: gpu.kernel(
437 "moe_shared_expert_fused_fp8_batch2",
438 "moe_expert_silu_down_shared_fp8_batch2",
439 )?,
440 moe_weighted_sum_blend_fp8_batch2: gpu.kernel(
441 "moe_shared_expert_fused_fp8_batch2",
442 "moe_weighted_sum_blend_fp8_batch2",
443 )?,
444 moe_expert_gate_up_shared_fp8_batch3: gpu.kernel(
445 "moe_shared_expert_fused_fp8_batch3",
446 "moe_expert_gate_up_shared_fp8_batch3",
447 )?,
448 moe_expert_silu_down_shared_fp8_batch3: gpu.kernel(
449 "moe_shared_expert_fused_fp8_batch3",
450 "moe_expert_silu_down_shared_fp8_batch3",
451 )?,
452 moe_weighted_sum_blend_fp8_batch3: gpu.kernel(
453 "moe_shared_expert_fused_fp8_batch3",
454 "moe_weighted_sum_blend_fp8_batch3",
455 )?,
456 fp8_gate_weight_ptrs: None,
457 fp8_up_weight_ptrs: None,
458 fp8_down_weight_ptrs: None,
459 bf16_gate_weight_ptrs: None,
460 bf16_up_weight_ptrs: None,
461 bf16_down_weight_ptrs: None,
462 bf16_shared_expert: None,
463 fp8_shared_expert: None,
464 moe_down_t_k64_fp4: super::super::try_kernel(
465 gpu,
466 "moe_w4a16",
467 "moe_w4a16_down_t_k64_fp4",
468 ),
469 moe_permute_tokens_k: super::super::try_kernel(gpu, "moe", "moe_permute_tokens"),
470 is_dflash_capture_layer: false,
472 lora: None,
473 correction_bias_dev: weights_correction_bias,
474 moe_topk_sigmoid_k: super::super::try_kernel(gpu, "moe_topk_sig", "moe_topk_sigmoid"),
484 moe_topk_sigmoid_batched_k: super::super::try_kernel(
485 gpu,
486 "moe_topk_sig",
487 "moe_topk_sigmoid_batched",
488 ),
489 })
490 }
491}