Hello list, I was searching for the ability to call any predefined mpi ops on arbitrary user buffers, without any communications, espacialy collective communications. but found nothing. so I 'invented' this function to perform this. it is just a wrapper around the internal ompi_op_reduce() function from ompi/op/op.h:573. so it isn't any magic behind this.
the only thing i didn't do, is marking this function as OMPI special! maybe another prefix should be used. also there are only C bindings. Hope this is helpful for other users too. greetings Bert Wesarg
diff -urN openmpi-1.1/ompi/include/mpi.h.in openmpi-1.1-mpi_op_reduce/ompi/include/mpi.h.in --- openmpi-1.1/ompi/include/mpi.h.in 2006-05-30 22:41:47.000000000 +0200 +++ openmpi-1.1-mpi_op_reduce/ompi/include/mpi.h.in 2006-07-01 11:59:23.893437057 +0200 @@ -1230,6 +1230,8 @@ OMPI_DECLSPEC int MPI_Win_wait(MPI_Win win); OMPI_DECLSPEC double MPI_Wtick(void); OMPI_DECLSPEC double MPI_Wtime(void); +OMPI_DECLSPEC int MPI_Op_reduce(void *source, void *target, int count, + MPI_Datatype datatype, MPI_Op op); /* @@ -1738,6 +1740,8 @@ OMPI_DECLSPEC int PMPI_Win_wait(MPI_Win win); OMPI_DECLSPEC double PMPI_Wtick(void); OMPI_DECLSPEC double PMPI_Wtime(void); +OMPI_DECLSPEC int PMPI_Op_reduce(void *source, void *target, int count, + MPI_Datatype datatype, MPI_Op op); #if defined(c_plusplus) || defined(__cplusplus) } diff -urN openmpi-1.1/ompi/mca/io/romio/romio/adio/include/mpipr.h openmpi-1.1-mpi_op_reduce/ompi/mca/io/romio/romio/adio/include/mpipr.h --- openmpi-1.1/ompi/mca/io/romio/romio/adio/include/mpipr.h 2006-05-30 22:42:01.000000000 +0200 +++ openmpi-1.1-mpi_op_reduce/ompi/mca/io/romio/romio/adio/include/mpipr.h 2006-07-01 15:28:32.453154536 +0200 @@ -200,6 +200,8 @@ #define MPI_Op_create PMPI_Op_create #undef MPI_Op_free #define MPI_Op_free PMPI_Op_free +#undef MPI_Op_reduce +#define MPI_Op_reduce PMPI_Op_reduce #undef MPI_Pack #define MPI_Pack PMPI_Pack #undef MPI_Pack_size diff -urN openmpi-1.1/ompi/mpi/c/Makefile.am openmpi-1.1-mpi_op_reduce/ompi/mpi/c/Makefile.am --- openmpi-1.1/ompi/mpi/c/Makefile.am 2006-05-30 22:41:50.000000000 +0200 +++ openmpi-1.1-mpi_op_reduce/ompi/mpi/c/Makefile.am 2006-07-01 11:58:40.884442991 +0200 @@ -252,6 +252,7 @@ op_create.c \ op_f2c.c \ op_free.c \ + op_reduce.c \ open_port.c \ pack_external.c \ pack_external_size.c \ diff -urN openmpi-1.1/ompi/mpi/c/op_reduce.c openmpi-1.1-mpi_op_reduce/ompi/mpi/c/op_reduce.c --- openmpi-1.1/ompi/mpi/c/op_reduce.c 1970-01-01 01:00:00.000000000 +0100 +++ openmpi-1.1-mpi_op_reduce/ompi/mpi/c/op_reduce.c 2006-07-01 15:22:16.222229672 +0200 @@ -0,0 +1,68 @@ +/* + * 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 <stdio.h> + +#include "ompi/mpi/c/bindings.h" +#include "ompi/op/op.h" + +#if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES +#pragma weak MPI_Op_reduce = PMPI_Op_reduce +#endif + +#if OMPI_PROFILING_DEFINES +#include "ompi/mpi/c/profile/defines.h" +#endif + +static const char FUNC_NAME[] = "MPI_Op_reduce"; + + +int MPI_Op_reduce(void *source, void *target, int count, + MPI_Datatype datatype, MPI_Op op) +{ + int err = MPI_SUCCESS; + + /* Error checking */ + + if (MPI_PARAM_CHECK) { + char *msg; + OMPI_ERR_INIT_FINALIZE(FUNC_NAME); + if (MPI_OP_NULL == op) { + err = MPI_ERR_OP; + } else if (!ompi_op_is_valid(op, datatype, &msg, FUNC_NAME)) { + int ret = OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_OP, msg); + free(msg); + return ret; + } else { + OMPI_CHECK_DATATYPE_FOR_SEND(err, datatype, count); + OMPI_CHECK_USER_BUFFER(err, source, datatype, count); + OMPI_CHECK_USER_BUFFER(err, target, datatype, count); + } + OMPI_ERRHANDLER_CHECK(err, MPI_COMM_WORLD, err, FUNC_NAME); + } + + if (0 == count) { + return MPI_SUCCESS; + } + + OBJ_RETAIN(op); + ompi_op_reduce(op, source, target, count, datatype); + OBJ_RELEASE(op); + + OMPI_ERRHANDLER_RETURN(err, MPI_COMM_WORLD, MPI_ERR_INTERN, FUNC_NAME); +} diff -urN openmpi-1.1/ompi/mpi/c/profile/defines.h openmpi-1.1-mpi_op_reduce/ompi/mpi/c/profile/defines.h --- openmpi-1.1/ompi/mpi/c/profile/defines.h 2006-05-30 22:41:49.000000000 +0200 +++ openmpi-1.1-mpi_op_reduce/ompi/mpi/c/profile/defines.h 2006-07-01 16:13:39.975281511 +0200 @@ -218,6 +218,7 @@ #define MPI_Op_create PMPI_Op_create #define MPI_Op_f2c PMPI_Op_f2c #define MPI_Op_free PMPI_Op_free +#define MPI_Op_reduce PMPI_Op_reduce #define MPI_Open_port PMPI_Open_port #define MPI_Pack_external PMPI_Pack_external #define MPI_Pack_external_size PMPI_Pack_external_size diff -urN openmpi-1.1/ompi/mpi/c/profile/Makefile.am openmpi-1.1-mpi_op_reduce/ompi/mpi/c/profile/Makefile.am --- openmpi-1.1/ompi/mpi/c/profile/Makefile.am 2006-05-30 22:41:49.000000000 +0200 +++ openmpi-1.1-mpi_op_reduce/ompi/mpi/c/profile/Makefile.am 2006-07-01 12:24:31.918874731 +0200 @@ -234,6 +234,7 @@ pop_create.c \ pop_f2c.c \ pop_free.c \ + pop_reduce.c \ popen_port.c \ ppack_external.c \ ppack_external_size.c \