use cubecl::{
cmma::MatrixIdent,
ir::{DeviceProperties, ElemType},
};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct MmaIo {
pub lhs_load_method: LoadMethod,
pub rhs_load_method: LoadMethod,
pub acc_load_method: LoadMethod,
pub store_method: StoreMethod,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum LoadMethod {
Manual,
LoadMatrix,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum StoreMethod {
Manual,
StoreMatrix,
}
impl Default for MmaIo {
fn default() -> Self {
Self {
lhs_load_method: LoadMethod::LoadMatrix,
rhs_load_method: LoadMethod::LoadMatrix,
..Self::manual()
}
}
}
impl MmaIo {
pub fn new(
device_props: &DeviceProperties,
lhs_stage: ElemType,
rhs_stage: ElemType,
acc_stage: ElemType,
) -> Self {
Self {
lhs_load_method: load_method(device_props, lhs_stage),
rhs_load_method: load_method(device_props, rhs_stage),
acc_load_method: load_method(device_props, acc_stage),
store_method: store_method(device_props, acc_stage),
}
}
pub fn manual() -> Self {
Self {
lhs_load_method: LoadMethod::Manual,
rhs_load_method: LoadMethod::Manual,
acc_load_method: LoadMethod::Manual,
store_method: StoreMethod::Manual,
}
}
pub fn load_method(&self, ident: MatrixIdent) -> LoadMethod {
match ident {
MatrixIdent::A => self.lhs_load_method,
MatrixIdent::B => self.rhs_load_method,
MatrixIdent::Accumulator => self.acc_load_method,
}
}
pub fn store_method(&self) -> StoreMethod {
self.store_method
}
}
fn load_method(device_props: &DeviceProperties, dtype: ElemType) -> LoadMethod {
if device_props.features.matmul.ldmatrix.contains(&dtype) {
LoadMethod::LoadMatrix
} else {
LoadMethod::Manual
}
}
fn store_method(device_props: &DeviceProperties, dtype: ElemType) -> StoreMethod {
if device_props.features.matmul.stmatrix.contains(&dtype) {
StoreMethod::StoreMatrix
} else {
StoreMethod::Manual
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct RegisterBlock {
pub budget: usize,
pub split_edge: bool,
pub component_fanout: bool,
}
impl RegisterBlock {
pub const fn new(budget: usize) -> Self {
Self {
budget,
split_edge: false,
component_fanout: false,
}
}
pub const fn split_edge(self) -> Self {
Self {
split_edge: true,
..self
}
}
pub const fn component_fanout(self) -> Self {
Self {
component_fanout: true,
..self
}
}
}