1a4af0ceeSJacob Faibussowitsch static const char help[] = "Tests PetscDeviceContextFork/Join.\n\n"; 2a4af0ceeSJacob Faibussowitsch 3a4af0ceeSJacob Faibussowitsch #include "petscdevicetestcommon.h" 4a4af0ceeSJacob Faibussowitsch 5*0e6b6b59SJacob Faibussowitsch static PetscErrorCode DoFork(PetscDeviceContext parent, PetscInt n, PetscDeviceContext **sub) { 6*0e6b6b59SJacob Faibussowitsch PetscDeviceType dtype; 7*0e6b6b59SJacob Faibussowitsch PetscStreamType stype; 8*0e6b6b59SJacob Faibussowitsch 9*0e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 10*0e6b6b59SJacob Faibussowitsch PetscCall(AssertDeviceContextExists(parent)); 11*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetDeviceType(parent, &dtype)); 12*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetStreamType(parent, &stype)); 13*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextFork(parent, n, sub)); 14*0e6b6b59SJacob Faibussowitsch if (n) PetscCheck(*sub, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContextFork() return NULL pointer for %" PetscInt_FMT " children", n); 15*0e6b6b59SJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 16*0e6b6b59SJacob Faibussowitsch PetscDeviceType sub_dtype; 17*0e6b6b59SJacob Faibussowitsch PetscStreamType sub_stype; 18*0e6b6b59SJacob Faibussowitsch 19*0e6b6b59SJacob Faibussowitsch PetscCall(AssertDeviceContextExists((*sub)[i])); 20*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetStreamType((*sub)[i], &sub_stype)); 21*0e6b6b59SJacob Faibussowitsch PetscCall(AssertPetscStreamTypesValidAndEqual(sub_stype, stype, "Child stream type %s != parent stream type %s")); 22*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetDeviceType((*sub)[i], &sub_dtype)); 23*0e6b6b59SJacob Faibussowitsch PetscCall(AssertPetscDeviceTypesValidAndEqual(sub_dtype, dtype, "Child device type %s != parent device type %s")); 24*0e6b6b59SJacob Faibussowitsch } 25*0e6b6b59SJacob Faibussowitsch PetscFunctionReturn(0); 26*0e6b6b59SJacob Faibussowitsch } 27*0e6b6b59SJacob Faibussowitsch 289371c9d4SSatish Balay static PetscErrorCode TestNestedPetscDeviceContextForkJoin(PetscDeviceContext parCtx, PetscDeviceContext *sub) { 29a4af0ceeSJacob Faibussowitsch const PetscInt nsub = 4; 30a4af0ceeSJacob Faibussowitsch PetscDeviceContext *subsub; 31a4af0ceeSJacob Faibussowitsch 32a4af0ceeSJacob Faibussowitsch PetscFunctionBegin; 33a4af0ceeSJacob Faibussowitsch PetscValidDeviceContext(parCtx, 1); 34a4af0ceeSJacob Faibussowitsch PetscValidPointer(sub, 2); 359566063dSJacob Faibussowitsch PetscCall(AssertPetscDeviceContextsValidAndEqual(parCtx, sub[0], "Current global context does not match expected global context")); 36a4af0ceeSJacob Faibussowitsch /* create some children from an active child */ 37*0e6b6b59SJacob Faibussowitsch PetscCall(DoFork(sub[1], nsub, &subsub)); 38a4af0ceeSJacob Faibussowitsch /* join on a sibling to the parent */ 399566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(sub[2], nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_SYNC, &subsub)); 40a4af0ceeSJacob Faibussowitsch /* join on the grandparent */ 419566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(parCtx, nsub - 2, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &subsub)); 429566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(sub[1], nsub, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &subsub)); 43a4af0ceeSJacob Faibussowitsch PetscFunctionReturn(0); 44a4af0ceeSJacob Faibussowitsch } 45a4af0ceeSJacob Faibussowitsch 46a4af0ceeSJacob Faibussowitsch /* test fork-join */ 479371c9d4SSatish Balay static PetscErrorCode TestPetscDeviceContextForkJoin(PetscDeviceContext dctx) { 48a4af0ceeSJacob Faibussowitsch PetscDeviceContext *sub; 49a4af0ceeSJacob Faibussowitsch const PetscInt n = 10; 50a4af0ceeSJacob Faibussowitsch 51a4af0ceeSJacob Faibussowitsch PetscFunctionBegin; 52a4af0ceeSJacob Faibussowitsch PetscValidDeviceContext(dctx, 1); 53a4af0ceeSJacob Faibussowitsch /* mostly for valgrind to catch errors */ 54*0e6b6b59SJacob Faibussowitsch PetscCall(DoFork(dctx, n, &sub)); 559566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub)); 56a4af0ceeSJacob Faibussowitsch /* do it twice */ 57*0e6b6b59SJacob Faibussowitsch PetscCall(DoFork(dctx, n, &sub)); 589566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub)); 59a4af0ceeSJacob Faibussowitsch 60a4af0ceeSJacob Faibussowitsch /* create some children */ 61*0e6b6b59SJacob Faibussowitsch PetscCall(DoFork(dctx, n + 1, &sub)); 62a4af0ceeSJacob Faibussowitsch /* test forking within nested function */ 639566063dSJacob Faibussowitsch PetscCall(TestNestedPetscDeviceContextForkJoin(sub[0], sub)); 64a4af0ceeSJacob Faibussowitsch /* join a subset */ 659566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(dctx, n - 1, PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC, &sub)); 66a4af0ceeSJacob Faibussowitsch /* back to the ether from whence they came */ 679566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(dctx, n + 1, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub)); 68a4af0ceeSJacob Faibussowitsch PetscFunctionReturn(0); 69a4af0ceeSJacob Faibussowitsch } 70a4af0ceeSJacob Faibussowitsch 719371c9d4SSatish Balay int main(int argc, char *argv[]) { 72*0e6b6b59SJacob Faibussowitsch MPI_Comm comm; 73a4af0ceeSJacob Faibussowitsch PetscDeviceContext dctx; 74a4af0ceeSJacob Faibussowitsch 75327415f7SBarry Smith PetscFunctionBeginUser; 769566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 77*0e6b6b59SJacob Faibussowitsch comm = PETSC_COMM_WORLD; 78a4af0ceeSJacob Faibussowitsch 799566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextCreate(&dctx)); 80*0e6b6b59SJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dctx, "local_")); 81*0e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextSetFromOptions(comm, dctx)); 829566063dSJacob Faibussowitsch PetscCall(TestPetscDeviceContextForkJoin(dctx)); 839566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextDestroy(&dctx)); 84a4af0ceeSJacob Faibussowitsch 859566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextGetCurrentContext(&dctx)); 869566063dSJacob Faibussowitsch PetscCall(TestPetscDeviceContextForkJoin(dctx)); 87a4af0ceeSJacob Faibussowitsch 88*0e6b6b59SJacob Faibussowitsch PetscCall(PetscPrintf(comm, "EXIT_SUCCESS\n")); 899566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 90b122ec5aSJacob Faibussowitsch return 0; 91a4af0ceeSJacob Faibussowitsch } 92a4af0ceeSJacob Faibussowitsch 93a4af0ceeSJacob Faibussowitsch /*TEST 94a4af0ceeSJacob Faibussowitsch 95a4af0ceeSJacob Faibussowitsch build: 96cb9b7bb0SJacob Faibussowitsch requires: defined(PETSC_HAVE_CXX) 97a4af0ceeSJacob Faibussowitsch 98a4af0ceeSJacob Faibussowitsch testset: 99a4af0ceeSJacob Faibussowitsch output_file: ./output/ExitSuccess.out 100a4af0ceeSJacob Faibussowitsch nsize: {{1 3}} 101*0e6b6b59SJacob Faibussowitsch args: -device_enable {{lazy eager}} 102a4af0ceeSJacob Faibussowitsch args: -local_device_context_stream_type {{global_blocking default_blocking global_nonblocking}} 103a4af0ceeSJacob Faibussowitsch test: 104*0e6b6b59SJacob Faibussowitsch requires: !device 105*0e6b6b59SJacob Faibussowitsch suffix: host_no_device 106*0e6b6b59SJacob Faibussowitsch test: 107*0e6b6b59SJacob Faibussowitsch requires: device 108*0e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type host 109*0e6b6b59SJacob Faibussowitsch suffix: host_with_device 110*0e6b6b59SJacob Faibussowitsch test: 111a4af0ceeSJacob Faibussowitsch requires: cuda 112*0e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type cuda 113a4af0ceeSJacob Faibussowitsch suffix: cuda 114a4af0ceeSJacob Faibussowitsch test: 115a4af0ceeSJacob Faibussowitsch requires: hip 116*0e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type hip 117a4af0ceeSJacob Faibussowitsch suffix: hip 118a4af0ceeSJacob Faibussowitsch 119a4af0ceeSJacob Faibussowitsch TEST*/ 120