Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 1 | // This file is part of Eigen, a lightweight C++ template library |
Benoit Jacob | 6347b1d | 2009-05-22 20:25:33 +0200 | [diff] [blame] | 2 | // for linear algebra. |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 3 | // |
| 4 | // Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> |
| 5 | // |
Benoit Jacob | 69124cf | 2012-07-13 14:42:47 -0400 | [diff] [blame] | 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/. |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 9 | |
| 10 | #include "main.h" |
| 11 | |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 12 | typedef Matrix<float,8,1> Vector8f; |
| 13 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 14 | struct TestNew1 |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 15 | { |
| 16 | MatrixXd m; // good: m will allocate its own array, taking care of alignment. |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 17 | TestNew1() : m(20,20) {} |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 18 | }; |
| 19 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 20 | struct TestNew2 |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 21 | { |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 22 | Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned, |
| 23 | // 8-byte alignment is good enough here, which we'll get automatically |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 24 | }; |
| 25 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 26 | struct TestNew3 |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 27 | { |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 28 | Vector2f m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 29 | }; |
| 30 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 31 | struct TestNew4 |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 32 | { |
Benoit Jacob | eb7dcbb | 2009-01-08 15:37:13 +0000 | [diff] [blame] | 33 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 34 | Vector2d m; |
| 35 | float f; // make the struct have sizeof%16!=0 to make it a little more tricky when we allow an array of 2 such objects |
| 36 | }; |
| 37 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 38 | struct TestNew5 |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 39 | { |
Benoit Jacob | eb7dcbb | 2009-01-08 15:37:13 +0000 | [diff] [blame] | 40 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 41 | float f; // try the f at first -- the EIGEN_ALIGN16 attribute of m should make that still work |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 42 | Matrix4f m; |
| 43 | }; |
| 44 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 45 | struct TestNew6 |
Benoit Jacob | 15ca665 | 2009-01-04 15:26:32 +0000 | [diff] [blame] | 46 | { |
Benoit Jacob | 2db4342 | 2009-01-06 18:07:16 +0000 | [diff] [blame] | 47 | Matrix<float,2,2,DontAlign> m; // good: no alignment requested |
Benoit Jacob | 15ca665 | 2009-01-04 15:26:32 +0000 | [diff] [blame] | 48 | float f; |
| 49 | }; |
| 50 | |
Benoit Jacob | 1c29d70 | 2009-01-06 03:16:50 +0000 | [diff] [blame] | 51 | template<bool Align> struct Depends |
| 52 | { |
Benoit Jacob | eb7dcbb | 2009-01-08 15:37:13 +0000 | [diff] [blame] | 53 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align) |
Benoit Jacob | 1c29d70 | 2009-01-06 03:16:50 +0000 | [diff] [blame] | 54 | Vector2d m; |
| 55 | float f; |
| 56 | }; |
| 57 | |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 58 | template<typename T> |
| 59 | void check_unalignedassert_good() |
| 60 | { |
| 61 | T *x, *y; |
| 62 | x = new T; |
| 63 | delete x; |
| 64 | y = new T[2]; |
| 65 | delete[] y; |
| 66 | } |
| 67 | |
Benoit Jacob | 2bd31d3 | 2010-03-06 09:05:15 -0500 | [diff] [blame] | 68 | #if EIGEN_ALIGN_STATICALLY |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 69 | template<typename T> |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 70 | void construct_at_boundary(int boundary) |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 71 | { |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 72 | char buf[sizeof(T)+256]; |
| 73 | size_t _buf = reinterpret_cast<size_t>(buf); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 74 | _buf += (EIGEN_ALIGN_BYTES - (_buf % EIGEN_ALIGN_BYTES)); // make 16/32-byte aligned |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 75 | _buf += boundary; // make exact boundary-aligned |
| 76 | T *x = ::new(reinterpret_cast<void*>(_buf)) T; |
Benoit Jacob | 46a9cac | 2009-12-14 23:31:00 -0500 | [diff] [blame] | 77 | x[0].setZero(); // just in order to silence warnings |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 78 | x->~T(); |
| 79 | } |
Benoit Jacob | f81479d | 2009-02-04 16:55:38 +0000 | [diff] [blame] | 80 | #endif |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 81 | |
| 82 | void unalignedassert() |
| 83 | { |
Gael Guennebaud | 1330f8b | 2015-03-13 21:15:50 +0100 | [diff] [blame^] | 84 | #if EIGEN_ALIGN_STATICALLY |
Benoit Jacob | bb1cc0d | 2009-10-05 10:55:42 -0400 | [diff] [blame] | 85 | construct_at_boundary<Vector2f>(4); |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 86 | construct_at_boundary<Vector3f>(4); |
| 87 | construct_at_boundary<Vector4f>(16); |
| 88 | construct_at_boundary<Matrix2f>(16); |
| 89 | construct_at_boundary<Matrix3f>(4); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 90 | construct_at_boundary<Matrix4f>(EIGEN_ALIGN_BYTES); |
Gael Guennebaud | 2049f74 | 2009-10-13 08:53:01 +0200 | [diff] [blame] | 91 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 92 | construct_at_boundary<Vector2d>(16); |
Benoit Jacob | bb1cc0d | 2009-10-05 10:55:42 -0400 | [diff] [blame] | 93 | construct_at_boundary<Vector3d>(4); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 94 | construct_at_boundary<Vector4d>(EIGEN_ALIGN_BYTES); |
| 95 | construct_at_boundary<Matrix2d>(EIGEN_ALIGN_BYTES); |
Benoit Jacob | bb1cc0d | 2009-10-05 10:55:42 -0400 | [diff] [blame] | 96 | construct_at_boundary<Matrix3d>(4); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 97 | construct_at_boundary<Matrix4d>(EIGEN_ALIGN_BYTES); |
Gael Guennebaud | 2049f74 | 2009-10-13 08:53:01 +0200 | [diff] [blame] | 98 | |
Benoit Jacob | bb1cc0d | 2009-10-05 10:55:42 -0400 | [diff] [blame] | 99 | construct_at_boundary<Vector2cf>(16); |
| 100 | construct_at_boundary<Vector3cf>(4); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 101 | construct_at_boundary<Vector2cd>(EIGEN_ALIGN_BYTES); |
Benoit Jacob | bb1cc0d | 2009-10-05 10:55:42 -0400 | [diff] [blame] | 102 | construct_at_boundary<Vector3cd>(16); |
Gael Guennebaud | 1330f8b | 2015-03-13 21:15:50 +0100 | [diff] [blame^] | 103 | #endif |
Gael Guennebaud | 2049f74 | 2009-10-13 08:53:01 +0200 | [diff] [blame] | 104 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 105 | check_unalignedassert_good<TestNew1>(); |
| 106 | check_unalignedassert_good<TestNew2>(); |
| 107 | check_unalignedassert_good<TestNew3>(); |
Benoit Jacob | f81479d | 2009-02-04 16:55:38 +0000 | [diff] [blame] | 108 | |
Benoit Jacob | d415778 | 2009-10-05 10:11:11 -0400 | [diff] [blame] | 109 | check_unalignedassert_good<TestNew4>(); |
| 110 | check_unalignedassert_good<TestNew5>(); |
| 111 | check_unalignedassert_good<TestNew6>(); |
Benoit Jacob | 1c29d70 | 2009-01-06 03:16:50 +0000 | [diff] [blame] | 112 | check_unalignedassert_good<Depends<true> >(); |
Gael Guennebaud | 2049f74 | 2009-10-13 08:53:01 +0200 | [diff] [blame] | 113 | |
Benoit Jacob | 2bd31d3 | 2010-03-06 09:05:15 -0500 | [diff] [blame] | 114 | #if EIGEN_ALIGN_STATICALLY |
Gael Guennebaud | 1330f8b | 2015-03-13 21:15:50 +0100 | [diff] [blame^] | 115 | if(EIGEN_ALIGN_BYTES>=16) |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 116 | { |
| 117 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8)); |
| 118 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8)); |
| 119 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cf>(8)); |
Gael Guennebaud | 1330f8b | 2015-03-13 21:15:50 +0100 | [diff] [blame^] | 120 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4i>(8)); |
Gael Guennebaud | 2606abe | 2014-04-18 21:14:40 +0200 | [diff] [blame] | 121 | } |
| 122 | for(int b=8; b<EIGEN_ALIGN_BYTES; b+=8) |
| 123 | { |
| 124 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector8f>(b)); |
| 125 | VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(b)); |
| 126 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4d>(b)); |
| 127 | VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix2d>(b)); |
| 128 | VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4d>(b)); |
| 129 | VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cd>(b)); |
| 130 | } |
Benoit Jacob | f81479d | 2009-02-04 16:55:38 +0000 | [diff] [blame] | 131 | #endif |
Benoit Jacob | 3958e7f | 2008-12-31 00:05:22 +0000 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | void test_unalignedassert() |
| 135 | { |
| 136 | CALL_SUBTEST(unalignedassert()); |
| 137 | } |