Actual source code: ptype.c


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

  7: const char *const PetscDataTypes[] = {"UNKNOWN", "DOUBLE", "COMPLEX", "LONG", "SHORT", "FLOAT", "CHAR", "LOGICAL", "ENUM", "BOOL", "LONGDOUBLE", "OBJECT", "FUNCTION", "STRING", "FP16", "STRUCT", "INT", "INT64", "PetscDataType", "PETSC_", NULL};

  9: /*@C
 10:      PetscDataTypeToMPIDataType - Converts the PETSc name of a datatype to its MPI name.

 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:   if (ptype == PETSC_INT) *mtype = MPIU_INT;
 27:   else if (ptype == PETSC_DOUBLE) *mtype = MPI_DOUBLE;
 28: #if defined(PETSC_HAVE_COMPLEX)
 29:   #if defined(PETSC_USE_REAL_SINGLE)
 30:   else if (ptype == PETSC_COMPLEX) *mtype = MPI_C_COMPLEX;
 31:   #elif defined(PETSC_USE_REAL___FLOAT128)
 32:   else if (ptype == PETSC_COMPLEX) *mtype = MPIU___COMPLEX128;
 33:   #else
 34:   else if (ptype == PETSC_COMPLEX) *mtype = MPI_C_DOUBLE_COMPLEX;
 35:   #endif
 36: #endif
 37:   else if (ptype == PETSC_LONG) *mtype = MPI_LONG;
 38:   else if (ptype == PETSC_SHORT) *mtype = MPI_SHORT;
 39:   else if (ptype == PETSC_ENUM) *mtype = MPI_INT;
 40:   else if (ptype == PETSC_BOOL) *mtype = MPI_INT;
 41:   else if (ptype == PETSC_INT64) *mtype = MPIU_INT64;
 42:   else if (ptype == PETSC_FLOAT) *mtype = MPI_FLOAT;
 43:   else if (ptype == PETSC_CHAR) *mtype = MPI_CHAR;
 44:   else if (ptype == PETSC_BIT_LOGICAL) *mtype = MPI_BYTE;
 45: #if defined(PETSC_USE_REAL___FLOAT128)
 46:   else if (ptype == PETSC___FLOAT128) *mtype = MPIU___FLOAT128;
 47: #elif defined(PETSC_USE_REAL___FP16)
 48:   else if (ptype == PETSC___FP16) *mtype = MPIU___FP16;
 49: #endif
 50:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
 51:   return 0;
 52: }

 54: /*@C
 55:      PetscMPIDataTypeToPetscDataType - Finds the PETSc name of a datatype from its MPI name

 57:    Not collective

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

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

 65:     Level: advanced

 67: .seealso: `PetscDataType`, `PetscMPIDataTypeToPetscDataType()`
 68: @*/
 69: PetscErrorCode PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype, PetscDataType *ptype)
 70: {
 71:   if (mtype == MPIU_INT) *ptype = PETSC_INT;
 72: #if defined(PETSC_USE_64BIT_INDICES)
 73:   else if (mtype == MPI_INT) *ptype = PETSC_ENUM;
 74: #endif
 75:   else if (mtype == MPIU_INT64) *ptype = PETSC_INT64;
 76:   else if (mtype == MPI_DOUBLE) *ptype = PETSC_DOUBLE;
 77: #if defined(PETSC_HAVE_COMPLEX)
 78:   #if defined(PETSC_USE_REAL_SINGLE)
 79:   else if (mtype == MPI_C_COMPLEX) *ptype = PETSC_COMPLEX;
 80:   #elif defined(PETSC_USE_REAL___FLOAT128)
 81:   else if (mtype == MPIU___COMPLEX128) *ptype = PETSC_COMPLEX;
 82:   #else
 83:   else if (mtype == MPI_C_DOUBLE_COMPLEX) *ptype = PETSC_COMPLEX;
 84:   #endif
 85: #endif
 86:   else if (mtype == MPI_LONG) *ptype = PETSC_LONG;
 87:   else if (mtype == MPI_SHORT) *ptype = PETSC_SHORT;
 88:   else if (mtype == MPI_FLOAT) *ptype = PETSC_FLOAT;
 89:   else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR;
 90: #if defined(PETSC_USE_REAL___FLOAT128)
 91:   else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128;
 92: #elif defined(PETSC_USE_REAL___FP16)
 93:   else if (mtype == MPIU___FP16) *ptype = PETSC___FP16;
 94: #endif
 95:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled MPI datatype");
 96:   return 0;
 97: }

 99: typedef enum {
100:   PETSC_INT_SIZE    = sizeof(PetscInt),
101:   PETSC_DOUBLE_SIZE = sizeof(double),
102: #if defined(PETSC_HAVE_COMPLEX)
103:   PETSC_COMPLEX_SIZE = sizeof(PetscComplex),
104: #else
105:   PETSC_COMPLEX_SIZE = 2 * sizeof(PetscReal),
106: #endif
107:   PETSC_LONG_SIZE        = sizeof(long),
108:   PETSC_SHORT_SIZE       = sizeof(short),
109:   PETSC_FLOAT_SIZE       = sizeof(float),
110:   PETSC_CHAR_SIZE        = sizeof(char),
111:   PETSC_ENUM_SIZE        = sizeof(PetscEnum),
112:   PETSC_BOOL_SIZE        = sizeof(PetscBool),
113:   PETSC_INT64_SIZE       = sizeof(PetscInt64),
114:   PETSC_BIT_LOGICAL_SIZE = sizeof(char)
115: #if defined(PETSC_USE_REAL___FLOAT128)
116:     ,
117:   PETSC___FLOAT128_SIZE = sizeof(__float128)
118: #elif defined(PETSC_USE_REAL___FP16)
119:     ,
120:   PETSC___FP16_SIZE = sizeof(__fp16)
121: #endif
122: } PetscDataTypeSize;

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

127:    Not collective

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

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

135:     Level: advanced

137: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`
138: @*/
139: PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size)
140: {
141:   if ((int)ptype < 0) *size = -(int)ptype;
142:   else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE;
143:   else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE;
144:   else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE;
145:   else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE;
146:   else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE;
147:   else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE;
148:   else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE;
149:   else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE;
150:   else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE;
151:   else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE;
152:   else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE;
153: #if defined(PETSC_USE_REAL___FLOAT128)
154:   else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE;
155: #elif defined(PETSC_USE_REAL___FP16)
156:   else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE;
157: #endif
158:   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
159:   return 0;
160: }

162: /*@C
163:      PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string

165:    Not collective

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

170:     Output Parameters:
171: +    ptype - the enum value, only valid if found is `PETSC_TRUE`
172: -    found - the string matches one of the data types

174:     Level: advanced

176: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()`
177: @*/
178: PetscErrorCode PetscDataTypeFromString(const char *name, PetscDataType *ptype, PetscBool *found)
179: {
180:   PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found);
181:   if (!*found) {
182:     char formatted[16];

184:     PetscStrncpy(formatted, name, 16);
185:     PetscStrtolower(formatted);
186:     PetscStrcmp(formatted, "scalar", found);
187:     if (*found) {
188:       *ptype = PETSC_SCALAR;
189:     } else {
190:       PetscStrcmp(formatted, "real", found);
191:       if (*found) *ptype = PETSC_REAL;
192:     }
193:   }
194:   return 0;
195: }