Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
723c5b6121609256169b259a8ecec57072244690
[simgrid.git] / src / smpi / colls / alltoall / alltoall-basic-linear.cpp
1 /* Copyright (c) 2013-2017. 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 /*Naive and simple basic alltoall implementation. */
10
11
12 namespace simgrid{
13 namespace smpi{
14
15
16 int Coll_alltoall_basic_linear::alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
17                                           void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
18 {
19   int system_tag = 888;
20   int i;
21   int count;
22   MPI_Aint lb = 0, sendext = 0, recvext = 0;
23   MPI_Request *requests;
24
25   /* Initialize. */
26   int rank = comm->rank();
27   int size = comm->size();
28   XBT_DEBUG("<%d> algorithm alltoall_basic_linear() called.", rank);
29   sendtype->extent(&lb, &sendext);
30   recvtype->extent(&lb, &recvext);
31   /* simple optimization */
32   int err = Datatype::copy(static_cast<char *>(sendbuf) + rank * sendcount * sendext, sendcount, sendtype,
33                                static_cast<char *>(recvbuf) + rank * recvcount * recvext, recvcount, recvtype);
34   if (err == MPI_SUCCESS && size > 1) {
35     /* Initiate all send/recv to/from others. */
36     requests = xbt_new(MPI_Request, 2 * (size - 1));
37     /* Post all receives first -- a simple optimization */
38     count = 0;
39     for (i = (rank + 1) % size; i != rank; i = (i + 1) % size) {
40       requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + i * recvcount * recvext, recvcount,
41                                         recvtype, i, system_tag, comm);
42       count++;
43     }
44     /* Now post all sends in reverse order
45      *   - We would like to minimize the search time through message queue
46      *     when messages actually arrive in the order in which they were posted.
47      * TODO: check the previous assertion
48      */
49     for (i = (rank + size - 1) % size; i != rank; i = (i + size - 1) % size) {
50       requests[count] = Request::isend_init(static_cast<char *>(sendbuf) + i * sendcount * sendext, sendcount,
51                                         sendtype, i, system_tag, comm);
52       count++;
53     }
54     /* Wait for them all. */
55     Request::startall(count, requests);
56     XBT_DEBUG("<%d> wait for %d requests", rank, count);
57     Request::waitall(count, requests, MPI_STATUS_IGNORE);
58     for(i = 0; i < count; i++) {
59       if(requests[i]!=MPI_REQUEST_NULL)
60         Request::unref(&requests[i]);
61     }
62     xbt_free(requests);
63   }
64   return err;
65 }
66
67 }
68 }