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