xref: /petsc/src/sys/objects/device/tests/petscdevicetestcommon.h (revision a4af0ceea8a251db97ee0dc5c0d52d4adf50264a)
1*a4af0ceeSJacob Faibussowitsch #ifndef PETSCDEVICE_H
2*a4af0ceeSJacob Faibussowitsch #error "included this file before petscdevice.h, this file must be included last to ensure that public petsc headers are well formed"
3*a4af0ceeSJacob Faibussowitsch #endif
4*a4af0ceeSJacob Faibussowitsch #ifndef PETSCDEVICETESTCOMMON_H
5*a4af0ceeSJacob Faibussowitsch #define PETSCDEVICETESTCOMMON_H
6*a4af0ceeSJacob Faibussowitsch 
7*a4af0ceeSJacob Faibussowitsch /* all of the error checking macros are undefined and redefined verbatim so that they are also
8*a4af0ceeSJacob Faibussowitsch  * defined for optimized builds.
9*a4af0ceeSJacob Faibussowitsch  */
10*a4af0ceeSJacob Faibussowitsch #undef PetscValidDeviceType
11*a4af0ceeSJacob Faibussowitsch #undef PetscValidDevice
12*a4af0ceeSJacob Faibussowitsch #undef PetscCheckCompatibleDevices
13*a4af0ceeSJacob Faibussowitsch #undef PetscValidStreamType
14*a4af0ceeSJacob Faibussowitsch #undef PetscValidDeviceContext
15*a4af0ceeSJacob Faibussowitsch #undef PetscCheckCompatibleDeviceContexts
16*a4af0ceeSJacob Faibussowitsch 
17*a4af0ceeSJacob Faibussowitsch #define PetscValidDeviceType(_p_dev_type__,_p_arg__) do {               \
18*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(((_p_dev_type__) < PETSC_DEVICE_INVALID) ||       \
19*a4af0ceeSJacob Faibussowitsch                       ((_p_dev_type__) > PETSC_DEVICE_MAX))) {          \
20*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,              \
21*a4af0ceeSJacob Faibussowitsch                "Unknown PetscDeviceType '%d': Argument #%d",            \
22*a4af0ceeSJacob Faibussowitsch                (_p_dev_type__),(_p_arg__));                             \
23*a4af0ceeSJacob Faibussowitsch     } else if (PetscUnlikely(!PetscDeviceConfiguredFor_Internal(_p_dev_type__))) { \
24*a4af0ceeSJacob Faibussowitsch       switch(_p_dev_type__) {                                           \
25*a4af0ceeSJacob Faibussowitsch       case PETSC_DEVICE_INVALID:                                        \
26*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,                         \
27*a4af0ceeSJacob Faibussowitsch                  "Invalid PetscDeviceType '%s': Argument #%d;"          \
28*a4af0ceeSJacob Faibussowitsch                  " PETSc is not configured with device support",        \
29*a4af0ceeSJacob Faibussowitsch                  PetscDeviceTypes[_p_dev_type__],(_p_arg__));           \
30*a4af0ceeSJacob Faibussowitsch         break;                                                          \
31*a4af0ceeSJacob Faibussowitsch       case PETSC_DEVICE_MAX:                                            \
32*a4af0ceeSJacob Faibussowitsch         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,                  \
33*a4af0ceeSJacob Faibussowitsch                  "Invalid PetscDeviceType '%s': Argument #%d",          \
34*a4af0ceeSJacob Faibussowitsch                  PetscDeviceTypes[_p_dev_type__],(_p_arg__));           \
35*a4af0ceeSJacob Faibussowitsch         break;                                                          \
36*a4af0ceeSJacob Faibussowitsch       default:                                                          \
37*a4af0ceeSJacob Faibussowitsch         SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,                         \
38*a4af0ceeSJacob Faibussowitsch                  "Not configured for PetscDeviceType '%s': Argument #%d;" \
39*a4af0ceeSJacob Faibussowitsch                  " run configure --help %s for available options",      \
40*a4af0ceeSJacob Faibussowitsch                  PetscDeviceTypes[_p_dev_type__],(_p_arg__),            \
41*a4af0ceeSJacob Faibussowitsch                  PetscDeviceTypes[_p_dev_type__]);                      \
42*a4af0ceeSJacob Faibussowitsch         break;                                                          \
43*a4af0ceeSJacob Faibussowitsch       }                                                                 \
44*a4af0ceeSJacob Faibussowitsch     }                                                                   \
45*a4af0ceeSJacob Faibussowitsch   } while (0)
46*a4af0ceeSJacob Faibussowitsch 
47*a4af0ceeSJacob Faibussowitsch #define PetscValidDevice(_p_dev__,_p_arg__)          do {       \
48*a4af0ceeSJacob Faibussowitsch     PetscValidPointer(_p_dev__,_p_arg__);                       \
49*a4af0ceeSJacob Faibussowitsch     PetscValidDeviceType((_p_dev__)->type,_p_arg__);            \
50*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely((_p_dev__)->id < 0)) {                    \
51*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,                  \
52*a4af0ceeSJacob Faibussowitsch                "Invalid PetscDevice: Argument #%d; id %D < 0",  \
53*a4af0ceeSJacob Faibussowitsch                (_p_arg__),(_p_dev__)->id);                      \
54*a4af0ceeSJacob Faibussowitsch     } else if (PetscUnlikely((_p_dev__)->refcnt < 0)) {         \
55*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,                  \
56*a4af0ceeSJacob Faibussowitsch                "Invalid PetscDevice: Argument #%d; "            \
57*a4af0ceeSJacob Faibussowitsch                "negative reference count %D",                   \
58*a4af0ceeSJacob Faibussowitsch                (_p_arg__),(_p_dev__)->refcnt);                  \
59*a4af0ceeSJacob Faibussowitsch     }                                                           \
60*a4af0ceeSJacob Faibussowitsch   } while (0)
61*a4af0ceeSJacob Faibussowitsch 
62*a4af0ceeSJacob Faibussowitsch /* for now just checks strict equality, but this can be changed as some devices
63*a4af0ceeSJacob Faibussowitsch    (i.e. kokkos and any cupm should be compatible once implemented) */
64*a4af0ceeSJacob Faibussowitsch #define PetscCheckCompatibleDevices(_p_dev1__,_p_arg1__,_p_dev2__,_p_arg2__) \
65*a4af0ceeSJacob Faibussowitsch   do {                                                                  \
66*a4af0ceeSJacob Faibussowitsch     PetscValidDevice(_p_dev1__,_p_arg1__);                              \
67*a4af0ceeSJacob Faibussowitsch     PetscValidDevice(_p_dev2__,_p_arg2__);                              \
68*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely((_p_dev1__)->type != (_p_dev2__)->type)) {        \
69*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,                    \
70*a4af0ceeSJacob Faibussowitsch                "PetscDevices are incompatible: Arguments #%d and #%d",  \
71*a4af0ceeSJacob Faibussowitsch                (_p_arg1__),(_p_arg2__));                                \
72*a4af0ceeSJacob Faibussowitsch     }                                                                   \
73*a4af0ceeSJacob Faibussowitsch  } while (0)
74*a4af0ceeSJacob Faibussowitsch 
75*a4af0ceeSJacob Faibussowitsch #define PetscValidStreamType(_p_strm_type__,_p_arg__)  do {             \
76*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely(((_p_strm_type__) < 0) ||                         \
77*a4af0ceeSJacob Faibussowitsch                       ((_p_strm_type__) > PETSC_STREAM_MAX))) {         \
78*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,              \
79*a4af0ceeSJacob Faibussowitsch                "Unknown PetscStreamType '%d': Argument #%d",            \
80*a4af0ceeSJacob Faibussowitsch                (_p_strm_type__),(_p_arg__));                            \
81*a4af0ceeSJacob Faibussowitsch     } else if (PetscUnlikely((_p_strm_type__) == PETSC_STREAM_MAX)) {   \
82*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,                    \
83*a4af0ceeSJacob Faibussowitsch                "Invalid PetscStreamType '%s': Argument #%d",            \
84*a4af0ceeSJacob Faibussowitsch                PetscStreamTypes[_p_strm_type__],(_p_arg__));            \
85*a4af0ceeSJacob Faibussowitsch     }                                                                   \
86*a4af0ceeSJacob Faibussowitsch   } while (0)
87*a4af0ceeSJacob Faibussowitsch 
88*a4af0ceeSJacob Faibussowitsch #define PetscValidDeviceContext(_p_dev_ctx__,_p_arg__) do {             \
89*a4af0ceeSJacob Faibussowitsch     PetscValidPointer(_p_dev_ctx__,_p_arg__);                           \
90*a4af0ceeSJacob Faibussowitsch     PetscValidStreamType((_p_dev_ctx__)->streamType,_p_arg__);          \
91*a4af0ceeSJacob Faibussowitsch     if ((_p_dev_ctx__)->device) {                                       \
92*a4af0ceeSJacob Faibussowitsch       PetscValidDevice((_p_dev_ctx__)->device,_p_arg__);                \
93*a4af0ceeSJacob Faibussowitsch     } else if (PetscUnlikely((_p_dev_ctx__)->setup)) {                  \
94*a4af0ceeSJacob Faibussowitsch       SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,                \
95*a4af0ceeSJacob Faibussowitsch                "Invalid PetscDeviceContext: Argument #%d; "             \
96*a4af0ceeSJacob Faibussowitsch                "PetscDeviceContext is setup but has no PetscDevice",    \
97*a4af0ceeSJacob Faibussowitsch                (_p_arg__));                                             \
98*a4af0ceeSJacob Faibussowitsch     }                                                                   \
99*a4af0ceeSJacob Faibussowitsch     if (PetscUnlikely((_p_dev_ctx__)->id < 1)) {                        \
100*a4af0ceeSJacob Faibussowitsch       SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,                          \
101*a4af0ceeSJacob Faibussowitsch                "Invalid PetscDeviceContext: Argument #%d; id %D < 1",   \
102*a4af0ceeSJacob Faibussowitsch                (_p_arg__),(_p_dev_ctx__)->id);                          \
103*a4af0ceeSJacob Faibussowitsch     } else if (PetscUnlikely((_p_dev_ctx__)->numChildren      >         \
104*a4af0ceeSJacob Faibussowitsch                              (_p_dev_ctx__)->maxNumChildren)) {         \
105*a4af0ceeSJacob Faibussowitsch       SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,                   \
106*a4af0ceeSJacob Faibussowitsch                "Invalid PetscDeviceContext: Argument #%d; "             \
107*a4af0ceeSJacob Faibussowitsch                "number of children %D > max number of children %D",     \
108*a4af0ceeSJacob Faibussowitsch                (_p_arg__),(_p_dev_ctx__)->numChildren,                  \
109*a4af0ceeSJacob Faibussowitsch                (_p_dev_ctx__)->maxNumChildren);                         \
110*a4af0ceeSJacob Faibussowitsch     }                                                                   \
111*a4af0ceeSJacob Faibussowitsch   } while (0)
112*a4af0ceeSJacob Faibussowitsch 
113*a4af0ceeSJacob Faibussowitsch #define PetscCheckCompatibleDeviceContexts(_p_dev_ctx1__,_p_arg1__,_p_dev_ctx2__,_p_arg2__) \
114*a4af0ceeSJacob Faibussowitsch   do {                                                                  \
115*a4af0ceeSJacob Faibussowitsch     PetscValidDeviceContext(_p_dev_ctx1__,_p_arg1__);                   \
116*a4af0ceeSJacob Faibussowitsch     PetscValidDeviceContext(_p_dev_ctx2__,_p_arg2__);                   \
117*a4af0ceeSJacob Faibussowitsch     PetscCheckCompatibleDevices((_p_dev_ctx1__)->device,_p_arg1__,      \
118*a4af0ceeSJacob Faibussowitsch                                 (_p_dev_ctx2__)->device,_p_arg2__);     \
119*a4af0ceeSJacob Faibussowitsch   } while (0)
120*a4af0ceeSJacob Faibussowitsch 
121*a4af0ceeSJacob Faibussowitsch /*  This header file should NEVER #include another file and should be the last thing included
122*a4af0ceeSJacob Faibussowitsch  *  in the test file. This is to guard against ill-formed PetscDevice header files!
123*a4af0ceeSJacob Faibussowitsch  */
124*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertDeviceExists(PetscDevice device)
125*a4af0ceeSJacob Faibussowitsch {
126*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
127*a4af0ceeSJacob Faibussowitsch   PetscValidDevice(device,1);
128*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
129*a4af0ceeSJacob Faibussowitsch }
130*a4af0ceeSJacob Faibussowitsch 
131*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertDeviceDoesNotExist(PetscDevice device)
132*a4af0ceeSJacob Faibussowitsch {
133*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
134*a4af0ceeSJacob Faibussowitsch   if (device) {
135*a4af0ceeSJacob Faibussowitsch     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscDevice was not destroyed for type %s",PetscDeviceTypes[device->type]);
136*a4af0ceeSJacob Faibussowitsch   }
137*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
138*a4af0ceeSJacob Faibussowitsch }
139*a4af0ceeSJacob Faibussowitsch 
140*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertDeviceContextExists(PetscDeviceContext dctx)
141*a4af0ceeSJacob Faibussowitsch {
142*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
143*a4af0ceeSJacob Faibussowitsch   PetscValidDeviceContext(dctx,1);
144*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
145*a4af0ceeSJacob Faibussowitsch }
146*a4af0ceeSJacob Faibussowitsch 
147*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertDeviceContextDoesNotExist(PetscDeviceContext dctx)
148*a4af0ceeSJacob Faibussowitsch {
149*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
150*a4af0ceeSJacob Faibussowitsch   if (dctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscDeviceContext was not destroyed");
151*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
152*a4af0ceeSJacob Faibussowitsch }
153*a4af0ceeSJacob Faibussowitsch 
154*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertPetscStreamTypesValidAndEqual(PetscStreamType left, PetscStreamType right, const char *errStr)
155*a4af0ceeSJacob Faibussowitsch {
156*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
157*a4af0ceeSJacob Faibussowitsch   PetscValidStreamType(left,1);
158*a4af0ceeSJacob Faibussowitsch   PetscValidStreamType(right,2);
159*a4af0ceeSJacob Faibussowitsch   if (left != right) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,errStr,PetscStreamTypes[left],PetscStreamTypes[right]);
160*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
161*a4af0ceeSJacob Faibussowitsch }
162*a4af0ceeSJacob Faibussowitsch 
163*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertPetscDevicesValidAndEqual(PetscDevice left, PetscDevice right, const char *errStr)
164*a4af0ceeSJacob Faibussowitsch {
165*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
166*a4af0ceeSJacob Faibussowitsch   PetscCheckCompatibleDevices(left,1,right,2);
167*a4af0ceeSJacob Faibussowitsch   if (left != right) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_CORRUPT,errStr);
168*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
169*a4af0ceeSJacob Faibussowitsch }
170*a4af0ceeSJacob Faibussowitsch 
171*a4af0ceeSJacob Faibussowitsch PETSC_STATIC_INLINE PetscErrorCode AssertPetscDeviceContextsValidAndEqual(PetscDeviceContext left, PetscDeviceContext right, const char *errStr)
172*a4af0ceeSJacob Faibussowitsch {
173*a4af0ceeSJacob Faibussowitsch   PetscFunctionBegin;
174*a4af0ceeSJacob Faibussowitsch   PetscCheckCompatibleDeviceContexts(left,1,right,2);
175*a4af0ceeSJacob Faibussowitsch   if (left != right) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,errStr);
176*a4af0ceeSJacob Faibussowitsch   PetscFunctionReturn(0);
177*a4af0ceeSJacob Faibussowitsch }
178*a4af0ceeSJacob Faibussowitsch #endif /* PETSCDEVICETESTCOMMON_H */
179