You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
4.0 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra. Eigen itself is part of the KDE project.
  3. //
  4. // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #include "main.h"
  10. // using namespace Eigen;
  11. template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)
  12. {
  13. for (int i=0; i<size; ++i)
  14. if (!ei_isApprox(a[i],b[i])) return false;
  15. return true;
  16. }
  17. #define CHECK_CWISE(REFOP, POP) { \
  18. for (int i=0; i<PacketSize; ++i) \
  19. ref[i] = REFOP(data1[i], data1[i+PacketSize]); \
  20. ei_pstore(data2, POP(ei_pload(data1), ei_pload(data1+PacketSize))); \
  21. VERIFY(areApprox(ref, data2, PacketSize) && #POP); \
  22. }
  23. #define REF_ADD(a,b) ((a)+(b))
  24. #define REF_SUB(a,b) ((a)-(b))
  25. #define REF_MUL(a,b) ((a)*(b))
  26. #define REF_DIV(a,b) ((a)/(b))
  27. namespace std {
  28. template<> const complex<float>& min(const complex<float>& a, const complex<float>& b)
  29. { return a.real() < b.real() ? a : b; }
  30. template<> const complex<float>& max(const complex<float>& a, const complex<float>& b)
  31. { return a.real() < b.real() ? b : a; }
  32. }
  33. template<typename Scalar> void packetmath()
  34. {
  35. typedef typename ei_packet_traits<Scalar>::type Packet;
  36. const int PacketSize = ei_packet_traits<Scalar>::size;
  37. const int size = PacketSize*4;
  38. EIGEN_ALIGN_128 Scalar data1[ei_packet_traits<Scalar>::size*4];
  39. EIGEN_ALIGN_128 Scalar data2[ei_packet_traits<Scalar>::size*4];
  40. EIGEN_ALIGN_128 Packet packets[PacketSize*2];
  41. EIGEN_ALIGN_128 Scalar ref[ei_packet_traits<Scalar>::size*4];
  42. for (int i=0; i<size; ++i)
  43. {
  44. data1[i] = ei_random<Scalar>();
  45. data2[i] = ei_random<Scalar>();
  46. }
  47. ei_pstore(data2, ei_pload(data1));
  48. VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");
  49. for (int offset=0; offset<PacketSize; ++offset)
  50. {
  51. ei_pstore(data2, ei_ploadu(data1+offset));
  52. VERIFY(areApprox(data1+offset, data2, PacketSize) && "ei_ploadu");
  53. }
  54. for (int offset=0; offset<PacketSize; ++offset)
  55. {
  56. ei_pstoreu(data2+offset, ei_pload(data1));
  57. VERIFY(areApprox(data1, data2+offset, PacketSize) && "ei_pstoreu");
  58. }
  59. for (int offset=0; offset<PacketSize; ++offset)
  60. {
  61. packets[0] = ei_pload(data1);
  62. packets[1] = ei_pload(data1+PacketSize);
  63. if (offset==0) ei_palign<0>(packets[0], packets[1]);
  64. else if (offset==1) ei_palign<1>(packets[0], packets[1]);
  65. else if (offset==2) ei_palign<2>(packets[0], packets[1]);
  66. else if (offset==3) ei_palign<3>(packets[0], packets[1]);
  67. ei_pstore(data2, packets[0]);
  68. for (int i=0; i<PacketSize; ++i)
  69. ref[i] = data1[i+offset];
  70. typedef Matrix<Scalar, PacketSize, 1> Vector;
  71. VERIFY(areApprox(ref, data2, PacketSize) && "ei_palign");
  72. }
  73. CHECK_CWISE(REF_ADD, ei_padd);
  74. CHECK_CWISE(REF_SUB, ei_psub);
  75. CHECK_CWISE(REF_MUL, ei_pmul);
  76. #ifndef EIGEN_VECTORIZE_ALTIVEC
  77. if (!ei_is_same_type<Scalar,int>::ret)
  78. CHECK_CWISE(REF_DIV, ei_pdiv);
  79. #endif
  80. CHECK_CWISE(std::min, ei_pmin);
  81. CHECK_CWISE(std::max, ei_pmax);
  82. for (int i=0; i<PacketSize; ++i)
  83. ref[i] = data1[0];
  84. ei_pstore(data2, ei_pset1(data1[0]));
  85. VERIFY(areApprox(ref, data2, PacketSize) && "ei_pset1");
  86. VERIFY(ei_isApprox(data1[0], ei_pfirst(ei_pload(data1))) && "ei_pfirst");
  87. ref[0] = 0;
  88. for (int i=0; i<PacketSize; ++i)
  89. ref[0] += data1[i];
  90. VERIFY(ei_isApprox(ref[0], ei_predux(ei_pload(data1))) && "ei_predux");
  91. for (int j=0; j<PacketSize; ++j)
  92. {
  93. ref[j] = 0;
  94. for (int i=0; i<PacketSize; ++i)
  95. ref[j] += data1[i+j*PacketSize];
  96. packets[j] = ei_pload(data1+j*PacketSize);
  97. }
  98. ei_pstore(data2, ei_preduxp(packets));
  99. VERIFY(areApprox(ref, data2, PacketSize) && "ei_preduxp");
  100. }
  101. void test_eigen2_packetmath()
  102. {
  103. for(int i = 0; i < g_repeat; i++) {
  104. CALL_SUBTEST_1( packetmath<float>() );
  105. CALL_SUBTEST_2( packetmath<double>() );
  106. CALL_SUBTEST_3( packetmath<int>() );
  107. CALL_SUBTEST_4( packetmath<std::complex<float> >() );
  108. }
  109. }