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
16#[allow(clippy::too_many_arguments)]
31pub fn rms_norm_strided(
32 gpu: &dyn GpuBackend,
33 kernel: KernelHandle,
34 input: DevicePtr,
35 weight: &DenseWeight,
36 output: DevicePtr,
37 rows_per_group: u32,
38 num_groups: u32,
39 hidden_size: u32,
40 eps: f32,
41 row_stride: u32,
42 stream: u64,
43) -> Result<()> {
44 KernelLaunch::new(gpu, kernel)
45 .grid([rows_per_group, num_groups, 1])
46 .block([hidden_size.min(1024), 1, 1])
47 .arg_ptr(input)
48 .arg_ptr(weight.weight)
49 .arg_ptr(output)
50 .arg_u32(hidden_size)
51 .arg_f32(eps)
52 .arg_u32(row_stride)
53 .launch(stream)
54}
55
56pub fn rms_norm(
57 gpu: &dyn GpuBackend,
58 kernel: KernelHandle,
59 input: DevicePtr,
60 weight: &DenseWeight,
61 output: DevicePtr,
62 num_tokens: u32,
63 hidden_size: u32,
64 eps: f32,
65 stream: u64,
66) -> Result<()> {
67 KernelLaunch::new(gpu, kernel)
68 .grid([num_tokens, 1, 1])
69 .block([hidden_size.min(1024), 1, 1])
70 .arg_ptr(input)
71 .arg_ptr(weight.weight)
72 .arg_ptr(output)
73 .arg_u32(hidden_size)
74 .arg_f32(eps)
75 .launch(stream)
76}
77
78pub fn rms_norm_warp_row(
84 gpu: &dyn GpuBackend,
85 kernel: KernelHandle,
86 input: DevicePtr,
87 weight: &DenseWeight,
88 output: DevicePtr,
89 num_rows: u32,
90 hidden_size: u32,
91 eps: f32,
92 stream: u64,
93) -> Result<()> {
94 const ROWS_PER_BLOCK: u32 = 8;
95 KernelLaunch::new(gpu, kernel)
96 .grid([num_rows.div_ceil(ROWS_PER_BLOCK), 1, 1])
97 .block([32 * ROWS_PER_BLOCK, 1, 1])
98 .arg_ptr(input)
99 .arg_ptr(weight.weight)
100 .arg_ptr(output)
101 .arg_u32(num_rows)
102 .arg_u32(hidden_size)
103 .arg_f32(eps)
104 .launch(stream)
105}
106
107pub fn rms_norm_short_row_eligible(num_rows: u32, hidden_size: u32) -> bool {
110 use std::sync::OnceLock;
111 static ON: OnceLock<bool> = OnceLock::new();
112 let on = *ON.get_or_init(|| std::env::var("ATLAS_RMS_NORM_WARP_ROW").as_deref() != Ok("0"));
113 on && hidden_size <= 256 && hidden_size.is_multiple_of(2) && num_rows >= 1024
114}
115
116pub fn rms_norm_residual(
124 gpu: &dyn GpuBackend,
125 kernel: KernelHandle,
126 input: DevicePtr,
127 weight: &DenseWeight,
128 output: DevicePtr,
129 residual: DevicePtr,
130 num_tokens: u32,
131 hidden_size: u32,
132 eps: f32,
133 stream: u64,
134) -> Result<()> {
135 KernelLaunch::new(gpu, kernel)
136 .grid([num_tokens, 1, 1])
137 .block([hidden_size.min(1024), 1, 1])
138 .arg_ptr(input)
139 .arg_ptr(weight.weight)
140 .arg_ptr(output)
141 .arg_ptr(residual)
142 .arg_u32(hidden_size)
143 .arg_f32(eps)
144 .launch(stream)
145}
146
147#[allow(clippy::too_many_arguments)]
155pub fn residual_add_rms_norm(
156 gpu: &dyn GpuBackend,
157 kernel: KernelHandle,
158 hidden: DevicePtr,
159 src: DevicePtr,
160 weight: &DenseWeight,
161 output: DevicePtr,
162 residual: DevicePtr,
163 num_tokens: u32,
164 hidden_size: u32,
165 eps: f32,
166 stream: u64,
167) -> Result<()> {
168 KernelLaunch::new(gpu, kernel)
169 .grid([num_tokens, 1, 1])
170 .block([hidden_size.min(1024), 1, 1])
171 .arg_ptr(hidden)
172 .arg_ptr(src)
173 .arg_ptr(weight.weight)
174 .arg_ptr(output)
175 .arg_ptr(residual)
176 .arg_u32(hidden_size)
177 .arg_f32(eps)
178 .launch(stream)
179}
180
181#[allow(clippy::too_many_arguments)]
191pub fn residual_add_rms_norm_gatef32(
192 gpu: &dyn GpuBackend,
193 kernel: KernelHandle,
194 hidden: DevicePtr,
195 src: DevicePtr,
196 weight: &DenseWeight,
197 output: DevicePtr,
198 output_f32: DevicePtr,
199 residual: DevicePtr,
200 num_tokens: u32,
201 hidden_size: u32,
202 eps: f32,
203 stream: u64,
204) -> Result<()> {
205 KernelLaunch::new(gpu, kernel)
206 .grid([num_tokens, 1, 1])
207 .block([hidden_size.min(1024), 1, 1])
208 .arg_ptr(hidden)
209 .arg_ptr(src)
210 .arg_ptr(weight.weight)
211 .arg_ptr(output)
212 .arg_ptr(output_f32)
213 .arg_ptr(residual)
214 .arg_u32(hidden_size)
215 .arg_f32(eps)
216 .launch(stream)
217}
218
219pub fn gated_rms_norm(
225 gpu: &dyn GpuBackend,
226 kernel: KernelHandle,
227 input: DevicePtr,
228 gate: DevicePtr,
229 weight: &DenseWeight,
230 output: DevicePtr,
231 num_tokens: u32,
232 hidden_size: u32,
233 gate_stride: u32,
234 eps: f32,
235 group_size: u32,
236 stream: u64,
237) -> Result<()> {
238 KernelLaunch::new(gpu, kernel)
239 .grid([num_tokens, 1, 1])
240 .block([hidden_size.min(1024), 1, 1])
241 .arg_ptr(input)
242 .arg_ptr(gate)
243 .arg_ptr(weight.weight)
244 .arg_ptr(output)
245 .arg_u32(hidden_size)
246 .arg_f32(eps)
247 .arg_u32(gate_stride)
248 .arg_u32(group_size)
249 .launch(stream)
250}
251
252#[allow(clippy::too_many_arguments)]
257pub fn gated_rms_norm_prefill(
258 gpu: &dyn GpuBackend,
259 kernel: KernelHandle,
260 input: DevicePtr,
261 gate: DevicePtr,
262 weight: &DenseWeight,
263 output: DevicePtr,
264 heads_per_token: u32,
265 head_dim: u32,
266 eps: f32,
267 num_actual_tokens: u32,
268 input_token_stride: u32,
269 gate_token_stride: u32,
270 stream: u64,
271) -> Result<()> {
272 KernelLaunch::new(gpu, kernel)
273 .grid([heads_per_token, num_actual_tokens, 1])
274 .block([head_dim.min(1024), 1, 1])
275 .arg_ptr(input)
276 .arg_ptr(gate)
277 .arg_ptr(weight.weight)
278 .arg_ptr(output)
279 .arg_u32(head_dim)
280 .arg_f32(eps)
281 .arg_u32(input_token_stride)
282 .arg_u32(gate_token_stride)
283 .launch(stream)
284}
285
286