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