TIMPI
Loading...
Searching...
No Matches
parallel_unit.C
Go to the documentation of this file.
1#include <timpi/timpi.h>
2
3#define TIMPI_UNIT_ASSERT(expr) \
4 do { \
5 if (!(expr)) \
6 timpi_error(); \
7 } while (0)
8
9using namespace TIMPI;
10
12
13std::vector<std::string> pt_number;
14
15 void setUp()
16 {
17 pt_number.resize(10);
18 pt_number[0] = "Zero";
19 pt_number[1] = "One";
20 pt_number[2] = "Two";
21 pt_number[3] = "Three";
22 pt_number[4] = "Four";
23 pt_number[5] = "Five";
24 pt_number[6] = "Six";
25 pt_number[7] = "Seven";
26 pt_number[8] = "Eight";
27 pt_number[9] = "Nine";
28 }
29
30 template <class Map>
31 void testSum()
32 {
33 Map data;
34
35 int N = TestCommWorld->size();
36
37 for (int p=0; p<N; ++p)
39
41
42 // Each map entry should now contain the sum:
43 // 0 + 1 + ... + N-1 = N*(N-1)/2
44 for (int p=0; p<N; ++p)
45 TIMPI_UNIT_ASSERT( data[p] == N*(N-1)/2 );
46 }
47
48
49
50 template <class Gettable>
52 {
54
55 int N = TestCommWorld->size();
56
57 std::get<0>(data) = TestCommWorld->rank();
58 std::get<1>(data) = TestCommWorld->rank()*2;
59
61
62 TIMPI_UNIT_ASSERT(std::get<0>(data) == N*(N-1)/2);
63 TIMPI_UNIT_ASSERT(std::get<1>(data) == N*(N-1));
64 }
65
66
67
68 template <class Map>
70 {
71 Map data;
72
73 int N = TestCommWorld->size();
74
75 for (int p=0; p<N; ++p)
76 data[std::string("key") + std::to_string(p)] = TestCommWorld->rank();
77
79
80 // Each map entry should now contain the sum:
81 // 0 + 1 + ... + N-1 = N*(N-1)/2
82 for (int p=0; p<N; ++p)
83 TIMPI_UNIT_ASSERT( data[std::string("key") + std::to_string(p)] == N*(N-1)/2 );
84 }
85
86
87
89 {
90 std::vector<processor_id_type> vals;
92
93 if (TestCommWorld->rank() == 0)
94 for (processor_id_type i=0; i<vals.size(); i++)
96 }
97
98
99
101 {
102 std::vector<std::string> vals;
103 TestCommWorld->gather(0, "Processor" + pt_number[TestCommWorld->rank() % 10], vals);
104
105 if (TestCommWorld->rank() == 0)
106 for (processor_id_type i=0; i<vals.size(); i++)
107 TIMPI_UNIT_ASSERT( "Processor" + pt_number[i % 10] == vals[i] );
108 }
109
110
111
113 {
114 std::vector<processor_id_type> vals;
116
117 for (processor_id_type i=0; i<vals.size(); i++)
118 TIMPI_UNIT_ASSERT( i == vals[i] );
119 }
120
121
123 {
124 std::vector<std::string> vals;
125 TestCommWorld->gather(0, "Processor" + pt_number[TestCommWorld->rank() % 10], vals);
126
127 for (processor_id_type i=0; i<vals.size(); i++)
128 TIMPI_UNIT_ASSERT( "Processor" + pt_number[i % 10] == vals[i] );
129 }
130
132 {
133 std::string send = "Processor" + std::to_string(TestCommWorld->rank());
134 std::vector<std::string> gathered;
135
137
139 for (std::size_t i = 0; i < gathered.size(); ++i)
140 TIMPI_UNIT_ASSERT(gathered[i] == "Processor" + std::to_string(i));
141 }
142
144 {
145 std::vector<std::string> vals;
146 vals.push_back("Processor" + pt_number[TestCommWorld->rank() % 10] + "A");
147 vals.push_back("Processor" + pt_number[TestCommWorld->rank() % 10] + "B");
149
150 for (processor_id_type i=0; i<(vals.size()/2); i++)
151 {
152 TIMPI_UNIT_ASSERT( "Processor" + pt_number[i % 10] + "A" == vals[2*i] );
153 TIMPI_UNIT_ASSERT( "Processor" + pt_number[i % 10] + "B" == vals[2*i+1] );
154 }
155 }
156
158 {
159 std::vector<int> vals;
160 for (processor_id_type i = 0, iend = TestCommWorld->rank()%10; i != iend; ++i)
161 vals.push_back(3*i);
162 std::vector<std::vector<int>> allvals;
164
165 for (processor_id_type i = 0, iend = TestCommWorld->rank(); i != iend; ++i)
166 {
167 TIMPI_UNIT_ASSERT(allvals[i].size() == i%10);
168 for (processor_id_type j = 0, jend = i%10; j != jend; ++j)
169 TIMPI_UNIT_ASSERT(allvals[i][j] == int(3*j));
170 }
171 }
172
174 {
175 std::vector<std::vector<double>> allvals;
176 if (TestCommWorld->rank() == 1)
177 {
178 // Leave test empty for rank 1
179 }
180 else
181 {
182 allvals.push_back(
183 {static_cast<double>(TestCommWorld->rank()),
184 static_cast<double>(TestCommWorld->rank() * 2)});
185 }
186
188
189 if (TestCommWorld->size() > 1)
191 else
192 TIMPI_UNIT_ASSERT(allvals.size() == 1);
193
194 for (processor_id_type i = 0, iend = TestCommWorld->size()-1; i != iend; ++i)
195 {
196 int r = i > 0 ? (i+1) : i;
197 TIMPI_UNIT_ASSERT(allvals[i].size() == 2);
199 TIMPI_UNIT_ASSERT(allvals[i][1] == r*2);
200 }
201 }
202
204 {
205 std::vector<std::string> vals;
206 for (processor_id_type i = 0, iend = TestCommWorld->rank()%10; i != iend; ++i)
207 vals.push_back(pt_number[i]);
208 std::vector<std::vector<std::string>> allvals;
210
211 for (processor_id_type i = 0, iend = TestCommWorld->rank(); i != iend; ++i)
212 {
213 TIMPI_UNIT_ASSERT(allvals[i].size() == i%10);
214 for (processor_id_type j = 0, jend = i%10; j != jend; ++j)
216 }
217 }
218
220 {
221 std::vector<std::string> vals;
223
224 TIMPI_UNIT_ASSERT( vals.empty() );
225 }
226
227
228
230 {
231 std::vector<std::string> vals;
232
233 if (!TestCommWorld->rank())
234 vals.push_back("Proc 0 only");
235
237
238 TIMPI_UNIT_ASSERT( vals[0] == std::string("Proc 0 only") );
239 }
240
241
242
243 template <class Container>
245 {
247
248 // Clear dest on non-root ranks
249 if (TestCommWorld->rank() != 0)
250 dest.clear();
251
253
254 for (std::size_t i=0; i<src.size(); i++)
255 TIMPI_UNIT_ASSERT( src[i] == dest[i] );
256 }
257
259 {
260 std::string src = "hello";
261 std::string dest = src;
262
263 // Clear dest on non-root ranks
264 if (TestCommWorld->rank() != 0)
265 dest.clear();
266
267 // By default the root_id is 0
269
270 for (std::size_t i=0; i<src.size(); i++)
271 TIMPI_UNIT_ASSERT( src[i] == dest[i] );
272 }
273
275 {
276 using std::array;
277 typedef array<array<int, 3>, 2> aa;
278
279 // Workaround for spurious warning from operator=
280 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100366
281 aa x{{ {0,1,2},{3,4,5} }};
282 std::vector<aa> src(3), dest(3,x);
283
284 src[0][0][0] = 0;
285 src[0][0][1] = -1;
286 src[0][0][2] = -2;
287 src[0][1][0] = -3;
288 src[0][1][1] = -4;
289 src[0][1][2] = -5;
290 src[1][0][0] = 10;
291 src[1][0][1] = 9;
292 src[1][0][2] = 8;
293 src[1][1][0] = 7;
294 src[1][1][1] = 6;
295 src[1][1][2] = 5;
296 src[2][0][0] = 20;
297 src[2][0][1] = 19;
298 src[2][0][2] = 18;
299 src[2][1][0] = 17;
300 src[2][1][1] = 16;
301 src[2][1][2] = 15;
302
303 if (TestCommWorld->rank() == 0)
304 dest = src;
305
307
308 for (std::size_t i=0; i<src.size(); i++)
309 for (std::size_t j=0; j<2; j++)
310 for (std::size_t k=0; k<3; k++)
311 TIMPI_UNIT_ASSERT(src[i][j][k] == dest[i][j][k]);
312 }
313
315 {
316 using std::pair;
317 typedef pair<pair<pair<pair<int, int>, int>, int>, int> pppp;
318 std::vector<pppp> src(3), dest(3);
319
320 src[0].first.first.first.first=0;
321 src[0].first.first.first.second=-1;
322 src[0].first.second = -2;
323 src[0].second = -3;
324 src[1].first.first.first.first=10;
325 src[1].first.first.first.second=9;
326 src[1].first.second = 8;
327 src[1].second = 7;
328 src[2].first.first.first.first=20;
329 src[2].first.first.first.second=19;
330 src[2].first.second = 18;
331 src[2].second = 17;
332
333 if (TestCommWorld->rank() == 0)
334 dest = src;
335
337
338 for (std::size_t i=0; i<src.size(); i++)
339 {
340 TIMPI_UNIT_ASSERT(src[i].first.first.first.first ==
341 dest[i].first.first.first.first);
342 TIMPI_UNIT_ASSERT(src[i].first.first.first.second ==
343 dest[i].first.first.first.second);
344 TIMPI_UNIT_ASSERT(src[i].first.first.second ==
345 dest[i].first.first.second);
346 TIMPI_UNIT_ASSERT(src[i].first.second ==
347 dest[i].first.second);
349 dest[i].second);
350 }
351 }
352
353
354
356 {
357 // Test Scalar scatter
358 {
359 std::vector<processor_id_type> src;
361
362 if (TestCommWorld->rank() == 0)
363 {
364 src.resize(TestCommWorld->size());
365 for (processor_id_type i=0; i<src.size(); i++)
366 src[i] = i + 1;
367 }
368
370
372 }
373
374 // Test Vector Scatter (equal-sized chunks)
375 {
376 std::vector<unsigned int> src;
377 std::vector<unsigned int> dest;
378 static const unsigned int CHUNK_SIZE = 3;
379
380 if (TestCommWorld->rank() == 0)
381 {
382 src.resize(TestCommWorld->size() * CHUNK_SIZE);
383 for (std::size_t i=0; i<src.size(); i++)
384 src[i] = i;
385 }
386
388
389 for (unsigned int i=0; i<CHUNK_SIZE; i++)
391 }
392
393 // Test Vector Scatter (jagged chunks)
394 {
395 std::vector<unsigned int> src;
396 std::vector<unsigned int> dest;
397 std::vector<int> counts;
398
399 if (TestCommWorld->rank() == 0)
400 {
401 // Give each processor "rank" number of items ( Sum i=1..n == (n * (n + 1))/2 )
402 src.resize((TestCommWorld->size() * (TestCommWorld->size() + 1)) / 2);
403 counts.resize(TestCommWorld->size());
404
405 for (std::size_t i=0; i<src.size(); i++)
406 src[i] = i;
407 for (unsigned int i=0; i<TestCommWorld->size(); i++)
408 counts[i] = static_cast<int>(i+1);
409 }
410
412
413 unsigned int start_value = (TestCommWorld->rank() * (TestCommWorld->rank() + 1)) / 2;
414 for (unsigned int i=0; i<=TestCommWorld->rank(); i++)
416 }
417
418 // Test Vector of Vector Scatter
419 {
420 std::vector<std::vector<unsigned int>> src;
421 std::vector<unsigned int> dest;
422
423 if (TestCommWorld->rank() == 0)
424 {
425 // Give each processor "rank" number of items ( Sum i=1..n == (n * (n + 1))/2 )
426 src.resize(TestCommWorld->size());
427 for (std::size_t i=0; i<src.size(); ++i)
428 src[i].resize(i+1);
429
430 unsigned int global_counter = 0;
431 for (std::size_t i=0; i<src.size(); i++)
432 for (std::size_t j=0; j<src[i].size(); j++)
433 src[i][j] = global_counter++;
434 }
435
437
438 unsigned int start_value = (TestCommWorld->rank() * (TestCommWorld->rank() + 1)) / 2;
439 for (unsigned int i=0; i<=TestCommWorld->rank(); i++)
441 }
442 }
443
444
445
447 {
449 }
450
451
453 {
454 const unsigned int local_val = TestCommWorld->rank() + 3;
455 unsigned int min = std::numeric_limits<unsigned int>::max();
456
457 Request req;
459
460 // not sure what I can safely test here; test() could return true
461 // immediately or could loop an arbitrarily long time first...
462 while(!req.test()) {}
463
464 TIMPI_UNIT_ASSERT (min == static_cast<unsigned int>(3));
465
466 // We could get away with destruct-before-wait since there's no
467 // post-wait-work attached to req, but that's not really
468 // *supported* behavior...
469 req.wait();
470 }
471
472
474 {
475 // We don't support non-blocking I/O in serial
476 if (TestCommWorld->size() < 2)
477 return;
478
479 const std::string send_string =
480 "More than 64 bytes to avoid false positives with Small String Optimization libraries";
481
482 // We need pre-sized buffers for non-blocking receive.
483 std::string recv_string(send_string.size(), ' ');
484
486 (TestCommWorld->rank() + 1) % TestCommWorld->size();
487
491
492 recv_req.wait();
493
495
496 send_req.wait();
497 }
498
499
501 {
502 constexpr std::size_t N=5;
503 std::vector<unsigned int> local_vals(N),
504 min_vals(N, std::numeric_limits<unsigned int>::max());
505 std::iota(local_vals.begin(), local_vals.end(), TestCommWorld->rank()+4);
506
507 std::size_t tests_done = 0;
508
509 std::vector<Request> reqs;
510 for (std::size_t i=0; i != N; ++i)
511 {
512 Request req;
514
515 // We might have finished immediately, e.g. if we're on one
516 // processor
517 if (*req.get() == Request::null_request)
518 {
519 TIMPI_UNIT_ASSERT (min_vals[i] == static_cast<unsigned int>(4+i));
520 ++tests_done;
521 }
522 reqs.push_back(req);
523 }
524
525 std::size_t i = std::size_t(-1);
526 if (tests_done != N)
527 i = waitany(reqs);
528 while (i != std::size_t(-1))
529 {
530 TIMPI_UNIT_ASSERT (min_vals[i] == static_cast<unsigned int>(4+i));
531 ++tests_done;
532 i = waitany(reqs);
533 }
534
536 }
537
538
539
541 {
542 int true_sum = 0;
543 for (int rank = 0; rank < (int)TestCommWorld->size(); ++rank)
544 true_sum += rank + 1;
545
546 int local_val = TestCommWorld->rank() + 1;
547 int sum;
548
551 request.wait();
552
554 }
555
556
557
559 {
560 unsigned int local_val = TestCommWorld->rank();
561 unsigned int min = std::numeric_limits<unsigned int>::max();
562
563 Request req;
565 req.wait();
566
567 TIMPI_UNIT_ASSERT (min == static_cast<unsigned int>(0));
568 }
569
570
571
572 void testMin ()
573 {
574 unsigned int min = TestCommWorld->rank();
575
576 TestCommWorld->min(min);
577
578 TIMPI_UNIT_ASSERT (min == static_cast<unsigned int>(0));
579 }
580
581
583 {
584 const processor_id_type rank = TestCommWorld->rank();
586
587 // Use a long vector, so we can be sure that many bits extends
588 // over multiple unsigned integers; use a weird size to test the
589 // not-evenly-divisible case.
590 constexpr std::size_t vec_size = 2345;
591 std::vector<bool> vec_bool(vec_size, true);
592 for (std::size_t i=0; i < vec_size; i += (rank+2))
593 vec_bool[i] = false;
594
596
597 for (std::size_t i=0; i != vec_size; ++i)
598 {
599 bool should_be_true = true;
600 for (processor_id_type p=0; p < N; ++p)
601 if (i % (p+2) == 0)
602 {
603 should_be_true = false;
604 break;
605 }
607 }
608 }
609
610
611
612
614 {
615 unsigned long min = 1;
616 if (TestCommWorld->rank() % 2)
617 min = std::numeric_limits<unsigned long>::max();
618
620 (MPI_Allreduce (MPI_IN_PLACE, &min, 1,
622 TestCommWorld->get()));
623
624 TIMPI_UNIT_ASSERT (min == 1);
625 }
626
627 template <typename T>
629 {
630 T min = 1;
631
632 if (TestCommWorld->rank() % 2)
633 min = std::numeric_limits<T>::max();
634
635 TestCommWorld->min(min);
636
637 TIMPI_UNIT_ASSERT (min == 1);
638 }
639
640
641
643 {
645 processor_id_type max = std::numeric_limits<processor_id_type>::min();
646
647 Request req;
649 req.wait();
650
653 }
654
655
656
666
667
668
670 {
671 const processor_id_type rank = TestCommWorld->rank();
673
674 // Use a long vector, so we can be sure it extends over multiple
675 // unsigned integers; use a weird size to test the
676 // not-evenly-divisible case.
677 constexpr std::size_t vec_size = 2345;
678 std::vector<bool> vec_bool(vec_size, false);
679 for (std::size_t i=0; i < vec_size; i += (rank+2))
680 vec_bool[i] = true;
681
683
684 for (std::size_t i=0; i != vec_size; ++i)
685 {
686 bool should_be_true = false;
687 for (processor_id_type p=0; p < N; ++p)
688 if (i % (p+2) == 0)
689 {
690 should_be_true = true;
691 break;
692 }
694 }
695 }
696
697
698
699 template <class Map>
701 {
702 Map data;
703
704 int rank = TestCommWorld->rank();
705 int N = TestCommWorld->size();
706
707 // On each proc, the map has the single entry (rank, rank)
708 data[rank] = rank;
709
710 // Compute the max
712
713 // After calling max, there should be an entry for each rank
714 for (int p=0; p<N; ++p)
716 }
717
718
719
720 template <class Map>
722 {
723 Map data;
724
725 int rank = TestCommWorld->rank();
726 int N = TestCommWorld->size();
727
728 // On each proc, the map has a single entry, e.g. ("key0", 0)
729 data[std::string("key") + std::to_string(rank)] = rank;
730
731 // Compute the max
733
734 // After calling max, there should be an entry for each rank
735 for (int p=0; p<N; ++p)
736 TIMPI_UNIT_ASSERT (data[std::string("key") + std::to_string(p)] == p);
737 }
738
739
740
742 {
743 int min = (TestCommWorld->rank() + 1) % TestCommWorld->size();
744 unsigned int minid = 0;
745
747
748 TIMPI_UNIT_ASSERT (min == static_cast<int>(0));
749 TIMPI_UNIT_ASSERT (minid == static_cast<unsigned int>(TestCommWorld->size()-1));
750 }
751
752
753
755 {
756 int max = TestCommWorld->rank();
757 unsigned int maxid = 0;
758
760
761 TIMPI_UNIT_ASSERT (max+1 ==
763 TIMPI_UNIT_ASSERT (maxid == static_cast<unsigned int>(TestCommWorld->size()-1));
764 }
765
766
767
769 {
770 bool min = ((TestCommWorld->rank() + TestCommWorld->size()-1) % 2);
771 unsigned int minid = 0;
772
774
775 TIMPI_UNIT_ASSERT (min == static_cast<int>(0));
776 TIMPI_UNIT_ASSERT (minid == static_cast<unsigned int>((TestCommWorld->size()-1)%2));
777 }
778
779
780
782 {
783 double min = (TestCommWorld->rank() + 1) % TestCommWorld->size();
784 unsigned int minid = 0;
785
787
788 TIMPI_UNIT_ASSERT (min == double(0));
789 TIMPI_UNIT_ASSERT (minid == static_cast<unsigned int>(TestCommWorld->size()-1));
790 }
791
792
793
795 {
796 bool max = ((TestCommWorld->rank() + TestCommWorld->size()) % 2);
797 unsigned int maxid = 0;
798
800
801 TIMPI_UNIT_ASSERT (max == static_cast<int>(1));
802 TIMPI_UNIT_ASSERT (maxid == static_cast<unsigned int>((TestCommWorld->size()-1)%2));
803 }
804
805
806
808 {
809 double max = TestCommWorld->rank();
810 unsigned int maxid = 0;
811
813
814 // Hope nobody uses 1677216 procs with single precision
815 TIMPI_UNIT_ASSERT (max+1 == double(TestCommWorld->size()));
816 TIMPI_UNIT_ASSERT (maxid == static_cast<unsigned int>(TestCommWorld->size()-1));
817 }
818
819
820
822 {
823 int min = (TestCommWorld->rank() + 1) % TestCommWorld->size();
824 int min_tag = min + 3;
825 unsigned int minid = 0;
826
827 std::pair<int, int> p{min, min_tag};
828
830
831 TIMPI_UNIT_ASSERT (p.first == static_cast<int>(0));
832 TIMPI_UNIT_ASSERT (p.second == static_cast<int>(3));
833 TIMPI_UNIT_ASSERT (minid == static_cast<unsigned int>(TestCommWorld->size()-1));
834 }
835
836
837
839 {
840 int max = TestCommWorld->rank();
841 int max_tag = max + 3;
842 unsigned int maxid = 0;
843
844 std::pair<int, int> p{max, max_tag};
845
847
848 TIMPI_UNIT_ASSERT (p.first+1 ==
850 TIMPI_UNIT_ASSERT (p.second+1 ==
852 TIMPI_UNIT_ASSERT (maxid == static_cast<unsigned int>(TestCommWorld->size()-1));
853 }
854
855
856
858 {
859 double min = std::numeric_limits<double>::infinity();
860
861 TestCommWorld->min(min);
862
863 TIMPI_UNIT_ASSERT (min == std::numeric_limits<double>::infinity());
864
865 min = -std::numeric_limits<double>::infinity();
866
867 TestCommWorld->min(min);
868
869 TIMPI_UNIT_ASSERT (min == -std::numeric_limits<double>::infinity());
870 }
871
872
873
875 {
876 double max = std::numeric_limits<double>::infinity();
877
878 TestCommWorld->max(max);
879
880 TIMPI_UNIT_ASSERT (max == std::numeric_limits<double>::infinity());
881
882 max = -std::numeric_limits<double>::infinity();
883
884 TestCommWorld->max(max);
885
886 TIMPI_UNIT_ASSERT (max == -std::numeric_limits<double>::infinity());
887 }
888
889
890
892 {
893 unsigned int procup = (TestCommWorld->rank() + 1) %
895 unsigned int procdown = (TestCommWorld->size() +
896 TestCommWorld->rank() - 1) %
898
899 std::vector<unsigned int> src_val(3), recv_val(3);
900
901 src_val[0] = 0;
902 src_val[1] = 1;
903 src_val[2] = 2;
904
906
907 if (TestCommWorld->size() > 1)
908 {
909 // Default communication
911
913 src_val,
914 request);
915
917 recv_val);
918
920
921 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
922
923 for (std::size_t i=0; i<src_val.size(); i++)
925
926
927 // Synchronous communication
929 std::fill (recv_val.begin(), recv_val.end(), 0);
930
932 src_val,
933 request);
934
936 recv_val);
937
939
940 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
941
942 for (std::size_t i=0; i<src_val.size(); i++)
944
945 // Restore default communication
947 }
948 }
949
950
951
953 {
954 unsigned int procup = (TestCommWorld->rank() + 1) %
956 unsigned int procdown = (TestCommWorld->size() +
957 TestCommWorld->rank() - 1) %
959
960 std::vector<unsigned int> src_val(3), recv_val(3);
961
962 src_val[0] = 0;
963 src_val[1] = 1;
964 src_val[2] = 2;
965
967
968 if (TestCommWorld->size() > 1)
969 {
970 // Default communication
972
974 recv_val,
975 request);
976
978 src_val);
979
981
982 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
983
984 for (std::size_t i=0; i<src_val.size(); i++)
986
987 // Synchronous communication
989 std::fill (recv_val.begin(), recv_val.end(), 0);
990
991
993 recv_val,
994 request);
995
997 src_val);
998
1000
1001 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
1002
1003 for (std::size_t i=0; i<src_val.size(); i++)
1005
1006 // Restore default communication
1008 }
1009 }
1010
1011
1013 {
1014 unsigned int procup = (TestCommWorld->rank() + 1) %
1016 unsigned int procdown = (TestCommWorld->size() +
1017 TestCommWorld->rank() - 1) %
1019
1020 std::set<unsigned int> src_val, recv_val;
1021
1022 src_val.insert(4); // Chosen by fair dice roll
1023 src_val.insert(42);
1024 src_val.insert(1337);
1025
1027
1028 if (TestCommWorld->size() > 1)
1029 {
1031
1033 recv_val);
1034
1035 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
1036
1037 for (std::set<unsigned int>::const_iterator
1038 it = src_val.begin(), end = src_val.end(); it != end;
1039 ++it)
1040 TIMPI_UNIT_ASSERT ( recv_val.count(*it) );
1041
1043
1044 recv_val.clear();
1045 }
1046 }
1047
1048
1049
1051 {
1052 unsigned int procup = (TestCommWorld->rank() + 1) %
1054 unsigned int procdown = (TestCommWorld->size() +
1055 TestCommWorld->rank() - 1) %
1057
1058 std::vector<std::vector<unsigned int> > src_val(3), recv_val;
1059
1060 src_val[0].push_back(4); // Chosen by fair dice roll
1061 src_val[2].push_back(procup);
1062 src_val[2].push_back(TestCommWorld->rank());
1063
1065
1066 if (TestCommWorld->size() > 1)
1067 {
1069
1071 recv_val);
1072
1073 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
1074
1075 for (std::size_t i = 0; i != 3; ++i)
1076 TIMPI_UNIT_ASSERT ( src_val[i].size() == recv_val[i].size() );
1077
1078 TIMPI_UNIT_ASSERT ( recv_val[0][0] == static_cast<unsigned int> (4) );
1079 TIMPI_UNIT_ASSERT ( recv_val[2][0] == static_cast<unsigned int> (TestCommWorld->rank()) );
1080 TIMPI_UNIT_ASSERT ( recv_val[2][1] == procdown );
1081
1083
1084 recv_val.clear();
1085 }
1086 }
1087
1088
1090 {
1091 unsigned int procup = (TestCommWorld->rank() + 1) %
1093 unsigned int procdown = (TestCommWorld->size() +
1094 TestCommWorld->rank() - 1) %
1096
1097 // Any odd processor out does nothing
1098 if ((TestCommWorld->size() % 2) && procup == 0)
1099 return;
1100
1101 std::vector<std::vector<unsigned int> > src_val(3), recv_val;
1102
1103 src_val[0].push_back(4); // Chosen by fair dice roll
1104 src_val[2].push_back(procup);
1105 src_val[2].push_back(TestCommWorld->rank());
1106
1107 // Other even numbered processors send
1108 if (TestCommWorld->rank() % 2 == 0)
1110 // Other odd numbered processors receive
1111 else
1112 {
1114 recv_val);
1115
1116 TIMPI_UNIT_ASSERT ( src_val.size() == recv_val.size() );
1117
1118 for (std::size_t i = 0; i != 3; ++i)
1119 TIMPI_UNIT_ASSERT ( src_val[i].size() == recv_val[i].size() );
1120
1121 TIMPI_UNIT_ASSERT ( recv_val[0][0] == static_cast<unsigned int> (4) );
1122 TIMPI_UNIT_ASSERT ( recv_val[2][0] == static_cast<unsigned int> (TestCommWorld->rank()) );
1123 TIMPI_UNIT_ASSERT ( recv_val[2][1] == procdown );
1124
1125 recv_val.clear();
1126 }
1127 }
1128
1129
1130
1132 {
1133 double inf = std::numeric_limits<double>::infinity();
1134
1135 double *infptr = TestCommWorld->rank()%2 ? NULL : &inf;
1136
1138
1139 inf = -std::numeric_limits<double>::infinity();
1140
1142 }
1143
1144
1146 {
1147 const std::string s = "Violin"; // Test requires a string instrument
1148
1149 const std::string *sptr = TestCommWorld->rank()%2 ? NULL : &s;
1150
1152 }
1153
1154
1156 {
1157 const std::vector<int> v = {1, 2, 3};
1158
1159 const std::vector<int> *vptr = TestCommWorld->rank()%2 ? NULL : &v;
1160
1162 }
1163
1164
1165 template<typename T>
1167 {
1168 const T one = 1;
1169
1170 const T * tptr = TestCommWorld->rank()%2 ? NULL : &one;
1171
1173 }
1174
1175
1177 {
1179 unsigned int rank = TestCommWorld->rank();
1180 unsigned int color = rank % 2;
1182
1183 TIMPI_UNIT_ASSERT(subcomm.size() >= 1);
1184 TIMPI_UNIT_ASSERT(subcomm.size() >= TestCommWorld->size() / 2);
1185 TIMPI_UNIT_ASSERT(subcomm.size() <= TestCommWorld->size() / 2 + 1);
1186 }
1187
1188
1190 {
1192 unsigned int rank = TestCommWorld->rank();
1193 TIMPI::info i = 0;
1194 int type = 0;
1195#ifdef TIMPI_HAVE_MPI
1196 type = MPI_COMM_TYPE_SHARED;
1197 i = MPI_INFO_NULL;
1198#endif
1199 TestCommWorld->split_by_type(type, rank, i, subcomm);
1200
1201 TIMPI_UNIT_ASSERT(subcomm.size() >= 1);
1203 }
1204
1205 template <typename NonBuiltin>
1213
1214
1215int main(int argc, const char * const * argv)
1216{
1218 TestCommWorld = &init.comm();
1219
1220 setUp();
1221
1227 testGather();
1228 testAllGather();
1239 testBroadcast<std::map<int, int>>({{0,0}, {1,1}, {2,2}});
1240 testBroadcast<std::map<int, std::string>>({{0,"foo"}, {1,"bar"}, {2,"baz"}});
1241 testBroadcast<std::unordered_map<int, int>>({{0,0}, {1,1}, {2,2}});
1242 testBroadcast<std::unordered_map<int, std::string>>({{0,"foo"}, {1,"bar"}, {2,"baz"}});
1246 testScatter();
1247 testBarrier();
1248 testMin();
1250 testMax();
1270 testMinloc();
1271 testMaxloc();
1280 testIsendRecv();
1281 testIrecvSend();
1302 testSplit();
1314
1315 return 0;
1316}
Encapsulates the MPI_Comm object.
void max(const T &r, T &o, Request &req) const
Non-blocking maximum of the local value r into o with the request req.
processor_id_type size() const
void maxloc(T &r, unsigned int &max_id) const
Take a local variable and replace it with the maximum of it's values on all processors,...
void split(int color, int key, Communicator &target) const
processor_id_type rank() const
void barrier() const
Pause execution until all processors reach a certain point.
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
Blocking-receive from one processor with data-defined type.
timpi_pure bool semiverify(const T *r) const
Check whether a local pointer points to the same value on all processors where it is not null,...
void min(const T &r, T &o, Request &req) const
Non-blocking minimum of the local value r into o with the request req.
void send_mode(const SendMode sm)
Explicitly sets the SendMode type used for send operations.
void minloc(T &r, unsigned int &min_id) const
Take a local variable and replace it with the minimum of it's values on all processors,...
void sum(T &r) const
Take a local variable and replace it with the sum of it's values on all processors.
void scatter(const std::vector< T, A > &data, T &recv, const unsigned int root_id=0) const
Take a vector of local variables and scatter the ith item to the ith processor in the communicator.
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.
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
Take a vector of length comm.size(), and on processor root_id fill in recv[processor_id] = the value ...
void split_by_type(int split_type, int key, info i, Communicator &target) const
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 send(const unsigned int dest_processor_id, const T &buf, const MessageTag &tag=no_tag) const
Blocking-send to one processor with data-defined type.
communicator & get()
Encapsulates the MPI_Request.
Definition request.h:68
static const request null_request
Definition request.h:111
Templated class to provide the appropriate MPI datatype for use with built-in C types or simple C++ c...
The TIMPIInit class, when constructed, initializes any dependent libraries (e.g.
Definition timpi_init.h:58
MPI_Info info
Info object used by some MPI-3 methods.
Status wait(Request &r)
Wait for a non-blocking send or receive to finish.
Definition request.h:135
MPI_Request request
Request object for non-blocking I/O.
Definition request.h:49
uint8_t processor_id_type
const unsigned int any_source
Processor id meaning "Accept from any source".
Tnew cast_int(Told oldvar)
std::size_t waitany(std::vector< Request > &r)
Wait for at least one non-blocking operation to finish.
Definition request.C:219
void testMaxloc()
void testAllGatherString()
void testBarrier()
void testStandardTypeAssignment()
void testMaxlocPair()
void testAllGatherVectorVector()
void testNonblockingMax()
void testInfinityMin()
void testMPIULongMin()
void testAllGatherVectorString()
void testBroadcastArrayType()
void testNonFixedTypeSum()
Communicator * TestCommWorld
void testMax()
void testNonblockingMin()
void testIrecvSend()
void testMapMax()
void testAllGatherHalfEmptyVectorString()
void testSplitByType()
void testMin()
void testMaxlocBool()
void testMinloc()
void setUp()
void testSumOpFunction()
void testNonblockingSum()
void testMinLarge()
void testSemiVerifyType()
void testNonblockingString()
void testMinVecBool()
void testRecvIsendSets()
void testRecvIsendVecVecs()
void testNonFixedTypeMapMax()
void testMinlocDouble()
void testSendRecvVecVecs()
std::vector< std::string > pt_number
void testAllGatherVectorVectorPacked()
void testGather()
void testMaxlocDouble()
void testInfinityMax()
void testSemiVerifyInf()
void testGatherString2()
void testSum()
void testMinlocPair()
void testAllGather()
void testSemiVerifyString()
void testMinlocBool()
void testNonblockingTest()
void testBroadcastString()
void testIsendRecv()
void testSplit()
void testBroadcastNestedType()
void testScatter()
void testAllGatherEmptyVectorString()
void testSemiVerifyVector()
void testBroadcast(Container &&src)
void testAllGatherVectorVectorInPlace()
void testMaxVecBool()
void testNonblockingWaitany()
void testGatherString()
int main()
Definition version.C:20