]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/graph_parallel/test/distributed_property_map_test.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / graph_parallel / test / distributed_property_map_test.cpp
CommitLineData
7c673cae
FG
1// Copyright (C) 2004-2008 The Trustees of Indiana University.
2
3// Use, modification and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7// Authors: Douglas Gregor
8// Andrew Lumsdaine
9#include <boost/graph/use_mpi.hpp>
10#include <boost/config.hpp>
11#include <boost/throw_exception.hpp>
12#include <boost/graph/distributed/mpi_process_group.hpp>
13#include <boost/property_map/property_map.hpp>
1e59de90 14#include <boost/core/lightweight_test.hpp>
7c673cae
FG
15#include <vector>
16#include <string>
17#include <boost/serialization/vector.hpp>
18#include <boost/serialization/string.hpp>
19#include <boost/serialization/utility.hpp>
20#include <boost/lexical_cast.hpp>
21#include <boost/graph/parallel/basic_reduce.hpp>
22
23#ifdef BOOST_NO_EXCEPTIONS
24void
25boost::throw_exception(std::exception const& ex)
26{
27 std::cout << ex.what() << std::endl;
28 abort();
29}
30#endif
31
32using namespace boost;
33using boost::graph::distributed::mpi_process_group;
34
35enum color_t { red, blue };
36
37struct remote_key
38{
39 remote_key(int p = -1, std::size_t l = 0) : processor(p), local_key(l) {}
40
41 int processor;
42 std::size_t local_key;
43
44 template<typename Archiver>
45 void serialize(Archiver& ar, const unsigned int /*version*/)
46 {
47 ar & processor & local_key;
48 }
49};
50
51namespace boost { namespace mpi {
52 template<> struct is_mpi_datatype<remote_key> : mpl::true_ { };
53} }
54BOOST_IS_BITWISE_SERIALIZABLE(remote_key)
55BOOST_CLASS_IMPLEMENTATION(remote_key,object_serializable)
56BOOST_CLASS_TRACKING(remote_key,track_never)
57
58namespace boost {
59
60template<>
61struct hash<remote_key>
62{
63 std::size_t operator()(const remote_key& key) const
64 {
65 std::size_t hash = hash_value(key.processor);
66 hash_combine(hash, key.local_key);
67 return hash;
68 }
69};
70}
71
72inline bool operator==(const remote_key& x, const remote_key& y)
73{ return x.processor == y.processor && x.local_key == y.local_key; }
74
75struct remote_key_to_global
76{
77 typedef readable_property_map_tag category;
78 typedef remote_key key_type;
79 typedef std::pair<int, std::size_t> value_type;
80 typedef value_type reference;
81};
82
83inline std::pair<int, std::size_t>
84get(remote_key_to_global, const remote_key& key)
85{
86 return std::make_pair(key.processor, key.local_key);
87}
88
89template<typename T>
90struct my_reduce : boost::parallel::basic_reduce<T> {
91 BOOST_STATIC_CONSTANT(bool, non_default_resolver = true);
92};
93
94void colored_test()
95{
96 mpi_process_group pg;
97 const int n = 500;
98
99 color_t my_start_color = process_id(pg) % 2 == 0? ::red : ::blue;
100 int next_processor = (process_id(pg) + 1) % num_processes(pg);
101 color_t next_start_color = next_processor % 2 == 0? ::red : ::blue;
102
103 // Initial color map: even-numbered processes are all red,
104 // odd-numbered processes are all blue.
105 std::vector<color_t> color_vec(n, my_start_color);
106
107 typedef iterator_property_map<std::vector<color_t>::iterator,
108 identity_property_map> LocalPropertyMap;
109 LocalPropertyMap local_colors(color_vec.begin(), identity_property_map());
110
111 synchronize(pg);
112
113 // Create the distributed property map
114 typedef boost::parallel::distributed_property_map<mpi_process_group,
115 remote_key_to_global,
116 LocalPropertyMap> ColorMap;
117 ColorMap colors(pg, remote_key_to_global(), local_colors);
118 colors.set_reduce(my_reduce<color_t>());
119
120 if (process_id(pg) == 0) std::cerr << "Checking local colors...";
121 // check local processor colors
122 for (int i = 0; i < n; ++i) {
123 remote_key k(process_id(pg), i);
1e59de90 124 BOOST_TEST(get(colors, k) == my_start_color);
7c673cae
FG
125 }
126
127 colors.set_consistency_model(boost::parallel::cm_bidirectional);
128 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's default colors...";
129 // check next processor's colors
130 for (int i = 0; i < n; ++i) {
131 remote_key k(next_processor, i);
1e59de90 132 BOOST_TEST(get(colors, k) == color_t());
7c673cae
FG
133 }
134
135 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
136 synchronize(pg);
137
138 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's colors...";
139 // check next processor's colors
140 for (int i = 0; i < n; ++i) {
141 remote_key k(next_processor, i);
1e59de90 142 BOOST_TEST(get(colors, k) == next_start_color);
7c673cae
FG
143 }
144
145 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
146 synchronize(pg);
147
148 if (process_id(pg) == 0) std::cerr << "OK.\nChanging next processor's colors...";
149 // change the next processor's colors
150 color_t next_finish_color = next_processor % 2 == 0? ::blue : ::red;
151 for (int i = 0; i < n; ++i) {
152 remote_key k(next_processor, i);
153 put(colors, k, next_finish_color);
154 }
155
156 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
157 synchronize(pg);
158
159 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed colors...";
160 // check our own colors
161 color_t my_finish_color = process_id(pg) % 2 == 0? ::blue : ::red;
162 for (int i = 0; i < n; ++i) {
163 remote_key k(process_id(pg), i);
1e59de90 164 BOOST_TEST(get(colors, k) == my_finish_color);
7c673cae
FG
165 }
166
167 // check our neighbor's colors
168 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed colors on neighbor...";
169 for (int i = 0; i < n; ++i) {
170 remote_key k(next_processor, i);
1e59de90 171 BOOST_TEST(get(colors, k) == next_finish_color);
7c673cae
FG
172 }
173
174 synchronize(pg);
175
176 if (process_id(pg) == 0) std::cerr << "OK.\n";
177}
178
179void bool_test()
180{
181 mpi_process_group pg;
182 const int n = 500;
183
184 bool my_start_value = process_id(pg) % 2;
185 int next_processor = (process_id(pg) + 1) % num_processes(pg);
186 bool next_start_value = ((process_id(pg) + 1) % num_processes(pg)) % 2;
187
188 // Initial color map: even-numbered processes are false,
189 // odd-numbered processes are true
190 std::vector<bool> bool_vec(n, my_start_value);
191
192 typedef iterator_property_map<std::vector<bool>::iterator,
193 identity_property_map> LocalPropertyMap;
194 LocalPropertyMap local_values(bool_vec.begin(), identity_property_map());
195
196 synchronize(pg);
197
198 // Create the distributed property map
199 typedef boost::parallel::distributed_property_map<mpi_process_group,
200 remote_key_to_global,
201 LocalPropertyMap> ValueMap;
202 ValueMap values(pg, remote_key_to_global(), local_values);
203 values.set_reduce(my_reduce<bool>());
204
205 if (process_id(pg) == 0) std::cerr << "Checking local values...";
206 // check local processor values
207 for (int i = 0; i < n; ++i) {
208 remote_key k(process_id(pg), i);
1e59de90 209 BOOST_TEST(get(values, k) == my_start_value);
7c673cae
FG
210 }
211
212 values.set_consistency_model(boost::parallel::cm_bidirectional);
213 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's default values...";
214 // check next processor's values
215 for (int i = 0; i < n; ++i) {
216 remote_key k(next_processor, i);
1e59de90 217 BOOST_TEST(get(values, k) == false);
7c673cae
FG
218 }
219
220 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
221 synchronize(pg);
222
223 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's values...";
224 // check next processor's values
225 for (int i = 0; i < n; ++i) {
226 remote_key k(next_processor, i);
1e59de90 227 BOOST_TEST(get(values, k) == next_start_value);
7c673cae
FG
228 }
229
230 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
231 synchronize(pg);
232
233 if (process_id(pg) == 0) std::cerr << "OK.\nChanging next processor's values...";
234 // change the next processor's values
235 bool next_finish_value = next_processor % 2 == 0;
236 for (int i = 0; i < n; ++i) {
237 remote_key k(next_processor, i);
238 put(values, k, next_finish_value);
239 }
240
241 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
242 synchronize(pg);
243
244 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed values...";
245 // check our own values
246 bool my_finish_value = process_id(pg) % 2 == 0;
247 for (int i = 0; i < n; ++i) {
248 remote_key k(process_id(pg), i);
1e59de90 249 BOOST_TEST(get(values, k) == my_finish_value);
7c673cae
FG
250 }
251
252 // check our neighbor's values
253 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed values on neighbor...";
254 for (int i = 0; i < n; ++i) {
255 remote_key k(next_processor, i);
1e59de90 256 BOOST_TEST(get(values, k) == next_finish_value);
7c673cae
FG
257 }
258
259 synchronize(pg);
260
261 if (process_id(pg) == 0) std::cerr << "OK.\n";
262}
263
264void string_test()
265{
266 mpi_process_group pg;
267 const int n = 500;
268
269 std::string my_start_string = lexical_cast<std::string>(process_id(pg));
270 int next_processor = (process_id(pg) + 1) % num_processes(pg);
271 std::string next_start_string = lexical_cast<std::string>(next_processor);
272
273 // Initial color map: even-numbered processes are false,
274 // odd-numbered processes are true
275 std::vector<std::string> string_vec(n, my_start_string);
276
277 typedef iterator_property_map<std::vector<std::string>::iterator,
278 identity_property_map> LocalPropertyMap;
279 LocalPropertyMap local_strings(string_vec.begin(), identity_property_map());
280
281 synchronize(pg);
282
283 // Create the distributed property map
284 typedef boost::parallel::distributed_property_map<mpi_process_group,
285 remote_key_to_global,
286 LocalPropertyMap> StringMap;
287 StringMap strings(pg, remote_key_to_global(), local_strings);
288 strings.set_reduce(my_reduce<std::string>());
289
290 if (process_id(pg) == 0) std::cerr << "Checking local strings...";
291 // check local processor strings
292 for (int i = 0; i < n; ++i) {
293 remote_key k(process_id(pg), i);
1e59de90 294 BOOST_TEST(get(strings, k) == my_start_string);
7c673cae
FG
295 }
296
297 strings.set_consistency_model(boost::parallel::cm_bidirectional);
298 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's default strings...";
299 // check next processor's strings
300 for (int i = 0; i < n; ++i) {
301 remote_key k(next_processor, i);
1e59de90 302 BOOST_TEST(get(strings, k) == (num_processes(pg) == 1 ? my_start_string : std::string()));
7c673cae
FG
303 }
304
305 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
306 synchronize(pg);
307
308 if (process_id(pg) == 0) std::cerr << "OK.\nChecking next processor's strings...";
309 // check next processor's strings
310 for (int i = 0; i < n; ++i) {
311 remote_key k(next_processor, i);
1e59de90 312 BOOST_TEST(get(strings, k) == next_start_string);
7c673cae
FG
313 }
314
315 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
316 synchronize(pg);
317
318 if (process_id(pg) == 0) std::cerr << "OK.\nChanging next processor's strings...";
319 // change the next processor's strings
320 std::string next_finish_string = next_start_string + next_start_string;
321 for (int i = 0; i < n; ++i) {
322 remote_key k(next_processor, i);
323 put(strings, k, next_finish_string);
324 }
325
326 if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
327 synchronize(pg);
328
329 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed strings...";
330 // check our own strings
331 std::string my_finish_string = my_start_string + my_start_string;
332 for (int i = 0; i < n; ++i) {
333 remote_key k(process_id(pg), i);
1e59de90 334 BOOST_TEST(get(strings, k) == my_finish_string);
7c673cae
FG
335 }
336
337 // check our neighbor's strings
338 if (process_id(pg) == 0) std::cerr << "OK.\nChecking changed strings on neighbor...";
339 for (int i = 0; i < n; ++i) {
340 remote_key k(next_processor, i);
1e59de90 341 BOOST_TEST(get(strings, k) == next_finish_string);
7c673cae
FG
342 }
343
344 synchronize(pg);
345
346 if (process_id(pg) == 0) std::cerr << "OK.\n";
347}
348
1e59de90 349int main(int argc, char** argv)
7c673cae
FG
350{
351 boost::mpi::environment env(argc, argv);
352 colored_test();
353 bool_test();
354 string_test();
1e59de90 355 return boost::report_errors();
7c673cae 356}