cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

dynalloc.cpp (4760B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.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_MAX_ALIGN_BYTES>0
     13 #define ALIGNMENT EIGEN_MAX_ALIGN_BYTES
     14 #else
     15 #define ALIGNMENT 1
     16 #endif
     17 
     18 typedef Matrix<float,16,1> Vector16f;
     19 typedef Matrix<float,8,1> Vector8f;
     20 
     21 void check_handmade_aligned_malloc()
     22 {
     23   for(int i = 1; i < 1000; i++)
     24   {
     25     char *p = (char*)internal::handmade_aligned_malloc(i);
     26     VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
     27     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
     28     for(int j = 0; j < i; j++) p[j]=0;
     29     internal::handmade_aligned_free(p);
     30   }
     31 }
     32 
     33 void check_aligned_malloc()
     34 {
     35   for(int i = ALIGNMENT; i < 1000; i++)
     36   {
     37     char *p = (char*)internal::aligned_malloc(i);
     38     VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
     39     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
     40     for(int j = 0; j < i; j++) p[j]=0;
     41     internal::aligned_free(p);
     42   }
     43 }
     44 
     45 void check_aligned_new()
     46 {
     47   for(int i = ALIGNMENT; i < 1000; i++)
     48   {
     49     float *p = internal::aligned_new<float>(i);
     50     VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
     51     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
     52     for(int j = 0; j < i; j++) p[j]=0;
     53     internal::aligned_delete(p,i);
     54   }
     55 }
     56 
     57 void check_aligned_stack_alloc()
     58 {
     59   for(int i = ALIGNMENT; i < 400; i++)
     60   {
     61     ei_declare_aligned_stack_constructed_variable(float,p,i,0);
     62     VERIFY(internal::UIntPtr(p)%ALIGNMENT==0);
     63     // if the buffer is wrongly allocated this will give a bad write --> check with valgrind
     64     for(int j = 0; j < i; j++) p[j]=0;
     65   }
     66 }
     67 
     68 
     69 // test compilation with both a struct and a class...
     70 struct MyStruct
     71 {
     72   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     73   char dummychar;
     74   Vector16f avec;
     75 };
     76 
     77 class MyClassA
     78 {
     79   public:
     80     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     81     char dummychar;
     82     Vector16f avec;
     83 };
     84 
     85 template<typename T> void check_dynaligned()
     86 {
     87   // TODO have to be updated once we support multiple alignment values
     88   if(T::SizeAtCompileTime % ALIGNMENT == 0)
     89   {
     90     T* obj = new T;
     91     VERIFY(T::NeedsToAlign==1);
     92     VERIFY(internal::UIntPtr(obj)%ALIGNMENT==0);
     93     delete obj;
     94   }
     95 }
     96 
     97 template<typename T> void check_custom_new_delete()
     98 {
     99   {
    100     T* t = new T;
    101     delete t;
    102   }
    103   
    104   {
    105     std::size_t N = internal::random<std::size_t>(1,10);
    106     T* t = new T[N];
    107     delete[] t;
    108   }
    109   
    110 #if EIGEN_MAX_ALIGN_BYTES>0 && (!EIGEN_HAS_CXX17_OVERALIGN)
    111   {
    112     T* t = static_cast<T *>((T::operator new)(sizeof(T)));
    113     (T::operator delete)(t, sizeof(T));
    114   }
    115   
    116   {
    117     T* t = static_cast<T *>((T::operator new)(sizeof(T)));
    118     (T::operator delete)(t);
    119   }
    120 #endif
    121 }
    122 
    123 EIGEN_DECLARE_TEST(dynalloc)
    124 {
    125   // low level dynamic memory allocation
    126   CALL_SUBTEST(check_handmade_aligned_malloc());
    127   CALL_SUBTEST(check_aligned_malloc());
    128   CALL_SUBTEST(check_aligned_new());
    129   CALL_SUBTEST(check_aligned_stack_alloc());
    130 
    131   for (int i=0; i<g_repeat*100; ++i)
    132   {
    133     CALL_SUBTEST( check_custom_new_delete<Vector4f>() );
    134     CALL_SUBTEST( check_custom_new_delete<Vector2f>() );
    135     CALL_SUBTEST( check_custom_new_delete<Matrix4f>() );
    136     CALL_SUBTEST( check_custom_new_delete<MatrixXi>() );
    137   }
    138   
    139   // check static allocation, who knows ?
    140   #if EIGEN_MAX_STATIC_ALIGN_BYTES
    141   for (int i=0; i<g_repeat*100; ++i)
    142   {
    143     CALL_SUBTEST(check_dynaligned<Vector4f>() );
    144     CALL_SUBTEST(check_dynaligned<Vector2d>() );
    145     CALL_SUBTEST(check_dynaligned<Matrix4f>() );
    146     CALL_SUBTEST(check_dynaligned<Vector4d>() );
    147     CALL_SUBTEST(check_dynaligned<Vector4i>() );
    148     CALL_SUBTEST(check_dynaligned<Vector8f>() );
    149     CALL_SUBTEST(check_dynaligned<Vector16f>() );
    150   }
    151 
    152   {
    153     MyStruct foo0;  VERIFY(internal::UIntPtr(foo0.avec.data())%ALIGNMENT==0);
    154     MyClassA fooA;  VERIFY(internal::UIntPtr(fooA.avec.data())%ALIGNMENT==0);
    155   }
    156   
    157   // dynamic allocation, single object
    158   for (int i=0; i<g_repeat*100; ++i)
    159   {
    160     MyStruct *foo0 = new MyStruct();  VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
    161     MyClassA *fooA = new MyClassA();  VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
    162     delete foo0;
    163     delete fooA;
    164   }
    165 
    166   // dynamic allocation, array
    167   const int N = 10;
    168   for (int i=0; i<g_repeat*100; ++i)
    169   {
    170     MyStruct *foo0 = new MyStruct[N];  VERIFY(internal::UIntPtr(foo0->avec.data())%ALIGNMENT==0);
    171     MyClassA *fooA = new MyClassA[N];  VERIFY(internal::UIntPtr(fooA->avec.data())%ALIGNMENT==0);
    172     delete[] foo0;
    173     delete[] fooA;
    174   }
    175   #endif
    176   
    177 }