Line data Source code
1 : /**
2 : * @file test_PartitionDescriptor.cpp
3 : *
4 : * @brief Tests for PartitionDescriptor class
5 : *
6 : * @author Nikola Dinev
7 : */
8 :
9 : #include "doctest/doctest.h"
10 : #include "PartitionDescriptor.h"
11 : #include "VolumeDescriptor.h"
12 : #include "TypeCasts.hpp"
13 :
14 : #include <stdexcept>
15 :
16 : using namespace elsa;
17 : using namespace doctest;
18 :
19 : TEST_SUITE_BEGIN("core");
20 :
21 : TEST_CASE("PartitionDescriptor: Testing construction")
22 26 : {
23 26 : GIVEN("a 1D descriptor")
24 26 : {
25 10 : VolumeDescriptor dd(IndexVector_t::Constant(1, 10));
26 :
27 10 : WHEN("partitioning it into 1 blocks")
28 10 : {
29 1 : REQUIRE_THROWS(PartitionDescriptor(dd, 1));
30 1 : REQUIRE_THROWS(PartitionDescriptor(dd, IndexVector_t::Constant(1, 10)));
31 1 : }
32 :
33 10 : WHEN("partitioning it into more blocks than the size of the last dimension")
34 10 : {
35 1 : REQUIRE_THROWS(PartitionDescriptor(dd, 11));
36 1 : REQUIRE_THROWS(PartitionDescriptor(dd, IndexVector_t::Ones(11)));
37 1 : REQUIRE_THROWS(PartitionDescriptor(dd, IndexVector_t::Zero(11)));
38 1 : }
39 :
40 10 : WHEN("partitioning it into 5 blocks with equal sizes")
41 10 : {
42 4 : index_t blocks = 5;
43 4 : PartitionDescriptor bd(dd, blocks);
44 :
45 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
46 4 : "dimension as the original")
47 4 : {
48 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
49 1 : bd.getNumberOfCoefficientsPerDimension());
50 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
51 1 : }
52 :
53 4 : THEN("there are 5 blocks of the correct size")
54 4 : {
55 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
56 :
57 1 : VolumeDescriptor bd0(IndexVector_t::Constant(1, 2), dd.getSpacingPerDimension());
58 6 : for (index_t i = 0; i < blocks; ++i)
59 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), bd0);
60 :
61 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
62 1 : }
63 :
64 4 : THEN("the block offsets are correct")
65 4 : {
66 6 : for (index_t i = 0; i < blocks; ++i)
67 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * dd.getNumberOfCoefficients() / blocks);
68 :
69 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
70 1 : }
71 :
72 4 : THEN("original and partitioned descriptor are not equal")
73 4 : {
74 1 : REQUIRE_NE(bd, dd);
75 1 : REQUIRE_NE(dd, bd);
76 1 : }
77 4 : }
78 :
79 10 : WHEN("partitioning it into 5 blocks with chosen sizes")
80 10 : {
81 4 : index_t blocks = 5;
82 4 : IndexVector_t split(blocks);
83 4 : split << 1, 2, 3, 1, 3;
84 4 : PartitionDescriptor bd(dd, split);
85 :
86 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
87 4 : "dimension as the original")
88 4 : {
89 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
90 1 : bd.getNumberOfCoefficientsPerDimension());
91 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
92 1 : }
93 :
94 4 : THEN("there are 5 blocks of the correct size")
95 4 : {
96 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
97 :
98 6 : for (index_t i = 0; i < blocks; ++i) {
99 5 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getNumberOfDimensions(), 1);
100 5 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getNumberOfCoefficients(), split[i]);
101 5 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getSpacingPerDimension(),
102 5 : bd.getSpacingPerDimension());
103 5 : }
104 :
105 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
106 1 : }
107 :
108 4 : THEN("the block offsets are correct")
109 4 : {
110 6 : for (index_t i = 0; i < blocks; ++i)
111 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), split.head(i).sum());
112 :
113 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
114 1 : }
115 :
116 4 : THEN("original and partitioned descriptor are not equal")
117 4 : {
118 1 : REQUIRE_NE(bd, dd);
119 1 : REQUIRE_NE(dd, bd);
120 1 : }
121 4 : }
122 10 : }
123 :
124 26 : GIVEN("a 2D descriptor with blocks")
125 26 : {
126 8 : IndexVector_t sizeVector(2);
127 8 : sizeVector << 11, 102;
128 8 : VolumeDescriptor dd(sizeVector);
129 :
130 8 : IndexVector_t coeffs(2);
131 8 : coeffs << 11, 10;
132 8 : VolumeDescriptor bd0(coeffs, dd.getSpacingPerDimension());
133 :
134 8 : coeffs[1] = 11;
135 8 : VolumeDescriptor bdn(coeffs, dd.getSpacingPerDimension());
136 :
137 8 : WHEN("partitioning it into 10 blocks")
138 8 : {
139 4 : index_t blocks = 10;
140 4 : PartitionDescriptor bd(dd, blocks);
141 :
142 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
143 4 : "dimension as the original")
144 4 : {
145 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
146 1 : bd.getNumberOfCoefficientsPerDimension());
147 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
148 1 : }
149 :
150 4 : THEN("there are 10 blocks of the correct size")
151 4 : {
152 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
153 :
154 9 : for (index_t i = 0; i < blocks - 2; ++i)
155 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), bd0);
156 :
157 3 : for (index_t i = blocks - 2; i < blocks; ++i)
158 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), bdn);
159 :
160 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
161 1 : }
162 :
163 4 : THEN("the block offsets are correct")
164 4 : {
165 1 : index_t size0 = bd0.getNumberOfCoefficients();
166 1 : index_t sizen = bdn.getNumberOfCoefficients();
167 9 : for (index_t i = 0; i < blocks - 2; ++i)
168 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * size0);
169 :
170 3 : for (index_t i = 0; i < 2; ++i)
171 1 : REQUIRE_EQ(bd.getOffsetOfBlock(blocks - 2 + i),
172 1 : (blocks - 2) * size0 + i * sizen);
173 :
174 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
175 1 : }
176 :
177 4 : THEN("original and partitioned descriptor are not equal")
178 4 : {
179 1 : REQUIRE_NE(bd, dd);
180 1 : REQUIRE_NE(dd, bd);
181 1 : }
182 4 : }
183 :
184 8 : WHEN("partitioning it into 10 blocks with chosen sizes")
185 8 : {
186 4 : index_t blocks = 10;
187 4 : IndexVector_t split(blocks);
188 4 : split << 1, 2, 3, 4, 5, 6, 7, 8, 9, 57;
189 4 : PartitionDescriptor bd(dd, split);
190 :
191 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
192 4 : "dimension as the original")
193 4 : {
194 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
195 1 : bd.getNumberOfCoefficientsPerDimension());
196 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
197 1 : }
198 :
199 4 : THEN("there are 10 blocks of the correct size")
200 4 : {
201 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
202 :
203 11 : for (index_t i = 0; i < blocks; i++) {
204 10 : auto coeffsPerDim = dd.getNumberOfCoefficientsPerDimension();
205 10 : coeffsPerDim[1] = split[i];
206 :
207 10 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getNumberOfCoefficientsPerDimension(),
208 10 : coeffsPerDim);
209 :
210 10 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getSpacingPerDimension(),
211 10 : bd.getSpacingPerDimension());
212 10 : }
213 :
214 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
215 1 : }
216 :
217 4 : THEN("the block offsets are correct")
218 4 : {
219 11 : for (index_t i = 0; i < blocks; i++)
220 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), sizeVector[0] * split.head(i).sum());
221 :
222 1 : REQUIRE_THROWS(bd.getOffsetOfBlock(blocks));
223 1 : }
224 :
225 4 : THEN("original and partitioned descriptor are not equal")
226 4 : {
227 1 : REQUIRE_NE(bd, dd);
228 1 : REQUIRE_NE(dd, bd);
229 1 : }
230 4 : }
231 8 : }
232 :
233 26 : GIVEN("a 3D descriptor with blocks")
234 26 : {
235 8 : IndexVector_t sizeVector(3);
236 8 : sizeVector << 101, 42, 750;
237 8 : VolumeDescriptor dd(sizeVector);
238 :
239 8 : sizeVector[2] = 30;
240 8 : VolumeDescriptor bd0(sizeVector);
241 8 : WHEN("creating 25 blocks")
242 8 : {
243 4 : index_t blocks = 25;
244 4 : PartitionDescriptor bd(dd, blocks);
245 :
246 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
247 4 : "dimension as the original")
248 4 : {
249 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
250 1 : bd.getNumberOfCoefficientsPerDimension());
251 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
252 1 : }
253 :
254 4 : THEN("there are 25 blocks of the correct size")
255 4 : {
256 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
257 :
258 26 : for (index_t i = 0; i < blocks; ++i)
259 1 : REQUIRE_EQ(bd.getDescriptorOfBlock(i), bd0);
260 :
261 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
262 1 : }
263 :
264 4 : THEN("the block offsets are correct")
265 4 : {
266 26 : for (index_t i = 0; i < blocks; ++i)
267 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i), i * bd0.getNumberOfCoefficients());
268 :
269 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
270 1 : }
271 :
272 4 : THEN("original and partitioned descriptor are not equal")
273 4 : {
274 1 : REQUIRE_NE(bd, dd);
275 1 : REQUIRE_NE(dd, bd);
276 1 : }
277 4 : }
278 :
279 8 : WHEN("creating 25 blocks with chosen sizes")
280 8 : {
281 4 : index_t blocks = 25;
282 4 : IndexVector_t split = IndexVector_t::Constant(blocks, 30);
283 4 : split.head(10).array() = 40;
284 4 : split.tail(10).array() = 20;
285 4 : PartitionDescriptor bd(dd, split);
286 :
287 4 : THEN("the partitioned descriptor has the same number of coefficients and spacing per "
288 4 : "dimension as the original")
289 4 : {
290 1 : REQUIRE_EQ(dd.getNumberOfCoefficientsPerDimension(),
291 1 : bd.getNumberOfCoefficientsPerDimension());
292 1 : REQUIRE_EQ(dd.getSpacingPerDimension(), bd.getSpacingPerDimension());
293 1 : }
294 :
295 4 : THEN("there are 25 blocks of the correct size")
296 4 : {
297 1 : REQUIRE_EQ(bd.getNumberOfBlocks(), blocks);
298 :
299 26 : for (index_t i = 0; i < blocks; ++i) {
300 25 : auto coeffsPerDim = sizeVector;
301 25 : coeffsPerDim[2] = split[i];
302 :
303 25 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getSpacingPerDimension(),
304 25 : dd.getSpacingPerDimension());
305 25 : REQUIRE_EQ(bd.getDescriptorOfBlock(i).getNumberOfCoefficientsPerDimension(),
306 25 : coeffsPerDim);
307 25 : }
308 :
309 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
310 1 : }
311 :
312 4 : THEN("the block offsets are correct")
313 4 : {
314 26 : for (index_t i = 0; i < blocks; ++i)
315 1 : REQUIRE_EQ(bd.getOffsetOfBlock(i),
316 1 : sizeVector.head(2).prod() * split.head(i).sum());
317 :
318 1 : REQUIRE_THROWS(bd.getDescriptorOfBlock(blocks));
319 1 : }
320 :
321 4 : THEN("original and partitioned descriptor are not equal")
322 4 : {
323 1 : REQUIRE_NE(bd, dd);
324 1 : REQUIRE_NE(dd, bd);
325 1 : }
326 4 : }
327 8 : }
328 26 : }
329 :
330 : TEST_CASE("PartitionDescriptor: Testing clone()")
331 3 : {
332 3 : GIVEN("a 1D PartitionDescriptor")
333 3 : {
334 1 : IndexVector_t sizeVector(1);
335 1 : sizeVector << 3891;
336 1 : VolumeDescriptor dd(sizeVector);
337 1 : index_t blocks = 21;
338 :
339 1 : WHEN("cloning the descriptor")
340 1 : {
341 1 : PartitionDescriptor bd(dd, blocks);
342 1 : auto bdClone = bd.clone();
343 :
344 1 : THEN("it's a real clone")
345 1 : {
346 1 : REQUIRE_NE(bdClone.get(), &bd);
347 1 : REQUIRE_UNARY(is<PartitionDescriptor>(bdClone.get()));
348 1 : REQUIRE_EQ(*bdClone, bd);
349 1 : }
350 1 : }
351 1 : }
352 :
353 3 : GIVEN("a 2D PartitionDescriptor")
354 3 : {
355 1 : IndexVector_t sizeVector(2);
356 1 : sizeVector << 43, 112;
357 1 : VolumeDescriptor dd(sizeVector);
358 1 : index_t blocks = 77;
359 :
360 1 : WHEN("cloning the descriptor")
361 1 : {
362 1 : PartitionDescriptor bd(dd, blocks);
363 1 : auto bdClone = bd.clone();
364 :
365 1 : THEN("it's a real clone")
366 1 : {
367 1 : REQUIRE_NE(bdClone.get(), &bd);
368 1 : REQUIRE_UNARY(is<PartitionDescriptor>(bdClone.get()));
369 1 : REQUIRE_EQ(*bdClone, bd);
370 1 : }
371 1 : }
372 1 : }
373 :
374 3 : GIVEN("a 3D PartitionDescriptor")
375 3 : {
376 1 : IndexVector_t sizeVector(3);
377 1 : sizeVector << 47, 11, 53;
378 1 : VolumeDescriptor dd(sizeVector);
379 1 : index_t blocks = 13;
380 :
381 1 : WHEN("cloning the descriptor")
382 1 : {
383 1 : PartitionDescriptor bd(dd, blocks);
384 1 : auto bdClone = bd.clone();
385 :
386 1 : THEN("it's a real clone")
387 1 : {
388 1 : REQUIRE_NE(bdClone.get(), &bd);
389 1 : REQUIRE_UNARY(is<PartitionDescriptor>(bdClone.get()));
390 1 : REQUIRE_EQ(*bdClone, bd);
391 1 : }
392 1 : }
393 1 : }
394 3 : }
395 :
396 : TEST_SUITE_END();
|