1a4af0ceeSJacob Faibussowitsch static const char help[] = "Tests PetscDeviceContextFork/Join.\n\n"; 2a4af0ceeSJacob Faibussowitsch 3a4af0ceeSJacob Faibussowitsch #include "petscdevicetestcommon.h" 4a4af0ceeSJacob Faibussowitsch 5d71ae5a4SJacob Faibussowitsch static PetscErrorCode DoFork(PetscDeviceContext parent, PetscInt n, PetscDeviceContext **sub) 6d71ae5a4SJacob Faibussowitsch { 70e6b6b59SJacob Faibussowitsch PetscDeviceType dtype; 80e6b6b59SJacob Faibussowitsch PetscStreamType stype; 90e6b6b59SJacob Faibussowitsch 100e6b6b59SJacob Faibussowitsch PetscFunctionBegin; 110e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetDeviceType(parent, &dtype)); 120e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetStreamType(parent, &stype)); 130e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextFork(parent, n, sub)); 140e6b6b59SJacob Faibussowitsch if (n) PetscCheck(*sub, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContextFork() return NULL pointer for %" PetscInt_FMT " children", n); 150e6b6b59SJacob Faibussowitsch for (PetscInt i = 0; i < n; ++i) { 160e6b6b59SJacob Faibussowitsch PetscDeviceType sub_dtype; 170e6b6b59SJacob Faibussowitsch PetscStreamType sub_stype; 180e6b6b59SJacob Faibussowitsch 190e6b6b59SJacob Faibussowitsch PetscCall(AssertDeviceContextExists((*sub)[i])); 200e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetStreamType((*sub)[i], &sub_stype)); 210e6b6b59SJacob Faibussowitsch PetscCall(AssertPetscStreamTypesValidAndEqual(sub_stype, stype, "Child stream type %s != parent stream type %s")); 220e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextGetDeviceType((*sub)[i], &sub_dtype)); 230e6b6b59SJacob Faibussowitsch PetscCall(AssertPetscDeviceTypesValidAndEqual(sub_dtype, dtype, "Child device type %s != parent device type %s")); 240e6b6b59SJacob Faibussowitsch } 253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 260e6b6b59SJacob Faibussowitsch } 270e6b6b59SJacob Faibussowitsch 28d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestNestedPetscDeviceContextForkJoin(PetscDeviceContext parCtx, PetscDeviceContext *sub) 29d71ae5a4SJacob Faibussowitsch { 30a4af0ceeSJacob Faibussowitsch const PetscInt nsub = 4; 31a4af0ceeSJacob Faibussowitsch PetscDeviceContext *subsub; 32a4af0ceeSJacob Faibussowitsch 33a4af0ceeSJacob Faibussowitsch PetscFunctionBegin; 344f572ea9SToby Isaac PetscAssertPointer(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 */ 370e6b6b59SJacob 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)); 433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44a4af0ceeSJacob Faibussowitsch } 45a4af0ceeSJacob Faibussowitsch 46a4af0ceeSJacob Faibussowitsch /* test fork-join */ 47d71ae5a4SJacob Faibussowitsch static PetscErrorCode TestPetscDeviceContextForkJoin(PetscDeviceContext dctx) 48d71ae5a4SJacob Faibussowitsch { 49a4af0ceeSJacob Faibussowitsch PetscDeviceContext *sub; 50a4af0ceeSJacob Faibussowitsch const PetscInt n = 10; 51a4af0ceeSJacob Faibussowitsch 52a4af0ceeSJacob Faibussowitsch PetscFunctionBegin; 53a4af0ceeSJacob Faibussowitsch /* mostly for valgrind to catch errors */ 540e6b6b59SJacob Faibussowitsch PetscCall(DoFork(dctx, n, &sub)); 559566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextJoin(dctx, n, PETSC_DEVICE_CONTEXT_JOIN_DESTROY, &sub)); 56a4af0ceeSJacob Faibussowitsch /* do it twice */ 570e6b6b59SJacob 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 */ 610e6b6b59SJacob 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)); 683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 69a4af0ceeSJacob Faibussowitsch } 70a4af0ceeSJacob Faibussowitsch 71d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[]) 72d71ae5a4SJacob Faibussowitsch { 730e6b6b59SJacob Faibussowitsch MPI_Comm comm; 74a4af0ceeSJacob Faibussowitsch PetscDeviceContext dctx; 75a4af0ceeSJacob Faibussowitsch 76327415f7SBarry Smith PetscFunctionBeginUser; 779566063dSJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 780e6b6b59SJacob Faibussowitsch comm = PETSC_COMM_WORLD; 79a4af0ceeSJacob Faibussowitsch 809566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextCreate(&dctx)); 810e6b6b59SJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)dctx, "local_")); 820e6b6b59SJacob Faibussowitsch PetscCall(PetscDeviceContextSetFromOptions(comm, dctx)); 839566063dSJacob Faibussowitsch PetscCall(TestPetscDeviceContextForkJoin(dctx)); 849566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextDestroy(&dctx)); 85a4af0ceeSJacob Faibussowitsch 869566063dSJacob Faibussowitsch PetscCall(PetscDeviceContextGetCurrentContext(&dctx)); 879566063dSJacob Faibussowitsch PetscCall(TestPetscDeviceContextForkJoin(dctx)); 88a4af0ceeSJacob Faibussowitsch 89f9fea11eSJacob Faibussowitsch PetscCall(TestPetscDeviceContextForkJoin(NULL)); 90f9fea11eSJacob Faibussowitsch 910e6b6b59SJacob Faibussowitsch PetscCall(PetscPrintf(comm, "EXIT_SUCCESS\n")); 929566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 93b122ec5aSJacob Faibussowitsch return 0; 94a4af0ceeSJacob Faibussowitsch } 95a4af0ceeSJacob Faibussowitsch 96a4af0ceeSJacob Faibussowitsch /*TEST 97a4af0ceeSJacob Faibussowitsch 98a4af0ceeSJacob Faibussowitsch testset: 99667ab0feSJacob Faibussowitsch requires: cxx 100a4af0ceeSJacob Faibussowitsch output_file: ./output/ExitSuccess.out 101a4af0ceeSJacob Faibussowitsch nsize: {{1 3}} 1020e6b6b59SJacob Faibussowitsch args: -device_enable {{lazy eager}} 103*d9acb416SHong Zhang args: -local_device_context_stream_type {{default nonblocking default_with_barrier nonblocking_with_barrier}} 104a4af0ceeSJacob Faibussowitsch test: 1050e6b6b59SJacob Faibussowitsch requires: !device 1060e6b6b59SJacob Faibussowitsch suffix: host_no_device 1070e6b6b59SJacob Faibussowitsch test: 1080e6b6b59SJacob Faibussowitsch requires: device 1090e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type host 1100e6b6b59SJacob Faibussowitsch suffix: host_with_device 1110e6b6b59SJacob Faibussowitsch test: 112a4af0ceeSJacob Faibussowitsch requires: cuda 1130e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type cuda 114a4af0ceeSJacob Faibussowitsch suffix: cuda 115a4af0ceeSJacob Faibussowitsch test: 116a4af0ceeSJacob Faibussowitsch requires: hip 1170e6b6b59SJacob Faibussowitsch args: -root_device_context_device_type hip 118a4af0ceeSJacob Faibussowitsch suffix: hip 119a4af0ceeSJacob Faibussowitsch 120a4af0ceeSJacob Faibussowitsch TEST*/ 121