Repository: xtensor-stack/xtensor (language: python)

Issue:
Build and runtime errors after upgrading to 0.23.1
Hello there.

Unfortunately the PR https://github.com/xtensor-stack/xtensor/pull/2292 creates havoc in our code base.

I found a minimal example for the build error (gcc 10.2.0 or gcc 8.3.0):

```
#include <xtensor/xtensor.hpp>
#include <xtensor/xrandom.hpp>
#include <xtensor/xio.hpp>

int main() {
    xt::xtensor<double, 1> y = xt::flatten(xt::random::randint({100, 1}, 1, 100));

    std::cout << y;

    return 0;
}
```

With `add_definitions(-DXTENSOR_USE_XSIMD)` in the CMakeLists.txt it fails with the following error only with that PR applied:

```
In file included from /home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xtensor.hpp:20,
                 from /home/mvm/code/xtensor/main.cpp:1:
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xcontainer.hpp: In instantiation of ‘xt::container_simd_return_type_t<typename xt::xcontainer_inner_types<D>::storage_type, typename xt::xcontainer_inner_types<D>::storage_type::value_type, requested_type> xt::xcontainer<D>::load_simd(xt::xcontainer<D>::size_type) const [with align = xt::inner_aligned_mode; requested_type = int; long unsigned int N = 8; D = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>; xt::container_simd_return_type_t<typename xt::xcontainer_inner_types<D>::storage_type, typename xt::xcontainer_inner_types<D>::storage_type::value_type, requested_type> = xsimd::batch<int, 8>; typename xt::xcontainer_inner_types<D>::storage_type::value_type = int; typename xt::xcontainer_inner_types<D>::storage_type = xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >; xt::xcontainer<D>::size_type = long unsigned int]’:
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xassign.hpp:671:104:   required from ‘static void xt::linear_assigner<simd_assign>::run(E1&, const E2&) [with E1 = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>; E2 = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>; bool simd_assign = true]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xassign.hpp:390:50:   required from ‘static void xt::xexpression_assigner_base<xt::xtensor_expression_tag>::assign_data(xt::xexpression<D>&, const xt::xexpression<E2>&, bool) [with E1 = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>; E2 = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xassign.hpp:413:31:   required from ‘static void xt::xexpression_assigner<Tag>::assign_xexpression(E1&, const E2&) [with E1 = xt::xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag> >; E2 = xt::xexpression<xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >; Tag = xt::xtensor_expression_tag]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xassign.hpp:204:58:   required from ‘xt::assign_xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>, xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >::<lambda(auto:65)> [with auto:65 = xtl::identity]’
/home/mvm/.conan/data/xtl/0.7.2/mdm/testing/package/73468d6cd433312abe58cd86e0da983f5d6f13ce/include/xtl/xmeta_utils.hpp:597:22:   required from ‘decltype(auto) xtl::mpl::static_if(std::false_type, const TF&, const FF&) [with TF = xt::assign_xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>, xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >::<lambda(auto:64)>; FF = xt::assign_xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>, xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >::<lambda(auto:65)>; std::false_type = std::integral_constant<bool, false>]’
/home/mvm/.conan/data/xtl/0.7.2/mdm/testing/package/73468d6cd433312abe58cd86e0da983f5d6f13ce/include/xtl/xmeta_utils.hpp:603:29:   required from ‘decltype(auto) xtl::mpl::static_if(const TF&, const FF&) [with bool cond = false; TF = xt::assign_xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>, xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >::<lambda(auto:64)>; FF = xt::assign_xexpression<xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>, xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag> >::<lambda(auto:65)>]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xassign.hpp:198:58:   required from ‘void xt::assign_xexpression(xt::xexpression<D>&, const xt::xexpression<E2>&) [with E1 = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>; E2 = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xsemantic.hpp:623:31:   required from ‘xt::xcontainer_semantic<D>::derived_type& xt::xcontainer_semantic<D>::assign_xexpression(const xt::xexpression<E>&) [with E = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>; D = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>; xt::xcontainer_semantic<D>::derived_type = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xsemantic.hpp:489:55:   required from ‘xt::xsemantic_base<D>::derived_type& xt::xsemantic_base<D>::assign(const xt::xexpression<E>&) [with E = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>; D = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>; xt::xsemantic_base<D>::derived_type = xt::xtensor_container<xt::uvector<double, xsimd::aligned_allocator<double, 32> >, 1, xt::layout_type::row_major, xt::xtensor_expression_tag>]’
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xtensor.hpp:528:30:   required from ‘xt::xtensor_container<EC, N, L, Tag>::xtensor_container(const xt::xexpression<E>&) [with E = xt::xtensor_view<xt::xiterator_owner_adaptor<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::detail::expression_iterator_getter<xt::xgenerator<xt::detail::random_impl<int, std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>, std::uniform_int_distribution<int> >, int, std::array<long unsigned int, 2> >, xt::layout_type::row_major> >, 1, xt::layout_type::dynamic, xt::xtensor_expression_tag>; EC = xt::uvector<double, xsimd::aligned_allocator<double, 32> >; long unsigned int N = 1; xt::layout_type L = xt::layout_type::row_major; Tag = xt::xtensor_expression_tag]’
/home/mvm/code/xtensor/main.cpp:6:81:   required from here
/home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xcontainer.hpp:721:77: error: use of deleted function ‘const _Tp* std::addressof(const _Tp&&) [with _Tp = int]’
  721 |         return xt_simd::load_simd<value_type, requested_type>(std::addressof(storage()[i]), align_mode());
      |                                                               ~~~~~~~~~~~~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/10/bits/stl_pair.h:59,
                 from /usr/include/c++/10/utility:70,
                 from /usr/include/c++/10/algorithm:60,
                 from /home/mvm/.conan/data/xtensor/0.23.1/mdm/testing/package/a0e618afb4923d511a263b94d6972ebb073bcb76/include/xtensor/xtensor.hpp:13,
                 from /home/mvm/code/xtensor/main.cpp:1:
/usr/include/c++/10/bits/move.h:146:16: note: declared here
  146 |     const _Tp* addressof(const _Tp&&) = delete;
      |                ^~~~~~~~~
```

