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