OpenMPI  0.1.1
op.h File Reference

MPI_Op back-end operation framework. More...

#include "ompi_config.h"
#include "opal/class/opal_object.h"
#include "opal/mca/mca.h"
#include "ompi/types.h"

Go to the source code of this file.

Data Structures

struct  ompi_op_base_component_1_0_0_t
 Op component interface. More...
 
struct  ompi_op_base_module_1_0_0_t
 Module struct. More...
 
struct  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 modules (so that we can properly RETAIN/RELEASE them) More...
 
struct  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 modules (so that we can properly RETAIN/RELEASE them) More...
 

Macros

#define OMPI_OP_BASE_VERSION_1_0_0
 

Typedefs

typedef struct
ompi_op_base_module_1_0_0_t 
ompi_op_base_module_t
 
typedef void(* ompi_op_base_handler_fn_1_0_0_t )(void *, void *, int *, struct ompi_datatype_t **, struct ompi_op_base_module_1_0_0_t *)
 Typedef for 2-buffer op functions. More...
 
typedef
ompi_op_base_handler_fn_1_0_0_t 
ompi_op_base_handler_fn_t
 
typedef void(* ompi_op_base_3buff_handler_fn_1_0_0_t )(void *, void *, void *, int *, struct ompi_datatype_t **, struct ompi_op_base_module_1_0_0_t *)
 
typedef
ompi_op_base_3buff_handler_fn_1_0_0_t 
ompi_op_base_3buff_handler_fn_t
 
typedef int(* ompi_op_base_component_init_query_fn_t )(bool enable_progress_threads, bool enable_mpi_threads)
 Op component initialization. More...
 
typedef struct
ompi_op_base_module_1_0_0_t *(* 
ompi_op_base_component_op_query_1_0_0_fn_t )(struct ompi_op_t *op, int *priority)
 Query whether a component is available for a specific MPI_Op. More...
 
typedef struct
ompi_op_base_component_1_0_0_t 
ompi_op_base_component_1_0_0_t
 Op component interface. More...
 
typedef struct
ompi_op_base_component_1_0_0_t 
ompi_op_base_component_t
 Per guidence in mca.h, use the unversioned struct name if you just want to always keep up with the most recent version of the interace. More...
 
typedef int(* ompi_op_base_module_enable_1_0_0_fn_t )(struct ompi_op_base_module_1_0_0_t *module, struct ompi_op_t *op)
 Module initialization function. More...
 
typedef struct
ompi_op_base_module_1_0_0_t 
ompi_op_base_module_1_0_0_t
 Module struct.
 
typedef struct
ompi_op_base_op_fns_1_0_0_t 
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 modules (so that we can properly RETAIN/RELEASE them)
 
typedef ompi_op_base_op_fns_1_0_0_t ompi_op_base_op_fns_t
 
typedef struct
ompi_op_base_op_3buff_fns_1_0_0_t 
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 modules (so that we can properly RETAIN/RELEASE them)
 
typedef
ompi_op_base_op_3buff_fns_1_0_0_t 
ompi_op_base_op_3buff_fns_t
 

Enumerations

