Actual source code: ex9.c
  1: static const char help[] = "Tests PetscDeviceContextQueryIdle.\n\n";
  3: #include "petscdevicetestcommon.h"
  5: static PetscErrorCode CheckIdle(PetscDeviceContext dctx, const char operation[])
  6: {
  7:   PetscBool idle = PETSC_FALSE;
  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: }
 18: static PetscErrorCode TestQueryIdle(PetscDeviceContext dctx)
 19: {
 20:   PetscDeviceContext other = NULL;
 22:   PetscFunctionBegin;
 23:   // Should of course be idle after synchronization
 24:   PetscCall(PetscDeviceContextSynchronize(dctx));
 25:   PetscCall(CheckIdle(dctx, "synchronization"));
 27:   // Creating an unrelated device context should leave it idle
 28:   PetscCall(PetscDeviceContextCreate(&other));
 29:   PetscCall(CheckIdle(dctx, "creating unrelated dctx"));
 31:   // Destroying an unrelated device context shouldn't change things either
 32:   PetscCall(PetscDeviceContextDestroy(&other));
 33:   PetscCall(CheckIdle(dctx, "destroying unrelated dctx"));
 35:   // Duplicating shouldn't change it either
 36:   PetscCall(PetscDeviceContextDuplicate(dctx, &other));
 37:   PetscCall(CheckIdle(dctx, "duplication"));
 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"));
 50:   PetscCall(PetscDeviceContextDestroy(&other));
 51:   PetscFunctionReturn(PETSC_SUCCESS);
 52: }
 54: int main(int argc, char *argv[])
 55: {
 56:   PetscDeviceContext dctx = NULL;
 58:   PetscFunctionBeginUser;
 59:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 61:   PetscCall(PetscDeviceContextCreate(&dctx));
 62:   PetscCall(PetscDeviceContextSetStreamType(dctx, PETSC_STREAM_NONBLOCKING));
 63:   PetscCall(PetscDeviceContextSetUp(dctx));
 64:   PetscCall(TestQueryIdle(dctx));
 65:   PetscCall(PetscDeviceContextDestroy(&dctx));
 67:   PetscCall(TestQueryIdle(NULL));
 69:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
 70:   PetscCall(PetscFinalize());
 71:   return 0;
 72: }
 74: /*TEST
 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
100:   test:
101:     requires: !cxx
102:     output_file: ./output/ExitSuccess.out
103:     suffix: no_cxx
105: TEST*/