xref: /petsc/src/sys/objects/ptype.c (revision 001c270e97a2c840518350fc2da4bcea772f2f15)
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", "LOGICAL", "ENUM", "BOOL", "LONGDOUBLE", "OBJECT", "FUNCTION", "STRING", "FP16", "STRUCT", "INT", "INT64", "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 @*/
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_INT32) *mtype = MPIU_INT32;
44   else if (ptype == PETSC_FLOAT) *mtype = MPI_FLOAT;
45   else if (ptype == PETSC_CHAR) *mtype = MPI_CHAR;
46   else if (ptype == PETSC_BIT_LOGICAL) *mtype = MPI_BYTE;
47 #if defined(PETSC_USE_REAL___FLOAT128)
48   else if (ptype == PETSC___FLOAT128) *mtype = MPIU___FLOAT128;
49 #elif defined(PETSC_USE_REAL___FP16)
50   else if (ptype == PETSC___FP16) *mtype = MPIU___FP16;
51 #endif
52   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
53   PetscFunctionReturn(PETSC_SUCCESS);
54 }
55 
56 /*@C
57      PetscMPIDataTypeToPetscDataType - Finds the `PetscDataType` name of a datatype from its `MPI_Datatype`
58 
59    Not Collective
60 
61     Input Parameter:
62 .     mtype - the MPI datatype (for example `MPI_DOUBLE`, ...)
63 
64     Output Parameter:
65 .     ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)
66 
67     Level: advanced
68 
69 .seealso: `PetscDataType`, `PetscMPIDataTypeToPetscDataType()`
70 @*/
71 PetscErrorCode PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype, PetscDataType *ptype)
72 {
73   PetscFunctionBegin;
74   if (mtype == MPIU_INT) *ptype = PETSC_INT;
75 #if defined(PETSC_USE_64BIT_INDICES)
76   else if (mtype == MPI_INT) *ptype = PETSC_ENUM;
77 #endif
78   else if (mtype == MPIU_INT64) *ptype = PETSC_INT64;
79   else if (mtype == MPIU_INT32) *ptype = PETSC_INT32;
80   else if (mtype == MPI_DOUBLE) *ptype = PETSC_DOUBLE;
81 #if defined(PETSC_HAVE_COMPLEX)
82   #if defined(PETSC_USE_REAL_SINGLE)
83   else if (mtype == MPI_C_COMPLEX) *ptype = PETSC_COMPLEX;
84   #elif defined(PETSC_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_FLOAT) *ptype = PETSC_FLOAT;
93   else if (mtype == MPI_CHAR) *ptype = PETSC_CHAR;
94 #if defined(PETSC_USE_REAL___FLOAT128)
95   else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128;
96 #elif defined(PETSC_USE_REAL___FP16)
97   else if (mtype == MPIU___FP16) *ptype = PETSC___FP16;
98 #endif
99   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Unhandled MPI datatype");
100   PetscFunctionReturn(PETSC_SUCCESS);
101 }
102 
103 typedef enum {
104   PETSC_INT_SIZE    = sizeof(PetscInt),
105   PETSC_DOUBLE_SIZE = sizeof(double),
106 #if defined(PETSC_HAVE_COMPLEX)
107   PETSC_COMPLEX_SIZE = sizeof(PetscComplex),
108 #else
109   PETSC_COMPLEX_SIZE = 2 * sizeof(PetscReal),
110 #endif
111   PETSC_LONG_SIZE        = sizeof(long),
112   PETSC_SHORT_SIZE       = sizeof(short),
113   PETSC_FLOAT_SIZE       = sizeof(float),
114   PETSC_CHAR_SIZE        = sizeof(char),
115   PETSC_ENUM_SIZE        = sizeof(PetscEnum),
116   PETSC_BOOL_SIZE        = sizeof(PetscBool),
117   PETSC_INT64_SIZE       = sizeof(PetscInt64),
118   PETSC_INT32_SIZE       = sizeof(PetscInt32),
119   PETSC_BIT_LOGICAL_SIZE = sizeof(char)
120 #if defined(PETSC_USE_REAL___FLOAT128)
121     ,
122   PETSC___FLOAT128_SIZE = sizeof(__float128)
123 #elif defined(PETSC_USE_REAL___FP16)
124     ,
125   PETSC___FP16_SIZE = sizeof(__fp16)
126 #endif
127 } PetscDataTypeSize;
128 
129 /*@C
130      PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype
131 
132    Not Collective
133 
134     Input Parameter:
135 .     ptype - the PETSc datatype name (for example `PETSC_DOUBLE`)
136 
137     Output Parameter:
138 .     size - the size in bytes (for example the size of `PETSC_DOUBLE` is 8)
139 
140     Level: advanced
141 
142 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`
143 @*/
144 PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size)
145 {
146   PetscFunctionBegin;
147   if ((int)ptype < 0) *size = -(int)ptype;
148   else if (ptype == PETSC_INT) *size = PETSC_INT_SIZE;
149   else if (ptype == PETSC_DOUBLE) *size = PETSC_DOUBLE_SIZE;
150   else if (ptype == PETSC_COMPLEX) *size = PETSC_COMPLEX_SIZE;
151   else if (ptype == PETSC_LONG) *size = PETSC_LONG_SIZE;
152   else if (ptype == PETSC_SHORT) *size = PETSC_SHORT_SIZE;
153   else if (ptype == PETSC_FLOAT) *size = PETSC_FLOAT_SIZE;
154   else if (ptype == PETSC_CHAR) *size = PETSC_CHAR_SIZE;
155   else if (ptype == PETSC_ENUM) *size = PETSC_ENUM_SIZE;
156   else if (ptype == PETSC_BOOL) *size = PETSC_BOOL_SIZE;
157   else if (ptype == PETSC_INT64) *size = PETSC_INT64_SIZE;
158   else if (ptype == PETSC_INT32) *size = PETSC_INT32_SIZE;
159   else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE;
160 #if defined(PETSC_USE_REAL___FLOAT128)
161   else if (ptype == PETSC___FLOAT128) *size = PETSC___FLOAT128_SIZE;
162 #elif defined(PETSC_USE_REAL___FP16)
163   else if (ptype == PETSC___FP16) *size = PETSC___FP16_SIZE;
164 #endif
165   else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Unknown PETSc datatype");
166   PetscFunctionReturn(PETSC_SUCCESS);
167 }
168 
169 /*@C
170      PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string
171 
172    Not Collective
173 
174     Input Parameter:
175 .     name - the PETSc datatype name (for example, "double" or "real")
176 
177     Output Parameters:
178 +    ptype - the enum value, only valid if found is `PETSC_TRUE`
179 -    found - the string matches one of the data types
180 
181     Level: advanced
182 
183 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()`
184 @*/
185 PetscErrorCode PetscDataTypeFromString(const char *name, PetscDataType *ptype, PetscBool *found)
186 {
187   PetscFunctionBegin;
188   PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found));
189   if (!*found) {
190     char formatted[16];
191 
192     PetscCall(PetscStrncpy(formatted, name, 16));
193     PetscCall(PetscStrtolower(formatted));
194     PetscCall(PetscStrcmp(formatted, "scalar", found));
195     if (*found) {
196       *ptype = PETSC_SCALAR;
197     } else {
198       PetscCall(PetscStrcmp(formatted, "real", found));
199       if (*found) *ptype = PETSC_REAL;
200     }
201   }
202   PetscFunctionReturn(PETSC_SUCCESS);
203 }
204