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