TIMPI
Loading...
Searching...
No Matches
set_unit.C
Go to the documentation of this file.
1#include <timpi/timpi.h>
2
3#include <bitset>
4#include <map>
5#include <set>
6#include <unordered_set>
7#include <unordered_map>
8
9#define TIMPI_UNIT_ASSERT(expr) \
10 if (!(expr)) \
11 timpi_error();
12
13using namespace TIMPI;
14
16
17void my_inserter(std::set<int> & s, int i)
18{ s.insert(i); }
19
20void my_inserter(std::multiset<int> & s, int i)
21{
22 s.insert(-1);
23 s.insert(3*i+1);
24 s.insert(3*i+2);
25}
26
27void my_inserter(std::unordered_multiset<int> & s, int i)
28{
29 s.insert(-1);
30 s.insert(3*i+1);
31 s.insert(3*i+2);
32}
33
34void my_inserter(std::set<std::vector<int>> & s, int i)
35{ s.insert(std::vector<int>(i,i)); }
36
37void my_inserter(std::unordered_set<int> & s, int i)
38{ s.insert(i); }
39
40void my_inserter(std::map<int, int> & m, int i)
41{ m.insert(std::make_pair(i,2*i+3)); }
42
43void my_inserter(std::multimap<int, int> & m, int i)
44{
45 m.insert(std::make_pair(-1,-1));
46 m.insert(std::make_pair(i,3*i+1));
47 m.insert(std::make_pair(i,3*i+2));
48}
49
50void my_inserter(std::unordered_multimap<int, int> & m, int i)
51{
52 m.insert(std::make_pair(-1,-1));
53 m.insert(std::make_pair(i,3*i+1));
54 m.insert(std::make_pair(i,3*i+2));
55}
56
57void my_inserter(std::map<int, std::vector<int>> & m, int i)
58{ m.insert(std::make_pair(i,std::vector<int>(i,2*i+3))); }
59
60void my_inserter(std::unordered_map<int, int> & m, int i)
61{ m.insert(std::make_pair(i,2*i+3)); }
62
63void my_inserter(std::unordered_map<int, std::vector<int>> & m, int i)
64{ m.insert(std::make_pair(i,std::vector<int>(i,2*i+3))); }
65
66
67void tester(const std::set<int> & s, int i)
68{ TIMPI_UNIT_ASSERT( s.count(i) == std::size_t(1) ); }
69
70void tester(const std::multiset<int> & s, int i)
71{
72 TIMPI_UNIT_ASSERT( s.count(-1) * 3 == s.size() );
73 TIMPI_UNIT_ASSERT( s.count(3*i+1) == std::size_t(1) );
74 TIMPI_UNIT_ASSERT( s.count(3*i+2) == std::size_t(1) );
75}
76
77void tester(const std::unordered_multiset<int> & s, int i)
78{
79 TIMPI_UNIT_ASSERT( s.count(-1) * 3 == s.size() );
80 TIMPI_UNIT_ASSERT( s.count(3*i+1) == std::size_t(1) );
81 TIMPI_UNIT_ASSERT( s.count(3*i+2) == std::size_t(1) );
82}
83
84void tester(const std::set<std::vector<int>> & s, int i)
85{ TIMPI_UNIT_ASSERT( s.count(std::vector<int>(i,i)) == std::size_t(1) ); }
86
87void tester(const std::unordered_set<int> & s, int i)
88{ TIMPI_UNIT_ASSERT( s.count(i) == std::size_t(1) ); }
89
90void tester(const std::map<int, int> & m, int i)
91{
92 TIMPI_UNIT_ASSERT( m.count(i) == std::size_t(1) );
93 TIMPI_UNIT_ASSERT( m.at(i) == 2*i+3 );
94}
95
96void tester(const std::multimap<int, int> & m, int i)
97{
98 TIMPI_UNIT_ASSERT( m.count(-1) * 3 == m.size() );
99
100 std::bitset<2> found;
101 auto pr = m.equal_range(i);
102 for (auto it = pr.first; it != pr.second; ++it)
103 {
104 auto val = it->second;
105 TIMPI_UNIT_ASSERT( val > 3*i && val < 3*i+3 );
106 TIMPI_UNIT_ASSERT( !found[val-3*i-1] );
107 found[val-3*i-1] = true;
108 }
109 TIMPI_UNIT_ASSERT( found.count() == 2 );
110}
111
112void tester(const std::unordered_multimap<int, int> & m, int i)
113{
114 TIMPI_UNIT_ASSERT( m.count(-1) * 3 == m.size() );
115
116 std::bitset<2> found;
117 const auto pr = m.equal_range(i);
118 for (auto it = pr.first; it != pr.second; ++it)
119 {
120 auto val = it->second;
121 TIMPI_UNIT_ASSERT( val > 3*i && val < 3*i+3 );
122 TIMPI_UNIT_ASSERT( !found[val-3*i-1] );
123 found[val-3*i-1] = true;
124 }
125 TIMPI_UNIT_ASSERT( found.count() == 2 );
126}
127
128void tester(const std::map<int, std::vector<int>> & m, int i)
129{
130 TIMPI_UNIT_ASSERT( m.count(i) == std::size_t(1) );
131 TIMPI_UNIT_ASSERT( m.at(i).size() == std::size_t(i) );
132 for (auto val : m.at(i))
133 TIMPI_UNIT_ASSERT( val == 2*i+3 );
134}
135
136void tester(const std::unordered_map<int, int> & m, int i)
137{
138 TIMPI_UNIT_ASSERT( m.count(i) == std::size_t(1) );
139 TIMPI_UNIT_ASSERT( m.at(i) == 2*i+3 );
140}
141
142void tester(const std::unordered_map<int, std::vector<int>> & m, int i)
143{
144 TIMPI_UNIT_ASSERT( m.count(i) == std::size_t(1) );
145 TIMPI_UNIT_ASSERT( m.at(i).size() == std::size_t(i) );
146 for (auto val : m.at(i))
147 TIMPI_UNIT_ASSERT( val == 2*i+3 );
148}
149
150
151 template <class Set>
152 void testBigUnion(int n_multi = 1)
153 {
154 Set data;
155
156 const int N = TestCommWorld->size();
157
159
161
162 // The real assertions here are the internal ones in that
163 // set_union
164 TIMPI_UNIT_ASSERT( data.size() == n_multi * std::size_t(N) );
165 for (int p=0; p<N; ++p)
166 {
167 tester(data, 150*N + p);
168 }
169 }
170
171
172
173 template <class Set>
175 {
176 Set data;
177
178 const int N = TestCommWorld->size();
179
181 my_inserter(data, 2*N);
183
185
186 TIMPI_UNIT_ASSERT( data.size() == std::size_t(2*N+1) );
187 tester(data, 2*N);
188 for (int p=0; p<N; ++p)
189 {
190 tester(data, p);
191 tester(data, 3*N+p);
192 }
193 }
194
195
197 {
198 std::map<unsigned int, std::set<unsigned short>> mapset;
199
200 // Values on all procs
201 mapset[0].insert(20201);
202
203 // Insert extra values on procs 0 and 2
204 switch (TestCommWorld->rank())
205 {
206 case 0:
207 case 2:
208 mapset[0].insert(60201);
209 break;
210 default:
211 break;
212 }
213
215
216 // Check results on all procs. In a broken 4-processor run what we
217 // saw was:
218 // key = 0, surface_ids = 20201 60201
219 // key = 0, surface_ids = 20201
220 // key = 0, surface_ids = 20201 60201
221 // key = 0, surface_ids = 20201
222 // whereas what we expect to see is that all procs have the
223 // same surface_ids, the ones from pid 0.
224 TIMPI_UNIT_ASSERT( mapset.size() == 1 );
225 const std::set<unsigned short> goodset {20201, 60201};
226 for (const auto & pr : mapset)
227 {
228 const auto & key = pr.first;
229 const auto & boundary_id_set = pr.second;
230 TIMPI_UNIT_ASSERT( key == 0 );
232 }
233 }
234
235
237 {
238 std::map<unsigned int, std::map<unsigned short, double>> mapmap;
239
240 // Values on all procs
241 mapmap[0].emplace(20201, 0.8);
242
243 // Insert extra values on procs 0 and 2
244 switch (TestCommWorld->rank())
245 {
246 case 0:
247 case 2:
248 mapmap[0].emplace(60201, 1.);
249 break;
250 default:
251 break;
252 }
253
255
256 TIMPI_UNIT_ASSERT( mapmap.size() == 1 );
257 const std::map<unsigned short, double> goodmap {{20201, 0.8},
258 {60201, 1}};
259 for (const auto & pr : mapmap)
260 {
261 const auto & key = pr.first;
262 const auto & boundary_id_map = pr.second;
263 TIMPI_UNIT_ASSERT( key == 0 );
265 }
266 }
267
268
269int main(int argc, const char * const * argv)
270{
272 TestCommWorld = &init.comm();
273
282
287
288 // TODO: allgather(vector<vector>)
289 // testUnion<std::set<std::vector<int>>>();
290
291 // No std::hash<vector<non-bool>>
292 // testUnion<std::unordered_set<std::vector<int>>>();
293
296
297 testMapSet();
298 testMapMap();
299
300 return 0;
301}
Encapsulates the MPI_Comm object.
processor_id_type size() const
processor_id_type rank() const
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,...
The TIMPIInit class, when constructed, initializes any dependent libraries (e.g.
Definition timpi_init.h:58
Tnew cast_int(Told oldvar)
Communicator * TestCommWorld
Definition set_unit.C:15
void testMapSet()
Definition set_unit.C:196
void testMapMap()
Definition set_unit.C:236
void tester(const std::set< int > &s, int i)
Definition set_unit.C:67
void testUnion()
Definition set_unit.C:174
void my_inserter(std::set< int > &s, int i)
Definition set_unit.C:17
void testBigUnion(int n_multi=1)
Definition set_unit.C:152
int main()
Definition version.C:20