eigen2_dynalloc.cpp revision c981c48f5bc9aefeffc0bcb0cc3934c2fae179dd
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@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
18void 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
30void 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
42void 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
54void 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...
67struct MyStruct
68{
69  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
70  char dummychar;
71  Vector4f avec;
72};
73
74class MyClassA
75{
76  public:
77    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
78    char dummychar;
79    Vector4f avec;
80};
81
82template<typename T> void check_dynaligned()
83{
84  T* obj = new T;
85  VERIFY(std::size_t(obj)%ALIGNMENT==0);
86  delete obj;
87}
88
89void 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