Skip to content
Open
7 changes: 6 additions & 1 deletion include/xtensor/views/xstrided_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,13 @@ namespace xt
using simd_value_type = xt_simd::simd_type<value_type>;
using bool_load_type = typename base_type::bool_load_type;

// load_simd/store_simd take the address of the flat storage, which requires the
// storage to expose lvalue references (not the case for lazy expressions wrapped
// in a flat_expression_adaptor).
static constexpr bool provides_simd_interface = has_simd_interface<xexpression_type>::value
&& L != layout_type::dynamic;
&& L != layout_type::dynamic
&& std::is_lvalue_reference_v<
decltype(std::declval<const storage_type&>()[0])>;

template <class CTA, class SA>
xstrided_view(CTA&& e, SA&& shape, strides_type&& strides, std::size_t offset, layout_type layout) noexcept;
Expand Down
23 changes: 23 additions & 0 deletions test/test_xstrided_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,29 @@ namespace xt
EXPECT_TRUE(std::equal(nv.shape().begin(), nv.shape().end(), expected_shape.begin()));
}

TEST(xstrided_view, reshape_view_lazy_expression)
{
const std::size_t G = 8, N = 4;
xtensor<double, 1> w = xt::arange<double>(G) + 1.0;
xtensor<double, 2> Phi = 3.0 * xt::ones<double>({G, N});

// reshape_view over a lazy expression must not enable the SIMD assign path,
// which takes the address of the (computed) flat storage.
auto col = xt::reshape_view(w * w, {G, std::size_t(1)});
xtensor<double, 2> out = Phi * col;

#if XTENSOR_USE_XSIMD
using lazy_traits = xassign_traits<xtensor<double, 2>, decltype(Phi * col)>;
EXPECT_FALSE(lazy_traits::simd_linear_assign());

auto colc = xt::reshape_view(w, {G, std::size_t(1)});
using cont_traits = xassign_traits<xtensor<double, 2>, decltype(Phi * colc)>;
EXPECT_TRUE(cont_traits::simd_linear_assign());
#endif

EXPECT_EQ(108.0, out(5, 2));
}

TEST(xstrided_view, reshape_view_assign)
{
xarray<int, layout_type::column_major> xa = {{1, 2, 3}, {4, 5, 6}};
Expand Down
Loading