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 18void 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 30void 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 42void 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 54void 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... 67struct MyStruct 68{ 69 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 70 char dummychar; 71 Vector4f avec; 72}; 73 74class MyClassA 75{ 76 public: 77 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 78 char dummychar; 79 Vector4f avec; 80}; 81 82template<typename T> void check_dynaligned() 83{ 84 T* obj = new T; 85 VERIFY(std::size_t(obj)%ALIGNMENT==0); 86 delete obj; 87} 88 89void 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