xref: /petsc/src/sys/objects/device/tests/ex4.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
1a4af0ceeSJacob Faibussowitsch static const char help[] = "Tests PetscDeviceContextFork/Join.\n\n";
2a4af0ceeSJacob Faibussowitsch 
3a4af0ceeSJacob Faibussowitsch #include "petscdevicetestcommon.h"
4a4af0ceeSJacob Faibussowitsch 
5*d71ae5a4SJacob Faibussowitsch static PetscErrorCode DoFork(PetscDeviceContext parent, PetscInt n, PetscDeviceContext **sub)
6*d71ae5a4SJacob Faibussowitsch {
70e6b6b59SJacob Faibussowitsch   PetscDeviceType dtype;
80e6b6b59SJacob Faibussowitsch   PetscStreamType stype;
90e6b6b59SJacob Faibussowitsch 
100e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
110e6b6b59SJacob Faibussowitsch   PetscCall(AssertDeviceContextExists(parent));
120e6b6b59SJacob Faibussowitsch   PetscCall(PetscDeviceContextGetDeviceType(parent, &dtype));
130e6b6b59SJacob Faibussowitsch   PetscCall(PetscDeviceContextGetStreamType(parent, &stype));
140e6b6b59SJacob Faibussowitsch   PetscCall(PetscDeviceContextFork(parent, n, sub));
150e6b6b59SJacob Faibussowitsch   if (n) PetscCheck(*sub, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContextFork() return NULL pointer for %" PetscInt_FMT " children", n);
160e6b6b59SJacob Faibussowitsch   for (PetscInt i = 0; i < n; ++i) {
170e6b6b59SJacob Faibussowitsch     PetscDeviceType sub_dtype;
180e6b6b59SJacob Faibussowitsch     PetscStreamType sub_stype;
190e6b6b59SJacob Faibussowitsch 
200e6b6b59SJacob Faibussowitsch     PetscCall(AssertDeviceContextExists((*sub)[i]));
210e6b6b59SJacob Faibussowitsch     PetscCall(PetscDeviceContextGetStreamType((*sub)[i], &sub_stype));
220e6b6b59SJacob Faibussowitsch     PetscCall(AssertPetscStreamTypesValidAndEqual(sub_stype, stype, "Child stream type %s != parent stream type %s"));
230e6b6b59SJacob Faibussowitsch     PetscCall(PetscDeviceContextGetDeviceType((*sub)[i], &sub_dtype));
240e6b6b59SJacob Faibussowitsch     PetscCall(AssertPetscDeviceTypesValidAndEqual(sub_dtype, dtype, "Child device type %s != parent device type %s"));
250e6b6b59SJacob Faibussowitsch   }
260e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(0);
270e6b6b59SJacob Faibussowitsch }
280e6b6b59SJacob Faibussowitsch 
29*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestNestedPetscDeviceContextForkJoin(PetscDeviceContext parCtx, PetscDeviceContext *sub)
30*d71ae5a4SJacob Faibussowitsch {
31a4af0ceeSJacob Faibussowitsch   const PetscInt      nsub = 4;
32a4af0ceeSJacob Faibussowitsch   PetscDeviceContext *subsub;
33a4af0ceeSJacob Faibussowitsch 
34a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
35a4af0ceeSJacob Faibussowitsch   PetscValidDeviceContext(parCtx, 1);
36a4af0ceeSJacob Faibussowitsch   PetscValidPointer(sub, 2);
379566063dSJacob Faibussowitsch   PetscCall(AssertPetscDeviceContextsValidAndEqual(parCtx, sub[0], "Current global context does not match expected global context"));
38a4af0ceeSJacob Faibussowitsch   /* create some children from an active child */
390e6b6b59SJacob Faibussowitsch   PetscCall(DoFork(sub[1], nsub, &subsub));
40a4af0ceeSJacob Faibussowitsch   /* join on a sibling to the parent */
419566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(sub[2], nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_SYNC, &subsub));
42a4af0ceeSJacob Faibussowitsch   /* join on the grandparent */
439566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(parCtx, nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &subsub));
449566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(sub[1], nsub, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &subsub));
45a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
46a4af0ceeSJacob Faibussowitsch }
47a4af0ceeSJacob Faibussowitsch 
48a4af0ceeSJacob Faibussowitsch /* test fork-join */
49*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestPetscDeviceContextForkJoin(PetscDeviceContext dctx)
50*d71ae5a4SJacob Faibussowitsch {
51a4af0ceeSJacob Faibussowitsch   PetscDeviceContext *sub;
52a4af0ceeSJacob Faibussowitsch   const PetscInt      n = 10;
53a4af0ceeSJacob Faibussowitsch 
54a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
55a4af0ceeSJacob Faibussowitsch   PetscValidDeviceContext(dctx, 1);
56a4af0ceeSJacob Faibussowitsch   /* mostly for valgrind to catch errors */
570e6b6b59SJacob Faibussowitsch   PetscCall(DoFork(dctx, n, &sub));
589566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
59a4af0ceeSJacob Faibussowitsch   /* do it twice */
600e6b6b59SJacob Faibussowitsch   PetscCall(DoFork(dctx, n, &sub));
619566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
62a4af0ceeSJacob Faibussowitsch 
63a4af0ceeSJacob Faibussowitsch   /* create some children */
640e6b6b59SJacob Faibussowitsch   PetscCall(DoFork(dctx, n + 1, &sub));
65a4af0ceeSJacob Faibussowitsch   /* test forking within nested function */
669566063dSJacob Faibussowitsch   PetscCall(TestNestedPetscDeviceContextForkJoin(sub[0], sub));
67a4af0ceeSJacob Faibussowitsch   /* join a subset */
689566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(dctx, n - 1, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &sub));
69a4af0ceeSJacob Faibussowitsch   /* back to the ether from whence they came */
709566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextJoin(dctx, n + 1, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub));
71a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
72a4af0ceeSJacob Faibussowitsch }
73a4af0ceeSJacob Faibussowitsch 
74*d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
75*d71ae5a4SJacob Faibussowitsch {
760e6b6b59SJacob Faibussowitsch   MPI_Comm           comm;
77a4af0ceeSJacob Faibussowitsch   PetscDeviceContext dctx;
78a4af0ceeSJacob Faibussowitsch 
79327415f7SBarry Smith   PetscFunctionBeginUser;
809566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
810e6b6b59SJacob Faibussowitsch   comm = PETSC_COMM_WORLD;
82a4af0ceeSJacob Faibussowitsch 
839566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextCreate(&dctx));
840e6b6b59SJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dctx, "local_"));
850e6b6b59SJacob Faibussowitsch   PetscCall(PetscDeviceContextSetFromOptions(comm, dctx));
869566063dSJacob Faibussowitsch   PetscCall(TestPetscDeviceContextForkJoin(dctx));
879566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextDestroy(&dctx));
88a4af0ceeSJacob Faibussowitsch 
899566063dSJacob Faibussowitsch   PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
909566063dSJacob Faibussowitsch   PetscCall(TestPetscDeviceContextForkJoin(dctx));
91a4af0ceeSJacob Faibussowitsch 
920e6b6b59SJacob Faibussowitsch   PetscCall(PetscPrintf(comm, "EXIT_SUCCESS\n"));
939566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
94b122ec5aSJacob Faibussowitsch   return 0;
95a4af0ceeSJacob Faibussowitsch }
96a4af0ceeSJacob Faibussowitsch 
97a4af0ceeSJacob Faibussowitsch /*TEST
98a4af0ceeSJacob Faibussowitsch 
99a4af0ceeSJacob Faibussowitsch  build:
100cb9b7bb0SJacob Faibussowitsch    requires: defined(PETSC_HAVE_CXX)
101a4af0ceeSJacob Faibussowitsch 
102a4af0ceeSJacob Faibussowitsch  testset:
103a4af0ceeSJacob Faibussowitsch    output_file: ./output/ExitSuccess.out
104a4af0ceeSJacob Faibussowitsch    nsize: {{1 3}}
1050e6b6b59SJacob Faibussowitsch    args: -device_enable {{lazy eager}}
106a4af0ceeSJacob Faibussowitsch    args: -local_device_context_stream_type {{global_blocking default_blocking global_nonblocking}}
107a4af0ceeSJacob Faibussowitsch    test:
1080e6b6b59SJacob Faibussowitsch      requires: !device
1090e6b6b59SJacob Faibussowitsch      suffix: host_no_device
1100e6b6b59SJacob Faibussowitsch    test:
1110e6b6b59SJacob Faibussowitsch      requires: device
1120e6b6b59SJacob Faibussowitsch      args: -root_device_context_device_type host
1130e6b6b59SJacob Faibussowitsch      suffix: host_with_device
1140e6b6b59SJacob Faibussowitsch    test:
115a4af0ceeSJacob Faibussowitsch      requires: cuda
1160e6b6b59SJacob Faibussowitsch      args: -root_device_context_device_type cuda
117a4af0ceeSJacob Faibussowitsch      suffix: cuda
118a4af0ceeSJacob Faibussowitsch    test:
119a4af0ceeSJacob Faibussowitsch      requires: hip
1200e6b6b59SJacob Faibussowitsch      args: -root_device_context_device_type hip
121a4af0ceeSJacob Faibussowitsch      suffix: hip
122a4af0ceeSJacob Faibussowitsch 
123a4af0ceeSJacob Faibussowitsch TEST*/
124