Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
46b0496769ec85462750d5a449de77f36e04edc3
[simgrid.git] / src / smpi / colls / reduce / reduce-flat-tree.cpp
1 /* Copyright (c) 2013-2019. 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 //#include <star-reduction.c>
9 namespace simgrid{
10 namespace smpi{
11 int
12 Coll_reduce_flat_tree::reduce(void *sbuf, void *rbuf, int count,
13                                  MPI_Datatype dtype, MPI_Op op,
14                                  int root, MPI_Comm comm)
15 {
16   int i, tag = COLL_TAG_REDUCE;
17   int size;
18   int rank;
19   MPI_Aint extent;
20   char *origin = 0;
21   char *inbuf;
22   MPI_Status status;
23
24   rank = comm->rank();
25   size = comm->size();
26
27   /* If not root, send data to the root. */
28   extent = dtype->get_extent();
29
30   if (rank != root) {
31     Request::send(sbuf, count, dtype, root, tag, comm);
32     return 0;
33   }
34
35   /* Root receives and reduces messages.  Allocate buffer to receive
36      messages. */
37
38   if (size > 1)
39     origin = (char *) smpi_get_tmp_recvbuffer(count * extent);
40
41
42   /* Initialize the receive buffer. */
43   if (rank == (size - 1))
44     Request::sendrecv(sbuf, count, dtype, rank, tag,
45                  rbuf, count, dtype, rank, tag, comm, &status);
46   else
47     Request::recv(rbuf, count, dtype, size - 1, tag, comm, &status);
48
49   /* Loop receiving and calling reduction function (C or Fortran). */
50
51   for (i = size - 2; i >= 0; --i) {
52     if (rank == i)
53       inbuf = static_cast<char*>(sbuf);
54     else {
55       Request::recv(origin, count, dtype, i, tag, comm, &status);
56       inbuf = origin;
57     }
58
59     /* Call reduction function. */
60     if(op!=MPI_OP_NULL) op->apply( inbuf, rbuf, &count, dtype);
61
62   }
63
64   if (origin)
65     smpi_free_tmp_buffer(origin);
66
67   /* All done */
68   return 0;
69 }
70 }
71 }