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",
8                                       "DOUBLE","COMPLEX","LONG","SHORT","FLOAT",
9                                       "CHAR","LOGICAL","ENUM","BOOL","LONGDOUBLE",
10                                       "OBJECT","FUNCTION","STRING","FP16","STRUCT",
11                                       "INT","INT64",
12                                       "PetscDataType","PETSC_",NULL};
13 
14 /*@C
15      PetscDataTypeToMPIDataType - Converts the PETSc name of a datatype to its MPI name.
16 
17    Not collective
18 
19     Input Parameter:
20 .     ptype - the PETSc datatype name (for example PETSC_DOUBLE)
21 
22     Output Parameter:
23 .     mtype - the MPI datatype (for example MPI_DOUBLE, ...)
24 
25     Level: advanced
26 
27 .seealso: PetscDataType, PetscMPIDataTypeToPetscDataType()
28 @*/
PetscDataTypeToMPIDataType(PetscDataType ptype,MPI_Datatype * mtype)29 PetscErrorCode  PetscDataTypeToMPIDataType(PetscDataType ptype,MPI_Datatype *mtype)
30 {
31   PetscFunctionBegin;
32   if (ptype == PETSC_INT)              *mtype = MPIU_INT;
33   else if (ptype == PETSC_DOUBLE)      *mtype = MPI_DOUBLE;
34 #if defined(PETSC_HAVE_COMPLEX)
35 #if defined(PETSC_USE_REAL_SINGLE)
36   else if (ptype == PETSC_COMPLEX)     *mtype = MPIU_C_COMPLEX;
37 #elif defined(PETSC_USE_REAL___FLOAT128)
38   else if (ptype == PETSC_COMPLEX)     *mtype = MPIU___COMPLEX128;
39 #else
40   else if (ptype == PETSC_COMPLEX)     *mtype = MPIU_C_DOUBLE_COMPLEX;
41 #endif
42 #endif
43   else if (ptype == PETSC_LONG)        *mtype = MPI_LONG;
44   else if (ptype == PETSC_SHORT)       *mtype = MPI_SHORT;
45   else if (ptype == PETSC_ENUM)        *mtype = MPI_INT;
46   else if (ptype == PETSC_BOOL)        *mtype = MPI_INT;
47   else if (ptype == PETSC_INT64)       *mtype = MPIU_INT64;
48   else if (ptype == PETSC_FLOAT)       *mtype = MPI_FLOAT;
49   else if (ptype == PETSC_CHAR)        *mtype = MPI_CHAR;
50   else if (ptype == PETSC_BIT_LOGICAL) *mtype = MPI_BYTE;
51 #if defined(PETSC_USE_REAL___FLOAT128)
52   else if (ptype == PETSC___FLOAT128)  *mtype = MPIU___FLOAT128;
53 #elif defined(PETSC_USE_REAL___FP16)
54   else if (ptype == PETSC___FP16)      *mtype = MPIU___FP16;
55 #endif
56   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown PETSc datatype");
57   PetscFunctionReturn(0);
58 }
59 
60 /*@C
61      PetscMPIDataTypeToPetscDataType Finds the PETSc name of a datatype from its MPI name
62 
63    Not collective
64 
65     Input Parameter:
66 .     mtype - the MPI datatype (for example MPI_DOUBLE, ...)
67 
68     Output Parameter:
69 .     ptype - the PETSc datatype name (for example PETSC_DOUBLE)
70 
71     Level: advanced
72 
73 .seealso: PetscDataType, PetscMPIDataTypeToPetscDataType()
74 @*/
PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype,PetscDataType * ptype)75 PetscErrorCode  PetscMPIDataTypeToPetscDataType(MPI_Datatype mtype,PetscDataType *ptype)
76 {
77   PetscFunctionBegin;
78   if (mtype == MPIU_INT)             *ptype = PETSC_INT;
79 #if defined(PETSC_USE_64BIT_INDICES)
80   else if (mtype == MPI_INT)         *ptype = PETSC_ENUM;
81 #endif
82   else if (mtype == MPIU_INT64)      *ptype = PETSC_INT64;
83   else if (mtype == MPI_DOUBLE)      *ptype = PETSC_DOUBLE;
84 #if defined(PETSC_HAVE_COMPLEX)
85 #if defined(PETSC_USE_REAL_SINGLE)
86   else if (mtype == MPIU_C_COMPLEX)  *ptype = PETSC_COMPLEX;
87 #elif defined(PETSC_USE_REAL___FLOAT128)
88   else if (mtype == MPIU___COMPLEX128) *ptype = PETSC_COMPLEX;
89 #else
90   else if (mtype == MPIU_C_DOUBLE_COMPLEX) *ptype = PETSC_COMPLEX;
91 #endif
92 #endif
93   else if (mtype == MPI_LONG)        *ptype = PETSC_LONG;
94   else if (mtype == MPI_SHORT)       *ptype = PETSC_SHORT;
95   else if (mtype == MPI_FLOAT)       *ptype = PETSC_FLOAT;
96   else if (mtype == MPI_CHAR)        *ptype = PETSC_CHAR;
97 #if defined(PETSC_USE_REAL___FLOAT128)
98   else if (mtype == MPIU___FLOAT128) *ptype = PETSC___FLOAT128;
99 #elif defined(PETSC_USE_REAL___FP16)
100   else if (mtype == MPIU___FP16) *ptype = PETSC___FP16;
101 #endif
102   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unhandled MPI datatype");
103   PetscFunctionReturn(0);
104 }
105 
106 typedef enum {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_BIT_LOGICAL_SIZE = sizeof(char)
121 #if defined(PETSC_USE_REAL___FLOAT128)
122               ,PETSC___FLOAT128_SIZE  = sizeof(__float128)
123 #elif defined(PETSC_USE_REAL___FP16)
124               ,PETSC___FP16_SIZE      = sizeof(__fp16)
125 #endif
126              } PetscDataTypeSize;
127 
128 /*@C
129      PetscDataTypeGetSize - Gets the size (in bytes) of a PETSc datatype
130 
131    Not collective
132 
133     Input Parameter:
134 .     ptype - the PETSc datatype name (for example PETSC_DOUBLE)
135 
136     Output Parameter:
137 .     size - the size in bytes (for example the size of PETSC_DOUBLE is 8)
138 
139     Level: advanced
140 
141 .seealso: PetscDataType, PetscDataTypeToMPIDataType()
142 @*/
PetscDataTypeGetSize(PetscDataType ptype,size_t * size)143 PetscErrorCode  PetscDataTypeGetSize(PetscDataType ptype,size_t *size)
144 {
145   PetscFunctionBegin;
146   if ((int) ptype < 0)                 *size = -(int)ptype;
147   else if (ptype == PETSC_INT)         *size = PETSC_INT_SIZE;
148   else if (ptype == PETSC_DOUBLE)      *size = PETSC_DOUBLE_SIZE;
149   else if (ptype == PETSC_COMPLEX)     *size = PETSC_COMPLEX_SIZE;
150   else if (ptype == PETSC_LONG)        *size = PETSC_LONG_SIZE;
151   else if (ptype == PETSC_SHORT)       *size = PETSC_SHORT_SIZE;
152   else if (ptype == PETSC_FLOAT)       *size = PETSC_FLOAT_SIZE;
153   else if (ptype == PETSC_CHAR)        *size = PETSC_CHAR_SIZE;
154   else if (ptype == PETSC_ENUM)        *size = PETSC_ENUM_SIZE;
155   else if (ptype == PETSC_BOOL)        *size = PETSC_BOOL_SIZE;
156   else if (ptype == PETSC_INT64)       *size = PETSC_INT64_SIZE;
157   else if (ptype == PETSC_BIT_LOGICAL) *size = PETSC_BIT_LOGICAL_SIZE;
158 #if defined(PETSC_USE_REAL___FLOAT128)
159   else if (ptype == PETSC___FLOAT128)  *size = PETSC___FLOAT128_SIZE;
160 #elif defined(PETSC_USE_REAL___FP16)
161   else if (ptype == PETSC___FP16)      *size = PETSC___FP16_SIZE;
162 #endif
163   else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unknown PETSc datatype");
164   PetscFunctionReturn(0);
165 }
166 
167 /*@C
168      PetscDataTypeFromString - Gets the enum value of a PETSc datatype represented as a string
169 
170    Not collective
171 
172     Input Parameter:
173 .     name - the PETSc datatype name (for example, DOUBLE or real or Scalar)
174 
175     Output Parameter:
176 +    ptype - the enum value
177 -    found - the string matches one of the data types
178 
179     Level: advanced
180 
181 .seealso: PetscDataType, PetscDataTypeToMPIDataType(), PetscDataTypeGetSize()
182 @*/
PetscDataTypeFromString(const char * name,PetscDataType * ptype,PetscBool * found)183 PetscErrorCode  PetscDataTypeFromString(const char*name, PetscDataType *ptype,PetscBool *found)
184 {
185   PetscErrorCode ierr;
186 
187   PetscFunctionBegin;
188   ierr = PetscEnumFind(PetscDataTypes,name,(PetscEnum*)ptype,found);CHKERRQ(ierr);
189   if (!*found) {
190     char formatted[16];
191 
192     ierr = PetscStrncpy(formatted,name,16);CHKERRQ(ierr);
193     ierr = PetscStrtolower(formatted);CHKERRQ(ierr);
194     ierr = PetscStrcmp(formatted,"scalar",found);CHKERRQ(ierr);
195     if (*found) {
196       *ptype = PETSC_SCALAR;
197     } else {
198       ierr = PetscStrcmp(formatted,"real",found);CHKERRQ(ierr);
199       if (*found) {
200         *ptype = PETSC_REAL;
201       }
202     }
203   }
204   PetscFunctionReturn(0);
205 }
206