1 static const char help[] = "Tests PetscDeviceContextQueryIdle.\n\n"; 2 3 #include "petscdevicetestcommon.h" 4 5 static PetscErrorCode CheckIdle(PetscDeviceContext dctx, const char operation[]) 6 { 7 PetscBool idle = PETSC_FALSE; 8 9 PetscFunctionBegin; 10 PetscCall(PetscDeviceContextQueryIdle(dctx, &idle)); 11 if (!idle) { 12 PetscCall(PetscDeviceContextView(dctx, NULL)); 13 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContext was not idle after %s!", operation); 14 } 15 PetscFunctionReturn(PETSC_SUCCESS); 16 } 17 18 static PetscErrorCode TestQueryIdle(PetscDeviceContext dctx) 19 { 20 PetscDeviceContext other = NULL; 21 22 PetscFunctionBegin; 23 // Should of course be idle after synchronization 24 PetscCall(PetscDeviceContextSynchronize(dctx)); 25 PetscCall(CheckIdle(dctx, "synchronization")); 26 27 // Creating an unrelated device context should leave it idle 28 PetscCall(PetscDeviceContextCreate(&other)); 29 PetscCall(CheckIdle(dctx, "creating unrelated dctx")); 30 31 // Destroying an unrelated device context shouldn't change things either 32 PetscCall(PetscDeviceContextDestroy(&other)); 33 PetscCall(CheckIdle(dctx, "destroying unrelated dctx")); 34 35 // Duplicating shouldn't change it either 36 PetscCall(PetscDeviceContextDuplicate(dctx, &other)); 37 PetscCall(CheckIdle(dctx, "duplication")); 38 39 // Another ctx waiting on it (which may make the other ctx non-idle) should not make the 40 // current one non-idle... 41 PetscCall(PetscDeviceContextWaitForContext(other, dctx)); 42 // ...unless it is the null ctx, in which case it being "idle" is equivalent to asking 43 // whether the whole device (which includes other streams) is idle. Since the other ctx might 44 // be busy, we should explicitly synchronize on the null ctx 45 PetscCall(PetscDeviceContextSynchronize(NULL /* equivalently dctx if dctx = NULL */)); 46 PetscCall(CheckIdle(dctx, "other context waited on it, and synchronizing the NULL context")); 47 // both contexts should be idle 48 PetscCall(CheckIdle(other, "waiting on other context, and synchronizing the NULL context")); 49 50 PetscCall(PetscDeviceContextDestroy(&other)); 51 PetscFunctionReturn(PETSC_SUCCESS); 52 } 53 54 int main(int argc, char *argv[]) 55 { 56 PetscDeviceContext dctx = NULL; 57 58 PetscFunctionBeginUser; 59 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 60 61 PetscCall(PetscDeviceContextCreate(&dctx)); 62 PetscCall(PetscDeviceContextSetStreamType(dctx, PETSC_STREAM_NONBLOCKING)); 63 PetscCall(PetscDeviceContextSetUp(dctx)); 64 PetscCall(TestQueryIdle(dctx)); 65 PetscCall(PetscDeviceContextDestroy(&dctx)); 66 67 PetscCall(TestQueryIdle(NULL)); 68 69 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n")); 70 PetscCall(PetscFinalize()); 71 return 0; 72 } 73 74 /*TEST 75 76 testset: 77 requires: cxx 78 output_file: output/ExitSuccess.out 79 args: -device_enable {{lazy eager}} 80 test: 81 requires: !device 82 suffix: host_no_device 83 test: 84 requires: device 85 args: -default_device_type host 86 suffix: host_with_device 87 test: 88 requires: cuda 89 args: -default_device_type cuda 90 suffix: cuda 91 test: 92 requires: hip 93 args: -default_device_type hip 94 suffix: hip 95 test: 96 requires: sycl 97 args: -default_device_type sycl 98 suffix: sycl 99 100 test: 101 requires: !cxx 102 output_file: output/ExitSuccess.out 103 suffix: no_cxx 104 105 TEST*/ 106