use cubecl::ir::Scope;
use cubecl::prelude::*;
use crate::{Axis, Coords, Space};
pub trait Reads {
fn reads(&self, scope: &Scope, axis: Axis) -> bool;
}
pub trait FactorReads {
fn factor_reads(&self, scope: &Scope, factor: usize, axis: Axis) -> bool;
}
#[derive(CubeType, Clone)]
#[expand(derive(Clone))]
pub struct RecipeCoords {
origin: Coords<u32>,
offset: Coords<u32>,
#[cube(comptime)]
pub space: Space,
}
#[cube]
impl RecipeCoords {
pub(crate) fn new(
origin: &Coords<u32>,
offset: &Coords<u32>,
#[comptime] space: Space,
) -> Self {
RecipeCoords {
origin: origin.clone(),
offset: offset.clone(),
space,
}
}
pub fn at(&self, #[comptime] p: usize) -> u32 {
self.origin.at(p) + self.offset.at(p)
}
pub fn along(&self, #[comptime] axis: Axis) -> u32 {
self.at(comptime!(self.space.position(axis)))
}
}
#[cube(expand_base_traits = "ExpandTypeClone")]
pub trait Recipe<T: Numeric> {
fn evaluate(&self, coordinates: &RecipeCoords) -> T;
}
#[cube]
pub trait Separable<T: Numeric>: Recipe<T> {
fn factors(&self) -> comptime_type!(usize);
fn factor(&self, coordinates: &RecipeCoords, #[comptime] factor: usize) -> T;
}