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