From fd681507dc9e8bf3cc1dbbc4c017b5d5c0d2b506 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 20 Aug 2008 20:08:38 +0000 Subject: [PATCH] Add a packetmath unit test, re-enable the comma-initializer unit test, and bug fix in PacketMath/SSE --- Eigen/src/Core/arch/SSE/PacketMath.h | 29 +++++- test/CMakeLists.txt | 2 + test/cholesky.cpp | 1 + test/commainitializer.cpp | 8 +- test/packetmath.cpp | 149 +++++++++++++++++++++++++++ test/triangular.cpp | 2 +- 6 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 test/packetmath.cpp diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index 07aa84d69..f2744e340 100644 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -219,7 +219,8 @@ struct ei_palign_impl { inline static void run(__m128& first, const __m128& second) { - first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(first), _mm_castps_si128(second), (4-Offset)*4)); + if (Offset!=0) + first = _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(second), _mm_castps_si128(first), (Offset)*4)); } }; @@ -228,7 +229,18 @@ struct ei_palign_impl { inline static void run(__m128i& first, const __m128i& second) { - first = _mm_alignr_epi8(first, second, (4-Offset)*4); + if (Offset!=0) + first = _mm_alignr_epi8(second,first, (Offset)*4); + } +}; + +template +struct ei_palign_impl +{ + inline static void run(__m128d& first, const __m128d& second) + { + if (Offset==1) + first = _mm_castsi128_pd(_mm_alignr_epi8(_mm_castpd_si128(second), _mm_castpd_si128(first), 8)); } }; #else @@ -278,6 +290,19 @@ struct ei_palign_impl } } }; + +template +struct ei_palign_impl +{ + inline static void run(__m128d& first, const __m128d& second) + { + if (Offset==1) + { + first = _mm_castps_pd(_mm_movehl_ps(_mm_castpd_ps(first),_mm_castpd_ps(first))); + first = _mm_castps_pd(_mm_movelh_ps(_mm_castpd_ps(first),_mm_castpd_ps(second))); + } + } +}; #endif #endif // EIGEN_PACKET_MATH_SSE_H diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 30fe3e755..917715eb0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -86,6 +86,7 @@ ENDIF(TEST_LIB) EI_ADD_TEST(sizeof) EI_ADD_TEST(nomalloc) +EI_ADD_TEST(packetmath) EI_ADD_TEST(basicstuff) EI_ADD_TEST(linearstructure) EI_ADD_TEST(cwiseop) @@ -95,6 +96,7 @@ EI_ADD_TEST(product_large ${EI_OFLAG}) EI_ADD_TEST(adjoint) EI_ADD_TEST(submatrices) EI_ADD_TEST(miscmatrices) +EI_ADD_TEST(commainitializer) EI_ADD_TEST(smallvectors) EI_ADD_TEST(map) EI_ADD_TEST(array) diff --git a/test/cholesky.cpp b/test/cholesky.cpp index 55a74c477..4bf28ef68 100644 --- a/test/cholesky.cpp +++ b/test/cholesky.cpp @@ -60,5 +60,6 @@ void test_cholesky() CALL_SUBTEST( cholesky(Matrix3f()) ); CALL_SUBTEST( cholesky(Matrix4d()) ); CALL_SUBTEST( cholesky(MatrixXcd(7,7)) ); + CALL_SUBTEST( cholesky(MatrixXf(85,85)) ); } } diff --git a/test/commainitializer.cpp b/test/commainitializer.cpp index fa3e3e348..257ecc21f 100644 --- a/test/commainitializer.cpp +++ b/test/commainitializer.cpp @@ -28,16 +28,16 @@ void test_commainitializer() { Matrix3d m3; Matrix4d m4; - VERIFY_RAISES_ASSERT(m4 = m3); VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) ); VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) ); double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + Matrix3d ref = Map >(data); m3 = Matrix3d::Random(); m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, ref ); Vector3d vec[3]; vec[0] << 1, 4, 7; @@ -45,7 +45,7 @@ void test_commainitializer() vec[2] << 3, 6, 9; m3 = Matrix3d::Random(); m3 << vec[0], vec[1], vec[2]; - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, ref); vec[0] << 1, 2, 3; vec[1] << 4, 5, 6; @@ -54,5 +54,5 @@ void test_commainitializer() m3 << vec[0].transpose(), 4, 5, 6, vec[2].transpose(); - VERIFY_IS_APPROX(m3, (Matrix::map(data)) ); + VERIFY_IS_APPROX(m3, ref); } diff --git a/test/packetmath.cpp b/test/packetmath.cpp new file mode 100644 index 000000000..c282762d6 --- /dev/null +++ b/test/packetmath.cpp @@ -0,0 +1,149 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2008 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#include "main.h" + +// using namespace Eigen; + +template bool areApprox(const Scalar* a, const Scalar* b, int size) +{ + for (int i=0; i const complex& min(const complex& a, const complex& b) +{ return a.real() < b.real() ? a : b; } + +template<> const complex& max(const complex& a, const complex& b) +{ return a.real() < b.real() ? b : a; } + +} + +template void packetmath() +{ + typedef typename ei_packet_traits::type Packet; + const int PacketSize = ei_packet_traits::size; + + const int size = PacketSize*4; + Scalar data1[ei_packet_traits::size*4]; + Scalar data2[ei_packet_traits::size*4]; + Packet packets[PacketSize]; + Scalar ref[ei_packet_traits::size*4]; + for (int i=0; i(); + data2[i] = ei_random(); + } + + ei_pstore(data2, ei_pload(data1)); + VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store"); + + for (int offset=0; offset::ret) + { + for (int offset=0; offset(packets[0], packets[1]); + else if (offset==1) ei_palign<1>(packets[0], packets[1]); + else if (offset==2) ei_palign<2>(packets[0], packets[1]); + else if (offset==3) ei_palign<3>(packets[0], packets[1]); + ei_pstore(data2, packets[0]); + + for (int i=0; i::ret) + CHECK_CWISE(REF_DIV, ei_pdiv); + CHECK_CWISE(std::min, ei_pmin); + CHECK_CWISE(std::max, ei_pmax); + + for (int i=0; i() ); + CALL_SUBTEST( packetmath() ); + CALL_SUBTEST( packetmath() ); + packetmath >(); + } +} diff --git a/test/triangular.cpp b/test/triangular.cpp index de3b85537..fd744114c 100644 --- a/test/triangular.cpp +++ b/test/triangular.cpp @@ -101,6 +101,6 @@ void test_triangular() CALL_SUBTEST( triangular(Matrix3d()) ); CALL_SUBTEST( triangular(MatrixXcf(4, 4)) ); CALL_SUBTEST( triangular(Matrix,8, 8>()) ); - CALL_SUBTEST( triangular(MatrixXf(12,12)) ); + CALL_SUBTEST( triangular(MatrixXf(85,85)) ); } }