Zoltan2
Toggle main menu visibility
Loading...
Searching...
No Matches
directoryTest_findUniqueGids.cpp
Go to the documentation of this file.
1
// @HEADER
2
//
3
// ***********************************************************************
4
//
5
// Zoltan2: A package of combinatorial algorithms for scientific computing
6
// Copyright 2012 Sandia Corporation
7
//
8
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9
// the U.S. Government retains certain rights in this software.
10
//
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are
13
// met:
14
//
15
// 1. Redistributions of source code must retain the above copyright
16
// notice, this list of conditions and the following disclaimer.
17
//
18
// 2. Redistributions in binary form must reproduce the above copyright
19
// notice, this list of conditions and the following disclaimer in the
20
// documentation and/or other materials provided with the distribution.
21
//
22
// 3. Neither the name of the Corporation nor the names of the
23
// contributors may be used to endorse or promote products derived from
24
// this software without specific prior written permission.
25
//
26
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37
//
38
// Questions? Contact Karen Devine (kddevin@sandia.gov)
39
// Erik Boman (egboman@sandia.gov)
40
// Siva Rajamanickam (srajama@sandia.gov)
41
//
42
// ***********************************************************************
43
//
44
// @HEADER
45
46
// Program to testing Zoltan2::findUniqueGids capability
47
// Input: Vector of keys: each key is an array with N entries
48
// Result vector to be filled by findUniqueGids
49
// Output: Filled result vector
50
51
52
#include <iostream>
53
#include <vector>
54
#include <array>
55
#include <unordered_set>
56
#include <string>
57
#include <typeinfo>
58
59
#include <
Zoltan2_Standards.hpp
>
60
#include <
Zoltan2_Directory_Impl.hpp
>
61
62
namespace
Zoltan2
63
{
64
65
template
<
typename
key_t,
typename
gno_t>
66
size_t
findUniqueGids
(
67
const
std::vector<key_t> &keys,
68
std::vector<gno_t> &gids,
69
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
70
)
71
{
72
// Compute the new GIDs
73
const
bool
bUseLocalIDs =
false
;
// Local IDs not needed
74
int
debug_level = 0;
75
76
typedef
int
lno_t
;
// unused
77
78
typedef
Zoltan2_Directory_Simple<key_t,lno_t,gno_t>
directory_t;
79
80
directory_t directory(comm, bUseLocalIDs, debug_level);
81
82
directory.update(keys.size(), &keys[0], NULL, &gids[0], NULL,
83
directory_t::Update_Mode::Replace);
84
85
directory.remap_user_data_as_unique_gids();
86
87
// Retrieve the global numbers and put in the result gids vector
88
directory.find(keys.size(), &keys[0], NULL, &gids[0], NULL, NULL,
false
);
89
90
// using ssize_t can be long* on clang and I get warnings here or in the original
91
// findUniqueGids - using long long specifically is ok. Can we do an MPI type
92
// as size_t safely or is a conversion necessary? TODO but this gives a clean
93
// build result.
94
typedef
long
long
mpi_t;
95
mpi_t nDDEntries =
static_cast<
mpi_t
>
(directory.node_map_size());
96
mpi_t nUnique = 0;
97
98
// TODO use Teuchos
99
#ifdef HAVE_MPI
100
MPI_Allreduce(&nDDEntries, &nUnique, 1, MPI_LONG_LONG, MPI_SUM,
101
Teuchos::getRawMpiComm(*comm));
102
#else
103
MPI_Allreduce(&nDDEntries, &nUnique, 1, MPI_LONG_LONG, MPI_SUM, MPI_COMM_WORLD);
104
#endif
105
106
return
size_t(nUnique);
107
}
108
109
template
<
typename
T>
110
struct
type_name
111
{
112
static
const
char
*
name
() {
113
std::cout <<
"You are missing a DECL_TYPE_NAME"
<< std::endl;
114
return
(NULL);
115
}
116
};
117
118
#define DECL_TYPE_NAME(x) \
119
template<> struct type_name<x> { static const char* name() {return #x;} }
120
121
DECL_TYPE_NAME
(
int
);
122
DECL_TYPE_NAME
(
long
long
);
123
125
// Tests for correctness
126
static
const
std::string
fail
=
"FAIL "
;
127
static
const
std::string
pass
=
" "
;
128
129
// Test for correct number of unique Gids
130
void
checkNUnique
(std::string &name,
size_t
nUniqueGids,
size_t
nExpected)
131
{
132
if
(nUniqueGids != nExpected)
133
std::cout <<
fail
<< name
134
<<
"nUniqueGids "
<< nUniqueGids <<
" != "
<< nExpected
135
<< std::endl;
136
}
137
138
// Test for correct maximum Gid
139
template
<
typename
gno_t>
140
void
checkMaxGid
(
141
std::string &name,
142
std::vector<gno_t> &gids,
143
gno_t
maxExpected,
144
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
145
)
146
{
147
gno_t
maxGid = 0, gmaxGid = 0;
148
size_t
len = gids.size();
149
for
(
size_t
i = 0; i < len; i++)
150
if
(gids[i] > maxGid) maxGid = gids[i];
151
152
Teuchos::reduceAll<int, gno_t>(*comm, Teuchos::REDUCE_MAX, 1,
153
&maxGid, &gmaxGid);
154
if
(gmaxGid != maxExpected)
155
std::cout <<
fail
<< name
156
<<
"max Gid "
<< gmaxGid <<
" != "
<< maxExpected
157
<< std::endl;
158
}
159
160
// Test for correct minimum Gid
161
template
<
typename
gno_t>
162
void
checkMinGid
(
163
std::string &name,
164
std::vector<gno_t> &gids,
165
gno_t
minExpected,
166
Teuchos::RCP<
const
Teuchos::Comm<int> > &comm
167
)
168
{
169
gno_t
minGid = std::numeric_limits<gno_t>::max(), gminGid;
170
size_t
len = gids.size();
171
for
(
size_t
i = 0; i < len; i++)
172
if
(gids[i] < minGid) minGid = gids[i];
173
174
Teuchos::reduceAll<int, gno_t>(*comm, Teuchos::REDUCE_MIN, 1,
175
&minGid, &gminGid);
176
if
(gminGid != minExpected)
177
std::cout <<
fail
<< name
178
<<
"min Gid "
<< gminGid <<
" != "
<< minExpected
179
<< std::endl;
180
}
181
182
// Test for number of locally unique Gids
183
template
<
typename
gno_t>
184
void
checkNLocallyUnique
(
185
std::string &name,
186
std::vector<gno_t> &gids,
187
size_t
nExpected)
188
{
189
size_t
gidsLen = gids.size();
190
std::unordered_set<gno_t> gidsSet(gidsLen);
191
192
size_t
nDups = 0;
193
for
(
size_t
i = 0; i < gidsLen; i++) {
194
if
(gidsSet.find(gids[i]) != gidsSet.end()) {
195
// Gid is already found locally
196
nDups++;
197
}
198
else
199
gidsSet.insert(gids[i]);
200
}
201
size_t
nUnique = gidsLen - nDups;
202
if
(nUnique != nExpected)
203
std::cout <<
fail
<< name
204
<<
"num locally unique Gids "
<< nUnique <<
" != "
<< nExpected
205
<< std::endl;
206
}
207
209
210
template
<
typename
gno_t>
211
void
test1
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
212
{
213
// Test 1:
214
// Key has only one entry
215
// Each proc has me+1 keys
216
// Keys are in range [1,np]
217
int
me = comm->getRank();
218
int
np = comm->getSize();
219
220
std::string name = std::string(
" test1: "
)
221
+ std::string(
type_name<gno_t>::name
());
222
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
223
224
typedef
std::array<gno_t, 1> zkey_t;
225
typedef
std::vector<zkey_t> keyvec_t;
226
typedef
std::vector<gno_t> gidvec_t;
227
228
const
size_t
nKeys = me+1;
229
keyvec_t keys(nKeys);
230
gidvec_t gids(nKeys);
231
232
for
(
size_t
i = 0; i < nKeys; i++) {
233
zkey_t k;
234
k[0] = i+1;
235
keys[i] = k;
236
}
237
238
size_t
nUniqueGids =
findUniqueGids<zkey_t, gno_t>
(keys,gids,comm);
239
240
// Test for correctness
241
if
(me == 0)
242
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
243
244
checkNUnique
(name, nUniqueGids,
size_t
(np));
245
246
checkMaxGid
(name, gids,
gno_t
(np-1), comm);
247
248
checkMinGid
(name, gids,
gno_t
(0), comm);
249
250
checkNLocallyUnique
(name, gids, nKeys);
251
}
252
254
255
template
<
typename
gno_t>
256
void
test2
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
257
{
258
// Test 2:
259
// Key has two entries
260
// Each proc has six keys
261
// Three Keys are {rank, x} for x in {1, 2, 3}
262
// Three Keys are {(rank+x)%np, x} for x in {1, 2, 3}
263
// Each rank has three unique and three non-unique keys
264
int
me = comm->getRank();
265
int
np = comm->getSize();
266
267
std::string name = std::string(
" test2: "
)
268
+ std::string(
type_name<gno_t>::name
());
269
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
270
271
typedef
std::array<gno_t, 2> zkey_t;
272
typedef
std::vector<zkey_t> keyvec_t;
273
typedef
std::vector<gno_t> gidvec_t;
274
275
const
size_t
nKeys = 6;
276
const
size_t
nKeysHalf = 3;
277
keyvec_t keys(nKeys);
278
gidvec_t gids(nKeys);
279
280
for
(
size_t
i = 0; i < nKeysHalf; i++) {
281
zkey_t k;
282
k[0] =
gno_t
(me);
283
k[1] =
gno_t
(i+1);
284
keys[i] = k;
285
}
286
for
(
size_t
i = 0; i < nKeysHalf; i++) {
287
zkey_t k;
288
k[0] =
gno_t
((me+i+1)%np);
289
k[1] =
gno_t
(i+1);
290
keys[i+nKeysHalf] = k;
291
}
292
293
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
294
295
// Test for correctness
296
if
(me == 0)
297
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
298
299
checkNUnique
(name, nUniqueGids,
size_t
(nKeysHalf*np));
300
301
checkMaxGid
(name, gids,
gno_t
(nKeysHalf*np-1), comm);
302
303
checkMinGid
(name, gids,
gno_t
(0), comm);
304
}
305
307
template
<
typename
gno_t>
308
void
test3
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
309
{
310
// Test 3:
311
// Key has three entries
312
// Each proc has 2*np keys
313
// np Keys are {x, x, x} for x in {0, 1, ..., np-1}
314
// np Keys are {rank, rank, x} for x in {0, 1, ..., np-1}
315
// Each proc has one locally duplicated key
316
// Each proc contributes np unique keys
317
int
me = comm->getRank();
318
int
np = comm->getSize();
319
320
std::string name = std::string(
" test3: "
)
321
+ std::string(
type_name<gno_t>::name
());
322
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
323
324
typedef
std::array<gno_t, 3> zkey_t;
325
typedef
std::vector<zkey_t> keyvec_t;
326
typedef
std::vector<gno_t> gidvec_t;
327
328
const
size_t
nKeys = 2*np;
329
const
size_t
nKeysHalf = np;
330
keyvec_t keys(nKeys);
331
gidvec_t gids(nKeys);
332
333
for
(
size_t
i = 0; i < nKeysHalf; i++) {
334
zkey_t k;
335
k[0] =
gno_t
(me);
336
k[1] =
gno_t
(me);
337
k[2] =
gno_t
(i);
338
keys[i+nKeysHalf] = k;
339
}
340
for
(
size_t
i = 0; i < nKeysHalf; i++) {
341
zkey_t k;
342
k[0] =
gno_t
(i);
343
k[1] =
gno_t
(i);
344
k[2] =
gno_t
(i);
345
keys[i] = k;
346
}
347
348
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
349
350
// for (size_t i = 0; i < nKeys; i++)
351
// std::cout << me << " Key " << i << ": "
352
// << keys[i][0] << " " << keys[i][1] << " " << keys[i][2]
353
// << " GID " << gids[i]
354
// << std::endl;
355
356
// Test for correctness
357
if
(me == 0)
358
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
359
360
checkNUnique
(name, nUniqueGids,
size_t
(np*np));
361
362
checkMaxGid
(name, gids,
gno_t
(np*np-1), comm);
363
364
checkMinGid
(name, gids,
gno_t
(0), comm);
365
366
checkNLocallyUnique
(name, gids,
size_t
(nKeys-1));
367
}
368
370
371
template
<
typename
gno_t>
372
void
test4
(Teuchos::RCP<
const
Teuchos::Comm<int> > &comm)
373
{
374
// Test 4:
375
// Key has four entries
376
// Each proc has (rank+1)%2 keys; odd-numbered ranks are empty
377
// Keys are all identical {0, 1, 2, 3}
378
int
me = comm->getRank();
379
380
std::string name = std::string(
" test4: "
)
381
+ std::string(
type_name<gno_t>::name
());
382
if
(me == 0) std::cout <<
"--------\n Starting "
<< name << std::endl;
383
384
typedef
std::array<gno_t, 4> zkey_t;
385
typedef
std::vector<zkey_t> keyvec_t;
386
typedef
std::vector<gno_t> gidvec_t;
387
388
const
size_t
nKeys = (me+1)%2;
389
keyvec_t keys(nKeys);
390
gidvec_t gids(nKeys);
391
392
for
(
size_t
i = 0; i < nKeys; i++) {
393
zkey_t k;
394
k[0] =
gno_t
(0);
395
k[1] =
gno_t
(1);
396
k[2] =
gno_t
(2);
397
k[3] =
gno_t
(3);
398
keys[i] = k;
399
}
400
401
size_t
nUniqueGids =
findUniqueGids<zkey_t,gno_t>
(keys,gids,comm);
402
403
// Test for correctness
404
if
(me == 0)
405
std::cout <<
" "
<< name <<
" nUniqueGids "
<< nUniqueGids << std::endl;
406
407
checkNUnique
(name, nUniqueGids,
size_t
(1));
408
409
checkMaxGid
(name, gids,
gno_t
(0), comm);
410
411
checkMinGid
(name, gids,
gno_t
(0), comm);
412
413
checkNLocallyUnique
(name, gids, (nKeys ?
size_t
(1):
size_t
(0)));
414
}
415
416
}
// namespace Zoltan2
417
418
int
main
(
int
argc,
char
*argv[])
419
{
420
Tpetra::ScopeGuard tscope(&argc, &argv);
421
Teuchos::RCP<const Teuchos::Comm<int> > comm =
422
Teuchos::DefaultComm<int>::getComm();
423
424
Zoltan2::test1<int>
(comm);
425
Zoltan2::test2<int>
(comm);
426
Zoltan2::test3<int>
(comm);
427
Zoltan2::test4<int>
(comm);
428
429
Zoltan2::test1<long long>
(comm);
430
Zoltan2::test2<long long>
(comm);
431
Zoltan2::test3<long long>
(comm);
432
Zoltan2::test4<long long>
(comm);
433
434
return
0;
435
}
Zoltan2_Directory_Impl.hpp
Zoltan2_Standards.hpp
Gathering definitions used in software development.
main
int main()
Definition
absdefinitiontest.cpp:6
Zoltan2::Zoltan2_Directory_Simple
Definition
Zoltan2_Directory.hpp:307
DECL_TYPE_NAME
#define DECL_TYPE_NAME(x)
Definition
directoryTest_findUniqueGids.cpp:118
gno_t
map_t::global_ordinal_type gno_t
Definition
mapRemotes.cpp:18
Zoltan2
Created by mbenlioglu on Aug 31, 2020.
Definition
Zoltan2_AlgHybrid2GL.hpp:38
Zoltan2::test3
void test3(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:308
Zoltan2::checkNUnique
void checkNUnique(std::string &name, size_t nUniqueGids, size_t nExpected)
Definition
directoryTest_findUniqueGids.cpp:130
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:125
Zoltan2::checkNLocallyUnique
void checkNLocallyUnique(std::string &name, std::vector< gno_t > &gids, size_t nExpected)
Definition
directoryTest_findUniqueGids.cpp:184
Zoltan2::fail
static const std::string fail
Definition
directoryTest_findUniqueGids.cpp:126
Zoltan2::test1
void test1(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:211
Zoltan2::test2
void test2(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:256
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:140
Zoltan2::test4
void test4(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Definition
directoryTest_findUniqueGids.cpp:372
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:162
Zoltan2::pass
static const std::string pass
Definition
directoryTest_findUniqueGids.cpp:127
Zoltan2::lno_t
Zoltan2::type_name
Definition
directoryTest_findUniqueGids.cpp:111
Zoltan2::type_name::name
static const char * name()
Definition
directoryTest_findUniqueGids.cpp:112
test
core
directory
directoryTest_findUniqueGids.cpp
Generated by
1.17.0