X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/3d25ce2fc68666d4b674c4f710cde362aa584632..d53d00d608a60a6f05e77ea7b7cd5c4e544d7ab1:/src/smpi/colls/reduce-flat-tree.cpp diff --git a/src/smpi/colls/reduce-flat-tree.cpp b/src/smpi/colls/reduce-flat-tree.cpp new file mode 100644 index 0000000000..685fc2ff04 --- /dev/null +++ b/src/smpi/colls/reduce-flat-tree.cpp @@ -0,0 +1,68 @@ +/* Copyright (c) 2013-2014. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "colls_private.h" +//#include + +int +smpi_coll_tuned_reduce_flat_tree(void *sbuf, void *rbuf, int count, + MPI_Datatype dtype, MPI_Op op, + int root, MPI_Comm comm) +{ + int i, tag = COLL_TAG_REDUCE; + int size; + int rank; + MPI_Aint extent; + char *origin = 0; + char *inbuf; + MPI_Status status; + + rank = smpi_comm_rank(comm); + size = smpi_comm_size(comm); + + /* If not root, send data to the root. */ + extent = smpi_datatype_get_extent(dtype); + + if (rank != root) { + smpi_mpi_send(sbuf, count, dtype, root, tag, comm); + return 0; + } + + /* Root receives and reduces messages. Allocate buffer to receive + messages. */ + + if (size > 1) + origin = (char *) smpi_get_tmp_recvbuffer(count * extent); + + + /* Initialize the receive buffer. */ + if (rank == (size - 1)) + smpi_mpi_sendrecv(sbuf, count, dtype, rank, tag, + rbuf, count, dtype, rank, tag, comm, &status); + else + smpi_mpi_recv(rbuf, count, dtype, size - 1, tag, comm, &status); + + /* Loop receiving and calling reduction function (C or Fortran). */ + + for (i = size - 2; i >= 0; --i) { + if (rank == i) + inbuf = static_cast(sbuf); + else { + smpi_mpi_recv(origin, count, dtype, i, tag, comm, &status); + inbuf = origin; + } + + /* Call reduction function. */ + smpi_op_apply(op, inbuf, rbuf, &count, &dtype); + + } + + if (origin) + smpi_free_tmp_buffer(origin); + + /* All done */ + return 0; +}