Actual source code: ptype.c

  1: /*
  2:      Provides utility routines for manipulating any type of PETSc object.
  3: */
  4: #include <petscsys.h>

  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};

  9: /*@C
 10:   PetscDataTypeToMPIDataType - Converts the `PetscDataType` name of a datatype to its `MPI_Datatype`

 12:   Not Collective

 14:   Input Parameter:
 15: . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)

 17:   Output Parameter:
 18: . mtype - the MPI datatype (for example `MPI_DOUBLE`, ...)

 20:   Level: advanced

 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_C_BOOL;
 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: }

 57: /*@C
 58:   PetscMPIDataTypeToPetscDataType - Finds the `PetscDataType` name of a datatype from its `MPI_Datatype`

 60:   Not Collective

 62:   Input Parameter:
 63: . mtype - the MPI datatype (for example `MPI_DOUBLE`, ...)

 65:   Output Parameter:
 66: . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)

 68:   Level: advanced

 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_C_BOOL) *ptype = PETSC_BOOL;
 95:   else if (mtype == MPI_FLOAT) *ptype = PETSC_FLOAT;
 96:   else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR;
 97: #if defined(PETSC_USE_REAL___FLOAT128)
 98:   else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128;
 99: #elif defined(PETSC_USE_REAL___FP16)
100:   else if (mtype == MPIU___FP16) *ptype = PETSC___FP16;
101: #endif
102:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled MPI datatype");
103:   PetscFunctionReturn(PETSC_SUCCESS);
104: }

106: typedef enum {
107:   PETSC_INT_SIZE    = sizeof(PetscInt),
108:   PETSC_DOUBLE_SIZE = sizeof(double),
109: #if defined(PETSC_HAVE_COMPLEX)
110:   PETSC_COMPLEX_SIZE = sizeof(PetscComplex),
111: #else
112:   PETSC_COMPLEX_SIZE = 2 * sizeof(PetscReal),
113: #endif
114:   PETSC_LONG_SIZE        = sizeof(long),
115:   PETSC_SHORT_SIZE       = sizeof(short),
116:   PETSC_FLOAT_SIZE       = sizeof(float),
117:   PETSC_CHAR_SIZE        = sizeof(char),
118:   PETSC_ENUM_SIZE        = sizeof(PetscEnum),
119:   PETSC_BOOL_SIZE        = sizeof(PetscBool),
120:   PETSC_INT64_SIZE       = sizeof(PetscInt64),
121:   PETSC_INT32_SIZE       = sizeof(PetscInt32),
122:   PETSC_BIT_LOGICAL_SIZE = sizeof(char),
123:   PETSC_COUNT_SIZE       = sizeof(PetscCount)
124: #if defined(PETSC_USE_REAL___FLOAT128)
125:     ,
126:   PETSC___FLOAT128_SIZE = sizeof(__float128)
127: #elif defined(PETSC_USE_REAL___FP16)
128:     ,
129:   PETSC___FP16_SIZE = sizeof(__fp16)
130: #endif
131: } PetscDataTypeSize;

133: /*@C
134:   PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype

136:   Not Collective

138:   Input Parameter:
139: . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)

141:   Output Parameter:
142: . size - the size in bytes (for example the size of `PETSC_DOUBLE` is 8)

144:   Level: advanced

146: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`
147: @*/
148: PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size)
149: {
150:   PetscFunctionBegin;
151:   if ((int)ptype < 0) *size = -(int)ptype;
152:   else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE;
153:   else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE;
154:   else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE;
155:   else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE;
156:   else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE;
157:   else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE;
158:   else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE;
159:   else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE;
160:   else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE;
161:   else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE;
162:   else if (ptype == PETSC_INT32) *size = PETSC_INT32_SIZE;
163:   else if (ptype == PETSC_COUNT) *size = PETSC_COUNT_SIZE;
164:   else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE;
165: #if defined(PETSC_USE_REAL___FLOAT128)
166:   else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE;
167: #elif defined(PETSC_USE_REAL___FP16)
168:   else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE;
169: #endif
170:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
171:   PetscFunctionReturn(PETSC_SUCCESS);
172: }

174: /*@
175:   PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string

177:   Not Collective

179:   Input Parameter:
180: . name - the PETSc datatype name (for example, "double" or "real")

182:   Output Parameters:
183: + ptype - the enum value, only valid if found is `PETSC_TRUE`
184: - found - the string matches one of the data types

186:   Level: advanced

188: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()`
189: @*/
190: PetscErrorCode PetscDataTypeFromString(const char name[], PetscDataType *ptype, PetscBool *found)
191: {
192:   PetscFunctionBegin;
193:   PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found));
194:   if (!*found) {
195:     char formatted[16];

197:     PetscCall(PetscStrncpy(formatted, name, 16));
198:     PetscCall(PetscStrtolower(formatted));
199:     PetscCall(PetscStrcmp(formatted, "scalar", found));
200:     if (*found) {
201:       *ptype = PETSC_SCALAR;
202:     } else {
203:       PetscCall(PetscStrcmp(formatted, "real", found));
204:       if (*found) *ptype = PETSC_REAL;
205:     }
206:   }
207:   PetscFunctionReturn(PETSC_SUCCESS);
208: }