00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. Eigen itself is part of the KDE project. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> 00005 // 00006 // Eigen is free software; you can redistribute it and/or 00007 // modify it under the terms of the GNU Lesser General Public 00008 // License as published by the Free Software Foundation; either 00009 // version 3 of the License, or (at your option) any later version. 00010 // 00011 // Alternatively, you can redistribute it and/or 00012 // modify it under the terms of the GNU General Public License as 00013 // published by the Free Software Foundation; either version 2 of 00014 // the License, or (at your option) any later version. 00015 // 00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY 00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License and a copy of the GNU General Public License along with 00023 // Eigen. If not, see <http://www.gnu.org/licenses/>. 00024 00025 #include "main.h" 00026 00027 #if EIGEN_ARCH_WANTS_ALIGNMENT 00028 #define ALIGNMENT 16 00029 #else 00030 #define ALIGNMENT 1 00031 #endif 00032 00033 void check_handmade_aligned_malloc() 00034 { 00035 for(int i = 1; i < 1000; i++) 00036 { 00037 char *p = (char*)ei_handmade_aligned_malloc(i); 00038 VERIFY(std::size_t(p)%ALIGNMENT==0); 00039 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 00040 for(int j = 0; j < i; j++) p[j]=0; 00041 ei_handmade_aligned_free(p); 00042 } 00043 } 00044 00045 void check_aligned_malloc() 00046 { 00047 for(int i = 1; i < 1000; i++) 00048 { 00049 char *p = (char*)ei_aligned_malloc(i); 00050 VERIFY(std::size_t(p)%ALIGNMENT==0); 00051 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 00052 for(int j = 0; j < i; j++) p[j]=0; 00053 ei_aligned_free(p); 00054 } 00055 } 00056 00057 void check_aligned_new() 00058 { 00059 for(int i = 1; i < 1000; i++) 00060 { 00061 float *p = ei_aligned_new<float>(i); 00062 VERIFY(std::size_t(p)%ALIGNMENT==0); 00063 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 00064 for(int j = 0; j < i; j++) p[j]=0; 00065 ei_aligned_delete(p,i); 00066 } 00067 } 00068 00069 void check_aligned_stack_alloc() 00070 { 00071 for(int i = 1; i < 1000; i++) 00072 { 00073 ei_declare_aligned_stack_constructed_variable(float, p, i, 0); 00074 VERIFY(std::size_t(p)%ALIGNMENT==0); 00075 // if the buffer is wrongly allocated this will give a bad write --> check with valgrind 00076 for(int j = 0; j < i; j++) p[j]=0; 00077 } 00078 } 00079 00080 00081 // test compilation with both a struct and a class... 00082 struct MyStruct 00083 { 00084 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00085 char dummychar; 00086 Vector4f avec; 00087 }; 00088 00089 class MyClassA 00090 { 00091 public: 00092 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00093 char dummychar; 00094 Vector4f avec; 00095 }; 00096 00097 template<typename T> void check_dynaligned() 00098 { 00099 T* obj = new T; 00100 VERIFY(std::size_t(obj)%ALIGNMENT==0); 00101 delete obj; 00102 } 00103 00104 void test_eigen2_dynalloc() 00105 { 00106 // low level dynamic memory allocation 00107 CALL_SUBTEST(check_handmade_aligned_malloc()); 00108 CALL_SUBTEST(check_aligned_malloc()); 00109 CALL_SUBTEST(check_aligned_new()); 00110 CALL_SUBTEST(check_aligned_stack_alloc()); 00111 00112 for (int i=0; i<g_repeat*100; ++i) 00113 { 00114 CALL_SUBTEST( check_dynaligned<Vector4f>() ); 00115 CALL_SUBTEST( check_dynaligned<Vector2d>() ); 00116 CALL_SUBTEST( check_dynaligned<Matrix4f>() ); 00117 CALL_SUBTEST( check_dynaligned<Vector4d>() ); 00118 CALL_SUBTEST( check_dynaligned<Vector4i>() ); 00119 } 00120 00121 // check static allocation, who knows ? 00122 { 00123 MyStruct foo0; VERIFY(std::size_t(foo0.avec.data())%ALIGNMENT==0); 00124 MyClassA fooA; VERIFY(std::size_t(fooA.avec.data())%ALIGNMENT==0); 00125 } 00126 00127 // dynamic allocation, single object 00128 for (int i=0; i<g_repeat*100; ++i) 00129 { 00130 MyStruct *foo0 = new MyStruct(); VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0); 00131 MyClassA *fooA = new MyClassA(); VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0); 00132 delete foo0; 00133 delete fooA; 00134 } 00135 00136 // dynamic allocation, array 00137 const int N = 10; 00138 for (int i=0; i<g_repeat*100; ++i) 00139 { 00140 MyStruct *foo0 = new MyStruct[N]; VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0); 00141 MyClassA *fooA = new MyClassA[N]; VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0); 00142 delete[] foo0; 00143 delete[] fooA; 00144 } 00145 00146 }