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