1#![allow(unused_imports)]
6
7use anyhow::Result;
8use spark_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
9use spark_runtime::kernel_args::{KernelLaunch, div_ceil};
10
11use crate::layers::moe;
12use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
13
14use super::*;
15
16pub const MOE_TOPK_SIGMOID_MAX_TOP_K: usize = 32;
30
31pub const MOE_TOPK_SIGMOID_MAX_EXPERTS: usize = 512;
36
37pub fn moe_topk_softmax(
45 gpu: &dyn GpuBackend,
46 kernel: KernelHandle,
47 gate_logits: DevicePtr,
48 expert_indices: DevicePtr,
49 expert_weights: DevicePtr,
50 num_experts: u32,
51 top_k: u32,
52 normalize: bool,
53 stream: u64,
54) -> Result<()> {
55 KernelLaunch::new(gpu, kernel)
56 .grid([1, 1, 1])
57 .block([256, 1, 1])
58 .arg_ptr(gate_logits)
59 .arg_ptr(expert_indices)
60 .arg_ptr(expert_weights)
61 .arg_u32(num_experts)
62 .arg_u32(top_k)
63 .arg_u32(if normalize { 1 } else { 0 })
64 .launch(stream)
65}
66
67#[allow(clippy::too_many_arguments)]
79pub fn moe_topk_softmax_bias(
80 gpu: &dyn GpuBackend,
81 kernel: KernelHandle,
82 gate_logits: DevicePtr,
83 bias: DevicePtr,
84 expert_indices: DevicePtr,
85 expert_weights: DevicePtr,
86 zero_accum: DevicePtr,
87 num_logits: u32, num_routed: u32,
89 top_k: u32,
90 normalize: bool,
91 scaling_factor: f32,
92 stream: u64,
93) -> Result<()> {
94 KernelLaunch::new(gpu, kernel)
95 .grid([1, 1, 1])
96 .block([256, 1, 1])
97 .arg_ptr(gate_logits)
98 .arg_ptr(bias)
99 .arg_ptr(expert_indices)
100 .arg_ptr(expert_weights)
101 .arg_ptr(zero_accum)
102 .arg_u32(num_logits)
103 .arg_u32(num_routed)
104 .arg_u32(top_k)
105 .arg_u32(normalize as u32)
106 .arg_f32(scaling_factor)
107 .launch(stream)
108}
109
110#[allow(clippy::too_many_arguments)]
112pub fn moe_topk_softmax_bias_batched(
113 gpu: &dyn GpuBackend,
114 kernel: KernelHandle,
115 gate_logits: DevicePtr,
116 bias: DevicePtr,
117 expert_indices: DevicePtr,
118 expert_weights: DevicePtr,
119 zero_accum: DevicePtr,
120 num_logits: u32,
121 num_routed: u32,
122 top_k: u32,
123 normalize: bool,
124 scaling_factor: f32,
125 n: u32,
126 stream: u64,
127) -> Result<()> {
128 KernelLaunch::new(gpu, kernel)
129 .grid([n, 1, 1])
130 .block([256, 1, 1])
131 .arg_ptr(gate_logits)
132 .arg_ptr(bias)
133 .arg_ptr(expert_indices)
134 .arg_ptr(expert_weights)
135 .arg_ptr(zero_accum)
136 .arg_u32(num_logits)
137 .arg_u32(num_routed)
138 .arg_u32(top_k)
139 .arg_u32(normalize as u32)
140 .arg_f32(scaling_factor)
141 .launch(stream)
142}
143
144pub fn moe_zero_expert_add(
146 gpu: &dyn GpuBackend,
147 kernel: KernelHandle,
148 out: DevicePtr,
149 x: DevicePtr,
150 zero_accum: DevicePtr,
151 n: u32,
152 h: u32,
153 stream: u64,
154) -> Result<()> {
155 use spark_runtime::kernel_args::div_ceil;
156 KernelLaunch::new(gpu, kernel)
157 .grid([div_ceil(n * h, 256), 1, 1])
158 .block([256, 1, 1])
159 .arg_ptr(out)
160 .arg_ptr(x)
161 .arg_ptr(zero_accum)
162 .arg_u32(n)
163 .arg_u32(h)
164 .launch(stream)
165}
166
167pub fn moe_topk_sigmoid(
168 gpu: &dyn GpuBackend,
169 kernel: KernelHandle,
170 gate_logits: DevicePtr,
171 bias: DevicePtr,
172 expert_indices: DevicePtr,
173 expert_weights: DevicePtr,
174 num_experts: u32,
175 top_k: u32,
176 normalize: bool,
177 scaling_factor: f32,
178 stream: u64,
179) -> Result<()> {
180 KernelLaunch::new(gpu, kernel)
181 .grid([1, 1, 1])
182 .block([256, 1, 1])
183 .arg_ptr(gate_logits)
184 .arg_ptr(bias)
185 .arg_ptr(expert_indices)
186 .arg_ptr(expert_weights)
187 .arg_u32(num_experts)
188 .arg_u32(top_k)
189 .arg_u32(if normalize { 1 } else { 0 })
190 .arg_f32(scaling_factor)
191 .launch(stream)
192}
193
194#[allow(clippy::too_many_arguments)]
204pub fn moe_topk_sqrtsoftplus(
205 gpu: &dyn GpuBackend,
206 kernel: KernelHandle,
207 gate_logits: DevicePtr,
208 bias: DevicePtr,
209 expert_indices: DevicePtr,
210 expert_weights: DevicePtr,
211 num_experts: u32,
212 top_k: u32,
213 normalize: bool,
214 scaling_factor: f32,
215 stream: u64,
216) -> Result<()> {
217 KernelLaunch::new(gpu, kernel)
218 .grid([1, 1, 1])
219 .block([256, 1, 1])
220 .arg_ptr(gate_logits)
221 .arg_ptr(bias)
222 .arg_ptr(expert_indices)
223 .arg_ptr(expert_weights)
224 .arg_u32(num_experts)
225 .arg_u32(top_k)
226 .arg_u32(if normalize { 1 } else { 0 })
227 .arg_f32(scaling_factor)
228 .launch(stream)
229}
230
231#[allow(clippy::too_many_arguments)]
242pub fn moe_hash_route(
243 gpu: &dyn GpuBackend,
244 kernel: KernelHandle,
245 gate_logits: DevicePtr,
246 tid2eid: DevicePtr,
247 token_id_ptr: DevicePtr,
248 expert_indices: DevicePtr,
249 expert_weights: DevicePtr,
250 num_experts: u32,
251 top_k: u32,
252 normalize: bool,
253 scaling_factor: f32,
254 stream: u64,
255) -> Result<()> {
256 KernelLaunch::new(gpu, kernel)
257 .grid([1, 1, 1])
258 .block([256, 1, 1])
259 .arg_ptr(gate_logits)
260 .arg_ptr(tid2eid)
261 .arg_ptr(token_id_ptr)
262 .arg_ptr(expert_indices)
263 .arg_ptr(expert_weights)
264 .arg_u32(num_experts)
265 .arg_u32(top_k)
266 .arg_u32(if normalize { 1 } else { 0 })
267 .arg_f32(scaling_factor)
268 .launch(stream)
269}
270
271#[allow(clippy::too_many_arguments)]
276pub fn moe_hash_route_batched(
277 gpu: &dyn GpuBackend,
278 kernel: KernelHandle,
279 gate_logits: DevicePtr,
280 tid2eid: DevicePtr,
281 token_ids: DevicePtr,
282 expert_indices: DevicePtr,
283 expert_weights: DevicePtr,
284 num_experts: u32,
285 top_k: u32,
286 normalize: bool,
287 scaling_factor: f32,
288 n: u32,
289 stream: u64,
290) -> Result<()> {
291 KernelLaunch::new(gpu, kernel)
292 .grid([n, 1, 1])
293 .block([256, 1, 1])
294 .arg_ptr(gate_logits)
295 .arg_ptr(tid2eid)
296 .arg_ptr(token_ids)
297 .arg_ptr(expert_indices)
298 .arg_ptr(expert_weights)
299 .arg_u32(num_experts)
300 .arg_u32(top_k)
301 .arg_u32(if normalize { 1 } else { 0 })
302 .arg_f32(scaling_factor)
303 .launch(stream)
304}
305
306