Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add new entry in Release_Notes.
[simgrid.git] / src / smpi / colls / alltoallv / alltoallv-bruck.cpp
1 /* Copyright (c) 2013-2023. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "../colls_private.hpp"
8
9 /**
10  * Alltoall Bruck
11  *
12  * Openmpi calls this routine when the message size sent to each rank < 2000 bytes and size < 12
13  * FIXME: uh, check smpi_pmpi again, but this routine is called for > 12, not
14  * less...
15  **/
16 namespace simgrid::smpi {
17 int alltoallv__bruck(const void *sendbuf, const int *sendcounts, const int *senddisps,
18                      MPI_Datatype sendtype, void *recvbuf,
19                      const int *recvcounts,const int *recvdisps, MPI_Datatype recvtype,
20                      MPI_Comm comm)
21 {
22   int system_tag = COLL_TAG_ALLTOALLV;
23   int i, rank, size, err, count;
24   MPI_Aint lb;
25   MPI_Aint sendext = 0;
26   MPI_Aint recvext = 0;
27
28   // FIXME: check implementation
29   rank = comm->rank();
30   size = comm->size();
31   XBT_DEBUG("<%d> algorithm alltoall_bruck() called.", rank);
32
33   sendtype->extent(&lb, &sendext);
34   recvtype->extent(&lb, &recvext);
35   /* Local copy from self */
36   err =
37       Datatype::copy((char *)sendbuf + senddisps[rank] * sendext,
38                          sendcounts[rank], sendtype,
39                          (char *)recvbuf + recvdisps[rank] * recvext,
40                          recvcounts[rank], recvtype);
41   if (err == MPI_SUCCESS && size > 1) {
42     /* Initiate all send/recv to/from others. */
43
44     int bblock = 4; // MPIR_PARAM_ALLTOALL_THROTTLE
45     // if (bblock == 0) bblock = comm_size;
46
47     // MPI_Request* requests = new MPI_Request[2 * (bblock - 1)];
48     int ii, ss, dst;
49     /* post only bblock isends/irecvs at a time as suggested by Tony Ladd */
50     for (ii = 0; ii < size; ii += bblock) {
51       auto* requests = new MPI_Request[2 * bblock];
52
53       ss    = size - ii < bblock ? size - ii : bblock;
54       count = 0;
55
56       /* do the communication -- post ss sends and receives: */
57       for (i = 0; i < ss; i++) {
58         dst = (rank + i + ii) % size;
59         if (dst == rank) {
60           XBT_DEBUG("<%d> skip request creation [src = %d, recvcount = %d]", rank, i, recvcounts[dst]);
61           continue;
62         }
63
64         requests[count] =
65             Request::irecv((char*)recvbuf + recvdisps[dst] * recvext, recvcounts[dst], recvtype, dst, system_tag, comm);
66         count++;
67       }
68       /* Now create all sends  */
69       for (i = 0; i < ss; i++) {
70         dst = (rank - i - ii + size) % size;
71         if (dst == rank) {
72           XBT_DEBUG("<%d> skip request creation [dst = %d, sendcount = %d]", rank, i, sendcounts[dst]);
73           continue;
74         }
75         requests[count] =
76             Request::isend((char*)sendbuf + senddisps[dst] * sendext, sendcounts[dst], sendtype, dst, system_tag, comm);
77         count++;
78       }
79       /* Wait for them all. */
80       // colls::startall(count, requests);
81       XBT_DEBUG("<%d> wait for %d requests", rank, count);
82       Request::waitall(count, requests, MPI_STATUSES_IGNORE);
83       delete[] requests;
84     }
85   }
86   return MPI_SUCCESS;
87 }
88 } // namespace simgrid::smpi