metrale_model_layers/layers/ops/
embeddings.rs1#![allow(unused_imports)]
10
11use anyhow::Result;
12use metrale_gpu_runtime::gpu::{DevicePtr, GpuBackend, KernelHandle};
13use metrale_gpu_runtime::kernel_args::{KernelLaunch, div_ceil};
14
15use crate::layers::moe;
16use crate::weight_map::{DenseWeight, Fp8DenseWeight, Fp8Weight, QuantizedWeight};
17
18use super::*;
19
20#[allow(clippy::too_many_arguments)]
25pub fn rope_strided(
26 gpu: &dyn GpuBackend,
27 kernel: KernelHandle,
28 q: DevicePtr,
29 k: DevicePtr,
30 positions: DevicePtr,
31 num_tokens: u32,
32 num_q_heads: u32,
33 num_kv_heads: u32,
34 head_dim: u32,
35 rotary_dim: u32,
36 theta: f32,
37 q_row_stride: u32,
38 k_row_stride: u32,
39 stream: u64,
40) -> Result<()> {
41 assert!(
42 rotary_dim > 0,
43 "rope_strided: rotary_dim=0, nq={num_q_heads} nkv={num_kv_heads} hd={head_dim}"
44 );
45 let half_rot = (rotary_dim / 2).max(1);
46 let pos_per_block = (128 / half_rot).max(1);
47 let seq_blocks = div_ceil(num_tokens, pos_per_block);
48 KernelLaunch::new(gpu, kernel)
49 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
50 .block([128, 1, 1])
51 .arg_ptr(q)
52 .arg_ptr(k)
53 .arg_ptr(positions)
54 .arg_u32(num_tokens)
55 .arg_u32(num_q_heads)
56 .arg_u32(num_kv_heads)
57 .arg_u32(head_dim)
58 .arg_u32(rotary_dim)
59 .arg_f32(theta)
60 .arg_u32(q_row_stride)
61 .arg_u32(k_row_stride)
62 .launch(stream)
63}
64
65pub fn rope(
69 gpu: &dyn GpuBackend,
70 kernel: KernelHandle,
71 q: DevicePtr,
72 k: DevicePtr,
73 positions: DevicePtr,
74 seq_len: u32,
75 num_q_heads: u32,
76 num_kv_heads: u32,
77 head_dim: u32,
78 rotary_dim: u32,
79 theta: f32,
80 stream: u64,
81) -> Result<()> {
82 assert!(
83 rotary_dim > 0,
84 "rope: rotary_dim=0, nq={num_q_heads} nkv={num_kv_heads} hd={head_dim}"
85 );
86 let half_rot = (rotary_dim / 2).max(1);
87 let pos_per_block = (128 / half_rot).max(1);
88 let seq_blocks = div_ceil(seq_len, pos_per_block);
89 KernelLaunch::new(gpu, kernel)
90 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
91 .block([128, 1, 1])
92 .arg_ptr(q)
93 .arg_ptr(k)
94 .arg_ptr(positions)
95 .arg_u32(seq_len)
96 .arg_u32(num_q_heads)
97 .arg_u32(num_kv_heads)
98 .arg_u32(head_dim)
99 .arg_u32(rotary_dim)
100 .arg_f32(theta)
101 .launch(stream)
102}
103
104#[allow(clippy::too_many_arguments)]
109pub fn rope_proportional(
110 gpu: &dyn GpuBackend,
111 kernel: KernelHandle,
112 q: DevicePtr,
113 k: DevicePtr,
114 positions: DevicePtr,
115 seq_len: u32,
116 num_q_heads: u32,
117 num_kv_heads: u32,
118 head_dim: u32,
119 rope_angles: u32,
120 theta: f32,
121 stream: u64,
122) -> Result<()> {
123 assert!(rope_angles > 0, "rope_proportional: rope_angles=0");
124 let pairs_per_pos = rope_angles.max(1);
125 let pos_per_block = (128 / pairs_per_pos).max(1);
126 let seq_blocks = div_ceil(seq_len, pos_per_block);
127 KernelLaunch::new(gpu, kernel)
128 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
129 .block([128, 1, 1])
130 .arg_ptr(q)
131 .arg_ptr(k)
132 .arg_ptr(positions)
133 .arg_u32(seq_len)
134 .arg_u32(num_q_heads)
135 .arg_u32(num_kv_heads)
136 .arg_u32(head_dim)
137 .arg_u32(rope_angles)
138 .arg_f32(theta)
139 .launch(stream)
140}
141
142#[allow(clippy::too_many_arguments)]
146pub fn rope_mrope_interleaved(
147 gpu: &dyn GpuBackend,
148 kernel: KernelHandle,
149 q: DevicePtr,
150 k: DevicePtr,
151 pos_t: DevicePtr,
152 pos_h: DevicePtr,
153 pos_w: DevicePtr,
154 seq_len: u32,
155 num_q_heads: u32,
156 num_kv_heads: u32,
157 head_dim: u32,
158 rotary_dim: u32,
159 theta: f32,
160 stream: u64,
161) -> Result<()> {
162 assert!(rotary_dim > 0, "rope_mrope_interleaved: rotary_dim=0");
163 let half_rot = (rotary_dim / 2).max(1);
164 let pos_per_block = (128 / half_rot).max(1);
165 let seq_blocks = div_ceil(seq_len, pos_per_block);
166 KernelLaunch::new(gpu, kernel)
167 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
168 .block([128, 1, 1])
169 .arg_ptr(q)
170 .arg_ptr(k)
171 .arg_ptr(pos_t)
172 .arg_ptr(pos_h)
173 .arg_ptr(pos_w)
174 .arg_u32(seq_len)
175 .arg_u32(num_q_heads)
176 .arg_u32(num_kv_heads)
177 .arg_u32(head_dim)
178 .arg_u32(rotary_dim)
179 .arg_f32(theta)
180 .launch(stream)
181}
182
183#[allow(clippy::too_many_arguments)]
186pub fn rope_mrope_interleaved_k_only(
187 gpu: &dyn GpuBackend,
188 kernel: KernelHandle,
189 k: DevicePtr,
190 pos_t: DevicePtr,
191 pos_h: DevicePtr,
192 pos_w: DevicePtr,
193 seq_len: u32,
194 num_kv_heads: u32,
195 head_dim: u32,
196 rotary_dim: u32,
197 theta: f32,
198 stream: u64,
199) -> Result<()> {
200 assert!(
201 rotary_dim > 0,
202 "rope_mrope_interleaved_k_only: rotary_dim=0"
203 );
204 let half_rot = (rotary_dim / 2).max(1);
205 let pos_per_block = (128 / half_rot).max(1);
206 let seq_blocks = div_ceil(seq_len, pos_per_block);
207 KernelLaunch::new(gpu, kernel)
208 .grid([num_kv_heads, seq_blocks, 1])
209 .block([128, 1, 1])
210 .arg_ptr(k)
211 .arg_ptr(pos_t)
212 .arg_ptr(pos_h)
213 .arg_ptr(pos_w)
214 .arg_u32(seq_len)
215 .arg_u32(num_kv_heads)
216 .arg_u32(head_dim)
217 .arg_u32(rotary_dim)
218 .arg_f32(theta)
219 .launch(stream)
220}
221
222#[allow(clippy::too_many_arguments)]
225pub fn rope_yarn(
226 gpu: &dyn GpuBackend,
227 kernel: KernelHandle,
228 q: DevicePtr,
229 k: DevicePtr,
230 positions: DevicePtr,
231 seq_len: u32,
232 num_q_heads: u32,
233 num_kv_heads: u32,
234 head_dim: u32,
235 rotary_dim: u32,
236 inv_freq: DevicePtr,
237 theta: f32,
238 stream: u64,
239) -> Result<()> {
240 assert!(
241 rotary_dim > 0,
242 "rope: rotary_dim=0, nq={num_q_heads} nkv={num_kv_heads} hd={head_dim}"
243 );
244 let half_rot = (rotary_dim / 2).max(1);
245 let pos_per_block = (128 / half_rot).max(1);
246 let seq_blocks = div_ceil(seq_len, pos_per_block);
247 KernelLaunch::new(gpu, kernel)
248 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
249 .block([128, 1, 1])
250 .arg_ptr(q)
251 .arg_ptr(k)
252 .arg_ptr(positions)
253 .arg_u32(seq_len)
254 .arg_u32(num_q_heads)
255 .arg_u32(num_kv_heads)
256 .arg_u32(head_dim)
257 .arg_u32(rotary_dim)
258 .arg_ptr(inv_freq)
259 .arg_f32(theta)
260 .launch(stream)
261}
262
263#[allow(clippy::too_many_arguments)]
266pub fn rope_yarn_scaled(
267 gpu: &dyn GpuBackend,
268 kernel: KernelHandle,
269 q: DevicePtr,
270 k: DevicePtr,
271 positions: DevicePtr,
272 seq_len: u32,
273 num_q_heads: u32,
274 num_kv_heads: u32,
275 head_dim: u32,
276 rotary_dim: u32,
277 inv_freq: DevicePtr,
278 attention_factor: f32,
279 stream: u64,
280) -> Result<()> {
281 assert!(rotary_dim > 0, "rope_yarn_scaled: rotary_dim=0");
282 let half_rot = (rotary_dim / 2).max(1);
283 let pos_per_block = (128 / half_rot).max(1);
284 let seq_blocks = div_ceil(seq_len, pos_per_block);
285 KernelLaunch::new(gpu, kernel)
286 .grid([num_q_heads + num_kv_heads, seq_blocks, 1])
287 .block([128, 1, 1])
288 .arg_ptr(q)
289 .arg_ptr(k)
290 .arg_ptr(positions)
291 .arg_u32(seq_len)
292 .arg_u32(num_q_heads)
293 .arg_u32(num_kv_heads)
294 .arg_u32(head_dim)
295 .arg_u32(rotary_dim)
296 .arg_ptr(inv_freq)
297 .arg_f32(attention_factor)
298 .launch(stream)
299}