12 #include <unordered_map> 13 #include <unordered_set> 18 #define TIMPI_UNIT_ASSERT(expr) \ 34 using namespace TIMPI;
39 template <
typename Container>
42 std::vector<typename Container::value_type> temp(size);
43 std::iota(temp.begin(), temp.end(), 0);
44 return Container(temp.begin(), temp.end());
50 {
return createContainer<std::set<T>>(size); }
53 template <
typename Container>
58 for (std::size_t i = 0; i != size; ++i)
59 c.insert(std::make_pair(i*10, i*50));
66 template <
typename Container>
69 std::vector<Container> vals;
72 auto my_val = createContainer<Container>(my_rank + 1);
77 const std::size_t vec_size = vals.size();
78 TIMPI_UNIT_ASSERT(comm_size == vec_size);
80 for (std::size_t i = 0; i < vec_size; ++i)
82 const auto & current_container = vals[i];
83 TIMPI_UNIT_ASSERT(current_container.size() == i+1);
84 for (std::size_t n = 0; n != i+1; ++n)
86 auto it = std::find(current_container.begin(),
87 current_container.end(), n);
88 TIMPI_UNIT_ASSERT(it != current_container.end());
93 template <
typename Container>
96 std::vector<Container> vals;
99 auto my_val = createMapContainer<Container>(my_rank + 1);
104 const std::size_t vec_size = vals.size();
105 TIMPI_UNIT_ASSERT(comm_size == vec_size);
107 for (std::size_t i = 0; i < vec_size; ++i)
109 const auto & current_container = vals[i];
110 TIMPI_UNIT_ASSERT(current_container.size() == i+1);
111 for (std::size_t n = 0; n != i+1; ++n)
113 auto it = current_container.find(n*10);
114 TIMPI_UNIT_ASSERT(it != current_container.end());
115 TIMPI_UNIT_ASSERT(it->second == n*50);
122 std::set<std::vector<std::tuple<int,int>>> data;
125 auto set_inserter = [&data](
int i)
127 std::vector<std::tuple<int,int>> datum(1);
128 std::get<0>(datum[0]) = i;
129 std::get<1>(datum[0]) = 2*i;
133 auto set_tester = [&data](
int i)
135 std::vector<std::tuple<int,int>> datum(1);
136 std::get<0>(datum[0]) = i;
137 std::get<1>(datum[0]) = 2*i;
138 TIMPI_UNIT_ASSERT(data.count(datum) == std::size_t(1));
147 TIMPI_UNIT_ASSERT( data.size() == std::size_t(2*N+1) );
149 for (
int p=0; p<N; ++p)
158 std::vector<std::set<unsigned int>> vals(1);
160 vals[0] = createSet<unsigned int>(my_rank + 1);
165 const std::size_t vec_size = vals.size();
166 TIMPI_UNIT_ASSERT(comm_size == vec_size);
168 for (std::size_t i = 0; i < vec_size; ++i)
170 const auto & current_set = vals[i];
171 TIMPI_UNIT_ASSERT(current_set.size() == i+1);
172 unsigned int value = 0;
173 for (
auto number : current_set)
174 TIMPI_UNIT_ASSERT(number == value++);
180 std::vector<std::array<std::set<unsigned int>, 2>> vals;
183 std::array<std::set<unsigned int>, 2> vals_out
184 {{createSet<unsigned int>(my_rank + 1),
185 createSet<unsigned int>(my_rank + 10)}};
190 const std::size_t vec_size = vals.size();
191 TIMPI_UNIT_ASSERT(comm_size == vec_size);
193 for (std::size_t i = 0; i < vec_size; ++i)
195 const auto & first_set = vals[i][0];
196 TIMPI_UNIT_ASSERT(first_set.size() == i+1);
197 unsigned int value = 0;
198 for (
auto number : first_set)
199 TIMPI_UNIT_ASSERT(number == value++);
200 const auto & second_set = vals[i][1];
201 TIMPI_UNIT_ASSERT(second_set.size() == i+10);
203 for (
auto number : second_set)
204 TIMPI_UNIT_ASSERT(number == value++);
210 std::vector<std::tuple<std::set<unsigned int>,
unsigned int,
unsigned int>> vals;
214 createSet<unsigned int>(my_rank + 1),
215 my_rank, 2*my_rank), vals);
218 const std::size_t vec_size = vals.size();
219 TIMPI_UNIT_ASSERT(comm_size == vec_size);
221 for (std::size_t i = 0; i < vec_size; ++i)
223 const auto & current_set = std::get<0>(vals[i]);
224 unsigned int value = 0;
225 for (
auto number : current_set)
226 TIMPI_UNIT_ASSERT(number == value++);
227 TIMPI_UNIT_ASSERT(std::get<1>(vals[i]) == i);
228 TIMPI_UNIT_ASSERT(std::get<2>(vals[i]) == 2*i);
234 std::vector<std::pair<std::set<unsigned int>,
unsigned int>> vals;
238 createSet<unsigned int>(my_rank + 1),
242 const std::size_t vec_size = vals.size();
243 TIMPI_UNIT_ASSERT(comm_size == vec_size);
245 for (std::size_t i = 0; i < vec_size; ++i)
247 const auto & current_set = vals[i].first;
248 unsigned int value = 0;
249 for (
auto number : current_set)
250 TIMPI_UNIT_ASSERT(number == value++);
251 TIMPI_UNIT_ASSERT(vals[i].second == i);
257 std::set<unsigned int> val;
265 TIMPI_UNIT_ASSERT(val.size() == 1);
266 TIMPI_UNIT_ASSERT(*val.begin() == 0);
271 std::vector<std::set<unsigned int>> vals;
277 vals.resize(comm_size + 1);
278 unsigned int counter = 1;
279 for (
auto & val : vals)
281 for (
unsigned int number = 0; number < counter; ++number)
288 const std::size_t vec_size = vals.size();
289 TIMPI_UNIT_ASSERT((comm_size + 1) == vec_size);
291 std::size_t counter = 1;
292 for (
const auto & current_set : vals)
294 TIMPI_UNIT_ASSERT(current_set.size() == counter);
295 unsigned int number = 0;
296 for (
auto elem : current_set)
297 TIMPI_UNIT_ASSERT(elem == number++);
310 for (
int d=0; d != M; ++d)
312 const int diffsize = std::abs(d-rank);
313 const int diffsqrt = std::sqrt(diffsize);
314 if (diffsqrt*diffsqrt == diffsize)
315 for (
int i=-1; i != diffsqrt; ++i)
316 data[d].push_back(createSet<unsigned int>(d+1));
326 std::string digit_strings [10] = {
"zero",
"one",
"two",
327 "three",
"four",
"five",
"six",
"seven",
"eight",
"nine"};
329 std::string returnval =
"done";
332 returnval = digit_strings[number%10]+
" "+returnval;
340 for (
int d=0; d != M; ++d)
342 const int diffsize = std::abs(d-rank);
343 const int diffsqrt = std::sqrt(diffsize);
344 if (diffsqrt*diffsqrt == diffsize)
345 for (
int i=-1; i != diffsqrt; ++i)
347 data[d].push_back(std::set<std::string>());
348 for (
int j=0; j!=d+1; ++j)
359 std::map<processor_id_type, std::vector<std::set<unsigned int>>> data, received_data;
366 const typename std::vector<std::set<unsigned int>> & vecset_received)
368 auto & vec = received_data[pid];
369 vec.insert(vec.end(), vecset_received.begin(), vecset_received.end());
376 for (
int srcp=0; srcp != size; ++srcp)
378 auto map_it = received_data.find(srcp);
380 const int diffsize = std::abs(srcp-p);
381 const int diffsqrt = std::sqrt(diffsize);
382 if (diffsqrt*diffsqrt != diffsize)
385 TIMPI_UNIT_ASSERT(map_it == received_data.end() || map_it->second.empty());
389 TIMPI_UNIT_ASSERT(map_it != received_data.end());
390 const std::vector<std::set<unsigned int>> & datum = map_it->second;
391 TIMPI_UNIT_ASSERT(datum.size() ==
static_cast<std::size_t
>(diffsqrt+1));
393 for (
const auto &
set : datum)
395 TIMPI_UNIT_ASSERT(
set.size() == static_cast<std::size_t>((p+1)));
397 unsigned int comparator = 0;
398 for (
const auto element :
set)
399 TIMPI_UNIT_ASSERT(element == comparator++);
408 std::map<processor_id_type, std::vector<std::set<unsigned int>> > data, received_data;
412 auto compose_replies =
415 const std::vector<std::set<unsigned int>> & query,
416 std::vector<std::set<unsigned int>> & response)
418 const std::size_t query_size = query.size();
419 response.resize(query_size);
420 for (
unsigned int i=0; i != query_size; ++i)
422 const auto & query_set = query[i];
423 for (
const unsigned int elem : query_set)
424 response[i].insert(elem*elem);
429 auto collect_replies =
432 const std::vector<std::set<unsigned int>> & query,
433 const std::vector<std::set<unsigned int>> & response)
435 const std::size_t query_size = query.size();
436 TIMPI_UNIT_ASSERT(query_size == response.size());
437 for (
unsigned int i=0; i != query_size; ++i)
439 TIMPI_UNIT_ASSERT(query[i].size() == response[i].size());
441 auto query_set_it = query[i].begin(), response_set_it = response[i].begin();
443 for (; query_set_it != query[i].end(); ++query_set_it, ++response_set_it)
445 const auto query_elem = *query_set_it, response_elem = *response_set_it;
446 TIMPI_UNIT_ASSERT(query_elem * query_elem == response_elem);
449 received_data[pid] = response;
453 std::set<unsigned int> * ex =
nullptr;
455 (*
TestCommWorld, data, compose_replies, collect_replies, ex);
458 for (
int p=0; p != size; ++p)
460 TIMPI_UNIT_ASSERT(data[p].size() == received_data[p].size());
461 for (std::size_t i = 0; i != data[p].size(); ++i)
463 TIMPI_UNIT_ASSERT(data[p][i].size() == received_data[p][i].size());
465 auto data_set_it = data[p][i].begin(), received_set_it = received_data[p][i].begin();
467 for (; data_set_it != data[p][i].end(); ++data_set_it, ++received_set_it)
469 const auto data_elem = *data_set_it, received_elem = *received_set_it;
470 TIMPI_UNIT_ASSERT(data_elem * data_elem == received_elem);
480 std::map<processor_id_type, std::vector<std::set<std::string>> > data, received_data;
484 auto compose_replies =
487 const std::vector<std::set<std::string>> & query,
488 std::vector<std::set<std::string>> & response)
490 const std::size_t query_size = query.size();
491 response.resize(query_size);
492 for (
unsigned int i=0; i != query_size; ++i)
494 const auto & query_set = query[i];
495 for (
const std::string & elem : query_set)
496 response[i].insert(elem+elem);
501 auto collect_replies =
504 const std::vector<std::set<std::string>> & query,
505 const std::vector<std::set<std::string>> & response)
507 const std::size_t query_size = query.size();
508 TIMPI_UNIT_ASSERT(query_size == response.size());
509 for (
unsigned int i=0; i != query_size; ++i)
511 TIMPI_UNIT_ASSERT(query[i].size() == response[i].size());
513 auto query_set_it = query[i].begin(), response_set_it = response[i].begin();
515 for (; query_set_it != query[i].end(); ++query_set_it, ++response_set_it)
517 const auto query_elem = *query_set_it, response_elem = *response_set_it;
518 TIMPI_UNIT_ASSERT(query_elem + query_elem == response_elem);
521 received_data[pid] = response;
525 std::set<std::string> * ex =
nullptr;
527 (*
TestCommWorld, data, compose_replies, collect_replies, ex);
530 for (
int p=0; p != size; ++p)
532 TIMPI_UNIT_ASSERT(data[p].size() == received_data[p].size());
533 for (std::size_t i = 0; i != data[p].size(); ++i)
535 TIMPI_UNIT_ASSERT(data[p][i].size() == received_data[p][i].size());
537 auto data_set_it = data[p][i].begin(), received_set_it = received_data[p][i].begin();
539 for (; data_set_it != data[p][i].end(); ++data_set_it, ++received_set_it)
541 const auto data_elem = *data_set_it, received_elem = *received_set_it;
542 TIMPI_UNIT_ASSERT(data_elem + data_elem == received_elem);
548 int main(
int argc,
const char *
const * argv)
553 testContainerAllGather<std::list<unsigned int>>();
554 testContainerAllGather<std::set<unsigned int>>();
555 testContainerAllGather<std::unordered_set<unsigned int>>();
556 testContainerAllGather<std::multiset<unsigned int>>();
557 testContainerAllGather<std::unordered_multiset<unsigned int>>();
558 testMapContainerAllGather<std::map<unsigned int, unsigned int>>();
559 testMapContainerAllGather<std::unordered_map<unsigned int, unsigned int>>();
560 testMapContainerAllGather<std::multimap<unsigned int, unsigned int>>();
561 testMapContainerAllGather<std::unordered_multimap<unsigned int, unsigned int>>();
void pull_parallel_vector_data(const Communicator &comm, const MapToVectors &queries, GatherFunctor &gather_data, const ActionFunctor &act_on_data, const datum *example)
Send query vectors, receive and answer them with vectors of data, then act on those answers...
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
Take a vector of length this->size(), and fill in recv[processor_id] = the value of send on that proc...
void fill_data(std::map< processor_id_type, std::vector< std::set< unsigned int >>> &data, int M)
Container createMapContainer(std::size_t size)
Communicator * TestCommWorld
void sync_type(const SyncType st)
Explicitly sets the SyncType used for sync operations.
void testMapContainerAllGather()
StandardType(const std::set< T > *)
void testContainerBroadcast()
The TIMPIInit class, when constructed, initializes any dependent libraries (e.g.
processor_id_type rank() const
Templated class to provide the appropriate MPI datatype for use with built-in C types or simple C++ c...
void testPackedSetUnion()
std::set< T > createSet(std::size_t size)
Encapsulates the MPI_Comm object.
processor_id_type size() const
void testArrayContainerAllGather()
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
Send and receive and act on vectors of data.
std::string stringy_number(int number)
uint8_t processor_id_type
void testPairContainerAllGather()
int main(int argc, const char *const *argv)
void testVectorOfContainersBroadcast()
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Take a local value and broadcast it to all processors.
StandardType<T>'s which do not define a way to MPI_Type T should inherit from this class...
void testTupleContainerAllGather()
void testVectorOfContainersAllGather()
void testContainerAllGather()
Container createContainer(std::size_t size)
const Communicator & comm() const
Returns the Communicator created by this object, which will be a compatibility shim if MPI is not ena...
void set_union(T &data, const unsigned int root_id) const
Take a container (set, map, unordered_set, multimap, etc) of local variables on each processor...