]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/mpi/test/ring_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / mpi / test / ring_test.cpp
CommitLineData
7c673cae
FG
1// Copyright (C) 2005, 2006 Douglas Gregor.
2
3// Use, modification and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7// A test of the communicator that passes data around a ring and
8// verifies that the same data makes it all the way. Should test all
9// of the various kinds of data that can be sent (primitive types, POD
10// types, serializable objects, etc.)
11#include <boost/mpi/communicator.hpp>
12#include <boost/mpi/environment.hpp>
7c673cae
FG
13#include <algorithm>
14#include "gps_position.hpp"
15#include <boost/serialization/string.hpp>
16#include <boost/serialization/list.hpp>
92f5a8d4
TL
17//#include "debugger.cpp"
18
19#define BOOST_TEST_MODULE mpi_reduce_ring
20#include <boost/test/included/unit_test.hpp>
7c673cae
FG
21
22using boost::mpi::communicator;
23using boost::mpi::status;
24
25template<typename T>
26void
27ring_test(const communicator& comm, const T& pass_value, const char* kind,
28 int root = 0)
29{
30 T transferred_value;
31
32 int rank = comm.rank();
33 int size = comm.size();
34
35 if (rank == root) {
36 std::cout << "Passing " << kind << " around a ring from root " << root
37 << "...";
38 comm.send((rank + 1) % size, 0, pass_value);
39 comm.recv((rank + size - 1) % size, 0, transferred_value);
40 BOOST_CHECK(transferred_value == pass_value);
41 if (transferred_value == pass_value) std::cout << " OK." << std::endl;
42 } else {
43 comm.recv((rank + size - 1) % size, 0, transferred_value);
44 BOOST_CHECK(transferred_value == pass_value);
45 comm.send((rank + 1) % size, 0, transferred_value);
46 }
47
48 (comm.barrier)();
49}
50
51
52template<typename T>
53void
54ring_array_test(const communicator& comm, const T* pass_values,
55 int n, const char* kind, int root = 0)
56{
57 T* transferred_values = new T[n];
58 int rank = comm.rank();
59 int size = comm.size();
60
61 if (rank == root) {
62
63 std::cout << "Passing " << kind << " array around a ring from root "
64 << root << "...";
65 comm.send((rank + 1) % size, 0, pass_values, n);
66 comm.recv((rank + size - 1) % size, 0, transferred_values, n);
67 bool okay = std::equal(pass_values, pass_values + n,
68 transferred_values);
69 BOOST_CHECK(okay);
70 if (okay) std::cout << " OK." << std::endl;
71 } else {
72 status stat = comm.probe(boost::mpi::any_source, 0);
73 boost::optional<int> num_values = stat.template count<T>();
74 if (boost::mpi::is_mpi_datatype<T>())
75 BOOST_CHECK(num_values && *num_values == n);
76 else
77 BOOST_CHECK(!num_values || *num_values == n);
78 comm.recv(stat.source(), 0, transferred_values, n);
79 BOOST_CHECK(std::equal(pass_values, pass_values + n,
80 transferred_values));
81 comm.send((rank + 1) % size, 0, transferred_values, n);
82 }
83 (comm.barrier)();
84 delete [] transferred_values;
85}
86
87enum color_t {red, green, blue};
88BOOST_IS_MPI_DATATYPE(color_t)
89
92f5a8d4 90BOOST_AUTO_TEST_CASE(ring)
7c673cae 91{
92f5a8d4 92 boost::mpi::environment env;
7c673cae 93 communicator comm;
92f5a8d4
TL
94
95 BOOST_TEST_REQUIRE(comm.size() > 1);
7c673cae
FG
96
97 // Check transfer of individual objects
98 ring_test(comm, 17, "integers", 0);
99 ring_test(comm, 17, "integers", 1);
100 ring_test(comm, red, "enums", 1);
101 ring_test(comm, red, "enums", 1);
102 ring_test(comm, gps_position(39,16,20.2799), "GPS positions", 0);
103 ring_test(comm, gps_position(26,25,30.0), "GPS positions", 1);
104 ring_test(comm, std::string("Rosie"), "string", 0);
105
106 std::list<std::string> strings;
107 strings.push_back("Hello");
108 strings.push_back("MPI");
109 strings.push_back("World");
110 ring_test(comm, strings, "list of strings", 1);
111
112 // Check transfer of arrays
113 int int_array[2] = { 17, 42 };
114 ring_array_test(comm, int_array, 2, "integer", 1);
115 gps_position gps_position_array[2] = {
116 gps_position(39,16,20.2799),
117 gps_position(26,25,30.0)
118 };
119 ring_array_test(comm, gps_position_array, 2, "GPS position", 1);
120
121 std::string string_array[3] = { "Hello", "MPI", "World" };
122 ring_array_test(comm, string_array, 3, "string", 0);
123 ring_array_test(comm, string_array, 3, "string", 1);
7c673cae 124}