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