123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- // Copyright (C) 2004-2006 The Trustees of Indiana University.
- // Use, modification and distribution is subject to the Boost Software
- // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- // Authors: Douglas Gregor
- // Andrew Lumsdaine
- #include <boost/graph/use_mpi.hpp>
- #include <boost/config.hpp>
- #include <boost/throw_exception.hpp>
- #include <boost/serialization/vector.hpp>
- #include <boost/graph/distributed/queue.hpp>
- #include <boost/test/minimal.hpp>
- #include <boost/graph/distributed/mpi_process_group.hpp>
- #include <boost/pending/queue.hpp>
- #include <boost/property_map/property_map.hpp>
- #include <utility>
- #include <iostream>
- #ifdef BOOST_NO_EXCEPTIONS
- void
- boost::throw_exception(std::exception const& ex)
- {
- std::cout << ex.what() << std::endl;
- abort();
- }
- #endif
- using boost::graph::distributed::mpi_process_group;
- struct global_value
- {
- global_value(int p = -1, std::size_t l = 0) : processor(p), value(l) {}
- int processor;
- std::size_t value;
- template<typename Archiver>
- void serialize(Archiver& ar, const unsigned int /*version*/)
- {
- ar & processor & value;
- }
- };
- namespace boost { namespace mpi {
- template<> struct is_mpi_datatype<global_value> : mpl::true_ { };
- } } // end namespace boost::mpi
- BOOST_IS_BITWISE_SERIALIZABLE(global_value)
- BOOST_CLASS_IMPLEMENTATION(global_value,object_serializable)
- BOOST_CLASS_TRACKING(global_value,track_never)
- inline bool operator==(const global_value& x, const global_value& y)
- { return x.processor == y.processor && x.value == y.value; }
- struct global_value_owner_map
- {
- typedef int value_type;
- typedef value_type reference;
- typedef global_value key_type;
- typedef boost::readable_property_map_tag category;
- };
- int get(global_value_owner_map, global_value k)
- {
- return k.processor;
- }
- void test_distributed_queue()
- {
- mpi_process_group process_group;
- typedef boost::queue<global_value> local_queue_type;
- typedef boost::graph::distributed::distributed_queue<mpi_process_group,
- global_value_owner_map,
- local_queue_type> dist_queue_type;
- dist_queue_type Q(process_group, global_value_owner_map());
- mpi_process_group::process_id_type id = process_id(process_group),
- n = num_processes(process_group);
- global_value v(0, 0);
- if (id == 0) {
- std::cerr << "Should print level of each processor in a binary tree:\n";
- }
- synchronize(process_group);
- if (id == n-1) Q.push(v);
- while (!Q.empty()) {
- v = Q.top(); Q.pop();
-
- std::cerr << "#" << id << ": level = " << v.value << std::endl;
- int level_begin = 1;
- for (std::size_t i = 0; i < v.value; ++i) level_begin *= 2;
- int level_end = level_begin * 2;
- BOOST_CHECK(level_begin <= (id + 1));
- BOOST_CHECK((id + 1) <= level_end);
- ++v.value;
- v.processor = v.processor * 2 + 1;
- if (v.processor < n) Q.push(v);
- ++v.processor;
- if (v.processor < n) Q.push(v);
- }
- }
- int test_main(int argc, char** argv)
- {
- boost::mpi::environment env(argc, argv);
- test_distributed_queue();
- return 0;
- }
|