xtensor icon indicating copy to clipboard operation
xtensor copied to clipboard

shared generator expressions

Open nodatapoints opened this issue 2 years ago • 2 comments

I would like to wrap generator expressions in a function like in the following example.

inline auto build(int n) {
    auto x = xt::make_xshared(xt::arange(n));
    return x*x;
}

xt::xtensor<double, 1> array;
array = build(10);

Currently this gives an error

/usr/include/xtensor/xexpression.hpp:575:9: error:
    ‘class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int,
    std::array<long unsigned int, 1> >’ has no member named ‘linear_begin’
  575 |         XTENSOR_FORWARD_METHOD(linear_begin)

As far as I understand, this is currently only possible for xexpressions of evaluated expressions. My current workarounds are:

  • Evaluating the generator. This sacrifices laziness.
  • Passing array by reference. This is not idiomatic and only works if the assignment results in a evaluation.

nodatapoints avatar Mar 22 '23 13:03 nodatapoints

I think that what happens is that the return forces the evaluation of the expression. (It is a bit tricky to see from you error snippet)

tdegeus avatar Mar 31 '23 07:03 tdegeus

For a minimum example I took the following code

#include <xtensor/xtensor.hpp>

inline auto build(int n) {
    auto x = xt::make_xshared(xt::arange(n));
    return x*x;
}

int main() {
    xt::xtensor<double, 1> array;
    array = build(10);
}

xtensor 0.24.6, xtl 0.7.5, GCC 12.2.1. This gave the following errors:

In file included from /usr/include/xtensor/xaccumulator.hpp:18,
                 from /usr/include/xtensor/xmath.hpp:27,
                 from /usr/include/xtensor/xcontainer.hpp:25,
                 from /usr/include/xtensor/xtensor.hpp:20,
                 from test.cpp:1:
/usr/include/xtensor/xexpression.hpp: In instantiation of ‘class xt::xshared_expression<xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> > >’:
test.cpp:4:30:   required from here
/usr/include/xtensor/xexpression.hpp:575:9: error: ‘class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_begin’
  575 |         XTENSOR_FORWARD_METHOD(linear_begin)
      |         ^
/usr/include/xtensor/xexpression.hpp:576:9: error: ‘class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_end’
  576 |         XTENSOR_FORWARD_METHOD(linear_end)
      |         ^
/usr/include/xtensor/xexpression.hpp:577:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_begin’
  577 |         XTENSOR_FORWARD_CONST_METHOD(linear_begin)
      |         ^
/usr/include/xtensor/xexpression.hpp:578:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_end’
  578 |         XTENSOR_FORWARD_CONST_METHOD(linear_end)
      |         ^
/usr/include/xtensor/xexpression.hpp:579:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_cbegin’; did you mean ‘get_cbegin’?
  579 |         XTENSOR_FORWARD_CONST_METHOD(linear_cbegin)
      |         ^
/usr/include/xtensor/xexpression.hpp:580:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_cend’
  580 |         XTENSOR_FORWARD_CONST_METHOD(linear_cend)
      |         ^
/usr/include/xtensor/xexpression.hpp:582:9: error: ‘class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_rbegin’
  582 |         XTENSOR_FORWARD_METHOD(linear_rbegin)
      |         ^
/usr/include/xtensor/xexpression.hpp:583:9: error: ‘class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_rend’
  583 |         XTENSOR_FORWARD_METHOD(linear_rend)
      |         ^
/usr/include/xtensor/xexpression.hpp:584:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_rbegin’
  584 |         XTENSOR_FORWARD_CONST_METHOD(linear_rbegin)
      |         ^
/usr/include/xtensor/xexpression.hpp:585:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_rend’
  585 |         XTENSOR_FORWARD_CONST_METHOD(linear_rend)
      |         ^
/usr/include/xtensor/xexpression.hpp:586:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_crbegin’
  586 |         XTENSOR_FORWARD_CONST_METHOD(linear_crbegin)
      |         ^
/usr/include/xtensor/xexpression.hpp:587:9: error: ‘const class xt::xgenerator<xt::detail::arange_generator<int, int, int>, int, std::array<long unsigned int, 1> >’ has no member named ‘linear_crend’
  587 |         XTENSOR_FORWARD_CONST_METHOD(linear_crend)
      |         ^

nodatapoints avatar Apr 07 '23 11:04 nodatapoints