rust-ndarray / ndarray

ndarray: an N-dimensional array with array views, multidimensional slicing, and efficient operations

Home Page:https://docs.rs/ndarray/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`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.. 🙂