Reverting the modification in xassign.hpp fixes the error.

Moreover the modification in xcontainer.hpp creates issues at runtime that I can't reproduce easily in a minimal example. We use a function from xtensor-blas that checks if an xexpression has row_major or column_major layout that now complains that this requirement is no more satisfied in some cases. Reverting the PR fixes the issue.

Is this an intended behavior or a regression?
If this is the intended behavior from now on, what should we pay attention to in order to avoid these problems?

Regards and thanks for your awesome work.


Discussion / hints:
Hi,

Thanks for the detailed report. This looks to be an issue starting from C++17 (the deletion of `addressof` on const rvalue references was introduced in C++17). I need to dive again into this part of the code, the explanation for this change is that some classes in xtensor redefine `operator&` (this is required to implement correct closure semantics for rvalues), but we probably need to handle const rvalues differently.

Out of curiosity, does it fix the issue if you pass `-std=c++14` to the compile option in your CMake?

> However the modification in xcontainer.hpp creates issues at runtime [...]

Not sure to fully understand what you mean here. Do you mean "reverting the change in `xassign` and keeping the changes in `xcontainer`"? Or did you identify another issue caused by the change in `xcontainer`, independent from that in `xassign`?

The change was made on purpose (it fixes a bug when resizing a non contiguous storage). However, it may lead to issues in downstream packages that we haven't detected.

I understand the issue in `xtensor-blas` is not easy to reproduce in a minimal example, therefore here are some information that would help us to try to reproduce or to understand what is going on:

- name of the xtensor-blas function
- exact types of the arguments passed to the function
- if they are `xcontainer` (or inheriting from), their layout, shape, and strides
- if they are `xstrided_view`, same info as above + same info of the underlying expression if it is an `xcontainer`

Thanks!
Hi,
thanks for the quick feedback.
Setting c++14 doesn't fix the issue at compile time. I don't know if it's important, but the error occurs only when defining XTENSOR_USE_XSIMD.

About the issue at run time: yes, this issue should not be related to the change in xassign.

I managed to isolate a minimal code example ripping off some code from xtensor-blas:

