Actual source code: ex62.c
2: static char help[] = "Tests `PetscGarbageKeySortedIntersect()`\n\n";
4: #include <petscsys.h>
5: #include <petsc/private/garbagecollector.h>
7: /* This program tests `PetscGarbageKeySortedIntersect(), which is the
8: public (MPI) interface to
9: `PetscErrorCode GarbageKeySortedIntersect_Private()`.
10: Sets are sent packed in arrays, with the first entry as the number of
11: set elements and the sets the remaining elements. This is because the
12: MPI reduction operation must have the call signature:
13: void PetscGarbageKeySortedIntersect(void *inset, void *inoutset, PetscMPIInt *length, MPI_Datatype *dtype)
14: This is a thin wrapper for the private routine:
15: PetscErrorCode GarbageKeySortedIntersect_Private(PetscInt64 seta[], PetscInt *lena, PetscInt64 setb[], PetscInt lenb)
16: Where
17: seta = (PetscInt64 *)inoutset;
18: setb = (PetscInt64 *)inset;
19: And the arguments are passed as:
20: &seta[1], (PetscInt *)&seta[0], &setb[1], (PetscInt)setb[0]
21: */
23: /* Populate a set with upto the first 49 unique Fibonnaci numbers */
24: PetscErrorCode Fibonnaci(PetscInt64 **set, PetscInt n)
25: {
26: PetscInt ii;
27: PetscInt64 fib[] = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,
28: 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465,
29: 14930352, 24157817, 39088169, 63245986, 102334155, 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073, 4807526976, 7778742049, 12586269025};
32: PetscAssert((n < 50), PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE, "n must be less than 50\n");
33: PetscMalloc1(n + 1, set);
34: (*set)[0] = (PetscInt64)n;
35: for (ii = 0; ii < n; ii++) { (*set)[ii + 1] = fib[ii]; }
36: return 0;
37: }
39: /* Populate a set with Square numbers */
40: PetscErrorCode Square(PetscInt64 **set, PetscInt n)
41: {
42: PetscInt64 ii;
45: PetscMalloc1(n + 1, set);
46: (*set)[0] = (PetscInt64)n;
47: for (ii = 1; ii < n + 1; ii++) { (*set)[ii] = ii * ii; }
48: return 0;
49: }
51: /* Populate a set with Cube numbers */
52: PetscErrorCode Cube(PetscInt64 **set, PetscInt n)
53: {
54: PetscInt64 ii;
57: PetscMalloc1(n + 1, set);
58: (*set)[0] = (PetscInt64)n;
59: for (ii = 1; ii < n + 1; ii++) { (*set)[ii] = ii * ii * ii; }
60: return 0;
61: }
63: /* Populate a set with numbers to sixth power */
64: PetscErrorCode Sixth(PetscInt64 **set, PetscInt n)
65: {
66: PetscInt64 ii;
69: PetscMalloc1(n + 1, set);
70: (*set)[0] = (PetscInt64)n;
71: for (ii = 1; ii < n + 1; ii++) { (*set)[ii] = ii * ii * ii * ii * ii * ii; }
72: return 0;
73: }
75: /* Print out the contents of a set */
76: PetscErrorCode PrintSet(PetscInt64 *set)
77: {
78: char text[64];
79: PetscInt ii;
82: PetscPrintf(PETSC_COMM_WORLD, "[");
83: for (ii = 1; ii <= (PetscInt)set[0]; ii++) {
84: PetscFormatConvert(" %" PetscInt64_FMT ",", text);
85: PetscPrintf(PETSC_COMM_WORLD, text, set[ii]);
86: }
87: PetscPrintf(PETSC_COMM_WORLD, "]\n");
88: return 0;
89: }
91: /* Check set equality */
92: PetscErrorCode AssertSetsEqual(PetscInt64 *set, PetscInt64 *true_set)
93: {
94: PetscInt ii;
97: PetscAssert((set[0] == true_set[0]), PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "Sets of different sizes");
98: for (ii = 1; ii < set[0] + 1; ii++) { PetscAssert((set[ii] == true_set[ii]), PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "Sets are different"); }
99: return 0;
100: }
102: /* Tests functionality when two enpty sets are passed */
103: PetscErrorCode test_empty_empty()
104: {
105: PetscInt64 *set_a, *set_b;
106: PetscInt64 truth[] = {0};
107: PetscMPIInt length = 1;
111: PetscMalloc1(1, &set_a);
112: PetscMalloc1(1, &set_b);
114: set_a[0] = 0;
116: set_b[0] = 0;
118: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
119: PrintSet(set_a);
120: AssertSetsEqual(set_a, truth);
122: PetscFree(set_a);
123: PetscFree(set_b);
125: return 0;
126: }
128: /* Tests functionality when seta is empty */
129: PetscErrorCode test_a_empty()
130: {
131: PetscInt64 *set_a, *set_b;
132: PetscInt64 truth[] = {0};
133: PetscMPIInt length = 1;
137: PetscMalloc1(1, &set_a);
138: PetscMalloc1(2, &set_b);
140: set_a[0] = 0;
142: set_b[0] = 1;
143: set_b[1] = 1;
145: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
146: PrintSet(set_a);
147: AssertSetsEqual(set_a, truth);
149: PetscFree(set_a);
150: PetscFree(set_b);
152: return 0;
153: }
155: /* Tests functionality when setb is empty */
156: PetscErrorCode test_b_empty()
157: {
158: PetscInt64 *set_a, *set_b;
159: PetscInt64 truth[] = {0};
160: PetscMPIInt length = 1;
164: PetscMalloc1(2, &set_a);
165: PetscMalloc1(1, &set_b);
167: set_a[0] = 1;
168: set_a[1] = 1;
170: set_b[0] = 0;
172: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
173: PrintSet(set_a);
174: AssertSetsEqual(set_a, truth);
176: PetscFree(set_a);
177: PetscFree(set_b);
179: return 0;
180: }
182: /* Tests functionality when both sets are identical */
183: PetscErrorCode test_identical()
184: {
185: PetscInt64 *set_a, *set_b;
186: PetscInt64 truth[] = {3, 1, 4, 9};
187: PetscMPIInt length = 4;
191: PetscMalloc1(4, &set_a);
192: PetscMalloc1(4, &set_b);
194: set_a[0] = 3;
195: set_a[1] = 1;
196: set_a[2] = 4;
197: set_a[3] = 9;
199: set_b[0] = 3;
200: set_b[1] = 1;
201: set_b[2] = 4;
202: set_b[3] = 9;
204: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
205: PrintSet(set_a);
206: AssertSetsEqual(set_a, truth);
208: PetscFree(set_a);
209: PetscFree(set_b);
211: return 0;
212: }
214: /* Tests functionality when sets have no elements in common */
215: PetscErrorCode test_disjoint()
216: {
217: PetscInt64 *set_a, *set_b;
218: PetscInt64 truth[] = {0};
219: PetscMPIInt length = 1;
223: PetscMalloc1(4, &set_a);
224: PetscMalloc1(4, &set_b);
226: set_a[0] = 3;
227: set_a[1] = 1;
228: set_a[2] = 4;
229: set_a[3] = 9;
231: set_b[0] = 3;
232: set_b[1] = 2;
233: set_b[2] = 6;
234: set_b[3] = 8;
236: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
237: PrintSet(set_a);
238: AssertSetsEqual(set_a, truth);
240: PetscFree(set_a);
241: PetscFree(set_b);
243: return 0;
244: }
246: /* Tests functionality when sets only have one element in common */
247: PetscErrorCode test_single_common()
248: {
249: PetscInt64 *set_a, *set_b;
250: PetscInt64 truth[] = {1, 4};
251: PetscMPIInt length = 1;
255: PetscMalloc1(4, &set_a);
256: PetscMalloc1(5, &set_b);
258: set_a[0] = 3;
259: set_a[1] = 1;
260: set_a[2] = 4;
261: set_a[3] = 9;
263: set_b[0] = 3;
264: set_b[1] = 2;
265: set_b[2] = 4;
266: set_b[3] = 6;
267: set_b[4] = 8;
269: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
270: PrintSet(set_a);
271: AssertSetsEqual(set_a, truth);
273: PetscFree(set_a);
274: PetscFree(set_b);
276: return 0;
277: }
279: /* Specific test case flagged by PETSc issue #1247 */
280: PetscErrorCode test_issue_1247()
281: {
282: PetscInt64 *set_a, *set_b;
283: PetscInt64 truth[] = {0};
284: PetscMPIInt length = 1;
288: PetscMalloc1(3, &set_a);
289: PetscMalloc1(2, &set_b);
291: set_a[0] = 2;
292: set_a[1] = 2;
293: set_a[2] = 3;
295: set_b[0] = 1;
296: set_b[1] = 1;
298: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
299: PrintSet(set_a);
300: AssertSetsEqual(set_a, truth);
302: PetscFree(set_a);
303: PetscFree(set_b);
305: return 0;
306: }
308: /* Tests functionality when seta is empty and setb is large */
309: PetscErrorCode test_empty_big()
310: {
311: PetscInt64 *set_a, *set_b;
312: PetscInt64 truth[] = {0};
313: PetscMPIInt length = 1;
317: PetscMalloc1(1, &set_a);
318: Square(&set_b, 999);
320: set_a[0] = 0;
322: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
323: PrintSet(set_a);
324: AssertSetsEqual(set_a, truth);
326: PetscFree(set_a);
327: PetscFree(set_b);
329: return 0;
330: }
332: /* Tests functionality when seta is small and setb is large */
333: PetscErrorCode test_small_big()
334: {
335: PetscInt64 *set_a, *set_b;
336: PetscInt64 truth[] = {3, 1, 4, 9};
337: PetscMPIInt length = 1;
341: PetscMalloc1(5, &set_a);
342: Square(&set_b, 999);
344: set_a[0] = 4;
345: set_a[1] = 1;
346: set_a[2] = 4;
347: set_a[3] = 8;
348: set_a[4] = 9;
350: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
351: PrintSet(set_a);
352: AssertSetsEqual(set_a, truth);
354: PetscFree(set_a);
355: PetscFree(set_b);
357: return 0;
358: }
360: /* Tests functionality when seta is medium sized and setb is large */
361: PetscErrorCode test_moderate_big()
362: {
363: PetscInt64 *set_a, *set_b;
364: PetscInt64 truth[] = {2, 1, 144};
365: PetscMPIInt length = 1;
369: Fibonnaci(&set_a, 49);
370: Square(&set_b, 999);
372: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
373: PrintSet(set_a);
374: AssertSetsEqual(set_a, truth);
376: PetscFree(set_a);
377: PetscFree(set_b);
379: return 0;
380: }
382: /* Tests functionality when seta and setb are large */
383: PetscErrorCode test_big_big()
384: {
385: PetscInt64 *set_a, *set_b;
386: PetscInt64 *truth;
387: PetscMPIInt length = 1;
391: Cube(&set_a, 999);
392: Square(&set_b, 999);
394: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
395: PrintSet(set_a);
397: Sixth(&truth, 9);
398: AssertSetsEqual(set_a, truth);
400: PetscFree(set_a);
401: PetscFree(set_b);
402: PetscFree(truth);
404: return 0;
405: }
407: /* Tests functionality when setb is empty and setb is large */
408: PetscErrorCode test_big_empty()
409: {
410: PetscInt64 *set_a, *set_b;
411: PetscInt64 truth[] = {0};
412: PetscMPIInt length = 1;
416: Cube(&set_a, 999);
417: PetscMalloc1(1, &set_b);
419: set_b[0] = 0;
421: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
422: PrintSet(set_a);
423: AssertSetsEqual(set_a, truth);
425: PetscFree(set_a);
426: PetscFree(set_b);
428: return 0;
429: }
431: /* Tests functionality when setb is small and setb is large */
432: PetscErrorCode test_big_small()
433: {
434: PetscInt64 *set_a, *set_b;
435: PetscInt64 truth[] = {2, 1, 8};
436: PetscMPIInt length = 1;
440: Cube(&set_a, 999);
441: PetscMalloc1(5, &set_b);
443: set_b[0] = 4;
444: set_b[1] = 1;
445: set_b[2] = 4;
446: set_b[3] = 8;
447: set_b[4] = 9;
449: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
450: PrintSet(set_a);
451: AssertSetsEqual(set_a, truth);
453: PetscFree(set_a);
454: PetscFree(set_b);
456: return 0;
457: }
459: /* Tests functionality when setb is medium sized and setb is large */
460: PetscErrorCode test_big_moderate()
461: {
462: PetscInt64 *set_a, *set_b;
463: PetscInt64 truth[] = {2, 1, 8};
464: PetscMPIInt length = 1;
468: Cube(&set_a, 999);
469: Fibonnaci(&set_b, 49);
471: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
472: PrintSet(set_a);
473: AssertSetsEqual(set_a, truth);
475: PetscFree(set_a);
476: PetscFree(set_b);
478: return 0;
479: }
481: /* Tests functionality when seta and setb are large, in the opposite
482: order to test_big_big() */
483: PetscErrorCode test_big_big_reversed()
484: {
485: PetscInt64 *set_a, *set_b;
486: PetscInt64 *truth;
487: PetscMPIInt length = 1;
491: Cube(&set_a, 999);
492: Square(&set_b, 999);
494: PetscGarbageKeySortedIntersect((void *)set_b, (void *)set_a, &length, NULL);
495: PrintSet(set_a);
497: Sixth(&truth, 9);
498: AssertSetsEqual(set_a, truth);
500: PetscFree(set_a);
501: PetscFree(set_b);
502: PetscFree(truth);
504: return 0;
505: }
507: /* Main executes the individual tests in a predefined order */
508: int main(int argc, char **argv)
509: {
511: PetscInitialize(&argc, &argv, (char *)0, help);
513: /* Small tests */
514: /* Test different edge cases with small sets */
515: test_empty_empty();
516: test_a_empty();
517: test_b_empty();
518: test_identical();
519: test_disjoint();
520: test_single_common();
521: test_issue_1247();
523: /* Big tests */
524: /* Test different edge cases with big sets */
525: test_empty_big();
526: test_small_big();
527: test_moderate_big();
528: test_big_big();
529: test_big_empty();
530: test_big_small();
531: test_big_moderate();
532: test_big_big_reversed();
534: PetscPrintf(PETSC_COMM_WORLD, "ALL PASSED\n");
535: PetscFinalize();
536: return 0;
537: }
539: /*TEST
541: test:
542: output_file: output/ex62.out
544: TEST*/