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