|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifndef MPIR_OP_H_INCLUDED
|
|
Packit Service |
c5cf8c |
#define MPIR_OP_H_INCLUDED
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*E
|
|
Packit Service |
c5cf8c |
MPIR_Op_kind - Enumerates types of MPI_Op types
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
These are needed for implementing 'MPI_Accumulate', since only predefined
|
|
Packit Service |
c5cf8c |
operations are allowed for that operation.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
A gap in the enum values was made allow additional predefined operations
|
|
Packit Service |
c5cf8c |
to be inserted. This might include future additions to MPI or experimental
|
|
Packit Service |
c5cf8c |
extensions (such as a Read-Modify-Write operation).
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Module:
|
|
Packit Service |
c5cf8c |
Collective-DS
|
|
Packit Service |
c5cf8c |
E*/
|
|
Packit Service |
c5cf8c |
typedef enum MPIR_Op_kind {
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__NULL = 0,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__MAX = 1,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__MIN = 2,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__SUM = 3,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__PROD = 4,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__LAND = 5,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__BAND = 6,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__LOR = 7,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__BOR = 8,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__LXOR = 9,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__BXOR = 10,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__MAXLOC = 11,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__MINLOC = 12,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__REPLACE = 13,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__NO_OP = 14,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__USER_NONCOMMUTE = 32,
|
|
Packit Service |
c5cf8c |
MPIR_OP_KIND__USER = 33
|
|
Packit Service |
c5cf8c |
} MPIR_Op_kind;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*S
|
|
Packit Service |
c5cf8c |
MPIR_User_function - Definition of a user function for MPI_Op types.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
This includes a 'const' to make clear which is the 'in' argument and
|
|
Packit Service |
c5cf8c |
which the 'inout' argument, and to indicate that the 'count' and 'datatype'
|
|
Packit Service |
c5cf8c |
arguments are unchanged (they are addresses in an attempt to allow
|
|
Packit Service |
c5cf8c |
interoperation with Fortran). It includes 'restrict' to emphasize that
|
|
Packit Service |
c5cf8c |
no overlapping operations are allowed.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
We need to include a Fortran version, since those arguments will
|
|
Packit Service |
c5cf8c |
have type 'MPI_Fint *' instead. We also need to add a test to the
|
|
Packit Service |
c5cf8c |
test suite for this case; in fact, we need tests for each of the handle
|
|
Packit Service |
c5cf8c |
types to ensure that the transfered handle works correctly.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
This is part of the collective module because user-defined operations
|
|
Packit Service |
c5cf8c |
are valid only for the collective computation routines and not for
|
|
Packit Service |
c5cf8c |
RMA accumulate.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Yes, the 'restrict' is in the correct location. C compilers that
|
|
Packit Service |
c5cf8c |
support 'restrict' should be able to generate code that is as good as a
|
|
Packit Service |
c5cf8c |
Fortran compiler would for these functions.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
We should note on the manual pages for user-defined operations that
|
|
Packit Service |
c5cf8c |
'restrict' should be used when available, and that a cast may be
|
|
Packit Service |
c5cf8c |
required when passing such a function to 'MPI_Op_create'.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Question:
|
|
Packit Service |
c5cf8c |
Should each of these function types have an associated typedef?
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Should there be a C++ function here?
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Module:
|
|
Packit Service |
c5cf8c |
Collective-DS
|
|
Packit Service |
c5cf8c |
S*/
|
|
Packit Service |
c5cf8c |
typedef union MPIR_User_function {
|
|
Packit Service |
c5cf8c |
void (*c_function) (const void *, void *, const int *, const MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void (*f77_function) (const void *, void *, const MPI_Fint *, const MPI_Fint *);
|
|
Packit Service |
c5cf8c |
} MPIR_User_function;
|
|
Packit Service |
c5cf8c |
/* FIXME: Should there be "restrict" in the definitions above, e.g.,
|
|
Packit Service |
c5cf8c |
(*c_function)(const void restrict * , void restrict *, ...)? */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*S
|
|
Packit Service |
c5cf8c |
MPIR_Op - MPI_Op structure
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
All of the predefined functions are commutative. Only user functions may
|
|
Packit Service |
c5cf8c |
be noncummutative, so there are two separate op types for commutative and
|
|
Packit Service |
c5cf8c |
non-commutative user-defined operations.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Operations do not require reference counts because there are no nonblocking
|
|
Packit Service |
c5cf8c |
operations that accept user-defined operations. Thus, there is no way that
|
|
Packit Service |
c5cf8c |
a valid program can free an 'MPI_Op' while it is in use.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Module:
|
|
Packit Service |
c5cf8c |
Collective-DS
|
|
Packit Service |
c5cf8c |
S*/
|
|
Packit Service |
c5cf8c |
typedef struct MPIR_Op {
|
|
Packit Service |
c5cf8c |
MPIR_OBJECT_HEADER; /* adds handle and ref_count fields */
|
|
Packit Service |
c5cf8c |
MPIR_Op_kind kind;
|
|
Packit Service |
c5cf8c |
MPIR_Lang_t language;
|
|
Packit Service |
c5cf8c |
MPIR_User_function function;
|
|
Packit Service |
c5cf8c |
#ifdef MPID_DEV_OP_DECL
|
|
Packit Service |
c5cf8c |
MPID_DEV_OP_DECL
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
} MPIR_Op;
|
|
Packit Service |
c5cf8c |
#define MPIR_OP_N_BUILTIN 15
|
|
Packit Service |
c5cf8c |
extern MPIR_Op MPIR_Op_builtin[MPIR_OP_N_BUILTIN];
|
|
Packit Service |
c5cf8c |
extern MPIR_Op MPIR_Op_direct[];
|
|
Packit Service |
c5cf8c |
extern MPIR_Object_alloc_t MPIR_Op_mem;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPIR_Op_ptr_add_ref(op_p_) \
|
|
Packit Service |
c5cf8c |
do { MPIR_Object_add_ref(op_p_); } while (0)
|
|
Packit Service |
c5cf8c |
#define MPIR_Op_ptr_release_ref(op_p_, inuse_) \
|
|
Packit Service |
c5cf8c |
do { MPIR_Object_release_ref(op_p_, inuse_); } while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* release and free-if-not-in-use helper */
|
|
Packit Service |
c5cf8c |
#define MPIR_Op_ptr_release(op_p_) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
int in_use_; \
|
|
Packit Service |
c5cf8c |
MPIR_Op_ptr_release_ref((op_p_), &in_use_); \
|
|
Packit Service |
c5cf8c |
if (!in_use_) { \
|
|
Packit Service |
c5cf8c |
MPIR_Handle_obj_free(&MPIR_Op_mem, (op_p_)); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
void MPIR_MAXF(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_MINF(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_SUM(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_PROD(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_LAND(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_BAND(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_LOR(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_BOR(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_LXOR(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_BXOR(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_MAXLOC(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_MINLOC(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_REPLACE(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
void MPIR_NO_OP(void *, void *, int *, MPI_Datatype *);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPIR_MAXF_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_MINF_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_SUM_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_PROD_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_LAND_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_BAND_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_LOR_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_BOR_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_LXOR_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_BXOR_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_MAXLOC_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_MINLOC_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_REPLACE_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
int MPIR_NO_OP_check_dtype(MPI_Datatype);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPIR_Op_add_ref_if_not_builtin(op) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if (HANDLE_GET_KIND(op) != HANDLE_KIND_BUILTIN) {\
|
|
Packit Service |
c5cf8c |
MPIR_Op *op_ptr = NULL; \
|
|
Packit Service |
c5cf8c |
MPIR_Op_get_ptr(op, op_ptr); \
|
|
Packit Service |
c5cf8c |
MPIR_Assert(op_ptr != NULL); \
|
|
Packit Service |
c5cf8c |
MPIR_Op_ptr_add_ref(op_ptr); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0) \
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPIR_Op_release_if_not_builtin(op) \
|
|
Packit Service |
c5cf8c |
do { \
|
|
Packit Service |
c5cf8c |
if (HANDLE_GET_KIND(op) != HANDLE_KIND_BUILTIN) {\
|
|
Packit Service |
c5cf8c |
MPIR_Op *op_ptr = NULL; \
|
|
Packit Service |
c5cf8c |
MPIR_Op_get_ptr(op, op_ptr); \
|
|
Packit Service |
c5cf8c |
MPIR_Assert(op_ptr != NULL); \
|
|
Packit Service |
c5cf8c |
MPIR_Op_ptr_release(op_ptr); \
|
|
Packit Service |
c5cf8c |
} \
|
|
Packit Service |
c5cf8c |
} while (0) \
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPIR_PREDEF_OP_COUNT 14
|
|
Packit Service |
c5cf8c |
extern MPI_User_function *MPIR_Op_table[];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
typedef int (MPIR_Op_check_dtype_fn) (MPI_Datatype);
|
|
Packit Service |
c5cf8c |
extern MPIR_Op_check_dtype_fn *MPIR_Op_check_dtype_table[];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define MPIR_OP_HDL_TO_FN(op) MPIR_Op_table[((op)&0xf)]
|
|
Packit Service |
c5cf8c |
#define MPIR_OP_HDL_TO_DTYPE_FN(op) MPIR_Op_check_dtype_table[((op)&0xf)]
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPIR_Op_commutative(MPIR_Op * op_ptr, int *commute);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPIR_Op_is_commutative(MPI_Op);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int MPIR_Op_create_impl(MPI_User_function * user_fn, int commute, MPI_Op * op);
|
|
Packit Service |
c5cf8c |
void MPIR_Op_free_impl(MPI_Op * op);
|
|
Packit Service |
c5cf8c |
#endif /* MPIR_OP_H_INCLUDED */
|