1 /* 2 Provides utility routines for manipulating any type of PETSc object. 3 */ 4 #include <petscsys.h> /*I "petscsys.h" I*/ 5 6 const char *const PetscDataTypes[] = {"UNKNOWN", "DOUBLE", "COMPLEX", "LONG", "SHORT", "FLOAT", "CHAR", "BIT_LOGICAL", "ENUM", "BOOL", "__FLOAT128", "OBJECT", 7 "FUNCTION", "STRING", "__FP16", "STRUCT", "INT", "INT64", "COUNT", "INT32", "PetscDataType", "PETSC_", NULL}; 8 9 /*@C 10 PetscDataTypeToMPIDataType - Converts the `PetscDataType` name of a datatype to its `MPI_Datatype` 11 12 Not Collective 13 14 Input Parameter: 15 . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`) 16 17 Output Parameter: 18 . mtype - the MPI datatype (for example `MPI_DOUBLE`, ...) 19 20 Level: advanced 21 22 .seealso: `PetscDataType`, `PetscMPIDataTypeToPetscDataType()` 23 @*/ 24 PetscErrorCode PetscDataTypeToMPIDataType(PetscDataType ptype, MPI_Datatype *mtype) 25 { 26 PetscFunctionBegin; 27 if (ptype == PETSC_INT) *mtype = MPIU_INT; 28 else if (ptype == PETSC_DOUBLE) *mtype = MPI_DOUBLE; 29 #if defined(PETSC_HAVE_COMPLEX) 30 #if defined(PETSC_USE_REAL_SINGLE) 31 else if (ptype == PETSC_COMPLEX) *mtype = MPI_C_COMPLEX; 32 #elif defined(PETSC_USE_REAL___FLOAT128) 33 else if (ptype == PETSC_COMPLEX) *mtype = MPIU___COMPLEX128; 34 #else 35 else if (ptype == PETSC_COMPLEX) *mtype = MPI_C_DOUBLE_COMPLEX; 36 #endif 37 #endif 38 else if (ptype == PETSC_LONG) *mtype = MPI_LONG; 39 else if (ptype == PETSC_SHORT) *mtype = MPI_SHORT; 40 else if (ptype == PETSC_ENUM) *mtype = MPI_INT; 41 else if (ptype == PETSC_BOOL) *mtype = MPI_INT; 42 else if (ptype == PETSC_INT64) *mtype = MPIU_INT64; 43 else if (ptype == PETSC_INT32) *mtype = MPIU_INT32; 44 else if (ptype == PETSC_FLOAT) *mtype = MPI_FLOAT; 45 else if (ptype == PETSC_CHAR) *mtype = MPI_CHAR; 46 else if (ptype == PETSC_BIT_LOGICAL) *mtype = MPI_BYTE; 47 #if defined(PETSC_USE_REAL___FLOAT128) 48 else if (ptype == PETSC___FLOAT128) *mtype = MPIU___FLOAT128; 49 #elif defined(PETSC_USE_REAL___FP16) 50 else if (ptype == PETSC___FP16) *mtype = MPIU___FP16; 51 #endif 52 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype"); 53 PetscFunctionReturn(PETSC_SUCCESS); 54 } 55 56 /*@C 57 PetscMPIDataTypeToPetscDataType - Finds the `PetscDataType` name of a datatype from its `MPI_Datatype` 58 59 Not Collective 60 61 Input Parameter: 62 . mtype - the MPI datatype (for example `MPI_DOUBLE`, ...) 63 64 Output Parameter: 65 . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`) 66 67 Level: advanced 68 69 .seealso: `PetscDataType` 70 @*/ 71 PetscErrorCode PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype, PetscDataType *ptype) 72 { 73 PetscFunctionBegin; 74 if (mtype == MPIU_INT) *ptype = PETSC_INT; 75 #if defined(PETSC_USE_64BIT_INDICES) 76 else if (mtype == MPI_INT) *ptype = PETSC_ENUM; 77 #endif 78 else if (mtype == MPIU_INT64) *ptype = PETSC_INT64; 79 else if (mtype == MPIU_INT32) *ptype = PETSC_INT32; 80 else if (mtype == MPI_DOUBLE) *ptype = PETSC_DOUBLE; 81 #if defined(PETSC_HAVE_COMPLEX) 82 #if defined(PETSC_USE_REAL_SINGLE) 83 else if (mtype == MPI_C_COMPLEX) *ptype = PETSC_COMPLEX; 84 #elif defined(PETSC_USE_REAL___FLOAT128) 85 else if (mtype == MPIU___COMPLEX128) *ptype = PETSC_COMPLEX; 86 #else 87 else if (mtype == MPI_C_DOUBLE_COMPLEX) *ptype = PETSC_COMPLEX; 88 #endif 89 #endif 90 else if (mtype == MPI_LONG) *ptype = PETSC_LONG; 91 else if (mtype == MPI_SHORT) *ptype = PETSC_SHORT; 92 else if (mtype == MPI_FLOAT) *ptype = PETSC_FLOAT; 93 else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR; 94 #if defined(PETSC_USE_REAL___FLOAT128) 95 else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128; 96 #elif defined(PETSC_USE_REAL___FP16) 97 else if (mtype == MPIU___FP16) *ptype = PETSC___FP16; 98 #endif 99 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled MPI datatype"); 100 PetscFunctionReturn(PETSC_SUCCESS); 101 } 102 103 typedef enum { 104 PETSC_INT_SIZE = sizeof(PetscInt), 105 PETSC_DOUBLE_SIZE = sizeof(double), 106 #if defined(PETSC_HAVE_COMPLEX) 107 PETSC_COMPLEX_SIZE = sizeof(PetscComplex), 108 #else 109 PETSC_COMPLEX_SIZE = 2 * sizeof(PetscReal), 110 #endif 111 PETSC_LONG_SIZE = sizeof(long), 112 PETSC_SHORT_SIZE = sizeof(short), 113 PETSC_FLOAT_SIZE = sizeof(float), 114 PETSC_CHAR_SIZE = sizeof(char), 115 PETSC_ENUM_SIZE = sizeof(PetscEnum), 116 PETSC_BOOL_SIZE = sizeof(PetscBool), 117 PETSC_INT64_SIZE = sizeof(PetscInt64), 118 PETSC_INT32_SIZE = sizeof(PetscInt32), 119 PETSC_BIT_LOGICAL_SIZE = sizeof(char) 120 #if defined(PETSC_USE_REAL___FLOAT128) 121 , 122 PETSC___FLOAT128_SIZE = sizeof(__float128) 123 #elif defined(PETSC_USE_REAL___FP16) 124 , 125 PETSC___FP16_SIZE = sizeof(__fp16) 126 #endif 127 } PetscDataTypeSize; 128 129 /*@C 130 PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype 131 132 Not Collective 133 134 Input Parameter: 135 . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`) 136 137 Output Parameter: 138 . size - the size in bytes (for example the size of `PETSC_DOUBLE` is 8) 139 140 Level: advanced 141 142 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()` 143 @*/ 144 PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size) 145 { 146 PetscFunctionBegin; 147 if ((int)ptype < 0) *size = -(int)ptype; 148 else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE; 149 else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE; 150 else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE; 151 else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE; 152 else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE; 153 else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE; 154 else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE; 155 else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE; 156 else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE; 157 else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE; 158 else if (ptype == PETSC_INT32) *size = PETSC_INT32_SIZE; 159 else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE; 160 #if defined(PETSC_USE_REAL___FLOAT128) 161 else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE; 162 #elif defined(PETSC_USE_REAL___FP16) 163 else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE; 164 #endif 165 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype"); 166 PetscFunctionReturn(PETSC_SUCCESS); 167 } 168 169 /*@C 170 PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string 171 172 Not Collective 173 174 Input Parameter: 175 . name - the PETSc datatype name (for example, "double" or "real") 176 177 Output Parameters: 178 + ptype - the enum value, only valid if found is `PETSC_TRUE` 179 - found - the string matches one of the data types 180 181 Level: advanced 182 183 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()` 184 @*/ 185 PetscErrorCode PetscDataTypeFromString(const char *name, PetscDataType *ptype, PetscBool *found) 186 { 187 PetscFunctionBegin; 188 PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found)); 189 if (!*found) { 190 char formatted[16]; 191 192 PetscCall(PetscStrncpy(formatted, name, 16)); 193 PetscCall(PetscStrtolower(formatted)); 194 PetscCall(PetscStrcmp(formatted, "scalar", found)); 195 if (*found) { 196 *ptype = PETSC_SCALAR; 197 } else { 198 PetscCall(PetscStrcmp(formatted, "real", found)); 199 if (*found) *ptype = PETSC_REAL; 200 } 201 } 202 PetscFunctionReturn(PETSC_SUCCESS); 203 } 204