1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *
4  *  (C) 2009 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 
8 #ifndef OPUTIL_H_INCLUDED
9 #define OPUTIL_H_INCLUDED
10 
11 /* The MPI Standard (MPI-2.1, sec 5.9.2) defines which predfined reduction
12    operators are valid by groups of types:
13      C integer
14      Fortran integer
15      Floating point
16      Logical
17      Complex
18      Byte
19 
20    We define an "x-macro" for each type group.  Immediately prior to
21    instantiating any of these macros you should define a valid
22    MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_).  The primary use for this
23    is to expand a given group's list into a sequence of case statements.  The
24    macro MPIR_OP_TYPE_REDUCE_CASE is available as a convenience to generate a
25    case block that performs a reduction with the given operator.  */
26 
27 #if 0 /* sample usage: */
28 #undef MPIR_OP_TYPE_MACRO
29 #define MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_REDUCE_CASE(mpi_type_,c_type_,MPIR_MAX)
30 /* or */
31 #define MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_) case (mpi_type_):
32 
33 MPIR_OP_TYPE_GROUP(C_INTEGER)
34 MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER)
35 #undef MPIR_OP_TYPE_MACRO
36 #endif
37 
38 
39 /* op_macro_ is a 2-arg macro or function that preforms the reduction
40    operation on a single element */
41 /* Ideally "b" would be const, but xlc on POWER7 can't currently handle
42  * "const long double _Complex * restrict" as a valid pointer type.  It just
43  * emits a warning and generates invalid arithmetic code.  We could drop the
44  * restrict instead, but we are more likely to get an optimization from it than
45  * const.  [goodell@ 2010-12-15] */
46 #define MPIR_OP_TYPE_REDUCE_CASE(mpi_type_,c_type_,op_macro_) \
47     case (mpi_type_): {                                       \
48         c_type_ * restrict a = (c_type_ *)inoutvec;           \
49         /*const*/ c_type_ * restrict b = (c_type_ *)invec;    \
50         for ( i=0; i<len; i++ )                               \
51             a[i] = op_macro_(a[i],b[i]);                      \
52         break;                                                \
53     }
54 
55 /* helps enforce consistent naming */
56 #define MPIR_OP_TYPE_GROUP(group) MPIR_OP_TYPE_GROUP_##group
57 
58 /* -------------------------------------------------------------------- */
59 /* These macros are used to disable non-existent types.  They evaluate to
60    nothing if the particular feature test is false, otherwise they evaluate to
61    the standard macro to be expanded like any other type. */
62 
63 /* first define all wrapper macros as empty for possibly non-existent types */
64 #define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_,c_type_,type_name_)
65 #define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(mpi_type_,c_type_,type_name_)
66 #define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(mpi_type_,c_type_,type_name_)
67 #define MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(mpi_type_,c_type_,type_name_)
68 #define MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(mpi_type_,c_type_,type_name_)
69 #define MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(mpi_type_,c_type_,type_name_)
70 #define MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(mpi_type_,c_type_,type_name_)
71 #define MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(mpi_type_,c_type_,type_name_)
72 #define MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(mpi_type_,c_type_,type_name_)
73 #define MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(mpi_type_,c_type_,type_name_)
74 #define MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(mpi_type_,c_type_,type_name_)
75 #define MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(mpi_type_,c_type_,type_name_)
76 #define MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(mpi_type_,c_type_,type_name_)
77 #define MPIR_OP_TYPE_MACRO_HAVE_CXX(mpi_type_,c_type_,type_name_)
78 #define MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(mpi_type_,c_type_,type_name_)
79 #define MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_)
80 #define MPIR_OP_TYPE_MACRO_HAVE_INT8_T(mpi_type_,c_type_,type_name_)
81 #define MPIR_OP_TYPE_MACRO_HAVE_INT16_T(mpi_type_,c_type_,type_name_)
82 #define MPIR_OP_TYPE_MACRO_HAVE_INT32_T(mpi_type_,c_type_,type_name_)
83 #define MPIR_OP_TYPE_MACRO_HAVE_INT64_T(mpi_type_,c_type_,type_name_)
84 #define MPIR_OP_TYPE_MACRO_HAVE_UINT8_T(mpi_type_,c_type_,type_name_)
85 #define MPIR_OP_TYPE_MACRO_HAVE_UINT16_T(mpi_type_,c_type_,type_name_)
86 #define MPIR_OP_TYPE_MACRO_HAVE_UINT32_T(mpi_type_,c_type_,type_name_)
87 #define MPIR_OP_TYPE_MACRO_HAVE_UINT64_T(mpi_type_,c_type_,type_name_)
88 #define MPIR_OP_TYPE_MACRO_HAVE_C_BOOL(mpi_type_,c_type_,type_name_)
89 #define MPIR_OP_TYPE_MACRO_HAVE_C_FLOAT_COMPLEX(mpi_type_,c_type_,type_name_)
90 #define MPIR_OP_TYPE_MACRO_HAVE_C_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_)
91 #define MPIR_OP_TYPE_MACRO_HAVE_C_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_)
92 
93 /* then redefine them to be valid based on other preprocessor definitions */
94 #if defined(HAVE_FORTRAN_BINDING)
95 #  undef MPIR_OP_TYPE_MACRO_HAVE_FORTRAN
96 #  undef MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8
97 #  undef MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16
98 #  define MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
99 /* These two shouldn't really be gated on HAVE_FORTRAN_BINDING alone.  There
100    should instead be an individual test like HAVE_LONG_DOUBLE, etc. */
101 #  define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
102 #  define MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
103 #endif
104 
105 #if defined(HAVE_LONG_LONG_INT)
106 #  undef MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG
107 #  define MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
108 #endif
109 
110 #if defined(HAVE_LONG_DOUBLE)
111 #  undef MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE
112 #  define MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
113 #endif
114 
115 /* Fortran fixed width integer type support */
116 #if defined(MPIR_INTEGER1_CTYPE)
117 #  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE
118 #  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
119 #endif
120 #if defined(MPIR_INTEGER2_CTYPE)
121 #  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE
122 #  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
123 #endif
124 #if defined(MPIR_INTEGER4_CTYPE)
125 #  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE
126 #  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
127 #endif
128 #if defined(MPIR_INTEGER8_CTYPE)
129 #  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE
130 #  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
131 #endif
132 #if defined(MPIR_INTEGER16_CTYPE)
133 #  undef MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE
134 #  define MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
135 #endif
136 
137 /* Fortran fixed width floating point type support */
138 #if defined(MPIR_REAL4_CTYPE)
139 #  undef MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE
140 #  define MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
141 #endif
142 #if defined(MPIR_REAL8_CTYPE)
143 #  undef MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE
144 #  define MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
145 #endif
146 #if defined(MPIR_REAL16_CTYPE)
147 #  undef MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE
148 #  define MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
149 #endif
150 
151 /* general C++ types */
152 #if defined(HAVE_CXX_BINDING)
153 #  undef MPIR_OP_TYPE_MACRO_HAVE_CXX
154 #  define MPIR_OP_TYPE_MACRO_HAVE_CXX(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
155 #endif
156 
157 /* C++ complex types */
158 #if defined(HAVE_CXX_COMPLEX)
159 #  undef MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX
160 #  define MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
161 #endif
162 /* also test against MPI_DATATYPE_NULL for extra safety, 0x0c000000 is the uncasted value. */
163 #if defined(HAVE_CXX_COMPLEX) && (MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE != 0x0c000000)
164 #  undef MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX
165 #  define MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
166 #endif
167 
168 /* C99 fixed-width types */
169 #if defined(HAVE_INT8_T)
170 #  undef MPIR_OP_TYPE_MACRO_HAVE_INT8_T
171 #  define MPIR_OP_TYPE_MACRO_HAVE_INT8_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
172 #endif
173 #if defined(HAVE_INT16_T)
174 #  undef MPIR_OP_TYPE_MACRO_HAVE_INT16_T
175 #  define MPIR_OP_TYPE_MACRO_HAVE_INT16_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
176 #endif
177 #if defined(HAVE_INT32_T)
178 #  undef MPIR_OP_TYPE_MACRO_HAVE_INT32_T
179 #  define MPIR_OP_TYPE_MACRO_HAVE_INT32_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
180 #endif
181 #if defined(HAVE_INT64_T)
182 #  undef MPIR_OP_TYPE_MACRO_HAVE_INT64_T
183 #  define MPIR_OP_TYPE_MACRO_HAVE_INT64_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
184 #endif
185 #if defined(HAVE_UINT8_T)
186 #  undef MPIR_OP_TYPE_MACRO_HAVE_UINT8_T
187 #  define MPIR_OP_TYPE_MACRO_HAVE_UINT8_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
188 #endif
189 #if defined(HAVE_UINT16_T)
190 #  undef MPIR_OP_TYPE_MACRO_HAVE_UINT16_T
191 #  define MPIR_OP_TYPE_MACRO_HAVE_UINT16_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
192 #endif
193 #if defined(HAVE_UINT32_T)
194 #  undef MPIR_OP_TYPE_MACRO_HAVE_UINT32_T
195 #  define MPIR_OP_TYPE_MACRO_HAVE_UINT32_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
196 #endif
197 #if defined(HAVE_UINT64_T)
198 #  undef MPIR_OP_TYPE_MACRO_HAVE_UINT64_T
199 #  define MPIR_OP_TYPE_MACRO_HAVE_UINT64_T(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
200 #endif
201 
202 /* C boolean */
203 #if defined(HAVE__BOOL)
204 #undef MPIR_OP_TYPE_MACRO_HAVE_C_BOOL
205 #define MPIR_OP_TYPE_MACRO_HAVE_C_BOOL(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
206 #endif
207 
208 /* C complex types */
209 /* Add another layer of indirection and make all of these macros evaluate to a
210    common MPIR_OP_C_COMPLEX_TYPE_MACRO macro which in turn evaluates to the
211    standard MPIR_OP_TYPE_MACRO.  This lets us override behavior for these
212    natively handled types with a single macro redefinition instead of 3. */
213 #undef MPIR_OP_C_COMPLEX_TYPE_MACRO
214 #define MPIR_OP_C_COMPLEX_TYPE_MACRO(mpi_type_,c_type_,type_name_) MPIR_OP_TYPE_MACRO(mpi_type_,c_type_,type_name_)
215 #if defined(HAVE_FLOAT__COMPLEX)
216 #  undef MPIR_OP_TYPE_MACRO_HAVE_C_FLOAT_COMPLEX
217 #  define MPIR_OP_TYPE_MACRO_HAVE_C_FLOAT_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_C_COMPLEX_TYPE_MACRO(mpi_type_,c_type_,type_name_)
218 #endif
219 #if defined(HAVE_DOUBLE__COMPLEX)
220 #  undef MPIR_OP_TYPE_MACRO_HAVE_C_DOUBLE_COMPLEX
221 #  define MPIR_OP_TYPE_MACRO_HAVE_C_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_C_COMPLEX_TYPE_MACRO(mpi_type_,c_type_,type_name_)
222 #endif
223 #if defined(HAVE_LONG_DOUBLE__COMPLEX)
224 #  undef MPIR_OP_TYPE_MACRO_HAVE_C_LONG_DOUBLE_COMPLEX
225 #  define MPIR_OP_TYPE_MACRO_HAVE_C_LONG_DOUBLE_COMPLEX(mpi_type_,c_type_,type_name_) MPIR_OP_C_COMPLEX_TYPE_MACRO(mpi_type_,c_type_,type_name_)
226 #endif
227 
228 /* C types needed to support some of the complex types.
229 
230    FIXME These are a hack in most cases, but they seem to work in practice
231    and it's what we were doing prior to the oputil.h refactoring. */
232 typedef struct {
233     float re;
234     float im;
235 } s_complex;
236 
237 #if defined(HAVE_FORTRAN_BINDING)
238 typedef struct {
239     MPIR_FC_REAL_CTYPE re;
240     MPIR_FC_REAL_CTYPE im;
241 } s_fc_complex;
242 
243 typedef struct {
244     MPIR_FC_DOUBLE_CTYPE re;
245     MPIR_FC_DOUBLE_CTYPE im;
246 } d_fc_complex;
247 #endif
248 
249 typedef struct {
250     double re;
251     double im;
252 } d_complex;
253 
254 #if defined(HAVE_LONG_DOUBLE)
255 typedef struct {
256     long double re;
257     long double im;
258 } ld_complex;
259 #endif
260 
261 /* -------------------------------------------------------------------- */
262 /* type group macros
263 
264    Implementation note: it is important that no MPI type show up more than once
265    among all the lists.  Otherwise it will be easy to end up with two case
266    statements with the same value, which is erroneous in C.  Duplicate C types
267    in this list are not a problem. */
268 
269 /* c integer group */
270 #define MPIR_OP_TYPE_GROUP_C_INTEGER                                                                                  \
271     MPIR_OP_TYPE_MACRO(MPI_INT, int, mpir_typename_int)                                                               \
272     MPIR_OP_TYPE_MACRO(MPI_LONG, long, mpir_typename_long)                                                            \
273     MPIR_OP_TYPE_MACRO(MPI_SHORT, short, mpir_typename_short)                                                         \
274     MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_SHORT, unsigned short, mpir_typename_unsigned_short)                              \
275     MPIR_OP_TYPE_MACRO(MPI_UNSIGNED, unsigned, mpir_typename_unsigned)                                                \
276     MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_LONG, unsigned long, mpir_typename_unsigned_long)                                 \
277     MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(MPI_LONG_LONG, long long, mpir_typename_long_long)                              \
278     MPIR_OP_TYPE_MACRO_HAVE_LONG_LONG(MPI_UNSIGNED_LONG_LONG, unsigned long long, mpir_typename_unsigned_long_long)   \
279     MPIR_OP_TYPE_MACRO(MPI_SIGNED_CHAR, signed char, mpir_typename_signed_char)                                       \
280     MPIR_OP_TYPE_MACRO(MPI_UNSIGNED_CHAR, unsigned char, mpir_typename_unsigned_char)                                 \
281     MPIR_OP_TYPE_MACRO_HAVE_INT8_T(MPI_INT8_T, int8_t, mpir_typename_int8_t)                                          \
282     MPIR_OP_TYPE_MACRO_HAVE_INT16_T(MPI_INT16_T, int16_t, mpir_typename_int16_t)                                      \
283     MPIR_OP_TYPE_MACRO_HAVE_INT32_T(MPI_INT32_T, int32_t, mpir_typename_int32_t)                                      \
284     MPIR_OP_TYPE_MACRO_HAVE_INT64_T(MPI_INT64_T, int64_t, mpir_typename_int64_t)                                      \
285     MPIR_OP_TYPE_MACRO_HAVE_UINT8_T(MPI_UINT8_T, uint8_t, mpir_typename_uint8_t)                                      \
286     MPIR_OP_TYPE_MACRO_HAVE_UINT16_T(MPI_UINT16_T, uint16_t, mpir_typename_uint16_t)                                  \
287     MPIR_OP_TYPE_MACRO_HAVE_UINT32_T(MPI_UINT32_T, uint32_t, mpir_typename_uint32_t)                                  \
288     MPIR_OP_TYPE_MACRO_HAVE_UINT64_T(MPI_UINT64_T, uint64_t, mpir_typename_uint64_t)                                  \
289 /* The MPI Standard doesn't include these types in the C integer group for
290    predefined operations but MPICH2 supports them when possible. */
291 #define MPIR_OP_TYPE_GROUP_C_INTEGER_EXTRA      \
292     MPIR_OP_TYPE_MACRO(MPI_CHAR, char, mpir_typename_char)
293 
294 /* fortran integer group */
295 #define MPIR_OP_TYPE_GROUP_FORTRAN_INTEGER                                            \
296     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_INTEGER, MPI_Fint, mpir_typename_integer)     \
297     MPIR_OP_TYPE_MACRO(MPI_AINT, MPI_Aint, mpir_typename_aint)                        \
298     MPIR_OP_TYPE_MACRO(MPI_OFFSET, MPI_Offset, mpir_typename_offset)
299 /* The MPI Standard doesn't include these types in the Fortran integer group for
300    predefined operations but MPICH2 supports them when possible. */
301 #define MPIR_OP_TYPE_GROUP_FORTRAN_INTEGER_EXTRA                                                      \
302     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_CHARACTER, char, mpir_typename_character)                     \
303     MPIR_OP_TYPE_MACRO_HAVE_INTEGER1_CTYPE(MPI_INTEGER1, MPIR_INTEGER1_CTYPE, mpir_typename_integer1) \
304     MPIR_OP_TYPE_MACRO_HAVE_INTEGER2_CTYPE(MPI_INTEGER2, MPIR_INTEGER2_CTYPE, mpir_typename_integer2) \
305     MPIR_OP_TYPE_MACRO_HAVE_INTEGER4_CTYPE(MPI_INTEGER4, MPIR_INTEGER4_CTYPE, mpir_typename_integer4) \
306     MPIR_OP_TYPE_MACRO_HAVE_INTEGER8_CTYPE(MPI_INTEGER8, MPIR_INTEGER8_CTYPE, mpir_typename_integer8) \
307     MPIR_OP_TYPE_MACRO_HAVE_INTEGER16_CTYPE(MPI_INTEGER16, MPIR_INTEGER16_CTYPE, mpir_typename_integer16)
308 
309 /* floating point group */
310 /* FIXME: REAL need not be float, nor DOUBLE_PRECISION be double.
311    Fortran types are not synonyms for the C types */
312 #define MPIR_OP_TYPE_GROUP_FLOATING_POINT                                                                             \
313     MPIR_OP_TYPE_MACRO(MPI_FLOAT, float, mpir_typename_float)                                                         \
314     MPIR_OP_TYPE_MACRO(MPI_DOUBLE, double, mpir_typename_double)                                                      \
315     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_REAL, MPIR_FC_REAL_CTYPE, mpir_typename_real)                                 \
316     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_DOUBLE_PRECISION, MPIR_FC_DOUBLE_CTYPE, mpir_typename_double_precision)       \
317     MPIR_OP_TYPE_MACRO_HAVE_LONG_DOUBLE(MPI_LONG_DOUBLE, long double, mpir_typename_long_double)                      \
318 /* The MPI Standard doesn't include these types in the floating point group for
319    predefined operations but MPICH2 supports them when possible. */
320 #define MPIR_OP_TYPE_GROUP_FLOATING_POINT_EXTRA                                               \
321     MPIR_OP_TYPE_MACRO_HAVE_REAL4_CTYPE(MPI_REAL4, MPIR_REAL4_CTYPE, mpir_typename_real4)     \
322     MPIR_OP_TYPE_MACRO_HAVE_REAL8_CTYPE(MPI_REAL8, MPIR_REAL8_CTYPE, mpir_typename_real8)     \
323     MPIR_OP_TYPE_MACRO_HAVE_REAL16_CTYPE(MPI_REAL16, MPIR_REAL16_CTYPE, mpir_typename_real16)
324 
325 /* logical group */
326 /* FIXME Is MPI_Fint really OK here? */
327 #define MPIR_OP_TYPE_GROUP_LOGICAL                                                    \
328     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_LOGICAL, MPI_Fint, mpir_typename_logical)     \
329     MPIR_OP_TYPE_MACRO_HAVE_C_BOOL(MPI_C_BOOL, _Bool, mpir_typename_c_bool)           \
330     MPIR_OP_TYPE_MACRO_HAVE_CXX(MPIR_CXX_BOOL_VALUE, MPIR_CXX_BOOL_CTYPE, mpir_typename_cxx_bool_value)
331 #define MPIR_OP_TYPE_GROUP_LOGICAL_EXTRA /* empty, provided for consistency */
332 
333 /* complex group */
334 #define MPIR_OP_TYPE_GROUP_COMPLEX                                                                                    \
335     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_COMPLEX, s_fc_complex, mpir_typename_complex)                                 \
336     MPIR_OP_TYPE_MACRO_HAVE_C_FLOAT_COMPLEX(MPI_C_FLOAT_COMPLEX, float _Complex, mpir_typename_c_float_complex)       \
337     MPIR_OP_TYPE_MACRO_HAVE_C_DOUBLE_COMPLEX(MPI_C_DOUBLE_COMPLEX, double _Complex, mpir_typename_c_double_complex)   \
338     MPIR_OP_TYPE_MACRO_HAVE_C_LONG_DOUBLE_COMPLEX(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex, mpir_typename_c_long_double_complex)
339 #define MPIR_OP_TYPE_GROUP_COMPLEX_EXTRA                                                                                      \
340     MPIR_OP_TYPE_MACRO_HAVE_FORTRAN(MPI_DOUBLE_COMPLEX, d_fc_complex, mpir_typename_double_complex)                           \
341     MPIR_OP_TYPE_MACRO_HAVE_COMPLEX8(MPI_COMPLEX8, s_complex, mpir_typename_complex8)                                         \
342     MPIR_OP_TYPE_MACRO_HAVE_COMPLEX16(MPI_COMPLEX16, d_complex, mpir_typename_complex16)                                      \
343     MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_COMPLEX_VALUE, s_complex, mpir_typename_cxx_complex_value)                   \
344     MPIR_OP_TYPE_MACRO_HAVE_CXX_COMPLEX(MPIR_CXX_DOUBLE_COMPLEX_VALUE, d_complex, mpir_typename_cxx_double_complex_value)     \
345     MPIR_OP_TYPE_MACRO_HAVE_CXX_LONG_DOUBLE_COMPLEX(MPIR_CXX_LONG_DOUBLE_COMPLEX_VALUE, ld_complex, mpir_typename_cxx_long_double_complex_value)
346 
347 /* byte group */
348 #define MPIR_OP_TYPE_GROUP_BYTE         \
349     MPIR_OP_TYPE_MACRO(MPI_BYTE, unsigned char, mpir_typename_byte)
350 #define MPIR_OP_TYPE_GROUP_BYTE_EXTRA /* empty, provided for consistency */
351 
352 /* convenience macro that just is all non-extra groups concatenated */
353 #define MPIR_OP_TYPE_GROUP_ALL_BASIC    \
354     MPIR_OP_TYPE_GROUP(C_INTEGER)       \
355     MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER) \
356     MPIR_OP_TYPE_GROUP(FLOATING_POINT)  \
357     MPIR_OP_TYPE_GROUP(LOGICAL)         \
358     MPIR_OP_TYPE_GROUP(COMPLEX)         \
359     MPIR_OP_TYPE_GROUP(BYTE)
360 
361 /* this macro includes just the extra type groups */
362 #define MPIR_OP_TYPE_GROUP_ALL_EXTRA          \
363     MPIR_OP_TYPE_GROUP(C_INTEGER_EXTRA)       \
364     MPIR_OP_TYPE_GROUP(FORTRAN_INTEGER_EXTRA) \
365     MPIR_OP_TYPE_GROUP(FLOATING_POINT_EXTRA)  \
366     MPIR_OP_TYPE_GROUP(LOGICAL_EXTRA)         \
367     MPIR_OP_TYPE_GROUP(COMPLEX_EXTRA)         \
368     MPIR_OP_TYPE_GROUP(BYTE_EXTRA)
369 
370 #endif /* OPUTIL_H_INCLUDED */
371