1 /* Copyright (c) 2013-2023. The SimGrid Team.
2 * All rights reserved. */
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. */
7 #include "../colls_private.hpp"
9 /*Naive and simple basic alltoall implementation. */
11 namespace simgrid::smpi {
13 int alltoall__basic_linear(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
14 void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
16 int system_tag = COLL_TAG_ALLTOALL;
19 MPI_Aint lb = 0, sendext = 0, recvext = 0;
22 int rank = comm->rank();
23 int size = comm->size();
24 XBT_DEBUG("<%d> algorithm alltoall_basic_linear() called.", rank);
25 sendtype->extent(&lb, &sendext);
26 recvtype->extent(&lb, &recvext);
27 /* simple optimization */
28 int err = Datatype::copy(static_cast<const char *>(sendbuf) + rank * sendcount * sendext, sendcount, sendtype,
29 static_cast<char *>(recvbuf) + rank * recvcount * recvext, recvcount, recvtype);
30 if (err == MPI_SUCCESS && size > 1) {
31 /* Initiate all send/recv to/from others. */
32 auto* requests = new MPI_Request[2 * (size - 1)];
33 /* Post all receives first -- a simple optimization */
35 for (i = (rank + 1) % size; i != rank; i = (i + 1) % size) {
36 requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + i * recvcount * recvext, recvcount,
37 recvtype, i, system_tag, comm);
40 /* Now post all sends in reverse order
41 * - We would like to minimize the search time through message queue
42 * when messages actually arrive in the order in which they were posted.
43 * TODO: check the previous assertion
45 for (i = (rank + size - 1) % size; i != rank; i = (i + size - 1) % size) {
46 requests[count] = Request::isend_init(static_cast<const char *>(sendbuf) + i * sendcount * sendext, sendcount,
47 sendtype, i, system_tag, comm);
50 /* Wait for them all. */
51 Request::startall(count, requests);
52 XBT_DEBUG("<%d> wait for %d requests", rank, count);
53 Request::waitall(count, requests, MPI_STATUS_IGNORE);
54 for(i = 0; i < count; i++) {
55 if(requests[i]!=MPI_REQUEST_NULL)
56 Request::unref(&requests[i]);
63 } // namespace simgrid::smpi