]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpi/test/skeleton_content_test.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / mpi / test / skeleton_content_test.cpp
1 // Copyright 2005 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 transmits skeletons and
8 // content for data types.
9 #include <boost/mpi/communicator.hpp>
10 #include <boost/mpi/environment.hpp>
11 #include <boost/test/minimal.hpp>
12 #include <boost/serialization/list.hpp>
13 #include <boost/mpi/skeleton_and_content.hpp>
14 #include <boost/mpi/nonblocking.hpp>
15 #include <algorithm>
16 #include <boost/iterator/counting_iterator.hpp>
17 #include <boost/mpi/collectives/broadcast.hpp>
18
19 using boost::mpi::communicator;
20
21 using boost::mpi::packed_skeleton_iarchive;
22 using boost::mpi::packed_skeleton_oarchive;
23
24 void
25 test_skeleton_and_content(const communicator& comm, int root,
26 bool manual_broadcast)
27 {
28 using boost::mpi::skeleton;
29 using boost::mpi::content;
30 using boost::mpi::get_content;
31 using boost::make_counting_iterator;
32 using boost::mpi::broadcast;
33
34 int list_size = comm.size() + 7;
35 if (comm.rank() == root) {
36 // Fill in the seed data
37 std::list<int> original_list;
38 for (int i = 0; i < list_size; ++i)
39 original_list.push_back(i);
40
41 std::cout << "Broadcasting integer list skeleton from root " << root
42 << "...";
43 if (manual_broadcast) {
44 // Broadcast the skeleton (manually)
45 for (int p = 0; p < comm.size(); ++p)
46 if (p != root) comm.send(p, 0, skeleton(original_list));
47 } else {
48 broadcast(comm, skeleton(original_list), root);
49 }
50 std::cout << "OK." << std::endl;
51
52 // Broadcast the content (manually)
53 std::cout << "Broadcasting integer list content from root " << root
54 << "...";
55 {
56 content c = get_content(original_list);
57 for (int p = 0; p < comm.size(); ++p)
58 if (p != root) comm.send(p, 1, c);
59 }
60 std::cout << "OK." << std::endl;
61
62 // Reverse the list, broadcast the content again
63 std::reverse(original_list.begin(), original_list.end());
64 std::cout << "Broadcasting reversed integer list content from root "
65 << root << "...";
66 {
67 content c = get_content(original_list);
68 for (int p = 0; p < comm.size(); ++p)
69 if (p != root) comm.send(p, 2, c);
70 }
71 std::cout << "OK." << std::endl;
72 } else {
73 // Allocate some useless data, to try to get the addresses of the
74 // list<int>'s used later to be different across processes.
75 std::list<int> junk_list(comm.rank() * 3 + 1, 17);
76
77 // Receive the skeleton to build up the transferred list
78 std::list<int> transferred_list;
79 if (manual_broadcast) {
80 comm.recv(root, 0, skeleton(transferred_list));
81 } else {
82 broadcast(comm, skeleton(transferred_list), root);
83 }
84 BOOST_CHECK((int)transferred_list.size() == list_size);
85
86 // Receive the content and check it
87 comm.recv(root, 1, get_content(transferred_list));
88 BOOST_CHECK(std::equal(make_counting_iterator(0),
89 make_counting_iterator(list_size),
90 transferred_list.begin()));
91
92 // Receive the reversed content and check it
93 comm.recv(root, 2, get_content(transferred_list));
94 BOOST_CHECK(std::equal(make_counting_iterator(0),
95 make_counting_iterator(list_size),
96 transferred_list.rbegin()));
97 }
98
99 (comm.barrier)();
100 }
101
102 void
103 test_skeleton_and_content_nonblocking(const communicator& comm, int root)
104 {
105 using boost::mpi::skeleton;
106 using boost::mpi::content;
107 using boost::mpi::get_content;
108 using boost::make_counting_iterator;
109 using boost::mpi::broadcast;
110 using boost::mpi::request;
111 using boost::mpi::wait_all;
112
113 int list_size = comm.size() + 7;
114 if (comm.rank() == root) {
115 // Fill in the seed data
116 std::list<int> original_list;
117 for (int i = 0; i < list_size; ++i)
118 original_list.push_back(i);
119
120 std::cout << "Non-blocking broadcast of integer list skeleton from root " << root
121 << "...";
122
123 // Broadcast the skeleton (manually)
124 {
125 std::vector<request> reqs;
126 for (int p = 0; p < comm.size(); ++p)
127 if (p != root)
128 reqs.push_back(comm.isend(p, 0, skeleton(original_list)));
129 wait_all(reqs.begin(), reqs.end());
130 }
131 std::cout << "OK." << std::endl;
132
133 // Broadcast the content (manually)
134 std::cout << "Non-blocking broadcast of integer list content from root " << root
135 << "...";
136 {
137 content c = get_content(original_list);
138 std::vector<request> reqs;
139 for (int p = 0; p < comm.size(); ++p)
140 if (p != root) reqs.push_back(comm.isend(p, 1, c));
141 wait_all(reqs.begin(), reqs.end());
142 }
143 std::cout << "OK." << std::endl;
144
145 // Reverse the list, broadcast the content again
146 std::reverse(original_list.begin(), original_list.end());
147 std::cout << "Non-blocking broadcast of reversed integer list content from root "
148 << root << "...";
149 {
150 std::vector<request> reqs;
151 content c = get_content(original_list);
152 for (int p = 0; p < comm.size(); ++p)
153 if (p != root) reqs.push_back(comm.isend(p, 2, c));
154 wait_all(reqs.begin(), reqs.end());
155 }
156 std::cout << "OK." << std::endl;
157 } else {
158 // Allocate some useless data, to try to get the addresses of the
159 // list<int>'s used later to be different across processes.
160 std::list<int> junk_list(comm.rank() * 3 + 1, 17);
161
162 // Receive the skeleton to build up the transferred list
163 std::list<int> transferred_list;
164 request req = comm.irecv(root, 0, skeleton(transferred_list));
165 req.wait();
166 BOOST_CHECK((int)transferred_list.size() == list_size);
167
168 // Receive the content and check it
169 req = comm.irecv(root, 1, get_content(transferred_list));
170 req.wait();
171 BOOST_CHECK(std::equal(make_counting_iterator(0),
172 make_counting_iterator(list_size),
173 transferred_list.begin()));
174
175 // Receive the reversed content and check it
176 req = comm.irecv(root, 2, get_content(transferred_list));
177 req.wait();
178 BOOST_CHECK(std::equal(make_counting_iterator(0),
179 make_counting_iterator(list_size),
180 transferred_list.rbegin()));
181 }
182
183 (comm.barrier)();
184 }
185
186 int test_main(int argc, char* argv[])
187 {
188 boost::mpi::environment env(argc, argv);
189
190 communicator comm;
191 if (comm.size() == 1) {
192 std::cerr << "ERROR: Must run the skeleton and content test with more "
193 "than one process."
194 << std::endl;
195 MPI_Abort(comm, -1);
196 }
197
198 test_skeleton_and_content(comm, 0, true);
199 test_skeleton_and_content(comm, 0, false);
200 test_skeleton_and_content(comm, 1, true);
201 test_skeleton_and_content(comm, 1, false);
202 test_skeleton_and_content_nonblocking(comm, 0);
203 test_skeleton_and_content_nonblocking(comm, 1);
204
205 return 0;
206 }