Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MPI_Iexscan, MPI_Iscan
authorAugustin Degomme <adegomme@users.noreply.github.com>
Mon, 1 Apr 2019 22:40:43 +0000 (00:40 +0200)
committerAugustin Degomme <adegomme@users.noreply.github.com>
Mon, 1 Apr 2019 22:46:45 +0000 (00:46 +0200)
src/smpi/bindings/smpi_mpi.cpp
src/smpi/bindings/smpi_pmpi_coll.cpp
src/smpi/colls/smpi_nbc_impl.cpp
teshsuite/smpi/mpich3-test/coll/nonblocking.c
teshsuite/smpi/mpich3-test/coll/nonblocking2.c

index f3a1f7e..e2fd734 100644 (file)
@@ -155,8 +155,8 @@ WRAPPED_PMPI_CALL(int,MPI_Igatherv,(void *sendbuf, int sendcount, MPI_Datatype s
 //WRAPPED_PMPI_CALL(int,MPI_Ireduce_scatter_block,(void *sendbuf, void *recvbuf, int recvcount, MPI_Datatype datatype, MPI_Op op,MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, recvcount, datatype, op, comm, request))
 //WRAPPED_PMPI_CALL(int,MPI_Ireduce_scatter,(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, recvcounts, datatype, op, comm, request))
 WRAPPED_PMPI_CALL(int,MPI_Ireduce,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, root, comm, request))
-//WRAPPED_PMPI_CALL(int,MPI_Iexscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
-//WRAPPED_PMPI_CALL(int,MPI_Iscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iexscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
 WRAPPED_PMPI_CALL(int,MPI_Iscatter,(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request))
 WRAPPED_PMPI_CALL(int,MPI_Iscatterv,(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount,MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, request))
 
index cc86aec..825a544 100644 (file)
@@ -309,7 +309,9 @@ int PMPI_Iscatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   } else if ((sendbuf == recvbuf) ||
       ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
     retval = MPI_ERR_BUFFER;
-  }else {
+  }else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  } else {
 
     if (recvbuf == MPI_IN_PLACE) {
       recvtype  = sendtype;
@@ -403,6 +405,8 @@ int PMPI_Ireduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
     retval = MPI_ERR_COMM;
   } else if (not datatype->is_valid() || op == MPI_OP_NULL) {
     retval = MPI_ERR_ARG;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank = simgrid::s4u::this_actor::get_pid();
 
@@ -455,6 +459,8 @@ int PMPI_Iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype dataty
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     char* sendtmpbuf = static_cast<char*>(sendbuf);
     if( sendbuf == MPI_IN_PLACE ) {
@@ -485,6 +491,11 @@ int PMPI_Iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype dataty
 }
 
 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Iscan(sendbuf, recvbuf, count, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
 
@@ -496,6 +507,8 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank = simgrid::s4u::this_actor::get_pid();
     void* sendtmpbuf = sendbuf;
@@ -503,11 +516,15 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
       sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
       memcpy(sendtmpbuf, recvbuf, count * datatype->size());
     }
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::Pt2PtTIData(
-                                           "scan", -1, datatype->is_replayable() ? count : count * datatype->size(),
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan", new simgrid::instr::Pt2PtTIData(
+                                           request==MPI_REQUEST_IGNORED ? "scan":"iscan", -1, 
+                                           datatype->is_replayable() ? count : count * datatype->size(),
                                            simgrid::smpi::Datatype::encode(datatype)));
 
-    retval = simgrid::smpi::Colls::scan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::scan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    else
+      retval = simgrid::smpi::Colls::iscan(sendtmpbuf, recvbuf, count, datatype, op, comm, request);
 
     TRACE_smpi_comm_out(rank);
     if (sendbuf == MPI_IN_PLACE)
@@ -518,7 +535,12 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
   return retval;
 }
 
-int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
+int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Iexscan(sendbuf, recvbuf, count, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iexscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request){
   int retval = 0;
 
   smpi_bench_end();
@@ -529,6 +551,8 @@ int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank         = simgrid::s4u::this_actor::get_pid();
     void* sendtmpbuf = sendbuf;
@@ -537,11 +561,14 @@ int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
       memcpy(sendtmpbuf, recvbuf, count * datatype->size());
     }
 
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::Pt2PtTIData(
-                                           "exscan", -1, datatype->is_replayable() ? count : count * datatype->size(),
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Exscan" : "PMPI_Iexscan", new simgrid::instr::Pt2PtTIData(
+                                           request==MPI_REQUEST_IGNORED ? "exscan":"iexscan", -1, datatype->is_replayable() ? count : count * datatype->size(),
                                            simgrid::smpi::Datatype::encode(datatype)));
 
