use cubecl::prelude::*;
use crate::{
AccumulateArg, AccumulateArgLaunch, Bound, Partitioning, Tile, TileArg, TmaOperand, TmaTileArg,
TmaTileArgLaunch,
};
#[derive(CubeType, CubeLaunch)]
pub enum Input<'a, E: Numeric, V: Size> {
Tensor(TileArg<'a, E, V>),
TensorMap(TmaTileArg<E>),
}
#[derive(CubeType, CubeLaunch)]
pub enum Output<'a, E: Numeric, V: Size> {
Tensor(TileArg<'a, E, V>),
Atomic(AccumulateArg<'a, E>),
}
#[cube]
impl<'a, E: Numeric, V: Size> Input<'a, E, V> {
pub fn tile(&self, #[comptime] partitioning: Partitioning) -> Tile<E> {
match self {
Input::Tensor(arg) => arg.tile(partitioning),
Input::TensorMap(arg) => arg.tile(partitioning),
}
}
}
#[cube]
impl<'a, E: Numeric, V: Size> Output<'a, E, V> {
pub fn tile(&self, #[comptime] partitioning: Partitioning) -> Tile<E> {
match self {
Output::Tensor(arg) => arg.tile(partitioning),
Output::Atomic(arg) => arg.tile::<V>(partitioning),
}
}
}
impl Bound {
pub fn input<E: Numeric, V: Size>(self) -> InputArgs<'static, E, V> {
InputArgs::Tensor(self.arg())
}
pub fn output<E: Numeric, V: Size>(self) -> OutputArgs<'static, E, V> {
OutputArgs::Tensor(self.arg())
}
pub fn atomic<E: Numeric, V: Size>(self) -> OutputArgs<'static, E, V> {
let spec = self.spec.clone();
OutputArgs::Atomic(AccumulateArgLaunch::new(self.tensor(), spec))
}
}
impl TmaOperand {
pub fn input<E: Numeric, V: Size>(self) -> InputArgs<'static, E, V> {
InputArgs::TensorMap(TmaTileArgLaunch::tensor_map(
self.map, &self.axes, self.shape,
))
}
}