OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

op.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2007 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2008 UT-Battelle, LLC
14 * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
15 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
16 * $COPYRIGHT$
17 *
18 * Additional copyrights may follow
19 *
20 * $HEADER$
21 */
22 /**
23 * @file
24 *
25 * Public interface for the MPI_Op handle.
26 */
27
28 #ifndef OMPI_OP_H
29 #define OMPI_OP_H
30
31 #include "ompi_config.h"
32
33 #include <stdio.h>
34
35 #include "mpi.h"
36
37 #include "opal/class/opal_object.h"
38
39 #include "ompi/datatype/ompi_datatype.h"
40 #include "ompi/mpi/f77/fint_2_int.h"
41 #include "ompi/mca/op/op.h"
42
43 BEGIN_C_DECLS
44
45 /**
46 * Typedef for C op functions for user-defined MPI_Ops.
47 *
48 * We don't use MPI_User_function because this would create a
49 * confusing dependency loop between this file and mpi.h. So this is
50 * repeated code, but it's better this way (and this typedef will
51 * never change, so there's not much of a maintenance worry).
52 */
53 typedef void (ompi_op_c_handler_fn_t)(void *, void *, int *,
54 struct ompi_datatype_t **);
55
56 /**
57 * Typedef for fortran user-defined MPI_Ops.
58 */
59 typedef void (ompi_op_fortran_handler_fn_t)(void *, void *,
60 MPI_Fint *, MPI_Fint *);
61
62 /**
63 * Typedef for C++ op functions intercept (used for user-defined
64 * MPI::Ops).
65 *
66 * See the lengthy explanation for why this is different than the C
67 * intercept in ompi/mpi/cxx/intercepts.cc in the
68 * ompi_mpi_cxx_op_intercept() function.
69 */
70 typedef void (ompi_op_cxx_handler_fn_t)(void *, void *, int *,
71 struct ompi_datatype_t **,
72 MPI_User_function * op);
73
74 /*
75 * Flags for MPI_Op
76 */
77 /** Set if the MPI_Op is a built-in operation */
78 #define OMPI_OP_FLAGS_INTRINSIC 0x0001
79 /** Set if the callback function is in Fortran */
80 #define OMPI_OP_FLAGS_FORTRAN_FUNC 0x0002
81 /** Set if the callback function is in C++ */
82 #define OMPI_OP_FLAGS_CXX_FUNC 0x0004
83 /** Set if the callback function is associative (MAX and SUM will both
84 have ASSOC set -- in fact, it will only *not* be set if we
85 implement some extensions to MPI, because MPI says that all
86 MPI_Op's should be associative, so this flag is really here for
87 future expansion) */
88 #define OMPI_OP_FLAGS_ASSOC 0x0008
89 /** Set if the callback function is associative for floating point
90 operands (e.g., MPI_SUM will have ASSOC set, but will *not* have
91 FLOAT_ASSOC set) */
92 #define OMPI_OP_FLAGS_FLOAT_ASSOC 0x0010
93 /** Set if the callback function is communative */
94 #define OMPI_OP_FLAGS_COMMUTE 0x0020
95
96
97 /**
98 * Back-end type of MPI_Op
99 */
100 struct ompi_op_t {
101 /** Parent class, for reference counting */
102 opal_object_t super;
103
104 /** Name, for debugging purposes */
105 char o_name[MPI_MAX_OBJECT_NAME];
106
107 /** Flags about the op */
108 uint32_t o_flags;
109
110 /** Index in Fortran <-> C translation array */
111 int o_f_to_c_index;
112
113 /** Union holding (2-buffer functions):
114 1. Function pointers for all supported datatypes when this op
115 is intrinsic
116 2. Function pointers for when this op is user-defined (only
117 need one function pointer for this; we call it for *all*
118 datatypes, even intrinsics)
119 */
120 union {
121 /** Function/module pointers for intrinsic ops */
122 ompi_op_base_op_fns_t intrinsic;
123 /** C handler function pointer */
124 ompi_op_c_handler_fn_t *c_fn;
125 /** Fortran handler function pointer */
126 ompi_op_fortran_handler_fn_t *fort_fn;
127 /** C++ intercept function data -- see lengthy comment in
128 ompi/mpi/cxx/intercepts.cc::ompi_mpi_cxx_op_intercept() for
129 an explanation */
130 struct {
131 /* The user's function (it's the wrong type, but that's ok) */
132 ompi_op_c_handler_fn_t *user_fn;
133 /* The OMPI C++ callback/intercept function */
134 ompi_op_cxx_handler_fn_t *intercept_fn;
135 } cxx_data;
136 } o_func;
137
138 /** 3-buffer functions, which is only for intrinsic ops. No need
139 for the C/C++/Fortran user-defined functions. */
140 ompi_op_base_op_3buff_fns_t o_3buff_intrinsic;
141 };
142
143 /**
144 * Convenience typedef
145 */
146 typedef struct ompi_op_t ompi_op_t;
147 OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_op_t);
148
149 /**
150 * Padded struct to maintain back compatibiltiy.
151 * See ompi/communicator/communicator.h comments with struct ompi_communicator_t
152 * for full explanation why we chose the following padding construct for predefines.
153 */
154 #define PREDEFINED_OP_PAD (sizeof(void*) * 256)
155
156 struct ompi_predefined_op_t {
157 struct ompi_op_t op;
158 char padding[PREDEFINED_OP_PAD - sizeof(ompi_op_t)];
159 };
160
161 typedef struct ompi_predefined_op_t ompi_predefined_op_t;
162
163 /**
164 * Array to map ddt->id values to the corresponding position in the op
165 * function array.
166 *
167 * NOTE: It is possible to have an implementation without this map.
168 * There are basically 3 choices for implementing "how to find the
169 * right position in the op array based on the datatype":
170 *
171 * 1. Use the exact same ordering as ddt->id in the op map. This is
172 * nice in that it's always a direct lookup via one memory
173 * de-reference. But it makes a sparse op array, and it's at least
174 * somewhat wasteful. It also chains the ddt and op implementations
175 * together. If the ddt ever changes its ordering, op is screwed. It
176 * seemed safer from a maintenance point of view not to do it that
177 * way.
178 *
179 * 2. Re-arrange the ddt ID values so that all the reducable types are
180 * at the beginning. This means that we can have a dense array here
181 * in op, but then we have the same problem as number one -- and so
182 * this didn't seem like a good idea from a maintenance point of view.
183 *
184 * 3. Create a mapping between the ddt->id values and the position in
185 * the op array. This allows a nice dense op array, and if we make
186 * the map based on symbolic values, then if ddt ever changes its
187 * ordering, it won't matter to op. This seemed like the safest thing
188 * to do from a maintenance perspective, and since it only costs one
189 * extra lookup, and that lookup is way cheaper than the function call
190 * to invoke the reduction operation, it seemed like the best idea.
191 */
192 OMPI_DECLSPEC extern int ompi_op_ddt_map[OMPI_DATATYPE_MAX_PREDEFINED];
193
194 /**
195 * Global variable for MPI_OP_NULL
196 */
197 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_null;
198
199 /**
200 * Global variable for MPI_MAX
201 */
202 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_max;
203
204 /**
205 * Global variable for MPI_MIN
206 */
207 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_min;
208
209 /**
210 * Global variable for MPI_SUM
211 */
212 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_sum;
213
214 /**
215 * Global variable for MPI_PROD
216 */
217 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_prod;
218
219 /**
220 * Global variable for MPI_LAND
221 */
222 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_land;
223
224 /**
225 * Global variable for MPI_BAND
226 */
227 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_band;
228
229 /**
230 * Global variable for MPI_LOR
231 */
232 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_lor;
233
234 /**
235 * Global variable for MPI_BOR
236 */
237 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_bor;
238
239 /**
240 * Global variable for MPI_LXOR
241 */
242 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_lxor;
243
244 /**
245 * Global variable for MPI_BXOR
246 */
247 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_bxor;
248
249 /**
250 * Global variable for MPI_MAXLOC
251 */
252 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_maxloc;
253
254 /**
255 * Global variable for MPI_MINLOC
256 */
257 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_minloc;
258
259 /**
260 * Global variable for MPI_REPLACE
261 */
262 OMPI_DECLSPEC extern ompi_predefined_op_t ompi_mpi_op_replace;
263
264
265 /**
266 * Table for Fortran <-> C op handle conversion
267 */
268 extern struct opal_pointer_array_t *ompi_op_f_to_c_table;
269
270 /**
271 * Initialize the op interface.
272 *
273 * @returns OMPI_SUCCESS Upon success
274 * @returns OMPI_ERROR Otherwise
275 *
276 * Invoked from ompi_mpi_init(); sets up the op interface, creates
277 * the predefined MPI operations, and creates the corresopnding F2C
278 * translation table.
279 */
280 int ompi_op_init(void);
281
282 /**
283 * Finalize the op interface.
284 *
285 * @returns OMPI_SUCCESS Always
286 *
287 * Invokes from ompi_mpi_finalize(); tears down the op interface, and
288 * destroys the F2C translation table.
289 */
290 int ompi_op_finalize(void);
291
292 /**
293 * Create a ompi_op_t with a user-defined callback (vs. creating an
294 * intrinsic ompi_op_t).
295 *
296 * @param commute Boolean indicating whether the operation is
297 * communative or not
298 * @param func Function pointer of the error handler
299 *
300 * @returns op Pointer to the ompi_op_t that will be
301 * created and returned
302 *
303 * This function is called as the back-end of all the MPI_OP_CREATE
304 * function. It creates a new ompi_op_t object, initializes it to the
305 * correct object type, and sets the callback function on it.
306 *
307 * The type of the function pointer is (arbitrarily) the fortran
308 * function handler type. Since this function has to accept 2
309 * different function pointer types (lest we have 2 different
310 * functions to create errhandlers), the fortran one was picked
311 * arbitrarily. Note that (void*) is not sufficient because at
312 * least theoretically, a sizeof(void*) may not necessarily be the
313 * same as sizeof(void(*)).
314 *
315 * NOTE: It *always* sets the "fortran" flag to false. The Fortran
316 * wrapper for MPI_OP_CREATE is expected to reset this flag to true
317 * manually.
318 */
319 ompi_op_t *ompi_op_create_user(bool commute,
320 ompi_op_fortran_handler_fn_t func);
321
322 /**
323 * Mark an MPI_Op as holding a C++ callback function, and cache
324 * that function in the MPI_Op. See a lenghty comment in
325 * ompi/mpi/cxx/op.c::ompi_mpi_cxx_op_intercept() for a full
326 * expalantion.
327 */
328 OMPI_DECLSPEC void ompi_op_set_cxx_callback(ompi_op_t * op,
329 MPI_User_function * fn);
330
331 /**
332 * Check to see if an op is intrinsic.
333 *
334 * @param op The op to check
335 *
336 * @returns true If the op is intrinsic
337 * @returns false If the op is not intrinsic
338 *
339 * Self-explanitory. This is needed in a few top-level MPI functions;
340 * this function is provided to hide the internal structure field
341 * names.
342 */
343 static inline bool ompi_op_is_intrinsic(ompi_op_t * op)
344 {
345 return (bool) (0 != (op->o_flags & OMPI_OP_FLAGS_INTRINSIC));
346 }
347
348
349 /**
350 * Check to see if an op is communative or not
351 *
352 * @param op The op to check
353 *
354 * @returns true If the op is communative
355 * @returns false If the op is not communative
356 *
357 * Self-explanitory. This is needed in a few top-level MPI functions;
358 * this function is provided to hide the internal structure field
359 * names.
360 */
361 static inline bool ompi_op_is_commute(ompi_op_t * op)
362 {
363 return (bool) (0 != (op->o_flags & OMPI_OP_FLAGS_COMMUTE));
364 }
365
366 /**
367 * Check to see if an op is floating point associative or not
368 *
369 * @param op The op to check
370 *
371 * @returns true If the op is floating point associative
372 * @returns false If the op is not floating point associative
373 *
374 * Self-explanitory. This is needed in a few top-level MPI functions;
375 * this function is provided to hide the internal structure field
376 * names.
377 */
378 static inline bool ompi_op_is_float_assoc(ompi_op_t * op)
379 {
380 return (bool) (0 != (op->o_flags & OMPI_OP_FLAGS_FLOAT_ASSOC));
381 }
382
383
384 /**
385 * Check to see if an op is valid on a given datatype
386 *
387 * @param op The op to check
388 * @param ddt The datatype to check
389 *
390 * @returns true If the op is valid on that datatype
391 * @returns false If the op is not valid on that datatype
392 *
393 * Self-explanitory. This is needed in a few top-level MPI functions;
394 * this function is provided to hide the internal structure field
395 * names.
396 */
397 static inline bool ompi_op_is_valid(ompi_op_t * op, ompi_datatype_t * ddt,
398 char **msg, const char *func)
399 {
400 /* Check:
401 - non-intrinsic ddt's cannot be invoked on intrinsic op's
402 - if intrinsic ddt invoked on intrinsic op:
403 - ensure the datatype is defined in the op map
404 - ensure we have a function pointer for that combination
405 */
406
407 if (ompi_op_is_intrinsic(op)) {
408 if (ompi_datatype_is_predefined(ddt)) {
409 /* Intrinsic ddt on intrinsic op */
410 if (-1 == ompi_op_ddt_map[ddt->id] ||
411 NULL == op->o_func.intrinsic.fns[ompi_op_ddt_map[ddt->id]]) {
412 asprintf(msg,
413 "%s: the reduction operation %s is not defined on the %s datatype",
414 func, op->o_name, ddt->name);
415 return false;
416 }
417 } else {
418 /* Non-intrinsic ddt on intrinsic op */
419 if ('\0' != ddt->name[0]) {
420 asprintf(msg,
421 "%s: the reduction operation %s is not defined for non-intrinsic datatypes (attempted with datatype named \"%s\")",
422 func, op->o_name, ddt->name);
423 } else {
424 asprintf(msg,
425 "%s: the reduction operation %s is not defined for non-intrinsic datatypes",
426 func, op->o_name);
427 }
428 return false;
429 }
430 }
431
432 /* All other cases ok */
433 return true;
434 }
435
436
437 /**
438 * Perform a reduction operation.
439 *
440 * @param op The operation (IN)
441 * @param source Source (input) buffer (IN)
442 * @param target Target (output) buffer (IN/OUT)
443 * @param count Number of elements (IN)
444 * @param dtype MPI datatype (IN)
445 *
446 * @returns void As with MPI user-defined reduction functions, there
447 * is no return code from this function.
448 *
449 * Perform a reduction operation with count elements of type dtype in
450 * the buffers source and target. The target buffer obtains the
451 * result (i.e., the original values in the target buffer are reduced
452 * with the values in the source buffer and the result is stored in
453 * the target buffer).
454 *
455 * This function figures out which reduction operation function to
456 * invoke and whether to invoke it with C- or Fortran-style invocation
457 * methods. If the op is intrinsic and has the operation defined for
458 * dtype, the appropriate back-end function will be invoked.
459 * Otherwise, the op is assumed to be a user op and the first function
460 * pointer in the op array will be used.
461 *
462 * NOTE: This function assumes that a correct combination will be
463 * given to it; it makes no provision for errors (in the name of
464 * optimization). If you give it an intrinsic op with a datatype that
465 * is not defined to have that operation, it is likely to seg fault.
466 */
467 static inline void ompi_op_reduce(ompi_op_t * op, void *source,
468 void *target, int count,
469 ompi_datatype_t * dtype)
470 {
471 MPI_Fint f_dtype, f_count;
472
473 /*
474 * Call the reduction function. Two dimensions: a) if both the op
475 * and the datatype are intrinsic, we have a series of predefined
476 * functions for each datatype (that are *only* in C -- not
477 * Fortran or C++!), or b) the op is user-defined, and therefore
478 * we have to check whether to invoke the callback with the C,
479 * C++, or Fortran callback signature (see lengthy description of
480 * the C++ callback in ompi/mpi/cxx/intercepts.cc).
481 *
482 * NOTE: We *assume* the following:
483 *
484 * 1. If the op is intrinsic, the op is pre-defined
485 * 2. That we will get a valid result back from the
486 * ompi_op_ddt_map[] (and not -1).
487 *
488 * Failures in these assumptions should have been caught by the
489 * upper layer (i.e., they should never have called this
490 * function). If either of these assumptions are wrong, it's
491 * likely that the MPI API function parameter checking is turned
492 * off, then it's an erroneous program and it's the user's fault.
493 * :-)
494 */
495
496 /* For intrinsics, we also pass the corresponding op module */
497 if (0 != (op->o_flags & OMPI_OP_FLAGS_INTRINSIC)) {
498 op->o_func.intrinsic.fns[ompi_op_ddt_map[dtype->id]](source, target,
499 &count, &dtype,
500 op->o_func.intrinsic.modules[ompi_op_ddt_map[dtype->id]]);
501 return;
502 }
503
504 /* User-defined function */
505 if (0 != (op->o_flags & OMPI_OP_FLAGS_FORTRAN_FUNC)) {
506 f_dtype = OMPI_INT_2_FINT(dtype->d_f_to_c_index);
507 f_count = OMPI_INT_2_FINT(count);
508 op->o_func.fort_fn(source, target, &f_count, &f_dtype);
509 return;
510 }
511 if (0 != (op->o_flags & OMPI_OP_FLAGS_CXX_FUNC)) {
512 op->o_func.cxx_data.intercept_fn(source, target, &count, &dtype,
513 op->o_func.cxx_data.user_fn);
514 return;
515 }
516 op->o_func.c_fn(source, target, &count, &dtype);
517 return;
518 }
519
520 /**
521 * Perform a reduction operation.
522 *
523 * @param op The operation (IN)
524 * @param source Source1 (input) buffer (IN)
525 * @param source Source2 (input) buffer (IN)
526 * @param target Target (output) buffer (IN/OUT)
527 * @param count Number of elements (IN)
528 * @param dtype MPI datatype (IN)
529 *
530 * @returns void As with MPI user-defined reduction functions, there
531 * is no return code from this function.
532 *
533 * Perform a reduction operation with count elements of type dtype in
534 * the buffers source and target. The target buffer obtains the
535 * result (i.e., the original values in the target buffer are reduced
536 * with the values in the source buffer and the result is stored in
537 * the target buffer).
538 *
539 * This function will *only* be invoked on intrinsic MPI_Ops.
540 *
541 * Otherwise, this function is the same as ompi_op_reduce.
542 */
543 static inline void ompi_3buff_op_reduce(ompi_op_t * op, void *source1,
544 void *source2, void *target,
545 int count, ompi_datatype_t * dtype)
546 {
547 void *restrict src1;
548 void *restrict src2;
549 void *restrict tgt;
550 src1 = source1;
551 src2 = source2;
552 tgt = target;
553
554 op->o_3buff_intrinsic.fns[ompi_op_ddt_map[dtype->id]](src1, src2,
555 tgt, &count,
556 &dtype,
557 op->o_3buff_intrinsic.modules[ompi_op_ddt_map[dtype->id]]);
558 }
559
560 END_C_DECLS
561
562 #endif /* OMPI_OP_H */
ompi_op_t::o_f_to_c_index
int o_f_to_c_index
Index in Fortran <-> C translation array.
Definition: op.h:111
ompi_op_base_op_3buff_fns_1_0_0_t
Struct that is used in op.h to hold all the function pointers and pointers to the corresopnding modul...
Definition: op.h:400
ompi_op_t::o_flags
uint32_t o_flags
Flags about the op.
Definition: op.h:108
ompi_op_f_to_c_table
struct opal_pointer_array_t * ompi_op_f_to_c_table
Table for Fortran <-> C op handle conversion.
Definition: op.c:34
ompi_op_is_intrinsic
static bool ompi_op_is_intrinsic(ompi_op_t *op)
Check to see if an op is intrinsic.
Definition: op.h:343
ompi_mpi_op_null
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_null
Global variable for MPI_OP_NULL.
Definition: op.c:61
opal_pointer_array_t
dynamic pointer array
Definition: opal_pointer_array.h:45
ompi_datatype_t
Definition: ompi_datatype.h:68
OBJ_CLASS_DECLARATION
OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_op_base_module_t)
Declare the module as a class, unversioned.
ompi_op_base_op_fns_1_0_0_t
Struct that is used in op.h to hold all the function pointers and pointers to the corresopnding modul...
Definition: op.h:388
OMPI_OP_FLAGS_FORTRAN_FUNC
#define OMPI_OP_FLAGS_FORTRAN_FUNC
Set if the callback function is in Fortran.
Definition: op.h:80
ompi_op_t::super
opal_object_t super
Parent class, for reference counting.
Definition: op.h:102
ompi_mpi_op_sum
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_sum
Global variable for MPI_SUM.
Definition: op.c:64
ompi_mpi_op_prod
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_prod
Global variable for MPI_PROD.
Definition: op.c:65
ompi_3buff_op_reduce
static void ompi_3buff_op_reduce(ompi_op_t *op, void *source1, void *source2, void *target, int count, ompi_datatype_t *dtype)
Perform a reduction operation.
Definition: op.h:543
ompi_op_create_user
ompi_op_t * ompi_op_create_user(bool commute, ompi_op_fortran_handler_fn_t func)
Create a ompi_op_t with a user-defined callback (vs.
Definition: op.c:260
ompi_mpi_op_min
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_min
Global variable for MPI_MIN.
Definition: op.c:63
OMPI_OP_FLAGS_FLOAT_ASSOC
#define OMPI_OP_FLAGS_FLOAT_ASSOC
Set if the callback function is associative for floating point operands (e.g., MPI_SUM will have ASSO...
Definition: op.h:92
ompi_op_t::o_name
char o_name[MPI_MAX_OBJECT_NAME]
Name, for debugging purposes.
Definition: op.h:105
ompi_op_is_commute
static bool ompi_op_is_commute(ompi_op_t *op)
Check to see if an op is communative or not.
Definition: op.h:361
ompi_mpi_op_maxloc
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_maxloc
Global variable for MPI_MAXLOC.
Definition: op.c:72
ompi_op_t::o_3buff_intrinsic
ompi_op_base_op_3buff_fns_t o_3buff_intrinsic
3-buffer functions, which is only for intrinsic ops.
Definition: op.h:140
ompi_op_t
struct ompi_op_t ompi_op_t
Convenience typedef.
Definition: op.h:146
ompi_op_t::o_func
union ompi_op_t::@129 o_func
Union holding (2-buffer functions):
ompi_mpi_op_lor
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_lor
Global variable for MPI_LOR.
Definition: op.c:68
ompi_op_is_valid
static bool ompi_op_is_valid(ompi_op_t *op, ompi_datatype_t *ddt, char **msg, const char *func)
Check to see if an op is valid on a given datatype.
Definition: op.h:397
ompi_op_cxx_handler_fn_t
void( ompi_op_cxx_handler_fn_t)(void *, void *, int *, struct ompi_datatype_t **, MPI_User_function *op)
Typedef for C++ op functions intercept (used for user-defined MPI::Ops).
Definition: op.h:70
ompi_mpi_op_land
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_land
Global variable for MPI_LAND.
Definition: op.c:66
ompi_mpi_op_minloc
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_minloc
Global variable for MPI_MINLOC.
Definition: op.c:73
OMPI_OP_FLAGS_CXX_FUNC
#define OMPI_OP_FLAGS_CXX_FUNC
Set if the callback function is in C++.
Definition: op.h:82
ompi_mpi_op_max
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_max
Global variable for MPI_MAX.
Definition: op.c:62
ompi_op_ddt_map
OMPI_DECLSPEC int ompi_op_ddt_map[OMPI_DATATYPE_MAX_PREDEFINED]
Array to map ddt->id values to the corresponding position in the op function array.
Definition: op.c:79
ompi_predefined_op_t
Definition: op.h:156
ompi_mpi_op_lxor
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_lxor
Global variable for MPI_LXOR.
Definition: op.c:70
ompi_datatype_t::name
char name[MPI_MAX_OBJECT_NAME]
Externally visible name.
Definition: ompi_datatype.h:79
ompi_mpi_op_replace
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_replace
Global variable for MPI_REPLACE.
Definition: op.c:74
ompi_op_init
int ompi_op_init(void)
Initialize the op interface.
Definition: op.c:91
opal_object_t
Base object.
Definition: opal_object.h:182
ompi_op_is_float_assoc
static bool ompi_op_is_float_assoc(ompi_op_t *op)
Check to see if an op is floating point associative or not.
Definition: op.h:378
ompi_mpi_op_band
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_band
Global variable for MPI_BAND.
Definition: op.c:67
PREDEFINED_OP_PAD
#define PREDEFINED_OP_PAD
Padded struct to maintain back compatibiltiy.
Definition: op.h:154
ompi_op_reduce
static void ompi_op_reduce(ompi_op_t *op, void *source, void *target, int count, ompi_datatype_t *dtype)
Perform a reduction operation.
Definition: op.h:467
ompi_op_t::cxx_data
struct ompi_op_t::@129::@130 cxx_data
C++ intercept function data – see lengthy comment in ompi/mpi/cxx/intercepts.cc::ompi_mpi_cxx_op_int...
ompi_op_t::fort_fn
ompi_op_fortran_handler_fn_t * fort_fn
Fortran handler function pointer.
Definition: op.h:126
OMPI_OP_FLAGS_INTRINSIC
#define OMPI_OP_FLAGS_INTRINSIC
Set if the MPI_Op is a built-in operation.
Definition: op.h:78
OMPI_OP_FLAGS_COMMUTE
#define OMPI_OP_FLAGS_COMMUTE
Set if the callback function is communative.
Definition: op.h:94
ompi_datatype_t::d_f_to_c_index
int32_t d_f_to_c_index
Fortran index for this datatype.
Definition: ompi_datatype.h:73
ompi_datatype_t::id
int32_t id
OMPI-layers unique id of the type.
Definition: ompi_datatype.h:72
ompi_mpi_op_bor
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_bor
Global variable for MPI_BOR.
Definition: op.c:69
ompi_mpi_op_bxor
OMPI_DECLSPEC ompi_predefined_op_t ompi_mpi_op_bxor
Global variable for MPI_BXOR.
Definition: op.c:71
ompi_op_c_handler_fn_t
BEGIN_C_DECLS typedef void() ompi_op_c_handler_fn_t(void *, void *, int *, struct ompi_datatype_t **)
Typedef for C op functions for user-defined MPI_Ops.
ompi_op_fortran_handler_fn_t
void( ompi_op_fortran_handler_fn_t)(void *, void *, MPI_Fint *, MPI_Fint *)
Typedef for fortran user-defined MPI_Ops.
Definition: op.h:59
opal_object.h
A simple C-language object-oriented system with single inheritance and ownership-based memory managem...
ompi_op_set_cxx_callback
OMPI_DECLSPEC void ompi_op_set_cxx_callback(ompi_op_t *op, MPI_User_function *fn)
Mark an MPI_Op as holding a C++ callback function, and cache that function in the MPI_Op...
Definition: op.c:307
ompi_op_t
Back-end type of MPI_Op.
Definition: op.h:100
ompi_op_t::intrinsic
ompi_op_base_op_fns_t intrinsic
Function/module pointers for intrinsic ops.
Definition: op.h:122
op.h
MPI_Op back-end operation framework.
ompi_op_finalize
int ompi_op_finalize(void)
Finalize the op interface.
Definition: op.c:229
ompi_op_t::c_fn
ompi_op_c_handler_fn_t * c_fn
C handler function pointer.
Definition: op.h:124