Zoltan2
Loading...
Searching...
No Matches
componentMetrics.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
14#include <iostream>
15#include <Teuchos_RCP.hpp>
16#include <Tpetra_CrsMatrix.hpp>
17#include <MatrixMarket_Tpetra.hpp>
18
19
21// Test program for componentMetrics code.
22// Usage:
23// a.out
24// Karen Devine, 2017
26
27typedef Tpetra::Map<zlno_t, zgno_t> zmap_t;
28typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t> zmatrix_t;
29typedef Tpetra::CrsGraph<zlno_t, zgno_t> zgraph_t;
30
33
35template <typename CC_T>
37 std::string &name, // test name (including rank)
38 CC_T cc, // the perProcessorComponentMetrics object for the test
39 size_t nccAnswer, // Expected answers for the test
40 size_t maxAnswer,
41 size_t minAnswer,
42 double avgAnswer
43)
44{
45 int ierr = 0;
46
47 if (cc.getNumComponents() != nccAnswer) {
48 std::cout << name << "Invalid number of components "
49 << cc.getNumComponents() << " should be " << nccAnswer
50 << std::endl;
51 ierr++;
52 }
53
54 if (cc.getMaxComponentSize() != maxAnswer) {
55 std::cout << name << "Maximum component size "
56 << cc.getMaxComponentSize() << " should be " << maxAnswer
57 << std::endl;
58 ierr++;
59 }
60
61 if (cc.getMinComponentSize() != minAnswer) {
62 std::cout << name << "Minimum component size "
63 << cc.getMinComponentSize() << " should be " << minAnswer
64 << std::endl;
65 ierr++;
66 }
67
68 if (cc.getAvgComponentSize() != avgAnswer) {
69 std::cout << name << "Average component size "
70 << cc.getAvgComponentSize() << " should be " << avgAnswer
71 << std::endl;
72 ierr++;
73 }
74
75 return ierr;
76}
77
79int test_every_third(Teuchos::RCP<const Teuchos::Comm<int> > &comm)
80{
81 // Testing a graph with every third vertex in the same component
82 // Test using a GraphAdapter.
83
84 std::ostringstream namestream;
85 namestream << comm->getRank() << " every_third ";
86 std::string name = namestream.str();
87
88 int ierr = 0;
89
90 // Create a default map
91 const size_t gNvtx = 27;
92
93 Teuchos::RCP<const zmap_t> map = rcp(new zmap_t(gNvtx, 0, comm));
94 size_t nVtx = map->getLocalNumElements();
95
96 // Create a Tpetra::Matrix with every third local row in the same component
97 size_t maxRowLen = 3;
98 Teuchos::RCP<zmatrix_t> matrix = rcp(new zmatrix_t(map, maxRowLen));
99
100 Teuchos::Array<zgno_t> col(3);
101 Teuchos::Array<zscalar_t> val(3); val[0] = 1.; val[1] = 1.; val[2] = 1.;
102
103 for (size_t i = 0; i < nVtx; i++) {
104 zgno_t id = map->getGlobalElement(i);
105 col[0] = (id+3)%gNvtx;
106 col[1] = (id+6)%gNvtx;
107 col[2] = (id+9)%gNvtx;
108 matrix->insertGlobalValues(id, col(), val());
109 }
110
111 matrix->fillComplete(map, map);
112
113 // Create a Zoltan2 XpetraGraphAdapter
114 graphAdapter_t ia(matrix->getCrsGraph(), 0);
115
116 // Call connected components utility
118 cc_t cc(ia, *comm);
119
120 // Check result:
121 size_t nccAnswer = std::min<size_t>(3, nVtx);
122 size_t maxAnswer = nVtx/3 + ((nVtx%3)!=0);
123 size_t minAnswer = (nVtx ? std::max<size_t>(nVtx/3, 1) : 0);
124 double avgAnswer = (nVtx ? double(nVtx) / double(std::min<size_t>(nVtx,3))
125 : 0.);
126
127 ierr = checkResult<cc_t>(name, cc,
128 nccAnswer, maxAnswer, minAnswer, avgAnswer);
129
130 return ierr;
131}
132
134int test_dist_component(Teuchos::RCP<const Teuchos::Comm<int> > &comm)
135{
136 // Testing a graph with single component, distributed among procs
137 // Test using a GraphAdapter.
138
139 std::ostringstream namestream;
140 namestream << comm->getRank() << " dist_component ";
141 std::string name = namestream.str();
142
143 int ierr = 0;
144
145 // Create a default map
146 const size_t gNvtx = 25;
147
148 Teuchos::RCP<const zmap_t> map = rcp(new zmap_t(gNvtx, 0, comm));
149 size_t nVtx = map->getLocalNumElements();
150
151 // Create a Tpetra::Matrix with a single component
152 size_t maxRowLen = 3;
153 Teuchos::RCP<zmatrix_t> matrix = rcp(new zmatrix_t(map, maxRowLen));
154
155 Teuchos::Array<zgno_t> col(3);
156 Teuchos::Array<zscalar_t> val(3); val[0] = 1.; val[1] = 1.; val[2] = 1.;
157
158 for (size_t i = 0; i < nVtx; i++) {
159 zgno_t id = map->getGlobalElement(i);
160 col[0] = (id+4)%gNvtx;
161 col[1] = (id+1)%gNvtx;
162 col[2] = (id+3)%gNvtx;
163 matrix->insertGlobalValues(id, col(), val());
164 }
165
166 matrix->fillComplete(map, map);
167
168 // Create a Zoltan2 XpetraGraphAdapter
169 graphAdapter_t ia(matrix->getCrsGraph(), 0);
170
171 // Call connected components utility
173 cc_t cc(ia, *comm);
174
175 // Check result:
176 // one component with all local vertices
177 size_t nccAnswer = size_t(nVtx > 0);
178 size_t maxAnswer = nVtx;
179 size_t minAnswer = nVtx;
180 double avgAnswer = nVtx;
181
182 ierr = checkResult<cc_t>(name, cc,
183 nccAnswer, maxAnswer, minAnswer, avgAnswer);
184
185 return ierr;
186}
187
189int test_one_proc(Teuchos::RCP<const Teuchos::Comm<int> > &comm)
190{
191 // Testing a graph with all vertices and edges on a single proc
192 // Test using a MatrixAdapter.
193
194 std::ostringstream namestream;
195 namestream << comm->getRank() << " one_proc ";
196 std::string name = namestream.str();
197
198 int ierr = 0;
199
200 int me = comm->getRank();
201 int np = comm->getSize();
202 bool allOnThisProc = (me == np-1);
203
204 // Create a map with all data on a single proc
205 const size_t gNvtx = 25;
206 size_t nVtx;
207
208 if (allOnThisProc) nVtx = gNvtx;
209 else nVtx = 0;
210
211 Teuchos::RCP<const zmap_t> map = rcp(new zmap_t(gNvtx, nVtx, 0, comm));
212
213 // Create a Tpetra::Matrix with one component
214 size_t maxRowLen = 2;
215 Teuchos::RCP<zmatrix_t> matrix = rcp(new zmatrix_t(map, maxRowLen));
216 if (allOnThisProc) {
217 Teuchos::Array<zgno_t> col(2);
218 Teuchos::Array<zscalar_t> val(2); val[0] = 1.; val[1] = 1.;
219 for (size_t i = 0; i < nVtx; i++) {
220 zgno_t id = map->getGlobalElement(i);
221 col[0] = id;
222 col[1] = (id+1)%gNvtx;
223 matrix->insertGlobalValues(id, col(), val());
224 }
225 }
226 matrix->fillComplete(map, map);
227
228 // Create a Zoltan2 XpetraMatrixAdapter
229 matrixAdapter_t ia(matrix, 0);
230
231 // Call connected components utility
233 cc_t cc(ia, *comm);
234
235 // Check result:
236 if (allOnThisProc) {
237 // one component with all global vertices
238 size_t nccAnswer = 1;
239 size_t maxAnswer = gNvtx;
240 size_t minAnswer = gNvtx;
241 double avgAnswer = double(gNvtx);
242
243 ierr = checkResult<cc_t>(name, cc,
244 nccAnswer, maxAnswer, minAnswer, avgAnswer);
245 }
246 else {
247 // one component with all global vertices
248 size_t nccAnswer = 0;
249 size_t maxAnswer = 0;
250 size_t minAnswer = 0;
251 double avgAnswer = 0.;
252
253 ierr = checkResult<cc_t>(name, cc,
254 nccAnswer, maxAnswer, minAnswer, avgAnswer);
255 }
256
257 return ierr;
258}
259
261int test_no_graph(Teuchos::RCP<const Teuchos::Comm<int> > &comm)
262{
263 // Testing a graph with no edges
264 // Test using a MatrixAdapter.
265 // Test using an MPI communicator rather than Teuchos::Comm, if appropriate.
266
267 std::ostringstream namestream;
268 namestream << comm->getRank() << " no_graph ";
269 std::string name = namestream.str();
270
271 int ierr = 0;
272
273 // Create a default map
274 const size_t gNvtx = 25;
275
276 Teuchos::RCP<const zmap_t> map = rcp(new zmap_t(gNvtx, 0, comm));
277 size_t nVtx = map->getLocalNumElements();
278
279 // Create a Tpetra::Matrix with no edges
280 size_t maxRowLen = 1;
281 Teuchos::RCP<zmatrix_t> matrix = rcp(new zmatrix_t(map, maxRowLen));
282 matrix->fillComplete(map, map);
283
284 // Create a Zoltan2 XpetraMatrixAdapter
285 matrixAdapter_t ia(matrix, 0);
286
287#ifdef HAVE_ZOLTAN2_MPI
288 // For testing only, extract MPI communicator from Teuchos::Comm
289 // There's no need to do this in real life; use Teuchos::Comm if you have it.
290 // We just want to exercise the MPI_Comm interface here.
291 if (comm->getRank() == 0) std::cout << " using MPI_Comm " << std::endl;
292 MPI_Comm useThisComm = Teuchos::getRawMpiComm(*comm);
293#else
294 const Teuchos::Comm<int> &useThisComm = *comm;
295#endif
296
297 // Call connected components utility
299 cc_t cc(ia, useThisComm);
300
301 // Check result:
302 // With no edges, every vertex should be a component
303 size_t nccAnswer = nVtx;
304 size_t maxAnswer = size_t(nVtx > 0);
305 size_t minAnswer = size_t(nVtx > 0);
306 double avgAnswer = double(nVtx > 0);
307
308 ierr = checkResult<cc_t>(name, cc,
309 nccAnswer, maxAnswer, minAnswer, avgAnswer);
310
311 return ierr;
312}
313
315int main(int narg, char** arg)
316{
317 // Establish session.
318 Tpetra::ScopeGuard tscope(&narg, &arg);
319 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
320 int me = comm->getRank();
321
322 int testReturn = 0;
323 if (me == 0) std::cout << "test_one_proc..." << std::endl;
324 testReturn += test_one_proc(comm); // all data on a single proc
325 if (me == 0) std::cout << "test_no_graph..." << std::endl;
326 testReturn += test_no_graph(comm); // no edges in graph
327 if (me == 0) std::cout << "test_dist_component..." << std::endl;
328 testReturn += test_dist_component(comm); // one component per rank
329 if (me == 0) std::cout << "test_every_third..." << std::endl;
330 testReturn += test_every_third(comm); // every 3rd vtx in same component
331
332 int gtestReturn = 0;
333 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MAX, 1,
334 &testReturn, &gtestReturn);
335 if (me == 0) {
336 if (gtestReturn) std::cout << "FAIL" << std::endl;
337 else std::cout << "PASS" << std::endl;
338 }
339
340 return gtestReturn;
341}
common code used by tests
Tpetra::Map ::global_ordinal_type zgno_t
Defines XpetraCrsGraphAdapter class.
Defines the XpetraCrsMatrixAdapter class.
Identify and compute the number of connected components in a processor's input Note that this routine...
int main()
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
Zoltan2::XpetraCrsMatrixAdapter< zmatrix_t > matrixAdapter_t
Tpetra::Map< zlno_t, zgno_t > zmap_t
Tpetra::CrsGraph< zlno_t, zgno_t > zgraph_t
int test_dist_component(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
int test_one_proc(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
int test_every_third(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
int test_no_graph(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Zoltan2::XpetraCrsGraphAdapter< zgraph_t > graphAdapter_t
int checkResult(std::string &name, CC_T cc, size_t nccAnswer, size_t maxAnswer, size_t minAnswer, double avgAnswer)
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t > zmatrix_t