xref: /petsc/src/sys/objects/device/tests/ex9.c (revision ccfb0f9f40a0131988d7995ed9679700dae2a75a)
1 static const char help[] = "Tests PetscDeviceContextQueryIdle.\n\n";
2 
3 #include "petscdevicetestcommon.h"
4 
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 
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 
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