Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move collective algorithms to separate folders
[simgrid.git] / src / smpi / colls / allgather / allgather-NTSLR.cpp
1 /* Copyright (c) 2013-2014. 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.h"
8
9 // Allgather-Non-Topoloty-Scecific-Logical-Ring algorithm
10 int
11 smpi_coll_tuned_allgather_NTSLR(void *sbuf, int scount, MPI_Datatype stype,
12                                 void *rbuf, int rcount, MPI_Datatype rtype,
13                                 MPI_Comm comm)
14 {
15   MPI_Aint rextent, sextent;
16   MPI_Status status;
17   int i, to, from, rank, size;
18   int send_offset, recv_offset;
19   int tag = COLL_TAG_ALLGATHER;
20
21   rank = comm->rank();
22   size = comm->size();
23   rextent = rtype->get_extent();
24   sextent = stype->get_extent();
25
26   // irregular case use default MPI fucntions
27   if (scount * sextent != rcount * rextent) {
28     XBT_WARN("MPI_allgather_NTSLR use default MPI_allgather.");  
29     smpi_mpi_allgather(sbuf, scount, stype, rbuf, rcount, rtype, comm);
30     return MPI_SUCCESS;    
31   }
32
33   // topo non-specific
34   to = (rank + 1) % size;
35   from = (rank + size - 1) % size;
36
37   //copy a single segment from sbuf to rbuf
38   send_offset = rank * scount * sextent;
39
40   Request::sendrecv(sbuf, scount, stype, rank, tag,
41                (char *)rbuf + send_offset, rcount, rtype, rank, tag,
42                comm, &status);
43
44
45   //start sending logical ring message
46   int increment = scount * sextent;
47   for (i = 0; i < size - 1; i++) {
48     send_offset = ((rank - i + size) % size) * increment;
49     recv_offset = ((rank - i - 1 + size) % size) * increment;
50     Request::sendrecv((char *) rbuf + send_offset, scount, stype, to, tag + i,
51                  (char *) rbuf + recv_offset, rcount, rtype, from, tag + i,
52                  comm, &status);
53   }
54
55   return MPI_SUCCESS;
56 }