• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) 2008 Gael Guennebaud <g.gael@free.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_ARCH_WANTS_ALIGNMENT
13 #define ALIGNMENT 16
14 #else
15 #define ALIGNMENT 1
16 #endif
17 
check_handmade_aligned_malloc()18 void check_handmade_aligned_malloc()
19 {
20   for(int i = 1; i < 1000; i++)
21   {
22     char *p = (char*)ei_handmade_aligned_malloc(i);
23     VERIFY(std::size_t(p)%ALIGNMENT==0);
24     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
25     for(int j = 0; j < i; j++) p[j]=0;
26     ei_handmade_aligned_free(p);
27   }
28 }
29 
check_aligned_malloc()30 void check_aligned_malloc()
31 {
32   for(int i = 1; i < 1000; i++)
33   {
34     char *p = (char*)ei_aligned_malloc(i);
35     VERIFY(std::size_t(p)%ALIGNMENT==0);
36     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
37     for(int j = 0; j < i; j++) p[j]=0;
38     ei_aligned_free(p);
39   }
40 }
41 
check_aligned_new()42 void check_aligned_new()
43 {
44   for(int i = 1; i < 1000; i++)
45   {
46     float *p = ei_aligned_new<float>(i);
47     VERIFY(std::size_t(p)%ALIGNMENT==0);
48     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
49     for(int j = 0; j < i; j++) p[j]=0;
50     ei_aligned_delete(p,i);
51   }
52 }
53 
check_aligned_stack_alloc()54 void check_aligned_stack_alloc()
55 {
56   for(int i = 1; i < 1000; i++)
57   {
58     ei_declare_aligned_stack_constructed_variable(float, p, i, 0);
59     VERIFY(std::size_t(p)%ALIGNMENT==0);
60     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
61     for(int j = 0; j < i; j++) p[j]=0;
62   }
63 }
64 
65 
66 // test compilation with both a struct and a class...
67 struct MyStruct
68 {
69   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
70   char dummychar;
71   Vector4f avec;
72 };
73 
74 class MyClassA
75 {
76   public:
77     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
78     char dummychar;
79     Vector4f avec;
80 };
81 
check_dynaligned()82 template<typename T> void check_dynaligned()
83 {
84   T* obj = new T;
85   VERIFY(std::size_t(obj)%ALIGNMENT==0);
86   delete obj;
87 }
88 
test_eigen2_dynalloc()89 void test_eigen2_dynalloc()
90 {
91   // low level dynamic memory allocation
92   CALL_SUBTEST(check_handmade_aligned_malloc());
93   CALL_SUBTEST(check_aligned_malloc());
94   CALL_SUBTEST(check_aligned_new());
95   CALL_SUBTEST(check_aligned_stack_alloc());
96 
97   for (int i=0; i<g_repeat*100; ++i)
98   {
99     CALL_SUBTEST( check_dynaligned<Vector4f>() );
100     CALL_SUBTEST( check_dynaligned<Vector2d>() );
101     CALL_SUBTEST( check_dynaligned<Matrix4f>() );
102     CALL_SUBTEST( check_dynaligned<Vector4d>() );
103     CALL_SUBTEST( check_dynaligned<Vector4i>() );
104   }
105 
106   // check static allocation, who knows ?
107   {
108     MyStruct foo0;  VERIFY(std::size_t(foo0.avec.data())%ALIGNMENT==0);
109     MyClassA fooA;  VERIFY(std::size_t(fooA.avec.data())%ALIGNMENT==0);
110   }
111 
112   // dynamic allocation, single object
113   for (int i=0; i<g_repeat*100; ++i)
114   {
115     MyStruct *foo0 = new MyStruct();  VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
116     MyClassA *fooA = new MyClassA();  VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
117     delete foo0;
118     delete fooA;
119   }
120 
121   // dynamic allocation, array
122   const int N = 10;
123   for (int i=0; i<g_repeat*100; ++i)
124   {
125     MyStruct *foo0 = new MyStruct[N];  VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
126     MyClassA *fooA = new MyClassA[N];  VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
127     delete[] foo0;
128     delete[] fooA;
129   }
130 
131 }
132