rudnn/attention/kernel_ir/definition/
spec.rs1use ruda_kernel::dsl as kernel_dsl;
2use ruda_kernel::dsl::prelude::*;
3use half::{bf16, f16};
4
5use crate::attention::kernel_ir::{
6 definition::{AccumulatorPrecision, AttentionGlobalTypes},
7 launch::{AttentionArgs, TensorArgs},
8};
9
10pub trait AttentionSpec: Send + Sync + Clone + 'static {
13 type Precision: AttentionPrecision;
14 type Args: AttentionArgs;
16}
17
18impl<AP: AttentionPrecision, Args: AttentionArgs> AttentionSpec for (AP, Args) {
19 type Precision = AP;
20 type Args = Args;
21}
22
23impl<AP: AttentionPrecision> AttentionSpec for AP {
25 type Precision = AP;
26 type Args = TensorArgs;
27}
28
29pub trait QueryPrecision: Send + Sync + Copy + 'static {
30 type Global: Float;
31 type GlobalSize: Size;
32 type Tile: Float;
33}
34
35pub trait StagedMatrixPrecision: Send + Sync + Copy + 'static {
36 type Global: Float;
37 type GlobalSize: Size;
38 type Stage: Float;
39 type StageSize: Size;
40}
41
42pub trait AttentionPrecision: Send + Sync + Copy + 'static {
43 type Query: QueryPrecision;
44 type Key: StagedMatrixPrecision;
45 type Value: StagedMatrixPrecision;
46 type KVTile: Float;
47 type SoftmaxAcc: Float;
48 type SoftmaxLhs: Float;
49 type Accumulator: Float;
50 type Mask: Numeric;
51 type MaskSize: Size;
52 type Out: StagedMatrixPrecision;
53}
54
55impl QueryPrecision for f16 {
56 type Global = f16;
57 type GlobalSize = Const<0>;
58 type Tile = f16;
59}
60
61impl QueryPrecision for bf16 {
62 type Global = bf16;
63 type GlobalSize = Const<0>;
64 type Tile = bf16;
65}
66
67impl QueryPrecision for flex32 {
68 type Global = f32;
69 type GlobalSize = Const<0>;
70 type Tile = f16;
71}
72
73impl QueryPrecision for f32 {
74 type Global = f32;
75 type GlobalSize = Const<0>;
76 type Tile = f32;
77}
78
79impl QueryPrecision for f64 {
80 type Global = f64;
81 type GlobalSize = Const<0>;
82 type Tile = f32;
83}
84
85impl<G: Float, GS: Size, T: Float> QueryPrecision for (G, GS, T) {
86 type Global = G;
87 type GlobalSize = GS;
88 type Tile = T;
89}
90
91impl StagedMatrixPrecision for f16 {
92 type Global = f16;
93 type GlobalSize = Const<0>;
94 type Stage = f16;
95 type StageSize = Const<0>;
96}
97
98impl StagedMatrixPrecision for bf16 {
99 type Global = bf16;
100 type GlobalSize = Const<0>;
101 type Stage = bf16;
102 type StageSize = Const<0>;
103}
104
105impl StagedMatrixPrecision for flex32 {
106 type Global = f32;
107 type GlobalSize = Const<0>;
108 type Stage = f16;
109 type StageSize = Const<0>;
110}
111
112impl StagedMatrixPrecision for f32 {
113 type Global = f32;
114 type GlobalSize = Const<0>;
115 type Stage = f32;
116 type StageSize = Const<0>;
117}
118
119impl StagedMatrixPrecision for f64 {
120 type Global = f64;
121 type GlobalSize = Const<0>;
122 type Stage = f32;
123 type StageSize = Const<0>;
124}
125
126impl<G: Float, GS: Size, S: Float, SS: Size> StagedMatrixPrecision for (G, GS, S, SS) {
127 type Global = G;
128 type GlobalSize = GS;
129 type Stage = S;
130 type StageSize = SS;
131}
132
133impl AttentionPrecision for f16 {
134 type Query = f16;
135 type Key = f16;
136 type Value = f16;
137 type KVTile = f16;
138 type SoftmaxLhs = f16;
139 #[cfg(target_os = "macos")]
140 type SoftmaxAcc = f16;
141 #[cfg(target_os = "macos")]
142 type Accumulator = f16;
143 #[cfg(not(target_os = "macos"))]
144 type SoftmaxAcc = f32;
145 #[cfg(not(target_os = "macos"))]
146 type Accumulator = f32;
147 type Mask = u8;
148 type MaskSize = Const<0>;
149 type Out = f16;
150}
151
152impl AttentionPrecision for flex32 {
153 type Query = flex32;
154 type Key = flex32;
155 type Value = flex32;
156 type KVTile = f16;
157 type SoftmaxLhs = f16;
158 #[cfg(target_os = "macos")]
159 type SoftmaxAcc = f16;
160 #[cfg(target_os = "macos")]
161 type Accumulator = f16;
162 #[cfg(not(target_os = "macos"))]
163 type SoftmaxAcc = f32;
164 #[cfg(not(target_os = "macos"))]
165 type Accumulator = f32;
166 type Mask = u8;
167 type MaskSize = Const<0>;
168 type Out = f32;
169}
170
171impl AttentionPrecision for bf16 {
172 type Query = bf16;
173 type Key = bf16;
174 type Value = bf16;
175 type KVTile = bf16;
176 type SoftmaxLhs = bf16;
177 #[cfg(target_os = "macos")]
178 type SoftmaxAcc = bf16;
179 #[cfg(target_os = "macos")]
180 type Accumulator = bf16;
181 #[cfg(not(target_os = "macos"))]
182 type SoftmaxAcc = f32;
183 #[cfg(not(target_os = "macos"))]
184 type Accumulator = f32;
185 type Mask = u8;
186 type MaskSize = Const<0>;
187 type Out = bf16;
188}
189
190impl AttentionPrecision for f32 {
191 type Query = f32;
192 type Key = f32;
193 type Value = f32;
194 type KVTile = f32;
195 type SoftmaxAcc = f32;
196 type SoftmaxLhs = f32;
197 type Accumulator = f32;
198 type Mask = u8;
199 type MaskSize = Const<0>;
200 type Out = f32;
201}
202
203impl AttentionPrecision for f64 {
204 type Query = f64;
205 type Key = f64;
206 type Value = f64;
207 type KVTile = f32;
208 type SoftmaxAcc = f32;
209 type SoftmaxLhs = f32;
210 type Accumulator = f32;
211 type Mask = u8;
212 type MaskSize = Const<0>;
213 type Out = f64;
214}
215
216impl<
217 QG: Float,
218 QGS: Size,
219 QT: Float,
220 KG: Float,
221 KGS: Size,
222 KS: Float,
223 KSS: Size,
224 VG: Float,
225 VGS: Size,
226 VS: Float,
227 VSS: Size,
228 KVT: Float,
229 SM: Float,
230 SML: Float,
231 ACC: Float,
232 MSK: Numeric,
233 MSKS: Size,
234 OG: Float,
235 OGS: Size,
236 OS: Float,
237 OSS: Size,
238> AttentionPrecision
239 for (
240 (QG, QGS, QT),
241 (KG, KGS, KS, KSS),
242 (VG, VGS, VS, VSS),
243 KVT,
244 SM,
245 SML,
246 ACC,
247 MSK,
248 MSKS,
249 (OG, OGS, OS, OSS),
250 )
251{
252 type Query = (QG, QGS, QT);
253 type Key = (KG, KGS, KS, KSS);
254 type Value = (VG, VGS, VS, VSS);
255 type KVTile = KVT;
256 type SoftmaxAcc = SM;
257 type SoftmaxLhs = SML;
258 type Accumulator = ACC;
259 type Mask = MSK;
260 type MaskSize = MSKS;
261 type Out = (OG, OGS, OS, OSS);
262}
263
264pub mod launch_types {
265 use super::*;
266
267 define_scalar!(pub QG);
268 define_scalar!(pub KG);
269 define_scalar!(pub VG);
270 define_scalar!(pub MSK);
271 define_scalar!(pub OG);
272
273 define_size!(pub QGS);
274 define_size!(pub KGS);
275 define_size!(pub VGS);
276 define_size!(pub MSKS);
277 define_size!(pub OGS);
278
279 pub type InputArg<AA> =
281 <AA as AttentionArgs>::Input<(QG, QGS), (KG, KGS), (VG, VGS), (MSK, MSKS)>;
282
283 pub type OutputArg<AA> = <AA as AttentionArgs>::Output<(OG, OGS)>;
285}
286
287pub use launch_types::{InputArg, OutputArg};
288
289pub type InputRuntimeArg<AA, R> = <InputArg<AA> as LaunchArg>::RuntimeArg<R>;
291
292pub type OutputRuntimeArg<AA, R> = <OutputArg<AA> as LaunchArg>::RuntimeArg<R>;
294
295pub mod attention_types {
296 use ruda_kernel::dsl::prelude::*;
297
298 use crate::attention::kernel_ir::definition::{
299 AttentionPrecision, AttentionSpec, QueryPrecision, StagedMatrixPrecision,
300 };
301
302 pub type Query<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Query;
305 pub type Key<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Key;
306 pub type Value<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Value;
307 pub type Out<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Out;
308
309 pub type QG<AS> = <Query<AS> as QueryPrecision>::Global;
313 pub type QGS<AS> = <Query<AS> as QueryPrecision>::GlobalSize;
314 pub type QT<AS> = <Query<AS> as QueryPrecision>::Tile;
315
316 pub type QGV<AS> = Vector<QG<AS>, QGS<AS>>;
318
319 pub type KG<AS> = <Key<AS> as StagedMatrixPrecision>::Global;
323 pub type KGS<AS> = <Key<AS> as StagedMatrixPrecision>::GlobalSize;
324 pub type KS<AS> = <Key<AS> as StagedMatrixPrecision>::Stage;
325 pub type KSS<AS> = <Key<AS> as StagedMatrixPrecision>::StageSize;
326
327 pub type KGV<AS> = Vector<KG<AS>, KGS<AS>>;
329 pub type KSV<AS> = Vector<KS<AS>, KSS<AS>>;
330
331 pub type VG<AS> = <Value<AS> as StagedMatrixPrecision>::Global;
335 pub type VGS<AS> = <Value<AS> as StagedMatrixPrecision>::GlobalSize;
336 pub type VS<AS> = <Value<AS> as StagedMatrixPrecision>::Stage;
337 pub type VSS<AS> = <Value<AS> as StagedMatrixPrecision>::StageSize;
338
339 pub type VGV<AS> = Vector<VG<AS>, VGS<AS>>;
341 pub type VSV<AS> = Vector<VS<AS>, VSS<AS>>;
342
343 pub type KVT<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::KVTile;
346 pub type SM<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::SoftmaxAcc;
347 pub type SML<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::SoftmaxLhs;
348 pub type ACC<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Accumulator;
349
350 pub type MSK<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::Mask;
353 pub type MSKS<AS> = <<AS as AttentionSpec>::Precision as AttentionPrecision>::MaskSize;
354
355 pub type MSKV<AS> = Vector<MSK<AS>, MSKS<AS>>;
357
358 pub type OG<AS> = <Out<AS> as StagedMatrixPrecision>::Global;
362 pub type OGS<AS> = <Out<AS> as StagedMatrixPrecision>::GlobalSize;
363 pub type OS<AS> = <Out<AS> as StagedMatrixPrecision>::Stage;
364 pub type OSS<AS> = <Out<AS> as StagedMatrixPrecision>::StageSize;
365
366 pub type OGV<AS> = Vector<OG<AS>, OGS<AS>>;
368 pub type OSV<AS> = Vector<OS<AS>, OSS<AS>>;
369}
370
371pub type Args<MS> = <MS as AttentionSpec>::Args;
372
373#[derive(Debug, Clone, Eq, PartialEq, Hash)]
374pub struct AttentionElems {
375 pub query_global: StorageType,
376 pub query_tile: StorageType,
377 pub key_global: StorageType,
378 pub key_stage: StorageType,
379 pub value_global: StorageType,
380 pub value_stage: StorageType,
381 pub key_value_tile: StorageType,
382 pub softmax_acc: StorageType,
383 pub softmax_lhs: StorageType,
384 pub accumulator: StorageType,
385 pub mask: StorageType,
386 pub out_global: StorageType,
387 pub out_stage: StorageType,
388}
389
390impl AttentionElems {
391 pub fn from_global_types(
392 global_dtypes: &AttentionGlobalTypes,
393 tile_type: StorageType,
394 accumulator_precision: &AccumulatorPrecision,
395 ) -> AttentionElems {
396 let accumulator = match accumulator_precision {
397 AccumulatorPrecision::Strict(storage_type) => *storage_type,
398 AccumulatorPrecision::Loose => AccumulatorPrecision::default_accumulator_type(),
399 };
400
401 Self {
402 query_global: global_dtypes.query,
403 query_tile: tile_type,
404 key_global: global_dtypes.key,
405 key_stage: tile_type,
406 value_global: global_dtypes.value,
407 value_stage: tile_type,
408 key_value_tile: tile_type,
409 softmax_acc: accumulator,
410 softmax_lhs: tile_type,
411 accumulator,
412 mask: global_dtypes.mask,
413 out_global: global_dtypes.out,
414 out_stage: global_dtypes.out,
415 }
416 }
417}
418
419impl From<&AttentionElems> for [StorageType; 5] {
420 fn from(elems: &AttentionElems) -> Self {
421 [
422 elems.query_global,
423 elems.key_global,
424 elems.value_global,
425 elems.mask,
426 elems.out_global,
427 ]
428 }
429}