use cubecl_core::ir::{IndexOperands, Instruction, Memory};
use cubecl_core::{self as cubecl, prelude::*};
use cubecl_core::{intrinsic, ir::Value};
#[cube]
pub trait UnalignedVector<E: Scalar, N: Size>: CubeType {
fn unaligned_vector_read(&self, index: usize) -> Vector<E, N>;
fn unaligned_vector_write(&mut self, index: usize, value: Vector<E, N>);
}
type ArrayExpand<T> = NativeExpand<Array<T>>;
macro_rules! impl_unaligned_vector {
($type: ty) => {
#[cube]
impl<E: Scalar, N: Size> UnalignedVector<E, N> for $type {
fn unaligned_vector_read(&self, index: usize) -> Vector<E, N> {
unaligned_vector_read::<E, N>(self.as_slice(), index)
}
fn unaligned_vector_write(&mut self, index: usize, value: Vector<E, N>) {
unaligned_vector_write::<E, N>(self.as_mut_slice(), index, value)
}
}
};
}
impl_unaligned_vector!(Array<E>);
impl_unaligned_vector!(Tensor<E>);
impl_unaligned_vector!(Shared<[E]>);
#[cube]
fn unaligned_vector_read<E: Scalar, N: Size>(this: &[E], index: usize) -> Vector<E, N> {
intrinsic!(|scope| {
let list: Value = this.__extract_list(scope);
if !matches!(list.ty, cubecl::ir::Type::Scalar(_)) {
todo!("Unaligned reads are only allowed on scalar arrays for now");
}
let vector_size = N::__expand_value(scope);
let out = scope.create_value(Type::pointer(list.ty, list.address_space()));
scope.register(Instruction::new(
Memory::Index(IndexOperands {
list: list,
index: index.expand,
unroll_factor: 1,
checked: false,
}),
out,
));
let mut out: NativeExpand<Vector<E, N>> = out.into();
out.__expand_deref_method(scope)
})
}
#[cube]
fn unaligned_vector_write<E: Scalar, N: Size>(this: &mut [E], index: usize, value: Vector<E, N>) {
intrinsic!(|scope| {
let list: Value = this.__extract_list(scope);
if !matches!(list.ty, cubecl::ir::Type::Scalar(_)) {
todo!("Unaligned reads are only allowed on scalar arrays for now");
}
let vector_size = N::__expand_value(scope);
let out = scope.create_value(Type::pointer(list.ty, list.address_space()));
scope.register(Instruction::new(
Memory::Index(IndexOperands {
list,
index: index.expand,
unroll_factor: 1,
checked: false,
}),
out,
));
let mut out: NativeExpand<Vector<E, N>> = out.into();
out.__expand_assign_method(scope, value);
})
}