566a050c23
- move files out of toplevel include/ and etc/, moving it into the sub-projects - rather than including config headers with <project>/include, have them as <project> - require all headers to be included with a project prefix, with the exception of the config headers ({opal,orte,ompi}_config.h mpi.h, and mpif.h) This commit was SVN r8985.
780 строки
22 KiB
C
780 строки
22 KiB
C
/*
|
|
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
|
* University Research and Technology
|
|
* Corporation. All rights reserved.
|
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
|
* of Tennessee Research Foundation. All rights
|
|
* reserved.
|
|
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
|
* University of Stuttgart. All rights reserved.
|
|
* Copyright (c) 2004-2005 The Regents of the University of California.
|
|
* All rights reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#include "ompi_config.h"
|
|
|
|
#include "ompi/constants.h"
|
|
#include "ompi/op/op.h"
|
|
#include "ompi/op/op_predefined.h"
|
|
#include "ompi/class/ompi_pointer_array.h"
|
|
#include "ompi/datatype/datatype_internal.h"
|
|
|
|
|
|
/*
|
|
* Table for Fortran <-> C op handle conversion
|
|
*/
|
|
ompi_pointer_array_t *ompi_op_f_to_c_table;
|
|
|
|
|
|
/*
|
|
* Create intrinsic op
|
|
*/
|
|
static int add_intrinsic(ompi_op_t *op, int fort_handle);
|
|
|
|
|
|
/*
|
|
* Class information
|
|
*/
|
|
static void ompi_op_construct(ompi_op_t *eh);
|
|
static void ompi_op_destruct(ompi_op_t *eh);
|
|
|
|
|
|
/*
|
|
* Class instance
|
|
*/
|
|
OBJ_CLASS_INSTANCE(ompi_op_t, opal_object_t,
|
|
ompi_op_construct, ompi_op_destruct);
|
|
|
|
|
|
/*
|
|
* Helpful defines, because there's soooo many names!
|
|
*
|
|
* **NOTE** These #define's are strictly ordered! A series of macros
|
|
* are built up to assemble a list of function names (or NULLs) that
|
|
* are put into the intrinsict ompi_op_t's in the middle of this
|
|
* file. The order of these function names is critical, and must be
|
|
* the same as the OMPI_OP_TYPE_* enums in op.h (i.e., the enum's
|
|
* starting with OMPI_OP_TYPE_INT -- at the time of this writing,
|
|
* this is op.h:78).
|
|
*/
|
|
|
|
/** C integer ***********************************************************/
|
|
|
|
#ifdef HAVE_LONG_LONG
|
|
#define C_INTEGER_LONG_LONG(name) \
|
|
{ ompi_mpi_op_##name##_long_long }, /* OMPI_OP_TYPE_LONG_LONG */ \
|
|
{ ompi_mpi_op_##name##_long_long_int }, /* OMPI_OP_TYPE_LONG_LONG_INT */ \
|
|
{ ompi_mpi_op_##name##_unsigned_long_long } /* OMPI_OP_TYPE_UNSIGNED_LONG_LONG */
|
|
#else
|
|
#define C_INTEGER_LONG_LONG(name) \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG_LONG */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG_LONG_INT */ \
|
|
{ NULL } /* OMPI_OP_TYPE_UNSIGNED_LONG_LONG */
|
|
#endif
|
|
|
|
#define C_INTEGER(name) \
|
|
{ ompi_mpi_op_##name##_int }, /* OMPI_OP_TYPE_INT */ \
|
|
{ ompi_mpi_op_##name##_long }, /* OMPI_OP_TYPE_LONG */ \
|
|
{ ompi_mpi_op_##name##_short }, /* OMPI_OP_TYPE_SHORT */ \
|
|
{ ompi_mpi_op_##name##_unsigned_short }, /* OMPI_OP_TYPE_UNSIGNED_SHORT */ \
|
|
{ ompi_mpi_op_##name##_unsigned }, /* OMPI_OP_TYPE_UNSIGNED */ \
|
|
{ ompi_mpi_op_##name##_unsigned_long }, /* OMPI_OP_TYPE_UNSIGNED_LONG */ \
|
|
C_INTEGER_LONG_LONG(name)
|
|
#define C_INTEGER_NULL \
|
|
{ NULL }, /* OMPI_OP_TYPE_INT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_SHORT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_UNSIGNED_SHORT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_UNSIGNED */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_UNSIGNED_LONG */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG_LONG */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG_LONG_ING */ \
|
|
{ NULL } /* OMPI_OP_TYPE_UNSIGNED_LONG_LONG */
|
|
|
|
/** All the Fortran integers ********************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_INTEGER
|
|
#define FORTRAN_INTEGER_PLAIN(name) { ompi_mpi_op_##name##_fortran_integer }
|
|
#else
|
|
#define FORTRAN_INTEGER_PLAIN(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER1
|
|
#define FORTRAN_INTEGER1(name) { ompi_mpi_op_##name##_fortran_integer1 }
|
|
#else
|
|
#define FORTRAN_INTEGER1(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER2
|
|
#define FORTRAN_INTEGER2(name) { ompi_mpi_op_##name##_fortran_integer2 }
|
|
#else
|
|
#define FORTRAN_INTEGER2(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER4
|
|
#define FORTRAN_INTEGER4(name) { ompi_mpi_op_##name##_fortran_integer4 }
|
|
#else
|
|
#define FORTRAN_INTEGER4(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER8
|
|
#define FORTRAN_INTEGER8(name) { ompi_mpi_op_##name##_fortran_integer8 }
|
|
#else
|
|
#define FORTRAN_INTEGER8(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER16
|
|
#define FORTRAN_INTEGER16(name) { ompi_mpi_op_##name##_fortran_integer16 }
|
|
#else
|
|
#define FORTRAN_INTEGER16(name) { NULL }
|
|
#endif
|
|
#define FORTRAN_INTEGER(name) \
|
|
FORTRAN_INTEGER_PLAIN(name), /* OMPI_OP_TYPE_INTEGER */ \
|
|
FORTRAN_INTEGER1(name), /* OMPI_OP_TYPE_INTEGER1 */ \
|
|
FORTRAN_INTEGER2(name), /* OMPI_OP_TYPE_INTEGER2 */ \
|
|
FORTRAN_INTEGER4(name), /* OMPI_OP_TYPE_INTEGER4 */ \
|
|
FORTRAN_INTEGER8(name), /* OMPI_OP_TYPE_INTEGER8 */ \
|
|
FORTRAN_INTEGER16(name) /* OMPI_OP_TYPE_INTEGER16 */
|
|
#define FORTRAN_INTEGER_NULL \
|
|
{ NULL }, /* OMPI_OP_TYPE_INTEGER */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_INTEGER1 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_INTEGER2 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_INTEGER4 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_INTEGER8 */ \
|
|
{ NULL } /* OMPI_OP_TYPE_INTEGER16 */
|
|
|
|
/** All the Fortran reals ***********************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_REAL
|
|
#define FLOATING_POINT_FORTRAN_REAL_PLAIN(name) { ompi_mpi_op_##name##_fortran_real }
|
|
#else
|
|
#define FLOATING_POINT_FORTRAN_REAL_PLAIN(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL4
|
|
#define FLOATING_POINT_FORTRAN_REAL4(name) { ompi_mpi_op_##name##_fortran_real4 }
|
|
#else
|
|
#define FLOATING_POINT_FORTRAN_REAL4(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL8
|
|
#define FLOATING_POINT_FORTRAN_REAL8(name) { ompi_mpi_op_##name##_fortran_real8 }
|
|
#else
|
|
#define FLOATING_POINT_FORTRAN_REAL8(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL16
|
|
#define FLOATING_POINT_FORTRAN_REAL16(name) { ompi_mpi_op_##name##_fortran_real16 }
|
|
#else
|
|
#define FLOATING_POINT_FORTRAN_REAL16(name) { NULL }
|
|
#endif
|
|
|
|
#define FLOATING_POINT_FORTRAN_REAL(name) \
|
|
FLOATING_POINT_FORTRAN_REAL_PLAIN(name), /* OMPI_OP_TYPE_REAL */ \
|
|
FLOATING_POINT_FORTRAN_REAL4(name), /* OMPI_OP_TYPE_REAL4 */ \
|
|
FLOATING_POINT_FORTRAN_REAL8(name), /* OMPI_OP_TYPE_REAL8 */ \
|
|
FLOATING_POINT_FORTRAN_REAL16(name) /* OMPI_OP_TYPE_REAL16 */
|
|
|
|
/** Fortran double precision ********************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_DOUBLE_PRECISION
|
|
#define FLOATING_POINT_FORTRAN_DOUBLE_PRECISION(name) \
|
|
{ ompi_mpi_op_##name##_fortran_double_precision }
|
|
#else
|
|
#define FLOATING_POINT_FORTRAN_DOUBLE_PRECISION(name) { NULL }
|
|
#endif
|
|
|
|
/** Floating point, including all the Fortran reals *********************/
|
|
|
|
#define FLOATING_POINT(name) \
|
|
{ ompi_mpi_op_##name##_float }, /* OMPI_OP_TYPE_FLOAT */\
|
|
{ ompi_mpi_op_##name##_double }, /* OMPI_OP_TYPE_DOUBLE */\
|
|
FLOATING_POINT_FORTRAN_REAL(name), /* OMPI_OP_TYPE_REAL */ \
|
|
FLOATING_POINT_FORTRAN_DOUBLE_PRECISION(name), /* OMPI_OP_TYPE_DOUBLE_PRECISION */ \
|
|
{ ompi_mpi_op_##name##_long_double } /* OMPI_OP_TYPE_LONG_DOUBLE */
|
|
#define FLOATING_POINT_NULL \
|
|
{ NULL }, /* OMPI_OP_TYPE_FLOAT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_DOUBLE */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_REAL */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_REAL4 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_REAL8 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_REAL16 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_DOUBLE_PRECISION */ \
|
|
{ NULL } /* OMPI_OP_TYPE_LONG_DOUBLE */
|
|
|
|
/** Fortran logical *****************************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_LOGICAL
|
|
#define LOGICAL(name) \
|
|
{ ompi_mpi_op_##name##_fortran_logical } /* OMPI_OP_TYPE_LOGICAL */
|
|
#else
|
|
#define LOGICAL(name) { NULL }
|
|
#endif
|
|
#define LOGICAL_NULL \
|
|
{ NULL } /* OMPI_OP_TYPE_LOGICAL */
|
|
|
|
/** Fortran complex *****************************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_REAL && OMPI_HAVE_FORTRAN_COMPLEX
|
|
#define COMPLEX_PLAIN(name) { ompi_mpi_op_##name##_fortran_complex }
|
|
#else
|
|
#define COMPLEX_PLAIN(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_DOUBLE_PRECISION && OMPI_HAVE_FORTRAN_COMPLEX
|
|
#define COMPLEX_DOUBLE(name) { ompi_mpi_op_##name##_fortran_double_complex }
|
|
#else
|
|
#define COMPLEX_DOUBLE(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL4 && OMPI_HAVE_FORTRAN_COMPLEX8
|
|
#define COMPLEX8(name) { ompi_mpi_op_##name##_fortran_complex8 }
|
|
#else
|
|
#define COMPLEX8(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL8 && OMPI_HAVE_FORTRAN_COMPLEX16
|
|
#define COMPLEX16(name) { ompi_mpi_op_##name##_fortran_complex16 }
|
|
#else
|
|
#define COMPLEX16(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_REAL16 && OMPI_HAVE_FORTRAN_COMPLEX32
|
|
#define COMPLEX32(name) { ompi_mpi_op_##name##_fortran_complex32 }
|
|
#else
|
|
#define COMPLEX32(name) { NULL }
|
|
#endif
|
|
|
|
#define COMPLEX(name) \
|
|
COMPLEX_PLAIN(name), /* OMPI_OP_TYPE_COMPLEX */ \
|
|
COMPLEX_DOUBLE(name), /* OMPI_OP_TYPE_DOUBLE_COMPLEX */ \
|
|
COMPLEX8(name), /* OMPI_OP_TYPE_COMPLEX8 */ \
|
|
COMPLEX16(name), /* OMPI_OP_TYPE_COMPLEX16 */ \
|
|
COMPLEX32(name) /* OMPI_OP_TYPE_COMPLEX32 */
|
|
#define COMPLEX_NULL \
|
|
{ NULL }, /* OMPI_OP_TYPE_COMPLEX */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_DOUBLE_COMPLEX */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_COMPLEX8 */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_COMPLEX16 */ \
|
|
{ NULL } /* OMPI_OP_TYPE_COMPLEX32 */
|
|
|
|
/** Byte ****************************************************************/
|
|
|
|
#define BYTE(name) \
|
|
{ ompi_mpi_op_##name##_byte } /* OMPI_OP_TYPE_BYTE */
|
|
#define BYTE_NULL \
|
|
{ NULL } /* OMPI_OP_TYPE_BYTE */
|
|
|
|
/** Fortran complex *****************************************************/
|
|
/** Fortran "2" types ***************************************************/
|
|
|
|
#if OMPI_HAVE_FORTRAN_REAL
|
|
#define TWOLOC_FORTRAN_2REAL(name) { ompi_mpi_op_##name##_2real }
|
|
#else
|
|
#define TWOLOC_FORTRAN_2REAL(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_DOUBLE_PRECISION
|
|
#define TWOLOC_FORTRAN_2DOUBLE_PRECISION(name) { ompi_mpi_op_##name##_2double_precision }
|
|
#else
|
|
#define TWOLOC_FORTRAN_2DOUBLE_PRECISION(name) { NULL }
|
|
#endif
|
|
#if OMPI_HAVE_FORTRAN_INTEGER
|
|
#define TWOLOC_FORTRAN_2INTEGER(name) { ompi_mpi_op_##name##_2integer }
|
|
#else
|
|
#define TWOLOC_FORTRAN_2INTEGER(name) { NULL }
|
|
#endif
|
|
|
|
/** All "2" types *******************************************************/
|
|
|
|
#define TWOLOC(name) \
|
|
TWOLOC_FORTRAN_2REAL(name), /* OMPI_OP_TYPE_2REAL */ \
|
|
TWOLOC_FORTRAN_2DOUBLE_PRECISION(name), /* OMPI_OP_TYPE_2DOUBLE_PRECISION */ \
|
|
TWOLOC_FORTRAN_2INTEGER(name), /* OMPI_OP_TYPE_2INTEGER */ \
|
|
{ ompi_mpi_op_##name##_float_int }, /* OMPI_OP_TYPE_FLOAT_INT */ \
|
|
{ ompi_mpi_op_##name##_double_int }, /* OMPI_OP_TYPE_DOUBLE_INT */ \
|
|
{ ompi_mpi_op_##name##_long_int }, /* OMPI_OP_TYPE_LONG_INT */ \
|
|
{ ompi_mpi_op_##name##_2int }, /* OMPI_OP_TYPE_2INT */ \
|
|
{ ompi_mpi_op_##name##_short_int }, /* OMPI_OP_TYPE_SHORT_INT */ \
|
|
{ ompi_mpi_op_##name##_long_double_int } /* OMPI_OP_TYPE_LONG_DOUBLE_INT */
|
|
#define TWOLOC_NULL \
|
|
{ NULL }, /* OMPI_OP_TYPE_2REAL */\
|
|
{ NULL }, /* OMPI_OP_TYPE_2DOUBLE_PRECISION */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_2INTEGER */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_FLOAT_INT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_DOUBLE_INT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_LONG_INT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_2INT */ \
|
|
{ NULL }, /* OMPI_OP_TYPE_SHORT_INT */ \
|
|
{ NULL } /* OMPI_OP_TYPE_LONG_DOUBLE_INT */
|
|
|
|
|
|
/*
|
|
* MPI_OP_NULL
|
|
* All types
|
|
*/
|
|
#define FLAGS_NO_FLOAT \
|
|
(OMPI_OP_FLAGS_INTRINSIC | OMPI_OP_FLAGS_ASSOC | OMPI_OP_FLAGS_COMMUTE)
|
|
#define FLAGS \
|
|
(OMPI_OP_FLAGS_INTRINSIC | OMPI_OP_FLAGS_ASSOC | \
|
|
OMPI_OP_FLAGS_FLOAT_ASSOC | OMPI_OP_FLAGS_COMMUTE)
|
|
|
|
ompi_op_t ompi_mpi_op_null = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_OP_NULL",
|
|
FLAGS,
|
|
{ C_INTEGER_NULL,
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_MAX
|
|
* C integer, Fortran integer, Floating point
|
|
*/
|
|
ompi_op_t ompi_mpi_op_max = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_MAX",
|
|
FLAGS,
|
|
{ C_INTEGER(max),
|
|
FORTRAN_INTEGER(max),
|
|
FLOATING_POINT(max),
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_MIN
|
|
*/
|
|
ompi_op_t ompi_mpi_op_min = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_MIN",
|
|
FLAGS,
|
|
{ C_INTEGER(min),
|
|
FORTRAN_INTEGER(min),
|
|
FLOATING_POINT(min),
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_SUM
|
|
*/
|
|
ompi_op_t ompi_mpi_op_sum = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_SUM",
|
|
FLAGS_NO_FLOAT,
|
|
{ C_INTEGER(sum),
|
|
FORTRAN_INTEGER(sum),
|
|
FLOATING_POINT(sum),
|
|
LOGICAL_NULL,
|
|
COMPLEX(sum),
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_PROD
|
|
*/
|
|
ompi_op_t ompi_mpi_op_prod = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_PROD",
|
|
FLAGS_NO_FLOAT,
|
|
{ C_INTEGER(prod),
|
|
FORTRAN_INTEGER(prod),
|
|
FLOATING_POINT(prod),
|
|
LOGICAL_NULL,
|
|
COMPLEX(prod),
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_LAND
|
|
*/
|
|
ompi_op_t ompi_mpi_op_land = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_LAND",
|
|
FLAGS,
|
|
{ C_INTEGER(land),
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL(land),
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_BAND
|
|
*/
|
|
ompi_op_t ompi_mpi_op_band = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_BAND",
|
|
FLAGS,
|
|
{ C_INTEGER(band),
|
|
FORTRAN_INTEGER(band),
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE(band),
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_LOR
|
|
*/
|
|
ompi_op_t ompi_mpi_op_lor = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_LOR",
|
|
FLAGS,
|
|
{ C_INTEGER(lor),
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL(lor),
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_BOR
|
|
*/
|
|
ompi_op_t ompi_mpi_op_bor = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_BOR",
|
|
FLAGS,
|
|
{ C_INTEGER(bor),
|
|
FORTRAN_INTEGER(bor),
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE(bor),
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_LXOR
|
|
*/
|
|
ompi_op_t ompi_mpi_op_lxor = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_LXOR",
|
|
FLAGS,
|
|
{ C_INTEGER(lxor),
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL(lxor),
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_BXOR
|
|
*/
|
|
ompi_op_t ompi_mpi_op_bxor = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_BXOR",
|
|
FLAGS,
|
|
{ C_INTEGER(bxor),
|
|
FORTRAN_INTEGER(bxor),
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE(bxor),
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_MAXLOC
|
|
*/
|
|
ompi_op_t ompi_mpi_op_maxloc = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_MAXLOC",
|
|
(OMPI_OP_FLAGS_INTRINSIC | OMPI_OP_FLAGS_ASSOC | OMPI_OP_FLAGS_COMMUTE),
|
|
{ C_INTEGER_NULL,
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC(maxloc) }
|
|
};
|
|
|
|
|
|
/*
|
|
* MPI_OP_MINLOC
|
|
*/
|
|
ompi_op_t ompi_mpi_op_minloc = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_MINLOC",
|
|
FLAGS,
|
|
{ C_INTEGER_NULL,
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC(minloc) }
|
|
};
|
|
|
|
/*
|
|
* MPI_OP_REPLACE
|
|
* (MPI_ACCUMULATE is handled differently than the other reductions,
|
|
* so just zero out its function impementations here to ensure that
|
|
* users don't invoke MPI_REPLACE with any reduction operations other
|
|
* than ACCUMULATE)
|
|
*/
|
|
ompi_op_t ompi_mpi_op_replace = {
|
|
{ NULL, 0 },
|
|
|
|
"MPI_REPLACE",
|
|
FLAGS,
|
|
{ C_INTEGER_NULL,
|
|
FORTRAN_INTEGER_NULL,
|
|
FLOATING_POINT_NULL,
|
|
LOGICAL_NULL,
|
|
COMPLEX_NULL,
|
|
BYTE_NULL,
|
|
TWOLOC_NULL }
|
|
};
|
|
|
|
/*
|
|
* Map from ddt->id to position in op function pointer array
|
|
*/
|
|
int ompi_op_ddt_map[DT_MAX_PREDEFINED];
|
|
|
|
|
|
/*
|
|
* Initialize OMPI op infrastructure
|
|
*/
|
|
int ompi_op_init(void)
|
|
{
|
|
int i;
|
|
|
|
/* initialize ompi_op_f_to_c_table */
|
|
|
|
ompi_op_f_to_c_table = OBJ_NEW(ompi_pointer_array_t);
|
|
if (NULL == ompi_op_f_to_c_table){
|
|
return OMPI_ERROR;
|
|
}
|
|
|
|
/* Fill in the ddt.id->op_position map */
|
|
|
|
for (i = 0; i < DT_MAX_PREDEFINED; ++i) {
|
|
ompi_op_ddt_map[i] = -1;
|
|
}
|
|
|
|
ompi_op_ddt_map[DT_BYTE] = OMPI_OP_TYPE_BYTE;
|
|
ompi_op_ddt_map[DT_SHORT] = OMPI_OP_TYPE_SHORT;
|
|
ompi_op_ddt_map[DT_UNSIGNED_SHORT] = OMPI_OP_TYPE_UNSIGNED_SHORT;
|
|
ompi_op_ddt_map[DT_INT] = OMPI_OP_TYPE_INT;
|
|
ompi_op_ddt_map[DT_UNSIGNED_INT] = OMPI_OP_TYPE_UNSIGNED;
|
|
ompi_op_ddt_map[DT_LONG] = OMPI_OP_TYPE_LONG;
|
|
ompi_op_ddt_map[DT_UNSIGNED_LONG] = OMPI_OP_TYPE_UNSIGNED_LONG;
|
|
ompi_op_ddt_map[DT_LONG_LONG] = OMPI_OP_TYPE_LONG_LONG;
|
|
ompi_op_ddt_map[DT_LONG_LONG_INT] = OMPI_OP_TYPE_LONG_LONG_INT;
|
|
ompi_op_ddt_map[DT_UNSIGNED_LONG_LONG] = OMPI_OP_TYPE_UNSIGNED_LONG_LONG;
|
|
ompi_op_ddt_map[DT_FLOAT] = OMPI_OP_TYPE_FLOAT;
|
|
ompi_op_ddt_map[DT_DOUBLE] = OMPI_OP_TYPE_DOUBLE;
|
|
ompi_op_ddt_map[DT_LONG_DOUBLE] = OMPI_OP_TYPE_LONG_DOUBLE;
|
|
ompi_op_ddt_map[DT_COMPLEX_FLOAT] = OMPI_OP_TYPE_COMPLEX;
|
|
ompi_op_ddt_map[DT_COMPLEX_DOUBLE] = OMPI_OP_TYPE_DOUBLE_COMPLEX;
|
|
ompi_op_ddt_map[DT_LOGIC] = OMPI_OP_TYPE_LOGICAL;
|
|
ompi_op_ddt_map[DT_FLOAT_INT] = OMPI_OP_TYPE_FLOAT_INT;
|
|
ompi_op_ddt_map[DT_DOUBLE_INT] = OMPI_OP_TYPE_DOUBLE_INT;
|
|
ompi_op_ddt_map[DT_LONG_INT] = OMPI_OP_TYPE_LONG_INT;
|
|
ompi_op_ddt_map[DT_2INT] = OMPI_OP_TYPE_2INT;
|
|
ompi_op_ddt_map[DT_SHORT_INT] = OMPI_OP_TYPE_SHORT_INT;
|
|
ompi_op_ddt_map[DT_INTEGER] = OMPI_OP_TYPE_INTEGER;
|
|
ompi_op_ddt_map[DT_REAL] = OMPI_OP_TYPE_REAL;
|
|
ompi_op_ddt_map[DT_DBLPREC] = OMPI_OP_TYPE_DOUBLE_PRECISION;
|
|
ompi_op_ddt_map[DT_2REAL] = OMPI_OP_TYPE_2REAL;
|
|
ompi_op_ddt_map[DT_2DBLPREC] = OMPI_OP_TYPE_2DOUBLE_PRECISION;
|
|
ompi_op_ddt_map[DT_2INTEGER] = OMPI_OP_TYPE_2INTEGER;
|
|
ompi_op_ddt_map[DT_LONG_DOUBLE_INT] = OMPI_OP_TYPE_LONG_DOUBLE_INT;
|
|
ompi_op_ddt_map[DT_WCHAR] = OMPI_OP_TYPE_WCHAR;
|
|
|
|
/* Create the intrinsic ops */
|
|
|
|
if (add_intrinsic(&ompi_mpi_op_null, OMPI_OP_FORTRAN_NULL) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_max, OMPI_OP_FORTRAN_MAX) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_min, OMPI_OP_FORTRAN_MIN) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_sum, OMPI_OP_FORTRAN_SUM) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_prod, OMPI_OP_FORTRAN_PROD) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_land, OMPI_OP_FORTRAN_LAND) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_band, OMPI_OP_FORTRAN_BAND) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_lor, OMPI_OP_FORTRAN_LOR) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_bor, OMPI_OP_FORTRAN_BOR) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_lxor, OMPI_OP_FORTRAN_LXOR) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_bxor, OMPI_OP_FORTRAN_BXOR) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_maxloc,
|
|
OMPI_OP_FORTRAN_MAXLOC) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_minloc,
|
|
OMPI_OP_FORTRAN_MINLOC) != OMPI_SUCCESS ||
|
|
add_intrinsic(&ompi_mpi_op_replace,
|
|
OMPI_OP_FORTRAN_REPLACE) != OMPI_SUCCESS) {
|
|
return OMPI_ERROR;
|
|
}
|
|
|
|
/* All done */
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Clean up the op resources
|
|
*/
|
|
int ompi_op_finalize(void)
|
|
{
|
|
/* clean up the intrinsic ops */
|
|
|
|
OBJ_DESTRUCT(&ompi_mpi_op_minloc);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_maxloc);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_bxor);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_lxor);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_bor);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_lor);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_band);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_land);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_prod);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_sum);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_min);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_max);
|
|
OBJ_DESTRUCT(&ompi_mpi_op_null);
|
|
|
|
/* Remove op F2C table */
|
|
|
|
OBJ_RELEASE(ompi_op_f_to_c_table);
|
|
|
|
/* All done */
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Create a new MPI_Op
|
|
*/
|
|
ompi_op_t *ompi_op_create(bool commute,
|
|
ompi_op_fortran_handler_fn_t *func)
|
|
{
|
|
int i;
|
|
ompi_op_t *new_op;
|
|
|
|
/* Create a new object and ensure that it's valid */
|
|
|
|
new_op = OBJ_NEW(ompi_op_t);
|
|
if (NULL != new_op) {
|
|
if (OMPI_ERROR == new_op->o_f_to_c_index) {
|
|
OBJ_RELEASE(new_op);
|
|
new_op = NULL;
|
|
} else {
|
|
|
|
/* The new object is valid -- initialize it. If this is being
|
|
created from fortran, the fortran MPI API wrapper function
|
|
will override the o_flags field directly. We cast the
|
|
function pointer type to the fortran type arbitrarily -- it
|
|
only has to be a function pointer in order to store properly,
|
|
it doesn't matter what type it is (we'll cast it to the Right
|
|
type when we *use* it). */
|
|
|
|
new_op->o_flags = OMPI_OP_FLAGS_ASSOC;
|
|
if (commute) {
|
|
new_op->o_flags |= OMPI_OP_FLAGS_COMMUTE;
|
|
}
|
|
new_op->o_func[0].fort_fn = func;
|
|
for (i = 1; i < OMPI_OP_TYPE_MAX; ++i) {
|
|
new_op->o_func[i].fort_fn = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* All done */
|
|
|
|
return new_op;
|
|
}
|
|
|
|
|
|
void ompi_op_set_cxx_callback(ompi_op_t *op, MPI_User_function *fn)
|
|
{
|
|
op->o_flags |= OMPI_OP_FLAGS_CXX_FUNC;
|
|
op->o_func[1].c_fn = fn;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* Static functions
|
|
*
|
|
**************************************************************************/
|
|
|
|
static int add_intrinsic(ompi_op_t *op, int fort_handle)
|
|
{
|
|
/* Add the op to the table */
|
|
|
|
OBJ_CONSTRUCT(op, ompi_op_t);
|
|
if (op->o_f_to_c_index != fort_handle) {
|
|
return OMPI_ERROR;
|
|
}
|
|
|
|
/* All done */
|
|
|
|
return OMPI_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
* Op constructor
|
|
*/
|
|
static void ompi_op_construct(ompi_op_t *new_op)
|
|
{
|
|
int ret_val;
|
|
|
|
/* assign entry in fortran <-> c translation array */
|
|
|
|
ret_val = ompi_pointer_array_add(ompi_op_f_to_c_table, new_op);
|
|
new_op->o_f_to_c_index = ret_val;
|
|
}
|
|
|
|
|
|
/*
|
|
* Op destructor
|
|
*/
|
|
static void ompi_op_destruct(ompi_op_t *op)
|
|
{
|
|
/* reset the ompi_op_f_to_c_table entry - make sure that the
|
|
entry is in the table */
|
|
|
|
if (NULL!= ompi_pointer_array_get_item(ompi_op_f_to_c_table,
|
|
op->o_f_to_c_index)) {
|
|
ompi_pointer_array_set_item(ompi_op_f_to_c_table,
|
|
op->o_f_to_c_index, NULL);
|
|
}
|
|
}
|