xref: /petsc/src/sys/objects/device/tests/ex4.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 static const char help[] = "Tests PetscDeviceContextFork/Join.\n\n";
2 
3 #include <petsc/private/deviceimpl.h>
4 #include "petscdevicetestcommon.h"
5 
6 static PetscErrorCode TestNestedPetscDeviceContextForkJoin(PetscDeviceContext parCtx, PetscDeviceContext *sub) {
7   const PetscInt      nsub = 4;
8   PetscDeviceContext *subsub;
9 
10   PetscFunctionBegin;
11   PetscValidDeviceContext(parCtx, 1);
12   PetscValidPointer(sub, 2);
13   PetscCall(AssertPetscDeviceContextsValidAndEqual(parCtx, sub[0], "Current global context does not match expected global context"));
14   /* create some children from an active child */
15   PetscCall(PetscDeviceContextFork(sub[1], nsub, &subsub));
16   /* join on a sibling to the parent */
17   PetscCall(PetscDeviceContextJoin(sub[2], nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_SYNC, &subsub));
18   /* join on the grandparent */
19   PetscCall(PetscDeviceContextJoin(parCtx, nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &subsub));
20   PetscCall(PetscDeviceContextJoin(sub[1], nsub, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &subsub));
21   PetscFunctionReturn(0);
22 }
23 
24 /* test fork-join */
25 static PetscErrorCode TestPetscDeviceContextForkJoin(PetscDeviceContext dctx) {
26   PetscDeviceContext *sub;
27   const PetscInt      n = 10;
28 
29   PetscFunctionBegin;
30   PetscValidDeviceContext(dctx, 1);
31   /* mostly for valgrind to catch errors */
32   PetscCall(PetscDeviceContextFork(dctx, n, &sub));
33   PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
34   /* do it twice */
35   PetscCall(PetscDeviceContextFork(dctx, n, &sub));
36   PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
37 
38   /* create some children */
39   PetscCall(PetscDeviceContextFork(dctx, n + 1, &sub));
40   /* test forking within nested function */
41   PetscCall(TestNestedPetscDeviceContextForkJoin(sub[0], sub));
42   /* join a subset */
43   PetscCall(PetscDeviceContextJoin(dctx, n - 1, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &sub));
44   /* back to the ether from whence they came */
45   PetscCall(PetscDeviceContextJoin(dctx, n + 1, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
46   PetscFunctionReturn(0);
47 }
48 
49 int main(int argc, char *argv[]) {
50   PetscDeviceContext dctx;
51 
52   PetscFunctionBeginUser;
53   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
54 
55   PetscCall(PetscDeviceContextCreate(&dctx));
56   PetscCall(PetscDeviceContextSetFromOptions(PETSC_COMM_WORLD, "local_", dctx));
57   PetscCall(PetscDeviceContextSetUp(dctx));
58   PetscCall(TestPetscDeviceContextForkJoin(dctx));
59   PetscCall(PetscDeviceContextDestroy(&dctx));
60 
61   PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
62   PetscCall(TestPetscDeviceContextForkJoin(dctx));
63 
64   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
65   PetscCall(PetscFinalize());
66   return 0;
67 }
68 
69 /*TEST
70 
71  build:
72    requires: defined(PETSC_HAVE_CXX)
73 
74  test:
75    TODO: broken in ci
76    requires: !device
77    suffix: no_device
78    filter: Error: grep -E -o -e ".*No support for this operation for this object type" -e ".*PETSc is not configured with device support.*" -e "^\[0\]PETSC ERROR:.*[0-9]{1} [A-z]+\(\)"
79 
80  testset:
81    output_file: ./output/ExitSuccess.out
82    nsize: {{1 3}}
83    args: -local_device_context_stream_type {{global_blocking default_blocking global_nonblocking}}
84    test:
85      requires: cuda
86      suffix: cuda
87    test:
88      requires: hip
89      suffix: hip
90 
91 TEST*/
92