Home | History | Annotate | Download | only in eigen2
      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 (at) 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 
     18 void 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 
     30 void 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 
     42 void 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 
     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(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...
     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(std::size_t(obj)%ALIGNMENT==0);
     86   delete obj;
     87 }
     88 
     89 void 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