Construct ndarray::ArrayView from multiple dimensional array

pub type SquareMatrix<T = f32> = [[T; BOARD_SIZE]; BOARD_SIZE];
pub type StateTensor<T = f32> = [SquareMatrix<T>; CHANNELS];

pub trait StateTensorExtension {
    fn shape(self: &Self) -> [usize; 3];
}
impl<T> StateTensorExtension for StateTensor<T> {
    fn shape(self: &Self) -> [usize; 3] {
        return [CHANNELS, BOARD_SIZE, BOARD_SIZE];
    }
}

I am using a quite ugly style to construct an array view from the array

    let state_tensor: StateTensor<f32> = // ...;
    let dims = state_tensor.shape();
    let x: ArrayBase<ViewRepr<&f32>, _> = unsafe {
        ArrayView::from_shape_ptr(dims, bytemuck::cast_slice(&state_tensor).as_ptr())
    };

The above code assumes multiple dimensional arrays are tightly packed in Rust. Would that work always?
What is the best way to construct ndarray::ArrayView from multiple dimensional array in my case? Or should I created a owned array instead?

Yes. Look at the array layout reference. It says that, essentially, arrays are always tightly packed and that they don't carry around extra meta-data. This means that multi-dimensional arrays are both tightly packed and stored in row-major order.

You shouldn't use unsafe for this! Why don't you simply use the from_shape() method of ArrayView?

let x = ArrayView::<f32, _>::from_shape(
    dims.into_dimension(),
    bytemuck::cast_slice::<_, f32>(&state_tensor)
);

Playground

2 Likes