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