1#![allow(unused_imports)]
11
12use anyhow::Result;
13use metrale_gpu_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
14use metrale_gpu_runtime::kernel_args::{KernelLaunch, div_ceil};
15
16use crate::layers::moe;
17use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
18
19use super::*;
20
21pub fn reshape_and_cache_nvfp4(
25 gpu: &dyn GpuBackend,
26 kernel: KernelHandle,
27 key: DevicePtr,
28 value: DevicePtr,
29 k_cache: DevicePtr,
30 v_cache: DevicePtr,
31 slot_mapping: DevicePtr,
32 num_tokens: u32,
33 num_kv_heads: u32,
34 head_dim: u32,
35 block_size: u32,
36 key_stride: u32,
37 value_stride: u32,
38 block_stride_bytes: u64,
39 data_section_bytes: u64,
40 stream: u64,
41) -> Result<()> {
42 KernelLaunch::new(gpu, kernel)
43 .grid([num_tokens, 1, 1])
44 .block([256, 1, 1])
45 .arg_ptr(key)
46 .arg_ptr(value)
47 .arg_ptr(k_cache)
48 .arg_ptr(v_cache)
49 .arg_ptr(slot_mapping)
50 .arg_u32(num_kv_heads)
51 .arg_u32(head_dim)
52 .arg_u32(block_size)
53 .arg_u32(key_stride)
54 .arg_u32(value_stride)
55 .arg_u64(block_stride_bytes)
56 .arg_u64(data_section_bytes)
57 .launch(stream)
58}
59
60pub fn bf16_absmax(
64 gpu: &dyn GpuBackend,
65 kernel: KernelHandle,
66 data: DevicePtr,
67 out_max: DevicePtr,
68 n_elems: u32,
69 stream: u64,
70) -> Result<()> {
71 let grid_x = (n_elems as u64).div_ceil(256 * 2).min(256) as u32;
73 KernelLaunch::new(gpu, kernel)
74 .grid([grid_x, 1, 1])
75 .block([256, 1, 1])
76 .arg_ptr(data)
77 .arg_ptr(out_max)
78 .arg_u32(n_elems)
79 .launch(stream)
80}
81
82pub fn paged_decode_attn_nvfp4(
85 gpu: &dyn GpuBackend,
86 kernel: KernelHandle,
87 q: DevicePtr,
88 k_cache: DevicePtr,
89 v_cache: DevicePtr,
90 output: DevicePtr,
91 block_tables: DevicePtr,
92 seq_lens: DevicePtr,
93 max_blocks_per_seq: u32,
94 num_seqs: u32,
95 num_q_heads: u32,
96 num_kv_heads: u32,
97 head_dim: u32,
98 block_size: u32,
99 inv_sqrt_d: f32,
100 q_stride: u32,
101 block_stride_bytes: u64,
102 data_section_bytes: u64,
103 stream: u64,
104) -> Result<()> {
105 KernelLaunch::new(gpu, kernel)
106 .grid([num_q_heads, num_seqs, 1])
107 .block([256, 1, 1])
108 .arg_ptr(q)
109 .arg_ptr(k_cache)
110 .arg_ptr(v_cache)
111 .arg_ptr(output)
112 .arg_ptr(block_tables)
113 .arg_ptr(seq_lens)
114 .arg_u32(max_blocks_per_seq)
115 .arg_u32(num_q_heads)
116 .arg_u32(num_kv_heads)
117 .arg_u32(head_dim)
118 .arg_u32(block_size)
119 .arg_f32(inv_sqrt_d)
120 .arg_u32(q_stride)
121 .arg_u64(block_stride_bytes)
122 .arg_u64(data_section_bytes)
123 .launch(stream)
124}
125
126#[allow(clippy::too_many_arguments)]
130pub fn paged_decode_attn_splitk_nvfp4(
131 gpu: &dyn GpuBackend,
132 kernel: KernelHandle,
133 q: DevicePtr,
134 k_cache: DevicePtr,
135 v_cache: DevicePtr,
136 workspace: DevicePtr,
137 block_tables: DevicePtr,
138 seq_lens: DevicePtr,
139 max_blocks_per_seq: u32,
140 num_q_heads: u32,
141 num_kv_heads: u32,
142 head_dim: u32,
143 block_size: u32,
144 inv_sqrt_d: f32,
145 num_splits: u32,
146 q_stride: u32,
147 block_stride_bytes: u64,
148 data_section_bytes: u64,
149 num_seqs: u32,
150 stream: u64,
151) -> Result<()> {
152 KernelLaunch::new(gpu, kernel)
153 .grid([num_q_heads, num_splits, num_seqs])
154 .block([256, 1, 1])
155 .arg_ptr(q)
156 .arg_ptr(k_cache)
157 .arg_ptr(v_cache)
158 .arg_ptr(workspace)
159 .arg_ptr(block_tables)
160 .arg_ptr(seq_lens)
161 .arg_u32(max_blocks_per_seq)
162 .arg_u32(num_q_heads)
163 .arg_u32(num_kv_heads)
164 .arg_u32(head_dim)
165 .arg_u32(block_size)
166 .arg_f32(inv_sqrt_d)
167 .arg_u32(num_splits)
168 .arg_u32(q_stride)
169 .arg_u64(block_stride_bytes)
170 .arg_u64(data_section_bytes)
171 .launch(stream)
172}
173
174#[allow(clippy::too_many_arguments)]
176pub fn paged_decode_attn_reduce_nvfp4(
177 gpu: &dyn GpuBackend,
178 kernel: KernelHandle,
179 workspace: DevicePtr,
180 output: DevicePtr,
181 seq_lens: DevicePtr,
182 num_q_heads: u32,
183 head_dim: u32,
184 num_splits: u32,
185 num_seqs: u32,
186 stream: u64,
187) -> Result<()> {
188 KernelLaunch::new(gpu, kernel)
189 .grid([num_q_heads, num_seqs, 1])
190 .block([32, 1, 1])
191 .arg_ptr(workspace)
192 .arg_ptr(output)
193 .arg_ptr(seq_lens)
194 .arg_u32(num_q_heads)
195 .arg_u32(head_dim)
196 .arg_u32(num_splits)
197 .launch(stream)
198}
199
200#[allow(clippy::too_many_arguments)]
202pub fn paged_decode_attn_splitk_fp8(
203 gpu: &dyn GpuBackend,
204 kernel: KernelHandle,
205 q: DevicePtr,
206 k_cache: DevicePtr,
207 v_cache: DevicePtr,
208 workspace: DevicePtr,
209 block_tables: DevicePtr,
210 seq_lens: DevicePtr,
211 max_blocks_per_seq: u32,
212 num_q_heads: u32,
213 num_kv_heads: u32,
214 head_dim: u32,
215 block_size: u32,
216 inv_sqrt_d: f32,
217 num_splits: u32,
218 k_scale: f32,
219 v_scale: f32,
220 q_stride: u32,
221 cache_stride: u64,
222 num_seqs: u32,
223 sliding_window: u32,
224 stream: u64,
225) -> Result<()> {
226 KernelLaunch::new(gpu, kernel)
227 .grid([num_q_heads, num_splits, num_seqs])
228 .block([256, 1, 1])
229 .arg_ptr(q)
230 .arg_ptr(k_cache)
231 .arg_ptr(v_cache)
232 .arg_ptr(workspace)
233 .arg_ptr(block_tables)
234 .arg_ptr(seq_lens)
235 .arg_u32(max_blocks_per_seq)
236 .arg_u32(num_q_heads)
237 .arg_u32(num_kv_heads)
238 .arg_u32(head_dim)
239 .arg_u32(block_size)
240 .arg_f32(inv_sqrt_d)
241 .arg_u32(num_splits)
242 .arg_f32(k_scale)
243 .arg_f32(v_scale)
244 .arg_u32(q_stride)
245 .arg_u64(cache_stride)
246 .arg_u32(sliding_window)
247 .launch(stream)
248}
249
250#[allow(clippy::too_many_arguments)]
255pub fn paged_decode_attn_splitk_bf16(
256 gpu: &dyn GpuBackend,
257 kernel: KernelHandle,
258 q: DevicePtr,
259 k_cache: DevicePtr,
260 v_cache: DevicePtr,
261 workspace: DevicePtr,
262 block_tables: DevicePtr,
263 seq_lens: DevicePtr,
264 max_blocks_per_seq: u32,
265 num_q_heads: u32,
266 num_kv_heads: u32,
267 head_dim: u32,
268 block_size: u32,
269 inv_sqrt_d: f32,
270 num_splits: u32,
271 q_stride: u32,
272 num_seqs: u32,
273 sliding_window: u32,
274 stream: u64,
275) -> Result<()> {
276 KernelLaunch::new(gpu, kernel)
277 .grid([num_q_heads, num_splits, num_seqs])
278 .block([256, 1, 1])
279 .arg_ptr(q)
280 .arg_ptr(k_cache)
281 .arg_ptr(v_cache)
282 .arg_ptr(workspace)
283 .arg_ptr(block_tables)
284 .arg_ptr(seq_lens)
285 .arg_u32(max_blocks_per_seq)
286 .arg_u32(num_q_heads)
287 .arg_u32(num_kv_heads)
288 .arg_u32(head_dim)
289 .arg_u32(block_size)
290 .arg_f32(inv_sqrt_d)
291 .arg_u32(num_splits)
292 .arg_u32(q_stride)
293 .arg_u32(sliding_window)
294 .launch(stream)
295}
296
297#[allow(clippy::too_many_arguments)]
302pub fn paged_decode_attn_reduce_fp8(
303 gpu: &dyn GpuBackend,
304 kernel: KernelHandle,
305 workspace: DevicePtr,
306 output: DevicePtr,
307 seq_lens: DevicePtr,
308 num_q_heads: u32,
309 head_dim: u32,
310 num_splits: u32,
311 num_seqs: u32,
312 stream: u64,
313) -> Result<()> {
314 KernelLaunch::new(gpu, kernel)
315 .grid([num_q_heads, num_seqs, 1])
316 .block([32, 1, 1])
317 .arg_ptr(workspace)
318 .arg_ptr(output)
319 .arg_ptr(seq_lens)
320 .arg_u32(num_q_heads)
321 .arg_u32(head_dim)
322 .arg_u32(num_splits)
323 .launch(stream)
324}