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_COUNT) *mtype = MPIU_COUNT; 44 else if (ptype == PETSC_INT32) *mtype = MPIU_INT32; 45 else if (ptype == PETSC_FLOAT) *mtype = MPI_FLOAT; 46 else if (ptype == PETSC_CHAR) *mtype = MPI_CHAR; 47 else if (ptype == PETSC_BIT_LOGICAL) *mtype = MPI_BYTE; 48 #if defined(PETSC_USE_REAL___FLOAT128) 49 else if (ptype == PETSC___FLOAT128) *mtype = MPIU___FLOAT128; 50 #elif defined(PETSC_USE_REAL___FP16) 51 else if (ptype == PETSC___FP16) *mtype = MPIU___FP16; 52 #endif 53 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype"); 54 PetscFunctionReturn(PETSC_SUCCESS); 55 } 56 57 /*@C 58 PetscMPIDataTypeToPetscDataType - Finds the `PetscDataType` name of a datatype from its `MPI_Datatype` 59 60 Not Collective 61 62 Input Parameter: 63 . mtype - the MPI datatype (for example `MPI_DOUBLE`, ...) 64 65 Output Parameter: 66 . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`) 67 68 Level: advanced 69 70 .seealso: `PetscDataType` 71 @*/ 72 PetscErrorCode PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype, PetscDataType *ptype) 73 { 74 PetscFunctionBegin; 75 if (mtype == MPIU_INT) *ptype = PETSC_INT; 76 #if defined(PETSC_USE_64BIT_INDICES) 77 else if (mtype == MPI_INT) *ptype = PETSC_ENUM; 78 #endif 79 else if (mtype == MPIU_INT64) *ptype = PETSC_INT64; 80 else if (mtype == MPIU_COUNT) *ptype = PETSC_COUNT; 81 else if (mtype == MPIU_INT32) *ptype = PETSC_INT32; 82 else if (mtype == MPI_DOUBLE) *ptype = PETSC_DOUBLE; 83 #if defined(PETSC_HAVE_COMPLEX) 84 #if defined(PETSC_USE_REAL_SINGLE) 85 else if (mtype == MPI_C_COMPLEX) *ptype = PETSC_COMPLEX; 86 #elif defined(PETSC_USE_REAL___FLOAT128) 87 else if (mtype == MPIU___COMPLEX128) *ptype = PETSC_COMPLEX; 88 #else 89 else if (mtype == MPI_C_DOUBLE_COMPLEX) *ptype = PETSC_COMPLEX; 90 #endif 91 #endif 92 else if (mtype == MPI_LONG) *ptype = PETSC_LONG; 93 else if (mtype == MPI_SHORT) *ptype = PETSC_SHORT; 94 else if (mtype == MPI_FLOAT) *ptype = PETSC_FLOAT; 95 else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR; 96 #if defined(PETSC_USE_REAL___FLOAT128) 97 else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128; 98 #elif defined(PETSC_USE_REAL___FP16) 99 else if (mtype == MPIU___FP16) *ptype = PETSC___FP16; 100 #endif 101 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled MPI datatype"); 102 PetscFunctionReturn(PETSC_SUCCESS); 103 } 104 105 typedef enum { 106 PETSC_INT_SIZE = sizeof(PetscInt), 107 PETSC_DOUBLE_SIZE = sizeof(double), 108 #if defined(PETSC_HAVE_COMPLEX) 109 PETSC_COMPLEX_SIZE = sizeof(PetscComplex), 110 #else 111 PETSC_COMPLEX_SIZE = 2 * sizeof(PetscReal), 112 #endif 113 PETSC_LONG_SIZE = sizeof(long), 114 PETSC_SHORT_SIZE = sizeof(short), 115 PETSC_FLOAT_SIZE = sizeof(float), 116 PETSC_CHAR_SIZE = sizeof(char), 117 PETSC_ENUM_SIZE = sizeof(PetscEnum), 118 PETSC_BOOL_SIZE = sizeof(PetscBool), 119 PETSC_INT64_SIZE = sizeof(PetscInt64), 120 PETSC_INT32_SIZE = sizeof(PetscInt32), 121 PETSC_BIT_LOGICAL_SIZE = sizeof(char), 122 PETSC_COUNT_SIZE = sizeof(PetscCount) 123 #if defined(PETSC_USE_REAL___FLOAT128) 124 , 125 PETSC___FLOAT128_SIZE = sizeof(__float128) 126 #elif defined(PETSC_USE_REAL___FP16) 127 , 128 PETSC___FP16_SIZE = sizeof(__fp16) 129 #endif 130 } PetscDataTypeSize; 131 132 /*@C 133 PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype 134 135 Not Collective 136 137 Input Parameter: 138 . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`) 139 140 Output Parameter: 141 . size - the size in bytes (for example the size of `PETSC_DOUBLE` is 8) 142 143 Level: advanced 144 145 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()` 146 @*/ 147 PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size) 148 { 149 PetscFunctionBegin; 150 if ((int)ptype < 0) *size = -(int)ptype; 151 else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE; 152 else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE; 153 else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE; 154 else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE; 155 else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE; 156 else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE; 157 else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE; 158 else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE; 159 else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE; 160 else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE; 161 else if (ptype == PETSC_INT32) *size = PETSC_INT32_SIZE; 162 else if (ptype == PETSC_COUNT) *size = PETSC_COUNT_SIZE; 163 else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE; 164 #if defined(PETSC_USE_REAL___FLOAT128) 165 else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE; 166 #elif defined(PETSC_USE_REAL___FP16) 167 else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE; 168 #endif 169 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype"); 170 PetscFunctionReturn(PETSC_SUCCESS); 171 } 172 173 /*@ 174 PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string 175 176 Not Collective 177 178 Input Parameter: 179 . name - the PETSc datatype name (for example, "double" or "real") 180 181 Output Parameters: 182 + ptype - the enum value, only valid if found is `PETSC_TRUE` 183 - found - the string matches one of the data types 184 185 Level: advanced 186 187 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()` 188 @*/ 189 PetscErrorCode PetscDataTypeFromString(const char name[], PetscDataType *ptype, PetscBool *found) 190 { 191 PetscFunctionBegin; 192 PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found)); 193 if (!*found) { 194 char formatted[16]; 195 196 PetscCall(PetscStrncpy(formatted, name, 16)); 197 PetscCall(PetscStrtolower(formatted)); 198 PetscCall(PetscStrcmp(formatted, "scalar", found)); 199 if (*found) { 200 *ptype = PETSC_SCALAR; 201 } else { 202 PetscCall(PetscStrcmp(formatted, "real", found)); 203 if (*found) *ptype = PETSC_REAL; 204 } 205 } 206 PetscFunctionReturn(PETSC_SUCCESS); 207 } 208