Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 
13 #include <Zoltan2_TestHelpers.hpp>
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 
27 typedef Tpetra::Map<zlno_t, zgno_t> zmap_t;
28 typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t> zmatrix_t;
29 typedef Tpetra::CrsGraph<zlno_t, zgno_t> zgraph_t;
30 
33 
35 template <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 
79 int 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 
134 int 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 
189 int 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 
261 int 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 
315 int 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 }
Tpetra::CrsGraph< zlno_t, zgno_t > zgraph_t
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
Zoltan2::XpetraCrsMatrixAdapter< tMatrix_t, tMVector_t > matrixAdapter_t
int test_dist_component(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
int checkResult(std::string &name, CC_T cc, size_t nccAnswer, size_t maxAnswer, size_t minAnswer, double avgAnswer)
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Zoltan2::XpetraCrsGraphAdapter< zgraph_t > graphAdapter_t
int test_every_third(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
int main(int narg, char **arg)
Definition: coloring1.cpp:164
common code used by tests
int test_one_proc(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t > zmatrix_t
Defines XpetraCrsGraphAdapter class.
Defines the XpetraCrsMatrixAdapter class.
int test_no_graph(Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Identify and compute the number of connected components in a processor&#39;s input Note that this routine...
Tpetra::Map< zlno_t, zgno_t > zmap_t
Tpetra::Map::global_ordinal_type zgno_t