Logo AND Algorithmique Numérique Distribuée

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