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.

175 lines
4.4 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
  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. #if EIGEN_MAX_ALIGN_BYTES>0
  11. #define ALIGNMENT EIGEN_MAX_ALIGN_BYTES
  12. #else
  13. #define ALIGNMENT 1
  14. #endif
  15. typedef Matrix<float,8,1> Vector8f;
  16. void check_handmade_aligned_malloc()
  17. {
  18. for(int i = 1; i < 1000; i++)
  19. {
  20. char *p = (char*)internal::handmade_aligned_malloc(i);
  21. VERIFY(size_t(p)%ALIGNMENT==0);
  22. // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
  23. for(int j = 0; j < i; j++) p[j]=0;
  24. internal::handmade_aligned_free(p);
  25. }
  26. }
  27. void check_aligned_malloc()
  28. {
  29. for(int i = 1; i < 1000; i++)
  30. {
  31. char *p = (char*)internal::aligned_malloc(i);
  32. VERIFY(size_t(p)%ALIGNMENT==0);
  33. // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
  34. for(int j = 0; j < i; j++) p[j]=0;
  35. internal::aligned_free(p);
  36. }
  37. }
  38. void check_aligned_new()
  39. {
  40. for(int i = 1; i < 1000; i++)
  41. {
  42. float *p = internal::aligned_new<float>(i);
  43. VERIFY(size_t(p)%ALIGNMENT==0);
  44. // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
  45. for(int j = 0; j < i; j++) p[j]=0;
  46. internal::aligned_delete(p,i);
  47. }
  48. }
  49. void check_aligned_stack_alloc()
  50. {
  51. for(int i = 1; i < 400; i++)
  52. {
  53. ei_declare_aligned_stack_constructed_variable(float,p,i,0);
  54. VERIFY(size_t(p)%ALIGNMENT==0);
  55. // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
  56. for(int j = 0; j < i; j++) p[j]=0;
  57. }
  58. }
  59. // test compilation with both a struct and a class...
  60. struct MyStruct
  61. {
  62. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  63. char dummychar;
  64. Vector8f avec;
  65. };
  66. class MyClassA
  67. {
  68. public:
  69. EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  70. char dummychar;
  71. Vector8f avec;
  72. };
  73. template<typename T> void check_dynaligned()
  74. {
  75. // TODO have to be updated once we support multiple alignment values
  76. if(T::SizeAtCompileTime % ALIGNMENT == 0)
  77. {
  78. T* obj = new T;
  79. VERIFY(T::NeedsToAlign==1);
  80. VERIFY(size_t(obj)%ALIGNMENT==0);
  81. delete obj;
  82. }
  83. }
  84. template<typename T> void check_custom_new_delete()
  85. {
  86. {
  87. T* t = new T;
  88. delete t;
  89. }
  90. {
  91. std::size_t N = internal::random<std::size_t>(1,10);
  92. T* t = new T[N];
  93. delete[] t;
  94. }
  95. #if EIGEN_MAX_ALIGN_BYTES>0
  96. {
  97. T* t = static_cast<T *>((T::operator new)(sizeof(T)));
  98. (T::operator delete)(t, sizeof(T));
  99. }
  100. {
  101. T* t = static_cast<T *>((T::operator new)(sizeof(T)));
  102. (T::operator delete)(t);
  103. }
  104. #endif
  105. }
  106. void test_dynalloc()
  107. {
  108. // low level dynamic memory allocation
  109. CALL_SUBTEST(check_handmade_aligned_malloc());
  110. CALL_SUBTEST(check_aligned_malloc());
  111. CALL_SUBTEST(check_aligned_new());
  112. CALL_SUBTEST(check_aligned_stack_alloc());
  113. for (int i=0; i<g_repeat*100; ++i)
  114. {
  115. CALL_SUBTEST( check_custom_new_delete<Vector4f>() );
  116. CALL_SUBTEST( check_custom_new_delete<Vector2f>() );
  117. CALL_SUBTEST( check_custom_new_delete<Matrix4f>() );
  118. CALL_SUBTEST( check_custom_new_delete<MatrixXi>() );
  119. }
  120. // check static allocation, who knows ?
  121. #if EIGEN_MAX_STATIC_ALIGN_BYTES
  122. for (int i=0; i<g_repeat*100; ++i)
  123. {
  124. CALL_SUBTEST(check_dynaligned<Vector4f>() );
  125. CALL_SUBTEST(check_dynaligned<Vector2d>() );
  126. CALL_SUBTEST(check_dynaligned<Matrix4f>() );
  127. CALL_SUBTEST(check_dynaligned<Vector4d>() );
  128. CALL_SUBTEST(check_dynaligned<Vector4i>() );
  129. CALL_SUBTEST(check_dynaligned<Vector8f>() );
  130. }
  131. {
  132. MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
  133. MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
  134. }
  135. // dynamic allocation, single object
  136. for (int i=0; i<g_repeat*100; ++i)
  137. {
  138. MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
  139. MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
  140. delete foo0;
  141. delete fooA;
  142. }
  143. // dynamic allocation, array
  144. const int N = 10;
  145. for (int i=0; i<g_repeat*100; ++i)
  146. {
  147. MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
  148. MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
  149. delete[] foo0;
  150. delete[] fooA;
  151. }
  152. #endif
  153. }