2
0
mirror of https://github.com/boostorg/mpi.git synced 2026-02-26 04:42:23 +00:00

Improved cartesian topology description.

This commit is contained in:
Alain Miniussi
2014-09-12 18:38:45 +02:00
parent a1c6e750cb
commit 0f13d9a20c
4 changed files with 158 additions and 90 deletions

View File

@@ -12,23 +12,37 @@
namespace boost { namespace mpi {
cartesian_communicator::cartesian_communicator(const communicator& comm,
const std::vector<int>& dims,
const std::vector<bool>& periodic,
bool reorder )
std::ostream&
operator<<(std::ostream& out, cartesian_dimension const& d) {
out << '(' << d.size << ',';
if (d.periodic) {
out << "periodic";
} else {
out << "bounded";
}
out << ')';
return out;
}
cartesian_communicator::cartesian_communicator(const communicator& comm,
const cartesian_topology& topology,
bool reorder )
: communicator()
{
BOOST_ASSERT(dims.size() == periodic.size());
MPI_Comm newcomm;
std::vector<int> local_dims = dims;
// Fill the gaps, if any
if (std::count(local_dims.begin(), local_dims.end(), 0) > 0) {
cartesian_dimensions(comm, local_dims);
std::vector<int> dims(topology.size());
std::vector<int> periodic(topology.size());
for(int i = 0; i < topology.size(); ++i) {
dims[i] = topology[i].size;
periodic[i] = topology[i].periodic;
}
std::vector<int> p(periodic.begin(), periodic.end());
// Fill the gaps, if any
if (std::count(dims.begin(), dims.end(), 0) > 0) {
cartesian_dimensions(comm, dims);
}
MPI_Comm newcomm;
BOOST_MPI_CHECK_RESULT(MPI_Cart_create,
((MPI_Comm)comm, dims.size(),
local_dims.data(), p.data(),
dims.data(), periodic.data(),
int(reorder), &newcomm));
if(newcomm != MPI_COMM_NULL) {
comm_ptr.reset(new MPI_Comm(newcomm), comm_free());
@@ -64,7 +78,7 @@ cartesian_communicator::ndims() const {
}
int
cartesian_communicator::rank(std::vector<int> const& coords ) const {
cartesian_communicator::rank(const std::vector<int>& coords ) const {
int r = -1;
BOOST_ASSERT(coords.size() == ndims());
BOOST_MPI_CHECK_RESULT(MPI_Cart_rank,
@@ -72,7 +86,7 @@ cartesian_communicator::rank(std::vector<int> const& coords ) const {
&r));
return r;
}
std::vector<int>&
cartesian_communicator::coords(int rk, std::vector<int>& cbuf) const {
cbuf.resize(ndims());
@@ -80,7 +94,7 @@ cartesian_communicator::coords(int rk, std::vector<int>& cbuf) const {
(MPI_Comm(*this), rk, cbuf.size(), cbuf.data() ));
return cbuf;
}
std::vector<int>
cartesian_communicator::coords(int rk) const {
std::vector<int> coords;
@@ -89,17 +103,29 @@ cartesian_communicator::coords(int rk) const {
}
void
cartesian_communicator::topology( std::vector<int>& dims,
std::vector<bool>& periodic,
std::vector<int>& coords ) const {
cartesian_communicator::topology( cartesian_topology& topo,
std::vector<int>& coords ) const {
int ndims = this->ndims();
dims.resize(ndims);
periodic.resize(ndims);
topo.resize(ndims);
coords.resize(ndims);
std::vector<int> cdims(ndims);
std::vector<int> cperiods(ndims);
BOOST_MPI_CHECK_RESULT(MPI_Cart_get,
(MPI_Comm(*this), ndims, dims.data(), cperiods.data(), coords.data()));
std::copy(cperiods.begin(), cperiods.end(), periodic.begin());
(MPI_Comm(*this), ndims, cdims.data(), cperiods.data(), coords.data()));
cartesian_topology res(cdims.begin(), cperiods.begin(), ndims);
topo.swap(res);
}
void
cartesian_topology::split(std::vector<int>& dims, std::vector<bool>& periodics) const {
int ndims = size();
dims.resize(ndims);
periodics.resize(ndims);
for(int i = 0; i < ndims; ++i) {
cartesian_dimension const& d = (*this)[i];
dims[i] = d.size;
periodics[i] = d.periodic;
}
}
std::vector<int>&