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 // ***********************************************************************
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 
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges...
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Definition: GraphModel.cpp:82
Zoltan2::GraphAdapter< tcrsGraph_t, simpleUser_t > baseGAdapter_t
Definition: GraphModel.cpp:89
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:187
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:174
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:141
default_offset_t offset_t
The data type to represent offsets.
int main(int narg, char *arg[])
double zscalar_t
#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.
int zlno_t
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:131
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, simpleUser_t > xGAdapter_t
Definition: GraphModel.cpp:92
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:617
algorithm requires no self edges
Defines the XpetraCrsMatrixAdapter class.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > simpleUser_t
Definition: GraphModel.cpp:80
size_t getVertexCoords(ArrayView< input_t > &xyz) const
Sets pointers to this process&#39; vertex coordinates, if available. Order of coordinate info matches tha...
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
Definition: GraphModel.cpp:83
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.
Zoltan2::BasicVectorAdapter< simpleUser_t > simpleVAdapter_t
Definition: GraphModel.cpp:86
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.
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:84
size_t getLocalNumVertices() const
Returns the number vertices on this process.
static const std::string fail
int zgno_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:91
Zoltan2::MatrixAdapter< tcrsMatrix_t, simpleUser_t > baseMAdapter_t
Definition: GraphModel.cpp:88
Defines the BasicVectorAdapter class.
model represents graph within only one rank
std::string testDataFilePath(".")