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 < 1000; 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(size_t(obj)%ALIGNMENT==0);
     86   delete obj;
     87 }
     88 
     89 void test_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   #if EIGEN_ALIGN_STATICALLY
    108   {
    109     MyStruct foo0;  VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
    110     MyClassA fooA;  VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
    111   }
    112 
    113   // dynamic allocation, single object
    114   for (int i=0; i<g_repeat*100; ++i)
    115   {
    116     MyStruct *foo0 = new MyStruct();  VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
    117     MyClassA *fooA = new MyClassA();  VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
    118     delete foo0;
    119     delete fooA;
    120   }
    121 
    122   // dynamic allocation, array
    123   const int N = 10;
    124   for (int i=0; i<g_repeat*100; ++i)
    125   {
    126     MyStruct *foo0 = new MyStruct[N];  VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
    127     MyClassA *fooA = new MyClassA[N];  VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
    128     delete[] foo0;
    129     delete[] fooA;
    130   }
    131   #endif
    132 
    133 }
    134