1 /* Copyright (c) 2013-2019. 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"
13 // Allgather-Non-Topoloty-Scecific-Logical-Ring algorithm
15 Coll_allgather_NTSLR_NB::allgather(const void *sbuf, int scount, MPI_Datatype stype,
16 void *rbuf, int rcount, MPI_Datatype rtype,
19 MPI_Aint rextent, sextent;
20 MPI_Status status, status2;
21 int i, to, from, rank, size;
22 int send_offset, recv_offset;
23 int tag = COLL_TAG_ALLGATHER;
27 rextent = rtype->get_extent();
28 sextent = stype->get_extent();
29 MPI_Request* rrequest_array = new MPI_Request[size];
30 MPI_Request* srequest_array = new MPI_Request[size];
32 // irregular case use default MPI fucntions
33 if (scount * sextent != rcount * rextent) {
34 XBT_WARN("MPI_allgather_NTSLR_NB use default MPI_allgather.");
35 Coll_allgather_default::allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
40 to = (rank + 1) % size;
41 from = (rank + size - 1) % size;
43 //copy a single segment from sbuf to rbuf
44 send_offset = rank * scount * sextent;
46 Request::sendrecv(sbuf, scount, stype, rank, tag,
47 (char *)rbuf + send_offset, rcount, rtype, rank, tag, comm, &status);
50 //start sending logical ring message
51 int increment = scount * sextent;
53 //post all irecv first
54 for (i = 0; i < size - 1; i++) {
55 recv_offset = ((rank - i - 1 + size) % size) * increment;
56 rrequest_array[i] = Request::irecv((char *)rbuf + recv_offset, rcount, rtype, from, tag + i, comm);
60 for (i = 0; i < size - 1; i++) {
61 send_offset = ((rank - i + size) % size) * increment;
62 srequest_array[i] = Request::isend((char *)rbuf + send_offset, scount, stype, to, tag + i, comm);
63 Request::wait(&rrequest_array[i], &status);
64 Request::wait(&srequest_array[i], &status2);
67 delete[] rrequest_array;
68 delete[] srequest_array;