blob: ceecd76e30378e9660c2bec3b3829ebf127af6e6 [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
Gael Guennebaudaec48142015-07-29 11:11:23 +020012#if EIGEN_MAX_ALIGN_BYTES>0
13#define ALIGNMENT EIGEN_MAX_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);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020025 VERIFY(internal::UIntPtr(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{
Gael Guennebaud5b2d2872016-02-05 21:46:39 +010034 for(int i = ALIGNMENT; i < 1000; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000035 {
Benoit Jacob47160402010-10-25 10:15:22 -040036 char *p = (char*)internal::aligned_malloc(i);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020037 VERIFY(internal::UIntPtr(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{
Gael Guennebaud5b2d2872016-02-05 21:46:39 +010046 for(int i = ALIGNMENT; i < 1000; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000047 {
Benoit Jacob47160402010-10-25 10:15:22 -040048 float *p = internal::aligned_new<float>(i);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020049 VERIFY(internal::UIntPtr(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 Guennebaud5b2d2872016-02-05 21:46:39 +010058 for(int i = ALIGNMENT; 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);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020061 VERIFY(internal::UIntPtr(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);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020091 VERIFY(internal::UIntPtr(obj)%ALIGNMENT==0);
Gael Guennebaud2606abe2014-04-18 21:14:40 +020092 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
Gael Guennebaudaec48142015-07-29 11:11:23 +0200109#if EIGEN_MAX_ALIGN_BYTES>0
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200110 {
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 Guennebaud82f0ce22018-07-17 14:46:15 +0200122EIGEN_DECLARE_TEST(dynalloc)
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000123{
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 {
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200132 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>() );
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000136 }
137
138 // check static allocation, who knows ?
Gael Guennebaudaec48142015-07-29 11:11:23 +0200139 #if EIGEN_MAX_STATIC_ALIGN_BYTES
Gael Guennebaud84456192015-11-30 22:36:14 +0100140 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
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000150 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200151 MyStruct foo0; VERIFY(internal::UIntPtr(foo0.avec.data())%ALIGNMENT==0);
152 MyClassA fooA; VERIFY(internal::UIntPtr(fooA.avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000153 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100154
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000155 // dynamic allocation, single object
156 for (int i=0; i<g_repeat*100; ++i)
157 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200158 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);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000160 delete foo0;
161 delete fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000162 }
163
164 // dynamic allocation, array
165 const int N = 10;
166 for (int i=0; i<g_repeat*100; ++i)
167 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200168 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);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000170 delete[] foo0;
171 delete[] fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000172 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100173 #endif
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000174
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000175}