Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[sonar] Use unsigned char* for smpi buffers.
[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(const 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   unsigned char* origin = nullptr;
21   const unsigned 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 = smpi_get_tmp_recvbuffer(count * extent);
40
41   /* Initialize the receive buffer. */
42   if (rank == (size - 1))
43     Request::sendrecv(sbuf, count, dtype, rank, tag,
44                  rbuf, count, dtype, rank, tag, comm, &status);
45   else
46     Request::recv(rbuf, count, dtype, size - 1, tag, comm, &status);
47
48   /* Loop receiving and calling reduction function (C or Fortran). */
49
50   for (i = size - 2; i >= 0; --i) {
51     if (rank == i)
52       inbuf = static_cast<const unsigned char*>(sbuf);
53     else {
54       Request::recv(origin, count, dtype, i, tag, comm, &status);
55       inbuf = origin;
56     }
57
58     /* Call reduction function. */
59     if(op!=MPI_OP_NULL) op->apply( inbuf, rbuf, &count, dtype);
60
61   }
62
63   smpi_free_tmp_buffer(origin);
64
65   /* All done */
66   return 0;
67 }
68 }
69 }