Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Welcome to simgrid::smpi::Op
authordegomme <augustin.degomme@unibas.ch>
Wed, 8 Mar 2017 13:14:21 +0000 (14:14 +0100)
committerdegomme <augustin.degomme@unibas.ch>
Wed, 8 Mar 2017 13:14:47 +0000 (14:14 +0100)
39 files changed:
include/smpi/forward.hpp
include/smpi/smpi.h
src/smpi/colls/allreduce-lr.cpp
src/smpi/colls/allreduce-mvapich-rs.cpp
src/smpi/colls/allreduce-ompi-ring-segmented.cpp
src/smpi/colls/allreduce-rab-rdb.cpp
src/smpi/colls/allreduce-rab1.cpp
src/smpi/colls/allreduce-rab2.cpp
src/smpi/colls/allreduce-rdb.cpp
src/smpi/colls/allreduce-smp-binomial-pipeline.cpp
src/smpi/colls/allreduce-smp-binomial.cpp
src/smpi/colls/allreduce-smp-rdb.cpp
src/smpi/colls/allreduce-smp-rsag-lr.cpp
src/smpi/colls/allreduce-smp-rsag-rab.cpp
src/smpi/colls/allreduce-smp-rsag.cpp
src/smpi/colls/reduce-NTSL.cpp
src/smpi/colls/reduce-arrival-pattern-aware.cpp
src/smpi/colls/reduce-binomial.cpp
src/smpi/colls/reduce-flat-tree.cpp
src/smpi/colls/reduce-mvapich-knomial.cpp
src/smpi/colls/reduce-mvapich-two-level.cpp
src/smpi/colls/reduce-ompi.cpp
src/smpi/colls/reduce-scatter-gather.cpp
src/smpi/colls/reduce_scatter-mpich.cpp
src/smpi/colls/reduce_scatter-ompi.cpp
src/smpi/colls/smpi_intel_mpi_selector.cpp
src/smpi/colls/smpi_mpich_selector.cpp
src/smpi/colls/smpi_mvapich2_selector.cpp
src/smpi/colls/smpi_openmpi_selector.cpp
src/smpi/private.h
src/smpi/smpi_base.cpp
src/smpi/smpi_f77.cpp
src/smpi/smpi_mpi_dt.cpp
src/smpi/smpi_mpi_dt_private.h
src/smpi/smpi_op.cpp [new file with mode: 0644]
src/smpi/smpi_op.hpp [new file with mode: 0644]
src/smpi/smpi_pmpi.cpp
src/smpi/smpi_request.cpp
tools/cmake/DefinePackages.cmake

