In Rust I'm trying to implement a 2D convolution (e.g. image blurring) with a 256x256 grey-image and a 3x3 kernel using the ndarray
crate for all matrix operations. I'm vectorising the algorithm to speed up and parallelise the process as instructed in https://towardsdatascience.com/how-are-convolutions-actually-performed-under-the-hood-226523ce7fbf
For the convolution with a 2x2 kernel I need to rewrite:
[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9,10,11,12]]
type:
ndarray::ArrayBase<ndarray::OwnedRepr<i32>, ndarray::Dim<[usize; 2]>>
to:
[[ 1, 2, 3, 5, 6, 7],
[ 2, 3, 4, 6, 7, 8],
[ 5, 6, 7, 9,10,11],
[ 6, 7, 8,10,11,12]];
With from_shape_ptr
:
let ptr = image.as_ptr();
unsafe {
let view = ArrayView::from_shape_ptr((6,2,2).strides((1,4,1)), ptr);
}
I get:
[[[1, 2],
[5, 6]],
[[2, 3],
[6, 7]],
[[3, 4],
[7, 8]],
[[4, 5],
[8, 9]],
[[5, 6],
[9, 10]],
[[6, 7],
[10, 11]]]
I was hoping to use into_shape
to get the 6x4 matrix from above:
let review = view.into_shape((6,4)).unwrap();
Alas the into_shape
fails with the following error:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ShapeError/IncompatibleLayout: incompatible memory layout'
So the question is: how can reshape the output of from_shape_ptr
from (6,2,2)
to (6, 4)
vectorising the inner two dimensions?