Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
have alltoallv bruck algo behave like mpich one, with only 4 messages sent at a time
[simgrid.git] / src / smpi / colls / alltoallv-bruck.c
1 #include "colls_private.h"
2
3 /**
4  * Alltoall Bruck
5  *
6  * Openmpi calls this routine when the message size sent to each rank < 2000 bytes and size < 12
7  * FIXME: uh, check smpi_pmpi again, but this routine is called for > 12, not
8  * less...
9  **/
10 int smpi_coll_tuned_alltoallv_bruck(void *sendbuf, int *sendcounts, int *senddisps,
11                                    MPI_Datatype sendtype, void *recvbuf,
12                                    int *recvcounts, int *recvdisps, MPI_Datatype recvtype,
13                                    MPI_Comm comm)
14 {
15   int system_tag = COLL_TAG_ALLTOALLV;
16   int i, rank, size, err, count;
17   MPI_Aint lb;
18   MPI_Aint sendext = 0;
19   MPI_Aint recvext = 0;
20   MPI_Request *requests;
21
22   // FIXME: check implementation
23   rank = smpi_comm_rank(comm);
24   size = smpi_comm_size(comm);
25   XBT_DEBUG("<%d> algorithm alltoall_bruck() called.", rank);
26
27   err = smpi_datatype_extent(sendtype, &lb, &sendext);
28   err = smpi_datatype_extent(recvtype, &lb, &recvext);
29   /* Local copy from self */
30   err =
31       smpi_datatype_copy((char *)sendbuf + senddisps[rank] * sendext,
32                          sendcounts[rank], sendtype,
33                          (char *)recvbuf + recvdisps[rank] * recvext,
34                          recvcounts[rank], recvtype);
35   if (err == MPI_SUCCESS && size > 1) {
36     /* Initiate all send/recv to/from others. */
37
38       int bblock = 4;//MPIR_PARAM_ALLTOALL_THROTTLE
39       //if (bblock == 0) bblock = comm_size;
40
41
42      // requests = xbt_new(MPI_Request, 2 * (bblock - 1));
43       int ii, ss, dst;
44       /* post only bblock isends/irecvs at a time as suggested by Tony Ladd */
45       for (ii=0; ii<size; ii+=bblock) {
46           requests = xbt_new(MPI_Request, 2 * (bblock ));
47
48           ss = size-ii < bblock ? size-ii : bblock;
49           count = 0;
50
51           /* do the communication -- post ss sends and receives: */
52           for ( i=0; i<ss; i++ ) {
53             dst = (rank+i+ii) % size;
54               if (dst == rank) {
55                 XBT_DEBUG("<%d> skip request creation [src = %d, recvcount = %d]",
56                        rank, i, recvcounts[dst]);
57                 continue;
58               }
59
60               requests[count]=smpi_mpi_irecv((char *)recvbuf + recvdisps[dst] * recvext, recvcounts[dst],
61                                   recvtype, dst, system_tag, comm );
62               count++;
63             }
64             /* Now create all sends  */
65           for ( i=0; i<ss; i++ ) {
66               dst = (rank-i-ii+size) % size;
67               if (dst == rank) {
68                 XBT_DEBUG("<%d> skip request creation [dst = %d, sendcount = %d]",
69                        rank, i, sendcounts[dst]);
70                 continue;
71               }
72               requests[count]=smpi_mpi_isend((char *)sendbuf + senddisps[dst] * sendext, sendcounts[dst],
73                                   sendtype, dst, system_tag, comm);
74               count++;
75             }
76             /* Wait for them all. */
77             //smpi_mpi_startall(count, requests);
78             XBT_DEBUG("<%d> wait for %d requests", rank, count);
79             smpi_mpi_waitall(count, requests, MPI_STATUSES_IGNORE);
80             xbt_free(requests);
81
82           }
83
84   }
85   return MPI_SUCCESS;
86 }