use cubecl::prelude::*;
use crate::*;
#[cube]
impl<EA: Float> Tile<EA> {
pub(crate) fn scale_and_mask(
&mut self,
scale: EA,
probe: &MaskProbe,
mask: &Tile<u32>,
state: &RowState<EA>,
) {
let rpu = comptime!(state.share.rows());
let rows = comptime!(self.place.space.extent_at(0));
let cols = comptime!(self.place.space.extent_at(1));
let w = self.vector_size();
let size!(W) = w;
let lines = comptime!(cols / w);
let mut view = self.flat_mut::<W>();
#[unroll]
for ri in 0..rpu {
let r = state.owned_row(ri);
if r < rows {
let q = probe.row_q(r);
#[unroll]
for line in 0..lines {
let i = r * lines + line;
let mut v = view.read(i) * Vector::<EA, W>::cast_from(scale);
#[unroll]
for j in 0..w {
let masked = probe.masked(q, probe.origin_s + line * w + j, mask);
v.insert(j, select(masked, EA::min_value(), v.extract(j)));
}
view.write(i, v);
}
}
}
}
pub(crate) fn row_max(&self, acc: &mut Array<EA>, state: &RowState<EA>) {
let rpu = comptime!(state.share.rows());
let rows = comptime!(self.place.space.extent_at(0));
let cols = comptime!(self.place.space.extent_at(1));
let w = self.vector_size();
let size!(W) = w;
let lines = comptime!(cols / w);
let view = self.flat::<W>();
#[unroll]
for ri in 0..rpu {
acc[ri] = state.m[ri];
let r = state.owned_row(ri);
if r < rows {
#[unroll]
for line in 0..lines {
let v = view.read(r * lines + line);
#[unroll]
for j in 0..w {
acc[ri] = max(acc[ri], v.extract(j));
}
}
}
}
}
pub(crate) fn exp_diff(&mut self, rowwise: &Array<EA>, state: &RowState<EA>) {
let rpu = comptime!(state.share.rows());
let rows = comptime!(self.place.space.extent_at(0));
let cols = comptime!(self.place.space.extent_at(1));
let threshold = EA::new(LOGIT_MASKED);
let w = self.vector_size();
let size!(W) = w;
let lines = comptime!(cols / w);
let mut view = self.flat_mut::<W>();
#[unroll]
for ri in 0..rpu {
let r = state.owned_row(ri);
if r < rows {
let live = EA::cast_from(rowwise[ri] >= threshold);
let safe_m = clamp_min(rowwise[ri], threshold);
#[unroll]
for line in 0..lines {
let i = r * lines + line;
let mut v = view.read(i);
#[unroll]
for j in 0..w {
v.insert(j, live * (v.extract(j) - safe_m).exp());
}
view.write(i, v);
}
}
}
}
pub(crate) fn row_sum(&self, acc: &mut Array<EA>, state: &RowState<EA>) {
let rpu = comptime!(state.share.rows());
let rows = comptime!(self.place.space.extent_at(0));
let cols = comptime!(self.place.space.extent_at(1));
let w = self.vector_size();
let size!(W) = w;
let lines = comptime!(cols / w);
let view = self.flat::<W>();
#[unroll]
for ri in 0..rpu {
acc[ri] = EA::from_int(0);
let r = state.owned_row(ri);
if r < rows {
#[unroll]
for line in 0..lines {
let v = view.read(r * lines + line);
#[unroll]
for j in 0..w {
acc[ri] += v.extract(j);
}
}
}
}
}
}