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