blob: 1190eb9cd7ad85416775f1e3eacedb94fcf03fcf [file] [log] [blame]
Gael Guennebaudf52d1192008-09-03 00:32:56 +00001// This file is part of Eigen, a lightweight C++ template library
Benoit Jacob6347b1d2009-05-22 20:25:33 +02002// for linear algebra.
Gael Guennebaudf52d1192008-09-03 00:32:56 +00003//
Gael Guennebaud28e64b02010-06-24 23:21:58 +02004// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
Gael Guennebaudf52d1192008-09-03 00:32:56 +00005//
Benoit Jacob69124cf2012-07-13 14:42:47 -04006// 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/.
Gael Guennebaudf52d1192008-09-03 00:32:56 +00009
10#include "main.h"
11
Benoit Jacob95bda5e2009-05-03 13:50:56 +000012#if EIGEN_ALIGN
Gael Guennebaud2606abe2014-04-18 21:14:40 +020013#define ALIGNMENT EIGEN_ALIGN_BYTES
Benoit Jacob93a089a2009-02-04 16:53:03 +000014#else
15#define ALIGNMENT 1
16#endif
17
Gael Guennebaud2606abe2014-04-18 21:14:40 +020018typedef Matrix<float,8,1> Vector8f;
19
Benoit Jacobfd831d52009-01-09 14:56:44 +000020void check_handmade_aligned_malloc()
21{
22 for(int i = 1; i < 1000; i++)
23 {
Benoit Jacob47160402010-10-25 10:15:22 -040024 char *p = (char*)internal::handmade_aligned_malloc(i);
Benoit Jacob93a089a2009-02-04 16:53:03 +000025 VERIFY(size_t(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000026 // 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;
Benoit Jacob47160402010-10-25 10:15:22 -040028 internal::handmade_aligned_free(p);
Benoit Jacobfd831d52009-01-09 14:56:44 +000029 }
30}
31
32void check_aligned_malloc()
33{
34 for(int i = 1; i < 1000; i++)
35 {
Benoit Jacob47160402010-10-25 10:15:22 -040036 char *p = (char*)internal::aligned_malloc(i);
Benoit Jacob93a089a2009-02-04 16:53:03 +000037 VERIFY(size_t(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000038 // 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;
Benoit Jacob47160402010-10-25 10:15:22 -040040 internal::aligned_free(p);
Benoit Jacobfd831d52009-01-09 14:56:44 +000041 }
42}
43
44void check_aligned_new()
45{
46 for(int i = 1; i < 1000; i++)
47 {
Benoit Jacob47160402010-10-25 10:15:22 -040048 float *p = internal::aligned_new<float>(i);
Benoit Jacob93a089a2009-02-04 16:53:03 +000049 VERIFY(size_t(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000050 // 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;
Benoit Jacob47160402010-10-25 10:15:22 -040052 internal::aligned_delete(p,i);
Benoit Jacobfd831d52009-01-09 14:56:44 +000053 }
54}
55
56void check_aligned_stack_alloc()
57{
Gael Guennebaude51da9c2014-08-04 12:46:00 +020058 for(int i = 1; i < 400; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000059 {
Gael Guennebaudbbb4b352011-03-19 08:51:38 +010060 ei_declare_aligned_stack_constructed_variable(float,p,i,0);
Benoit Jacob93a089a2009-02-04 16:53:03 +000061 VERIFY(size_t(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000062 // 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;
Benoit Jacobfd831d52009-01-09 14:56:44 +000064 }
65}
66
67
Gael Guennebaudf52d1192008-09-03 00:32:56 +000068// test compilation with both a struct and a class...
Benoit Jacob1d52bd42009-01-08 15:20:21 +000069struct MyStruct
Gael Guennebaudf52d1192008-09-03 00:32:56 +000070{
Benoit Jacobeb7dcbb2009-01-08 15:37:13 +000071 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Gael Guennebaudf52d1192008-09-03 00:32:56 +000072 char dummychar;
Gael Guennebaud2606abe2014-04-18 21:14:40 +020073 Vector8f avec;
Gael Guennebaudf52d1192008-09-03 00:32:56 +000074};
75
Benoit Jacob1d52bd42009-01-08 15:20:21 +000076class MyClassA
Gael Guennebaudf52d1192008-09-03 00:32:56 +000077{
78 public:
Benoit Jacobeb7dcbb2009-01-08 15:37:13 +000079 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Gael Guennebaudf52d1192008-09-03 00:32:56 +000080 char dummychar;
Gael Guennebaud2606abe2014-04-18 21:14:40 +020081 Vector8f avec;
Gael Guennebaudf52d1192008-09-03 00:32:56 +000082};
83
84template<typename T> void check_dynaligned()
85{
Gael Guennebaud2606abe2014-04-18 21:14:40 +020086 // 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(size_t(obj)%ALIGNMENT==0);
92 delete obj;
93 }
Gael Guennebaudf52d1192008-09-03 00:32:56 +000094}
95
Gael Guennebaudba694ce2014-07-30 09:32:35 +020096template<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#ifdef EIGEN_ALIGN
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
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000122void test_dynalloc()
123{
Benoit Jacobfd831d52009-01-09 14:56:44 +0000124 // 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());
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000129
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000130 for (int i=0; i<g_repeat*100; ++i)
131 {
Benoit Jacob2840ac72009-10-28 18:19:29 -0400132 CALL_SUBTEST(check_dynaligned<Vector4f>() );
133 CALL_SUBTEST(check_dynaligned<Vector2d>() );
134 CALL_SUBTEST(check_dynaligned<Matrix4f>() );
135 CALL_SUBTEST(check_dynaligned<Vector4d>() );
136 CALL_SUBTEST(check_dynaligned<Vector4i>() );
Gael Guennebaud2606abe2014-04-18 21:14:40 +0200137 CALL_SUBTEST(check_dynaligned<Vector8f>() );
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200138
139 CALL_SUBTEST( check_custom_new_delete<Vector4f>() );
140 CALL_SUBTEST( check_custom_new_delete<Vector2f>() );
141 CALL_SUBTEST( check_custom_new_delete<Matrix4f>() );
142 CALL_SUBTEST( check_custom_new_delete<MatrixXi>() );
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000143 }
144
145 // check static allocation, who knows ?
Gael Guennebaud23594862011-03-15 09:53:23 +0100146 #if EIGEN_ALIGN_STATICALLY
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000147 {
Benoit Jacob93a089a2009-02-04 16:53:03 +0000148 MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
149 MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000150 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100151
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000152 // dynamic allocation, single object
153 for (int i=0; i<g_repeat*100; ++i)
154 {
Benoit Jacob93a089a2009-02-04 16:53:03 +0000155 MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
156 MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000157 delete foo0;
158 delete fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000159 }
160
161 // dynamic allocation, array
162 const int N = 10;
163 for (int i=0; i<g_repeat*100; ++i)
164 {
Benoit Jacob93a089a2009-02-04 16:53:03 +0000165 MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
166 MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000167 delete[] foo0;
168 delete[] fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000169 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100170 #endif
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000171
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000172}