use std::marker::PhantomData;
use cubecl::ir::StorageType;
use cubecl::prelude::*;
use cubecl::server::TensorMapMeta;
pub use cubecl::zspace::metadata::Metadata;
use cubecl::zspace::{Shape, Strides, shape, strides};
use crate::MatrixLayout;
pub fn remap_storage_for_tma(ty: StorageType) -> StorageType {
if ty == f32::as_type_native_unchecked().storage_type() {
tf32::as_type_native_unchecked().storage_type()
} else {
ty
}
}
pub fn transpose_inner_for_tma(
shape: &mut Shape,
strides: &mut Strides,
layout: MatrixLayout,
) -> bool {
if matches!(layout, MatrixLayout::ColMajor) {
let s_rank = shape.num_dims();
let t_rank = strides.rank();
shape.swap(s_rank - 1, s_rank - 2);
strides.swap(t_rank - 1, t_rank - 2);
true
} else {
false
}
}
pub fn tma_operand<R: Runtime>(
binding: TensorBinding<R>,
batches: usize,
layout: MatrixLayout,
box_shape: (usize, usize),
storage_ty: StorageType,
swizzle: TensorMapSwizzle,
) -> (TensorMapArg<R, Tiled>, bool) {
let rank = binding.shape.len();
let mut shape = shape![batches, binding.shape[rank - 2], binding.shape[rank - 1]];
let mut strides: Strides = if rank > 2 {
binding.strides[rank - 3..].into()
} else {
strides![binding.strides[0], binding.strides[1]]
};
let transposed = transpose_inner_for_tma(&mut shape, &mut strides, layout);
if strides.len() == 2 {
let stride = strides[0];
strides.insert(0, stride);
}
let (box_rows, box_cols) = box_shape;
let tile_size = match transposed {
true => shape![1, box_cols, box_rows],
false => shape![1, box_rows, box_cols],
};
let meta = tma_meta_tiled(
Metadata::new(shape, strides),
tile_size,
remap_storage_for_tma(storage_ty),
swizzle,
);
let arg = TensorMapArg {
tensor: binding.into_tensor_arg(),
metadata: meta,
_kind: PhantomData,
};
(arg, transposed)
}
pub fn tma_meta_tiled(
metadata: Metadata,
tile_size: Shape,
storage_ty: StorageType,
swizzle: TensorMapSwizzle,
) -> TensorMapMeta {
let rank = metadata.rank();
TensorMapMeta {
format: TensorMapFormat::Tiled(TiledArgs { tile_size }),
metadata,
elem_stride: Strides::new(&vec![1; rank]),
interleave: TensorMapInterleave::None,
swizzle,
prefetch: TensorMapPrefetch::None,
oob_fill: OobFill::Zero,
storage_ty,
}
}