enum  {
  OMPI_OP_BASE_TYPE_INT8_T, OMPI_OP_BASE_TYPE_UINT8_T, OMPI_OP_BASE_TYPE_INT16_T, OMPI_OP_BASE_TYPE_UINT16_T,
  OMPI_OP_BASE_TYPE_INT32_T, OMPI_OP_BASE_TYPE_UINT32_T, OMPI_OP_BASE_TYPE_INT64_T, OMPI_OP_BASE_TYPE_UINT64_T,
  OMPI_OP_BASE_TYPE_INTEGER, OMPI_OP_BASE_TYPE_INTEGER1, OMPI_OP_BASE_TYPE_INTEGER2, OMPI_OP_BASE_TYPE_INTEGER4,
  OMPI_OP_BASE_TYPE_INTEGER8, OMPI_OP_BASE_TYPE_INTEGER16, OMPI_OP_BASE_TYPE_FLOAT, OMPI_OP_BASE_TYPE_DOUBLE,
  OMPI_OP_BASE_TYPE_REAL, OMPI_OP_BASE_TYPE_REAL2, OMPI_OP_BASE_TYPE_REAL4, OMPI_OP_BASE_TYPE_REAL8,
  OMPI_OP_BASE_TYPE_REAL16, OMPI_OP_BASE_TYPE_DOUBLE_PRECISION, OMPI_OP_BASE_TYPE_LONG_DOUBLE, OMPI_OP_BASE_TYPE_LOGICAL,
  OMPI_OP_BASE_TYPE_BOOL, OMPI_OP_BASE_TYPE_COMPLEX, OMPI_OP_BASE_TYPE_DOUBLE_COMPLEX, OMPI_OP_BASE_TYPE_COMPLEX8,
  OMPI_OP_BASE_TYPE_COMPLEX16, OMPI_OP_BASE_TYPE_COMPLEX32, OMPI_OP_BASE_TYPE_BYTE, OMPI_OP_BASE_TYPE_2REAL,
  OMPI_OP_BASE_TYPE_2DOUBLE_PRECISION, OMPI_OP_BASE_TYPE_2INTEGER, OMPI_OP_BASE_TYPE_FLOAT_INT, OMPI_OP_BASE_TYPE_DOUBLE_INT,
  OMPI_OP_BASE_TYPE_LONG_INT, OMPI_OP_BASE_TYPE_2INT, OMPI_OP_BASE_TYPE_SHORT_INT, OMPI_OP_BASE_TYPE_LONG_DOUBLE_INT,
  OMPI_OP_BASE_TYPE_WCHAR, OMPI_OP_BASE_TYPE_MAX
}
 Corresponding to the types that we can reduce over. More...
 
enum  {
  OMPI_OP_BASE_FORTRAN_NULL = 0, OMPI_OP_BASE_FORTRAN_MAX, OMPI_OP_BASE_FORTRAN_MIN, OMPI_OP_BASE_FORTRAN_SUM,
  OMPI_OP_BASE_FORTRAN_PROD, OMPI_OP_BASE_FORTRAN_LAND, OMPI_OP_BASE_FORTRAN_BAND, OMPI_OP_BASE_FORTRAN_LOR,
  OMPI_OP_BASE_FORTRAN_BOR, OMPI_OP_BASE_FORTRAN_LXOR, OMPI_OP_BASE_FORTRAN_BXOR, OMPI_OP_BASE_FORTRAN_MAXLOC,
  OMPI_OP_BASE_FORTRAN_MINLOC, OMPI_OP_BASE_FORTRAN_REPLACE, OMPI_OP_BASE_FORTRAN_OP_MAX
}
 Fortran handles; must be [manually set to be] equivalent to the values in mpif.h. More...
 

Functions

OMPI_DECLSPEC OBJ_CLASS_DECLARATION (ompi_op_base_module_t)
 Declare the module as a class, unversioned.
 

Detailed Description

MPI_Op back-end operation framework.

This framework allows component-izing the back-end operations of MPI_Op in order to use specialized hardware (e.g., mathematical accelerators). In short: each MPI_Op contains a table of function pointers; one for implementing the operation on each predefined datatype.

The MPI interface provides error checking and error handler invocation, but the op components provide all other functionality.

Component selection is done on a per-MPI_Op basis when each MPI_Op is created. All MPI_Ops go through the selection process, even user-defined MPI_Ops – although it is expected that most (all?) op components will only be able to handle the predefined MPI_Ops.

The general sequence of usage for the op framework is:

  1. ompi_op_base_open() is invoked during MPI_INIT to find/open all op components.
  2. ompi_op_base_find_available() is invoked during MPI_INIT to call each successfully opened op component's opc_init_query() function. All op components that return OMPI_SUCCESS are kept; all others are closed and removed from the process.
  3. ompi_op_base_op_select() is invoked during MPI_INIT for each predefined MPI_Op (e.g., MPI_SUM). This function will call each available op component's opc_op_query() function to see if this component wants to provide a module for one or more of the function pointers on this MPI_Op. Priorities are used to rank returned modules; the module with the highest priority has its function pointers set in the MPI_Op function table.

Note that a module may only have some non-NULL function pointers (i.e., for the functions that it can support). For example, some modules may only support operations on single-precision floating point datatypes. These modules would provide function pointers for these datatypes and NULL for all the rest. The op framework will mix-n-match function pointers between modules to obtain a full set of non-NULL function pointers for a given MPI_Op (note that the op base provides a complete set of functions for the MPI_Op, usually a simple C loop around the operation, such as "+=" – so even if there is no specialized op component available, there will always be a full set of MPI_Op function pointers). The op framework will OBJ_RETAIN an op module once for each function pointer where it is used on a given MPI_Op.

