xref: /petsc/src/sys/objects/ptype.c (revision 6467efc9ef4d99487050cf3d5fe3db991cbd2979)
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`
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