comm.barrier();
}
+template<typename Generator>
+void
+scatterd_test(const communicator& comm, Generator generator,
+ const char* kind, int root = -1)
+{
+ typedef typename Generator::result_type value_type;
+
+ if (root == -1) {
+ for (root = 0; root < comm.size(); ++root)
+ scatterv_test(comm, generator, kind, root);
+ } else {
+ using boost::mpi::scatterv;
+
+ int mysize = comm.rank() + 1;
+ std::vector<value_type> myvalues(mysize);
+
+ if (comm.rank() == root) {
+ std::vector<value_type> values;
+ std::vector<int> sizes(comm.size());
+ std::vector<int> displs(comm.size());
+ value_type noise = generator(comm.size()+1);
+ // process p will receive a payload of p+1 identical generator(p) elements
+ // root will insert pseudo random pading between each payload.
+ int shift = 0; // the current position of next payload in source array
+ for (int p = 0; p < comm.size(); ++p) {
+ int size = p+1;
+ int pad = p % 3;
+ // padding
+ for (int i = 0; i < pad; ++i) {
+ values.push_back(noise);
+ }
+ // payload
+ for (int i = 0; i < size; ++i)
+ values.push_back(generator(p));
+ shift += pad;
+ displs[p] = shift;
+ sizes[p] = size;
+ shift += size;
+ }
+
+ std::cout << "Scatteringv " << kind << " from root "
+ << root << "..." << std::endl;
+ assert(mysize == sizes[comm.rank()]);
+ scatterv(comm, values, sizes, displs, &(myvalues[0]), mysize, root);
+ } else {
+ scatterv(comm, &(myvalues[0]), mysize, root);
+ }
+
+ for (int i = 0; i < mysize; ++i)
+ BOOST_CHECK(myvalues[i] == generator(comm.rank()));
+ }
+
+ comm.barrier();
+}
+
BOOST_AUTO_TEST_CASE(simple_scatter)
{
scatterv_test(comm, gps_generator(), "GPS positions");
scatterv_test(comm, string_generator(), "string");
scatterv_test(comm, string_list_generator(), "list of strings");
+
+ scatterd_test(comm, int_generator(), "integers");
+ scatterd_test(comm, gps_generator(), "GPS positions");
+ scatterd_test(comm, string_generator(), "string");
+ scatterd_test(comm, string_list_generator(), "list of strings");
}