mirror of
https://github.com/boostorg/mpi.git
synced 2026-02-25 16:32:22 +00:00
Merge pull request #13 from aminiussi/nonblocking_test_split
split nonblocking_test in two functions, one to run all tests and one to run simgle tests.29292
This commit is contained in:
@@ -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<typename T>
|
||||
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<typename T>
|
||||
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<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) {
|
||||
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));
|
||||
// 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<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_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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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<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[])
|
||||
@@ -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<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);
|
||||
nonblocking_tests(comm, &lst_of_strings, 1, "list of strings", true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user