/***************************************************************************
* 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::value)
#define EXPECT_XTENSOR(EXPRESSION) \
EXPECT_TRUE(detail::is_array::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);
}
}
}