xtensor icon indicating copy to clipboard operation
xtensor copied to clipboard

xt::flip compile error: "no member named 'data_offset' in ..."

Open lfnoise opened this issue 3 years ago • 2 comments

This code does not compile for me. Removing xt::flip does compile. I've been using xtensor for only a few hours so likely I'm doing something wrong..

#include <iostream>
#include <xtensor/xarray.hpp>
#include <xtensor/xio.hpp>
#include <xtensor/xview.hpp>

int main(int argc, char* argv[])
{
    xt::xarray<double> arr1
      {{1.0, 2.0, 3.0},
       {4.0, 5.0, 6.0},
       {7.0, 8.0, 9.0}};

    xt::xarray<double> arr2
      {50.0, 60.0, 70.0};

    //auto expr = arr1 + arr2;  // OK
    auto expr = xt::flip(arr1 + arr2); // compile error.

    xt::xarray<double> result = xt::zeros<double>(expr.shape());
    
    std::copy(expr.cbegin(), expr.cend(), result.begin());
    std::cout << result << std::endl;
    return 0;
}

Error message:

In file included from /Users/xxxxxx/xxxxxx/dev/xtensor-xample/xtensor-xample/main.cpp:3:
In file included from /usr/local/include/xtensor/xarray.hpp:20:
In file included from /usr/local/include/xtensor/xcontainer.hpp:25:
In file included from /usr/local/include/xtensor/xmath.hpp:28:
/usr/local/include/xtensor/xmanipulation.hpp:667:85: error: no member named 'data_offset' in 'xt::xfunction<xt::detail::plus, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &>'
        std::size_t offset = static_cast<std::size_t>(static_cast<std::ptrdiff_t>(e.data_offset()) + old_strides[axis] * (static_cast<std::ptrdiff_t>(e.shape()[axis]) - 1));
                                                                                  ~ ^
/usr/local/include/xtensor/xmanipulation.hpp:635:18: note: in instantiation of function template specialization 'xt::flip<xt::xfunction<xt::detail::plus, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &> &>' requested here
        auto r = flip(e, 0);
                 ^
/Users/xxxxxx/xxxxxx/dev/xtensor-xample/xtensor-xample/main.cpp:36:21: note: in instantiation of function template specialization 'xt::flip<xt::xfunction<xt::detail::plus, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &, const xt::xarray_container<xt::uvector<double, std::__1::allocator<double> >, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::__1::allocator<unsigned long>, true>, xt::xtensor_expression_tag> &> >' requested here
    auto expr = xt::flip(arr1 + arr2); // compile error.
                    ^

MacOS 11.5.1 Xcode 12.3

lfnoise avatar Oct 25 '21 07:10 lfnoise

Looks like flip accepts evaluated expressions only. The following should fix your issue:

auto expr = xt::flip(xt::eval(arr1 + arr2));

If you need the result of arr1 + arr2 for another operation, you can evaluate it in a variable before calling flip.

JohanMabille avatar Oct 25 '21 07:10 JohanMabille

Looks like flip accepts evaluated expressions only. The following should fix your issue:

auto expr = xt::flip(xt::eval(arr1 + arr2));

Making that change causes a EXC_BAD_ACCESS crash in this example.

Changing the std::copy to a nested loop also crashes on the first access.

	for (int i = 0; i < 3; ++i) {
		for (int j = 0; j < 3; ++j) {
			printf("%d %d :\n", i, j);
			auto x = expr(i,j);
			printf("   %12.6f\n", x);
		}
	}

edit: Calling eval also causes an allocation, which I must avoid. xt::transpose causes no allocation, for example. I'd think flip should be able to work similarly.

lfnoise avatar Oct 25 '21 08:10 lfnoise