Note that this scheme can result in up to N different modules being used for a single MPI_Op, one per needed datatype function.

  1. Finally, during MPI_FINALIZE, ompi_op_base_close() is invoked to close all available op components.

Macro Definition Documentation

#define OMPI_OP_BASE_VERSION_1_0_0
Value:
MCA_BASE_VERSION_2_0_0, \
"op", 1, 0, 0

Typedef Documentation

Op component interface.

Component interface for the op framework. A public instance of this structure, called mca_op_[component_name]_component, must exist in any op component.

typedef int(* ompi_op_base_component_init_query_fn_t)(bool enable_progress_threads, bool enable_mpi_threads)

Op component initialization.

Initialize the given op component. This function should initialize any component-level. data. It will be called exactly once during MPI_INIT.

Note
The component framework is not lazily opened, so attempts should be made to minimze the amount of memory allocated during this function.
Parameters
[in]enable_progress_threadsTrue if the component needs to support progress threads
[in]enable_mpi_threadsTrue if the component needs to support MPI_THREAD_MULTIPLE
Return values
OMPI_SUCCESSComponent successfully initialized
OMPI_ERRORAn unspecified error occurred
typedef struct ompi_op_base_module_1_0_0_t*(* ompi_op_base_component_op_query_1_0_0_fn_t)(struct ompi_op_t *op, int *priority)

Query whether a component is available for a specific MPI_Op.

If the component is available, an object should be allocated and returned (with refcount at 1). The module will not be used for reduction operations until module_enable() is called on the module, but may be destroyed (via OBJ_RELEASE) either before or after module_enable() is called. If the module needs to release resources obtained during query(), it should do so in the module destructor.

A component may provide NULL to this function to indicate it does not wish to run or return an error during module_enable().

Parameters
[in]opThe MPI_Op being created
[out]priorityPriority setting for component on this op
Returns
An initialized module structure if the component can provide a module with the requested functionality or NULL if the component should not be used on the given communicator.

Per guidence in mca.h, use the unversioned struct name if you just want to always keep up with the most recent version of the interace.

typedef void(* ompi_op_base_handler_fn_1_0_0_t)(void *, void *, int *, struct ompi_datatype_t **, struct ompi_op_base_module_1_0_0_t *)

Typedef for 2-buffer op functions.

