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