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