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 \

Reply via email to