/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #include "xtensor/containers/xarray.hpp" #include "xtensor/containers/xtensor.hpp" #include "xtensor/core/xeval.hpp" #include "xtensor/core/xtensor_config.hpp" #include "xtensor/generators/xbuilder.hpp" #include "test_common.hpp" namespace xt { TEST(xeval, array_tensor) { xarray a = {1, 2, 3, 4}; auto&& b = eval(a); EXPECT_EQ(a.storage().data(), b.storage().data()); EXPECT_EQ(&a, &b); bool type_eq = std::is_same&>::value; EXPECT_TRUE(type_eq); xtensor t({3, 3}); auto&& i = eval(t); EXPECT_EQ(t.storage().data(), i.storage().data()); EXPECT_EQ(&t, &i); bool type_eq_2 = std::is_same&>::value; EXPECT_TRUE(type_eq_2); } TEST(xeval, funcs) { xarray a = {1, 2, 3, 4}; auto f = a * a - 2; auto&& b = eval(f); bool type_eq = std::is_same&&>::value; EXPECT_TRUE(type_eq); xtensor k({3, 3}); auto m = k * k - 4; auto&& n = eval(m); bool type_eq_3 = std::is_same&&>::value; EXPECT_TRUE(type_eq_3); auto&& i = eval(linspace(0, 100)); bool type_eq_2 = std::is_same&&>::value; EXPECT_TRUE(type_eq_2); } #define EXPECT_LAYOUT(EXPRESSION, LAYOUT) EXPECT_TRUE((decltype(EXPRESSION)::static_layout == LAYOUT)) #define HAS_DATA_INTERFACE(EXPRESSION) data_interface_expression> #define EXPECT_XARRAY(EXPRESSION) \ EXPECT_TRUE(!detail::is_array::shape_type>::value) #define EXPECT_XTENSOR(EXPRESSION) \ EXPECT_TRUE(detail::is_array::shape_type>::value == true) TEST(utils, has_same_layout) { xt::xtensor ten1{1., 2., 3.2}; EXPECT_TRUE(detail::has_same_layout(ten1)); EXPECT_FALSE(detail::has_same_layout(ten1)); EXPECT_TRUE(detail::has_same_layout(ten1)); xt::xtensor ten2{1., 2., 3.2}; EXPECT_TRUE(detail::has_same_layout(ten2)); EXPECT_FALSE(detail::has_same_layout(ten2)); EXPECT_TRUE(detail::has_same_layout(ten2)); EXPECT_FALSE((detail::has_same_layout(ten1, ten2))); EXPECT_TRUE( (detail::has_same_layout(ten1, xt::xtensor({1., 2., 3.2}))) ); EXPECT_TRUE( (detail::has_same_layout(ten2, xt::xtensor({1., 2., 3.2}))) ); } TEST(utils, has_fixed_dims) { xt::xtensor ten{1., 2., 3.2}; EXPECT_TRUE((detail::has_fixed_dims>())); EXPECT_TRUE(detail::has_fixed_dims(ten)); xt::xarray arr{1., 2., 3.2}; EXPECT_FALSE((detail::has_fixed_dims>())); EXPECT_FALSE(detail::has_fixed_dims(arr)); } TEST(utils, as_xarray_container_t) { using array_type = xt::xarray; detail::as_xarray_container_t arr; EXPECT_XARRAY(arr); EXPECT_LAYOUT(arr, layout_type::column_major); } TEST(utils, as_xtensor_container_t) { using tensor_type = xt::xtensor; detail::as_xtensor_container_t ten; EXPECT_XTENSOR(ten); EXPECT_LAYOUT(ten, layout_type::column_major); } namespace testing { // avoid collision with fixture class class as_strided : public ::testing::Test { protected: xt::xtensor ten{1., 2., 3.2}; xt::xarray arr{1., 2., 3.2}; }; TEST_F(as_strided, array_reference) { EXPECT_LAYOUT(arr, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(arr)); EXPECT_XARRAY(arr); EXPECT_EQ(arr(2), 3.2); } TEST_F(as_strided, tensor_reference) { EXPECT_LAYOUT(ten, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(ten)); EXPECT_XTENSOR(ten); EXPECT_EQ(ten(2), 3.2); } TEST_F(as_strided, array_layout_unchanged) { auto res_lvalue = xt::as_strided(arr); EXPECT_LAYOUT(res_lvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XARRAY(res_lvalue); EXPECT_EQ(res_lvalue(2), 3.2); auto res_rvalue = xt::as_strided( xt::xarray({1., 2., 3.2}) ); EXPECT_LAYOUT(res_rvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XARRAY(res_rvalue); EXPECT_EQ(res_rvalue(2), 3.2); } TEST_F(as_strided, tensor_layout_unchanged) { auto res_lvalue = xt::as_strided(ten); EXPECT_LAYOUT(res_lvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XTENSOR(res_lvalue); EXPECT_EQ(res_lvalue(2), 3.2); auto res_rvalue = xt::as_strided( xt::xtensor({1., 2., 3.2}) ); EXPECT_LAYOUT(res_rvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XTENSOR(res_rvalue); EXPECT_EQ(res_rvalue(2), 3.2); } TEST_F(as_strided, array_layout_change) { auto res_lvalue = xt::as_strided(arr); EXPECT_LAYOUT(res_lvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XARRAY(res_lvalue); EXPECT_EQ(res_lvalue(2), 3.2); auto res_rvalue = xt::as_strided( xt::xarray({1., 2., 3.2}) ); EXPECT_LAYOUT(res_rvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XARRAY(res_rvalue); EXPECT_EQ(res_rvalue(2), 3.2); } TEST_F(as_strided, tensor_layout_changed) { auto res_lvalue = xt::as_strided(ten); EXPECT_LAYOUT(res_lvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XTENSOR(res_lvalue); EXPECT_EQ(res_lvalue(2), 3.2); auto res_rvalue = xt::as_strided( xt::xtensor({1., 2., 3.2}) ); EXPECT_LAYOUT(res_rvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XTENSOR(res_rvalue); EXPECT_EQ(res_rvalue(2), 3.2); } TEST_F(as_strided, array_no_data_interface_layout_unchanged) { auto array_cast = xt::cast(arr); EXPECT_FALSE(HAS_DATA_INTERFACE(array_cast)); EXPECT_XARRAY(array_cast); auto res_lvalue = xt::as_strided(array_cast); EXPECT_LAYOUT(res_lvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XARRAY(res_lvalue); EXPECT_EQ(res_lvalue(2), 3); auto res_rvalue = xt::as_strided(xt::cast(arr)); EXPECT_LAYOUT(res_rvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XARRAY(res_rvalue); EXPECT_EQ(res_rvalue(2), 3); } TEST_F(as_strided, tensor_no_data_interface_layout_unchanged) { auto tensor_cast = xt::cast(ten); EXPECT_FALSE(HAS_DATA_INTERFACE(tensor_cast)); EXPECT_XTENSOR(tensor_cast); auto res_lvalue = xt::as_strided(tensor_cast); EXPECT_LAYOUT(res_lvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XTENSOR(res_lvalue); EXPECT_EQ(res_lvalue(2), 3); auto res_rvalue = xt::as_strided(xt::cast(ten)); EXPECT_LAYOUT(res_rvalue, layout_type::row_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XTENSOR(res_rvalue); EXPECT_EQ(res_rvalue(2), 3); } TEST_F(as_strided, array_no_data_interface_layout_changed) { auto array_cast = xt::cast(arr); EXPECT_FALSE(HAS_DATA_INTERFACE(array_cast)); EXPECT_XARRAY(array_cast); auto res_lvalue = xt::as_strided(array_cast); EXPECT_LAYOUT(res_lvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XARRAY(res_lvalue); EXPECT_EQ(res_lvalue(2), 3); auto res_rvalue = xt::as_strided(xt::cast(arr)); EXPECT_LAYOUT(res_rvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XARRAY(res_rvalue); EXPECT_EQ(res_rvalue(2), 3); } TEST_F(as_strided, tensor_no_data_interface_layout_changed) { auto tensor_cast = xt::cast(ten); EXPECT_FALSE(HAS_DATA_INTERFACE(tensor_cast)); EXPECT_XTENSOR(tensor_cast); auto res_lvalue = xt::as_strided(tensor_cast); EXPECT_LAYOUT(res_lvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_lvalue)); EXPECT_XTENSOR(res_lvalue); EXPECT_EQ(res_lvalue(2), 3); auto res_rvalue = xt::as_strided(xt::cast(ten)); EXPECT_LAYOUT(res_rvalue, layout_type::column_major); EXPECT_TRUE(HAS_DATA_INTERFACE(res_rvalue)); EXPECT_XTENSOR(res_rvalue); EXPECT_EQ(res_rvalue(2), 3); } } }