use cubecl::prelude::*;
#[derive(CubeType, Clone)]
#[expand(derive(Clone))]
pub struct Scale<FS: CubePrimitive> {
pub(super) inner: FS,
pub(super) global: ComptimeOption<f32>,
}
#[cube]
impl<FS: CubePrimitive> Scale<FS> {
pub fn dequantize_symmetric<F: Float, N: Size>(&self, values: Vector<F, N>) -> Vector<F, N> {
#[comptime]
match self.global {
ComptimeOption::Some(global) => Vector::cast_from(
Vector::<f32, N>::cast_from(values) * Vector::new(self.effective(global)),
),
ComptimeOption::None => values * Vector::cast_from(self.inner),
}
}
pub fn quantize_symmetric<F: Float, N: Size>(&self, values: Vector<F, N>) -> Vector<F, N> {
#[comptime]
match self.global {
ComptimeOption::Some(global) => Vector::cast_from(
Vector::<f32, N>::cast_from(values) / Vector::new(self.effective(global)),
),
ComptimeOption::None => values / Vector::cast_from(self.inner),
}
}
fn effective(&self, global: f32) -> f32 {
global * f32::cast_from(self.inner)
}
}