GCC Code Coverage Report


Directory: ./
File: TestEigen.cpp
Date: 2026-03-21 20:51:59
Exec Total Coverage
Lines: 350 355 98.6%
Functions: 166 167 99.4%
Branches: 398 1066 37.3%

Line Branch Exec Source
1 // NOLINTNEXTLINE(*-macro-usage)
2 #define EIGEN_RUNTIME_NO_MALLOC 1
3
4 // See https://gitlab.com/libeigen/eigen/-/issues/2506
5 #pragma GCC diagnostic push
6 #pragma GCC diagnostic ignored "-Warray-bounds"
7
8 #include <Eigen/Eigen>
9
10 #pragma GCC diagnostic pop
11
12 #include <boost/timer/timer.hpp>
13 #include <gtest/gtest.h>
14 #include <vector>
15
16 using namespace Eigen;
17
18 // [Writing Functions Taking Eigen Types as Parameters](https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html)
19 // [Block Operations](https://eigen.tuxfamily.org/dox/group__TutorialBlockOperations.html)
20
21 class TestEigen : public testing::Test {
22 public:
23 // Fixed-capacity, dynamically sized column vector.
24 using VectorX4d = Matrix<double, Dynamic, 1, StorageOptions{}, 4, 1>;
25
26 // Fixed-capacity column vectors packed into a dynamically-sized matrix.
27 using MatrixXX4Xd =
28 Matrix<double, Dynamic, Dynamic, StorageOptions{}, 4, Dynamic>;
29
30 1 static void SetUpTestCase() {
31 1 std::cout << "size of a + b + n = "
32 1 << (sizeof(double) * ((aSize * bSize) + 3 * (aSize + bSize)))
33 1 << std::endl;
34 1 }
35
36 // Initialize all data structures (with the same random data)
37 // during setup in order to exclude this work from timing results.
38 41 void SetUp() override {
39 41 aDynamic.setRandom(3, aSize);
40 41 bDynamic.setRandom(3, bSize);
41 41 aCapped = aDynamic;
42 41 bCapped = bDynamic;
43 41 aFixed = aDynamic;
44 41 bFixed = bDynamic;
45
46 41 aPointerCollection.resize(aSize);
47 41 aDynamicCollection.resize(aSize);
48 41 aCappedCollection.resize(aSize);
49 41 aFixedCollection.resize(aSize);
50
2/2
✓ Branch 0 taken 1640 times.
✓ Branch 1 taken 41 times.
1681 for (auto i = 0; i < aSize; i++) {
51
2/4
✓ Branch 6 taken 1640 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1640 times.
✗ Branch 11 not taken.
1640 aPointerCollection[i] = std::make_unique<VectorXd>(aDynamic.col(i));
52
2/4
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 1640 times.
✗ Branch 14 not taken.
1640 aDynamicCollection[i] = aDynamic.col(i);
53
2/4
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 1640 times.
✗ Branch 14 not taken.
1640 aCappedCollection[i] = aDynamic.col(i);
54
2/4
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 1640 times.
✗ Branch 14 not taken.
1640 aFixedCollection[i] = aDynamic.col(i);
55 }
56
57 41 bPointerCollection.resize(bSize);
58 41 bDynamicCollection.resize(bSize);
59 41 bCappedCollection.resize(bSize);
60 41 bFixedCollection.resize(bSize);
61
2/2
✓ Branch 0 taken 6150 times.
✓ Branch 1 taken 41 times.
6191 for (auto i = 0; i < bSize; i++) {
62
2/4
✓ Branch 6 taken 6150 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 6150 times.
✗ Branch 11 not taken.
6150 bPointerCollection[i] = std::make_unique<VectorXd>(bDynamic.col(i));
63
2/4
✓ Branch 5 taken 6150 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 6150 times.
✗ Branch 14 not taken.
6150 bDynamicCollection[i] = bDynamic.col(i);
64
2/4
✓ Branch 5 taken 6150 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 6150 times.
✗ Branch 14 not taken.
6150 bCappedCollection[i] = bDynamic.col(i);
65
2/4
✓ Branch 5 taken 6150 times.
✗ Branch 6 not taken.
✓ Branch 13 taken 6150 times.
✗ Branch 14 not taken.
6150 bFixedCollection[i] = bDynamic.col(i);
66 }
67
68 41 actual.setZero(aSize, bSize);
69 41 expected.setZero(aSize, bSize);
70
2/2
✓ Branch 4 taken 1640 times.
✓ Branch 5 taken 41 times.
1681 for (auto row = 0; row < expected.rows(); row++) {
71
2/2
✓ Branch 4 taken 246000 times.
✓ Branch 5 taken 1640 times.
247640 for (auto col = 0; col < expected.cols(); col++) {
72
1/2
✓ Branch 4 taken 246000 times.
✗ Branch 5 not taken.
492000 expected(row, col) =
73
4/8
✓ Branch 5 taken 246000 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 246000 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 246000 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 246000 times.
✗ Branch 19 not taken.
492000 (aDynamic.col(row) - bDynamic.col(col)).squaredNorm();
74 }
75 }
76 41 Eigen::internal::set_is_malloc_allowed(false);
77 41 timer.start();
78 41 }
79
80 41 void TearDown() override {
81 41 timer.stop();
82 41 Eigen::internal::set_is_malloc_allowed(true);
83 41 expectEq(actual, expected);
84
2/4
✓ Branch 5 taken 41 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 41 times.
✗ Branch 10 not taken.
41 std::cout << timer.format(3);
85 41 }
86
87 // Accept arguments by non-const lvalue reference
88 // in order to prevent creation of temporary objects.
89 // Compilation fails if types are mismatched.
90 41 void expectEq(MatrixXd& actual, MatrixXd& expected) {
91
2/2
✓ Branch 3 taken 30 times.
✓ Branch 4 taken 11 times.
41 if (actual(0, 0) != 0) {
92
4/14
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 30 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 30 times.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 30 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
30 EXPECT_DOUBLE_EQ(actual(0, 0), expected(0, 0));
93 }
94
9/26
✓ Branch 8 taken 41 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 11 times.
✓ Branch 11 taken 30 times.
✓ Branch 17 taken 11 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 11 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 11 times.
✓ Branch 23 taken 30 times.
✓ Branch 25 taken 41 times.
✗ Branch 26 not taken.
✗ Branch 30 not taken.
✓ Branch 31 taken 41 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✗ Branch 58 not taken.
✗ Branch 59 not taken.
✗ Branch 61 not taken.
✗ Branch 62 not taken.
41 EXPECT_TRUE(actual.isApprox(expected) or actual.isZero());
95 41 }
96
97 // Benchmark for collection of vectors.
98 template <typename A, typename B>
99 8 void squaredDistance(const std::vector<A>& a, const std::vector<B>& b) {
100
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
32 for (auto i = 0; i < repeat; i++) {
101
2/2
✓ Branch 4 taken 480 times.
✓ Branch 5 taken 12 times.
984 for (auto row = 0; row < actual.rows(); row++) {
102
2/2
✓ Branch 4 taken 72000 times.
✓ Branch 5 taken 480 times.
144960 for (auto col = 0; col < actual.cols(); col++) {
103
3/6
✓ Branch 7 taken 72000 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 72000 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 72000 times.
✗ Branch 17 not taken.
144000 actual(row, col) = (a[row] - b[col]).squaredNorm();
104 }
105 }
106 }
107 8 }
108
109 // Benchmark for matrix types.
110 template <typename A, typename B>
111 8 void squaredDistance(const MatrixBase<A>& a, const MatrixBase<B>& b) {
112
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
32 for (auto i = 0; i < repeat; i++) {
113
2/2
✓ Branch 4 taken 480 times.
✓ Branch 5 taken 12 times.
984 for (auto row = 0; row < actual.rows(); row++) {
114
2/2
✓ Branch 4 taken 72000 times.
✓ Branch 5 taken 480 times.
144960 for (auto col = 0; col < actual.cols(); col++) {
115
5/10
✓ Branch 4 taken 72000 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 72000 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 72000 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 72000 times.
✗ Branch 16 not taken.
✓ Branch 21 taken 72000 times.
✗ Branch 22 not taken.
144000 actual(row, col) = (a.col(row) - b.col(col)).squaredNorm();
116 }
117 }
118 }
119 8 }
120
121 // Column-wise benchmark.
122 template <typename A, typename B>
123 8 void squaredDistanceColwise(const MatrixBase<A>& a, const MatrixBase<B>& b) {
124
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
32 for (auto i = 0; i < repeat; i++) {
125
2/2
✓ Branch 4 taken 1800 times.
✓ Branch 5 taken 12 times.
3624 for (auto col = 0; col < actual.cols(); col++) {
126
2/4
✓ Branch 6 taken 1800 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1800 times.
✗ Branch 10 not taken.
7200 actual.col(col) =
127
5/10
✓ Branch 5 taken 1800 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1800 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1800 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1800 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1800 times.
✗ Branch 20 not taken.
7200 (a.colwise() - b.col(col)).colwise().squaredNorm();
128 }
129 }
130 8 }
131
132 // Replicate benchmark.
133 template <typename A, typename B>
134 8 void squaredDistanceReplicate(const MatrixBase<A>& a, const MatrixBase<B>& b) {
135
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
32 for (auto i = 0; i < repeat; i++) {
136
2/2
✓ Branch 4 taken 1800 times.
✓ Branch 5 taken 12 times.
3624 for (auto col = 0; col < actual.cols(); col++) {
137
6/12
✓ Branch 6 taken 1800 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1800 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 1800 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1800 times.
✗ Branch 19 not taken.
✓ Branch 25 taken 1800 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1800 times.
✗ Branch 29 not taken.
10800 actual.col(col) = (a - b.col(col).rowwise().replicate(a.cols()))
138
1/2
✓ Branch 2 taken 1800 times.
✗ Branch 3 not taken.
10800 .colwise()
139
1/2
✓ Branch 2 taken 1800 times.
✗ Branch 3 not taken.
10800 .squaredNorm();
140 }
141 }
142 8 }
143
144 // Parallel benchmark.
145 template <typename A, typename B>
146 8 void squaredDistanceParallel(const MatrixBase<A>& a, const MatrixBase<B>& b) {
147
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
32 for (auto i = 0; i < repeat; i++) {
148 24 #pragma omp parallel for num_threads(2)
149 for (auto col = 0; col < actual.cols(); col++) {
150 actual.col(col) =
151 (a.colwise() - b.col(col)).colwise().squaredNorm();
152 }
153 }
154 8 }
155
156 // No temporary objects are created when arguments are any matrix (or vector)
157 // expression (but not a special matrix such as Eigen::DiagonalMatrix)
158 template <typename A, typename B>
159 18000 double squaredDistanceTemplate(const MatrixBase<A>& a, const MatrixBase<B>& b) {
160
2/4
✓ Branch 2 taken 18000 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 18000 times.
✗ Branch 6 not taken.
18000 return (a - b).squaredNorm();
161 }
162
163 // No temporary objects are created when arguments are any vector or subvector.
164 54000 double squaredDistanceRef(
165 const Ref<const VectorXd>& a, const Ref<const VectorXd>& b) {
166
2/4
✓ Branch 3 taken 54000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 54000 times.
✗ Branch 7 not taken.
54000 return (a - b).squaredNorm();
167 }
168
169 // No temporary objects are created when arguments are any vector or subvector.
170 18000 double squaredDistanceFixedRef(
171 const Ref<const Vector3d>& a, const Ref<const Vector3d>& b) {
172
2/4
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18000 times.
✗ Branch 7 not taken.
18000 return (a - b).squaredNorm();
173 }
174
175 // No temporary objects are created when arguments are Vector3d.
176 18000 double squaredDistanceFixed(const Vector3d& a, const Vector3d& b) {
177
2/4
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18000 times.
✗ Branch 7 not taken.
18000 return (a - b).squaredNorm();
178 }
179
180 // No temporary objects are created when arguments are VectorX4d.
181 18000 double squaredDistanceCapped(const VectorX4d& a, const VectorX4d& b) {
182
2/4
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18000 times.
✗ Branch 7 not taken.
18000 return (a - b).squaredNorm();
183 }
184
185 // No temporary objects are created when arguments are VectorXd.
186 double squaredDistanceDynamic(const VectorXd& a, const VectorXd& b) {
187 return (a - b).squaredNorm();
188 }
189
190 // Verify that temporary objects are not created by comparing data pointers.
191 template <typename T>
192 6 bool sameDataTemplate(const MatrixBase<T>& x, const double* data) {
193 6 return x.derived().data() == data;
194 }
195
196 // Verify that temporary objects are not created by comparing data pointers.
197 8 bool sameDataRef(const Ref<const MatrixXd>& x, const double* data) {
198 8 return x.data() == data;
199 }
200
201 // Verify that temporary objects are not created by comparing data pointers.
202 5 bool sameData(const MatrixXd& x, const double* data) {
203 5 return x.data() == data;
204 }
205
206 // Extract a read-write block from any matrix expression
207 // without creating temporary objects.
208 template <typename Derived>
209 72000 Block<Derived> columnTemplate(MatrixBase<Derived>& x, int col) {
210 72000 return x.block(0, col, x.rows(), 1);
211 }
212
213 // Extract a read-only block from any matrix expression
214 // without creating temporary objects.
215 template <typename Derived>
216 const Block<const Derived> columnTemplate(const MatrixBase<Derived>& x, int col) {
217 return x.block(0, col, x.rows(), 1);
218 }
219
220 // Extract a read-only block from any matrix type
221 // without creating temporary objects.
222 36001 const Block<const Ref<const MatrixXd>> columnRef(
223 const Ref<const MatrixXd>& x, int col) {
224 36001 return x.block(0, col, x.rows(), 1);
225 }
226
227 // Generic output parameters have no restrictions
228 // and can be mixed with reference parameters.
229 template <typename T>
230 1 void assignTemplate(MatrixBase<T>& self, const Ref<const MatrixXd>& other) {
231 1 self = other;
232 1 }
233
234 // Reference output parameters have some limitations
235 // * cannot be resized (DEBUG compiler error)
236 1 void assignRef(Ref<MatrixXd> self, const Ref<const MatrixXd>& other) {
237 1 self = other;
238 1 }
239
240 #if __cplusplus >= 202002L // since C++20
241
242 // No temporary objects are created.
243 18000 auto squaredDistanceAuto(const auto& a, const auto& b) {
244
2/4
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 18000 times.
✗ Branch 7 not taken.
18000 return (a - b).squaredNorm();
245 }
246
247 // Verify that temporary objects are not created by comparing data pointers.
248 6 bool sameDataAuto(const auto& x, const double* data) {
249 6 return x.data() == data;
250 }
251
252 #endif // C++20
253
254 #ifdef NDEBUG
255 static constexpr int aSize{40};
256 static constexpr int bSize{150};
257 static constexpr int repeat = 100'000;
258 #else
259 static constexpr int aSize{40};
260 static constexpr int bSize{150};
261 static constexpr int repeat = 3;
262 #endif
263
264 // Collection of fixed-size vectors.
265 std::vector<Vector3d> aFixedCollection;
266 std::vector<Vector3d> bFixedCollection;
267
268 // Collection of fixed-capacity vectors.
269 std::vector<VectorX4d> aCappedCollection;
270 std::vector<VectorX4d> bCappedCollection;
271
272 // Collection of dynamic-capacity vectors.
273 std::vector<VectorXd> aDynamicCollection;
274 std::vector<VectorXd> bDynamicCollection;
275
276 // Collection of pointers to dynamic-capacity vectors.
277 std::vector<std::unique_ptr<VectorXd>> aPointerCollection;
278 std::vector<std::unique_ptr<VectorXd>> bPointerCollection;
279
280 // Matrix packed with fixed-size vectors.
281 Matrix3Xd aFixed;
282 Matrix3Xd bFixed;
283
284 // Matrix packed with fixed-capacity vectors.
285 MatrixXX4Xd aCapped;
286 MatrixXX4Xd bCapped;
287
288 // Matrix packed with dynamic-capacity vectors.
289 MatrixXd aDynamic;
290 MatrixXd bDynamic;
291
292 MatrixXd actual;
293 MatrixXd expected;
294
295 boost::timer::cpu_timer timer;
296 };
297
298 8 TEST_F(TestEigen, sizeof) {
299 2 auto vectorDataSize = 3 * sizeof(double);
300 2 auto matrixDataSize = aSize * vectorDataSize;
301
302 // Pointer, size.
303 2 auto dynamicVectorSize = sizeof(double*) + sizeof(size_t);
304
305 // Pointer, rows, columns.
306 2 auto dynamicMatrixSize = sizeof(double*) + 2 * sizeof(size_t);
307
308
2/12
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
2 EXPECT_EQ(sizeof(Vector3d), vectorDataSize) << "expect no overhead";
309
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_EQ(sizeof(VectorXd), dynamicVectorSize);
310
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ(sizeof(Matrix3Xd), dynamicMatrixSize - sizeof(size_t))
311
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 << "expect no row count";
312
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_EQ(sizeof(MatrixXd), dynamicMatrixSize);
313
314
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ(sizeof(Ref<VectorXd>), dynamicVectorSize + sizeof(size_t))
315
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 << "expect added stride";
316
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ(
317 sizeof(const Ref<const VectorXd>),
318 sizeof(Ref<VectorXd>) + dynamicVectorSize)
319
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 << "expect added object";
320
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
2 EXPECT_EQ(sizeof(Block<VectorXd>), sizeof(Ref<VectorXd>) + 4 * sizeof(size_t));
321
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
2 EXPECT_EQ(sizeof(const Block<const VectorXd>), sizeof(Block<VectorXd>));
322
323
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_GE(sizeof(Ref<MatrixXd>), dynamicMatrixSize);
324
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
2 EXPECT_EQ(
325 sizeof(const Ref<const MatrixXd>),
326 sizeof(Ref<MatrixXd>) + dynamicMatrixSize)
327
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
2 << "expect added object";
328
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
2 EXPECT_EQ(sizeof(Block<MatrixXd>), sizeof(Ref<MatrixXd>) + 2 * sizeof(size_t));
329
2/10
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
2 EXPECT_EQ(sizeof(const Block<const MatrixXd>), sizeof(Block<MatrixXd>));
330
331
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_LT(sizeof(aFixedCollection), matrixDataSize);
332
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_LT(sizeof(aDynamicCollection), matrixDataSize);
333
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_LT(sizeof(aPointerCollection), matrixDataSize);
334
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_LT(sizeof(aFixed), matrixDataSize);
335
2/10
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_LT(sizeof(aDynamic), matrixDataSize);
336 2 }
337
338 // This test fails until C++17 on some x86 processors.
339 #if __cplusplus >= 201703L || not defined __x86_64__
340
341 // [Structures Having Eigen Members](https://eigen.tuxfamily.org/dox/group__TopicStructHavingEigenMembers.html)
342 8 TEST_F(TestEigen, alignment) {
343 2 Eigen::internal::set_is_malloc_allowed(true);
344 2 auto desiredAlignment = alignof(Matrix4d);
345
346 #pragma GCC diagnostic push
347 #pragma GCC diagnostic ignored "-Wpadded"
348
349 struct aligned_padded {
350 double d1{};
351 Matrix4d m{};
352 double d2{};
353
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 } a;
354
355 #pragma GCC diagnostic pop
356
357
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto pa = std::make_unique<aligned_padded>();
358 // NOLINTNEXTLINE(*-reinterpret-cast)
359 2 auto pam = reinterpret_cast<std::ptrdiff_t>(std::addressof(pa->m));
360
361
2/12
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
2 EXPECT_GT(sizeof(a), 18 * sizeof(double)) << "expect padding";
362
3/12
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(offsetof(aligned_padded, m) % desiredAlignment, 0);
363
3/12
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(pam % desiredAlignment, 0);
364
365 struct misaligned_unpadded {
366 double d1{};
367 Matrix<double, 4, 4, DontAlign> m{};
368 double d2{};
369
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 } b;
370
371
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto pb = std::make_unique<misaligned_unpadded>();
372 // NOLINTNEXTLINE(*-reinterpret-cast)
373 2 auto pbm = reinterpret_cast<std::ptrdiff_t>(std::addressof(pb->m));
374
375
2/12
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
2 EXPECT_EQ(sizeof(b), 18 * sizeof(double)) << "expect no padding";
376
3/12
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_NE(offsetof(misaligned_unpadded, m) % desiredAlignment, 0);
377
3/12
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_NE(pbm % desiredAlignment, 0);
378 4 }
379
380 #endif // C++17 or not x86
381
382 8 TEST_F(TestEigen, outputParameters) {
383
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 VectorX4d v1;
384
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 Vector3d v2;
385
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 v2.setRandom();
386
387
2/10
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
2 EXPECT_EQ(v1.size(), 0);
388
2/10
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
2 EXPECT_EQ(v2.size(), 3);
389
2/4
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
2 assignTemplate(v1, v2);
390
2/10
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ(v1.size(), v2.size()); // template parameters can be resized
391
2/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
2 EXPECT_EQ(v1, v2);
392
393
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 VectorX4d v3;
394
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 v3.resizeLike(v2);
395
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 v3.setZero();
396
2/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
2 EXPECT_NE(v3, v2);
397
3/6
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
2 assignRef(v3, v2); // reference parameters cannot be resized
398
2/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
2 EXPECT_EQ(v3, v2); // but their values can be modified
399 2 }
400
401 8 TEST_F(TestEigen, collectionFixed) {
402 2 squaredDistance(aFixedCollection, bFixedCollection);
403 2 }
404
405 8 TEST_F(TestEigen, collectionCapped) {
406 2 squaredDistance(aCappedCollection, bCappedCollection);
407 2 }
408
409 8 TEST_F(TestEigen, collectionDynamic) {
410 2 squaredDistance(aDynamicCollection, bDynamicCollection);
411 2 }
412
413 8 TEST_F(TestEigen, collectionMixed) {
414 2 squaredDistance(aFixedCollection, bDynamicCollection);
415 2 }
416
417 8 TEST_F(TestEigen, collectionPointer) {
418 2 auto& a = aPointerCollection;
419 2 auto& b = bPointerCollection;
420
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
421
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
422
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
423
3/6
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 18000 times.
✗ Branch 15 not taken.
✓ Branch 20 taken 18000 times.
✗ Branch 21 not taken.
36000 actual(row, col) = (*a[row] - *b[col]).squaredNorm();
424 }
425 }
426 }
427 2 }
428
429 8 TEST_F(TestEigen, packedFixed) { squaredDistance(aFixed, bFixed); }
430
431 8 TEST_F(TestEigen, packedCapped) { squaredDistance(aCapped, bCapped); }
432
433 8 TEST_F(TestEigen, packedDynamic) { squaredDistance(aDynamic, bDynamic); }
434
435 8 TEST_F(TestEigen, packedMixed) { squaredDistance(aFixed, bDynamic); }
436
437 8 TEST_F(TestEigen, colwiseFixed) { squaredDistanceColwise(aFixed, bFixed); }
438
439 8 TEST_F(TestEigen, colwiseCapped) { squaredDistanceColwise(aCapped, bCapped); }
440
441 8 TEST_F(TestEigen, colwiseDynamic) {
442 2 squaredDistanceColwise(aDynamic, bDynamic);
443 2 }
444
445 8 TEST_F(TestEigen, colwiseMixed) { squaredDistanceColwise(aFixed, bDynamic); }
446
447 8 TEST_F(TestEigen, replicateFixed) { squaredDistanceReplicate(aFixed, bFixed); }
448
449 8 TEST_F(TestEigen, replicateCapped) {
450 2 squaredDistanceReplicate(aCapped, bCapped);
451 2 }
452
453 8 TEST_F(TestEigen, replicateDynamic) {
454 2 squaredDistanceReplicate(aDynamic, bDynamic);
455 2 }
456
457 8 TEST_F(TestEigen, replicateMixed) {
458 2 squaredDistanceReplicate(aFixed, bDynamic);
459 2 }
460
461 8 TEST_F(TestEigen, parallelFixed) { squaredDistanceParallel(aFixed, bFixed); }
462
463 8 TEST_F(TestEigen, parallelCapped) { squaredDistanceParallel(aCapped, bCapped); }
464
465 8 TEST_F(TestEigen, parallelDynamic) {
466 2 squaredDistanceParallel(aDynamic, bDynamic);
467 2 }
468
469 8 TEST_F(TestEigen, parallelMixed) { squaredDistanceParallel(aFixed, bDynamic); }
470
471 8 TEST_F(TestEigen, templateMixed) {
472 2 auto& a = aFixed;
473 2 auto& b = bDynamic;
474
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
475
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
476
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
477
1/2
✓ Branch 4 taken 18000 times.
✗ Branch 5 not taken.
72000 actual(row, col) =
478
3/6
✓ Branch 7 taken 18000 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 18000 times.
✗ Branch 15 not taken.
108000 squaredDistanceTemplate(a.col(row), b.col(col));
479 }
480 }
481 }
482 2 }
483
484 8 TEST_F(TestEigen, refMixed) {
485 2 auto& a = aFixed;
486 2 auto& b = bDynamic;
487
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
488
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
489
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
490
6/12
✓ Branch 8 taken 18000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 18 taken 18000 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
✓ Branch 31 taken 18000 times.
✗ Branch 32 not taken.
36000 actual(row, col) = squaredDistanceRef(a.col(row), b.col(col));
491 }
492 }
493 }
494 2 }
495
496 8 TEST_F(TestEigen, fixedRefMixed) {
497 2 auto& a = aFixed;
498 2 auto& b = bDynamic;
499
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
500
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
501
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
502
1/2
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
36000 actual(row, col) =
503
5/10
✓ Branch 8 taken 18000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 18 taken 18000 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
72000 squaredDistanceFixedRef(a.col(row), b.col(col));
504 }
505 }
506 }
507 2 }
508
509 8 TEST_F(TestEigen, fixedMixedSlow) {
510 // This test is expected to be slower because
511 // arguments to squaredDistanceFixed() will be
512 // converted to temporary fixed-size vectors
513
514 2 auto& a = aFixed;
515 2 auto& b = bDynamic;
516
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
517
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
518
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
519
6/12
✓ Branch 8 taken 18000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 18 taken 18000 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
✓ Branch 31 taken 18000 times.
✗ Branch 32 not taken.
36000 actual(row, col) = squaredDistanceFixed(a.col(row), b.col(col));
520 }
521 }
522 }
523 2 }
524
525 8 TEST_F(TestEigen, cappedMixedSlow) {
526 // This test is expected to be slower because
527 // arguments to squaredDistanceCapped() will be
528 // converted to temporary fixed-capacity vectors
529
530 2 auto& a = aFixed;
531 2 auto& b = bDynamic;
532
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
533
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
534
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
535
6/12
✓ Branch 8 taken 18000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 18 taken 18000 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
✓ Branch 31 taken 18000 times.
✗ Branch 32 not taken.
36000 actual(row, col) = squaredDistanceCapped(a.col(row), b.col(col));
536 }
537 }
538 }
539 2 }
540
541 8 TEST_F(TestEigen, dynamicMixedSlow) {
542 // This test is expected to take longer because
543 // arguments to squaredDistanceDynamic() will be
544 // converted to temporary dynamic-capacity vectors.
545 // This will also cause dynamic memory allocation.
546 2 Eigen::internal::set_is_malloc_allowed(true);
547
548 2 auto& a = aFixed;
549 2 auto& b = bDynamic;
550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 for (int i = 0; i < repeat / 10; i++) { // NOLINT(*-avoid-magic-numbers)
551 for (auto row = 0; row < actual.rows(); row++) {
552 for (auto col = 0; col < actual.cols(); col++) {
553 actual(row, col) = squaredDistanceDynamic(a.col(row), b.col(col));
554 }
555 }
556 }
557 2 }
558
559 8 TEST_F(TestEigen, blockTemplateMixed) {
560 2 auto& a = aFixed;
561 2 auto& b = bDynamic;
562
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
563
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
564
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
565
2/4
✓ Branch 5 taken 18000 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
72000 actual(row, col) = squaredDistanceRef(
566
4/8
✓ Branch 8 taken 18000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 18000 times.
✗ Branch 12 not taken.
✓ Branch 22 taken 18000 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
72000 columnTemplate(a, row), columnTemplate(b, col));
567 }
568 }
569 }
570 2 }
571
572 8 TEST_F(TestEigen, blockRefMixed) {
573 2 auto& a = aFixed;
574 2 auto& b = bDynamic;
575
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
576
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
577
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
578
1/2
✓ Branch 3 taken 18000 times.
✗ Branch 4 not taken.
36000 actual(row, col) =
579
7/14
✓ Branch 13 taken 18000 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 18000 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 18000 times.
✗ Branch 21 not taken.
✓ Branch 32 taken 18000 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 18000 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 18000 times.
✗ Branch 40 not taken.
✓ Branch 43 taken 18000 times.
✗ Branch 44 not taken.
72000 squaredDistanceRef(columnRef(a, row), columnRef(b, col));
580 }
581 }
582 }
583 2 }
584
585 8 TEST_F(TestEigen, absDynamic) {
586 2 auto& a = aDynamic;
587 2 auto& b = bDynamic;
588
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
589
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
590
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
591
6/12
✓ Branch 5 taken 18000 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 18000 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 18000 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 18000 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 18000 times.
✗ Branch 20 not taken.
✓ Branch 25 taken 18000 times.
✗ Branch 26 not taken.
36000 actual(row, col) = (a.col(row) - b.col(col)).cwiseAbs().sum();
592 }
593 }
594 }
595 2 timer.stop();
596 2 actual.setZero(); // do not check results
597 2 }
598
599 8 TEST_F(TestEigen, 1Dynamic) {
600 2 auto& a = aDynamic;
601 2 auto& b = bDynamic;
602
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
603
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
604
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
605
5/10
✓ Branch 4 taken 18000 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 18000 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 18000 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 18000 times.
✗ Branch 16 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
36000 actual(row, col) = (a.col(row) - b.col(col)).lpNorm<1>();
606 }
607 }
608 }
609 2 timer.stop();
610 2 actual.setZero(); // do not check results
611 2 }
612
613 8 TEST_F(TestEigen, 2Dynamic) {
614 2 auto& a = aDynamic;
615 2 auto& b = bDynamic;
616
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
617
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
618
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
619
5/10
✓ Branch 4 taken 18000 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 18000 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 18000 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 18000 times.
✗ Branch 16 not taken.
✓ Branch 21 taken 18000 times.
✗ Branch 22 not taken.
36000 actual(row, col) = (a.col(row) - b.col(col)).norm();
620 }
621 }
622 }
623 2 timer.stop();
624
3/6
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
2 actual = actual.array().square(); // adjust result
625 2 }
626
627 8 TEST_F(TestEigen, sameDataFixed) {
628
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataTemplate(aFixed, aFixed.data()));
629
4/16
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
2 EXPECT_TRUE(sameDataRef(aFixed, aFixed.data()));
630 // The next test causes dynamic allocation for a temporary object.
631 2 Eigen::internal::set_is_malloc_allowed(true);
632
4/16
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
2 EXPECT_FALSE(sameData(aFixed, aFixed.data()));
633 2 }
634
635 8 TEST_F(TestEigen, sameDataCapped) {
636
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataTemplate(aCapped, aCapped.data()));
637
4/16
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
2 EXPECT_TRUE(sameDataRef(aCapped, aCapped.data()));
638 // The next test causes dynamic allocation for a temporary object.
639 2 Eigen::internal::set_is_malloc_allowed(true);
640
4/16
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
2 EXPECT_FALSE(sameData(aCapped, aCapped.data()));
641 2 }
642
643 8 TEST_F(TestEigen, sameDataDynamic) {
644
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataTemplate(aDynamic, aDynamic.data()));
645
4/16
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
2 EXPECT_TRUE(sameDataRef(aDynamic, aDynamic.data()));
646
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameData(aDynamic, aDynamic.data()));
647 2 }
648
649 8 TEST_F(TestEigen, sameDataBlock) {
650
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_TRUE(sameDataRef(aDynamic.leftCols(1), aDynamic.data()));
651
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_TRUE(sameDataRef(aDynamic.topRows(1), aDynamic.data()));
652
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_FALSE(sameDataRef(aDynamic.rightCols(1), aDynamic.data()));
653
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_FALSE(sameDataRef(aDynamic.bottomRows(1), aDynamic.data()));
654
6/20
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 44 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 63 not taken.
✗ Branch 64 not taken.
2 EXPECT_TRUE(sameDataRef(columnRef(aDynamic, 0), aDynamic.data()));
655
656 // The next tests cause dynamic allocation for temporary objects.
657 2 Eigen::internal::set_is_malloc_allowed(true);
658
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_FALSE(sameData(aDynamic.leftCols(1), aDynamic.data()));
659
5/18
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 33 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✗ Branch 53 not taken.
2 EXPECT_FALSE(sameData(aDynamic.topRows(1), aDynamic.data()));
660 2 }
661
662 #if __cplusplus >= 202002L // since C++20
663
664 8 TEST_F(TestEigen, sameDataAuto) {
665
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataAuto(aFixed, aFixed.data()));
666
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataAuto(aCapped, aCapped.data()));
667
3/14
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
2 EXPECT_TRUE(sameDataAuto(aDynamic, aDynamic.data()));
668 2 }
669
670 8 TEST_F(TestEigen, autoMixed) {
671 2 auto& a = aFixed;
672 2 auto& b = bDynamic;
673
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
8 for (int i = 0; i < repeat; i++) {
674
2/2
✓ Branch 4 taken 120 times.
✓ Branch 5 taken 3 times.
246 for (auto row = 0; row < actual.rows(); row++) {
675
2/2
✓ Branch 4 taken 18000 times.
✓ Branch 5 taken 120 times.
36240 for (auto col = 0; col < actual.cols(); col++) {
676
4/8
✓ Branch 7 taken 18000 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 18000 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 18000 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 18000 times.
✗ Branch 24 not taken.
36000 actual(row, col) = squaredDistanceAuto(a.col(row), b.col(col));
677 }
678 }
679 }
680 2 }
681
682 #endif // C++20
683