From 31c5077aa2783dc3ed4e07301b53150ea8078be1 Mon Sep 17 00:00:00 2001 From: Jeff Squyres Date: Tue, 13 Jul 2004 15:20:46 +0000 Subject: [PATCH] - Code review by George; fix some minor errors - Add MINLOC and MAXLOC - Add REPLACE This commit was SVN r1672. --- src/op/op_predefined.c | 103 +++++++++++++++++++++++++++++++++++++++-- src/op/op_predefined.h | 23 +++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/src/op/op_predefined.c b/src/op/op_predefined.c index 82ddd72be7..c4907c69f6 100644 --- a/src/op/op_predefined.c +++ b/src/op/op_predefined.c @@ -44,11 +44,41 @@ type *a = (type *) in; \ type *b = (type *) out; \ for (i = 0; i < *count; ++i) { \ - *(b) = current_func(*(b), *(a++)); \ + *(b) = current_func(*(b), *(a)); \ ++b; \ + ++a; \ } \ } +/* + * Since all the functions in this file are essentially identical, we + * use a macro to substitute in names and types. The core operation + * in all functions that use this macro is the same. + * + * This macro is for minloc and maxloc + */ +#define LOC_STRUCT(type_name, type1, type2) \ + typedef struct { \ + type1 v; \ + type2 k; \ + } ompi_op_predefined_##type_name##_t; + +#define LOC_FUNC(name, type_name, op) \ + void ompi_mpi_op_##name##_##type_name(void *in, void *out, int *count, \ + MPI_Datatype *dtype) \ + { \ + int i; \ + ompi_op_predefined_##type_name##_t *a = (ompi_op_predefined_##type_name##_t*) in; \ + ompi_op_predefined_##type_name##_t *b = (ompi_op_predefined_##type_name##_t*) out; \ + for (i = 0; i < *count; ++i) { \ + if (a->v op b->v) { \ + *b = *a; \ + } else if (a->v == b->v) { \ + b->k = (b->k < a->k ? b->k : a->k); \ + } \ + } \ + } + /************************************************************************* * Max *************************************************************************/ @@ -152,9 +182,11 @@ void ompi_mpi_op_prod_fortran_complex(void *in, void *out, int *count, int i; ompi_fortran_complex_t *a = (ompi_fortran_complex_t*) in; ompi_fortran_complex_t *b = (ompi_fortran_complex_t*) out; + ompi_fortran_complex_t temp; for (i = 0; i < *count; ++i) { - b->real *= a->real; - b->imag *= a->imag; + temp.real = a->real * b->real - a->imag * b->imag; + temp.imag = a->imag * b->real + a->real * b->imag; + *b = temp; } } @@ -260,3 +292,68 @@ FUNC_FUNC(bxor, fortran_integer, MPI_Fint) /* Byte */ FUNC_FUNC(bxor, byte, char) +/************************************************************************* + * Min and max location "pair" datatypes + *************************************************************************/ + +LOC_STRUCT(2real, ompi_fortran_real_t, ompi_fortran_real_t) +LOC_STRUCT(2double_precision, ompi_fortran_dblprec_t, ompi_fortran_dblprec_t) +LOC_STRUCT(2integer, ompi_fortran_integer_t, ompi_fortran_integer_t) +LOC_STRUCT(float_int, float, int) +LOC_STRUCT(double_int, double, int) +LOC_STRUCT(long_int, long, int) +LOC_STRUCT(2int, int, int) +LOC_STRUCT(short_int, short, short) +LOC_STRUCT(long_double_int, long double, int) + +/************************************************************************* + * Max location + *************************************************************************/ + +LOC_FUNC(maxloc, 2real, >) +LOC_FUNC(maxloc, 2double_precision, >) +LOC_FUNC(maxloc, 2integer, >) +LOC_FUNC(maxloc, float_int, >) +LOC_FUNC(maxloc, double_int, >) +LOC_FUNC(maxloc, long_int, >) +LOC_FUNC(maxloc, 2int, >) +LOC_FUNC(maxloc, short_int, >) +LOC_FUNC(maxloc, long_double_int, >) + +/************************************************************************* + * Min location + *************************************************************************/ + +LOC_FUNC(minloc, 2real, <) +LOC_FUNC(minloc, 2double_precision, <) +LOC_FUNC(minloc, 2integer, <) +LOC_FUNC(minloc, float_int, <) +LOC_FUNC(minloc, double_int, <) +LOC_FUNC(minloc, long_int, <) +LOC_FUNC(minloc, 2int, <) +LOC_FUNC(minloc, short_int, <) +LOC_FUNC(minloc, long_double_int, <) + +/************************************************************************* + * Replace (for MPI_ACCUMULATE) + *************************************************************************/ + +/* C integer */ +OP_FUNC(replace, int, int, =) +OP_FUNC(replace, long, long, =) +OP_FUNC(replace, short, short, =) +OP_FUNC(replace, unsigned_short, unsigned short, =) +OP_FUNC(replace, unsigned, unsigned, =) +OP_FUNC(replace, unsigned_long, unsigned long, =) +/* Fortran integer */ +OP_FUNC(replace, fortran_integer, MPI_Fint, =) +/* Floating point */ +OP_FUNC(replace, float, float, =) +OP_FUNC(replace, double, double, =) +OP_FUNC(replace, fortran_real, ompi_fortran_real_t, =) +OP_FUNC(replace, fortran_double_precision, ompi_fortran_dblprec_t, =) +OP_FUNC(replace, long_double, long double, =) +/* Complex */ +OP_FUNC(replace, fortran_complex, ompi_fortran_complex_t, =) +/* Byte */ +OP_FUNC(replace, byte, char, =) diff --git a/src/op/op_predefined.h b/src/op/op_predefined.h index a2deee261a..d493b1ba8e 100644 --- a/src/op/op_predefined.h +++ b/src/op/op_predefined.h @@ -39,6 +39,17 @@ #define OMPI_OP_HANDLER_BYTE(name) \ void ompi_mpi_op_##name##_byte OMPI_OP_PROTO +#define OMPI_OP_HANDLER_2TYPE(name) \ + void ompi_mpi_op_##name##_2real OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_2double_precision OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_2integer OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_float_int OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_double_int OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_long_int OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_2int OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_short_int OMPI_OP_PROTO; \ + void ompi_mpi_op_##name##_long_double_int OMPI_OP_PROTO + #if defined(c_plusplus) || defined(__cplusplus) extern "C" { #endif @@ -115,9 +126,21 @@ extern "C" { /** * Handler functions for MPI_MAXLOC */ + OMPI_OP_HANDLER_2TYPE(maxloc); /** * Handler functions for MPI_MINLOC */ + OMPI_OP_HANDLER_2TYPE(minloc); + +/** + * Handler functions for MPI_REPLACE (only for MPI_ACCUMULATE) + */ + OMPI_OP_HANDLER_C_INTEGER(replace); + OMPI_OP_HANDLER_FORTRAN_INTEGER(replace); + OMPI_OP_HANDLER_FLOATING_POINT(replace); + OMPI_OP_HANDLER_LOGICAL(replace); + OMPI_OP_HANDLER_COMPLEX(replace); + OMPI_OP_HANDLER_BYTE(replace); #endif /* OMPI_OP_PREDEFINED_H */