Home | History | Annotate | Download | only in test
      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 (at) 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_ALIGN
     13 #define ALIGNMENT 16
     14 #else
     15 #define ALIGNMENT 1
     16 #endif
     17 
     18 void check_handmade_aligned_malloc()
     19 {
     20   for(int i = 1; i < 1000; i++)
     21   {
     22     char *p = (char*)internal::handmade_aligned_malloc(i);
     23     VERIFY(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     internal::handmade_aligned_free(p);
     27   }
     28 }
     29 
     30 void check_aligned_malloc()
     31 {
     32   for(int i = 1; i < 1000; i++)
     33   {
     34     char *p = (char*)internal::aligned_malloc(i);
     35     VERIFY(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     internal::aligned_free(p);
     39   }
     40 }
     41 
     42 void check_aligned_new()
     43 {
     44   for(int i = 1; i < 1000; i++)
     45   {
     46     float *p = internal::aligned_new<float>(i);
     47     VERIFY(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     internal::aligned_delete(p,i);
     51   }
     52 }
     53 
     54 void check_aligned_stack_alloc()
     55 {
     56   for(int i = 1; i < 400; i++)
     57   {
     58     ei_declare_aligned_stack_constructed_variable(float,p,i,0);
     59     VERIFY(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...
     67 struct MyStruct
     68 {
     69   EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     70   char dummychar;
     71   Vector4f avec;
     72 };
     73 
     74 class MyClassA
     75 {
     76   public:
     77     EIGEN_MAKE_ALIGNED_OPERATOR_NEW
     78     char dummychar;
     79     Vector4f avec;
     80 };
     81 
     82 template<typename T> void check_dynaligned()
     83 {
     84   T* obj = new T;
     85   VERIFY(T::NeedsToAlign==1);
     86   VERIFY(size_t(obj)%ALIGNMENT==0);
     87   delete obj;
     88 }
     89 
     90 void test_dynalloc()
     91 {
     92   // low level dynamic memory allocation
     93   CALL_SUBTEST(check_handmade_aligned_malloc());
     94   CALL_SUBTEST(check_aligned_malloc());
     95   CALL_SUBTEST(check_aligned_new());
     96   CALL_SUBTEST(check_aligned_stack_alloc());
     97 
     98   for (int i=0; i<g_repeat*100; ++i)
     99   {
    100     CALL_SUBTEST(check_dynaligned<Vector4f>() );
    101     CALL_SUBTEST(check_dynaligned<Vector2d>() );
    102     CALL_SUBTEST(check_dynaligned<Matrix4f>() );
    103     CALL_SUBTEST(check_dynaligned<Vector4d>() );
    104     CALL_SUBTEST(check_dynaligned<Vector4i>() );
    105   }
    106 
    107   // check static allocation, who knows ?
    108   #if EIGEN_ALIGN_STATICALLY
    109   {
    110     MyStruct foo0;  VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
    111     MyClassA fooA;  VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
    112   }
    113 
    114   // dynamic allocation, single object
    115   for (int i=0; i<g_repeat*100; ++i)
    116   {
    117     MyStruct *foo0 = new MyStruct();  VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
    118     MyClassA *fooA = new MyClassA();  VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
    119     delete foo0;
    120     delete fooA;
    121   }
    122 
    123   // dynamic allocation, array
    124   const int N = 10;
    125   for (int i=0; i<g_repeat*100; ++i)
    126   {
    127     MyStruct *foo0 = new MyStruct[N];  VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
    128     MyClassA *fooA = new MyClassA[N];  VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
    129     delete[] foo0;
    130     delete[] fooA;
    131   }
    132   #endif
    133 
    134 }
    135