use crate::domain::error::{LetoError, Result};
use super::Layout;
impl<const N: usize> Layout<N> {
pub fn broadcast<const M: usize>(&self, target_shape: [usize; M]) -> Result<Layout<M>> {
if M < N {
return Err(LetoError::IncompatibleBroadcast {
from: self.shape.to_vec(),
to: target_shape.to_vec(),
});
}
let mut new_shape = [0usize; M];
let mut new_strides = [0isize; M];
let shift = M - N;
for i in 0..shift {
new_shape[i] = target_shape[i];
new_strides[i] = 0; }
for i in 0..N {
let target_idx = i + shift;
let target_dim = target_shape[target_idx];
let source_dim = self.shape[i];
if source_dim == target_dim {
new_shape[target_idx] = target_dim;
new_strides[target_idx] = self.strides[i];
} else if source_dim == 1 {
new_shape[target_idx] = target_dim;
new_strides[target_idx] = 0; } else {
return Err(LetoError::IncompatibleBroadcast {
from: self.shape.to_vec(),
to: target_shape.to_vec(),
});
}
}
Ok(Layout {
shape: new_shape,
strides: new_strides,
offset: self.offset,
})
}
}