We don't use MPI_User_function because this would create a confusing dependency loop between this file and mpi.h. So this is repeated code, but it's better this way (and this typedef will never change, so there's not much of a maintenance worry).

typedef int(* ompi_op_base_module_enable_1_0_0_fn_t)(struct ompi_op_base_module_1_0_0_t *module, struct ompi_op_t *op)

Module initialization function.

Should return OPAL_SUCCESS if everything goes ok. This function can be NULL in the module struct if the module doesn't need to do anything between the component query function and being invoked for MPI_Op operations.

Enumeration Type Documentation

anonymous enum

Corresponding to the types that we can reduce over.

See MPI-1:4.9.2, p114-115 and MPI-2:4.15, p76-77

Enumerator
OMPI_OP_BASE_TYPE_INT8_T 

C integer: int8_t.

OMPI_OP_BASE_TYPE_UINT8_T 

C integer: uint8_t.

OMPI_OP_BASE_TYPE_INT16_T 

C integer: int16_t.

OMPI_OP_BASE_TYPE_UINT16_T 

C integer: uint16_t.

OMPI_OP_BASE_TYPE_INT32_T 

C integer: int32_t.

OMPI_OP_BASE_TYPE_UINT32_T 

C integer: uint32_t.

OMPI_OP_BASE_TYPE_INT64_T 

C integer: int64_t.

OMPI_OP_BASE_TYPE_UINT64_T 

C integer: uint64_t.

OMPI_OP_BASE_TYPE_INTEGER 

Fortran integer.

OMPI_OP_BASE_TYPE_INTEGER1 

Fortran integer*1.

OMPI_OP_BASE_TYPE_INTEGER2 

Fortran integer*2.

OMPI_OP_BASE_TYPE_INTEGER4 

Fortran integer*4.

OMPI_OP_BASE_TYPE_INTEGER8 

Fortran integer*8.

OMPI_OP_BASE_TYPE_INTEGER16 

Fortran integer*16.

OMPI_OP_BASE_TYPE_FLOAT 

Floating point: float.

OMPI_OP_BASE_TYPE_DOUBLE 

Floating point: double.

OMPI_OP_BASE_TYPE_REAL 

Floating point: real.

OMPI_OP_BASE_TYPE_REAL2 

Floating point: real*2.

OMPI_OP_BASE_TYPE_REAL4 

Floating point: real*4.

OMPI_OP_BASE_TYPE_REAL8 

Floating point: real*8.

OMPI_OP_BASE_TYPE_REAL16 

Floating point: real*16.

OMPI_OP_BASE_TYPE_DOUBLE_PRECISION 

Floating point: double precision.

OMPI_OP_BASE_TYPE_LONG_DOUBLE 

Floating point: long double.

OMPI_OP_BASE_TYPE_LOGICAL 

Logical.

OMPI_OP_BASE_TYPE_BOOL 

Bool.

OMPI_OP_BASE_TYPE_COMPLEX 

Complex.

OMPI_OP_BASE_TYPE_DOUBLE_COMPLEX 

Double complex.

OMPI_OP_BASE_TYPE_COMPLEX8 

Complex8.

OMPI_OP_BASE_TYPE_COMPLEX16 

Complex16.

OMPI_OP_BASE_TYPE_COMPLEX32 

Complex32.

OMPI_OP_BASE_TYPE_BYTE 

Byte.

OMPI_OP_BASE_TYPE_2REAL 

2 location Fortran: 2 real

OMPI_OP_BASE_TYPE_2DOUBLE_PRECISION 

2 location Fortran: 2 double precision

OMPI_OP_BASE_TYPE_2INTEGER 

2 location Fortran: 2 integer

OMPI_OP_BASE_TYPE_FLOAT_INT 

2 location C: float int

OMPI_OP_BASE_TYPE_DOUBLE_INT 

2 location C: double int

OMPI_OP_BASE_TYPE_LONG_INT 

2 location C: long int

OMPI_OP_BASE_TYPE_2INT 

2 location C: int int

OMPI_OP_BASE_TYPE_SHORT_INT 

2 location C: short int

OMPI_OP_BASE_TYPE_LONG_DOUBLE_INT 

2 location C: long double int

OMPI_OP_BASE_TYPE_WCHAR 

2 location C: wchar_t

OMPI_OP_BASE_TYPE_MAX 

Maximum type.

anonymous enum

Fortran handles; must be [manually set to be] equivalent to the values in mpif.h.

Enumerator
OMPI_OP_BASE_FORTRAN_NULL 

Corresponds to Fortran MPI_OP_NULL.

OMPI_OP_BASE_FORTRAN_MAX 

Corresponds to Fortran MPI_MAX.

OMPI_OP_BASE_FORTRAN_MIN 

Corresponds to Fortran MPI_MIN.

OMPI_OP_BASE_FORTRAN_SUM 

Corresponds to Fortran MPI_SUM.

OMPI_OP_BASE_FORTRAN_PROD 

Corresponds to Fortran MPI_PROD.

OMPI_OP_BASE_FORTRAN_LAND 

Corresponds to Fortran MPI_LAND.

OMPI_OP_BASE_FORTRAN_BAND 

Corresponds to Fortran MPI_BAND.

OMPI_OP_BASE_FORTRAN_LOR 

Corresponds to Fortran MPI_LOR.

OMPI_OP_BASE_FORTRAN_BOR 

Corresponds to Fortran MPI_BOR.

OMPI_OP_BASE_FORTRAN_LXOR 

Corresponds to Fortran MPI_LXOR.

OMPI_OP_BASE_FORTRAN_BXOR 

Corresponds to Fortran MPI_BXOR.

OMPI_OP_BASE_FORTRAN_MAXLOC 

Corresponds to Fortran MPI_MAXLOC.

OMPI_OP_BASE_FORTRAN_MINLOC 

Corresponds to Fortran MPI_MINLOC.

OMPI_OP_BASE_FORTRAN_REPLACE 

Corresponds to Fortran MPI_REPLACE.

OMPI_OP_BASE_FORTRAN_OP_MAX 

Maximum value.