From 54ca763246f9384325201b9e6693fea797dc5129 Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Mon, 1 Feb 2021 10:30:11 +0100 Subject: [PATCH 1/2] test pyarray assign traits --- test/CMakeLists.txt | 1 + test/test_pyarray_traits.cpp | 145 +++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 test/test_pyarray_traits.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 32ad45b..b53ac18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,7 @@ include_directories(${GTEST_INCLUDE_DIRS}) set(XTENSOR_PYTHON_TESTS main.cpp test_pyarray.cpp + test_pyarray_traits.cpp test_pytensor.cpp test_pyvectorize.cpp ) diff --git a/test/test_pyarray_traits.cpp b/test/test_pyarray_traits.cpp new file mode 100644 index 0000000..a90b460 --- /dev/null +++ b/test/test_pyarray_traits.cpp @@ -0,0 +1,145 @@ +/*************************************************************************** +* Copyright (c) Wolf Vollprecht, Johan Mabille and Sylvain Corlay * +* 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 "gtest/gtest.h" + +#include "xtensor-python/pyarray.hpp" + + + +namespace xt +{ + namespace testing + { + class pyarray_traits: public ::testing::Test + { + protected: + + using dynamic_type = xt::pyarray; + using row_major_type = xt::pyarray; + using column_major_type = xt::pyarray; + + dynamic_type d1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + dynamic_type d2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + row_major_type r1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + row_major_type r2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + column_major_type c1 = {{0., 1.}, {0., 10.}, {0., 100.}}; + column_major_type c2 = {{0., 2.}, {0., 20.}, {0., 200.}}; + + template + bool test_has_strides(T const&) + { + return xt::has_strides::value; + } + + template + xt::layout_type test_result_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return (tmp1 + tmp2).layout(); + } + + template + bool test_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + T res = tmp1 + tmp2; + return xt::xassign_traits::linear_assign(res, tmp1 + tmp2, true); + } + + template + bool test_simd_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::xassign_traits::simd_linear_assign(); + } + + template + bool test_linear_static_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::detail::linear_static_layout(); + } + + template + bool test_contiguous_layout(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return decltype(tmp1)::contiguous_layout && decltype(tmp2)::contiguous_layout; + } + }; + + TEST_F(pyarray_traits, result_layout) + { + EXPECT_TRUE(d1.layout() == layout_type::row_major); + EXPECT_TRUE(test_result_layout(d1, d2) == layout_type::row_major); + + EXPECT_TRUE(r1.layout() == layout_type::row_major); + EXPECT_TRUE(test_result_layout(r1, r2) == layout_type::row_major); + + EXPECT_TRUE(c1.layout() == layout_type::column_major); + EXPECT_TRUE(test_result_layout(c1, c2) == layout_type::column_major); + } + + TEST_F(pyarray_traits, has_strides) + { + EXPECT_TRUE(test_has_strides(d1)); + EXPECT_TRUE(test_has_strides(r1)); + EXPECT_TRUE(test_has_strides(c1)); + } + + TEST_F(pyarray_traits, has_linear_assign) + { + EXPECT_TRUE(d2.has_linear_assign(d1.strides())); + EXPECT_TRUE(r2.has_linear_assign(r1.strides())); + EXPECT_TRUE(c2.has_linear_assign(c1.strides())); + } + + TEST_F(pyarray_traits, linear_assign) + { + EXPECT_TRUE(test_linear_assign(d1, d2)); + EXPECT_TRUE(test_linear_assign(r1, r2)); + EXPECT_TRUE(test_linear_assign(c1, c2)); + } + + TEST_F(pyarray_traits, simd_linear_assign) + { +#ifdef XTENSOR_USE_XSIMD + EXPECT_FALSE(test_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_simd_linear_assign(c1, c2)); +#else + EXPECT_FALSE(test_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_simd_linear_assign(c1, c2)); +#endif + } + + TEST_F(pyarray_traits, linear_static_layout) + { + EXPECT_FALSE(test_linear_static_layout(d1, d2)); + EXPECT_TRUE(test_linear_static_layout(r1, r2)); + EXPECT_TRUE(test_linear_static_layout(c1, c2)); + } + + TEST_F(pyarray_traits, contiguous_layout) + { + EXPECT_FALSE(test_contiguous_layout(d1, d2)); + EXPECT_TRUE(test_contiguous_layout(r1, r2)); + EXPECT_TRUE(test_contiguous_layout(c1, c2)); + } + } +} From 63d083a9b63bee12e3b9e2160cc853abd91dcb4c Mon Sep 17 00:00:00 2001 From: Adrien DELSALLE Date: Mon, 1 Feb 2021 17:40:54 +0100 Subject: [PATCH 2/2] test both static and dynamic simd linear assign --- test/test_pyarray_traits.cpp | 37 ++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/test/test_pyarray_traits.cpp b/test/test_pyarray_traits.cpp index a90b460..fe9ef6a 100644 --- a/test/test_pyarray_traits.cpp +++ b/test/test_pyarray_traits.cpp @@ -58,13 +58,21 @@ namespace xt } template - bool test_simd_linear_assign(T const& a1, T const& a2) + bool test_static_simd_linear_assign(T const& a1, T const& a2) { auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); auto tmp2 = cos(a1); return xt::xassign_traits::simd_linear_assign(); } + template + bool test_dynamic_simd_linear_assign(T const& a1, T const& a2) + { + auto tmp1 = pow(sin((a2 - a1) / 2.), 2.); + auto tmp2 = cos(a1); + return xt::xassign_traits::simd_linear_assign(a1, tmp2); + } + template bool test_linear_static_layout(T const& a1, T const& a2) { @@ -115,16 +123,29 @@ namespace xt EXPECT_TRUE(test_linear_assign(c1, c2)); } - TEST_F(pyarray_traits, simd_linear_assign) + TEST_F(pyarray_traits, static_simd_linear_assign) + { +#ifdef XTENSOR_USE_XSIMD + EXPECT_FALSE(test_static_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_static_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_static_simd_linear_assign(c1, c2)); +#else + EXPECT_FALSE(test_static_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_static_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_static_simd_linear_assign(c1, c2)); +#endif + } + + TEST_F(pyarray_traits, dynamic_simd_linear_assign) { #ifdef XTENSOR_USE_XSIMD - EXPECT_FALSE(test_simd_linear_assign(d1, d2)); - EXPECT_TRUE(test_simd_linear_assign(r1, r2)); - EXPECT_TRUE(test_simd_linear_assign(c1, c2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(d1, d2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(r1, r2)); + EXPECT_TRUE(test_dynamic_simd_linear_assign(c1, c2)); #else - EXPECT_FALSE(test_simd_linear_assign(d1, d2)); - EXPECT_FALSE(test_simd_linear_assign(r1, r2)); - EXPECT_FALSE(test_simd_linear_assign(c1, c2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(d1, d2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(r1, r2)); + EXPECT_FALSE(test_dynamic_simd_linear_assign(c1, c2)); #endif }