]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/mpi/test/skeleton_content_test.cpp
1 // Copyright 2005 Douglas Gregor.
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)
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>
16 #include <boost/iterator/counting_iterator.hpp>
17 #include <boost/mpi/collectives/broadcast.hpp>
19 using boost::mpi::communicator
;
21 using boost::mpi::packed_skeleton_iarchive
;
22 using boost::mpi::packed_skeleton_oarchive
;
25 test_skeleton_and_content(const communicator
& comm
, int root
,
26 bool manual_broadcast
)
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
;
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
);
41 std::cout
<< "Broadcasting integer list skeleton from root " << root
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
));
48 broadcast(comm
, skeleton(original_list
), root
);
50 std::cout
<< "OK." << std::endl
;
52 // Broadcast the content (manually)
53 std::cout
<< "Broadcasting integer list content from root " << root
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
);
60 std::cout
<< "OK." << std::endl
;
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 "
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
);
71 std::cout
<< "OK." << std::endl
;
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);
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
));
82 broadcast(comm
, skeleton(transferred_list
), root
);
84 BOOST_CHECK((int)transferred_list
.size() == list_size
);
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()));
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()));
103 test_skeleton_and_content_nonblocking(const communicator
& comm
, int root
)
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
;
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
);
120 std::cout
<< "Non-blocking broadcast of integer list skeleton from root " << root
123 // Broadcast the skeleton (manually)
125 std::vector
<request
> reqs
;
126 for (int p
= 0; p
< comm
.size(); ++p
)
128 reqs
.push_back(comm
.isend(p
, 0, skeleton(original_list
)));
129 wait_all(reqs
.begin(), reqs
.end());
131 std::cout
<< "OK." << std::endl
;
133 // Broadcast the content (manually)
134 std::cout
<< "Non-blocking broadcast of integer list content from root " << root
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());
143 std::cout
<< "OK." << std::endl
;
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 "
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());
156 std::cout
<< "OK." << std::endl
;
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);
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
));
166 BOOST_CHECK((int)transferred_list
.size() == list_size
);
168 // Receive the content and check it
169 req
= comm
.irecv(root
, 1, get_content(transferred_list
));
171 BOOST_CHECK(std::equal(make_counting_iterator(0),
172 make_counting_iterator(list_size
),
173 transferred_list
.begin()));
175 // Receive the reversed content and check it
176 req
= comm
.irecv(root
, 2, get_content(transferred_list
));
178 BOOST_CHECK(std::equal(make_counting_iterator(0),
179 make_counting_iterator(list_size
),
180 transferred_list
.rbegin()));
186 int test_main(int argc
, char* argv
[])
188 boost::mpi::environment
env(argc
, argv
);
191 if (comm
.size() == 1) {
192 std::cerr
<< "ERROR: Must run the skeleton and content test with more "
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);