Actual source code: ex2.c

  1: static const char help[] = "Tests creation and destruction of PetscDeviceContext.\n\n";

  3: #include "petscdevicetestcommon.h"

  5: static PetscDeviceContext rootContext = NULL, userContext = NULL;

  7: static PetscErrorCode CheckRootContextOwnership(void)
  8: {
  9:   PetscDeviceContext extra = userContext;
 10:   PetscInt           refs;

 12:   PetscFunctionBeginUser;
 13:   PetscCall(PetscObjectGetReference((PetscObject)userContext, &refs));
 14:   PetscCheck(refs == 2, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Root cleanup changed the application context reference count to %" PetscInt_FMT, refs);
 15:   PetscCall(PetscObjectGetReference((PetscObject)rootContext, &refs));
 16:   PetscCheck(refs == 1, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Root cleanup left %" PetscInt_FMT " references to the root context", refs);
 17:   PetscCall(PetscDeviceContextDestroy(&extra));
 18:   PetscCall(PetscDeviceContextDestroy(&userContext));
 19:   PetscCall(PetscDeviceContextDestroy(&rootContext));
 20:   PetscFunctionReturn(PETSC_SUCCESS);
 21: }

 23: int main(int argc, char *argv[])
 24: {
 25:   PetscDeviceContext dctx = NULL, ddup = NULL;
 26:   PetscBool          test_root_ownership = PETSC_FALSE;

 28:   PetscFunctionBeginUser;
 29:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 30:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_root_ownership", &test_root_ownership, NULL));
 31:   // With lazy initialization, registering before root creation makes this run after root cleanup.
 32:   if (test_root_ownership) PetscCall(PetscRegisterFinalize(CheckRootContextOwnership));

 34:   /* basic creation and destruction */
 35:   PetscCall(PetscDeviceContextCreate(&dctx));
 36:   PetscCall(AssertDeviceContextExists(dctx));
 37:   PetscCall(PetscDeviceContextDestroy(&dctx));
 38:   PetscCall(AssertDeviceContextDoesNotExist(dctx));
 39:   /* double free is no-op */
 40:   PetscCall(PetscDeviceContextDestroy(&dctx));
 41:   PetscCall(AssertDeviceContextDoesNotExist(dctx));

 43:   /* test global context returns a valid context */
 44:   dctx = NULL;
 45:   PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
 46:   PetscCall(AssertDeviceContextExists(dctx));
 47:   /* test locally setting to null doesn't clobber the global */
 48:   dctx = NULL;
 49:   PetscCall(PetscDeviceContextGetCurrentContext(&dctx));
 50:   PetscCall(AssertDeviceContextExists(dctx));

 52:   /* test duplicate */
 53:   PetscCall(PetscDeviceContextDuplicate(dctx, &ddup));
 54:   /* both device contexts should exist */
 55:   PetscCall(AssertDeviceContextExists(dctx));
 56:   PetscCall(AssertDeviceContextExists(ddup));

 58:   /* destroying the dup should leave the original untouched */
 59:   PetscCall(PetscDeviceContextDestroy(&ddup));
 60:   PetscCall(AssertDeviceContextDoesNotExist(ddup));
 61:   PetscCall(AssertDeviceContextExists(dctx));

 63:   if (test_root_ownership) {
 64:     rootContext = dctx;
 65:     PetscCall(PetscObjectReference((PetscObject)rootContext));
 66:     PetscCall(PetscDeviceContextDuplicate(rootContext, &userContext));
 67:     // Keep both contexts alive so an incorrect cleanup can be checked without accessing freed storage.
 68:     PetscCall(PetscObjectReference((PetscObject)userContext));
 69:     PetscCall(PetscDeviceContextSetCurrentContext(userContext));
 70:   }

 72:   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
 73:   PetscCall(PetscFinalize());
 74:   return 0;
 75: }

 77: /*TEST

 79:   test:
 80:     suffix: root_ownership
 81:     requires: defined(PETSC_DEVICELANGUAGE_CXX)
 82:     args: -test_root_ownership -device_enable lazy -default_device_type host
 83:     output_file: output/ExitSuccess.out

 85:   testset:
 86:     requires: defined(PETSC_DEVICELANGUAGE_CXX)
 87:     output_file: output/ExitSuccess.out
 88:     nsize: {{1 2 4}}
 89:     args: -device_enable {{lazy eager}}
 90:     test:
 91:       requires: !device
 92:       suffix: host_no_device
 93:     test:
 94:       requires: device
 95:       args: -root_device_context_device_type host
 96:       suffix: host_with_device
 97:     test:
 98:       requires: cuda
 99:       args: -root_device_context_device_type cuda
100:       suffix: cuda
101:     test:
102:       requires: hip
103:       args: -root_device_context_device_type hip
104:       suffix: hip
105:     test:
106:       requires: sycl
107:       args: -root_device_context_device_type sycl
108:       suffix: sycl

110:   testset:
111:     requires: !defined(PETSC_DEVICELANGUAGE_CXX)
112:     output_file: output/ExitSuccess.out
113:     suffix: no_cxx

115: TEST*/