blob: cdc10ee89aaeccaad2bb8251e6195a3f22656cc5 [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
Gustavo Lima Chaves2bf1cc82018-08-02 15:55:36 -070018typedef Matrix<float,16,1> Vector16f;
Gael Guennebaud2606abe2014-04-18 21:14:40 +020019typedef Matrix<float,8,1> Vector8f;
20
Benoit Jacobfd831d52009-01-09 14:56:44 +000021void check_handmade_aligned_malloc()
22{
Antonio Sánchez3342fc72022-04-12 14:48:22 +000023 // Hand-make alignment needs at least sizeof(void*) to store the offset.
24 constexpr int alignment = (std::max<int>)(EIGEN_DEFAULT_ALIGN_BYTES, sizeof(void*));
25
Benoit Jacobfd831d52009-01-09 14:56:44 +000026 for(int i = 1; i < 1000; i++)
27 {
Antonio Sánchez3342fc72022-04-12 14:48:22 +000028 char *p = (char*)internal::handmade_aligned_malloc(i, alignment);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020029 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000030 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
31 for(int j = 0; j < i; j++) p[j]=0;
Benoit Jacob47160402010-10-25 10:15:22 -040032 internal::handmade_aligned_free(p);
Benoit Jacobfd831d52009-01-09 14:56:44 +000033 }
34}
35
36void check_aligned_malloc()
37{
Gael Guennebaud5b2d2872016-02-05 21:46:39 +010038 for(int i = ALIGNMENT; i < 1000; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000039 {
Benoit Jacob47160402010-10-25 10:15:22 -040040 char *p = (char*)internal::aligned_malloc(i);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020041 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000042 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
43 for(int j = 0; j < i; j++) p[j]=0;
Benoit Jacob47160402010-10-25 10:15:22 -040044 internal::aligned_free(p);
Benoit Jacobfd831d52009-01-09 14:56:44 +000045 }
46}
47
48void check_aligned_new()
49{
Gael Guennebaud5b2d2872016-02-05 21:46:39 +010050 for(int i = ALIGNMENT; i < 1000; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000051 {
Benoit Jacob47160402010-10-25 10:15:22 -040052 float *p = internal::aligned_new<float>(i);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020053 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000054 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
55 for(int j = 0; j < i; j++) p[j]=0;
Benoit Jacob47160402010-10-25 10:15:22 -040056 internal::aligned_delete(p,i);
Benoit Jacobfd831d52009-01-09 14:56:44 +000057 }
58}
59
60void check_aligned_stack_alloc()
61{
Gael Guennebaud5b2d2872016-02-05 21:46:39 +010062 for(int i = ALIGNMENT; i < 400; i++)
Benoit Jacobfd831d52009-01-09 14:56:44 +000063 {
Gael Guennebaudbbb4b352011-03-19 08:51:38 +010064 ei_declare_aligned_stack_constructed_variable(float,p,i,0);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020065 VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
Benoit Jacobfd831d52009-01-09 14:56:44 +000066 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
67 for(int j = 0; j < i; j++) p[j]=0;
Benoit Jacobfd831d52009-01-09 14:56:44 +000068 }
69}
70
71
Gael Guennebaudf52d1192008-09-03 00:32:56 +000072// test compilation with both a struct and a class...
Benoit Jacob1d52bd42009-01-08 15:20:21 +000073struct MyStruct
Gael Guennebaudf52d1192008-09-03 00:32:56 +000074{
Benoit Jacobeb7dcbb2009-01-08 15:37:13 +000075 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Gael Guennebaudf52d1192008-09-03 00:32:56 +000076 char dummychar;
Gustavo Lima Chaves2bf1cc82018-08-02 15:55:36 -070077 Vector16f avec;
Gael Guennebaudf52d1192008-09-03 00:32:56 +000078};
79
Benoit Jacob1d52bd42009-01-08 15:20:21 +000080class MyClassA
Gael Guennebaudf52d1192008-09-03 00:32:56 +000081{
82 public:
Benoit Jacobeb7dcbb2009-01-08 15:37:13 +000083 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
Gael Guennebaudf52d1192008-09-03 00:32:56 +000084 char dummychar;
Gustavo Lima Chaves2bf1cc82018-08-02 15:55:36 -070085 Vector16f avec;
Gael Guennebaudf52d1192008-09-03 00:32:56 +000086};
87
88template<typename T> void check_dynaligned()
89{
Gael Guennebaud2606abe2014-04-18 21:14:40 +020090 // TODO have to be updated once we support multiple alignment values
91 if(T::SizeAtCompileTime % ALIGNMENT == 0)
92 {
93 T* obj = new T;
94 VERIFY(T::NeedsToAlign==1);
Gael Guennebaudfdcad682016-05-26 17:41:28 +020095 VERIFY(internal::UIntPtr(obj)%ALIGNMENT==0);
Gael Guennebaud2606abe2014-04-18 21:14:40 +020096 delete obj;
97 }
Gael Guennebaudf52d1192008-09-03 00:32:56 +000098}
99
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200100template<typename T> void check_custom_new_delete()
101{
102 {
103 T* t = new T;
104 delete t;
105 }
106
107 {
108 std::size_t N = internal::random<std::size_t>(1,10);
109 T* t = new T[N];
110 delete[] t;
111 }
112
Gael Guennebaudedd413c2019-02-20 13:52:11 +0100113#if EIGEN_MAX_ALIGN_BYTES>0 && (!EIGEN_HAS_CXX17_OVERALIGN)
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200114 {
115 T* t = static_cast<T *>((T::operator new)(sizeof(T)));
116 (T::operator delete)(t, sizeof(T));
117 }
118
119 {
120 T* t = static_cast<T *>((T::operator new)(sizeof(T)));
121 (T::operator delete)(t);
122 }
123#endif
124}
125
Gael Guennebaud82f0ce22018-07-17 14:46:15 +0200126EIGEN_DECLARE_TEST(dynalloc)
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000127{
Benoit Jacobfd831d52009-01-09 14:56:44 +0000128 // low level dynamic memory allocation
129 CALL_SUBTEST(check_handmade_aligned_malloc());
130 CALL_SUBTEST(check_aligned_malloc());
131 CALL_SUBTEST(check_aligned_new());
132 CALL_SUBTEST(check_aligned_stack_alloc());
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000133
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000134 for (int i=0; i<g_repeat*100; ++i)
135 {
Gael Guennebaudba694ce2014-07-30 09:32:35 +0200136 CALL_SUBTEST( check_custom_new_delete<Vector4f>() );
137 CALL_SUBTEST( check_custom_new_delete<Vector2f>() );
138 CALL_SUBTEST( check_custom_new_delete<Matrix4f>() );
139 CALL_SUBTEST( check_custom_new_delete<MatrixXi>() );
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000140 }
141
142 // check static allocation, who knows ?
Gael Guennebaudaec48142015-07-29 11:11:23 +0200143 #if EIGEN_MAX_STATIC_ALIGN_BYTES
Gael Guennebaud84456192015-11-30 22:36:14 +0100144 for (int i=0; i<g_repeat*100; ++i)
145 {
146 CALL_SUBTEST(check_dynaligned<Vector4f>() );
147 CALL_SUBTEST(check_dynaligned<Vector2d>() );
148 CALL_SUBTEST(check_dynaligned<Matrix4f>() );
149 CALL_SUBTEST(check_dynaligned<Vector4d>() );
150 CALL_SUBTEST(check_dynaligned<Vector4i>() );
151 CALL_SUBTEST(check_dynaligned<Vector8f>() );
Gustavo Lima Chaves2bf1cc82018-08-02 15:55:36 -0700152 CALL_SUBTEST(check_dynaligned<Vector16f>() );
Gael Guennebaud84456192015-11-30 22:36:14 +0100153 }
154
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000155 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200156 MyStruct foo0; VERIFY(internal::UIntPtr(foo0.avec.data())%ALIGNMENT==0);
157 MyClassA fooA; VERIFY(internal::UIntPtr(fooA.avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000158 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100159
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000160 // dynamic allocation, single object
161 for (int i=0; i<g_repeat*100; ++i)
162 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200163 MyStruct *foo0 = new MyStruct(); VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
164 MyClassA *fooA = new MyClassA(); VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000165 delete foo0;
166 delete fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000167 }
168
169 // dynamic allocation, array
170 const int N = 10;
171 for (int i=0; i<g_repeat*100; ++i)
172 {
Gael Guennebaudfdcad682016-05-26 17:41:28 +0200173 MyStruct *foo0 = new MyStruct[N]; VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
174 MyClassA *fooA = new MyClassA[N]; VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000175 delete[] foo0;
176 delete[] fooA;
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000177 }
Gael Guennebaud23594862011-03-15 09:53:23 +0100178 #endif
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000179
Gael Guennebaudf52d1192008-09-03 00:32:56 +0000180}