Zoltan2
Toggle main menu visibility
Loading...
Searching...
No Matches
directoryTest_findUniqueGids.cpp
Go to the documentation of this file.
1
// @HEADER
2
// *****************************************************************************
3
// Zoltan2: A package of combinatorial algorithms for scientific computing
4
//
5
// Copyright 2012 NTESS and the Zoltan2 contributors.
6
// SPDX-License-Identifier: BSD-3-Clause
7
// *****************************************************************************
8
// @HEADER
9
10
// Program to testing Zoltan2::findUniqueGids capability
11
// Input: Vector of keys: each key is an array with N entries
12
// Result vector to be filled by findUniqueGids
13
// Output: Filled result vector
14
15
16
#include <iostream>
17
#include <vector>
18
#include <array>
19
#include <unordered_set>
20
#include <string>
21
#include <typeinfo>
22
23
#include <
Zoltan2_Standards.hpp
>
24
#include <
Zoltan2_Directory_Impl.hpp
>
25
26
namespace
Zoltan2
27
{
28
29
template
<
typename
key_t,
typename
gno_t>
30
size_t
findUniqueGids
(
31
const
std::vector<key_t> &keys,
32
std::vector<gno_t> &gids,
33
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
34
)
35
{
36
// Compute the new GIDs
37
const
bool
bUseLocalIDs =
false
;
// Local IDs not needed
38
int
debug_level = 0;
39
40
typedef
int
lno_t
;
// unused
41
42
typedef
Zoltan2_Directory_Simple<key_t,lno_t,gno_t>
directory_t;
43
44
directory_t directory(comm, bUseLocalIDs, debug_level);
45
46
directory.update(keys.size(), &keys[0], NULL, &gids[0], NULL,
47
directory_t::Update_Mode::Replace);
48
49
directory.remap_user_data_as_unique_gids();
50
51
// Retrieve the global numbers and put in the result gids vector
52
directory.find(keys.size(), &keys[0], NULL, &gids[0], NULL, NULL,
false
);
53
54
// using ssize_t can be long* on clang and I get warnings here or in the original
55
// findUniqueGids - using long long specifically is ok. Can we do an MPI type
56
// as size_t safely or is a conversion necessary? TODO but this gives a clean
57
// build result.
58
typedef
long
long
mpi_t;
59
mpi_t nDDEntries =
static_cast<
mpi_t
>
(directory.node_map_size());
60
mpi_t nUnique = 0;
61
62
// TODO use Teuchos
63
#ifdef HAVE_MPI
64
MPI_Allreduce(&nDDEntries, &nUnique, 1, MPI_LONG_LONG, MPI_SUM,
65
Teuchos::getRawMpiComm(*comm));
66
#else
67
MPI_Allreduce(&nDDEntries, &nUnique, 1, MPI_LONG_LONG, MPI_SUM, MPI_COMM_WORLD);
68
#endif
69
70
return
size_t(nUnique);
71
}
72
73
template
<
typename
T>
74
struct
type_name
75
{
76
static
const
char
*
name
() {
77
std::cout <<
"You are missing a DECL_TYPE_NAME"
<< std::endl;
78
return
(NULL);
79
}
80
};
81
82
#define DECL_TYPE_NAME(x) \
83
template<> struct type_name<x> { static const char* name() {return #x;} }
84
85
DECL_TYPE_NAME
(
int
);
86
DECL_TYPE_NAME
(
long
long
);
87
89
// Tests for correctness
90
static
const
std::string
fail
=
"FAIL "
;
91
static
const
std::string
pass
=
" "
;
92
93
// Test for correct number of unique Gids
94
void
checkNUnique
(std::string &name,
size_t
nUniqueGids,
size_t
nExpected)
95
{
96
if
(nUniqueGids != nExpected)
97
std::cout <<
fail
<< name
98
<<
"nUniqueGids "
<< nUniqueGids <<
" != "
<< nExpected
99
<< std::endl;
100
}
101
102
// Test for correct maximum Gid
103
template
<
typename
gno_t>
104
void
checkMaxGid
(
105
std::string &name,
106
std::vector<gno_t> &gids,
107
gno_t
maxExpected,
108
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
109
)
110
{
111
gno_t
maxGid = 0, gmaxGid = 0;
112
size_t
len = gids.size();
113
for
(
size_t
i = 0; i < len; i++)
114
if
(gids[i] > maxGid) maxGid = gids[i];
115
116
Teuchos::reduceAll<int, gno_t>(*comm, Teuchos::REDUCE_MAX, 1,
117
&maxGid, &gmaxGid);
118
if
(gmaxGid != maxExpected)
119
std::cout <<
fail
<< name
120
<<
"max Gid "
<< gmaxGid <<
" != "
<< maxExpected
121
<< std::endl;
122
}
123
124
// Test for correct minimum Gid
125
template
<
typename
gno_t>
126
void
checkMinGid
(
127
std::string &name,
128
std::vector<gno_t> &gids,
129
gno_t
minExpected,
130
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
131
)
132
{
133
gno_t
minGid = std::numeric_limits<gno_t>::max(), gminGid;
134
size_t
len = gids.size();
135
for
(
size_t
i = 0; i < len; i++)
136
if
(gids[i] < minGid) minGid = gids[i];
137
138
Teuchos::reduceAll<int, gno_t>(*comm, Teuchos::REDUCE_MIN, 1,
139
&minGid, &gminGid);
140
if
(gminGid != minExpected)
141
std::cout <<
fail
<< name
142
<<
"min Gid "
<< gminGid <<
" != "
<< minExpected
143
<< std::endl;
144
}
145
146
// Test for number of locally unique Gids
147
template
<
typename
gno_t>
148
void
checkNLocallyUnique
(
149
std::string &name,
150
std::vector<gno_t> &gids,
151
size_t
nExpected)
152
{
153
size_t
gidsLen = gids.size();
154
std::unordered_set<gno_t> gidsSet(gidsLen);
155
156
size_t
nDups = 0;
157
for
(
size_t
i = 0; i < gidsLen; i++) {
158
if
(gidsSet.find(gids[i]) != gidsSet.end()) {
159
// Gid is already found locally
160
nDups++;
161
}
162
else
163
gidsSet.insert(gids[i]);
164
}
165
size_t
nUnique = gidsLen - nDups;
166
if
(nUnique != nExpected)
167
std::cout <<
fail
<< name
168
<<
"num locally unique Gids "
<< nUnique <<
" != "
<< nExpected
169
<< std::endl;
170
}
171
173
174
template
<
typename
gno_t>
175
void
test1
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
176
{
177
// Test 1:
178
// Key has only one entry
179
// Each proc has me+1 keys
180
// Keys are in range [1,np]
181
int
me = comm->getRank();
182
int
np = comm->getSize();
183
184
std::string name = std::string(
" test1: "
)
185
+ std::string(
type_name<gno_t>::name
());
186
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
187
188
typedef
std::array<gno_t, 1> zkey_t;
189
typedef
std::vector<zkey_t> keyvec_t;
190
typedef
std::vector<gno_t> gidvec_t;
191
192
const
size_t
nKeys = me+1;
193
keyvec_t keys(nKeys);
194
gidvec_t gids(nKeys);
195
196
for
(
size_t
i = 0; i < nKeys; i++) {
197
zkey_t k;
198
k[0] = i+1;
199
keys[i] = k;
200
}
201
202
size_t
nUniqueGids =
findUniqueGids<zkey_t, gno_t>
(keys,gids,comm);
203
204
// Test for correctness
205
if
(me == 0)
206
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
207
208
checkNUnique
(name, nUniqueGids,
size_t
(np));
209
210
checkMaxGid
(name, gids,
gno_t
(np-1), comm);
211
212
checkMinGid
(name, gids,
gno_t
(0), comm);
213
214
checkNLocallyUnique
(name, gids, nKeys);
215
}
216
218
219
template
<
typename
gno_t>
220
void
test2
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
221
{
222
// Test 2:
223
// Key has two entries
224
// Each proc has six keys
225
// Three Keys are {rank, x} for x in {1, 2, 3}
226
// Three Keys are {(rank+x)%np, x} for x in {1, 2, 3}
227
// Each rank has three unique and three non-unique keys
228
int
me = comm->getRank();
229
int
np = comm->getSize();
230
231
std::string name = std::string(
" test2: "
)
232
+ std::string(
type_name<gno_t>::name
());
233
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
234
235
typedef
std::array<gno_t, 2> zkey_t;
236
typedef
std::vector<zkey_t> keyvec_t;
237
typedef
std::vector<gno_t> gidvec_t;
238
239
const
size_t
nKeys = 6;
240
const
size_t
nKeysHalf = 3;
241
keyvec_t keys(nKeys);
242
gidvec_t gids(nKeys);
243
244
for
(
size_t
i = 0; i < nKeysHalf; i++) {
245
zkey_t k;
246
k[0] =
gno_t
(me);
247
k[1] =
gno_t
(i+1);
248
keys[i] = k;
249
}
250
for
(
size_t
i = 0; i < nKeysHalf; i++) {
251
zkey_t k;
252
k[0] =
gno_t
((me+i+1)%np);
253
k[1] =
gno_t
(i+1);
254
keys[i+nKeysHalf] = k;
255
}
256
257
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
258
259
// Test for correctness
260
if
(me == 0)
261
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
262
263
checkNUnique
(name, nUniqueGids,
size_t
(nKeysHalf*np));
264
265
checkMaxGid
(name, gids,
gno_t
(nKeysHalf*np-1), comm);
266
267
checkMinGid
(name, gids,
gno_t
(0), comm);
268
}
269
271
template
<
typename
gno_t>
272
void
test3
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
273
{
274
// Test 3:
275
// Key has three entries
276
// Each proc has 2*np keys
277
// np Keys are {x, x, x} for x in {0, 1, ..., np-1}
278
// np Keys are {rank, rank, x} for x in {0, 1, ..., np-1}
279
// Each proc has one locally duplicated key
280
// Each proc contributes np unique keys
281
int
me = comm->getRank();
282
int
np = comm->getSize();
283
284
std::string name = std::string(
" test3: "
)
285
+ std::string(
type_name<gno_t>::name
());
286
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
287
288
typedef
std::array<gno_t, 3> zkey_t;
289
typedef
std::vector<zkey_t> keyvec_t;
290
typedef
std::vector<gno_t> gidvec_t;
291
292
const
size_t
nKeys = 2*np;
293
const
size_t
nKeysHalf = np;
294
keyvec_t keys(nKeys);
295
gidvec_t gids(nKeys);
296
297
for
(
size_t
i = 0; i < nKeysHalf; i++) {
298
zkey_t k;
299
k[0] =
gno_t
(me);
300
k[1] =
gno_t
(me);
301
k[2] =
gno_t
(i);
302
keys[i+nKeysHalf] = k;
303
}
304
for
(
size_t
i = 0; i < nKeysHalf; i++) {
305
zkey_t k;
306
k[0] =
gno_t
(i);
307
k[1] =
gno_t
(i);
308
k[2] =
gno_t
(i);
309
keys[i] = k;
310
}
311
312
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
313
314
// for (size_t i = 0; i < nKeys; i++)
315
// std::cout << me << " Key " << i << ": "
316
// << keys[i][0] << " " << keys[i][1] << " " << keys[i][2]
317
// << " GID " << gids[i]
318
// << std::endl;
319
320
// Test for correctness
321
if
(me == 0)
322
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
323
324
checkNUnique
(name, nUniqueGids,
size_t
(np*np));
325
326
checkMaxGid
(name, gids,
gno_t
(np*np-1), comm);
327
328
checkMinGid
(name, gids,
gno_t
(0), comm);
329
330
checkNLocallyUnique
(name, gids,
size_t
(nKeys-1));
331
}
332
334
335
template
<
typename
gno_t>
336
void
test4
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
337
{
338
// Test 4:
339
// Key has four entries
340
// Each proc has (rank+1)%2 keys; odd-numbered ranks are empty
341
// Keys are all identical {0, 1, 2, 3}
342
int
me = comm->getRank();
343
344
std::string name = std::string(
" test4: "
)
345
+ std::string(
type_name<gno_t>::name
());
346
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
347
348
typedef
std::array<gno_t, 4> zkey_t;
349
typedef
std::vector<zkey_t> keyvec_t;
350
typedef
std::vector<gno_t> gidvec_t;
351
352
const
size_t
nKeys = (me+1)%2;
353
keyvec_t keys(nKeys);
354
gidvec_t gids(nKeys);
355
356
for
(
size_t
i = 0; i < nKeys; i++) {
357
zkey_t k;
358
k[0] =
gno_t
(0);
359
k[1] =
gno_t
(1);
360
k[2] =
gno_t
(2);
361
k[3] =
gno_t
(3);
362
keys[i] = k;
363
}
364
365
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
366
367
// Test for correctness
368
if
(me == 0)
369
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
370
371
checkNUnique
(name, nUniqueGids,
size_t
(1));
372
373
checkMaxGid
(name, gids,
gno_t
(0), comm);
374
375
checkMinGid
(name, gids,
gno_t
(0), comm);
376
377
checkNLocallyUnique
(name, gids, (nKeys ?
size_t
(1):
size_t
(0)));
378
}
379
380
}
// namespace Zoltan2
381
382
int
main
(
int
argc,
char
*argv[])
383
{
384
Tpetra::ScopeGuard tscope(&argc, &argv);
385
Teuchos::RCP<const Teuchos::Comm<int> > comm =
386
Teuchos::DefaultComm<int>::getComm();
387
388
Zoltan2::test1<int>
(comm);
389
Zoltan2::test2<int>
(comm);
390
Zoltan2::test3<int>
(comm);
391
Zoltan2::test4<int>
(comm);
392
393
Zoltan2::test1<long long>
(comm);
394
Zoltan2::test2<long long>
(comm);
395
Zoltan2::test3<long long>
(comm);
396
Zoltan2::test4<long long>
(comm);
397
398
return
0;
399
}
Zoltan2_Directory_Impl.hpp
Zoltan2_Standards.hpp
Gathering definitions used in software development.
main
int main()
Definition
absdefinitiontest.cpp:15
Zoltan2::Zoltan2_Directory_Simple
Definition
Zoltan2_Directory.hpp:270
DECL_TYPE_NAME
#define DECL_TYPE_NAME(x)
Definition
directoryTest_findUniqueGids.cpp:82
gno_t
map_t::global_ordinal_type gno_t
Definition
mapRemotes.cpp:27
Zoltan2
Created by mbenlioglu on Aug 31, 2020.
Definition
Zoltan2_AlgHybrid2GL.hpp:47
Zoltan2::test3
void test3(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:272
Zoltan2::checkNUnique
void checkNUnique(std::string &name, size_t nUniqueGids, size_t nExpected)
Definition
directoryTest_findUniqueGids.cpp:94
Zoltan2::findUniqueGids
size_t findUniqueGids(Tpetra::MultiVector< gno_t, lno_t, gno_t > &keys, Tpetra::Vector< gno_t, lno_t, gno_t > &gids)
Definition
Zoltan2_findUniqueGids.hpp:89
Zoltan2::checkNLocallyUnique
void checkNLocallyUnique(std::string &name, std::vector< gno_t > &gids, size_t nExpected)
Definition
directoryTest_findUniqueGids.cpp:148
Zoltan2::fail
static const std::string fail
Definition
directoryTest_findUniqueGids.cpp:90
Zoltan2::test1
void test1(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:175
Zoltan2::test2
void test2(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:220
Zoltan2::checkMaxGid
void checkMaxGid(std::string &name, std::vector< gno_t > &gids, gno_t maxExpected, Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:104
Zoltan2::test4
void test4(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:336
Zoltan2::checkMinGid
void checkMinGid(std::string &name, std::vector< gno_t > &gids, gno_t minExpected, Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:126
Zoltan2::pass
static const std::string pass
Definition
directoryTest_findUniqueGids.cpp:91
Zoltan2::lno_t
Zoltan2::type_name
Definition
directoryTest_findUniqueGids.cpp:75
Zoltan2::type_name::name
static const char * name()
Definition
directoryTest_findUniqueGids.cpp:76
test
core
directory
directoryTest_findUniqueGids.cpp
Generated by
1.17.0