3 #include <libmesh/int_range.h>
4 #include <libmesh/simple_range.h>
7 #include <libmesh/parallel_sync.h>
23 CPPUNIT_TEST( testPush );
24 CPPUNIT_TEST( testPull );
25 CPPUNIT_TEST( testPushVecVec );
26 CPPUNIT_TEST( testPullVecVec );
27 CPPUNIT_TEST( testPushMultimap );
28 CPPUNIT_TEST( testPushMultimapVecVec );
34 CPPUNIT_TEST( testPushOversized );
35 CPPUNIT_TEST( testPullOversized );
36 CPPUNIT_TEST( testPushVecVecOversized );
37 CPPUNIT_TEST( testPullVecVecOversized );
38 CPPUNIT_TEST( testPushMultimapOversized );
39 CPPUNIT_TEST( testPushMultimapVecVecOversized );
41 CPPUNIT_TEST_SUITE_END();
59 for (
int d=0; d != M; ++d)
63 if (diffsqrt*diffsqrt == diffsize)
64 for (
int i=-1; i != diffsqrt; ++i)
79 for (
int d=0; d != M; ++d)
83 if (diffsqrt*diffsqrt == diffsize)
85 std::vector<unsigned int> v;
86 for (
int i=-1; i != diffsqrt; ++i)
100 void fill_vector_data
105 for (
int d=0; d != M; ++d)
109 if (diffsqrt*diffsqrt == diffsize)
112 for (
int i=-1; i != diffsqrt; ++i)
113 data[d][0].push_back(d);
114 data[d][1].push_back(d);
125 void fill_vector_data
130 for (
int d=0; d != M; ++d)
134 if (diffsqrt*diffsqrt == diffsize)
136 std::vector<std::vector<unsigned int>> vv(2);
137 for (
int i=-1; i != diffsqrt; ++i)
154 std::map<processor_id_type, std::vector<unsigned int> >
data, received_data;
156 fill_scalar_data(
data, M);
161 const typename std::vector<unsigned int> &
data)
163 auto & vec = received_data[pid];
164 vec.insert(vec.end(),
data.begin(),
data.end());
171 std::vector<std::size_t> checked_sizes(size, 0);
172 for (
int p=rank; p != M; p += size)
173 for (
int srcp=0; srcp != size; ++srcp)
177 if (diffsqrt*diffsqrt != diffsize)
179 if (received_data.count(srcp))
181 const std::vector<unsigned int> & datum = received_data[srcp];
182 CPPUNIT_ASSERT_EQUAL(std::count(datum.begin(), datum.end(), p), std::ptrdiff_t(0));
187 CPPUNIT_ASSERT_EQUAL(received_data.count(srcp), std::size_t(1));
188 const std::vector<unsigned int> & datum = received_data[srcp];
189 CPPUNIT_ASSERT_EQUAL(std::count(datum.begin(), datum.end(), p), std::ptrdiff_t(diffsqrt+1));
190 checked_sizes[srcp] += diffsqrt+1;
193 for (
int srcp=0; srcp != size; ++srcp)
194 CPPUNIT_ASSERT_EQUAL(checked_sizes[srcp], received_data[srcp].size());
212 std::map<processor_id_type, std::vector<unsigned int> >
data, received_data;
214 fill_scalar_data(
data, M);
216 auto compose_replies =
219 const std::vector<unsigned int> &
query,
220 std::vector<unsigned int> & response)
222 const std::size_t query_size =
query.size();
223 response.resize(query_size);
224 for (
unsigned int i=0; i != query_size; ++i)
229 auto collect_replies =
232 const std::vector<unsigned int> &
query,
233 const std::vector<unsigned int> & response)
235 const std::size_t query_size =
query.size();
236 CPPUNIT_ASSERT_EQUAL(query_size, response.size());
237 for (
unsigned int i=0; i != query_size; ++i)
239 CPPUNIT_ASSERT_EQUAL(
query[i]*
query[i], response[i]);
241 received_data[pid] = response;
245 unsigned int * ex =
nullptr;
246 Parallel::pull_parallel_vector_data
250 for (
int p=0; p != M; ++p)
252 CPPUNIT_ASSERT_EQUAL(
data[p].size(), received_data[p].size());
254 CPPUNIT_ASSERT_EQUAL(
data[p][i]*
data[p][i], received_data[p][i]);
276 std::map<processor_id_type, std::vector<std::vector<unsigned int>>>
data;
277 std::map<processor_id_type, std::vector<unsigned int>> received_data;
279 fill_vector_data(
data, M);
284 const typename std::vector<std::vector<unsigned int>> &
data)
286 auto & vec = received_data[pid];
287 vec.insert(vec.end(),
data[0].begin(),
data[0].end());
288 CPPUNIT_ASSERT_EQUAL(
data.size(), std::size_t(2));
289 CPPUNIT_ASSERT_EQUAL(
data[1].size(), std::size_t(1));
290 CPPUNIT_ASSERT_EQUAL(
data[0][0],
data[1][0]);
297 std::vector<std::size_t> checked_sizes(size, 0);
298 for (
int p=rank; p != M; p += size)
299 for (
int srcp=0; srcp != size; ++srcp)
303 if (diffsqrt*diffsqrt != diffsize)
305 if (received_data.count(srcp))
307 const std::vector<unsigned int> & datum = received_data[srcp];
308 CPPUNIT_ASSERT_EQUAL(std::count(datum.begin(), datum.end(), p), std::ptrdiff_t(0));
313 CPPUNIT_ASSERT_EQUAL(received_data.count(srcp), std::size_t(1));
314 const std::vector<unsigned int> & datum = received_data[srcp];
315 CPPUNIT_ASSERT_EQUAL(std::count(datum.begin(), datum.end(), p), std::ptrdiff_t(diffsqrt+1));
316 checked_sizes[srcp] += diffsqrt+1;
319 for (
int srcp=0; srcp != size; ++srcp)
320 CPPUNIT_ASSERT_EQUAL(checked_sizes[srcp], received_data[srcp].size());
338 std::map<processor_id_type, std::vector<std::vector<unsigned int>>>
data;
339 std::map<processor_id_type, std::vector<std::vector<unsigned int>>> received_data;
341 fill_vector_data(
data, M);
343 auto compose_replies =
346 const std::vector<std::vector<unsigned int>> &
query,
347 std::vector<std::vector<unsigned int>> & response)
349 const std::size_t query_size =
query.size();
350 response.resize(query_size);
351 for (
unsigned int i=0; i != query_size; ++i)
353 const std::size_t query_i_size =
query[i].size();
354 response[i].resize(query_i_size);
355 for (
unsigned int j=0; j != query_i_size; ++j)
361 auto collect_replies =
364 const std::vector<std::vector<unsigned int>> &
query,
365 const std::vector<std::vector<unsigned int>> & response)
367 const std::size_t query_size =
query.size();
368 CPPUNIT_ASSERT_EQUAL(query_size, response.size());
369 for (
unsigned int i=0; i != query_size; ++i)
371 const std::size_t query_i_size =
query[i].size();
372 CPPUNIT_ASSERT_EQUAL(query_i_size, response[i].size());
373 for (
unsigned int j=0; j != query_i_size; ++j)
374 CPPUNIT_ASSERT_EQUAL(
query[i][j]*
query[i][j], response[i][j]);
376 auto & vec = received_data[pid];
377 vec.emplace_back(response[0].begin(), response[0].
end());
378 CPPUNIT_ASSERT_EQUAL(response[1].size(), std::size_t(1));
379 CPPUNIT_ASSERT_EQUAL(response[1][0], response[0][0]);
380 vec.emplace_back(response[1].begin(), response[1].
end());
384 std::vector<unsigned int> * ex =
nullptr;
385 Parallel::pull_parallel_vector_data
389 for (
int p=0; p != M; ++p)
391 CPPUNIT_ASSERT_EQUAL(
data[p].size(), received_data[p].size());
394 CPPUNIT_ASSERT_EQUAL(
data[p][i][j]*
data[p][i][j], received_data[p][i][j]);
419 std::multimap<processor_id_type, std::vector<unsigned int> >
data, received_data;
421 fill_scalar_data(
data, M);
426 const typename std::vector<unsigned int> &
data)
428 received_data.emplace(pid,
data);
435 std::vector<std::size_t> checked_sizes(size, 0);
436 for (
int p=rank; p != M; p += size)
437 for (
int srcp=0; srcp != size; ++srcp)
441 auto rng = received_data.equal_range(srcp);
442 if (diffsqrt*diffsqrt != diffsize)
446 CPPUNIT_ASSERT_EQUAL(std::count(pv_it.second.begin(), pv_it.second.end(), p), std::ptrdiff_t(0));
451 CPPUNIT_ASSERT(rng.first != rng.second);
452 for (
auto pv_it = rng.first; pv_it != rng.second; ++pv_it)
454 std::ptrdiff_t cnt = std::count(pv_it->second.begin(), pv_it->second.end(), p);
457 CPPUNIT_ASSERT_EQUAL(cnt, std::ptrdiff_t(diffsqrt+1));
458 auto pv_it2 = pv_it; ++pv_it2;
459 CPPUNIT_ASSERT(pv_it2 != rng.second);
460 std::ptrdiff_t cnt2 = std::count(pv_it2->second.begin(), pv_it2->second.end(), p);
461 CPPUNIT_ASSERT_EQUAL(cnt2, std::ptrdiff_t(1));
462 checked_sizes[srcp] += cnt + cnt2;
468 for (
int srcp=0; srcp != size; ++srcp)
470 std::size_t total_size = 0;
471 for (
auto & pv_it :
as_range(received_data.equal_range(srcp)))
472 total_size += pv_it.second.size();
473 CPPUNIT_ASSERT_EQUAL(checked_sizes[srcp], total_size);
498 std::multimap<processor_id_type, std::vector<std::vector<unsigned int>>>
data, received_data;
500 fill_vector_data(
data, M);
505 const typename std::vector<std::vector<unsigned int>> &
data)
507 received_data.emplace(pid,
data);
514 std::vector<std::size_t> checked_sizes(size, 0);
515 for (
int p=rank; p != M; p += size)
516 for (
int srcp=0; srcp != size; ++srcp)
520 auto rng = received_data.equal_range(srcp);
521 if (diffsqrt*diffsqrt != diffsize)
525 for (
auto & v : pvv.second)
526 CPPUNIT_ASSERT_EQUAL(std::count(v.begin(), v.end(), p), std::ptrdiff_t(0));
531 CPPUNIT_ASSERT(rng.first != rng.second);
532 for (
auto pvv_it = rng.first; pvv_it != rng.second; ++pvv_it)
534 if(pvv_it->second.size() != std::size_t(2))
536 CPPUNIT_ASSERT_EQUAL(pvv_it->second.size(), std::size_t(2));
537 std::ptrdiff_t cnt = std::count(pvv_it->second[0].begin(), pvv_it->second[0].end(), p);
540 CPPUNIT_ASSERT_EQUAL(cnt, std::ptrdiff_t(diffsqrt+1));
541 std::ptrdiff_t cnt2 = std::count(pvv_it->second[1].begin(), pvv_it->second[1].end(), p);
542 CPPUNIT_ASSERT_EQUAL(cnt2, std::ptrdiff_t(1));
543 auto pvv_it2 = pvv_it; ++pvv_it2;
544 CPPUNIT_ASSERT(pvv_it2 != rng.second);
545 CPPUNIT_ASSERT_EQUAL(pvv_it2->second.size(), std::size_t(1));
546 std::ptrdiff_t cnt3 = std::count(pvv_it2->second[0].begin(), pvv_it2->second[0].end(), p);
547 CPPUNIT_ASSERT_EQUAL(cnt3, std::ptrdiff_t(1));
548 checked_sizes[srcp] += cnt + cnt2 + cnt3;
556 for (
int srcp=0; srcp != size; ++srcp)
558 std::size_t total_size = 0;
559 for (
auto & pvv :
as_range(received_data.equal_range(srcp)))
560 for (
auto & v : pvv.second)
561 total_size += v.size();
562 CPPUNIT_ASSERT_EQUAL(checked_sizes[srcp], total_size);