```
#include <stdexcept>
#include <tuple>
#include <type_traits>

#include <xtensor/xtensor.hpp>
#include <xtensor/xrandom.hpp>
#include <xtensor/xutils.hpp>

#ifndef DEFAULT_LEADING_STRIDE_BEHAVIOR
#define DEFAULT_LEADING_STRIDE_BEHAVIOR XTENSOR_THROW(std::runtime_error, "No valid layout chosen.");
#endif

template<xt::layout_type L = xt::layout_type::row_major, class T, class I = std::decay_t<T>>
inline auto view_eval(T &&t) -> std::enable_if_t<
        (!xt::has_data_interface<std::decay_t<T>>::value || I::static_layout != L) &&
        xt::detail::is_array<typename I::shape_type>::value,
        xt::xtensor<typename I::value_type, std::tuple_size<typename I::shape_type>::value, layout_remove_any(L)>> {
    return t;
}

template<class A,
        std::enable_if_t<A::static_layout != xt::layout_type::row_major &&
                         A::static_layout != xt::layout_type::column_major> * = nullptr>
inline size_t get_leading_stride(const A &a) {
    if (a.layout() == xt::layout_type::row_major) {
        return 0;
    } else if (a.layout() == xt::layout_type::column_major) {
        return 1;
    }
    DEFAULT_LEADING_STRIDE_BEHAVIOR;
}

template<class T>
void func(const xt::xexpression<T> &xt) {
    auto &&t = view_eval<T::static_layout>(xt.derived_cast());
    get_leading_stride(t);
}

int main() {
    std::vector<int> indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    xt::xtensor<double, 2> X = xt::zeros<double>({100, 100});

    func(xt::index_view(X, indices));

    return 0;
}

```

It throws `No valid layout chosen.` only with version 0.23.1.

Best regards.
This also fails, again only with version 0.23.1:

```
int main() {
    auto a = xt::random::randint({100, 1}, 1, 100);
    func(a);

    return 0;
}
```


Fix patch:
diff --git a/include/xtensor/xtensor.hpp b/include/xtensor/xtensor.hpp
index 483545eb0..98a09d4e4 100644
--- a/include/xtensor/xtensor.hpp
+++ b/include/xtensor/xtensor.hpp
@@ -375,6 +375,28 @@ namespace xt
         friend class xview_semantic<xtensor_view<EC, N, L, Tag>>;
     };
 
+    namespace detail
+    {
+        template <class V>
+        struct tensor_view_simd_helper
+        {
+            using valid_return_type = detail::has_simd_interface_impl<V, typename V::value_type>;
+            using valid_reference = std::is_lvalue_reference<typename V::reference>;
+            static constexpr bool value = valid_return_type::value && valid_reference::value;
+            using type = std::integral_constant<bool, value>;
+        };
+    }
+
+    // xtensor_view can be used on pseudo containers, i.e. containers
+    // whowe access operator does not return a reference. Since it
+    // is not possible to take the address f a temporary, the load_simd
+    // method implementation leads to a compilation error.
+    template <class EC, std::size_t N, layout_type L, class Tag>
+    struct has_simd_interface<xtensor_view<EC, N, L, Tag>>
+        : detail::tensor_view_simd_helper<xtensor_view<EC, N, L, Tag>>::type
+    {
+    };
+
     /************************************
      * xtensor_container implementation *
      ************************************/


Test patch:
diff --git a/test/test_xmanipulation.cpp b/test/test_xmanipulation.cpp
index c2ede538a..aea7689df 100644
--- a/test/test_xmanipulation.cpp
+++ b/test/test_xmanipulation.cpp
@@ -13,6 +13,7 @@
 #include "xtensor/xtensor.hpp"
 #include "xtensor/xbuilder.hpp"
 #include "xtensor/xmanipulation.hpp"
+#include "xtensor/xrandom.hpp"
 #include "xtensor/xview.hpp"
 
 #include "xtensor/xio.hpp"
@@ -137,6 +138,12 @@ namespace xt
         EXPECT_EQ(iter, view.end());
     }
 
+    TEST(xmanipulation, flatten_generator)
+    {
+        // Compilation test
+        xt::xtensor<double, 1> y = xt::flatten(xt::random::randint({100, 1}, 1, 100));
+    }
+
     TEST(xmanipulation, flatten_simd_linear_assign_trait)
     {
         xtensor<double, 3> a = linspace<double>(1., 100., 100).reshape({2, 5, 10});