index 7b81207..0586826 100644 (file)
@@ -15,6 +15,7 @@ namespace smpi {
 
 class Comm;
 class Group;
+class Op;
 class Request;
 class Topo;
 class Win;
@@ -29,6 +30,7 @@ class Dist_Graph;
 
 typedef simgrid::smpi::Comm SMPI_Comm;
 typedef simgrid::smpi::Group SMPI_Group;
+typedef simgrid::smpi::Op SMPI_Op;
 typedef simgrid::smpi::Request SMPI_Request;
 typedef simgrid::smpi::Topo SMPI_Topology;
 typedef simgrid::smpi::Win SMPI_Win;
@@ -40,6 +42,7 @@ typedef simgrid::smpi::Dist_Graph SMPI_Dist_Graph_topology;
 
 typedef struct SMPI_Comm SMPI_Comm;
 typedef struct SMPI_Group SMPI_Group;
+typedef struct SMPI_Op SMPI_Op;
 typedef struct SMPI_Request SMPI_Request;
 typedef struct SMPI_Topology SMPI_Topology;
 typedef struct SMPI_Win SMPI_Win;
index 3d2ec2b..589e956 100644 (file)
@@ -343,8 +343,7 @@ XBT_PUBLIC_DATA( const MPI_Datatype ) MPI_INTEGER16;
 #define MPI_2DOUBLE_PRECISION MPI_2DOUBLE
 
 typedef void MPI_User_function(void *invec, void *inoutvec, int *len, MPI_Datatype * datatype);
-struct s_smpi_mpi_op;
-typedef struct s_smpi_mpi_op *MPI_Op;
+typedef SMPI_Op *MPI_Op;
 
 #define MPI_OP_NULL ((MPI_Op)NULL)
 XBT_PUBLIC_DATA( MPI_Op ) MPI_MAX;
index af35d43..3148836 100644 (file)
@@ -81,7 +81,7 @@ smpi_coll_tuned_allreduce_lr(void *sbuf, void *rbuf, int rcount,
                  ((rank + size - 1) % size), tag + i, comm, &status);
 
     // compute result to rbuf+recv_offset
-    smpi_op_apply(op, (char *) sbuf + recv_offset, (char *) rbuf + recv_offset,
+    if(op!=MPI_OP_NULL) op->apply( (char *) sbuf + recv_offset, (char *) rbuf + recv_offset,
                    &count, &dtype);
   }
 
index 3bc2d5b..bf8cba4 100644 (file)
@@ -46,7 +46,7 @@ int smpi_coll_tuned_allreduce_mvapich2_rs(void *sendbuf,
     int comm_size =  comm->size();
     int rank = comm->rank();
 
-    is_commutative = smpi_op_is_commute(op);
+    is_commutative = (op==MPI_OP_NULL || op->is_commutative());
 
     /* need to allocate temporary buffer to store incoming data */
     smpi_datatype_extent(datatype, &true_lb, &true_extent);
@@ -94,7 +94,7 @@ int smpi_coll_tuned_allreduce_mvapich2_rs(void *sendbuf,
             /* do the reduction on received data. since the
                ordering is right, it doesn't matter whether
                the operation is commutative or not. */
-               smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+               if(op!=MPI_OP_NULL) op->apply( tmp_buf, recvbuf, &count, &datatype);
                 /* change the rank */
                 newrank = rank / 2;
         }
@@ -132,10 +132,10 @@ int smpi_coll_tuned_allreduce_mvapich2_rs(void *sendbuf,
 
                 if (is_commutative || (dst < rank)) {
                     /* op is commutative OR the order is already right */
-                     smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+                     if(op!=MPI_OP_NULL) op->apply( tmp_buf, recvbuf, &count, &datatype);
                 } else {
                     /* op is noncommutative and the order is not right */
-                    smpi_op_apply(op, recvbuf, tmp_buf, &count, &datatype);
+                    if(op!=MPI_OP_NULL) op->apply( recvbuf, tmp_buf, &count, &datatype);
                     /* copy result back into recvbuf */
                     mpi_errno = smpi_datatype_copy(tmp_buf, count, datatype,
                                                recvbuf, count, datatype);
@@ -202,7 +202,7 @@ int smpi_coll_tuned_allreduce_mvapich2_rs(void *sendbuf,
                 /* This algorithm is used only for predefined ops
                    and predefined ops are always commutative. */
 
-                smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+                if(op!=MPI_OP_NULL) op->apply( (char *) tmp_buf + disps[recv_idx] * extent,
                         (char *) recvbuf + disps[recv_idx] * extent,
                         &recv_cnt, &datatype);
 
index b54f501..2130db4 100644 (file)
@@ -318,7 +318,7 @@ smpi_coll_tuned_allreduce_ompi_ring_segmented(void *sbuf, void *rbuf, int count,
                          (phase * early_phase_segcount) : 
                          (phase * late_phase_segcount + split_phase));
          tmprecv = ((char*)rbuf) + (block_offset + phase_offset) * extent;
-         smpi_op_apply(op, inbuf[inbi ^ 0x1], tmprecv, &phase_count, &dtype);
+         if(op!=MPI_OP_NULL) op->apply( inbuf[inbi ^ 0x1], tmprecv, &phase_count, &dtype);
          /* send previous block to send_to */
          Request::send(tmprecv, phase_count, dtype, send_to,
                               666, comm);
@@ -344,7 +344,7 @@ smpi_coll_tuned_allreduce_ompi_ring_segmented(void *sbuf, void *rbuf, int count,
                       (phase * early_phase_segcount) : 
                       (phase * late_phase_segcount + split_phase));
       tmprecv = ((char*)rbuf) + (block_offset + phase_offset) * extent;
-      smpi_op_apply(op, inbuf[inbi], tmprecv, &phase_count, &dtype);
+      if(op!=MPI_OP_NULL) op->apply( inbuf[inbi], tmprecv, &phase_count, &dtype);
    }
 
    /* Distribution loop - variation of ring allgather */
index cbffe49..cf36d06 100644 (file)
@@ -56,7 +56,7 @@ int smpi_coll_tuned_allreduce_rab_rdb(void *sbuff, void *rbuff, int count,
       // do the reduction on received data. since the
       // ordering is right, it doesn't matter whether
       // the operation is commutative or not.
-       smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+       if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuff, &count, &dtype);
 
       // change the rank 
       newrank = rank / 2;
@@ -125,7 +125,7 @@ int smpi_coll_tuned_allreduce_rab_rdb(void *sbuff, void *rbuff, int count,
 
       // This algorithm is used only for predefined ops
       // and predefined ops are always commutative.
-      smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+      if(op!=MPI_OP_NULL) op->apply( (char *) tmp_buf + disps[recv_idx] * extent,
                         (char *) rbuff + disps[recv_idx] * extent, &recv_cnt, &dtype);
 
       // update send_idx for next iteration 
index 2171fbc..206ec1b 100644 (file)
@@ -59,7 +59,7 @@ int smpi_coll_tuned_allreduce_rab1(void *sbuff, void *rbuff,
       Request::sendrecv((char *) recv + send_idx * extent, send_cnt, dtype, dst, tag,
                    tmp_buf, recv_cnt, dtype, dst, tag, comm, &status);
 
-      smpi_op_apply(op, tmp_buf, (char *) recv + recv_idx * extent, &recv_cnt,
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *) recv + recv_idx * extent, &recv_cnt,
                      &dtype);
 
       // update send_idx for next iteration 
@@ -93,7 +93,7 @@ int smpi_coll_tuned_allreduce_rab1(void *sbuff, void *rbuff,
       Request::sendrecv((char *) rbuff + send_idx * extent, send_cnt, dtype, dst,
                    tag, tmp_buf, recv_cnt, dtype, dst, tag, comm, &status);
 
-      smpi_op_apply(op, tmp_buf, (char *) rbuff + recv_idx * extent, &recv_cnt,
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *) rbuff + recv_idx * extent, &recv_cnt,
                      &dtype);
 
       // update send_idx for next iteration 
index 02f4995..7e239e3 100644 (file)
@@ -51,7 +51,7 @@ int smpi_coll_tuned_allreduce_rab2(void *sbuff, void *rbuff,
     memcpy(tmp, recv, nbytes);
 
     for (i = 1, s_offset = nbytes; i < nprocs; i++, s_offset = i * nbytes)
-      smpi_op_apply(op, (char *) recv + s_offset, tmp, &send_size, &dtype);
+      if(op!=MPI_OP_NULL) op->apply( (char *) recv + s_offset, tmp, &send_size, &dtype);
 
     mpi_coll_allgather_fun(tmp, send_size, dtype, recv, send_size, dtype, comm);
     memcpy(rbuff, recv, count * s_extent);
@@ -72,7 +72,7 @@ int smpi_coll_tuned_allreduce_rab2(void *sbuff, void *rbuff,
     memcpy((char *) rbuff + r_offset, recv, nbytes);
 
     for (i = 1, s_offset = nbytes; i < nprocs; i++, s_offset = i * nbytes)
-      smpi_op_apply(op, (char *) recv + s_offset, (char *) rbuff + r_offset,
+      if(op!=MPI_OP_NULL) op->apply( (char *) recv + s_offset, (char *) rbuff + r_offset,
                      &send_size, &dtype);
 
     mpi_coll_allgather_fun((char *) rbuff + r_offset, send_size, dtype, rbuff, send_size,
index 994fb28..8a6dafc 100644 (file)
@@ -64,7 +64,7 @@ int smpi_coll_tuned_allreduce_rdb(void *sbuff, void *rbuff, int count,
       // do the reduction on received data. since the
       // ordering is right, it doesn't matter whether
       // the operation is commutative or not.
-      smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuff, &count, &dtype);
 
       // change the rank 
       newrank = rank / 2;
@@ -102,10 +102,10 @@ int smpi_coll_tuned_allreduce_rdb(void *sbuff, void *rbuff, int count,
       // we assume it is commuttive op
       //      if (op -> op_commute  || (dst < rank))
       if ((dst < rank)) {
-        smpi_op_apply(op, tmp_buf, rbuff, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuff, &count, &dtype);
       } else                    // op is noncommutative and the order is not right
       {
-        smpi_op_apply(op, rbuff, tmp_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( rbuff, tmp_buf, &count, &dtype);
 
         // copy result back into recvbuf
         Request::sendrecv(tmp_buf, count, dtype, rank, tag, rbuff, count,
index efc2f27..7c6ca81 100644 (file)
@@ -99,7 +99,7 @@ int smpi_coll_tuned_allreduce_smp_binomial_pipeline(void *send_buf,
           if (src < comm_size) {
             recv_offset = phase * pcount * extent;
             Request::recv(tmp_buf, pcount, dtype, src, tag, comm, &status);
-            smpi_op_apply(op, tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
+            if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
           }
         } else {
           send_offset = phase * pcount * extent;
@@ -123,7 +123,7 @@ int smpi_coll_tuned_allreduce_smp_binomial_pipeline(void *send_buf,
             if (src < comm_size) {
               recv_offset = (phase - 1) * pcount * extent;
               Request::recv(tmp_buf, pcount, dtype, src, tag, comm, &status);
-              smpi_op_apply(op, tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
+              if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *)recv_buf + recv_offset, &pcount, &dtype);
             }
           } else {
             dst = (inter_rank & (~mask)) * num_core;
index b4ec04f..764e536 100644 (file)
@@ -71,7 +71,7 @@ int smpi_coll_tuned_allreduce_smp_binomial(void *send_buf, void *recv_buf,
       src = (inter_rank * num_core) + (intra_rank | mask);
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
       }
     } else {
       dst = (inter_rank * num_core) + (intra_rank & (~mask));
@@ -90,7 +90,7 @@ int smpi_coll_tuned_allreduce_smp_binomial(void *send_buf, void *recv_buf,
         src = (inter_rank | mask) * num_core;
         if (src < comm_size) {
           Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-          smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+          if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
         }
       } else {
         dst = (inter_rank & (~mask)) * num_core;
index a330eef..94490b6 100644 (file)
@@ -78,7 +78,7 @@ int smpi_coll_tuned_allreduce_smp_rdb(void *send_buf, void *recv_buf, int count,
       src = (inter_rank * num_core) + (intra_rank | mask);
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
       }
     } else {
       dst = (inter_rank * num_core) + (intra_rank & (~mask));
@@ -115,7 +115,7 @@ int smpi_coll_tuned_allreduce_smp_rdb(void *send_buf, void *recv_buf, int count,
       } else {
         src = rank - num_core;
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
         newrank = inter_rank / 2;
       }
     } else {
@@ -141,7 +141,7 @@ int smpi_coll_tuned_allreduce_smp_rdb(void *send_buf, void *recv_buf, int count,
         /* exchange data in rdb manner */
         Request::sendrecv(recv_buf, count, dtype, dst, tag, tmp_buf, count, dtype,
                      dst, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
         mask <<= 1;
       }
     }
index 253376a..6f44f10 100644 (file)
@@ -72,7 +72,7 @@ int smpi_coll_tuned_allreduce_smp_rsag_lr(void *send_buf, void *recv_buf,
       //      if (src < ((inter_rank + 1) * num_core)) {
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
         //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
       }
     } else {
@@ -130,7 +130,7 @@ int smpi_coll_tuned_allreduce_smp_rsag_lr(void *send_buf, void *recv_buf,
                    &status);
 
       // result is in rbuf
-      smpi_op_apply(op, tmp_buf, (char *) recv_buf + recv_offset, &recv_count,
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *) recv_buf + recv_offset, &recv_count,
                      &dtype);
     }
 
index c3da378..eb1f9ec 100644 (file)
@@ -64,7 +64,7 @@ int smpi_coll_tuned_allreduce_smp_rsag_rab(void *sbuf, void *rbuf, int count,
       //      if (src < ((inter_rank + 1) * num_core)) {
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, rbuf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, &dtype);
         //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
       }
     } else {
@@ -118,7 +118,7 @@ int smpi_coll_tuned_allreduce_smp_rsag_rab(void *sbuf, void *rbuf, int count,
                    tmp_buf, curr_count, dtype, (dst * num_core), tag,
                    comm, &status);
 
-      smpi_op_apply(op, tmp_buf, (char *)rbuf + recv_offset, &curr_count, &dtype);
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *)rbuf + recv_offset, &curr_count, &dtype);
 
       mask *= 2;
       curr_count /= 2;
index 8cb4532..bee18b2 100644 (file)
@@ -71,7 +71,7 @@ int smpi_coll_tuned_allreduce_smp_rsag(void *send_buf, void *recv_buf,
       //      if (src < ((inter_rank + 1) * num_core)) {
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_buf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_buf, &count, &dtype);
         //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
       }
     } else {
@@ -111,7 +111,7 @@ int smpi_coll_tuned_allreduce_smp_rsag(void *send_buf, void *recv_buf,
                    &status);
 
       // result is in rbuf
-      smpi_op_apply(op, tmp_buf, (char *) recv_buf + recv_offset, &seg_count,
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, (char *) recv_buf + recv_offset, &seg_count,
                      &dtype);
     }
 
index c7a3e0c..64d1019 100644 (file)
@@ -72,12 +72,12 @@ int smpi_coll_tuned_reduce_NTSL(void *buf, void *rbuf, int count,
   if (count <= segment) {
     if (rank == root) {
       Request::recv(tmp_buf, count, datatype, from, tag, comm, &status);
-      smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, &datatype);
     } else if (rank == ((root - 1 + size) % size)) {
       Request::send(rbuf, count, datatype, to, tag, comm);
     } else {
       Request::recv(tmp_buf, count, datatype, from, tag, comm, &status);
-      smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+      if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, &datatype);
       Request::send(rbuf, count, datatype, to, tag, comm);
     }
     smpi_free_tmp_buffer(tmp_buf);
@@ -103,7 +103,7 @@ int smpi_coll_tuned_reduce_NTSL(void *buf, void *rbuf, int count,
       }
       for (i = 0; i < pipe_length; i++) {
         Request::wait(&recv_request_array[i], &status);
-        smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf + (i * increment), (char *)rbuf + (i * increment),
                        &segment, &datatype);
       }
     }
@@ -125,7 +125,7 @@ int smpi_coll_tuned_reduce_NTSL(void *buf, void *rbuf, int count,
       }
       for (i = 0; i < pipe_length; i++) {
         Request::wait(&recv_request_array[i], &status);
-        smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf + (i * increment), (char *)rbuf + (i * increment),
                        &segment, &datatype);
         send_request_array[i] = Request::isend((char *) rbuf + (i * increment), segment, datatype, to,
                   (tag + i), comm);
index 9778ecc..51ac468 100644 (file)
@@ -129,7 +129,7 @@ int smpi_coll_tuned_reduce_arrival_pattern_aware(void *buf, void *rbuf,
 
           Request::send(header_buf, HEADER_SIZE, MPI_INT, to, tag, comm);
           Request::recv(tmp_buf, count, datatype, from, tag, comm, &status);
-          smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+          if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, &datatype);
         }
       }                         /* while loop */
     }
@@ -180,7 +180,7 @@ int smpi_coll_tuned_reduce_arrival_pattern_aware(void *buf, void *rbuf,
         }
         from = header_buf[myordering - 1];
         Request::recv(tmp_buf, count, datatype, from, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, rbuf, &count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, &datatype);
         Request::send(rbuf, count, datatype, to, tag, comm);
       }
     }                           /* non-root */
@@ -256,7 +256,7 @@ int smpi_coll_tuned_reduce_arrival_pattern_aware(void *buf, void *rbuf,
           for (i = 0; i < pipe_length; i++) {
             Request::recv(tmp_buf + (i * increment), segment, datatype, from, tag,
                      comm, &status);
-            smpi_op_apply(op, tmp_buf + (i * increment),
+            if(op!=MPI_OP_NULL) op->apply( tmp_buf + (i * increment),
                            (char *)rbuf + (i * increment), &segment, &datatype);
           }
         }
@@ -310,7 +310,7 @@ int smpi_coll_tuned_reduce_arrival_pattern_aware(void *buf, void *rbuf,
         }
         for (i = 0; i < pipe_length; i++) {
           Request::wait(&recv_request_array[i], MPI_STATUS_IGNORE);
-          smpi_op_apply(op, tmp_buf + (i * increment), (char *)rbuf + (i * increment),
+          if(op!=MPI_OP_NULL) op->apply( tmp_buf + (i * increment), (char *)rbuf + (i * increment),
                          &segment, &datatype);
           send_request_array[i]=Request::isend((char *)rbuf + (i * increment), segment, datatype, to, tag, comm);
         }
index c35390d..bf0a078 100644 (file)
@@ -28,7 +28,7 @@ int smpi_coll_tuned_reduce_binomial(void *sendbuf, void *recvbuf, int count,
   extent = smpi_datatype_get_extent(datatype);
 
   tmp_buf = (void *) smpi_get_tmp_sendbuffer(count * extent);
-  int is_commutative = smpi_op_is_commute(op);
+  int is_commutative =  (op==MPI_OP_NULL || op->is_commutative());
   mask = 1;
   
   int lroot;
@@ -62,9 +62,9 @@ int smpi_coll_tuned_reduce_binomial(void *sendbuf, void *recvbuf, int count,
         Request::recv(tmp_buf, count, datatype, source, tag, comm, &status);
         
         if (is_commutative) {
-          smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+          if(op!=MPI_OP_NULL) op->apply( tmp_buf, recvbuf, &count, &datatype);
         } else {
-          smpi_op_apply(op, recvbuf, tmp_buf, &count, &datatype);
+          if(op!=MPI_OP_NULL) op->apply( recvbuf, tmp_buf, &count, &datatype);
           smpi_datatype_copy(tmp_buf, count, datatype,recvbuf, count, datatype);
         }
       }
index 33999ad..ebfabe4 100644 (file)
@@ -56,7 +56,7 @@ smpi_coll_tuned_reduce_flat_tree(void *sbuf, void *rbuf, int count,
     }
 
     /* Call reduction function. */
-    smpi_op_apply(op, inbuf, rbuf, &count, &dtype);
+    if(op!=MPI_OP_NULL) op->apply( inbuf, rbuf, &count, &dtype);
 
   }
 
index 837da1e..f2fc5da 100644 (file)
@@ -145,7 +145,7 @@ int smpi_coll_tuned_reduce_mvapich2_knomial (
     smpi_datatype_extent(datatype, &true_lb, &true_extent);
     extent = smpi_datatype_get_extent(datatype);
 
-    is_commutative = smpi_op_is_commute(op);
+    is_commutative =  (op==MPI_OP_NULL || op->is_commutative());
 
     if (rank != root) {
         recvbuf=(void *)smpi_get_tmp_recvbuffer(count*(MAX(extent,true_extent)));
@@ -195,7 +195,7 @@ int smpi_coll_tuned_reduce_mvapich2_knomial (
             recv_iter++;
 
             if (is_commutative) {
-              smpi_op_apply(op, tmp_buf[index], recvbuf, &count, &datatype);
+              if(op!=MPI_OP_NULL) op->apply( tmp_buf[index], recvbuf, &count, &datatype);
             }
         }
 
index 45c5cd7..8a2a44d 100644 (file)
@@ -111,7 +111,7 @@ int smpi_coll_tuned_reduce_mvapich2_two_level( void *sendbuf,
     leader_of_root = comm->group()->rank(leaders_map[root]);
     leader_root = leader_comm->group()->rank(leaders_map[root]);
 
-    is_commutative=smpi_op_is_commute(op);
+    is_commutative= (op==MPI_OP_NULL || op->is_commutative());
 
     smpi_datatype_extent(datatype, &true_lb,
                                        &true_extent);
index 100023b..5c81b0c 100644 (file)
@@ -92,7 +92,7 @@ int smpi_coll_tuned_ompi_reduce_generic( void* sendbuf, void* recvbuf, int origi
 
         /* If this is a non-commutative operation we must copy
            sendbuf to the accumbuf, in order to simplfy the loops */
-        if (!smpi_op_is_commute(op)) {
+        if ( (op!=MPI_OP_NULL && !op->is_commutative())) {
             smpi_datatype_copy(
                                                 (char*)sendtmpbuf, original_count, datatype,
                                                 (char*)accumbuf, original_count, datatype);
@@ -145,7 +145,7 @@ int smpi_coll_tuned_ompi_reduce_generic( void* sendbuf, void* recvbuf, int origi
                          * BUT if the operation is non-commutative or 
                          * we are root and are USING MPI_IN_PLACE this is wrong!
                          */
-                        if( (smpi_op_is_commute(op)) &&
+                        if(  (op==MPI_OP_NULL || op->is_commutative()) &&
                             !((MPI_IN_PLACE == sendbuf) && (rank == tree->tree_root)) ) {
                             local_recvbuf = accumbuf + segindex * segment_increment;
                         }
@@ -170,24 +170,24 @@ int smpi_coll_tuned_ompi_reduce_generic( void* sendbuf, void* recvbuf, int origi
                      * not using MPI_IN_PLACE)
                      */
                     if( 1 == i ) {
-                        if( (smpi_op_is_commute(op)) && 
+                        if( (op==MPI_OP_NULL || op->is_commutative())&& 
                             !((MPI_IN_PLACE == sendbuf) && (rank == tree->tree_root)) ) {
                             local_op_buffer = sendtmpbuf + segindex * segment_increment;
                         }
                     }
                     /* apply operation */
-                    smpi_op_apply(op, local_op_buffer, 
+                    if(op!=MPI_OP_NULL) op->apply( local_op_buffer, 
                                    accumbuf + segindex * segment_increment, 
                                    &recvcount, &datatype );
                 } else if ( segindex > 0 ) {
                     void* accumulator = accumbuf + (segindex-1) * segment_increment;
                     if( tree->tree_nextsize <= 1 ) {
-                        if( (smpi_op_is_commute(op)) &&
+                        if(  (op==MPI_OP_NULL || op->is_commutative()) &&
                             !((MPI_IN_PLACE == sendbuf) && (rank == tree->tree_root)) ) {
                             local_op_buffer = sendtmpbuf + (segindex-1) * segment_increment;
                         }
                     }
-                    smpi_op_apply(op, local_op_buffer, accumulator, &prevcount, 
+                    if(op!=MPI_OP_NULL) op->apply( local_op_buffer, accumulator, &prevcount, 
                                    &datatype );
 
                     /* all reduced on available data this step (i) complete, 
@@ -662,7 +662,7 @@ smpi_coll_tuned_reduce_ompi_basic_linear(void *sbuf, void *rbuf, int count,
         }
 
         /* Perform the reduction */
-        smpi_op_apply(op, inbuf, rbuf, &count, &dtype);
+        if(op!=MPI_OP_NULL) op->apply( inbuf, rbuf, &count, &dtype);
     }
 
     if (NULL != inplace_temp) {
index 65279e5..dbe4c18 100644 (file)
@@ -68,7 +68,7 @@ int smpi_coll_tuned_reduce_scatter_gather(void *sendbuf, void *recvbuf,
         newrank = -1;
       } else {
         Request::recv(tmp_buf, count, datatype, rank + 1, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recv_ptr, &new_count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recv_ptr, &new_count, &datatype);
         newrank = rank / 2;
       }
     } else                      /* rank >= 2*rem */
@@ -121,7 +121,7 @@ int smpi_coll_tuned_reduce_scatter_gather(void *sendbuf, void *recvbuf,
         /* tmp_buf contains data received in this step.
            recvbuf contains data accumulated so far */
 
-        smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+        if(op!=MPI_OP_NULL) op->apply( (char *) tmp_buf + disps[recv_idx] * extent,
                        (char *) recv_ptr + disps[recv_idx] * extent,
                        &recv_cnt, &datatype);
 
@@ -245,7 +245,7 @@ int smpi_coll_tuned_reduce_scatter_gather(void *sendbuf, void *recvbuf,
 
       else {
         Request::recv(tmp_buf, count, datatype, rank + 1, tag, comm, &status);
-        smpi_op_apply(op, tmp_buf, recvbuf, &count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmp_buf, recvbuf, &count, &datatype);
         newrank = rank / 2;
       }
     } else                      /* rank >= 2*rem */
@@ -298,7 +298,7 @@ int smpi_coll_tuned_reduce_scatter_gather(void *sendbuf, void *recvbuf,
         /* tmp_buf contains data received in this step.
            recvbuf contains data accumulated so far */
 
-        smpi_op_apply(op, (char *) tmp_buf + disps[recv_idx] * extent,
+        if(op!=MPI_OP_NULL) op->apply( (char *) tmp_buf + disps[recv_idx] * extent,
                        (char *) recvbuf + disps[recv_idx] * extent,
                        &recv_cnt, &datatype);
 
index 00cd986..878d311 100644 (file)
@@ -38,7 +38,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_pair(void *sendbuf, void *recvbuf, int
     extent =smpi_datatype_get_extent(datatype);
     smpi_datatype_extent(datatype, &true_lb, &true_extent);
     
-    if (smpi_op_is_commute(op)) {
+    if (op->is_commutative()) {
         is_commutative = 1;
     }
 
@@ -90,12 +90,12 @@ int smpi_coll_tuned_reduce_scatter_mpich_pair(void *sendbuf, void *recvbuf, int
             
             if (is_commutative || (src < rank)) {
                 if (sendbuf != MPI_IN_PLACE) {
-                    smpi_op_apply( op,
+                    if(op!=MPI_OP_NULL) op->apply(
                                                  tmp_recvbuf, recvbuf, &recvcounts[rank],
                                &datatype); 
                 }
                 else {
-                   smpi_op_apply(op, 
+                   if(op!=MPI_OP_NULL) op->apply( 
                        tmp_recvbuf, ((char *)recvbuf+disps[rank]*extent), 
                        &recvcounts[rank], &datatype);
                     /* we can't store the result at the beginning of
@@ -107,7 +107,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_pair(void *sendbuf, void *recvbuf, int
             }
             else {
                 if (sendbuf != MPI_IN_PLACE) {
-                   smpi_op_apply(op, 
+                   if(op!=MPI_OP_NULL) op->apply( 
                       recvbuf, tmp_recvbuf, &recvcounts[rank], &datatype);
                     /* copy result back into recvbuf */
                     mpi_errno = smpi_datatype_copy(tmp_recvbuf, recvcounts[rank],
@@ -116,7 +116,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_pair(void *sendbuf, void *recvbuf, int
                     if (mpi_errno) return(mpi_errno);
                 }
                 else {
-                   smpi_op_apply(op, 
+                   if(op!=MPI_OP_NULL) op->apply( 
                         ((char *)recvbuf+disps[rank]*extent),
                        tmp_recvbuf, &recvcounts[rank], &datatype);
                     /* copy result back into recvbuf */
@@ -232,7 +232,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_noncomm(void *sendbuf, void *recvbuf, i
            is now our peer's responsibility */
         if (rank > peer) {
             /* higher ranked value so need to call op(received_data, my_data) */
-            smpi_op_apply(op, 
+            if(op!=MPI_OP_NULL) op->apply( 
                    incoming_data + recv_offset*true_extent,
                      outgoing_data + recv_offset*true_extent,
                      &size, &datatype );
@@ -240,7 +240,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_noncomm(void *sendbuf, void *recvbuf, i
         }
         else {
             /* lower ranked value so need to call op(my_data, received_data) */
-           smpi_op_apply( op,
+           if(op!=MPI_OP_NULL) op->apply(
                     outgoing_data + recv_offset*true_extent,
                      incoming_data + recv_offset*true_extent,
                      &size, &datatype);
@@ -285,7 +285,7 @@ int smpi_coll_tuned_reduce_scatter_mpich_rdb(void *sendbuf, void *recvbuf, int r
     extent =smpi_datatype_get_extent(datatype);
     smpi_datatype_extent(datatype, &true_lb, &true_extent);
     
-    if (smpi_op_is_commute(op)) {
+    if ((op==MPI_OP_NULL) || op->is_commutative()) {
         is_commutative = 1;
     }
 
@@ -454,10 +454,10 @@ int smpi_coll_tuned_reduce_scatter_mpich_rdb(void *sendbuf, void *recvbuf, int r
                 if (received) {
                     if (is_commutative || (dst_tree_root < my_tree_root)) {
                         {
-                                smpi_op_apply(op, 
+                                if(op!=MPI_OP_NULL) op->apply( 
                                tmp_recvbuf, tmp_results, &blklens[0],
                               &datatype); 
-                               smpi_op_apply(op, 
+                               if(op!=MPI_OP_NULL) op->apply( 
                                ((char *)tmp_recvbuf + dis[1]*extent),
                               ((char *)tmp_results + dis[1]*extent),
                               &blklens[1], &datatype); 
@@ -465,10 +465,10 @@ int smpi_coll_tuned_reduce_scatter_mpich_rdb(void *sendbuf, void *recvbuf, int r
                     }
                     else {
                         {
-                                smpi_op_apply(op,
+                                if(op!=MPI_OP_NULL) op->apply(
                                    tmp_results, tmp_recvbuf, &blklens[0],
                                    &datatype); 
-                                smpi_op_apply(op,
+                                if(op!=MPI_OP_NULL) op->apply(
                                    ((char *)tmp_results + dis[1]*extent),
                                    ((char *)tmp_recvbuf + dis[1]*extent),
                                    &blklens[1], &datatype); 
index 2838220..1f37ef1 100644 (file)
@@ -62,7 +62,7 @@ smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(void *sbuf,
     size = comm->size();
    
     XBT_DEBUG("coll:tuned:reduce_scatter_ompi_basic_recursivehalving, rank %d", rank);
-    if(!smpi_op_is_commute(op))
+    if( (op!=MPI_OP_NULL && !op->is_commutative()))
       THROWF(arg_error,0, " reduce_scatter ompi_basic_recursivehalving can only be used for commutative operations! ");
 
     /* Find displacements and the like */
@@ -132,7 +132,7 @@ smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(void *sbuf,
                                     comm, MPI_STATUS_IGNORE);
          
             /* integrate their results into our temp results */
-            smpi_op_apply(op, recv_buf, result_buf, &count, &dtype);
+            if(op!=MPI_OP_NULL) op->apply( recv_buf, result_buf, &count, &dtype);
          
             /* adjust rank to be the bottom "remain" ranks */
             tmp_rank = rank / 2;
@@ -243,7 +243,7 @@ smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(void *sbuf,
             /* if we received something on this step, push it into
                the results buffer */
             if (recv_count > 0) {
-                smpi_op_apply(op, 
+                if(op!=MPI_OP_NULL) op->apply( 
                                recv_buf + (ptrdiff_t)tmp_disps[recv_index] * extent, 
                                result_buf + (ptrdiff_t)tmp_disps[recv_index] * extent,
                                &recv_count, &dtype);
@@ -482,7 +482,7 @@ smpi_coll_tuned_reduce_scatter_ompi_ring(void *sbuf, void *rbuf, int *rcounts,
            rbuf[prevblock] = inbuf[inbi ^ 0x1] (op) rbuf[prevblock]
         */
         tmprecv = accumbuf + (ptrdiff_t)displs[prevblock] * extent;
-        smpi_op_apply(op, inbuf[inbi ^ 0x1], tmprecv, &(rcounts[prevblock]), &dtype);
+        if(op!=MPI_OP_NULL) op->apply( inbuf[inbi ^ 0x1], tmprecv, &(rcounts[prevblock]), &dtype);
       
         /* send previous block to send_to */
         Request::send(tmprecv, rcounts[prevblock], dtype, send_to,
@@ -496,7 +496,7 @@ smpi_coll_tuned_reduce_scatter_ompi_ring(void *sbuf, void *rbuf, int *rcounts,
     /* Apply operation on the last block (my block)
        rbuf[rank] = inbuf[inbi] (op) rbuf[rank] */
     tmprecv = accumbuf + (ptrdiff_t)displs[rank] * extent;
-    smpi_op_apply(op, inbuf[inbi], tmprecv, &(rcounts[rank]), &dtype);
+    if(op!=MPI_OP_NULL) op->apply( inbuf[inbi], tmprecv, &(rcounts[rank]), &dtype);
    
     /* Copy result from tmprecv to rbuf */
     ret = smpi_datatype_copy(tmprecv, rcounts[rank], dtype, (char*)rbuf, rcounts[rank], dtype);
index 43138e3..ee2dfe0 100644 (file)
@@ -1069,7 +1069,7 @@ static  int  intel_reduce_scatter_recursivehalving(void *sbuf, void *rbuf,
                                                     MPI_Op  op,
                                                     MPI_Comm  comm)
 {
-  if(smpi_op_is_commute(op))
+  if(op==MPI_OP_NULL || op->is_commutative())
     return smpi_coll_tuned_reduce_scatter_ompi_basic_recursivehalving(sbuf, rbuf, rcounts,dtype, op,comm);
   else
     return smpi_coll_tuned_reduce_scatter_mvapich2(sbuf, rbuf, rcounts,dtype, op,comm);
index 7e6aa52..99c147f 100644 (file)
@@ -72,7 +72,7 @@ int smpi_coll_tuned_allreduce_mpich(void *sbuf, void *rbuf, int count,
     while (pof2 <= comm_size) pof2 <<= 1;
     pof2 >>=1;
 
-    if (block_dsize > large_message && count >= pof2 && smpi_op_is_commute(op)) {
+    if (block_dsize > large_message && count >= pof2 && (op==MPI_OP_NULL || op->is_commutative())) {
       //for long messages
        return (smpi_coll_tuned_allreduce_rab_rdb (sbuf, rbuf, 
                                                                    count, dtype,
@@ -359,7 +359,7 @@ int smpi_coll_tuned_reduce_mpich( void *sendbuf, void *recvbuf,
     pof2 >>= 1;
 
 
-    if ((count < pof2) || (message_size < 2048) || !smpi_op_is_commute(op)) {
+    if ((count < pof2) || (message_size < 2048) || (op!=MPI_OP_NULL && !op->is_commutative())) {
         return smpi_coll_tuned_reduce_binomial (sendbuf, recvbuf, count, datatype, op, root, comm); 
     }
         return smpi_coll_tuned_reduce_scatter_gather(sendbuf, recvbuf, count, datatype, op, root, comm/*, module,
@@ -437,11 +437,11 @@ int smpi_coll_tuned_reduce_scatter_mpich( void *sbuf, void *rbuf,
         total_message_size += rcounts[i];
     }
 
-    if( smpi_op_is_commute(op) &&  total_message_size > 524288) { 
+    if( (op==MPI_OP_NULL || op->is_commutative()) &&  total_message_size > 524288) { 
         return smpi_coll_tuned_reduce_scatter_mpich_pair (sbuf, rbuf, rcounts, 
                                                                     dtype, op, 
                                                                     comm); 
-    }else if (!smpi_op_is_commute(op)) {
+    }else if ((op!=MPI_OP_NULL && !op->is_commutative())) {
         int is_block_regular = 1;
         for (i = 0; i < (comm_size - 1); ++i) {
             if (rcounts[i] != rcounts[i+1]) {
index 4dc8c57..f3800b6 100644 (file)
@@ -365,7 +365,7 @@ int smpi_coll_tuned_allreduce_mvapich2(void *sendbuf,
 
   smpi_datatype_extent(datatype, &true_lb, &true_extent);
   //MPI_Op *op_ptr;
-  //is_commutative = smpi_op_is_commute(op);
+  //is_commutative = op->is_commutative();
 
   {
     /* Search for the corresponding system size inside the tuning table */
@@ -704,7 +704,7 @@ int smpi_coll_tuned_reduce_mvapich2( void *sendbuf,
   if (count == 0)
     return MPI_SUCCESS;
 
-  is_commutative = smpi_op_is_commute(op);
+  is_commutative = (op==MPI_OP_NULL || op->is_commutative());
 
   /* find nearest power-of-two less than or equal to comm_size */
   for( pof2 = 1; pof2 <= comm_size; pof2 <<= 1 );
@@ -811,7 +811,7 @@ int smpi_coll_tuned_reduce_scatter_mvapich2(void *sendbuf, void *recvbuf, int *r
   if(mv2_red_scat_thresholds_table==NULL)
     init_mv2_reduce_scatter_tables_stampede();
 
-  is_commutative=smpi_op_is_commute(op);
+  is_commutative=(op==MPI_OP_NULL || op->is_commutative());
   for (i = 0; i < comm_size; i++) {
       disps[i] = total_count;
       total_count += recvcnts[i];
index a0acf0c..fb9b9cb 100644 (file)
@@ -32,7 +32,7 @@ int smpi_coll_tuned_allreduce_ompi(void *sbuf, void *rbuf, int count,
                                                                    op, comm));
     } 
 
-    if( smpi_op_is_commute(op) && (count > comm_size) ) {
+    if( ((op==MPI_OP_NULL) || op->is_commutative()) && (count > comm_size) ) {
         const size_t segment_size = 1 << 20; /* 1 MB */
         if ((comm_size * segment_size >= block_dsize)) {
             //FIXME: ok, these are not the right algorithms, try to find closer ones
@@ -253,7 +253,7 @@ int smpi_coll_tuned_reduce_ompi( void *sendbuf, void *recvbuf,
      * If the operation is non commutative we currently have choice of linear 
      * or in-order binary tree algorithm.
      */
-    if( !smpi_op_is_commute(op) ) {
+    if(  (op!=MPI_OP_NULL) && !op->is_commutative() ) {
         if ((communicator_size < 12) && (message_size < 2048)) {
             return smpi_coll_tuned_reduce_ompi_basic_linear (sendbuf, recvbuf, count, datatype, op, root, comm/*, module*/); 
         } 
@@ -353,7 +353,7 @@ int smpi_coll_tuned_reduce_scatter_ompi( void *sbuf, void *rbuf,
         }
     }
 
-    if( !smpi_op_is_commute(op) || (zerocounts)) {
+    if(  ((op!=MPI_OP_NULL) && !op->is_commutative()) || (zerocounts)) {
         smpi_mpi_reduce_scatter (sbuf, rbuf, rcounts, 
                                                                     dtype, op, 
                                                                     comm); 
index 3d0bdb9..89908b3 100644 (file)
@@ -17,6 +17,7 @@
 #include "xbt/xbt_os_time.h"
 #include "src/smpi/smpi_group.hpp"
 #include "src/smpi/smpi_comm.hpp"
+#include "src/smpi/smpi_op.hpp"
 #include "src/smpi/smpi_request.hpp"
 #include "src/smpi/smpi_topo.hpp"
 #include "src/smpi/smpi_win.hpp"
@@ -198,12 +199,6 @@ XBT_PRIVATE int smpi_mpi_pack(void* inbuf, int incount, MPI_Datatype type, void*
 
 XBT_PRIVATE void smpi_empty_status(MPI_Status * status);
 XBT_PRIVATE int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype);
-XBT_PRIVATE MPI_Op smpi_op_new(MPI_User_function * function, bool commute);
-XBT_PRIVATE bool smpi_op_is_commute(MPI_Op op);
-XBT_PRIVATE void smpi_op_destroy(MPI_Op op);
-XBT_PRIVATE void smpi_op_set_fortran(MPI_Op op);
-XBT_PRIVATE void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len, MPI_Datatype * datatype);
-
 
 XBT_PRIVATE int smpi_comm_c2f(MPI_Comm comm);
 XBT_PRIVATE int smpi_comm_add_f(MPI_Comm comm);
index 6efaa9b..94fa819 100644 (file)
@@ -323,7 +323,7 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datat
   int rank = comm->rank();
   int size = comm->size();
   //non commutative case, use a working algo from openmpi
-  if(!smpi_op_is_commute(op)){
+  if(op != MPI_OP_NULL && !op->is_commutative()){
     smpi_coll_tuned_reduce_ompi_basic_linear(sendtmpbuf, recvbuf, count, datatype, op, root, comm);
     return;
   }
@@ -367,7 +367,7 @@ void smpi_mpi_reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datat
         Request::unuse(&requests[index]);
       }
       if(op) /* op can be MPI_OP_NULL that does nothing */
-        smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmpbufs[index], recvbuf, &count, &datatype);
     }
       for(index = 0; index < size - 1; index++) {
         smpi_free_tmp_buffer(tmpbufs[index]);
@@ -417,7 +417,7 @@ void smpi_mpi_scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
   // Wait for completion of all comms.
   Request::startall(size - 1, requests);
 
-  if(smpi_op_is_commute(op)){
+  if(op != MPI_OP_NULL && op->is_commutative()){
     for (int other = 0; other < size - 1; other++) {
       index = Request::waitany(size - 1, requests, MPI_STATUS_IGNORE);
       if(index == MPI_UNDEFINED) {
@@ -425,7 +425,7 @@ void smpi_mpi_scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
       }
       if(index < rank) {
         // #Request is below rank: it's a irecv
-        smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmpbufs[index], recvbuf, &count, &datatype);
       }
     }
   }else{
@@ -433,7 +433,7 @@ void smpi_mpi_scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
     for (int other = 0; other < size - 1; other++) {
       Request::wait(&(requests[other]), MPI_STATUS_IGNORE);
       if(index < rank) {
-        smpi_op_apply(op, tmpbufs[other], recvbuf, &count, &datatype);
+        if(op!=MPI_OP_NULL) op->apply( tmpbufs[other], recvbuf, &count, &datatype);
       }
     }
   }
@@ -474,7 +474,7 @@ void smpi_mpi_exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datat
   // Wait for completion of all comms.
   Request::startall(size - 1, requests);
 
-  if(smpi_op_is_commute(op)){
+  if(op != MPI_OP_NULL && op->is_commutative()){
     for (int other = 0; other < size - 1; other++) {
       index = Request::waitany(size - 1, requests, MPI_STATUS_IGNORE);
       if(index == MPI_UNDEFINED) {
@@ -486,7 +486,7 @@ void smpi_mpi_exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datat
           recvbuf_is_empty=0;
         } else
           // #Request is below rank: it's a irecv
-          smpi_op_apply(op, tmpbufs[index], recvbuf, &count, &datatype);
+          if(op!=MPI_OP_NULL) op->apply( tmpbufs[index], recvbuf, &count, &datatype);
       }
     }
   }else{
@@ -498,7 +498,7 @@ void smpi_mpi_exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datat
           smpi_datatype_copy(tmpbufs[other], count, datatype, recvbuf, count, datatype);
           recvbuf_is_empty = 0;
         } else
-          smpi_op_apply(op, tmpbufs[other], recvbuf, &count, &datatype);
+          if(op!=MPI_OP_NULL) op->apply( tmpbufs[other], recvbuf, &count, &datatype);
       }
     }
   }
index 3cbb271..183e3a7 100644 (file)
@@ -890,7 +890,7 @@ void mpi_op_create_ (void * function, int* commute, int* op, int* ierr){
   MPI_Op tmp;
  *ierr = MPI_Op_create(reinterpret_cast<MPI_User_function*>(function),*commute, &tmp);
  if(*ierr == MPI_SUCCESS) {
-   smpi_op_set_fortran(tmp);
+   tmp->set_fortran_op();
    *op = smpi_op_add_f(tmp);
  }
 }
index cc01776..b029c1c 100644 (file)
@@ -49,47 +49,7 @@ const MPI_Datatype name = &mpi_##name;
   };                                                  \
 const MPI_Datatype name = &mpi_##name;
 
-//The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
-typedef struct {
-  float value;
-  int index;
-} float_int;
-typedef struct {
-  float value;
-  float index;
-} float_float;
-typedef struct {
-  long value;
-  long index;
-} long_long;
-typedef struct {
-  double value;
-  double index;
-} double_double;
-typedef struct {
-  long value;
-  int index;
-} long_int;
-typedef struct {
-  double value;
-  int index;
-} double_int;
-typedef struct {
-  short value;
-  int index;
-} short_int;
-typedef struct {
-  int value;
-  int index;
-} int_int;
-typedef struct {
-  long double value;
-  int index;
-} long_double_int;
-typedef struct {
-  int64_t value;
-  int64_t index;
-} integer128_t;
+
 // Predefined data types
 CREATE_MPI_DATATYPE(MPI_CHAR, char);
 CREATE_MPI_DATATYPE(MPI_SHORT, short);
@@ -334,10 +294,11 @@ void unserialize_vector( void* contiguous_vector, void *noncontiguous_vector, in
   char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector);
 
   for (i = 0; i < type_c->block_count * count; i++) {
-    if (type_c->old_type->sizeof_substruct == 0)
-      smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length,
+    if (type_c->old_type->sizeof_substruct == 0){
+      if(op!=MPI_OP_NULL)
+        op->apply( contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length,
           &type_c->old_type);
-    else
+    }else
       static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize(contiguous_vector_char, noncontiguous_vector_char,
                                                                     type_c->block_length,type_c->old_type->substruct,
                                                                     op);
@@ -489,7 +450,8 @@ void unserialize_contiguous(void* contiguous_vector, void *noncontiguous_vector,
   char* contiguous_vector_char = static_cast<char*>(contiguous_vector);
   char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector)+type_c->lb;
   int n= count* type_c->block_count;
-  smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &n, &type_c->old_type);
+  if(op!=MPI_OP_NULL)
+    op->apply( contiguous_vector_char, noncontiguous_vector_char, &n, &type_c->old_type);
 }
 
 void free_contiguous(MPI_Datatype* d){
@@ -620,9 +582,10 @@ void unserialize_hvector( void* contiguous_vector, void *noncontiguous_vector, i
   char* noncontiguous_vector_char = static_cast<char*>(noncontiguous_vector);
 
   for (i = 0; i < type_c->block_count * count; i++) {
-    if (type_c->old_type->sizeof_substruct == 0)
-      smpi_op_apply(op, contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length, &type_c->old_type);
-    else
+    if (type_c->old_type->sizeof_substruct == 0){
+      if(op!=MPI_OP_NULL) 
+        op->apply( contiguous_vector_char, noncontiguous_vector_char, &type_c->block_length, &type_c->old_type);
+    }else
       static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_vector_char, noncontiguous_vector_char,
                                                                      type_c->block_length, type_c->old_type->substruct,
                                                                      op);
@@ -739,10 +702,11 @@ void unserialize_indexed( void* contiguous_indexed, void *noncontiguous_indexed,
     static_cast<char*>(noncontiguous_indexed)+type_c->block_indices[0]*smpi_datatype_get_extent(type_c->old_type);
   for (int j = 0; j < count; j++) {
     for (int i = 0; i < type_c->block_count; i++) {
-      if (type_c->old_type->sizeof_substruct == 0)
-        smpi_op_apply(op, contiguous_indexed_char, noncontiguous_indexed_char, &type_c->block_lengths[i],
+      if (type_c->old_type->sizeof_substruct == 0){
+        if(op!=MPI_OP_NULL) 
+          op->apply( contiguous_indexed_char, noncontiguous_indexed_char, &type_c->block_lengths[i],
                     &type_c->old_type);
-      else
+      }else
         static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_indexed_char,
                                                                        noncontiguous_indexed_char,
                                                                        type_c->block_lengths[i],
@@ -884,10 +848,11 @@ void unserialize_hindexed( void* contiguous_hindexed, void *noncontiguous_hindex
   char* noncontiguous_hindexed_char = static_cast<char*>(noncontiguous_hindexed)+ type_c->block_indices[0];
   for (int j = 0; j < count; j++) {
     for (int i = 0; i < type_c->block_count; i++) {
-      if (type_c->old_type->sizeof_substruct == 0)
-        smpi_op_apply(op, contiguous_hindexed_char, noncontiguous_hindexed_char, &type_c->block_lengths[i],
+      if (type_c->old_type->sizeof_substruct == 0){
+        if(op!=MPI_OP_NULL) 
+          op->apply( contiguous_hindexed_char, noncontiguous_hindexed_char, &type_c->block_lengths[i],
                             &type_c->old_type);
-      else
+      }else
         static_cast<s_smpi_subtype_t*>(type_c->old_type->substruct)->unserialize( contiguous_hindexed_char,
                                                                        noncontiguous_hindexed_char,
                                                                        type_c->block_lengths[i],
@@ -1029,10 +994,11 @@ void unserialize_struct( void* contiguous_struct, void *noncontiguous_struct, in
   char* noncontiguous_struct_char = static_cast<char*>(noncontiguous_struct)+ type_c->block_indices[0];
   for (int j = 0; j < count; j++) {
     for (int i = 0; i < type_c->block_count; i++) {
-      if (type_c->old_types[i]->sizeof_substruct == 0)
-        smpi_op_apply(op, contiguous_struct_char, noncontiguous_struct_char, &type_c->block_lengths[i],
+      if (type_c->old_types[i]->sizeof_substruct == 0){
+        if(op!=MPI_OP_NULL) 
+          op->apply( contiguous_struct_char, noncontiguous_struct_char, &type_c->block_lengths[i],
            & type_c->old_types[i]);
-      else
+      }else
         static_cast<s_smpi_subtype_t*>(type_c->old_types[i]->substruct)->unserialize( contiguous_struct_char,
                                                                            noncontiguous_struct_char,
                                                                            type_c->block_lengths[i],
@@ -1140,257 +1106,6 @@ void smpi_datatype_commit(MPI_Datatype *datatype)
   (*datatype)->flags=  ((*datatype)->flags | DT_FLAG_COMMITED);
 }
 
-typedef struct s_smpi_mpi_op {
-  MPI_User_function *func;
-  bool is_commute;
-  bool is_fortran_op;
-} s_smpi_mpi_op_t;
-
-#define MAX_OP(a, b)  (b) = (a) < (b) ? (b) : (a)
-#define MIN_OP(a, b)  (b) = (a) < (b) ? (a) : (b)
-#define SUM_OP(a, b)  (b) += (a)
-#define PROD_OP(a, b) (b) *= (a)
-#define LAND_OP(a, b) (b) = (a) && (b)
-#define LOR_OP(a, b)  (b) = (a) || (b)
-#define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
-#define BAND_OP(a, b) (b) &= (a)
-#define BOR_OP(a, b)  (b) |= (a)
-#define BXOR_OP(a, b) (b) ^= (a)
-#define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : (a)
-#define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : (b)
-
-#define APPLY_FUNC(a, b, length, type, func) \
-{                                          \
-  int i;                                   \
-  type* x = (type*)(a);                    \
-  type* y = (type*)(b);                    \
-  for(i = 0; i < *(length); i++) {         \
-    func(x[i], y[i]);                      \
-  }                                        \
-}
-
-#define APPLY_OP_LOOP(dtype, type, op) \
-  if (*datatype == dtype) {\
-    APPLY_FUNC(a, b, length, type, op)\
-  } else \
-
-
-#define APPLY_BASIC_OP_LOOP(op)\
-APPLY_OP_LOOP(MPI_CHAR, char,op)\
-APPLY_OP_LOOP(MPI_SHORT, short,op)\
-APPLY_OP_LOOP(MPI_INT, int,op)\
-APPLY_OP_LOOP(MPI_LONG, long,op)\
-APPLY_OP_LOOP(MPI_LONG_LONG, long long,op)\
-APPLY_OP_LOOP(MPI_SIGNED_CHAR, signed char,op)\
-APPLY_OP_LOOP(MPI_UNSIGNED_CHAR, unsigned char,op)\
-APPLY_OP_LOOP(MPI_UNSIGNED_SHORT, unsigned short,op)\
-APPLY_OP_LOOP(MPI_UNSIGNED, unsigned int,op)\
-APPLY_OP_LOOP(MPI_UNSIGNED_LONG, unsigned long,op)\
-APPLY_OP_LOOP(MPI_UNSIGNED_LONG_LONG, unsigned long long,op)\
-APPLY_OP_LOOP(MPI_WCHAR, wchar_t,op)\
-APPLY_OP_LOOP(MPI_BYTE, int8_t,op)\
-APPLY_OP_LOOP(MPI_INT8_T, int8_t,op)\
-APPLY_OP_LOOP(MPI_INT16_T, int16_t,op)\
-APPLY_OP_LOOP(MPI_INT32_T, int32_t,op)\
-APPLY_OP_LOOP(MPI_INT64_T, int64_t,op)\
-APPLY_OP_LOOP(MPI_UINT8_T, uint8_t,op)\
-APPLY_OP_LOOP(MPI_UINT16_T, uint16_t,op)\
-APPLY_OP_LOOP(MPI_UINT32_T, uint32_t,op)\
-APPLY_OP_LOOP(MPI_UINT64_T, uint64_t,op)\
-APPLY_OP_LOOP(MPI_AINT, MPI_Aint,op)\
-APPLY_OP_LOOP(MPI_OFFSET, MPI_Offset,op)\
-APPLY_OP_LOOP(MPI_INTEGER1, int,op)\
-APPLY_OP_LOOP(MPI_INTEGER2, int16_t,op)\
-APPLY_OP_LOOP(MPI_INTEGER4, int32_t,op)\
-APPLY_OP_LOOP(MPI_INTEGER8, int64_t,op)
-
-#define APPLY_BOOL_OP_LOOP(op)\
-APPLY_OP_LOOP(MPI_C_BOOL, bool,op)
-
-#define APPLY_FLOAT_OP_LOOP(op)\
-APPLY_OP_LOOP(MPI_FLOAT, float,op)\
-APPLY_OP_LOOP(MPI_DOUBLE, double,op)\
-APPLY_OP_LOOP(MPI_LONG_DOUBLE, long double,op)\
-APPLY_OP_LOOP(MPI_REAL, float,op)\
-APPLY_OP_LOOP(MPI_REAL4, float,op)\
-APPLY_OP_LOOP(MPI_REAL8, float,op)\
-APPLY_OP_LOOP(MPI_REAL16, double,op)
-
-#define APPLY_COMPLEX_OP_LOOP(op)\
-APPLY_OP_LOOP(MPI_C_FLOAT_COMPLEX, float _Complex,op)\
-APPLY_OP_LOOP(MPI_C_DOUBLE_COMPLEX, double _Complex,op)\
-APPLY_OP_LOOP(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex,op)
-
-#define APPLY_PAIR_OP_LOOP(op)\
-APPLY_OP_LOOP(MPI_FLOAT_INT, float_int,op)\
-APPLY_OP_LOOP(MPI_LONG_INT, long_int,op)\
-APPLY_OP_LOOP(MPI_DOUBLE_INT, double_int,op)\
-APPLY_OP_LOOP(MPI_SHORT_INT, short_int,op)\
-APPLY_OP_LOOP(MPI_2INT, int_int,op)\
-APPLY_OP_LOOP(MPI_2FLOAT, float_float,op)\
-APPLY_OP_LOOP(MPI_2DOUBLE, double_double,op)\
-APPLY_OP_LOOP(MPI_LONG_DOUBLE_INT, long_double_int,op)\
-APPLY_OP_LOOP(MPI_2LONG, long_long,op)
-
-#define APPLY_END_OP_LOOP(op)\
-  {\
-    xbt_die("Failed to apply " #op " to type %s", (*datatype)->name);\
-  }
-
-
-static void max_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(MAX_OP)
-  APPLY_FLOAT_OP_LOOP(MAX_OP)
-  APPLY_END_OP_LOOP(MAX_OP)
-}
-
-static void min_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(MIN_OP)
-  APPLY_FLOAT_OP_LOOP(MIN_OP)
-  APPLY_END_OP_LOOP(MIN_OP)
-}
-
-static void sum_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(SUM_OP)
-  APPLY_FLOAT_OP_LOOP(SUM_OP)
-  APPLY_COMPLEX_OP_LOOP(SUM_OP)
-  APPLY_END_OP_LOOP(SUM_OP)
-}
-
-static void prod_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(PROD_OP)
-  APPLY_FLOAT_OP_LOOP(PROD_OP)
-  APPLY_COMPLEX_OP_LOOP(PROD_OP)
-  APPLY_END_OP_LOOP(PROD_OP)
-}
-
-static void land_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(LAND_OP)
-  APPLY_BOOL_OP_LOOP(LAND_OP)
-  APPLY_END_OP_LOOP(LAND_OP)
-}
-
-static void lor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(LOR_OP)
-  APPLY_BOOL_OP_LOOP(LOR_OP)
-  APPLY_END_OP_LOOP(LOR_OP)
-}
-
-static void lxor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(LXOR_OP)
-  APPLY_BOOL_OP_LOOP(LXOR_OP)
-  APPLY_END_OP_LOOP(LXOR_OP)
-}
-
-static void band_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(BAND_OP)
-  APPLY_BOOL_OP_LOOP(BAND_OP)
-  APPLY_END_OP_LOOP(BAND_OP)
-}
-
-static void bor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(BOR_OP)
-  APPLY_BOOL_OP_LOOP(BOR_OP)
-  APPLY_END_OP_LOOP(BOR_OP)
-}
-
-static void bxor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_BASIC_OP_LOOP(BXOR_OP)
-  APPLY_BOOL_OP_LOOP(BXOR_OP)
-  APPLY_END_OP_LOOP(BXOR_OP)
-}
-
-static void minloc_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_PAIR_OP_LOOP(MINLOC_OP)
-  APPLY_END_OP_LOOP(MINLOC_OP)
-}
-
-static void maxloc_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  APPLY_PAIR_OP_LOOP(MAXLOC_OP)
-  APPLY_END_OP_LOOP(MAXLOC_OP)
-}
-
-static void replace_func(void *a, void *b, int *length, MPI_Datatype * datatype)
-{
-  memcpy(b, a, *length * smpi_datatype_size(*datatype));
-}
-
-#define CREATE_MPI_OP(name, func)                             \
-  static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */, true, false }; \
-MPI_Op name = &mpi_##name;
-
-CREATE_MPI_OP(MPI_MAX, max_func);
-CREATE_MPI_OP(MPI_MIN, min_func);
-CREATE_MPI_OP(MPI_SUM, sum_func);
-CREATE_MPI_OP(MPI_PROD, prod_func);
-CREATE_MPI_OP(MPI_LAND, land_func);
-CREATE_MPI_OP(MPI_LOR, lor_func);
-CREATE_MPI_OP(MPI_LXOR, lxor_func);
-CREATE_MPI_OP(MPI_BAND, band_func);
-CREATE_MPI_OP(MPI_BOR, bor_func);
-CREATE_MPI_OP(MPI_BXOR, bxor_func);
-CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
-CREATE_MPI_OP(MPI_MINLOC, minloc_func);
-CREATE_MPI_OP(MPI_REPLACE, replace_func);
-
-MPI_Op smpi_op_new(MPI_User_function * function, bool commute)
-{
-  MPI_Op op          = xbt_new(s_smpi_mpi_op_t, 1);
-  op->func = function;
-  op-> is_commute = commute;
-  op-> is_fortran_op = false;
-  return op;
-}
-
-bool smpi_op_is_commute(MPI_Op op)
-{
-  return (op==MPI_OP_NULL) ? true : op-> is_commute;
-}
-
-void smpi_op_destroy(MPI_Op op)
-{
-  xbt_free(op);
-}
-
-void smpi_op_set_fortran(MPI_Op op)
-{
-  //tell that we were created from fortran, so we need to translate the type to fortran when called
-  op->is_fortran_op = true;
-}
-
-void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len, MPI_Datatype * datatype)
-{
-  if(op==MPI_OP_NULL)
-    return;
-
-  if(smpi_privatize_global_variables){//we need to switch as the called function may silently touch global variables
-    XBT_DEBUG("Applying operation, switch to the right data frame ");
-    smpi_switch_data_segment(smpi_process_index());
-  }
-
-  if(!smpi_process_get_replaying()){
-    if(! op->is_fortran_op)
-      op->func(invec, inoutvec, len, datatype);
-    else{
-      int tmp = smpi_type_c2f(*datatype);
-      /* Unfortunately, the C and Fortran version of the MPI standard do not agree on the type here,
-         thus the reinterpret_cast. */
-      op->func(invec, inoutvec, len, reinterpret_cast<MPI_Datatype*>(&tmp) );
-    }
-  }
-}
 
 int smpi_type_attr_delete(MPI_Datatype type, int keyval){
   smpi_type_key_elem elem =
index fe0dd8f..b6dd5ba 100644 (file)
@@ -90,6 +90,49 @@ typedef struct s_smpi_mpi_struct{
   MPI_Datatype* old_types;
 } s_smpi_mpi_struct_t;
 
+//The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
+typedef struct {
+  float value;
+  int index;
+} float_int;
+typedef struct {
+  float value;
+  float index;
+} float_float;
+typedef struct {
+  long value;
+  long index;
+} long_long;
+typedef struct {
+  double value;
+  double index;
+} double_double;
+typedef struct {
+  long value;
+  int index;
+} long_int;
+typedef struct {
+  double value;
+  int index;
+} double_int;
+typedef struct {
+  short value;
+  int index;
+} short_int;
+typedef struct {
+  int value;
+  int index;
+} int_int;
+typedef struct {
+  long double value;
+  int index;
+} long_double_int;
+typedef struct {
+  int64_t value;
+  int64_t index;
+} integer128_t;
+
+
 /*
   Functions to handle serialization/unserialization of messages, 3 for each type of MPI_Type
   One for creating the substructure to handle, one for serialization, one for unserialization
diff --git a/src/smpi/smpi_op.cpp b/src/smpi/smpi_op.cpp
new file mode 100644 (file)
index 0000000..e3d4e2a
--- /dev/null
@@ -0,0 +1,254 @@
+/* Copyright (c) 2009-2017. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "mc/mc.h"
+#include "private.h"
+#include "smpi_mpi_dt_private.h"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_op, smpi, "Logging specific to SMPI (op)");
+
+#define MAX_OP(a, b)  (b) = (a) < (b) ? (b) : (a)
+#define MIN_OP(a, b)  (b) = (a) < (b) ? (a) : (b)
+#define SUM_OP(a, b)  (b) += (a)
+#define PROD_OP(a, b) (b) *= (a)
+#define LAND_OP(a, b) (b) = (a) && (b)
+#define LOR_OP(a, b)  (b) = (a) || (b)
+#define LXOR_OP(a, b) (b) = (!(a) && (b)) || ((a) && !(b))
+#define BAND_OP(a, b) (b) &= (a)
+#define BOR_OP(a, b)  (b) |= (a)
+#define BXOR_OP(a, b) (b) ^= (a)
+#define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : (a)
+#define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : (b)
+
+#define APPLY_FUNC(a, b, length, type, func) \
+{                                          \
+  int i;                                   \
+  type* x = (type*)(a);                    \
+  type* y = (type*)(b);                    \
+  for(i = 0; i < *(length); i++) {         \
+    func(x[i], y[i]);                      \
+  }                                        \
+}
+
+#define APPLY_OP_LOOP(dtype, type, op) \
+  if (*datatype == dtype) {\
+    APPLY_FUNC(a, b, length, type, op)\
+  } else \
+
+
+#define APPLY_BASIC_OP_LOOP(op)\
+APPLY_OP_LOOP(MPI_CHAR, char,op)\
+APPLY_OP_LOOP(MPI_SHORT, short,op)\
+APPLY_OP_LOOP(MPI_INT, int,op)\
+APPLY_OP_LOOP(MPI_LONG, long,op)\
+APPLY_OP_LOOP(MPI_LONG_LONG, long long,op)\
+APPLY_OP_LOOP(MPI_SIGNED_CHAR, signed char,op)\
+APPLY_OP_LOOP(MPI_UNSIGNED_CHAR, unsigned char,op)\
+APPLY_OP_LOOP(MPI_UNSIGNED_SHORT, unsigned short,op)\
+APPLY_OP_LOOP(MPI_UNSIGNED, unsigned int,op)\
+APPLY_OP_LOOP(MPI_UNSIGNED_LONG, unsigned long,op)\
+APPLY_OP_LOOP(MPI_UNSIGNED_LONG_LONG, unsigned long long,op)\
+APPLY_OP_LOOP(MPI_WCHAR, wchar_t,op)\
+APPLY_OP_LOOP(MPI_BYTE, int8_t,op)\
+APPLY_OP_LOOP(MPI_INT8_T, int8_t,op)\
+APPLY_OP_LOOP(MPI_INT16_T, int16_t,op)\
+APPLY_OP_LOOP(MPI_INT32_T, int32_t,op)\
+APPLY_OP_LOOP(MPI_INT64_T, int64_t,op)\
+APPLY_OP_LOOP(MPI_UINT8_T, uint8_t,op)\
+APPLY_OP_LOOP(MPI_UINT16_T, uint16_t,op)\
+APPLY_OP_LOOP(MPI_UINT32_T, uint32_t,op)\
+APPLY_OP_LOOP(MPI_UINT64_T, uint64_t,op)\
+APPLY_OP_LOOP(MPI_AINT, MPI_Aint,op)\
+APPLY_OP_LOOP(MPI_OFFSET, MPI_Offset,op)\
+APPLY_OP_LOOP(MPI_INTEGER1, int,op)\
+APPLY_OP_LOOP(MPI_INTEGER2, int16_t,op)\
+APPLY_OP_LOOP(MPI_INTEGER4, int32_t,op)\
+APPLY_OP_LOOP(MPI_INTEGER8, int64_t,op)
+
+#define APPLY_BOOL_OP_LOOP(op)\
+APPLY_OP_LOOP(MPI_C_BOOL, bool,op)
+
+#define APPLY_FLOAT_OP_LOOP(op)\
+APPLY_OP_LOOP(MPI_FLOAT, float,op)\
+APPLY_OP_LOOP(MPI_DOUBLE, double,op)\
+APPLY_OP_LOOP(MPI_LONG_DOUBLE, long double,op)\
+APPLY_OP_LOOP(MPI_REAL, float,op)\
+APPLY_OP_LOOP(MPI_REAL4, float,op)\
+APPLY_OP_LOOP(MPI_REAL8, float,op)\
+APPLY_OP_LOOP(MPI_REAL16, double,op)
+
+#define APPLY_COMPLEX_OP_LOOP(op)\
+APPLY_OP_LOOP(MPI_C_FLOAT_COMPLEX, float _Complex,op)\
+APPLY_OP_LOOP(MPI_C_DOUBLE_COMPLEX, double _Complex,op)\
+APPLY_OP_LOOP(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex,op)
+
+#define APPLY_PAIR_OP_LOOP(op)\
+APPLY_OP_LOOP(MPI_FLOAT_INT, float_int,op)\
+APPLY_OP_LOOP(MPI_LONG_INT, long_int,op)\
+APPLY_OP_LOOP(MPI_DOUBLE_INT, double_int,op)\
+APPLY_OP_LOOP(MPI_SHORT_INT, short_int,op)\
+APPLY_OP_LOOP(MPI_2INT, int_int,op)\
+APPLY_OP_LOOP(MPI_2FLOAT, float_float,op)\
+APPLY_OP_LOOP(MPI_2DOUBLE, double_double,op)\
+APPLY_OP_LOOP(MPI_LONG_DOUBLE_INT, long_double_int,op)\
+APPLY_OP_LOOP(MPI_2LONG, long_long,op)
+
+#define APPLY_END_OP_LOOP(op)\
+  {\
+    xbt_die("Failed to apply " #op " to type %s", (*datatype)->name);\
+  }
+
+static void max_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(MAX_OP)
+  APPLY_FLOAT_OP_LOOP(MAX_OP)
+  APPLY_END_OP_LOOP(MAX_OP)
+}
+
+static void min_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(MIN_OP)
+  APPLY_FLOAT_OP_LOOP(MIN_OP)
+  APPLY_END_OP_LOOP(MIN_OP)
+}
+
+static void sum_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(SUM_OP)
+  APPLY_FLOAT_OP_LOOP(SUM_OP)
+  APPLY_COMPLEX_OP_LOOP(SUM_OP)
+  APPLY_END_OP_LOOP(SUM_OP)
+}
+
+static void prod_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(PROD_OP)
+  APPLY_FLOAT_OP_LOOP(PROD_OP)
+  APPLY_COMPLEX_OP_LOOP(PROD_OP)
+  APPLY_END_OP_LOOP(PROD_OP)
+}
+
+static void land_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(LAND_OP)
+  APPLY_BOOL_OP_LOOP(LAND_OP)
+  APPLY_END_OP_LOOP(LAND_OP)
+}
+
+static void lor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(LOR_OP)
+  APPLY_BOOL_OP_LOOP(LOR_OP)
+  APPLY_END_OP_LOOP(LOR_OP)
+}
+
+static void lxor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(LXOR_OP)
+  APPLY_BOOL_OP_LOOP(LXOR_OP)
+  APPLY_END_OP_LOOP(LXOR_OP)
+}
+
+static void band_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(BAND_OP)
+  APPLY_BOOL_OP_LOOP(BAND_OP)
+  APPLY_END_OP_LOOP(BAND_OP)
+}
+
+static void bor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(BOR_OP)
+  APPLY_BOOL_OP_LOOP(BOR_OP)
+  APPLY_END_OP_LOOP(BOR_OP)
+}
+
+static void bxor_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_BASIC_OP_LOOP(BXOR_OP)
+  APPLY_BOOL_OP_LOOP(BXOR_OP)
+  APPLY_END_OP_LOOP(BXOR_OP)
+}
+
+static void minloc_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_PAIR_OP_LOOP(MINLOC_OP)
+  APPLY_END_OP_LOOP(MINLOC_OP)
+}
+
+static void maxloc_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  APPLY_PAIR_OP_LOOP(MAXLOC_OP)
+  APPLY_END_OP_LOOP(MAXLOC_OP)
+}
+
+static void replace_func(void *a, void *b, int *length, MPI_Datatype * datatype)
+{
+  memcpy(b, a, *length * smpi_datatype_size(*datatype));
+}
+
+#define CREATE_MPI_OP(name, func)                             \
+  static SMPI_Op mpi_##name (&(func) /* func */, true ); \
+MPI_Op name = &mpi_##name;
+
+CREATE_MPI_OP(MPI_MAX, max_func);
+CREATE_MPI_OP(MPI_MIN, min_func);
+CREATE_MPI_OP(MPI_SUM, sum_func);
+CREATE_MPI_OP(MPI_PROD, prod_func);
+CREATE_MPI_OP(MPI_LAND, land_func);
+CREATE_MPI_OP(MPI_LOR, lor_func);
+CREATE_MPI_OP(MPI_LXOR, lxor_func);
+CREATE_MPI_OP(MPI_BAND, band_func);
+CREATE_MPI_OP(MPI_BOR, bor_func);
+CREATE_MPI_OP(MPI_BXOR, bxor_func);
+CREATE_MPI_OP(MPI_MAXLOC, maxloc_func);
+CREATE_MPI_OP(MPI_MINLOC, minloc_func);
+CREATE_MPI_OP(MPI_REPLACE, replace_func);
+
+namespace simgrid{
+namespace smpi{
+
+Op::Op(MPI_User_function * function, bool commutative) : func_(function), is_commutative_(commutative)
+{
+  is_fortran_op_ = false;
+}
+
+bool Op::is_commutative()
+{
+  return is_commutative_;
+}
+
+bool Op::is_fortran_op()
+{
+  return is_fortran_op_;
+}
+
+void Op::set_fortran_op()
+{
+  //tell that we were created from fortran, so we need to translate the type to fortran when called
+  is_fortran_op_ = true;
+}
+
+void Op::apply(void *invec, void *inoutvec, int *len, MPI_Datatype * datatype)
+{
+  if(smpi_privatize_global_variables){//we need to switch as the called function may silently touch global variables
+    XBT_DEBUG("Applying operation, switch to the right data frame ");
+    smpi_switch_data_segment(smpi_process_index());
+  }
+
+  if(!smpi_process_get_replaying()){
+    if(! is_fortran_op_)
+      this->func_(invec, inoutvec, len, datatype);
+    else{
+      int tmp = smpi_type_c2f(*datatype);
+      /* Unfortunately, the C and Fortran version of the MPI standard do not agree on the type here,
+         thus the reinterpret_cast. */
+      this->func_(invec, inoutvec, len, reinterpret_cast<MPI_Datatype*>(&tmp) );
+    }
+  }
+}
+
+}
+}
diff --git a/src/smpi/smpi_op.hpp b/src/smpi/smpi_op.hpp
new file mode 100644 (file)
index 0000000..55e2c42
--- /dev/null
@@ -0,0 +1,33 @@
+/* Copyright (c) 2009-2010, 2012-2014. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SMPI_OP_HPP
+#define SMPI_OP_HPP
+
+#include <xbt/base.h>
+
+#include "private.h"
+
+namespace simgrid{
+namespace smpi{
+
+class Op {
+  private:
+    MPI_User_function *func_;
+    bool is_commutative_;
+    bool is_fortran_op_;
+  public:
+    Op(MPI_User_function * function, bool commutative);
+    bool is_commutative();
+    bool is_fortran_op();
+    void set_fortran_op();
+    void apply(void *invec, void *inoutvec, int *len, MPI_Datatype * datatype);
+};
+
+}
+}
+
+#endif
index d032edf..449032c 100644 (file)
@@ -247,7 +247,7 @@ int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
   if (function == nullptr || op == nullptr) {
     return MPI_ERR_ARG;
   } else {
-    *op = smpi_op_new(function, (commute!=0));
+    *op = new Op(function, (commute!=0));
     return MPI_SUCCESS;
   }
 }
@@ -259,7 +259,7 @@ int PMPI_Op_free(MPI_Op * op)
   } else if (*op == MPI_OP_NULL) {
     return MPI_ERR_OP;
   } else {
-    smpi_op_destroy(*op);
+    delete (*op);
     *op = MPI_OP_NULL;
     return MPI_SUCCESS;
   }
@@ -525,7 +525,7 @@ int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
     return MPI_SUCCESS;
   }else{
     group->use();
-    *newcomm = new simgrid::smpi::Comm(group, nullptr);
+    *newcomm = new Comm(group, nullptr);
     return MPI_SUCCESS;
   }
 }
@@ -1767,7 +1767,7 @@ int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datat
   if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
     retval = MPI_ERR_ARG;
   } else {
-    smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
+    if(op!=MPI_OP_NULL) op->apply( inbuf, inoutbuf, &count, &datatype);
     retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
@@ -2303,7 +2303,7 @@ int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int
   } else if (ndims < 0 || (ndims > 0 && (dims == nullptr || periodic == nullptr)) || comm_cart == nullptr) {
     return MPI_ERR_ARG;
   } else{
-    new simgrid::smpi::Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
+    new Cart(comm_old, ndims, dims, periodic, reorder, comm_cart);
     return MPI_SUCCESS;
   }
 }
@@ -2315,7 +2315,7 @@ int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
   if (coords == nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
@@ -2329,7 +2329,7 @@ int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* d
   if (source == nullptr || dest == nullptr || direction < 0 ) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
@@ -2349,7 +2349,7 @@ int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
   if(coords == nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
@@ -2363,7 +2363,7 @@ int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coor
   if(maxdims <= 0 || dims == nullptr || periods == nullptr || coords == nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
@@ -2377,7 +2377,7 @@ int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
   if (ndims == nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
@@ -2391,7 +2391,7 @@ int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
   if (ndims < 1 || nnodes < 1) {
     return MPI_ERR_DIMS;
   }
-  return simgrid::smpi::Dims_create(nnodes, ndims, dims);
+  return Dims_create(nnodes, ndims, dims);
 }
 
 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
@@ -2401,11 +2401,11 @@ int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
   if (comm_new == nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* topo = static_cast<simgrid::smpi::Cart*>(comm->topo());
+  Cart* topo = static_cast<Cart*>(comm->topo());
   if (topo==nullptr) {
     return MPI_ERR_ARG;
   }
-  simgrid::smpi::Cart* cart = topo->sub(remain_dims, comm_new);
+  Cart* cart = topo->sub(remain_dims, comm_new);
   if(cart==nullptr)
     return  MPI_ERR_ARG;
   return MPI_SUCCESS;
@@ -2434,7 +2434,7 @@ int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MP
   }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
     retval= MPI_ERR_OTHER;
   }else{
-    *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
+    *win = new Win( base, size, disp_unit, info, comm);
     retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
index ca0f1d1..89bab5a 100644 (file)
@@ -110,7 +110,7 @@ static double smpi_or(size_t size)
 namespace simgrid{
 namespace smpi{
 Request::Request(){}
-Request::Request(void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags) : src_(src), dst_(dst), tag_(tag), comm_(comm), flags_(flags)
+Request::Request(void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags) : buf_(buf), old_type_(datatype), src_(src), dst_(dst), tag_(tag), comm_(comm), flags_(flags) 
 {
   void *old_buf = nullptr;
   s_smpi_subtype_t *subtype = static_cast<s_smpi_subtype_t*>(datatype->substruct);
@@ -118,15 +118,13 @@ Request::Request(void *buf, int count, MPI_Datatype datatype, int src, int dst,
   if((((flags & RECV) != 0) && ((flags & ACCUMULATE) !=0)) || (datatype->sizeof_substruct != 0)){
     // This part handles the problem of non-contiguous memory
     old_buf = buf;
-    buf = count==0 ? nullptr : xbt_malloc(count*smpi_datatype_size(datatype));
+    buf_ = count==0 ? nullptr : xbt_malloc(count*smpi_datatype_size(datatype));
     if ((datatype->sizeof_substruct != 0) && ((flags & SEND) != 0)) {
-      subtype->serialize(old_buf, buf, count, datatype->substruct);
+      subtype->serialize(old_buf, buf_, count, datatype->substruct);
     }
   }
-  buf_      = buf;
   // This part handles the problem of non-contiguous memory (for the unserialisation at the reception)
   old_buf_  = old_buf;
-  old_type_ = datatype;
   size_ = smpi_datatype_size(datatype) * count;
   smpi_datatype_use(datatype);
   comm_->use();
@@ -812,7 +810,7 @@ void Request::finish_wait(MPI_Request* request, MPI_Status * status)
         xbt_free(req->buf_);
       }else if(req->flags_ & RECV){//apply op on contiguous buffer for accumulate
           int n =req->real_size_/smpi_datatype_size(datatype);
-          smpi_op_apply(req->op_, req->buf_, req->old_buf_, &n, &datatype);
+          req->op_->apply(req->buf_, req->old_buf_, &n, &datatype);
           xbt_free(req->buf_);
       }
     }
index 1b32575..6aa4ac9 100644 (file)
@@ -220,6 +220,8 @@ set(SMPI_SRC
   src/smpi/smpi_group.hpp
   src/smpi/smpi_mpi.cpp
   src/smpi/smpi_mpi_dt.cpp
+  src/smpi/smpi_op.cpp
+  src/smpi/smpi_op.hpp
   src/smpi/smpi_pmpi.cpp
   src/smpi/smpi_replay.cpp
   src/smpi/smpi_request.cpp