nonblocking_test.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 248 行

CPP
248
字号
// Copyright (C) 2006 Douglas Gregor.// 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)// A test of the nonblocking point-to-point operations.#include <boost/mpi/nonblocking.hpp>#include <boost/mpi/communicator.hpp>#include <boost/mpi/environment.hpp>#include <boost/test/minimal.hpp>#include "gps_position.hpp"#include <boost/lexical_cast.hpp>#include <boost/serialization/string.hpp>#include <boost/serialization/list.hpp>#include <iterator>#include <algorithm>using boost::mpi::communicator;using boost::mpi::request;using boost::mpi::status;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};static char* method_kind_names[mk_all] = {  "wait_any",  "test_any",  "wait_all",  "wait_all (keep results)",  "test_all",  "test_all (keep results)",  "wait_some",  "wait_some (keep results)",  "test_some",  "test_some (keep results)"};template<typename T>voidnonblocking_test(const communicator& comm, const T* values, int num_values,                  const char* kind, method_kind method = mk_all){  using boost::mpi::wait_any;  using boost::mpi::test_any;  using boost::mpi::wait_all;  using boost::mpi::test_all;  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<status, std::vector<request>::iterator>       status_iterator_pair;    T incoming_value;    std::vector<T> incoming_values(num_values);    std::vector<request> 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));#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())        reqs[1].wait();      else        reqs[0].wait();      break;    case mk_test_any:      {        boost::optional<status_iterator_pair> 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<status> 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<status> stats;        while (!test_all(reqs.begin(), reqs.end(), std::back_inserter(stats)))          /* Busy wait */;      }      break;    case mk_wait_some:      {        std::vector<request>::iterator pos = reqs.end();        do {          pos = wait_some(reqs.begin(), pos);        } while (pos != reqs.begin());      }      break;    case mk_wait_some_keep:      {        std::vector<status> stats;        std::vector<request>::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<request>::iterator pos = reqs.end();        do {          pos = test_some(reqs.begin(), pos);        } while (pos != reqs.begin());      }      break;    case mk_test_some_keep:      {        std::vector<status> stats;        std::vector<request>::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[]){  boost::mpi::environment env(argc, argv);  communicator comm;  int int_array[3] = {17, 42, 256};  nonblocking_test(comm, int_array, 3, "integers");  gps_position gps_array[2] = {    gps_position(17, 42, .06),    gps_position(42, 17, .06)  };  nonblocking_test(comm, gps_array, 2, "gps positions");  std::string string_array[2] = { "Hello", "World" };  nonblocking_test(comm, string_array, 2, "strings",                    mk_all_except_test_all);  std::list<std::string> lst_of_strings;  for (int i = 0; i < comm.size(); ++i)    lst_of_strings.push_back(boost::lexical_cast<std::string>(i));  nonblocking_test(comm, &lst_of_strings, 1, "list of strings",                    mk_all_except_test_all);  return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?