xref: /petsc/src/sys/objects/device/tests/ex9.c (revision dfcd79e9a510627fbd55c16b1d80626af0fcec4f)
1*dfcd79e9SJacob Faibussowitsch static const char help[] = "Tests PetscDeviceContextQueryIdle.\n\n";
2*dfcd79e9SJacob Faibussowitsch 
3*dfcd79e9SJacob Faibussowitsch #include "petscdevicetestcommon.h"
4*dfcd79e9SJacob Faibussowitsch 
5*dfcd79e9SJacob Faibussowitsch static PetscErrorCode CheckIdle(PetscDeviceContext dctx, const char operation[])
6*dfcd79e9SJacob Faibussowitsch {
7*dfcd79e9SJacob Faibussowitsch   PetscBool idle = PETSC_FALSE;
8*dfcd79e9SJacob Faibussowitsch 
9*dfcd79e9SJacob Faibussowitsch   PetscFunctionBegin;
10*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextQueryIdle(dctx, &idle));
11*dfcd79e9SJacob Faibussowitsch   if (!idle) {
12*dfcd79e9SJacob Faibussowitsch     PetscCall(PetscDeviceContextView(dctx, NULL));
13*dfcd79e9SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscDeviceContext was not idle after %s!", operation);
14*dfcd79e9SJacob Faibussowitsch   }
15*dfcd79e9SJacob Faibussowitsch   PetscFunctionReturn(0);
16*dfcd79e9SJacob Faibussowitsch }
17*dfcd79e9SJacob Faibussowitsch 
18*dfcd79e9SJacob Faibussowitsch static PetscErrorCode TestQueryIdle(PetscDeviceContext dctx)
19*dfcd79e9SJacob Faibussowitsch {
20*dfcd79e9SJacob Faibussowitsch   PetscDeviceContext other = NULL;
21*dfcd79e9SJacob Faibussowitsch 
22*dfcd79e9SJacob Faibussowitsch   PetscFunctionBegin;
23*dfcd79e9SJacob Faibussowitsch   // Should of course be idle after synchronization
24*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextSynchronize(dctx));
25*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(dctx, "synchronization"));
26*dfcd79e9SJacob Faibussowitsch 
27*dfcd79e9SJacob Faibussowitsch   // Creating an unrelated device context should leave it idle
28*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextCreate(&other));
29*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(dctx, "creating unrelated dctx"));
30*dfcd79e9SJacob Faibussowitsch 
31*dfcd79e9SJacob Faibussowitsch   // Destroying an unrelated device context shouldn't change things either
32*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextDestroy(&other));
33*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(dctx, "destroying unrelated dctx"));
34*dfcd79e9SJacob Faibussowitsch 
35*dfcd79e9SJacob Faibussowitsch   // Duplicating shouldn't change it either
36*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextDuplicate(dctx, &other));
37*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(dctx, "duplication"));
38*dfcd79e9SJacob Faibussowitsch 
39*dfcd79e9SJacob Faibussowitsch   // Another ctx waiting on it (which may make the other ctx non-idle) should not make the
40*dfcd79e9SJacob Faibussowitsch   // current one non-idle...
41*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextWaitForContext(other, dctx));
42*dfcd79e9SJacob Faibussowitsch   // ...unless it is the null ctx, in which case it being "idle" is equivalent to asking
43*dfcd79e9SJacob Faibussowitsch   // whether the whole device (which includes other streams) is idle. Since the other ctx might
44*dfcd79e9SJacob Faibussowitsch   // be busy, we should explicitly synchronize on the null ctx
45*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextSynchronize(NULL /* equivalently dctx if dctx = NULL */));
46*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(dctx, "other context waited on it, and synchronizing the NULL context"));
47*dfcd79e9SJacob Faibussowitsch   // both contexts should be idle
48*dfcd79e9SJacob Faibussowitsch   PetscCall(CheckIdle(other, "waiting on other context, and synchronizing the NULL context"));
49*dfcd79e9SJacob Faibussowitsch 
50*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextDestroy(&other));
51*dfcd79e9SJacob Faibussowitsch   PetscFunctionReturn(0);
52*dfcd79e9SJacob Faibussowitsch }
53*dfcd79e9SJacob Faibussowitsch 
54*dfcd79e9SJacob Faibussowitsch int main(int argc, char *argv[])
55*dfcd79e9SJacob Faibussowitsch {
56*dfcd79e9SJacob Faibussowitsch   PetscDeviceContext dctx = NULL;
57*dfcd79e9SJacob Faibussowitsch 
58*dfcd79e9SJacob Faibussowitsch   PetscFunctionBeginUser;
59*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
60*dfcd79e9SJacob Faibussowitsch 
61*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextCreate(&dctx));
62*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextSetStreamType(dctx, PETSC_STREAM_GLOBAL_NONBLOCKING));
63*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextSetUp(dctx));
64*dfcd79e9SJacob Faibussowitsch   PetscCall(TestQueryIdle(dctx));
65*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscDeviceContextDestroy(&dctx));
66*dfcd79e9SJacob Faibussowitsch 
67*dfcd79e9SJacob Faibussowitsch   PetscCall(TestQueryIdle(NULL));
68*dfcd79e9SJacob Faibussowitsch 
69*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "EXIT_SUCCESS\n"));
70*dfcd79e9SJacob Faibussowitsch   PetscCall(PetscFinalize());
71*dfcd79e9SJacob Faibussowitsch   return 0;
72*dfcd79e9SJacob Faibussowitsch }
73*dfcd79e9SJacob Faibussowitsch 
74*dfcd79e9SJacob Faibussowitsch /*TEST
75*dfcd79e9SJacob Faibussowitsch 
76*dfcd79e9SJacob Faibussowitsch  testset:
77*dfcd79e9SJacob Faibussowitsch    output_file: ./output/ExitSuccess.out
78*dfcd79e9SJacob Faibussowitsch    args: -device_enable {{lazy eager}}
79*dfcd79e9SJacob Faibussowitsch    test:
80*dfcd79e9SJacob Faibussowitsch      requires: !device
81*dfcd79e9SJacob Faibussowitsch      suffix: host_no_device
82*dfcd79e9SJacob Faibussowitsch    test:
83*dfcd79e9SJacob Faibussowitsch      requires: device
84*dfcd79e9SJacob Faibussowitsch      args: -default_device_type host
85*dfcd79e9SJacob Faibussowitsch      suffix: host_with_device
86*dfcd79e9SJacob Faibussowitsch    test:
87*dfcd79e9SJacob Faibussowitsch      requires: cuda
88*dfcd79e9SJacob Faibussowitsch      args: -default_device_type cuda
89*dfcd79e9SJacob Faibussowitsch      suffix: cuda
90*dfcd79e9SJacob Faibussowitsch    test:
91*dfcd79e9SJacob Faibussowitsch      requires: hip
92*dfcd79e9SJacob Faibussowitsch      args: -default_device_type hip
93*dfcd79e9SJacob Faibussowitsch      suffix: hip
94*dfcd79e9SJacob Faibussowitsch    test:
95*dfcd79e9SJacob Faibussowitsch      requires: sycl
96*dfcd79e9SJacob Faibussowitsch      args: -default_device_type sycl
97*dfcd79e9SJacob Faibussowitsch      suffix: sycl
98*dfcd79e9SJacob Faibussowitsch 
99*dfcd79e9SJacob Faibussowitsch TEST*/
100