Buggy behaviour of non-contiguous xadaptor and scalar assignment
Hi, When assigning with a scalar on a xadaptor with non-contiguous strides, there is some problem where contiguous assignment is done instead, producing unexpected results. For instance, the following does not work:
void test_strided_scalar_assign() {
auto data = std::vector<double>(8);
std::fill(data.begin(), data.end(), 0.);
auto adapter_strided_noncont = xt::adapt(
data.data(), 6, xt::no_ownership(), std::vector<size_t>{2, 3},
std::vector<size_t>{4, 1});
xt::noalias(adapter_strided_noncont) += 1;
auto expected = std::vector<double>({1, 1, 1, 0, 1, 1, 1, 0});
assert(expected == data);
}
When running this, the first 6 values of data are incremented, instead of taking into account the {4,1} strides.
What's do you think the best way is to fix this?
This is the source of your issue:
In the case of contiguous containers this implementation works fine. We don't care about strides because adding a scalar to the whole container is independent of the order in which the container is traversed. For discontinuous strides that is not true as we would stride over some locations. Additionally, when we call begin to the storage in this case we get a contiguous iterator from the underlying data pointer which also isn't aware of strides.
@JohanMabille does the adaptor assume a contiguous underlying data structure?
@ewoudwempe I think your best way of fixing this would be to create your own xtensor compatible container which provides iterators which step through your data in the right order.