diff --git a/test/nonblocking_test.cpp b/test/nonblocking_test.cpp index a3789d7..7ff44b4 100644 --- a/test/nonblocking_test.cpp +++ b/test/nonblocking_test.cpp @@ -24,11 +24,10 @@ enum method_kind { mk_wait_any, mk_test_any, mk_wait_all, mk_wait_all_keep, mk_test_all, mk_test_all_keep, mk_wait_some, mk_wait_some_keep, mk_test_some, mk_test_some_keep, - mk_all, // use to run all of the different methods - mk_all_except_test_all // use for serialized types + mk_test_size }; -static const char* method_kind_names[mk_all] = { +static const char* method_kind_names[mk_test_size] = { "wait_any", "test_any", "wait_all", @@ -42,10 +41,29 @@ static const char* method_kind_names[mk_all] = { }; +template +void +nonblocking_tests( const communicator& comm, const T* values, int num_values, + const char* kind, bool composite) +{ + nonblocking_test(comm, values, num_values, kind, mk_wait_any); + nonblocking_test(comm, values, num_values, kind, mk_test_any); + nonblocking_test(comm, values, num_values, kind, mk_wait_all); + nonblocking_test(comm, values, num_values, kind, mk_wait_all_keep); + if (!composite) { + nonblocking_test(comm, values, num_values, kind, mk_test_all); + nonblocking_test(comm, values, num_values, kind, mk_test_all_keep); + } + nonblocking_test(comm, values, num_values, kind, mk_wait_some); + nonblocking_test(comm, values, num_values, kind, mk_wait_some_keep); + nonblocking_test(comm, values, num_values, kind, mk_test_some); + nonblocking_test(comm, values, num_values, kind, mk_test_some_keep); +} + template void nonblocking_test(const communicator& comm, const T* values, int num_values, - const char* kind, method_kind method = mk_all) + const char* kind, method_kind method) { using boost::mpi::wait_any; using boost::mpi::test_any; @@ -54,167 +72,152 @@ nonblocking_test(const communicator& comm, const T* values, int num_values, using boost::mpi::wait_some; using boost::mpi::test_some; - if (method == mk_all || method == mk_all_except_test_all) { - nonblocking_test(comm, values, num_values, kind, mk_wait_any); - nonblocking_test(comm, values, num_values, kind, mk_test_any); - nonblocking_test(comm, values, num_values, kind, mk_wait_all); - nonblocking_test(comm, values, num_values, kind, mk_wait_all_keep); - if (method == mk_all) { - nonblocking_test(comm, values, num_values, kind, mk_test_all); - nonblocking_test(comm, values, num_values, kind, mk_test_all_keep); - } - nonblocking_test(comm, values, num_values, kind, mk_wait_some); - nonblocking_test(comm, values, num_values, kind, mk_wait_some_keep); - nonblocking_test(comm, values, num_values, kind, mk_test_some); - nonblocking_test(comm, values, num_values, kind, mk_test_some_keep); - } else { - if (comm.rank() == 0) { - std::cout << "Testing " << method_kind_names[method] - << " with " << kind << "..."; - std::cout.flush(); - } - - typedef std::pair::iterator> - status_iterator_pair; - - T incoming_value; - std::vector incoming_values(num_values); - - std::vector reqs; - // Send/receive the first value - reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 0, values[0])); - reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), - 0, incoming_value)); - - if (method != mk_wait_any && method != mk_test_any) { + if (comm.rank() == 0) { + std::cout << "Testing " << method_kind_names[method] + << " with " << kind << "..."; + std::cout.flush(); + } + + typedef std::pair::iterator> + status_iterator_pair; + + T incoming_value; + std::vector incoming_values(num_values); + + std::vector reqs; + // Send/receive the first value + reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 0, values[0])); + reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), + 0, incoming_value)); + + if (method != mk_wait_any && method != mk_test_any) { #ifndef LAM_MPI - // We've run into problems here (with 0-length messages) with - // LAM/MPI on Mac OS X and x86-86 Linux. Will investigate - // further at a later time, but the problem only seems to occur - // when using shared memory, not TCP. - - // Send/receive an empty message - reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 1)); - reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), - 1)); + // We've run into problems here (with 0-length messages) with + // LAM/MPI on Mac OS X and x86-86 Linux. Will investigate + // further at a later time, but the problem only seems to occur + // when using shared memory, not TCP. + + // Send/receive an empty message + reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 1)); + reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), + 1)); #endif - - // Send/receive an array - reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 2, values, - num_values)); - reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), - 2, &incoming_values.front(), num_values)); - } - - switch (method) { - case mk_wait_any: - if (wait_any(reqs.begin(), reqs.end()).second == reqs.begin()) + + // Send/receive an array + reqs.push_back(comm.isend((comm.rank() + 1) % comm.size(), 2, values, + num_values)); + reqs.push_back(comm.irecv((comm.rank() + comm.size() - 1) % comm.size(), + 2, &incoming_values.front(), num_values)); + } + + switch (method) { + case mk_wait_any: + if (wait_any(reqs.begin(), reqs.end()).second == reqs.begin()) + reqs[1].wait(); + else + reqs[0].wait(); + break; + + case mk_test_any: + { + boost::optional result; + do { + result = test_any(reqs.begin(), reqs.end()); + } while (!result); + if (result->second == reqs.begin()) reqs[1].wait(); else reqs[0].wait(); break; - - case mk_test_any: - { - boost::optional result; - do { - result = test_any(reqs.begin(), reqs.end()); - } while (!result); - if (result->second == reqs.begin()) - reqs[1].wait(); - else - reqs[0].wait(); - break; - } - - case mk_wait_all: - wait_all(reqs.begin(), reqs.end()); - break; - - case mk_wait_all_keep: - { - std::vector stats; - wait_all(reqs.begin(), reqs.end(), std::back_inserter(stats)); - } - break; - - case mk_test_all: - while (!test_all(reqs.begin(), reqs.end())) { /* Busy wait */ } - break; - - case mk_test_all_keep: - { - std::vector stats; - while (!test_all(reqs.begin(), reqs.end(), std::back_inserter(stats))) - /* Busy wait */; - } - break; - - case mk_wait_some: - { - std::vector::iterator pos = reqs.end(); - do { - pos = wait_some(reqs.begin(), pos); - } while (pos != reqs.begin()); - } - break; - - case mk_wait_some_keep: - { - std::vector stats; - std::vector::iterator pos = reqs.end(); - do { - pos = wait_some(reqs.begin(), pos, std::back_inserter(stats)).second; - } while (pos != reqs.begin()); - } - break; - - case mk_test_some: - { - std::vector::iterator pos = reqs.end(); - do { - pos = test_some(reqs.begin(), pos); - } while (pos != reqs.begin()); - } - break; - - case mk_test_some_keep: - { - std::vector stats; - std::vector::iterator pos = reqs.end(); - do { - pos = test_some(reqs.begin(), pos, std::back_inserter(stats)).second; - } while (pos != reqs.begin()); - } - break; - - default: - BOOST_CHECK(false); } - - if (comm.rank() == 0) { - bool okay = true; - - if (!((incoming_value == values[0]))) - okay = false; - - if (method != mk_wait_any && method != mk_test_any - && !std::equal(incoming_values.begin(), incoming_values.end(), - values)) - okay = false; - - if (okay) - std::cout << "OK." << std::endl; - else - std::cerr << "ERROR!" << std::endl; + + case mk_wait_all: + wait_all(reqs.begin(), reqs.end()); + break; + + case mk_wait_all_keep: + { + std::vector stats; + wait_all(reqs.begin(), reqs.end(), std::back_inserter(stats)); } - - BOOST_CHECK(incoming_value == values[0]); - - if (method != mk_wait_any && method != mk_test_any) - BOOST_CHECK(std::equal(incoming_values.begin(), incoming_values.end(), - values)); + break; + + case mk_test_all: + while (!test_all(reqs.begin(), reqs.end())) { /* Busy wait */ } + break; + + case mk_test_all_keep: + { + std::vector stats; + while (!test_all(reqs.begin(), reqs.end(), std::back_inserter(stats))) + /* Busy wait */; + } + break; + + case mk_wait_some: + { + std::vector::iterator pos = reqs.end(); + do { + pos = wait_some(reqs.begin(), pos); + } while (pos != reqs.begin()); + } + break; + + case mk_wait_some_keep: + { + std::vector stats; + std::vector::iterator pos = reqs.end(); + do { + pos = wait_some(reqs.begin(), pos, std::back_inserter(stats)).second; + } while (pos != reqs.begin()); + } + break; + + case mk_test_some: + { + std::vector::iterator pos = reqs.end(); + do { + pos = test_some(reqs.begin(), pos); + } while (pos != reqs.begin()); + } + break; + + case mk_test_some_keep: + { + std::vector stats; + std::vector::iterator pos = reqs.end(); + do { + pos = test_some(reqs.begin(), pos, std::back_inserter(stats)).second; + } while (pos != reqs.begin()); + } + break; + + default: + BOOST_CHECK(false); } + + if (comm.rank() == 0) { + bool okay = true; + + if (!((incoming_value == values[0]))) + okay = false; + + if (method != mk_wait_any && method != mk_test_any + && !std::equal(incoming_values.begin(), incoming_values.end(), + values)) + okay = false; + + if (okay) + std::cout << "OK." << std::endl; + else + std::cerr << "ERROR!" << std::endl; + } + + BOOST_CHECK(incoming_value == values[0]); + + if (method != mk_wait_any && method != mk_test_any) + BOOST_CHECK(std::equal(incoming_values.begin(), incoming_values.end(), + values)); } int test_main(int argc, char* argv[]) @@ -224,24 +227,22 @@ int test_main(int argc, char* argv[]) communicator comm; int int_array[3] = {17, 42, 256}; - nonblocking_test(comm, int_array, 3, "integers"); + nonblocking_tests(comm, int_array, 3, "integers", false); gps_position gps_array[2] = { gps_position(17, 42, .06), gps_position(42, 17, .06) }; - nonblocking_test(comm, gps_array, 2, "gps positions"); + nonblocking_tests(comm, gps_array, 2, "gps positions", false); std::string string_array[2] = { "Hello", "World" }; - nonblocking_test(comm, string_array, 2, "strings", - mk_all_except_test_all); + nonblocking_tests(comm, string_array, 2, "strings", true); std::list lst_of_strings; for (int i = 0; i < comm.size(); ++i) lst_of_strings.push_back(boost::lexical_cast(i)); - nonblocking_test(comm, &lst_of_strings, 1, "list of strings", - mk_all_except_test_all); + nonblocking_tests(comm, &lst_of_strings, 1, "list of strings", true); return 0; }