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*/