]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpi/test/cartesian_topology_test.cpp
1 // Copyright Alain Miniussi 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 // Authors: Alain Miniussi
15 #include <boost/mpi/communicator.hpp>
16 #include <boost/mpi/collectives.hpp>
17 #include <boost/mpi/environment.hpp>
18 #include <boost/mpi/cartesian_communicator.hpp>
20 #define BOOST_TEST_MODULE mpi_cartesian_topolohy
21 #include <boost/test/included/unit_test.hpp>
23 namespace mpi
= boost::mpi
;
26 mpi::cartesian_dimension
27 operator()(mpi::cartesian_dimension
const& d1
,
28 mpi::cartesian_dimension
const& d2
) const {
29 return mpi::cartesian_dimension(std::min(d1
.size
, d2
.size
),
30 d1
.periodic
&& d2
.periodic
);
34 std::string
topology_description( mpi::cartesian_topology
const& topo
) {
35 std::ostringstream out
;
36 std::copy(topo
.begin(), topo
.end(), std::ostream_iterator
<mpi::cartesian_dimension
>(out
, " "));
41 // Check that everyone agrees on the coordinates
42 void test_coordinates_consistency( mpi::cartesian_communicator
const& cc
,
43 std::vector
<int> const& coords
)
45 cc
.barrier(); // flush IOs for nice printing
46 bool master
= cc
.rank() == 0;
48 std::cout
<< "Test coordinates consistency.\n";
50 for(int p
= 0; p
< cc
.size(); ++p
) {
51 std::vector
<int> min(cc
.ndims());
52 std::vector
<int> local(cc
.coordinates(p
));
53 mpi::reduce(cc
, &local
.front(), local
.size(),
54 &(min
[0]), mpi::minimum
<int>(), p
);
57 BOOST_CHECK(std::equal(coords
.begin(), coords
.end(), min
.begin()));
58 std::ostringstream out
;
59 out
<< "proc " << p
<< " at (";
60 std::copy(min
.begin(), min
.end(), std::ostream_iterator
<int>(out
, " "));
62 std::cout
<< out
.str();
67 void test_shifted_coords( mpi::cartesian_communicator
const& cc
, int pos
, mpi::cartesian_dimension desc
, int dim
)
70 for (int i
= -(desc
.size
); i
< desc
.size
; ++i
) {
71 std::pair
<int,int> rks
= cc
.shifted_ranks(dim
, i
);
72 int src
= cc
.coordinates(rks
.first
)[dim
];
73 int dst
= cc
.coordinates(rks
.second
)[dim
];
75 std::ostringstream out
;
76 out
<< "Rank " << cc
.rank() << ", dim. " << dim
<< ", pos " << pos
<< ", in " << desc
<< ' ';
77 out
<< "shifted pos: " << src
<< ", " << dst
<< '\n';
78 std::cout
<< out
.str();
84 void test_shifted_coords( mpi::cartesian_communicator
const& cc
)
86 cc
.barrier(); // flush IOs for nice printing
87 std::vector
<int> coords
;
88 mpi::cartesian_topology
topo(cc
.ndims());
89 cc
.topology(topo
, coords
);
90 bool master
= cc
.rank() == 0;
92 std::cout
<< "Testing shifts with topology " << topo
<< '\n';
94 for(int i
= 0; i
< cc
.ndims(); ++i
) {
96 std::cout
<< " for dimension " << i
<< ": " << topo
[i
] << '\n';
98 test_shifted_coords( cc
, coords
[i
], topo
[i
], i
);
102 void test_topology_consistency( mpi::cartesian_communicator
const& cc
)
104 cc
.barrier(); // flush IOs for nice printing
105 mpi::cartesian_topology
itopo(cc
.ndims());
106 mpi::cartesian_topology
otopo(cc
.ndims());
107 std::vector
<int> coords(cc
.ndims());
108 cc
.topology(itopo
, coords
);
109 bool master
= cc
.rank() == 0;
111 std::cout
<< "Test topology consistency of" << itopo
<< "(on master)\n";
112 std::cout
<< "Check that everyone agrees on the dimensions.\n";
115 &(itopo
[0]), itopo
.size(), &(otopo
[0]),
117 BOOST_CHECK(std::equal(itopo
.begin(), itopo
.end(), otopo
.begin()));
119 std::cout
<< "We agree on " << topology_description(otopo
) << '\n';
121 test_coordinates_consistency( cc
, coords
);
124 void test_cartesian_topology( mpi::cartesian_communicator
const& cc
)
126 BOOST_CHECK(cc
.has_cartesian_topology());
127 for( int r
= 0; r
< cc
.size(); ++r
) {
129 if (r
== cc
.rank()) {
130 std::vector
<int> coords
= cc
.coordinates(r
);
131 std::cout
<< "Process of cartesian rank " << cc
.rank()
132 << " has coordinates (";
133 std::copy(coords
.begin(), coords
.end(), std::ostream_iterator
<int>(std::cout
," "));
137 test_topology_consistency(cc
);
138 test_shifted_coords(cc
);
139 std::vector
<int> even
;
140 for(int i
= 0; i
< cc
.ndims(); i
+= 2) {
144 mpi::cartesian_communicator
cce(cc
, even
);
147 void test_cartesian_topology( mpi::communicator
const& world
, mpi::cartesian_topology
const& topo
)
149 mpi::cartesian_communicator
cc(world
, topo
, true);
151 BOOST_CHECK(cc
.has_cartesian_topology());
152 BOOST_CHECK(cc
.ndims() == int(topo
.size()));
153 if (cc
.rank() == 0) {
154 std::cout
<< "Asked topology " << topo
<< ", got " << cc
.topology() << '\n';
156 test_cartesian_topology(cc
);
158 std::ostringstream out
;
159 out
<< world
.rank() << " was left outside the cartesian grid\n";
160 std::cout
<< out
.str();
164 BOOST_AUTO_TEST_CASE(cartesian_topology
)
166 mpi::environment env
;
167 mpi::communicator world
;
169 int const ndim
= world
.size() >= 24 ? 3 : 2;
170 mpi::cartesian_topology
topo(ndim
);
171 typedef mpi::cartesian_dimension cd
;
172 if (topo
.size() == 3) {
173 topo
[0] = cd(2,true);
174 topo
[1] = cd(3,false);
175 topo
[2] = cd(4, true);
177 if (world
.size() >= 6) {
178 topo
[0] = cd(2,true);
179 topo
[1] = cd(3, false);
181 topo
[0] = cd(1,true);
182 topo
[1] = cd(1, false);
185 test_cartesian_topology( world
, topo
);
186 #if !defined(BOOST_NO_CXX11_DEFAULTED_MOVES)
188 if (world
.rank()==0) {
189 std::cout
<< "Testing move constructor.\n";
191 test_cartesian_topology( world
, std::move(topo
));