Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
GraphModel.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 //
11 // Testing of GraphModel built from Xpetra matrix input adapters.
12 //
13 
23 #include <Zoltan2_GraphModel.hpp>
27 #include <Zoltan2_TestHelpers.hpp>
28 #include <Zoltan2_InputTraits.hpp>
29 
30 #include <string>
31 #include <vector>
32 #include <iostream>
33 #include <bitset>
34 
35 #include <Teuchos_Comm.hpp>
36 #include <Teuchos_DefaultComm.hpp>
37 #include <Teuchos_ArrayView.hpp>
38 
39 const int SMALL_NUMBER_OF_ROWS = 5;
40 using Teuchos::RCP;
41 using Teuchos::rcp;
42 using Teuchos::Comm;
43 using Teuchos::ArrayView;
44 
46 
47 typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t, znode_t> tcrsMatrix_t;
48 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t> tcrsGraph_t;
49 typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tmap_t;
50 
52 
55 
58 
59 using std::string;
60 using std::vector;
61 
63 template<typename offset_t>
64 void printGraph(zlno_t nrows, const zgno_t *v,
65  const zgno_t *elid, const zgno_t *egid,
66  const offset_t *idx,
67  const RCP<const Comm<int> > &comm)
68 {
69  int rank = comm->getRank();
70  int nprocs = comm->getSize();
71  comm->barrier();
72 
73  for (int p=0; p < nprocs; p++){
74  if (p == rank){
75  std::cout << "Rank " << p << std::endl;
76  for (zlno_t i=0; i < nrows; i++){
77  std::cout << " Vtx " << i << ": ";
78  if (elid)
79  for (offset_t j=idx[i]; j < idx[i+1]; j++)
80  std::cout << *elid++ << " ";
81  else
82  for (offset_t j=idx[i]; j < idx[i+1]; j++)
83  std::cout << *egid++ << " ";
84  std::cout << std::endl;
85  }
86  std::cout.flush();
87  }
88  comm->barrier();
89  }
90  comm->barrier();
91 }
92 
94 
95 template <typename MatrixOrGraph>
97  RCP<const MatrixOrGraph> &M,
98  size_t &numLocalDiags,
99  size_t &numGlobalDiags
100 )
101 {
102  // See specializations below
103 }
104 
105 template <>
107  RCP<const tcrsGraph_t> &M,
108  size_t &numLocalDiags,
109  size_t &numGlobalDiags
110 )
111 {
112  typedef typename tcrsGraph_t::global_ordinal_type gno_t;
113 
114  size_t maxnnz = M->getLocalMaxNumRowEntries();
115  typename tcrsGraph_t::nonconst_global_inds_host_view_type colGids("colGIds", maxnnz);
116  numLocalDiags = 0;
117  numGlobalDiags = 0;
118 
119  int nLocalRows = M->getLocalNumRows();
120  for (int i = 0; i < nLocalRows; i++) {
121 
122  gno_t rowGid = M->getRowMap()->getGlobalElement(i);
123  size_t nnz;
124  M->getGlobalRowCopy(rowGid, colGids, nnz);
125 
126  for (size_t j = 0; j < nnz; j++) {
127  if (rowGid == colGids[j]) {
128  numLocalDiags++;
129  break;
130  }
131  }
132  }
133  Teuchos::reduceAll<int, size_t>(*(M->getComm()), Teuchos::REDUCE_SUM, 1,
134  &numLocalDiags, &numGlobalDiags);
135 }
136 
137 template <>
139  RCP<const tcrsMatrix_t> &M,
140  size_t &numLocalDiags,
141  size_t &numGlobalDiags
142 )
143 {
144  RCP<const tcrsGraph_t> graph = M->getCrsGraph();
145  computeNumDiags<tcrsGraph_t>(graph, numLocalDiags, numGlobalDiags);
146 }
147 
148 
150 template <typename BaseAdapter, typename Adapter, typename MatrixOrGraph>
152  RCP<const MatrixOrGraph> &M,
153  RCP<const Tpetra::CrsGraph<zlno_t, zgno_t> > &Mgraph,
154  const RCP<const Comm<int> > &comm,
155  bool idsAreConsecutive,
156  int nVtxWeights, int nEdgeWeights, int nnzWgtIdx, int coordDim,
157  bool consecutiveIdsRequested, bool removeSelfEdges, bool buildLocalGraph)
158 {
160  typedef typename
162 
163  int fail=0;
164  int rank = comm->getRank();
165  int nprocs = comm->getSize();
166  RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment(comm));
167 
168  zlno_t nLocalRows = M->getLocalNumRows();
169  zlno_t nLocalNZ = M->getLocalNumEntries();
170  zgno_t nGlobalRows = M->getGlobalNumRows();
171  zgno_t nGlobalNZ = M->getGlobalNumEntries();
172 
173  std::bitset<Zoltan2::NUM_MODEL_FLAGS> modelFlags;
174  if (consecutiveIdsRequested)
175  modelFlags.set(Zoltan2::GENERATE_CONSECUTIVE_IDS);
176  if (removeSelfEdges)
177  modelFlags.set(Zoltan2::REMOVE_SELF_EDGES);
178  if (buildLocalGraph)
179  modelFlags.set(Zoltan2::BUILD_LOCAL_GRAPH);
180 
181  // Set up some fake input
182  zscalar_t **coords=NULL;
183  zscalar_t **rowWeights=NULL;
184 
185  if (coordDim > 0){
186  coords = new zscalar_t * [coordDim];
187  for (int i=0; i < coordDim; i++){
188  coords[i] = new zscalar_t [nLocalRows];
189  for (zlno_t j=0; j < nLocalRows; j++){
190  coords[i][j] = 100000*i + j;
191  }
192  }
193  }
194 
195  if (nVtxWeights > 0){
196  rowWeights = new zscalar_t * [nVtxWeights];
197  for (int i=0; i < nVtxWeights; i++){
198  if (nnzWgtIdx == i)
199  rowWeights[i] = NULL;
200  else{
201  rowWeights[i] = new zscalar_t [nLocalRows];
202  for (zlno_t j=0; j < nLocalRows; j++){
203  rowWeights[i][j] = 200000*i + j;
204  }
205  }
206  }
207  }
208 
209  if (nEdgeWeights > 0 && rank == 0){
210  std::cout << "TODO: STILL NEED TO TEST EDGE WEIGHTS!" << std::endl;
211  }
212 
213  // Create a matrix or graph input adapter.
214 
215  Adapter tmi(M, nVtxWeights);
216 
217  for (int i=0; i < nVtxWeights; i++){
218  if (nnzWgtIdx == i)
219  tmi.setWeightIsDegree(i);
220  else
221  tmi.setWeights(rowWeights[i], 1, i);
222  }
223 
224  zgno_t *gids = NULL;
225 
226  simpleVAdapter_t *via = NULL;
227 
228  if (coordDim > 0) {
229  gids = new zgno_t[nLocalRows];
230  for (zlno_t i = 0; i < nLocalRows; i++)
231  gids[i] = M->getRowMap()->getGlobalElement(i);
232  via = new simpleVAdapter_t(nLocalRows, gids, coords[0],
233  (coordDim > 1 ? coords[1] : NULL),
234  (coordDim > 2 ? coords[2] : NULL),
235  1,1,1);
236  tmi.setCoordinateInput(via);
237  }
238 
239  size_t numLocalDiags = 0;
240  size_t numGlobalDiags = 0;
241  if (removeSelfEdges) {
242  computeNumDiags<MatrixOrGraph>(M, numLocalDiags, numGlobalDiags);
243  }
244 
245  const RCP<const tmap_t> rowMap = M->getRowMap();
246  const RCP<const tmap_t> colMap = M->getColMap();
247 
248  // How many neighbor vertices are not on my process.
249 
250  int *numNbors = new int [nLocalRows];
251  int *numLocalNbors = new int [nLocalRows];
252  bool *haveDiag = new bool [nLocalRows];
253  size_t totalLocalNbors = 0;
254 
255  for (zlno_t i=0; i < nLocalRows; i++){
256  numLocalNbors[i] = 0;
257  haveDiag[i] = false;
258 
259  typename Tpetra::CrsGraph<zlno_t, zgno_t>::local_inds_host_view_type idx;
260  Mgraph->getLocalRowView(i, idx);
261  numNbors[i] = idx.extent(0);
262 
263  for (std::size_t j=0; j < idx.size(); j++){
264  if (idx[j] == i){
265  haveDiag[i] = true;
266  numLocalNbors[i]++;
267  totalLocalNbors++;
268  }
269  else{
270  zgno_t gidVal = colMap->getGlobalElement(idx[j]);
271  if (rowMap->getLocalElement(gidVal) !=
272  Teuchos::OrdinalTraits<zlno_t>::invalid()) {
273  // nbor is local to this process
274  numLocalNbors[i]++;
275  totalLocalNbors++;
276  }
277  }
278  }
279  }
280 
281  // Create a GraphModel based on this input data.
282 
283  if (rank == 0) std::cout << " Creating GraphModel" << std::endl;
284  Zoltan2::GraphModel<BaseAdapter> *model = NULL;
285  RCP<const BaseAdapter> baseTmi = rcp(dynamic_cast<BaseAdapter *>(&tmi),false);
286 
287  try{
288  model = new Zoltan2::GraphModel<BaseAdapter>(baseTmi, env,
289  comm, modelFlags);
290  }
291  catch (std::exception &e){
292  std::cerr << rank << ") " << e.what() << std::endl;
293  fail = 1;
294  }
295  TEST_FAIL_AND_EXIT(*comm, !fail, "Creating graph model", 1)
296 
297  // Test the GraphModel interface
298 
299  if (rank == 0) std::cout << " Checking counts" << std::endl;
300  if (model->getLocalNumVertices() != size_t(nLocalRows)) fail = 1;
301  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalNumVertices", 1)
302 
303  if (buildLocalGraph) {
304  if (model->getLocalNumVertices() != size_t(nLocalRows)) fail = 1;
305  TEST_FAIL_AND_EXIT(*comm, !fail, "getGlobalNumVertices", 1)
306 
307  size_t num = (removeSelfEdges ? totalLocalNbors - numLocalDiags
308  : totalLocalNbors);
309  if (model->getLocalNumEdges() != num) fail = 1;
310  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalNumEdges", 1)
311 
312  if (model->getGlobalNumEdges() != num) fail = 1;
313  TEST_FAIL_AND_EXIT(*comm, !fail, "getGlobalNumEdges", 1)
314  }
315  else {
316  if (model->getGlobalNumVertices() != size_t(nGlobalRows)) fail = 1;
317  TEST_FAIL_AND_EXIT(*comm, !fail, "getGlobalNumVertices", 1)
318 
319  size_t num = (removeSelfEdges ? nLocalNZ-numLocalDiags : nLocalNZ);
320  if (model->getLocalNumEdges() != num) fail = 1;
321  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalNumEdges", 1)
322 
323  num = (removeSelfEdges ? (nGlobalNZ-numGlobalDiags) : nGlobalNZ);
324  if (model->getGlobalNumEdges() != num) fail = 1;
325  TEST_FAIL_AND_EXIT(*comm, !fail, "getGlobalNumEdges", 1)
326  }
327 
328  if (model->getNumWeightsPerVertex() != nVtxWeights) fail = 1;
329  TEST_FAIL_AND_EXIT(*comm, !fail, "getNumWeightsPerVertex", 1)
330 
331  if (model->getNumWeightsPerEdge() != 0) fail = 1;
332  TEST_FAIL_AND_EXIT(*comm, !fail, "getNumWeightsPerEdge", 1)
333 
334  if (model->getCoordinateDim() != coordDim) fail = 1;
335  TEST_FAIL_AND_EXIT(*comm, !fail, "getCoordinateDim", 1)
336 
337 
338  if (rank == 0) std::cout << " Checking vertices" << std::endl;
339  ArrayView<const zgno_t> vertexGids;
340  ArrayView<input_t> crds;
341  ArrayView<input_t> wgts;
342 
343  try{
344  model->getVertexList(vertexGids, wgts);
345  if (coordDim) model->getVertexCoords(crds);
346  }
347  catch (std::exception &e){
348  std::cerr << rank << ") Error " << e.what() << std::endl;
349  fail = 1;
350  }
351  TEST_FAIL_AND_EXIT(*comm, !fail, "getVertexList", 1)
352 
353  if (vertexGids.size() != nLocalRows) fail = 1;
354  TEST_FAIL_AND_EXIT(*comm, !fail, "getVertexList size", 1)
355 
356  if (buildLocalGraph) {
357  // For local graph, vertexGIDs are 0 to n-1, where n = nLocalRows
358  for (zlno_t i = 0; i < nLocalRows; i++) {
359  if (vertexGids[i] != i) {
360  fail = 1;
361  break;
362  }
363  }
364  }
365  else {
366  // We know model stores things in same order we gave it.
367  if (idsAreConsecutive){
368  zgno_t minLocalGID = rowMap->getMinGlobalIndex();
369  for (zlno_t i=0; i < nLocalRows; i++){
370  if (vertexGids[i] != minLocalGID + i) {
371  fail = 1;
372  break;
373  }
374  }
375  }
376  else{ // round robin ids
377  if (consecutiveIdsRequested) {
378  zgno_t myFirstRow;
379  zgno_t tnLocalRows = nLocalRows;
380  scan(*comm, Teuchos::REDUCE_SUM, 1, &tnLocalRows, &myFirstRow);
381  myFirstRow -= nLocalRows;
382  for (zlno_t i=0; i < nLocalRows; i++){
383  if (vertexGids[i] != myFirstRow+i){
384  std::cout << rank << " Row " << i << " of " << nLocalRows
385  << " myFirstRow+i " << myFirstRow+i
386  << " vertexGids " << vertexGids[i]
387  << std::endl;
388  fail = 1;
389  break;
390  }
391  }
392  }
393  else {
394  zgno_t myGid = rank;
395  for (zlno_t i=0; i < nLocalRows; i++, myGid += nprocs){
396  if (vertexGids[i] != myGid){
397  std::cout << rank << " Row " << i << " of " << nLocalRows
398  << " myGid " << myGid << " vertexGids " << vertexGids[i]
399  << std::endl;
400  fail = 1;
401  break;
402  }
403  }
404  }
405  }
406  }
407  TEST_FAIL_AND_EXIT(*comm, !fail, "vertex gids", 1)
408 
409 
410  if ((crds.size() != coordDim) || (wgts.size() != nVtxWeights)) fail = 1;
411  TEST_FAIL_AND_EXIT(*comm, !fail, "coord or weight array size", 1)
412 
413  for (int i=0; !fail && i < coordDim; i++){
414  for (zlno_t j=0; j < nLocalRows; j++){
415  if (crds[i][j] != 100000*i + j){
416  fail = 1;
417  break;
418  }
419  }
420  }
421  TEST_FAIL_AND_EXIT(*comm, !fail, "coord values", 1)
422 
423  for (int i=0; !fail && i < nVtxWeights; i++){
424  if (nnzWgtIdx == i){
425  for (zlno_t j=0; j < nLocalRows; j++){
426  zscalar_t val = (buildLocalGraph ? numLocalNbors[j] : numNbors[j]);
427  if (removeSelfEdges && haveDiag[j])
428  val -= 1;
429  if (wgts[i][j] != val){
430  fail = 1;
431  break;
432  }
433  }
434  }
435  else{
436  for (zlno_t j=0; j < nLocalRows; j++){
437  if (wgts[i][j] != 200000*i + j){
438  fail = 1;
439  break;
440  }
441  }
442  }
443  }
444 
445  TEST_FAIL_AND_EXIT(*comm, !fail, "row weight values", 1)
446 
447 
448  if (rank == 0) std::cout << " Checking edges" << std::endl;
449 
450  if (!buildLocalGraph) {
451  ArrayView<const zgno_t> edgeGids;
452  ArrayView<const offset_t> offsets;
453  size_t numEdges=0;
454 
455  try{
456  numEdges = model->getEdgeList(edgeGids, offsets, wgts);
457  }
458  catch(std::exception &e){
459  std::cerr << rank << ") Error " << e.what() << std::endl;
460  fail = 1;
461  }
462  TEST_FAIL_AND_EXIT(*comm, !fail, "getEdgeList", 1)
463 
464  TEST_FAIL_AND_EXIT(*comm, wgts.size() == 0, "edge weights present", 1)
465 
466  size_t num = 0;
467  for (typename ArrayView<const offset_t>::size_type i=0;
468  i < offsets.size()-1; i++){
469  offset_t edgeListSize = offsets[i+1] - offsets[i];
470  num += edgeListSize;
471  size_t val = numNbors[i];
472  if (removeSelfEdges && haveDiag[i])
473  val--;
474  if (edgeListSize != val){
475  fail = 1;
476  break;
477  }
478  }
479 
480  TEST_FAIL_AND_EXIT(*comm, numEdges==num, "getEdgeList size", 1)
481  if (nGlobalRows < SMALL_NUMBER_OF_ROWS){
482  if (rank == 0)
483  std::cout << "Printing graph now " << nGlobalRows << std::endl;
484  printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(), NULL,
485  edgeGids.getRawPtr(), offsets.getRawPtr(), comm);
486  }
487  else{
488  if (rank==0)
489  std::cout << " " << nGlobalRows << " total rows" << std::endl;
490  }
491  }
492 
493  else { // buildLocalGraph
494  // Get graph restricted to this process
495 
496  if (rank == 0) std::cout << " Checking local edges" << std::endl;
497  ArrayView<const zgno_t> localEdges;
498  ArrayView<const offset_t> localOffsets;
499  size_t numLocalNeighbors=0;
500 
501  try{
502  numLocalNeighbors= model->getEdgeList(localEdges, localOffsets, wgts);
503  }
504  catch(std::exception &e){
505  std::cout << rank << ") Error " << e.what() << std::endl;
506  std::cerr << rank << ") Error " << e.what() << std::endl;
507  fail = 1;
508  }
509  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalEdgeList", 1)
510  TEST_FAIL_AND_EXIT(*comm, ((localOffsets.size()-1) == nLocalRows),
511  "getLocalEdgeList localOffsets.size", 1)
512 
513  size_t num = 0;
514  for (zlno_t i=0; i < nLocalRows; i++){
515  offset_t edgeListSize = localOffsets[i+1] - localOffsets[i];
516  num += edgeListSize;
517  size_t val = numLocalNbors[i];
518  if (removeSelfEdges && haveDiag[i])
519  val--;
520  if (edgeListSize != val){
521  std::cout << rank << "vtx " << i << " of " << localOffsets.size()
522  << " Number of local edges in model " << edgeListSize
523  << " not equal to expected number of edges " << val
524  << std::endl;
525  fail = 1;
526  break;
527  }
528  }
529  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalEdgeList list sizes", 1)
530 
531  TEST_FAIL_AND_EXIT(*comm, numLocalNeighbors==num,
532  "getLocalEdgeList sum size", 1)
533 
534  fail = ((removeSelfEdges ? totalLocalNbors-numLocalDiags
535  : totalLocalNbors)
536  != numLocalNeighbors);
537  TEST_FAIL_AND_EXIT(*comm, !fail, "getLocalEdgeList total size", 1)
538 
539  if (nGlobalRows < SMALL_NUMBER_OF_ROWS){
540  if (totalLocalNbors == 0){
541  if (rank == 0)
542  std::cout << " Graph of local edges is empty" << std::endl;
543  }
544  else{
545  printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(),
546  localEdges.getRawPtr(), NULL, localOffsets.getRawPtr(), comm);
547  }
548  }
549  }
550 
551  if (rank == 0) std::cout << " Cleaning up" << std::endl;
552  delete model;
553 
554  if (nLocalRows){
555  delete [] numNbors;
556  delete [] numLocalNbors;
557  delete [] haveDiag;
558 
559  if (nVtxWeights > 0){
560  for (int i=0; i < nVtxWeights; i++){
561  if (rowWeights[i])
562  delete [] rowWeights[i];
563  }
564  delete [] rowWeights;
565  }
566 
567  if (coordDim > 0){
568  delete via;
569  delete [] gids;
570  for (int i=0; i < coordDim; i++){
571  if (coords[i])
572  delete [] coords[i];
573  }
574  delete [] coords;
575  }
576  }
577 
578  if (rank==0) std::cout << " OK" << std::endl;
579 }
580 
582 void testGraphModel(string fname, zgno_t xdim, zgno_t ydim, zgno_t zdim,
583  const RCP<const Comm<int> > &comm,
584  int nVtxWeights, int nnzWgtIdx, int coordDim,
585  bool consecutiveIdsRequested, bool removeSelfEdges, bool buildLocalGraph)
586 {
587  int rank = comm->getRank();
588 
589  if (rank==0){
590  std::cout << std::endl << "=======================" << std::endl;
591  if (fname.size() > 0)
592  std::cout << std::endl << "Test parameters: file name " << fname << std::endl;
593  else{
594  std::cout << std::endl << "Test parameters: dimension ";
595  std::cout << xdim << "x" << ydim << "x" << zdim << std::endl;
596  }
597 
598  std::cout << "Num Vertex Weights: " << nVtxWeights << std::endl;
599  if (nnzWgtIdx >= 0)
600  std::cout << " Dimension " << nnzWgtIdx << " is number of neighbors" << std::endl;
601 
602  std::cout << "Coordinate dim: " << coordDim << std::endl;
603  std::cout << "Request consecutive vertex gids: ";
604  std::cout << (consecutiveIdsRequested ? "yes" : "no") << std::endl;
605  std::cout << "Request to remove self edges: ";
606  std::cout << (removeSelfEdges ? "yes" : "no") << std::endl;
607  }
608 
609  // Input generator
610  UserInputForTests *uinput;
611 
612  if (fname.size() > 0)
613  uinput = new UserInputForTests(testDataFilePath, fname, comm, true);
614  else
615  uinput = new UserInputForTests(xdim,ydim,zdim,string(""), comm, true, true);
616 
617  RCP<tcrsMatrix_t> M = uinput->getUITpetraCrsMatrix();
618 
619  // Row Ids of test input are already consecutive
620 
621  RCP<const tcrsMatrix_t> Mconsec = rcp_const_cast<const tcrsMatrix_t>(M);
622 
623  RCP<const Tpetra::CrsGraph<zlno_t, zgno_t> > graph = Mconsec->getCrsGraph();
624 
625 // printTpetraGraph<zlno_t, zgno_t>(comm, *graph, std::cout, 100,
626 // "Graph having consecutive IDs");
627 
628  if (rank == 0)
629  std::cout << " TEST MatrixAdapter for graph having Consecutive IDs"
630  << std::endl;
631  bool idsAreConsecutive = true;
632 
633  testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mconsec, graph, comm,
634  idsAreConsecutive,
635  nVtxWeights, 0,
636  nnzWgtIdx, coordDim,
637  consecutiveIdsRequested,
638  removeSelfEdges,
639  buildLocalGraph);
640 
641  if (rank == 0)
642  std::cout << " TEST GraphAdapter for graph having Consecutive IDs"
643  << std::endl;
644  testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
645  idsAreConsecutive,
646  nVtxWeights, 1,
647  nnzWgtIdx, coordDim,
648  consecutiveIdsRequested,
649  removeSelfEdges,
650  buildLocalGraph);
651 
652  // Do a round robin migration so that global IDs are not consecutive.
653 
654  Array<zgno_t> myNewRows;
655  int nprocs = comm->getSize();
656  for (size_t i=rank; i < Mconsec->getGlobalNumRows(); i+=nprocs)
657  myNewRows.push_back(i);
658 
659  RCP<const tcrsMatrix_t> Mnonconsec = rcp_const_cast<const tcrsMatrix_t>(
661  *Mconsec, myNewRows.size(), myNewRows.getRawPtr()));
662 
663  graph = Mnonconsec->getCrsGraph();
664 
665 // printTpetraGraph<zlno_t, zgno_t>(comm, *graph, std::cout, 100,
666 // "Graph having non-consecutive (Round-Robin) IDs");
667 
668  if (rank == 0)
669  std::cout << " TEST MatrixAdapter graph having Round-Robin IDs"
670  << std::endl;
671  idsAreConsecutive = false;
672 
673  testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mnonconsec, graph, comm,
674  idsAreConsecutive,
675  nVtxWeights, 0,
676  nnzWgtIdx, coordDim,
677  consecutiveIdsRequested,
678  removeSelfEdges,
679  buildLocalGraph);
680 
681  if (rank == 0)
682  std::cout << " TEST GraphAdapter graph having Round-Robin IDs"
683  << std::endl;
684  testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
685  idsAreConsecutive,
686  nVtxWeights, 0,
687  nnzWgtIdx, coordDim,
688  consecutiveIdsRequested,
689  removeSelfEdges,
690  buildLocalGraph);
691 
692  delete uinput;
693 }
694 
696 int main(int narg, char *arg[])
697 {
698  Tpetra::ScopeGuard tscope(&narg, &arg);
699  Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
700 
701  int rank = comm->getRank();
702 
703  int nVtxWeights=0;
704  int nnzWgtIdx = -1;
705  int coordDim=0;
706  bool consecutiveIdsRequested = false;
707  bool removeSelfEdges = false;
708  bool buildLocalGraph = false;
709  string fname("simple");
710 
711  if (rank == 0)
712  std::cout << "TESTING base case (global)" << std::endl;
713  testGraphModel(fname, 0, 0, 0, comm,
714  nVtxWeights, nnzWgtIdx, coordDim,
715  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
716 
717  if (rank == 0)
718  std::cout << "TESTING with row weights (global)" << std::endl;
719  nVtxWeights = 1;
720  testGraphModel(fname, 0, 0, 0, comm,
721  nVtxWeights, nnzWgtIdx, coordDim,
722  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
723 
724  if (rank == 0)
725  std::cout << "TESTING with weights = nnz (global)" << std::endl;
726  nnzWgtIdx = 1;
727  testGraphModel(fname, 0, 0, 0, comm,
728  nVtxWeights, nnzWgtIdx, coordDim,
729  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
730 
731  if (rank == 0)
732  std::cout << "TESTING with multiple row weights and coords (global)"
733  << std::endl;
734  nVtxWeights = 2;
735  coordDim = 3;
736  testGraphModel(fname, 0, 0, 0, comm,
737  nVtxWeights, nnzWgtIdx, coordDim,
738  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
739 
740  if (rank == 0)
741  std::cout << "TESTING with consecutiveIdsRequested (global)" << std::endl;
742  consecutiveIdsRequested = true;
743  testGraphModel(fname, 0, 0, 0, comm,
744  nVtxWeights, nnzWgtIdx, coordDim,
745  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
746 
747  if (rank == 0)
748  std::cout << "TESTING with consecutiveIdsRequested and removeSelfEdges "
749  << "(global)" << std::endl;
750  removeSelfEdges = true;
751  testGraphModel(fname, 0, 0, 0, comm,
752  nVtxWeights, nnzWgtIdx, coordDim,
753  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
754 
755  if (rank == 0)
756  std::cout << "TESTING with removeSelfEdges (global)" << std::endl;
757  consecutiveIdsRequested = false;
758  testGraphModel(fname, 0, 0, 0, comm,
759  nVtxWeights, nnzWgtIdx, coordDim,
760  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
761 
762  if (rank == 0)
763  std::cout << "TESTING base case (local)" << std::endl;
764  buildLocalGraph = true;
765  consecutiveIdsRequested = false;
766  removeSelfEdges = false;
767  testGraphModel(fname, 0, 0, 0, comm,
768  nVtxWeights, nnzWgtIdx, coordDim,
769  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
770 
771  if (rank == 0)
772  std::cout << "TESTING with row weights (local)" << std::endl;
773  nVtxWeights = 1;
774  testGraphModel(fname, 0, 0, 0, comm,
775  nVtxWeights, nnzWgtIdx, coordDim,
776  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
777 
778  if (rank == 0)
779  std::cout << "TESTING with weights = nnz (local)" << std::endl;
780  nnzWgtIdx = 1;
781  testGraphModel(fname, 0, 0, 0, comm,
782  nVtxWeights, nnzWgtIdx, coordDim,
783  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
784 
785  if (rank == 0)
786  std::cout << "TESTING with multiple row weights and coords (local)"
787  << std::endl;
788  nVtxWeights = 2;
789  coordDim = 3;
790  testGraphModel(fname, 0, 0, 0, comm,
791  nVtxWeights, nnzWgtIdx, coordDim,
792  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
793 
794  if (rank == 0)
795  std::cout << "TESTING with consecutiveIdsRequested (local)" << std::endl;
796  consecutiveIdsRequested = true;
797  testGraphModel(fname, 0, 0, 0, comm,
798  nVtxWeights, nnzWgtIdx, coordDim,
799  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
800 
801  if (rank == 0)
802  std::cout << "TESTING with consecutiveIdsRequested and removeSelfEdges"
803  << "(local)"
804  << std::endl;
805  removeSelfEdges = true;
806  testGraphModel(fname, 0, 0, 0, comm,
807  nVtxWeights, nnzWgtIdx, coordDim,
808  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
809 
810  if (rank == 0)
811  std::cout << "TESTING with removeSelfEdges (local)" << std::endl;
812  consecutiveIdsRequested = false;
813  testGraphModel(fname, 0, 0, 0, comm,
814  nVtxWeights, nnzWgtIdx, coordDim,
815  consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
816  if (rank==0)
817  std::cout << "PASS" << std::endl;
818 
819  return 0;
820 }
821 
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges...
Zoltan2::GraphAdapter< tcrsGraph_t, simpleUser_t > baseGAdapter_t
Definition: GraphModel.cpp:54
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process&#39; vertex Ids and their weights.
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
void testAdapter(RCP< const MatrixOrGraph > &M, RCP< const Tpetra::CrsGraph< zlno_t, zgno_t > > &Mgraph, const RCP< const Comm< int > > &comm, bool idsAreConsecutive, int nVtxWeights, int nEdgeWeights, int nnzWgtIdx, int coordDim, bool consecutiveIdsRequested, bool removeSelfEdges, bool buildLocalGraph)
Definition: GraphModel.cpp:151
MatrixAdapter defines the adapter interface for matrices.
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()
void computeNumDiags< tcrsMatrix_t >(RCP< const tcrsMatrix_t > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:138
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
GraphAdapter defines the interface for graph-based user data.
algorithm requires consecutive ids
void computeNumDiags< tcrsGraph_t >(RCP< const tcrsGraph_t > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:106
default_offset_t offset_t
The data type to represent offsets.
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:27
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
static RCP< User > doMigration(const User &from, size_t numLocalRows, const gno_t *myNewRows)
Migrate the object Given a user object and a new row distribution, create and return a new user objec...
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > simpleUser_t
int main(int narg, char **arg)
Definition: coloring1.cpp:164
common code used by tests
size_t getGlobalNumVertices() const
Returns the global number vertices.
void printGraph(RCP< const Comm< int > > &comm, zlno_t nvtx, const zgno_t *vtxIds, const offset_t *offsets, const zgno_t *edgeIds)
void computeNumDiags(RCP< const MatrixOrGraph > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:96
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, simpleUser_t > xGAdapter_t
Definition: GraphModel.cpp:57
Defines XpetraCrsGraphAdapter class.
void testGraphModel(string fname, zgno_t xdim, zgno_t ydim, zgno_t zdim, const RCP< const Comm< int > > &comm, int nVtxWeights, int nnzWgtIdx, int coordDim, bool consecutiveIdsRequested, bool removeSelfEdges, bool buildLocalGraph)
Definition: GraphModel.cpp:582
list fname
Begin.
Definition: validXML.py:19
algorithm requires no self edges
Defines the XpetraCrsMatrixAdapter class.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
Zoltan2::BasicVectorAdapter< simpleUser_t > simpleVAdapter_t
size_t getVertexCoords(ArrayView< input_t > &xyz) const
Sets pointers to this process&#39; vertex coordinates, if available. Order of coordinate info matches tha...
size_t getEdgeList(ArrayView< const gno_t > &edgeIds, ArrayView< const offset_t > &offsets, ArrayView< input_t > &wgts) const
Sets pointers to this process&#39; edge (neighbor) global Ids, including off-process edges.
size_t getGlobalNumEdges() const
Returns the global number edges. For local graphs, the number of global edges is the number of local ...
The StridedData class manages lists of weights or coordinates.
Zoltan2::MatrixAdapter< tcrsMatrix_t, simpleUser_t > baseMAdapter_t
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
Traits for application input objects.
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
const int SMALL_NUMBER_OF_ROWS
Test of GraphModel interface.
Definition: GraphModel.cpp:39
size_t getLocalNumVertices() const
Returns the number vertices on this process.
Tpetra::Map::local_ordinal_type zlno_t
static const std::string fail
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Tpetra::Map< zlno_t, zgno_t, znode_t > tmap_t
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
GraphModel defines the interface required for graph models.
int getNumWeightsPerEdge() const
Returns the number (0 or greater) of weights per edge.
Defines the GraphModel interface.
Zoltan2::XpetraCrsMatrixAdapter< tcrsMatrix_t, simpleUser_t > xMAdapter_t
Definition: GraphModel.cpp:56
float zscalar_t
Defines the BasicVectorAdapter class.
model represents graph within only one rank
Tpetra::Map::global_ordinal_type zgno_t
std::string testDataFilePath(".")