1use alloc::{format, string::String};
2use derive_more::Display;
3use derive_new::new;
4
5use super::Value;
6use crate::{Closure, OperationReflect};
7use crate::{StorageType, TypeHash};
8use core::fmt::Display;
9
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[derive(Debug, Clone, Copy, TypeHash, PartialEq, Eq, Hash, PartialOrd, Ord, Display)]
12#[allow(missing_docs)]
13pub enum MatrixIdent {
14 #[display("IdentA")]
15 A,
16 #[display("IdentB")]
17 B,
18 #[display("IdentAcc")]
19 Accumulator,
20}
21
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[derive(Debug, Clone, Copy, TypeHash, PartialEq, Eq, Hash, PartialOrd, Ord, Display)]
24#[display(rename_all = "snake_case")]
25#[allow(missing_docs)]
26pub enum MatrixLayout {
27 ColMajor,
28 RowMajor,
29 Undefined,
30}
31
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33#[derive(Debug, Clone, Copy, TypeHash, PartialEq, Eq, Hash, PartialOrd, Ord, Display)]
34#[display(rename_all = "snake_case")]
35#[allow(missing_docs)]
36pub enum MatrixScope {
37 Plane,
38 Cube,
39}
40
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[derive(new, Debug, Clone, Copy, TypeHash, PartialEq, Eq, Hash, PartialOrd, Ord)]
43#[allow(missing_docs)]
44pub struct MatrixType {
45 pub ident: MatrixIdent,
46 pub m: usize,
47 pub n: usize,
48 pub k: usize,
49 pub storage: StorageType,
50 pub layout: MatrixLayout,
51 pub scope: MatrixScope,
52}
53
54impl MatrixType {
55 pub fn num_elems(&self) -> usize {
57 let elems = match self.ident {
58 MatrixIdent::A => self.m * self.k,
59 MatrixIdent::B => self.k * self.n,
60 MatrixIdent::Accumulator => self.m * self.n,
61 };
62 elems / self.storage.packing_factor()
63 }
64}
65
66#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67#[derive(Debug, Clone, Copy, TypeHash, PartialEq, Eq, Hash, PartialOrd, Ord)]
68pub enum ClampMode {
69 Undefined,
70 Constant(u32),
71 ClampToEdge,
72 Repeat,
73 RepeatMirrored,
74}
75
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78#[derive(Debug, Clone, TypeHash, PartialEq, Eq, Hash, OperationReflect)]
79#[operation(opcode_name = CmmaOpCode)]
80#[allow(missing_docs)]
81pub enum CoopMma {
82 Fill { value: Value },
84 Load {
86 #[args(allow_ptr, ptr_read)]
87 ptr: Value,
88 stride: Value,
89 #[args(skip)]
90 layout: Option<MatrixLayout>,
91 },
92 LoadTensor {
94 #[args(allow_ptr, ptr_read)]
95 buffer: Value,
96 layout: Value,
97 #[args(skip)]
98 view: Option<Value>,
99 },
100 Execute {
104 mat_a: Value,
105 mat_b: Value,
106 mat_c: Value,
107 },
108 Store {
110 mat: Value,
111 stride: Value,
112 #[args(allow_ptr, ptr_write)]
113 destination: Value,
114 #[args(skip)]
115 layout: MatrixLayout,
116 },
117 StoreTensor {
119 mat: Value,
120 layout: Value,
121 #[args(skip)]
122 view: Option<Value>,
123 },
124 Cast { input: Value },
126
127 RowIndex {
129 lane_id: Value,
130 i: Value,
131 #[args(skip)]
132 matrix: MatrixType,
133 },
134 ColIndex {
136 lane_id: Value,
137 i: Value,
138 #[args(skip)]
139 matrix: MatrixType,
140 },
141 LoadMatrix {
143 #[args(allow_ptr, ptr_read)]
144 ptr: Value,
145 factor: usize,
146 transpose: bool,
147 },
148 StoreMatrix {
150 registers: Value,
151 factor: usize,
152 transpose: bool,
153 #[args(allow_ptr, ptr_write)]
154 destination: Value,
155 },
156 ExecuteManual {
158 #[args(skip)]
159 matrix: MatrixType,
160 registers_a: Value,
161 registers_b: Value,
162 registers_c: Value,
163 },
164 ExecuteScaled {
166 #[args(skip)]
167 matrix: MatrixType,
168 registers_a: Value,
169 registers_b: Value,
170 registers_c: Value,
171 scales_a: Value,
172 scales_b: Value,
173 scales_factor: usize,
174 },
175 ExecuteElementwise {
176 matrix: Value,
177 #[args(skip)]
178 op: Closure,
179 },
180}
181
182impl Display for CoopMma {
183 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
184 match self {
185 CoopMma::Fill { value } => write!(f, "fill({value})"),
186 CoopMma::Load {
187 ptr,
188 stride,
189 layout,
190 } => {
191 let layout = layout
192 .map(|it| format!(", layout: {it:?}"))
193 .unwrap_or(String::new());
194 write!(f, "matrix_load({ptr}, stride: {stride}{layout})")
195 }
196 CoopMma::LoadTensor {
197 buffer,
198 layout,
199 view,
200 } => {
201 let view = view.map(|it| format!(", view: {it}")).unwrap_or_default();
202 write!(f, "matrix_load_tensor({buffer}, layout: {layout}{view})")
203 }
204 CoopMma::Execute {
205 mat_a,
206 mat_b,
207 mat_c,
208 } => write!(f, "execute_cmma({mat_a}, {mat_b}, {mat_c})"),
209 CoopMma::ExecuteManual {
210 matrix,
211 registers_a,
212 registers_b,
213 registers_c,
214 } => {
215 write!(
216 f,
217 "execute_manual_mma(
218 matrix: {matrix:?},
219 frag_a: {registers_a},
220 frag_b: {registers_b},
221 frag_c: {registers_c},
222 )"
223 )
224 }
225 CoopMma::ExecuteScaled {
226 matrix,
227 registers_a,
228 registers_b,
229 registers_c,
230 scales_a,
231 scales_b,
232 scales_factor,
233 } => {
234 write!(
235 f,
236 "execute_scaled_mma_{scales_factor}x(
237 matrix: {matrix:?},
238 frag_a: {registers_a},
239 frag_b: {registers_b},
240 frag_c: {registers_c},
241 scales_a: {scales_a},
242 scales_b: {scales_b}
243 )"
244 )
245 }
246 CoopMma::ExecuteElementwise { matrix, op } => {
247 write!(f, "execute_elementwise({matrix}, {op})")
248 }
249 CoopMma::Store {
250 mat,
251 stride,
252 destination,
253 layout,
254 } => write!(
255 f,
256 "matrix_store({mat}, stride: {stride}, layout: {layout:?}, dest: {destination})"
257 ),
258 CoopMma::StoreTensor { mat, layout, .. } => {
259 write!(f, "matrix_store_tensor({mat}, layout: {layout})")
260 }
261 CoopMma::Cast { input } => {
262 write!(f, "matrix_cast(input: {input})")
263 }
264 CoopMma::RowIndex { lane_id, i, matrix } => {
265 write!(f, "row_idx(lane_id: {lane_id}, i: {i}, matrix: {matrix:?})",)
266 }
267 CoopMma::ColIndex { lane_id, i, matrix } => {
268 write!(f, "col_idx(lane_id: {lane_id}, i: {i}, matrix: {matrix:?})",)
269 }
270 CoopMma::LoadMatrix {
271 ptr,
272 factor,
273 transpose,
274 } => {
275 write!(f, "ldmatrix_{factor}x({ptr}, transpose: {transpose})")
276 }
277 CoopMma::StoreMatrix {
278 registers,
279 factor,
280 transpose,
281 destination,
282 } => {
283 write!(
284 f,
285 "stmatrix_{factor}x({registers}, dest: {destination}, transpose: {transpose})"
286 )
287 }
288 }
289 }
290}