Logo AND Algorithmique Numérique Distribuée

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