use cubecl::{
cmma::{MatrixIdent, MatrixLayout, MmaDefinition},
prelude::*,
};
use crate::*;
pub(super) const LDMATRIX_ROW_BYTES: usize = 16;
#[cube]
pub(super) fn load_ldmatrix<T: Numeric, W: Size, N: Size, A: Numeric, B: Numeric, CD: Numeric>(
src: &Tile<T>,
fragment: &mut Array<Vector<T, N>>,
def: &MmaDefinition<A, B, CD>,
#[comptime] ident: MatrixIdent,
#[comptime] layout: MatrixLayout,
#[comptime] edges: (usize, usize),
) {
let width = src.vector_size();
let elem_size = T::size().comptime();
let row_cells = comptime!(LDMATRIX_ROW_BYTES / elem_size);
let (rows, cols) = comptime!(edges);
let col_major_window = comptime!(match layout {
MatrixLayout::RowMajor => false,
MatrixLayout::ColMajor => true,
MatrixLayout::Undefined => {
panic!("MmaData::load: an ldmatrix load reads a row- or col-major window")
}
});
let view = if comptime!(col_major_window) {
src.fragment_matrix_packed::<W>(cols, rows)
} else {
src.fragment_matrix_packed::<W>(rows, cols)
};
let num_regs = def.vectors_per_lane(ident);
let vector_size = def.vector_size(ident);
let vector_layout = def.vector_layout(ident);
let instruction_transposes = comptime!(vector_layout != layout);
let unit = UNIT_POS_PLANE;
let row_in_matrix = unit % 8;
let nth_matrix = unit / 8 % comptime!(num_regs as u32);
let (row, col) = def.position_of_nth(0, nth_matrix * comptime!(vector_size as u32), ident);
let (line_row, cell) = if comptime!(col_major_window) {
(col + row_in_matrix, row)
} else {
(row + row_in_matrix, col)
};
let row_slice = view.line_slice(
(line_row, cell / comptime!(width as u32)),
(
1u32.runtime(),
comptime!((row_cells / width) as u32).runtime(),
),
);
let regs =
def.load_matrix::<Vector<T, W>, N>(row_slice, ident, num_regs, instruction_transposes);
#[unroll]
for i in 0..num_regs {
fragment[i] = regs[i];
}
}