-    retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    else
+      retval = simgrid::smpi::Colls::iexscan(sendtmpbuf, recvbuf, count, datatype, op, comm, request);
 
     TRACE_smpi_comm_out(rank);
     if (sendbuf == MPI_IN_PLACE)
index 8e9b16d..6d5f761 100644 (file)
@@ -53,7 +53,7 @@ int Colls::ibcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Com
   int rank = comm->rank();
   MPI_Request* requests;
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_BARRIER, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, COLL_TAG_BCAST, comm, MPI_REQ_PERSISTENT);
   if (rank != root) {
     requests = new MPI_Request[1];
     requests[0] = Request::irecv (buf, count, datatype, root,
@@ -90,7 +90,7 @@ int Colls::iallgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_BARRIER, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   // FIXME: check for errors
   recvtype->extent(&lb, &recvext);
   // Local copy from self
@@ -124,7 +124,7 @@ int Colls::iscatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_BARRIER, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   if(rank != root) {
     requests = new MPI_Request[1];
     // Recv buffer from root
@@ -164,7 +164,7 @@ int Colls::iallgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_BARRIER, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   recvtype->extent(&lb, &recvext);
   // Local copy from self
   Datatype::copy(sendbuf, sendcount, sendtype,
@@ -199,7 +199,7 @@ int system_tag = COLL_TAG_ALLTOALL;
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_ALLTOALL, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   sendtype->extent(&lb, &sendext);
   recvtype->extent(&lb, &recvext);
   /* simple optimization */
@@ -244,7 +244,7 @@ int Colls::ialltoallv(void *sendbuf, int *sendcounts, int *senddisps, MPI_Dataty
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_ALLTOALLV, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   sendtype->extent(&lb, &sendext);
   recvtype->extent(&lb, &recvext);
   /* Local copy from self */
@@ -290,7 +290,7 @@ int Colls::ialltoallw(void *sendbuf, int *sendcounts, int *senddisps, MPI_Dataty
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_ALLTOALLV, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   /* Local copy from self */
   int err = (sendcounts[rank]>0 && recvcounts[rank]) ? Datatype::copy(static_cast<char *>(sendbuf) + senddisps[rank], sendcounts[rank], sendtypes[rank],
                                static_cast<char *>(recvbuf) + recvdisps[rank], recvcounts[rank], recvtypes[rank]): MPI_SUCCESS;
@@ -336,7 +336,7 @@ int Colls::igather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_GATHER, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   if(rank != root) {
     // Send buffer to root
     requests = new MPI_Request[1];
@@ -375,7 +375,7 @@ int Colls::igatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *r
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_GATHERV, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   if (rank != root) {
     // Send buffer to root
     requests = new MPI_Request[1];
@@ -413,7 +413,7 @@ int Colls::iscatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype s
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( nullptr, 0, MPI_BYTE,
-                         rank,rank, COLL_TAG_SCATTERV, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
   if(rank != root) {
     // Recv buffer from root
     requests = new MPI_Request[1];
@@ -466,11 +466,11 @@ int Colls::ireduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
 
   if(rank == root){
     (*request) =  new Request( recvbuf, count, datatype,
-                         rank,rank, COLL_TAG_REDUCE, comm, MPI_REQ_PERSISTENT, op);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
   }
   else
     (*request) = new Request( nullptr, count, datatype,
-                         rank,rank, COLL_TAG_REDUCE, comm, MPI_REQ_PERSISTENT);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
 
   if(rank != root) {
     // Send buffer to root
@@ -514,7 +514,7 @@ int Colls::iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype data
   int rank = comm->rank();
   int size = comm->size();
   (*request) = new Request( recvbuf, count, datatype,
-                         rank,rank, COLL_TAG_ALLREDUCE, comm, MPI_REQ_PERSISTENT, op);
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
   // FIXME: check for errors
   datatype->extent(&lb, &dataext);
   // Local copy from self
@@ -536,5 +536,71 @@ int Colls::iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype data
   return MPI_SUCCESS;
 }
 
+int Colls::iscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
+{
+  int system_tag = -888;
+  MPI_Aint lb      = 0;
+  MPI_Aint dataext = 0;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  datatype->extent(&lb, &dataext);
+
+  // Local copy from self
+  Datatype::copy(sendbuf, count, datatype, recvbuf, count, datatype);
+
+  // Send/Recv buffers to/from others
+  MPI_Request *requests = new MPI_Request[size - 1];
+  void **tmpbufs = xbt_new(void *, rank);
+  int index = 0;
+  for (int other = 0; other < rank; other++) {
+    tmpbufs[index] = smpi_get_tmp_sendbuffer(count * dataext);
+    requests[index] = Request::irecv_init(tmpbufs[index], count, datatype, other, system_tag, comm);
+    index++;
+  }
+  for (int other = rank + 1; other < size; other++) {
+    requests[index] = Request::isend_init(sendbuf, count, datatype, other, system_tag, comm);
+    index++;
+  }
+  // Wait for completion of all comms.
+  Request::startall(size - 1, requests);
+  (*request)->set_nbc_requests(requests, size - 1);
+  return MPI_SUCCESS;
+}
+
+int Colls::iexscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
+{
+  int system_tag = -888;
+  MPI_Aint lb         = 0;
+  MPI_Aint dataext    = 0;
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  datatype->extent(&lb, &dataext);
+  if(rank != 0)
+    memset(recvbuf, 0, count*dataext);
+
+  // Send/Recv buffers to/from others
+  MPI_Request *requests = new MPI_Request[size - 1];
+  void **tmpbufs = xbt_new(void *, rank);
+  int index = 0;
+  for (int other = 0; other < rank; other++) {
+    tmpbufs[index] = smpi_get_tmp_sendbuffer(count * dataext);
+    requests[index] = Request::irecv_init(tmpbufs[index], count, datatype, other, system_tag, comm);
+    index++;
+  }
+  for (int other = rank + 1; other < size; other++) {
+    requests[index] = Request::isend_init(sendbuf, count, datatype, other, system_tag, comm);
+    index++;
+  }
+  // Wait for completion of all comms.
+  Request::startall(size - 1, requests);
+  (*request)->set_nbc_requests(requests, size - 1);
+  return MPI_SUCCESS;
+}
+
 }
 }
index 94938e5..548b073 100644 (file)
@@ -180,17 +180,17 @@ int main(int argc, char **argv)
 /*    MPI_Ireduce_scatter_block(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);*/
 /*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
 
-/*    MPI_Iscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
+    MPI_Iscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
 
-/*    MPI_Iscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
+    MPI_Iscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
 
-/*    MPI_Iexscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
+    MPI_Iexscan(sbuf, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
 
-/*    MPI_Iexscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
+    MPI_Iexscan(MPI_IN_PLACE, rbuf, NUM_INTS, MPI_INT, MPI_SUM, comm, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
 
     if (sbuf)
         free(sbuf);
index f266f54..6e216b5 100644 (file)
@@ -396,29 +396,29 @@ int main(int argc, char **argv)
     }
 
     /* MPI_Iscan */
-/*    for (i = 0; i < COUNT; ++i) {*/
-/*        buf[i] = rank + i;*/
-/*        recvbuf[i] = 0xdeadbeef;*/
-/*    }*/
-/*    MPI_Iscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, MPI_COMM_WORLD, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
-/*    for (i = 0; i < COUNT; ++i) {*/
-/*        my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1))));*/
-/*    }*/
+    for (i = 0; i < COUNT; ++i) {
+        buf[i] = rank + i;
+        recvbuf[i] = 0xdeadbeef;
+    }
+    MPI_Iscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, MPI_COMM_WORLD, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
+    for (i = 0; i < COUNT; ++i) {
+        my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1))));
+    }
 
     /* MPI_Iexscan */
-/*    for (i = 0; i < COUNT; ++i) {*/
-/*        buf[i] = rank + i;*/
-/*        recvbuf[i] = 0xdeadbeef;*/
-/*    }*/
-/*    MPI_Iexscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, MPI_COMM_WORLD, &req);*/
-/*    MPI_Wait(&req, MPI_STATUS_IGNORE);*/
-/*    for (i = 0; i < COUNT; ++i) {*/
-/*        if (rank == 0)*/
-/*            my_assert(recvbuf[i] == 0xdeadbeef);*/
-/*        else*/
-/*            my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1)) - (rank + i)));*/
-/*    }*/
+    for (i = 0; i < COUNT; ++i) {
+        buf[i] = rank + i;
+        recvbuf[i] = 0xdeadbeef;
+    }
+    MPI_Iexscan(buf, recvbuf, COUNT, MPI_INT, MPI_SUM, MPI_COMM_WORLD, &req);
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
+    for (i = 0; i < COUNT; ++i) {
+        if (rank == 0)
+            my_assert(recvbuf[i] == 0xdeadbeef);
+        else
+            my_assert(recvbuf[i] == ((rank * (rank + 1) / 2) + (i * (rank + 1)) - (rank + i)));
+    }
 
     /* MPI_Ialltoallw (a weak test, neither irregular nor sparse) */
     for (i = 0; i < size; ++i) {