YAC 3.13.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_collection_selection.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <mpi.h>
6
7#include "tests.h"
8#include "test_common.h"
9
11
17static void utest_contiguous_with_indices_null(void);
18static void utest_contiguous_with_explicit_contiguous_indices(void);
19static void utest_single_with_explicit_zero_index(void);
20static void utest_single_with_explicit_non_zero_index(void);
21static void utest_noncontiguous(void);
22static void utest_copy(void);
23static void utest_zero_size(void);
24static void test_compare(void);
25static void utest_pack_unpack(void);
26
27int main(void) {
28
29 MPI_Init(NULL, NULL);
30
31 utest_contiguous_with_indices_null();
32 utest_contiguous_with_explicit_contiguous_indices();
33 utest_noncontiguous();
34 utest_single_with_explicit_zero_index();
35 utest_single_with_explicit_non_zero_index();
36 utest_copy();
37 utest_zero_size();
39 utest_pack_unpack();
40
41 MPI_Finalize();
42
43 return TEST_EXIT_CODE;
44}
45
46static void utest_contiguous_with_indices_null(void) {
47 size_t N = 5;
48 struct yac_collection_selection *sel =
50
51 if (sel == NULL) PUT_ERR("selection is NULL");
53 PUT_ERR("wrong collection_size");
55 PUT_ERR("should be contiguous");
57 PUT_ERR("indices should be NULL for contiguous");
59 PUT_ERR("wrong maximum index");
60
62}
63
64static void utest_contiguous_with_explicit_contiguous_indices(void) {
65 size_t idxs[] = {0, 1, 2, 3};
66 enum {N = sizeof(idxs) / sizeof(idxs[0])};
67 struct yac_collection_selection *sel =
69
70 if (sel == NULL) PUT_ERR("selection is NULL");
72 PUT_ERR("wrong collection_size");
74 PUT_ERR("should be contiguous");
76 PUT_ERR("indices should be NULL for contiguous");
78 PUT_ERR("wrong maximum index");
79
81}
82
83static void utest_noncontiguous(void) {
84 size_t idxs[] = {0, 2, 3, 5};
85 enum {N = sizeof(idxs) / sizeof(idxs[0])};
86 struct yac_collection_selection *sel =
88
89 if (sel == NULL) PUT_ERR("selection is NULL");
91 PUT_ERR("wrong collection_size");
93 PUT_ERR("should not be contiguous");
94
95 size_t ref_max_index = 0;
96 size_t const *got = yac_collection_selection_get_indices(sel);
97 if (got == NULL) {
98 PUT_ERR("indices should not be NULL for non-contiguous");
99 } else {
100 for (size_t i = 0; i < N; ++i) {
101 if (got[i] != idxs[i]) PUT_ERR("wrong index value");
102 if (ref_max_index < idxs[i]) ref_max_index = idxs[i];
103 }
104 }
105
106 if (yac_collection_selection_get_max_index(sel) != ref_max_index)
107 PUT_ERR("wrong maximum index");
108
110}
111
112static void utest_copy(void) {
113
114 { /* test various collection selection configurations*/
115 struct {
116 size_t N;
117 size_t * indices;
118 } test_configs[] =
119 {{.N = 3, .indices = (size_t[]){0, 2, 5}},
120 {.N = 4, .indices = (size_t[]){0, 1, 2, 3}},
121 {.N = 0, .indices = NULL},
122 {.N = 5, .indices = NULL}};
123 enum {NUM_TESTS = sizeof(test_configs) / sizeof(test_configs[0])};
124
125 for (size_t t = 0; t < NUM_TESTS; ++t) {
126
127 struct yac_collection_selection *orig =
128 yac_collection_selection_new(test_configs[t].N, test_configs[t].indices);
129 struct yac_collection_selection *copy =
131
132 if (yac_collection_selection_compare(orig, copy)) PUT_ERR("orig != copy");
133
136 }
137 }
138
139 { /* NULL is a valid empty collection selection*/
140
141 struct yac_collection_selection *orig = NULL;
142 struct yac_collection_selection *copy =
144
145 if (copy != NULL) PUT_ERR("copy is not NULL");
146 }
147}
148
149static void utest_zero_size(void) {
150
151 struct yac_collection_selection *sel =
153
154 if (sel != NULL) PUT_ERR("selection is NULL");
156 PUT_ERR("wrong collection_size");
158 PUT_ERR("zero-size should be contiguous");
160 PUT_ERR("indices should be NULL for zero-size contiguous");
161 if (yac_collection_selection_get_max_index(sel) != SIZE_MAX)
162 PUT_ERR("wrong maximum index");
163
165}
166
167static void utest_single_with_explicit_zero_index(void) {
168 size_t idxs[] = {0};
169 enum {N = sizeof(idxs) / sizeof(idxs[0])};
170 struct yac_collection_selection *sel =
172
173 if (sel == NULL) PUT_ERR("selection is NULL");
175 PUT_ERR("wrong collection_size");
177 PUT_ERR("index {0} should be treated as contiguous");
179 PUT_ERR("indices should be NULL for contiguous");
180 if (yac_collection_selection_get_max_index(sel) != idxs[0])
181 PUT_ERR("wrong maximum index");
182
184}
185
186static void utest_single_with_explicit_non_zero_index(void) {
187 size_t idxs[] = {7};
188 enum {N = sizeof(idxs) / sizeof(idxs[0])};
189 struct yac_collection_selection *sel =
191
192 if (sel == NULL) PUT_ERR("selection is NULL");
194 PUT_ERR("wrong collection_size");
196 PUT_ERR("index {7} should not be contiguous");
197
198 size_t const *indices = yac_collection_selection_get_indices(sel);
199 if (indices == NULL) {
200 PUT_ERR("indices should not be NULL for non-contiguous");
201 } else if (indices[0] != 7) {
202 PUT_ERR("wrong stored index value");
203 }
204 if (yac_collection_selection_get_max_index(sel) != idxs[0])
205 PUT_ERR("wrong maximum index");
206
208}
209
210static void test_compare(void) {
211
212 // --- Case 1: both NULL
213 if (yac_collection_selection_compare(NULL, NULL) != 0)
214 PUT_ERR("yac_collection_selection_compare(NULL, NULL) failed");
215
216 // --- Case 2: one NULL, one valid
217 {
218 struct yac_collection_selection * sel =
220 if (yac_collection_selection_compare(sel, NULL) == 0)
221 PUT_ERR("yac_collection_selection_compare(sel, NULL)");
222 if (+yac_collection_selection_compare(sel, NULL) !=
224 PUT_ERR("yac_collection_selection_compare(NULL, sel)");
226 }
227
228 // --- Case 3: two contiguous selections, same size
229 {
230 size_t indices[] = {0,1,2,3,4,5};
231 enum {N = sizeof(indices) / sizeof(indices[0])};
232 struct yac_collection_selection * sel_a =
234 struct yac_collection_selection * sel_b =
236 if (yac_collection_selection_compare(sel_a, sel_b) != 0)
237 PUT_ERR("identical contiguous selections should be equal");
238 if (yac_collection_selection_compare(sel_b, sel_a) != 0)
239 PUT_ERR("identical contiguous selections should be equal");
242 }
243
244 // --- Case 4: two contiguous selections, different sizes
245 {
246 struct yac_collection_selection *sel_a =
248 struct yac_collection_selection *sel_b =
250 if (yac_collection_selection_compare(sel_a, sel_b) == 0)
251 PUT_ERR("different contiguous sizes should not be equal");
252 if (+yac_collection_selection_compare(sel_b, sel_a) !=
254 PUT_ERR("different contiguous sizes should not be equal");
257 }
258
259 // --- Case 5: non-contiguous identical indices
260 {
261 size_t indices[] = {0, 2, 4, 6, 8};
262 enum {N = sizeof(indices) / sizeof(indices[0])};
263 struct yac_collection_selection *sel_a =
265 struct yac_collection_selection *sel_b =
267 if (yac_collection_selection_compare(sel_a, sel_b) != 0)
268 PUT_ERR("identical non-contiguous selections should be equal");
269 if (yac_collection_selection_compare(sel_b, sel_a) != 0)
270 PUT_ERR("identical non-contiguous selections should be equal");
273 }
274
275 // --- Case 6: non-contiguous different indices
276 {
277 size_t indices_a[] = {0, 1, 2, 3, 4};
278 enum {N_a = sizeof(indices_a) / sizeof(indices_a[0])};
279 struct yac_collection_selection *sel_a =
280 yac_collection_selection_new(N_a, indices_a);
281 size_t indices_b[] = {0, 1, 3, 2, 4};
282 enum {N_b = sizeof(indices_b) / sizeof(indices_b[0])};
283 struct yac_collection_selection *sel_b =
284 yac_collection_selection_new(N_b, indices_b);
285 if (yac_collection_selection_compare(sel_a, sel_b) == 0)
286 PUT_ERR("different non-contiguous selections should not be equal");
287 if (+yac_collection_selection_compare(sel_b, sel_a) !=
289 PUT_ERR("different non-contiguous selections should not be equal");
292 }
293
294 // --- Case 7: contiguous with implicit indices vs.
295 // contiguous with explicit indices
296 {
297 size_t indices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
298 enum {N = sizeof(indices) / sizeof(indices[0])};
299 struct yac_collection_selection *sel_a =
301 struct yac_collection_selection *sel_b =
303 if (yac_collection_selection_compare(sel_a, sel_b) != 0)
304 PUT_ERR("contiguous and equivalent explicit list should be equal");
305 if (yac_collection_selection_compare(sel_b, sel_a) != 0)
306 PUT_ERR("contiguous and equivalent explicit list should be equal");
309 }
310
311 // --- Case 8: contiguous vs. non-matching non-contiguous with same size
312 {
313 size_t indices[] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10};
314 enum {N = sizeof(indices) / sizeof(indices[0])};
315 struct yac_collection_selection *sel_a =
317 struct yac_collection_selection *sel_b =
319 if (yac_collection_selection_compare(sel_a, sel_b) == 0)
320 PUT_ERR("contiguous and non-matching explicit list should differ");
321 if (+yac_collection_selection_compare(sel_b, sel_a) !=
323 PUT_ERR("contiguous and non-matching explicit list should differ");
326 }
327}
328
329static void utest_pack_unpack(void) {
330
331 MPI_Comm comm = MPI_COMM_SELF;
332
333 { /* test contiguous and non-contiguous selections */
334 struct {
335 size_t N;
336 size_t * indices;
337 } test_configs[] = {
338 {.N = 3, .indices = (size_t[]){0, 2, 5}}, /* non-contiguous */
339 {.N = 4, .indices = (size_t[]){0, 1, 2, 3}},/* contiguous */
340 {.N = 0, .indices = NULL}, /* empty contiguous */
341 {.N = 5, .indices = NULL} /* contiguous 0..4 */
342 };
343 enum { NUM_TESTS = sizeof(test_configs) / sizeof(test_configs[0]) };
344
345 for (size_t t = 0; t < NUM_TESTS; ++t) {
346
347 struct yac_collection_selection * orig =
349 test_configs[t].N, test_configs[t].indices);
350
351 size_t pack_size = yac_collection_selection_get_pack_size(orig, comm);
352 YAC_ASSERT(pack_size > 0,
353 "utest_pack_unpack: pack_size must be positive");
354
355 void * buffer = xmalloc(pack_size);
356 int position = 0;
357
359 orig, buffer, (int)pack_size, &position, comm);
360
361 // unpack into a new object
362 int unpack_position = 0;
363 struct yac_collection_selection *copy =
365 buffer, (int)pack_size, &unpack_position, comm);
366
367 if (yac_collection_selection_compare(orig, copy))
368 PUT_ERR("ERROR in pack/unpack");
369
372 free(buffer);
373 }
374 }
375
376 { /* test NULL selection (should behave as empty contiguous) */
377 struct yac_collection_selection *orig = NULL;
378
379 size_t pack_size = yac_collection_selection_get_pack_size(orig, comm);
380 void * buffer = xmalloc(pack_size);
381 int position = 0;
382
384 orig, buffer, (int)pack_size, &position, comm);
385
386 int unpack_position = 0;
387 struct yac_collection_selection *copy =
389 buffer, (int)pack_size, &unpack_position, comm);
390
391 if (copy != NULL)
392 PUT_ERR("unpacked object from NULL should be NULL");
393
394 free(buffer);
395 }
396}
#define YAC_ASSERT(exp, msg)
int yac_collection_selection_is_contiguous(struct yac_collection_selection const *collection_selection)
Query whether a selection is contiguous.
size_t yac_collection_selection_get_collection_size(struct yac_collection_selection const *collection_selection)
Get the size of the collection selection.
struct yac_collection_selection * yac_collection_selection_unpack(void const *buffer, int buffer_size, int *position, MPI_Comm comm)
Unpack a collection selection from a contiguous MPI buffer.
size_t yac_collection_selection_get_pack_size(struct yac_collection_selection const *sel, MPI_Comm comm)
Compute the MPI pack size of a collection selection.
size_t const * yac_collection_selection_get_indices(struct yac_collection_selection const *collection_selection)
Get explicit selection indices if non-contiguous.
void yac_collection_selection_delete(struct yac_collection_selection *collection_selection)
Delete a collection selection object.
int yac_collection_selection_compare(struct yac_collection_selection const *a, struct yac_collection_selection const *b)
Compare two collection selections.
struct yac_collection_selection * yac_collection_selection_copy(const struct yac_collection_selection *collection_selection)
Selection of indices from a collection.
void yac_collection_selection_pack(struct yac_collection_selection const *sel, void *buffer, int buffer_size, int *position, MPI_Comm comm)
Pack a collection selection into a contiguous MPI buffer.
struct yac_collection_selection * yac_collection_selection_new(size_t collection_size, size_t const *selection_indices)
Create a new collection selection.
size_t yac_collection_selection_get_max_index(struct yac_collection_selection const *selection)
Get the maximum index of a collection selection.
#define xmalloc(size)
Definition ppm_xfuncs.h:66
static void test_compare(void)
#define NUM_TESTS
#define N
#define TEST_EXIT_CODE
Definition tests.h:14
#define PUT_ERR(string)
Definition tests.h:10
double * buffer