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 @*/
PetscDataTypeToMPIDataType(PetscDataType ptype,MPI_Datatype * mtype)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 @*/
PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype,PetscDataType * ptype)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 @*/
PetscDataTypeGetSize(PetscDataType ptype,size_t * size)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 @*/
PetscDataTypeFromString(const char name[],PetscDataType * ptype,PetscBool * found)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