Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ompi selector was using the wrong algo for alltoallv, add the right one and use it
authorAugustin Degomme <degomme@idpann.imag.fr>
Wed, 19 Jun 2013 11:08:42 +0000 (13:08 +0200)
committerAugustin Degomme <degomme@idpann.imag.fr>
Wed, 19 Jun 2013 11:11:16 +0000 (13:11 +0200)
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
src/smpi/colls/alltoallv-ompi-basic-linear.c [new file with mode: 0644]
src/smpi/colls/colls.h
src/smpi/colls/smpi_openmpi_selector.c

index 0b72e11..c8a7fb3 100644 (file)
@@ -401,7 +401,7 @@ if(NOT enable_memcheck)
     
     FOREACH (ALLTOALLV_COLL default pair pair_light_barrier pair_mpi_barrier
                            pair_one_barrier  ring ring_light_barrier
     
     FOREACH (ALLTOALLV_COLL default pair pair_light_barrier pair_mpi_barrier
                            pair_one_barrier  ring ring_light_barrier
-                           ring_mpi_barrier ring_one_barrier bruck ompi)
+                           ring_mpi_barrier ring_one_barrier bruck ompi ompi_basic_linear)
         ADD_TEST(smpi-alltoallv-coll-${ALLTOALLV_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/alltoallv:${ALLTOALLV_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/alltoallv_coll.tesh)
     ENDFOREACH()
     
         ADD_TEST(smpi-alltoallv-coll-${ALLTOALLV_COLL} ${CMAKE_BINARY_DIR}/bin/tesh ${TESH_OPTION} --cfg smpi/alltoallv:${ALLTOALLV_COLL} --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/alltoallv_coll.tesh)
     ENDFOREACH()
     
index f8436b7..5f96eab 100644 (file)
@@ -174,6 +174,7 @@ set(SMPI_SRC
   src/smpi/colls/alltoallv-ring-mpi-barrier.c
   src/smpi/colls/alltoallv-ring-one-barrier.c
   src/smpi/colls/alltoallv-bruck.c
   src/smpi/colls/alltoallv-ring-mpi-barrier.c
   src/smpi/colls/alltoallv-ring-one-barrier.c
   src/smpi/colls/alltoallv-bruck.c
+  src/smpi/colls/alltoallv-ompi-basic-linear.c
   src/smpi/colls/bcast-arrival-nb.c
   src/smpi/colls/bcast-arrival-pattern-aware.c
   src/smpi/colls/bcast-arrival-pattern-aware-wait.c
   src/smpi/colls/bcast-arrival-nb.c
   src/smpi/colls/bcast-arrival-pattern-aware.c
   src/smpi/colls/bcast-arrival-pattern-aware-wait.c
diff --git a/src/smpi/colls/alltoallv-ompi-basic-linear.c b/src/smpi/colls/alltoallv-ompi-basic-linear.c
new file mode 100644 (file)
index 0000000..f90471d
--- /dev/null
@@ -0,0 +1,100 @@
+
+#include "colls_private.h"
+#define MCA_COLL_BASE_TAG_ALLTOALLV 111
+/*  
+ * Linear functions are copied from the basic coll module.  For
+ * some small number of nodes and/or small data sizes they are just as
+ * fast as tuned/tree based segmenting operations and as such may be
+ * selected by the decision functions.  These are copied into this module
+ * due to the way we select modules in V1. i.e. in V2 we will handle this
+ * differently and so will not have to duplicate code.  
+ * GEF Oct05 after asking Jeff.  
+ */
+int
+smpi_coll_tuned_alltoallv_ompi_basic_linear(void *sbuf, int *scounts, int *sdisps,
+                                            MPI_Datatype sdtype,
+                                            void *rbuf, int *rcounts, int *rdisps,
+                                            MPI_Datatype rdtype,
+                                            MPI_Comm comm)
+{
+    int i, size, rank;
+    char *psnd, *prcv;
+    int nreqs;
+    ptrdiff_t sext, rext;
+    MPI_Request *preq;
+    size = smpi_comm_size(comm);
+    rank = smpi_comm_rank(comm);
+    MPI_Request *ireqs= xbt_malloc(sizeof(MPI_Request) * size * 2);
+    XBT_DEBUG(
+                 "coll:tuned:alltoallv_intra_basic_linear rank %d", rank);
+
+    sext=smpi_datatype_get_extent(sdtype);
+    rext=smpi_datatype_get_extent(rdtype);
+
+    /* Simple optimization - handle send to self first */
+    psnd = ((char *) sbuf) + (sdisps[rank] * sext);
+    prcv = ((char *) rbuf) + (rdisps[rank] * rext);
+    if (0 != scounts[rank]) {
+        smpi_datatype_copy(psnd, scounts[rank], sdtype,
+                              prcv, rcounts[rank], rdtype);
+    }
+
+    /* If only one process, we're done. */
+    if (1 == size) {
+        return MPI_SUCCESS;
+    }
+
+    /* Now, initiate all send/recv to/from others. */
+    nreqs = 0;
+    preq = ireqs;
+
+    /* Post all receives first */
+    for (i = 0; i < size; ++i) {
+        if (i == rank || 0 == rcounts[i]) {
+            continue;
+        }
+
+        prcv = ((char *) rbuf) + (rdisps[i] * rext);
+
+        *preq = smpi_irecv_init(prcv, rcounts[i], rdtype,
+                                      i, MCA_COLL_BASE_TAG_ALLTOALLV, comm
+                                      );
+        preq++;
+        ++nreqs;
+        
+    }
+
+    /* Now post all sends */
+    for (i = 0; i < size; ++i) {
+        if (i == rank || 0 == scounts[i]) {
+            continue;
+        }
+
+        psnd = ((char *) sbuf) + (sdisps[i] * sext);
+        *preq=smpi_isend_init(psnd, scounts[i], sdtype,
+                                      i, MCA_COLL_BASE_TAG_ALLTOALLV, comm
+                                      );
+        preq++;
+        ++nreqs;
+    }
+
+    /* Start your engines.  This will never return an error. */
+    smpi_mpi_startall(nreqs, ireqs);
+
+    /* Wait for them all.  If there's an error, note that we don't care
+     * what the error was -- just that there *was* an error.  The PML
+     * will finish all requests, even if one or more of them fail.
+     * i.e., by the end of this call, all the requests are free-able.
+     * So free them anyway -- even if there was an error, and return the
+     * error after we free everything. */
+    smpi_mpi_waitall(nreqs, ireqs,
+                                MPI_STATUSES_IGNORE);
+
+    /* Free the requests. */
+    for (i = 0; i < nreqs; ++i) {
+      if(ireqs[i]!=MPI_REQUEST_NULL)smpi_mpi_request_free(&ireqs[i]);
+    }
+
+    return MPI_SUCCESS;
+}
+
index 3de3681..c870515 100644 (file)
@@ -166,7 +166,8 @@ COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_light_barrier) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_mpi_barrier) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_one_barrier) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ompi) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_mpi_barrier) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ring_one_barrier) COLL_sep \
 COLL_APPLY(action, COLL_ALLTOALLV_SIG, ompi) COLL_sep \
-COLL_APPLY(action, COLL_ALLTOALLV_SIG, mpich)
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, mpich)COLL_sep \
+COLL_APPLY(action, COLL_ALLTOALLV_SIG, ompi_basic_linear)
 
 COLL_ALLTOALLVS(COLL_PROTO, COLL_NOsep)
 
 
 COLL_ALLTOALLVS(COLL_PROTO, COLL_NOsep)
 
index 939b643..8109fba 100644 (file)
@@ -94,7 +94,7 @@ int smpi_coll_tuned_alltoallv_ompi(void *sbuf, int *scounts, int *sdisps,
                                               )
 {
     /* For starters, just keep the original algorithm. */
                                               )
 {
     /* For starters, just keep the original algorithm. */
-    return smpi_coll_tuned_alltoallv_pair(sbuf, scounts, sdisps, sdtype, 
+    return smpi_coll_tuned_alltoallv_ompi_basic_linear(sbuf, scounts, sdisps, sdtype, 
                                                         rbuf, rcounts, rdisps,rdtype,
                                                         comm);
 }
                                                         rbuf, rcounts, rdisps,rdtype,
                                                         comm);
 }