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
21#[allow(clippy::too_many_arguments)]
26pub fn prefill_attention(
27 gpu: &dyn GpuBackend,
28 kernel: KernelHandle,
29 q: DevicePtr,
30 k: DevicePtr,
31 v: DevicePtr,
32 output: DevicePtr,
33 seq_len: u32,
34 batch: u32,
35 num_q_heads: u32,
36 num_kv_heads: u32,
37 head_dim: u32,
38 inv_sqrt_d: f32,
39 causal: bool,
40 sliding_window: u32,
41 stream: u64,
42) -> Result<()> {
43 let br = if head_dim > 256 {
47 wide_prefill_kernel(gpu).1
48 } else {
49 32u32
50 };
51 KernelLaunch::new(gpu, kernel)
52 .grid([num_q_heads, div_ceil(seq_len, br), batch])
53 .block([128, 1, 1])
54 .arg_ptr(q)
55 .arg_ptr(k)
56 .arg_ptr(v)
57 .arg_ptr(output)
58 .arg_u32(seq_len)
59 .arg_u32(num_q_heads)
60 .arg_u32(num_kv_heads)
61 .arg_u32(head_dim)
62 .arg_f32(inv_sqrt_d)
63 .arg_u32(if causal { 1 } else { 0 })
64 .arg_u32(sliding_window)
65 .launch(stream)
66}
67
68#[allow(clippy::too_many_arguments)]
73pub fn prefill_attention_512_sink(
74 gpu: &dyn GpuBackend,
75 kernel: KernelHandle,
76 q: DevicePtr,
77 k: DevicePtr,
78 v: DevicePtr,
79 output: DevicePtr,
80 seq_len: u32,
81 batch: u32,
82 num_q_heads: u32,
83 num_kv_heads: u32,
84 head_dim: u32,
85 inv_sqrt_d: f32,
86 causal: bool,
87 sliding_window: u32,
88 sinks: DevicePtr,
89 stream: u64,
90) -> Result<()> {
91 KernelLaunch::new(gpu, kernel)
92 .grid([num_q_heads, div_ceil(seq_len, 16), batch])
93 .block([128, 1, 1])
94 .arg_ptr(q)
95 .arg_ptr(k)
96 .arg_ptr(v)
97 .arg_ptr(output)
98 .arg_u32(seq_len)
99 .arg_u32(num_q_heads)
100 .arg_u32(num_kv_heads)
101 .arg_u32(head_dim)
102 .arg_f32(inv_sqrt_d)
103 .arg_u32(if causal { 1 } else { 0 })
104 .arg_u32(sliding_window)
105 .arg_ptr(sinks)
106 .launch(stream)
107}
108
109#[allow(clippy::too_many_arguments)]
112pub fn prefill_attention_64(
113 gpu: &dyn GpuBackend,
114 kernel: KernelHandle,
115 q: DevicePtr,
116 k: DevicePtr,
117 v: DevicePtr,
118 output: DevicePtr,
119 seq_len: u32,
120 batch: u32,
121 num_q_heads: u32,
122 num_kv_heads: u32,
123 head_dim: u32,
124 inv_sqrt_d: f32,
125 causal: bool,
126 sliding_window: u32,
127 stream: u64,
128) -> Result<()> {
129 let br = if cfg!(metrale_scale) { 32u32 } else { 64u32 };
135 KernelLaunch::new(gpu, kernel)
136 .grid([num_q_heads, div_ceil(seq_len, br), batch])
137 .block([256, 1, 1])
138 .arg_ptr(q)
139 .arg_ptr(k)
140 .arg_ptr(v)
141 .arg_ptr(output)
142 .arg_u32(seq_len)
143 .arg_u32(num_q_heads)
144 .arg_u32(num_kv_heads)
145 .arg_u32(head_dim)
146 .arg_f32(inv_sqrt_d)
147 .arg_u32(if causal { 1 } else { 0 })
148 .arg_u32(sliding_window)
149 .launch(stream)
150}
151
152#[allow(clippy::too_many_arguments)]
155pub fn prefill_attention_fp8kv(
156 gpu: &dyn GpuBackend,
157 kernel: KernelHandle,
158 q: DevicePtr,
159 k_fp8: DevicePtr,
160 v_fp8: DevicePtr,
161 output: DevicePtr,
162 seq_len: u32,
163 batch: u32,
164 num_q_heads: u32,
165 num_kv_heads: u32,
166 head_dim: u32,
167 inv_sqrt_d: f32,
168 causal: bool,
169 stream: u64,
170) -> Result<()> {
171 let br = 64u32;
172 KernelLaunch::new(gpu, kernel)
173 .grid([num_q_heads, div_ceil(seq_len, br), batch])
174 .block([256, 1, 1])
175 .arg_ptr(q)
176 .arg_ptr(k_fp8)
177 .arg_ptr(v_fp8)
178 .arg_ptr(output)
179 .arg_u32(seq_len)
180 .arg_u32(num_q_heads)
181 .arg_u32(num_kv_heads)
182 .arg_u32(head_dim)
183 .arg_f32(inv_sqrt_d)
184 .arg_u32(if causal { 1 } else { 0 })
185 .launch(stream)
186}
187
188#[allow(clippy::too_many_arguments)]
192pub fn prefill_attention_paged(
193 gpu: &dyn GpuBackend,
194 kernel: KernelHandle,
195 q: DevicePtr,
196 k_cache: DevicePtr,
197 v_cache: DevicePtr,
198 output: DevicePtr,
199 block_table: DevicePtr,
200 q_len: u32,
201 kv_len: u32,
202 q_offset: u32,
203 num_q_heads: u32,
204 num_kv_heads: u32,
205 head_dim: u32,
206 cache_block_size: u32,
207 sliding_window: u32,
208 inv_sqrt_d: f32,
209 stream: u64,
210) -> Result<()> {
211 let br = 32u32;
212 KernelLaunch::new(gpu, kernel)
213 .grid([num_q_heads, div_ceil(q_len, br), 1])
214 .block([128, 1, 1])
215 .arg_ptr(q)
216 .arg_ptr(k_cache)
217 .arg_ptr(v_cache)
218 .arg_ptr(output)
219 .arg_ptr(block_table)
220 .arg_u32(q_len)
221 .arg_u32(kv_len)
222 .arg_u32(q_offset)
223 .arg_u32(num_q_heads)
224 .arg_u32(num_kv_heads)
225 .arg_u32(head_dim)
226 .arg_u32(cache_block_size)
227 .arg_u32(sliding_window)
228 .arg_u32(1u32)
229 .arg_f32(inv_sqrt_d)
230 .launch(stream)
231}
232
233#[allow(clippy::too_many_arguments)]
235pub fn prefill_attention_paged_fp8(
236 gpu: &dyn GpuBackend,
237 kernel: KernelHandle,
238 q: DevicePtr,
239 k_cache: DevicePtr,
240 v_cache: DevicePtr,
241 output: DevicePtr,
242 block_table: DevicePtr,
243 q_len: u32,
244 kv_len: u32,
245 q_offset: u32,
246 num_q_heads: u32,
247 num_kv_heads: u32,
248 head_dim: u32,
249 cache_block_size: u32,
250 sliding_window: u32,
251 inv_sqrt_d: f32,
252 k_scale: f32,
253 v_scale: f32,
254 cache_stride: u64,
255 stream: u64,
256) -> Result<()> {
257 let br = 32u32;
258 KernelLaunch::new(gpu, kernel)
259 .grid([num_q_heads, div_ceil(q_len, br), 1])
260 .block([128, 1, 1])
261 .arg_ptr(q)
262 .arg_ptr(k_cache)
263 .arg_ptr(v_cache)
264 .arg_ptr(output)
265 .arg_ptr(block_table)
266 .arg_u32(q_len)
267 .arg_u32(kv_len)
268 .arg_u32(q_offset)
269 .arg_u32(num_q_heads)
270 .arg_u32(num_kv_heads)
271 .arg_u32(head_dim)
272 .arg_u32(cache_block_size)
273 .arg_u32(sliding_window)
274 .arg_u32(1u32)
275 .arg_f32(inv_sqrt_d)
276 .arg_f32(k_scale)
277 .arg_f32(v_scale)
278 .arg_u64(cache_stride)
279 .launch(stream)
280}
281
282#[allow(clippy::too_many_arguments)]
286pub fn prefill_attention_paged_fp8_dflash(
287 gpu: &dyn GpuBackend,
288 kernel: KernelHandle,
289 q: DevicePtr,
290 k_cache: DevicePtr,
291 v_cache: DevicePtr,
292 output: DevicePtr,
293 block_table: DevicePtr,
294 q_len: u32,
295 kv_len: u32,
296 q_offset: u32,
297 num_q_heads: u32,
298 num_kv_heads: u32,
299 head_dim: u32,
300 cache_block_size: u32,
301 sliding_window: u32,
302 inv_sqrt_d: f32,
303 k_scale: f32,
304 v_scale: f32,
305 cache_stride: u64,
306 stream: u64,
307) -> Result<()> {
308 let br = 32u32;
309 KernelLaunch::new(gpu, kernel)
310 .grid([num_q_heads, div_ceil(q_len, br), 1])
311 .block([128, 1, 1])
312 .arg_ptr(q)
313 .arg_ptr(k_cache)
314 .arg_ptr(v_cache)
315 .arg_ptr(output)
316 .arg_ptr(block_table)
317 .arg_u32(q_len)
318 .arg_u32(kv_len)
319 .arg_u32(q_offset)
320 .arg_u32(num_q_heads)
321 .arg_u32(num_kv_heads)
322 .arg_u32(head_dim)
323 .arg_u32(cache_block_size)
324 .arg_u32(sliding_window)
325 .arg_u32(0u32)
326 .arg_f32(inv_sqrt_d)
327 .arg_f32(k_scale)
328 .arg_f32(v_scale)
329 .arg_u64(cache_stride)
330 .launch(stream)
331}
332
333#[allow(clippy::too_many_arguments)]
337pub fn prefill_attention_paged_dflash(
338 gpu: &dyn GpuBackend,
339 kernel: KernelHandle,
340 q: DevicePtr,
341 k_cache: DevicePtr,
342 v_cache: DevicePtr,
343 output: DevicePtr,
344 block_table: DevicePtr,
345 q_len: u32,
346 kv_len: u32,
347 q_offset: u32,
348 num_q_heads: u32,
349 num_kv_heads: u32,
350 head_dim: u32,
351 cache_block_size: u32,
352 sliding_window: u32,
353 inv_sqrt_d: f32,
354 stream: u64,
355) -> Result<()> {
356 let br = 32u32;
357 KernelLaunch::new(gpu, kernel)
358 .grid([num_q_heads, div_ceil(q_len, br), 1])
359 .block([128, 1, 1])
360 .arg_ptr(q)
361 .arg_ptr(k_cache)
362 .arg_ptr(v_cache)
363 .arg_ptr(output)
364 .arg_ptr(block_table)
365 .arg_u32(q_len)
366 .arg_u32(kv_len)
367 .arg_u32(q_offset)
368 .arg_u32(num_q_heads)
369 .arg_u32(num_kv_heads)
370 .arg_u32(head_dim)
371 .arg_u32(cache_block_size)
372 .arg_u32(sliding_window)
373 .arg_u32(0u32)
374 .arg_f32(inv_sqrt_d)
375 .launch(stream)
376}
377
378#[allow(clippy::too_many_arguments)]
386pub fn prefill_attention_paged_dflash_bf16_indirect(
387 gpu: &dyn GpuBackend,
388 kernel: KernelHandle,
389 q: DevicePtr,
390 k_cache: DevicePtr,
391 v_cache: DevicePtr,
392 output: DevicePtr,
393 block_table: DevicePtr,
394 q_len: u32,
395 kv_len_q_offset_dev: DevicePtr,
396 num_q_heads: u32,
397 num_kv_heads: u32,
398 head_dim: u32,
399 cache_block_size: u32,
400 sliding_window: u32,
401 inv_sqrt_d: f32,
402 stream: u64,
403) -> Result<()> {
404 let br = 32u32;
405 KernelLaunch::new(gpu, kernel)
408 .grid([num_q_heads, div_ceil(q_len, br), 1])
409 .block([128, 1, 1])
410 .arg_ptr(q)
411 .arg_ptr(k_cache)
412 .arg_ptr(v_cache)
413 .arg_ptr(output)
414 .arg_ptr(block_table)
415 .arg_u32(q_len)
416 .arg_u32(0u32)
417 .arg_u32(0u32)
418 .arg_u32(num_q_heads)
419 .arg_u32(num_kv_heads)
420 .arg_u32(head_dim)
421 .arg_u32(cache_block_size)
422 .arg_u32(sliding_window)
423 .arg_u32(0u32)
424 .arg_f32(inv_sqrt_d)
425 .arg_ptr(kv_len_q_offset_dev)
426 .arg_ptr(kv_len_q_offset_dev.offset(4))
427 .arg_ptr(kv_len_q_offset_dev.offset(8))
428 .launch(stream)
429}