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