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: /*@
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 PetscDefined(HAVE_COMPLEX)
30: #if PetscDefined(USE_REAL_SINGLE)
31: else if (ptype == PETSC_COMPLEX) *mtype = MPI_C_COMPLEX;
32: #elif PetscDefined(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 PetscDefined(USE_REAL___FLOAT128)
49: else if (ptype == PETSC___FLOAT128) *mtype = MPIU___FLOAT128;
50: #elif PetscDefined(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: /*@
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: else if (PetscDefined(USE_64BIT_INDICES) && mtype == MPI_INT) *ptype = PETSC_ENUM;
77: else if (mtype == MPIU_INT64) *ptype = PETSC_INT64;
78: else if (mtype == MPIU_COUNT) *ptype = PETSC_COUNT;
79: else if (mtype == MPIU_INT32) *ptype = PETSC_INT32;
80: else if (mtype == MPI_DOUBLE) *ptype = PETSC_DOUBLE;
81: #if PetscDefined(HAVE_COMPLEX)
82: #if PetscDefined(USE_REAL_SINGLE)
83: else if (mtype == MPI_C_COMPLEX) *ptype = PETSC_COMPLEX;
84: #elif PetscDefined(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_C_BOOL) *ptype = PETSC_BOOL;
93: else if (mtype == MPI_FLOAT) *ptype = PETSC_FLOAT;
94: else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR;
95: #if PetscDefined(USE_REAL___FLOAT128)
96: else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128;
97: #elif PetscDefined(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: }
104: typedef enum {
105: PETSC_INT_SIZE = sizeof(PetscInt),
106: PETSC_DOUBLE_SIZE = sizeof(double),
107: #if PetscDefined(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: PETSC_COUNT_SIZE = sizeof(PetscCount)
122: #if PetscDefined(USE_REAL___FLOAT128)
123: ,
124: PETSC___FLOAT128_SIZE = sizeof(__float128)
125: #elif PetscDefined(USE_REAL___FP16)
126: ,
127: PETSC___FP16_SIZE = sizeof(__fp16)
128: #endif
129: } PetscDataTypeSize;
131: /*@
132: PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype
134: Not Collective
136: Input Parameter:
137: . ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)
139: Output Parameter:
140: . size - the size in bytes (for example the size of `PETSC_DOUBLE` is 8)
142: Level: advanced
144: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`
145: @*/
146: PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size)
147: {
148: PetscFunctionBegin;
149: if ((int)ptype < 0) *size = -(int)ptype;
150: else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE;
151: else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE;
152: else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE;
153: else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE;
154: else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE;
155: else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE;
156: else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE;
157: else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE;
158: else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE;
159: else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE;
160: else if (ptype == PETSC_INT32) *size = PETSC_INT32_SIZE;
161: else if (ptype == PETSC_COUNT) *size = PETSC_COUNT_SIZE;
162: else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE;
163: #if PetscDefined(USE_REAL___FLOAT128)
164: else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE;
165: #elif PetscDefined(USE_REAL___FP16)
166: else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE;
167: #endif
168: else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
169: PetscFunctionReturn(PETSC_SUCCESS);
170: }
172: /*@
173: PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string
175: Not Collective
177: Input Parameter:
178: . name - the PETSc datatype name (for example, "double" or "real")
180: Output Parameters:
181: + ptype - the enum value, only valid if found is `PETSC_TRUE`
182: - found - the string matches one of the data types
184: Level: advanced
186: .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()`
187: @*/
188: PetscErrorCode PetscDataTypeFromString(const char name[], PetscDataType *ptype, PetscBool *found)
189: {
190: PetscFunctionBegin;
191: PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found));
192: if (!*found) {
193: char formatted[16];
195: PetscCall(PetscStrncpy(formatted, name, 16));
196: PetscCall(PetscStrtolower(formatted));
197: PetscCall(PetscStrcmp(formatted, "scalar", found));
198: if (*found) {
199: *ptype = PETSC_SCALAR;
200: } else {
201: PetscCall(PetscStrcmp(formatted, "real", found));
202: if (*found) *ptype = PETSC_REAL;
203: }
204: }
205: PetscFunctionReturn(PETSC_SUCCESS);
206: }