xref: /petsc/src/sys/objects/ptype.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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 PETSc name of a datatype to its MPI name.
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   PetscFunctionBegin;
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   PetscFunctionReturn(0);
52 }
53 
54 /*@C
55      PetscMPIDataTypeToPetscDataType Finds the PETSc name of a datatype from its MPI name
56 
57    Not collective
58 
59     Input Parameter:
60 .     mtype - the MPI datatype (for example MPI_DOUBLE, ...)
61 
62     Output Parameter:
63 .     ptype - the PETSc datatype name (for example PETSC_DOUBLE)
64 
65     Level: advanced
66 
67 .seealso: `PetscDataType`, `PetscMPIDataTypeToPetscDataType()`
68 @*/
69 PetscErrorCode PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype, PetscDataType *ptype) {
70   PetscFunctionBegin;
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   PetscFunctionReturn(0);
97 }
98 
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;
123 
124 /*@C
125      PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype
126 
127    Not collective
128 
129     Input Parameter:
130 .     ptype - the PETSc datatype name (for example PETSC_DOUBLE)
131 
132     Output Parameter:
133 .     size - the size in bytes (for example the size of PETSC_DOUBLE is 8)
134 
135     Level: advanced
136 
137 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`
138 @*/
139 PetscErrorCode PetscDataTypeGetSize(PetscDataType ptype, size_t *size) {
140   PetscFunctionBegin;
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   PetscFunctionReturn(0);
160 }
161 
162 /*@C
163      PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string
164 
165    Not collective
166 
167     Input Parameter:
168 .     name - the PETSc datatype name (for example, DOUBLE or real or Scalar)
169 
170     Output Parameters:
171 +    ptype - the enum value
172 -    found - the string matches one of the data types
173 
174     Level: advanced
175 
176 .seealso: `PetscDataType`, `PetscDataTypeToMPIDataType()`, `PetscDataTypeGetSize()`
177 @*/
178 PetscErrorCode PetscDataTypeFromString(const char *name, PetscDataType *ptype, PetscBool *found) {
179   PetscFunctionBegin;
180   PetscCall(PetscEnumFind(PetscDataTypes, name, (PetscEnum *)ptype, found));
181   if (!*found) {
182     char formatted[16];
183 
184     PetscCall(PetscStrncpy(formatted, name, 16));
185     PetscCall(PetscStrtolower(formatted));
186     PetscCall(PetscStrcmp(formatted, "scalar", found));
187     if (*found) {
188       *ptype = PETSC_SCALAR;
189     } else {
190       PetscCall(PetscStrcmp(formatted, "real", found));
191       if (*found) { *ptype = PETSC_REAL; }
192     }
193   }
194   PetscFunctionReturn(0);
195 }
196