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