`ArrayBase::as_slice_memory_order` returns `None` when slice has a single element
LoganAMorrison opened this issue · comments
For some reason, as_slice_memory_order
returns None
when called on a 1-element slice. Minimal example:
use ndarray::{s, Array1};
let arr = Array1::from_vec(vec![1.0, 2.0, 3.0]);
println!("{:?}", arr.slice(s![0..1]).as_slice_memory_order());
// Prints None
Interesting! Thank you for the bug report.
This is failing in is_contiguous
let defaults = dim.default_strides();
if strides.equal(&defaults) { return true; } // strides = [0], defaults = [1]
if dim.ndim() == 1 { // Yes
return strides[0] as isize == -1; // false -> `as_slice_memory_order` returns None
}
In fact, the actual problem is probably that self.strides
contains [0]
. It can be traced to do_slice
// Update stride. The additional check is necessary to avoid possible
// overflow in the multiplication.
*stride = if *dim <= 1 { 0 } else { (s * step) as usize }; // dim = 1
I don't know this project enough so I'm not sure what's going on. IMO, the array in your example is contiguous and the stride of a contiguous 1D array should be 1. However, maybe an array of len 1 is by definition not contiguous?
@bluss I need your help on this issue.
This sounds like a bug, and it sounds like @nilgoyette has found why.
For axes with length <= 1, any stride value is valid and IIRC any stride value can appear in an array view (depending on the shape/state of a source array that was sliced), likely we can fix this by a bug fix to the contig check
The code we have doesn't promise that is_contiguous returns true for every contiguous array. But it's always good to improve the coverage.. 🙂