Zoltan2
Loading...
Searching...
No Matches
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
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
75using Teuchos::RCP;
76using Teuchos::rcp;
77using Teuchos::Comm;
78using Teuchos::ArrayView;
79
81
82typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t, znode_t> tcrsMatrix_t;
83typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t> tcrsGraph_t;
84typedef Tpetra::Map<zlno_t, zgno_t, znode_t> tmap_t;
85
87
90
93
94using std::string;
95using std::vector;
96
98template<typename offset_t>
99void 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
130template <typename MatrixOrGraph>
132 RCP<const MatrixOrGraph> &M,
133 size_t &numLocalDiags,
134 size_t &numGlobalDiags
135)
136{
137 // See specializations below
138}
139
140template <>
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->getLocalMaxNumRowEntries();
150 typename tcrsGraph_t::nonconst_global_inds_host_view_type colGids("colGIds", maxnnz);
151 numLocalDiags = 0;
152 numGlobalDiags = 0;
153
154 int nLocalRows = M->getLocalNumRows();
155 for (int i = 0; i < nLocalRows; i++) {
156
157 gno_t rowGid = M->getRowMap()->getGlobalElement(i);
158 size_t nnz;
159 M->getGlobalRowCopy(rowGid, colGids, nnz);
160
161 for (size_t j = 0; j < nnz; j++) {
162 if (rowGid == colGids[j]) {
163 numLocalDiags++;
164 break;
165 }
166 }
167 }
168 Teuchos::reduceAll<int, size_t>(*(M->getComm()), Teuchos::REDUCE_SUM, 1,
169 &numLocalDiags, &numGlobalDiags);
170}
171
172template <>
174 RCP<const tcrsMatrix_t> &M,
175 size_t &numLocalDiags,
176 size_t &numGlobalDiags
177)
178{
179 RCP<const tcrsGraph_t> graph = M->getCrsGraph();
180 computeNumDiags<tcrsGraph_t>(graph, numLocalDiags, numGlobalDiags);
181}
182
183
185template <typename BaseAdapter, typename Adapter, typename MatrixOrGraph>
187 RCP<const MatrixOrGraph> &M,
188 RCP<const Tpetra::CrsGraph<zlno_t, zgno_t> > &Mgraph,
189 const RCP<const Comm<int> > &comm,
190 bool idsAreConsecutive,
191 int nVtxWeights, int nEdgeWeights, int nnzWgtIdx, int coordDim,
192 bool consecutiveIdsRequested, bool removeSelfEdges, bool buildLocalGraph)
193{
195 typedef typename
197
198 int fail=0;
199 int rank = comm->getRank();
200 int nprocs = comm->getSize();
201 RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment(comm));
202
203 zlno_t nLocalRows = M->getLocalNumRows();
204 zlno_t nLocalNZ = M->getLocalNumEntries();
205 zgno_t nGlobalRows = M->getGlobalNumRows();
206 zgno_t nGlobalNZ = M->getGlobalNumEntries();
207
208 std::bitset<Zoltan2::NUM_MODEL_FLAGS> modelFlags;
209 if (consecutiveIdsRequested)
210 modelFlags.set(Zoltan2::GENERATE_CONSECUTIVE_IDS);
211 if (removeSelfEdges)
212 modelFlags.set(Zoltan2::REMOVE_SELF_EDGES);
213 if (buildLocalGraph)
214 modelFlags.set(Zoltan2::BUILD_LOCAL_GRAPH);
215
216 // Set up some fake input
217 zscalar_t **coords=NULL;
218 zscalar_t **rowWeights=NULL;
219
220 if (coordDim > 0){
221 coords = new zscalar_t * [coordDim];
222 for (int i=0; i < coordDim; i++){
223 coords[i] = new zscalar_t [nLocalRows];
224 for (zlno_t j=0; j < nLocalRows; j++){
225 coords[i][j] = 100000*i + j;
226 }
227 }
228 }
229
230 if (nVtxWeights > 0){
231 rowWeights = new zscalar_t * [nVtxWeights];
232 for (int i=0; i < nVtxWeights; i++){
233 if (nnzWgtIdx == i)
234 rowWeights[i] = NULL;
235 else{
236 rowWeights[i] = new zscalar_t [nLocalRows];
237 for (zlno_t j=0; j < nLocalRows; j++){
238 rowWeights[i][j] = 200000*i + j;
239 }
240 }
241 }
242 }
243
244 if (nEdgeWeights > 0 && rank == 0){
245 std::cout << "TODO: STILL NEED TO TEST EDGE WEIGHTS!" << std::endl;
246 }
247
248 // Create a matrix or graph input adapter.
249
250 Adapter tmi(M, nVtxWeights);
251
252 for (int i=0; i < nVtxWeights; i++){
253 if (nnzWgtIdx == i)
254 tmi.setWeightIsDegree(i);
255 else
256 tmi.setWeights(rowWeights[i], 1, i);
257 }
258
259 zgno_t *gids = NULL;
260
261 simpleVAdapter_t *via = NULL;
262
263 if (coordDim > 0) {
264 gids = new zgno_t[nLocalRows];
265 for (zlno_t i = 0; i < nLocalRows; i++)
266 gids[i] = M->getRowMap()->getGlobalElement(i);
267 via = new simpleVAdapter_t(nLocalRows, gids, coords[0],
268 (coordDim > 1 ? coords[1] : NULL),
269 (coordDim > 2 ? coords[2] : NULL),
270 1,1,1);
271 tmi.setCoordinateInput(via);
272 }
273
274 size_t numLocalDiags = 0;
275 size_t numGlobalDiags = 0;
276 if (removeSelfEdges) {
277 computeNumDiags<MatrixOrGraph>(M, numLocalDiags, numGlobalDiags);
278 }
279
280 const RCP<const tmap_t> rowMap = M->getRowMap();
281 const RCP<const tmap_t> colMap = M->getColMap();
282
283 // How many neighbor vertices are not on my process.
284
285 int *numNbors = new int [nLocalRows];
286 int *numLocalNbors = new int [nLocalRows];
287 bool *haveDiag = new bool [nLocalRows];
288 size_t totalLocalNbors = 0;
289
290 for (zlno_t i=0; i < nLocalRows; i++){
291 numLocalNbors[i] = 0;
292 haveDiag[i] = false;
293
294 typename Tpetra::CrsGraph<zlno_t, zgno_t>::local_inds_host_view_type idx;
295 Mgraph->getLocalRowView(i, idx);
296 numNbors[i] = idx.extent(0);
297
298 for (std::size_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;
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
617void 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
731int 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
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, simpleUser_t > xGAdapter_t
Definition: GraphModel.cpp:92
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Definition: GraphModel.cpp:82
Zoltan2::BasicVectorAdapter< simpleUser_t > simpleVAdapter_t
Definition: GraphModel.cpp:86
Zoltan2::MatrixAdapter< tcrsMatrix_t, simpleUser_t > baseMAdapter_t
Definition: GraphModel.cpp:88
Zoltan2::XpetraCrsMatrixAdapter< tcrsMatrix_t, simpleUser_t > xMAdapter_t
Definition: GraphModel.cpp:91
void computeNumDiags< tcrsMatrix_t >(RCP< const tcrsMatrix_t > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:173
void computeNumDiags(RCP< const MatrixOrGraph > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:131
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
const int SMALL_NUMBER_OF_ROWS
Test of GraphModel interface.
Definition: GraphModel.cpp:74
Zoltan2::GraphAdapter< tcrsGraph_t, simpleUser_t > baseGAdapter_t
Definition: GraphModel.cpp:89
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:186
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > simpleUser_t
Definition: GraphModel.cpp:80
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
Tpetra::Map< zlno_t, zgno_t, znode_t > tmap_t
Definition: GraphModel.cpp:84
void computeNumDiags< tcrsGraph_t >(RCP< const tcrsGraph_t > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Definition: GraphModel.cpp:141
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_t
Definition: GraphModel.cpp:83
Defines the BasicVectorAdapter class.
Defines the GraphModel interface.
Traits for application input objects.
common code used by tests
float zscalar_t
Tpetra::Map ::local_ordinal_type zlno_t
std::string testDataFilePath(".")
Tpetra::Map ::global_ordinal_type zgno_t
Defines XpetraCrsGraphAdapter class.
Defines the XpetraCrsMatrixAdapter class.
int main()
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()
A simple class that can be the User template argument for an InputAdapter.
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
GraphAdapter defines the interface for graph-based user data.
GraphModel defines the interface required for graph models.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
size_t getGlobalNumVertices() const
Returns the global number vertices.
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges.
int getNumWeightsPerVertex() const
Returns the number (0 or greater) of weights per vertex.
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.
size_t getVertexCoords(ArrayView< input_t > &xyz) const
Sets pointers to this process' vertex coordinates, if available. Order of coordinate info matches tha...
size_t getLocalNumVertices() const
Returns the number vertices on this process.
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' vertex Ids and their weights.
size_t getGlobalNumEdges() const
Returns the global number edges. For local graphs, the number of global edges is the number of local ...
int getNumWeightsPerEdge() const
Returns the number (0 or greater) of weights per edge.
MatrixAdapter defines the adapter interface for matrices.
The StridedData class manages lists of weights or coordinates.
Provides access for Zoltan2 to Xpetra::CrsGraph data.
Provides access for Zoltan2 to Xpetra::CrsMatrix data.
static const std::string fail
map_t::global_ordinal_type gno_t
Definition: mapRemotes.cpp:18
@ GENERATE_CONSECUTIVE_IDS
algorithm requires consecutive ids
@ REMOVE_SELF_EDGES
algorithm requires no self edges
@ BUILD_LOCAL_GRAPH
model represents graph within only one rank
default_offset_t offset_t
The data type to represent offsets.
Defines the traits required for Tpetra, Eptra and Xpetra objects.