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