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