diff options
Diffstat (limited to 'src/boost/libs/mpi/example/random_content.cpp')
-rw-r--r-- | src/boost/libs/mpi/example/random_content.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/boost/libs/mpi/example/random_content.cpp b/src/boost/libs/mpi/example/random_content.cpp new file mode 100644 index 00000000..22fd06d8 --- /dev/null +++ b/src/boost/libs/mpi/example/random_content.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2006 Douglas Gregor <doug.gregor@gmail.com> + +// 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) + +// An example using Boost.MPI's skeletons and content to optimize +// communication. +#include <boost/mpi.hpp> +#include <boost/serialization/list.hpp> +#include <algorithm> +#include <functional> +#include <numeric> +#include <iostream> +#include <stdlib.h> +namespace mpi = boost::mpi; + +int main(int argc, char* argv[]) +{ + mpi::environment env(argc, argv); + mpi::communicator world; + + if (world.size() < 2 || world.size() > 4) { + if (world.rank() == 0) + std::cerr << "error: please execute this program with 2-4 processes.\n"; + world.abort(-1); + } + + if (world.rank() == 0) { + int list_len = 50; + int iterations = 10; + + if (argc > 1) list_len = atoi(argv[1]); + if (argc > 2) iterations = atoi(argv[2]); + + if (list_len <= 0) { + std::cerr << "error: please specific a list length greater than zero.\n"; + world.abort(-1); + } + + // Generate the list and broadcast its structure + std::list<int> l(list_len); + broadcast(world, mpi::skeleton(l), 0); + + // Generate content several times and broadcast out that content + mpi::content c = mpi::get_content(l); + for (int i = 0; i < iterations; ++i) { + do { + std::generate(l.begin(), l.end(), &random); + } while (std::find_if(l.begin(), l.end(), + std::bind1st(std::not_equal_to<int>(), 0)) + == l.end()); + + + std::cout << "Iteration #" << i << ": sending content" + << " (min = " << *std::min_element(l.begin(), l.end()) + << ", max = " << *std::max_element(l.begin(), l.end()) + << ", avg = " + << std::accumulate(l.begin(), l.end(), 0)/l.size() + << ").\n"; + + broadcast(world, c, 0); + } + + // Notify the slaves that we're done by sending all zeroes + std::fill(l.begin(), l.end(), 0); + broadcast(world, c, 0); + + } else { + // Receive the content and build up our own list + std::list<int> l; + broadcast(world, mpi::skeleton(l), 0); + + mpi::content c = mpi::get_content(l); + int i = 0; + do { + broadcast(world, c, 0); + + if (std::find_if(l.begin(), l.end(), + std::bind1st(std::not_equal_to<int>(), 0)) == l.end()) + break; + + if (world.rank() == 1) + std::cout << "Iteration #" << i << ": max value = " + << *std::max_element(l.begin(), l.end()) << ".\n"; + else if (world.rank() == 2) + std::cout << "Iteration #" << i << ": min value = " + << *std::min_element(l.begin(), l.end()) << ".\n"; + else if (world.rank() == 3) + std::cout << "Iteration #" << i << ": avg value = " + << std::accumulate(l.begin(), l.end(), 0)/l.size() + << ".\n"; + ++i; + } while (true); + } + + return 0; +} |