Skip to main content

cubecl_cpp/hip/mma/
rocwmma_compiler.rs

1use crate::{
2    hip::{
3        HipDialect,
4        arch::AMDArchitecture,
5        mma::{compile_manual_mma, supported_mma_combinations},
6    },
7    shared::{
8        DialectWmmaCompiler, Flags, FragmentIdent, FragmentLayout, FragmentType, ManualMma,
9        SupportedMmaCombinations, Value, WmmaInstruction, wmma_api_base,
10    },
11};
12use cubecl_core::ir::{self as gpu, features::MmaConfig};
13
14const ROCWMMA_NAMESPACE: &str = "rocwmma";
15
16#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
17pub struct RocWmmaCompiler {}
18
19impl DialectWmmaCompiler<HipDialect<Self>> for RocWmmaCompiler {
20    fn compile_wmma_includes(
21        f: &mut std::fmt::Formatter<'_>,
22        _flags: &Flags<HipDialect<Self>>,
23    ) -> std::fmt::Result {
24        f.write_str("#include <rocwmma/rocwmma.hpp>\n")
25    }
26
27    fn compile_wmma_type_definitions(
28        f: &mut std::fmt::Formatter<'_>,
29        flags: &Flags<HipDialect<Self>>,
30    ) -> std::fmt::Result {
31        // For manual MMA, maybe add a flag for this at some point
32        if flags.elem_bf16 {
33            f.write_str("typedef __bf16 bhalf8_t __attribute__((ext_vector_type(8)));\n")?;
34            f.write_str("typedef __bf16 bhalf16_t __attribute__((ext_vector_type(16)));\n")?;
35        }
36        if flags.elem_f16 {
37            f.write_str("typedef _Float16 half8_t __attribute__((ext_vector_type(8)));\n")?;
38            f.write_str("typedef _Float16 half16_t __attribute__((ext_vector_type(16)));\n")?;
39        }
40        f.write_str("typedef float float8_t __attribute__((ext_vector_type(8)));\n")
41    }
42
43    fn compile_wmma_local_variables(_f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        Ok(())
45    }
46
47    fn compile_wmma_fragment_declaration(
48        f: &mut std::fmt::Formatter<'_>,
49        val: &crate::shared::Value<HipDialect<Self>>,
50        ty: &crate::shared::Item<HipDialect<Self>>,
51    ) -> std::fmt::Result {
52        wmma_api_base::compile_fragment_declaration(f, val, ty)
53    }
54
55    fn compile_wwma_fragment_ident(
56        f: &mut std::fmt::Formatter<'_>,
57        ident: &FragmentIdent<HipDialect<Self>>,
58    ) -> std::fmt::Result {
59        wmma_api_base::compile_fragment_ident(f, ROCWMMA_NAMESPACE, ident)
60    }
61
62    fn compile_wmma_fragment_layout(
63        f: &mut std::fmt::Formatter<'_>,
64        layout: &FragmentLayout<HipDialect<Self>>,
65    ) -> std::fmt::Result {
66        wmma_api_base::compile_fragment_layout(f, ROCWMMA_NAMESPACE, layout)
67    }
68
69    fn compile_wmma_fragment(
70        f: &mut std::fmt::Formatter<'_>,
71        fragment: &FragmentType<HipDialect<Self>>,
72    ) -> std::fmt::Result {
73        wmma_api_base::compile_fragment(f, ROCWMMA_NAMESPACE, fragment)
74    }
75
76    fn compile_wmma_instruction(
77        f: &mut std::fmt::Formatter<'_>,
78        instruction: &WmmaInstruction<HipDialect<Self>>,
79    ) -> std::fmt::Result {
80        wmma_api_base::compile_instruction(f, ROCWMMA_NAMESPACE, instruction)
81    }
82
83    fn compile_manual_mma(
84        f: &mut std::fmt::Formatter<'_>,
85        mma: ManualMma<HipDialect<Self>>,
86    ) -> std::fmt::Result {
87        compile_manual_mma(f, mma.shape, mma.frag_a, mma.frag_b, mma.frag_c, mma.frag_d)
88    }
89
90    fn compile_scaled_mma(
91        f: &mut std::fmt::Formatter<'_>,
92        _mma: ManualMma<HipDialect<Self>>,
93        _scales_a: Value<HipDialect<Self>>,
94        _scales_b: Value<HipDialect<Self>>,
95        _scales_factor: u32,
96    ) -> std::fmt::Result {
97        f.write_str("#error Scaled MMA not supported on HIP\n")
98    }
99
100    fn supported_wmma_combinations(arch: &AMDArchitecture) -> SupportedMmaCombinations {
101        let combinations = match arch {
102            AMDArchitecture::GFX12 => {
103                // Group types by their tile dimensions for readability
104                let tdims_16_16_32 = vec![(16, 16, 32)];
105                let types_16_16_32 = vec![
106                    (
107                        gpu::ElemType::Float(gpu::FloatKind::E5M2), // bfloat8_t / bf8
108                        gpu::ElemType::Float(gpu::FloatKind::F32),
109                        gpu::ElemType::Float(gpu::FloatKind::F32),
110                    ),
111                    (
112                        gpu::ElemType::Float(gpu::FloatKind::E4M3), // float8_t / f8
113                        gpu::ElemType::Float(gpu::FloatKind::F32),
114                        gpu::ElemType::Float(gpu::FloatKind::F32),
115                    ),
116                ];
117
118                let tdims_16_16_16 = vec![(16, 16, 16)];
119                let types_16_16_16 = vec![
120                    (
121                        gpu::ElemType::Int(gpu::IntKind::I8),
122                        gpu::ElemType::Int(gpu::IntKind::I32),
123                        gpu::ElemType::Int(gpu::IntKind::I32),
124                    ),
125                    (
126                        gpu::ElemType::Int(gpu::IntKind::I8),
127                        gpu::ElemType::Int(gpu::IntKind::I8),
128                        gpu::ElemType::Int(gpu::IntKind::I32),
129                    ),
130                    (
131                        gpu::ElemType::Float(gpu::FloatKind::F16),
132                        gpu::ElemType::Float(gpu::FloatKind::F32),
133                        gpu::ElemType::Float(gpu::FloatKind::F32),
134                    ),
135                    (
136                        gpu::ElemType::Float(gpu::FloatKind::F16),
137                        gpu::ElemType::Float(gpu::FloatKind::F16),
138                        gpu::ElemType::Float(gpu::FloatKind::F32),
139                    ),
140                    (
141                        gpu::ElemType::Float(gpu::FloatKind::F16),
142                        gpu::ElemType::Float(gpu::FloatKind::F16),
143                        gpu::ElemType::Float(gpu::FloatKind::F16),
144                    ),
145                    (
146                        gpu::ElemType::Float(gpu::FloatKind::BF16),
147                        gpu::ElemType::Float(gpu::FloatKind::F32),
148                        gpu::ElemType::Float(gpu::FloatKind::F32),
149                    ),
150                    (
151                        gpu::ElemType::Float(gpu::FloatKind::BF16),
152                        gpu::ElemType::Float(gpu::FloatKind::BF16),
153                        gpu::ElemType::Float(gpu::FloatKind::F32),
154                    ),
155                    (
156                        gpu::ElemType::Float(gpu::FloatKind::BF16),
157                        gpu::ElemType::Float(gpu::FloatKind::BF16),
158                        gpu::ElemType::Float(gpu::FloatKind::BF16),
159                    ),
160                ];
161
162                // Combine all type-dimension pairs
163                types_16_16_32
164                    .into_iter()
165                    .map(|it| (it, tdims_16_16_32.clone()))
166                    .chain(
167                        types_16_16_16
168                            .into_iter()
169                            .map(|it| (it, tdims_16_16_16.clone())),
170                    )
171                    .collect()
172            }
173            AMDArchitecture::GFX10 | AMDArchitecture::GFX11 => {
174                // For gfx11 the supported tile dimensions are always the same
175                //                                   m   n   k
176                let tdims = vec![(16, 16, 16), (16, 16, 32)];
177                let types = vec![
178                    (
179                        gpu::ElemType::Float(gpu::FloatKind::F16), // m / i
180                        gpu::ElemType::Float(gpu::FloatKind::F32), // n / o
181                        gpu::ElemType::Float(gpu::FloatKind::F32), // k / c
182                    ),
183                    (
184                        gpu::ElemType::Float(gpu::FloatKind::F16),
185                        gpu::ElemType::Float(gpu::FloatKind::F16),
186                        gpu::ElemType::Float(gpu::FloatKind::F32),
187                    ),
188                    (
189                        gpu::ElemType::Float(gpu::FloatKind::F16),
190                        gpu::ElemType::Float(gpu::FloatKind::F16),
191                        gpu::ElemType::Float(gpu::FloatKind::F16),
192                    ),
193                    (
194                        gpu::ElemType::Float(gpu::FloatKind::BF16),
195                        gpu::ElemType::Float(gpu::FloatKind::F32),
196                        gpu::ElemType::Float(gpu::FloatKind::F32),
197                    ),
198                    (
199                        gpu::ElemType::Float(gpu::FloatKind::BF16),
200                        gpu::ElemType::Float(gpu::FloatKind::BF16),
201                        gpu::ElemType::Float(gpu::FloatKind::F32),
202                    ),
203                    (
204                        gpu::ElemType::Float(gpu::FloatKind::BF16),
205                        gpu::ElemType::Float(gpu::FloatKind::BF16),
206                        gpu::ElemType::Float(gpu::FloatKind::BF16),
207                    ),
208                ];
209                types.into_iter().map(|it| (it, tdims.clone())).collect()
210            }
211            AMDArchitecture::GFX908 => {
212                vec![
213                    (
214                        (
215                            gpu::ElemType::Float(gpu::FloatKind::F32), // m / i
216                            gpu::ElemType::Float(gpu::FloatKind::F32), // n / o
217                            gpu::ElemType::Float(gpu::FloatKind::F32),
218                        ), // k / c
219                        vec![
220                            //m  n   k
221                            (16, 16, 4),
222                            (16, 16, 8),
223                            (16, 16, 16),
224                            (16, 16, 32),
225                            (32, 32, 2),
226                            (32, 32, 4),
227                            (32, 32, 8),
228                            (32, 32, 16),
229                            (32, 32, 32),
230                        ],
231                    ),
232                    (
233                        (
234                            gpu::ElemType::Float(gpu::FloatKind::F16),
235                            gpu::ElemType::Float(gpu::FloatKind::F32),
236                            gpu::ElemType::Float(gpu::FloatKind::F32),
237                        ),
238                        vec![
239                            (16, 16, 16),
240                            (16, 16, 32),
241                            (32, 32, 8),
242                            (32, 32, 16),
243                            (32, 32, 32),
244                        ],
245                    ),
246                    (
247                        (
248                            gpu::ElemType::Float(gpu::FloatKind::F16),
249                            gpu::ElemType::Float(gpu::FloatKind::F16),
250                            gpu::ElemType::Float(gpu::FloatKind::F32),
251                        ),
252                        vec![
253                            (16, 16, 16),
254                            (16, 16, 32),
255                            (32, 32, 8),
256                            (32, 32, 16),
257                            (32, 32, 32),
258                        ],
259                    ),
260                    (
261                        (
262                            gpu::ElemType::Float(gpu::FloatKind::F16),
263                            gpu::ElemType::Float(gpu::FloatKind::F16),
264                            gpu::ElemType::Float(gpu::FloatKind::F16),
265                        ),
266                        vec![
267                            (16, 16, 16),
268                            (16, 16, 32),
269                            (32, 32, 8),
270                            (32, 32, 16),
271                            (32, 32, 32),
272                        ],
273                    ),
274                    (
275                        (
276                            gpu::ElemType::Float(gpu::FloatKind::BF16),
277                            gpu::ElemType::Float(gpu::FloatKind::F32),
278                            gpu::ElemType::Float(gpu::FloatKind::F32),
279                        ),
280                        vec![
281                            (16, 16, 8),
282                            (16, 16, 16),
283                            (16, 16, 32),
284                            (32, 32, 4),
285                            (32, 32, 8),
286                            (32, 32, 16),
287                            (32, 32, 32),
288                        ],
289                    ),
290                    (
291                        (
292                            gpu::ElemType::Float(gpu::FloatKind::BF16),
293                            gpu::ElemType::Float(gpu::FloatKind::BF16),
294                            gpu::ElemType::Float(gpu::FloatKind::F32),
295                        ),
296                        vec![
297                            (16, 16, 8),
298                            (16, 16, 16),
299                            (16, 16, 32),
300                            (32, 32, 4),
301                            (32, 32, 8),
302                            (32, 32, 16),
303                            (32, 32, 32),
304                        ],
305                    ),
306                    (
307                        (
308                            gpu::ElemType::Float(gpu::FloatKind::BF16),
309                            gpu::ElemType::Float(gpu::FloatKind::BF16),
310                            gpu::ElemType::Float(gpu::FloatKind::BF16),
311                        ),
312                        vec![
313                            (16, 16, 8),
314                            (16, 16, 16),
315                            (16, 16, 32),
316                            (32, 32, 4),
317                            (32, 32, 8),
318                            (32, 32, 16),
319                            (32, 32, 32),
320                        ],
321                    ),
322                ]
323            }
324            AMDArchitecture::GFX90A | AMDArchitecture::GFX94 => {
325                vec![
326                    (
327                        (
328                            gpu::ElemType::Float(gpu::FloatKind::F32), // m / i
329                            gpu::ElemType::Float(gpu::FloatKind::F32), // n / o
330                            gpu::ElemType::Float(gpu::FloatKind::F32),
331                        ), // k / c
332                        vec![
333                            //m  n   k
334                            (16, 16, 4),
335                            (16, 16, 8),
336                            (16, 16, 16),
337                            (16, 16, 32),
338                            (32, 32, 2),
339                            (32, 32, 4),
340                            (32, 32, 8),
341                            (32, 32, 16),
342                            (32, 32, 32),
343                        ],
344                    ),
345                    (
346                        (
347                            gpu::ElemType::Float(gpu::FloatKind::F16),
348                            gpu::ElemType::Float(gpu::FloatKind::F32),
349                            gpu::ElemType::Float(gpu::FloatKind::F32),
350                        ),
351                        vec![
352                            (16, 16, 16),
353                            (16, 16, 32),
354                            (32, 32, 8),
355                            (32, 32, 16),
356                            (32, 32, 32),
357                        ],
358                    ),
359                    (
360                        (
361                            gpu::ElemType::Float(gpu::FloatKind::F16),
362                            gpu::ElemType::Float(gpu::FloatKind::F16),
363                            gpu::ElemType::Float(gpu::FloatKind::F32),
364                        ),
365                        vec![
366                            (16, 16, 16),
367                            (16, 16, 32),
368                            (32, 32, 8),
369                            (32, 32, 16),
370                            (32, 32, 32),
371                        ],
372                    ),
373                    (
374                        (
375                            gpu::ElemType::Float(gpu::FloatKind::F16),
376                            gpu::ElemType::Float(gpu::FloatKind::F16),
377                            gpu::ElemType::Float(gpu::FloatKind::F16),
378                        ),
379                        vec![
380                            (16, 16, 16),
381                            (16, 16, 32),
382                            (32, 32, 8),
383                            (32, 32, 16),
384                            (32, 32, 32),
385                        ],
386                    ),
387                    (
388                        (
389                            gpu::ElemType::Float(gpu::FloatKind::BF16),
390                            gpu::ElemType::Float(gpu::FloatKind::F32),
391                            gpu::ElemType::Float(gpu::FloatKind::F32),
392                        ),
393                        vec![
394                            (16, 16, 16),
395                            (16, 16, 32),
396                            (32, 32, 8),
397                            (32, 32, 16),
398                            (32, 32, 32),
399                        ],
400                    ),
401                    (
402                        (
403                            gpu::ElemType::Float(gpu::FloatKind::BF16),
404                            gpu::ElemType::Float(gpu::FloatKind::BF16),
405                            gpu::ElemType::Float(gpu::FloatKind::F32),
406                        ),
407                        vec![
408                            (16, 16, 16),
409                            (16, 16, 32),
410                            (32, 32, 8),
411                            (32, 32, 16),
412                            (32, 32, 32),
413                        ],
414                    ),
415                    (
416                        (
417                            gpu::ElemType::Float(gpu::FloatKind::BF16),
418                            gpu::ElemType::Float(gpu::FloatKind::BF16),
419                            gpu::ElemType::Float(gpu::FloatKind::BF16),
420                        ),
421                        vec![
422                            (16, 16, 16),
423                            (16, 16, 32),
424                            (32, 32, 8),
425                            (32, 32, 16),
426                            (32, 32, 32),
427                        ],
428                    ),
429                ]
430            }
431            AMDArchitecture::Other => vec![],
432        };
433        combinations
434            .into_iter()
435            .flat_map(|(ty, sizes)| sizes.into_iter().map(move |size| (ty, size)))
436            .map(|((i, o, c), (m, n, k))| MmaConfig {
437                a_type: i.into(),
438                b_type: o.into(),
439                cd_type: c.into(),
440                m,
441                n,
442                k,
443            })
444            .collect()
445    }
446
447    fn supported_mma_combinations(arch: &AMDArchitecture) -> SupportedMmaCombinations {
448        supported_mma_combinations(arch)
449    }
450}