Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Open MPI User's mailing list

From: Bert Wesarg (wesarg_at_[hidden])
Date: 2006-07-01 10:53:46


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 \