35 #include <Teuchos_Comm.hpp>
36 #include <Teuchos_DefaultComm.hpp>
37 #include <Teuchos_ArrayView.hpp>
43 using Teuchos::ArrayView;
47 typedef Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t, znode_t>
tcrsMatrix_t;
48 typedef Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>
tcrsGraph_t;
49 typedef Tpetra::Map<zlno_t, zgno_t, znode_t>
tmap_t;
63 template<
typename offset_t>
67 const RCP<
const Comm<int> > &comm)
69 int rank = comm->getRank();
70 int nprocs = comm->getSize();
73 for (
int p=0; p < nprocs; p++){
75 std::cout <<
"Rank " << p << std::endl;
76 for (
zlno_t i=0; i < nrows; i++){
77 std::cout <<
" Vtx " << i <<
": ";
79 for (offset_t j=idx[i]; j < idx[i+1]; j++)
80 std::cout << *elid++ <<
" ";
82 for (offset_t j=idx[i]; j < idx[i+1]; j++)
83 std::cout << *egid++ <<
" ";
84 std::cout << std::endl;
95 template <
typename MatrixOrGraph>
97 RCP<const MatrixOrGraph> &M,
98 size_t &numLocalDiags,
99 size_t &numGlobalDiags
107 RCP<const tcrsGraph_t> &M,
108 size_t &numLocalDiags,
109 size_t &numGlobalDiags
112 typedef typename tcrsGraph_t::global_ordinal_type
gno_t;
114 size_t maxnnz = M->getLocalMaxNumRowEntries();
115 typename tcrsGraph_t::nonconst_global_inds_host_view_type colGids(
"colGIds", maxnnz);
119 int nLocalRows = M->getLocalNumRows();
120 for (
int i = 0; i < nLocalRows; i++) {
122 gno_t rowGid = M->getRowMap()->getGlobalElement(i);
124 M->getGlobalRowCopy(rowGid, colGids, nnz);
126 for (
size_t j = 0; j < nnz; j++) {
127 if (rowGid == colGids[j]) {
133 Teuchos::reduceAll<int, size_t>(*(M->getComm()), Teuchos::REDUCE_SUM, 1,
134 &numLocalDiags, &numGlobalDiags);
139 RCP<const tcrsMatrix_t> &M,
140 size_t &numLocalDiags,
141 size_t &numGlobalDiags
144 RCP<const tcrsGraph_t> graph = M->getCrsGraph();
150 template <
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)
164 int rank = comm->getRank();
165 int nprocs = comm->getSize();
168 zlno_t nLocalRows = M->getLocalNumRows();
169 zlno_t nLocalNZ = M->getLocalNumEntries();
170 zgno_t nGlobalRows = M->getGlobalNumRows();
171 zgno_t nGlobalNZ = M->getGlobalNumEntries();
173 std::bitset<Zoltan2::NUM_MODEL_FLAGS> modelFlags;
174 if (consecutiveIdsRequested)
187 for (
int i=0; i < coordDim; i++){
189 for (
zlno_t j=0; j < nLocalRows; j++){
190 coords[i][j] = 100000*i + j;
195 if (nVtxWeights > 0){
196 rowWeights =
new zscalar_t * [nVtxWeights];
197 for (
int i=0; i < nVtxWeights; i++){
199 rowWeights[i] = NULL;
201 rowWeights[i] =
new zscalar_t [nLocalRows];
202 for (
zlno_t j=0; j < nLocalRows; j++){
203 rowWeights[i][j] = 200000*i + j;
209 if (nEdgeWeights > 0 && rank == 0){
210 std::cout <<
"TODO: STILL NEED TO TEST EDGE WEIGHTS!" << std::endl;
215 Adapter tmi(M, nVtxWeights);
217 for (
int i=0; i < nVtxWeights; i++){
219 tmi.setWeightIsDegree(i);
221 tmi.setWeights(rowWeights[i], 1, i);
229 gids =
new zgno_t[nLocalRows];
230 for (
zlno_t i = 0; i < nLocalRows; i++)
231 gids[i] = M->getRowMap()->getGlobalElement(i);
233 (coordDim > 1 ? coords[1] : NULL),
234 (coordDim > 2 ? coords[2] : NULL),
236 tmi.setCoordinateInput(via);
239 size_t numLocalDiags = 0;
240 size_t numGlobalDiags = 0;
241 if (removeSelfEdges) {
242 computeNumDiags<MatrixOrGraph>(M, numLocalDiags, numGlobalDiags);
245 const RCP<const tmap_t> rowMap = M->getRowMap();
246 const RCP<const tmap_t> colMap = M->getColMap();
250 int *numNbors =
new int [nLocalRows];
251 int *numLocalNbors =
new int [nLocalRows];
252 bool *haveDiag =
new bool [nLocalRows];
253 size_t totalLocalNbors = 0;
255 for (
zlno_t i=0; i < nLocalRows; i++){
256 numLocalNbors[i] = 0;
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);
263 for (std::size_t j=0; j < idx.size(); j++){
270 zgno_t gidVal = colMap->getGlobalElement(idx[j]);
271 if (rowMap->getLocalElement(gidVal) !=
272 Teuchos::OrdinalTraits<zlno_t>::invalid()) {
283 if (rank == 0) std::cout <<
" Creating GraphModel" << std::endl;
285 RCP<const BaseAdapter> baseTmi = rcp(dynamic_cast<BaseAdapter *>(&tmi),
false);
291 catch (std::exception &e){
292 std::cerr << rank <<
") " << e.what() << std::endl;
299 if (rank == 0) std::cout <<
" Checking counts" << std::endl;
303 if (buildLocalGraph) {
307 size_t num = (removeSelfEdges ? totalLocalNbors - numLocalDiags
319 size_t num = (removeSelfEdges ? nLocalNZ-numLocalDiags : nLocalNZ);
323 num = (removeSelfEdges ? (nGlobalNZ-numGlobalDiags) : nGlobalNZ);
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;
347 catch (std::exception &e){
348 std::cerr << rank <<
") Error " << e.what() << std::endl;
353 if (vertexGids.size() != nLocalRows) fail = 1;
356 if (buildLocalGraph) {
358 for (
zlno_t i = 0; i < nLocalRows; i++) {
359 if (vertexGids[i] != i) {
367 if (idsAreConsecutive){
368 zgno_t minLocalGID = rowMap->getMinGlobalIndex();
369 for (
zlno_t i=0; i < nLocalRows; i++){
370 if (vertexGids[i] != minLocalGID + i) {
377 if (consecutiveIdsRequested) {
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]
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]
410 if ((crds.size() != coordDim) || (wgts.size() != nVtxWeights)) fail = 1;
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){
423 for (
int i=0; !fail && i < nVtxWeights; i++){
425 for (
zlno_t j=0; j < nLocalRows; j++){
426 zscalar_t val = (buildLocalGraph ? numLocalNbors[j] : numNbors[j]);
427 if (removeSelfEdges && haveDiag[j])
429 if (wgts[i][j] != val){
436 for (
zlno_t j=0; j < nLocalRows; j++){
437 if (wgts[i][j] != 200000*i + j){
448 if (rank == 0) std::cout <<
" Checking edges" << std::endl;
450 if (!buildLocalGraph) {
451 ArrayView<const zgno_t> edgeGids;
452 ArrayView<const offset_t> offsets;
456 numEdges = model->
getEdgeList(edgeGids, offsets, wgts);
458 catch(std::exception &e){
459 std::cerr << rank <<
") Error " << e.what() << std::endl;
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];
471 size_t val = numNbors[i];
472 if (removeSelfEdges && haveDiag[i])
474 if (edgeListSize != val){
483 std::cout <<
"Printing graph now " << nGlobalRows << std::endl;
484 printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(), NULL,
485 edgeGids.getRawPtr(), offsets.getRawPtr(), comm);
489 std::cout <<
" " << nGlobalRows <<
" total rows" << std::endl;
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;
502 numLocalNeighbors= model->
getEdgeList(localEdges, localOffsets, wgts);
504 catch(std::exception &e){
505 std::cout << rank <<
") Error " << e.what() << std::endl;
506 std::cerr << rank <<
") Error " << e.what() << std::endl;
511 "getLocalEdgeList localOffsets.size", 1)
514 for (
zlno_t i=0; i < nLocalRows; i++){
515 offset_t edgeListSize = localOffsets[i+1] - localOffsets[i];
517 size_t val = numLocalNbors[i];
518 if (removeSelfEdges && haveDiag[i])
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
532 "getLocalEdgeList sum size", 1)
534 fail = ((removeSelfEdges ? totalLocalNbors-numLocalDiags
536 != numLocalNeighbors);
540 if (totalLocalNbors == 0){
542 std::cout <<
" Graph of local edges is empty" << std::endl;
545 printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(),
546 localEdges.getRawPtr(), NULL, localOffsets.getRawPtr(), comm);
551 if (rank == 0) std::cout <<
" Cleaning up" << std::endl;
556 delete [] numLocalNbors;
559 if (nVtxWeights > 0){
560 for (
int i=0; i < nVtxWeights; i++){
562 delete [] rowWeights[i];
564 delete [] rowWeights;
570 for (
int i=0; i < coordDim; i++){
578 if (rank==0) std::cout <<
" OK" << std::endl;
583 const RCP<
const Comm<int> > &comm,
584 int nVtxWeights,
int nnzWgtIdx,
int coordDim,
585 bool consecutiveIdsRequested,
bool removeSelfEdges,
bool buildLocalGraph)
587 int rank = comm->getRank();
590 std::cout << std::endl <<
"=======================" << std::endl;
591 if (fname.size() > 0)
592 std::cout << std::endl <<
"Test parameters: file name " << fname << std::endl;
594 std::cout << std::endl <<
"Test parameters: dimension ";
595 std::cout << xdim <<
"x" << ydim <<
"x" << zdim << std::endl;
598 std::cout <<
"Num Vertex Weights: " << nVtxWeights << std::endl;
600 std::cout <<
" Dimension " << nnzWgtIdx <<
" is number of neighbors" << std::endl;
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;
612 if (fname.size() > 0)
621 RCP<const tcrsMatrix_t> Mconsec = rcp_const_cast<
const tcrsMatrix_t>(M);
623 RCP<const Tpetra::CrsGraph<zlno_t, zgno_t> > graph = Mconsec->getCrsGraph();
629 std::cout <<
" TEST MatrixAdapter for graph having Consecutive IDs"
631 bool idsAreConsecutive =
true;
633 testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mconsec, graph, comm,
637 consecutiveIdsRequested,
642 std::cout <<
" TEST GraphAdapter for graph having Consecutive IDs"
644 testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
648 consecutiveIdsRequested,
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);
659 RCP<const tcrsMatrix_t> Mnonconsec = rcp_const_cast<
const tcrsMatrix_t>(
661 *Mconsec, myNewRows.size(), myNewRows.getRawPtr()));
663 graph = Mnonconsec->getCrsGraph();
669 std::cout <<
" TEST MatrixAdapter graph having Round-Robin IDs"
671 idsAreConsecutive =
false;
673 testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mnonconsec, graph, comm,
677 consecutiveIdsRequested,
682 std::cout <<
" TEST GraphAdapter graph having Round-Robin IDs"
684 testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
688 consecutiveIdsRequested,
696 int main(
int narg,
char *arg[])
698 Tpetra::ScopeGuard tscope(&narg, &arg);
699 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
701 int rank = comm->getRank();
706 bool consecutiveIdsRequested =
false;
707 bool removeSelfEdges =
false;
708 bool buildLocalGraph =
false;
709 string fname(
"simple");
712 std::cout <<
"TESTING base case (global)" << std::endl;
714 nVtxWeights, nnzWgtIdx, coordDim,
715 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
718 std::cout <<
"TESTING with row weights (global)" << std::endl;
721 nVtxWeights, nnzWgtIdx, coordDim,
722 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
725 std::cout <<
"TESTING with weights = nnz (global)" << std::endl;
728 nVtxWeights, nnzWgtIdx, coordDim,
729 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
732 std::cout <<
"TESTING with multiple row weights and coords (global)"
737 nVtxWeights, nnzWgtIdx, coordDim,
738 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
741 std::cout <<
"TESTING with consecutiveIdsRequested (global)" << std::endl;
742 consecutiveIdsRequested =
true;
744 nVtxWeights, nnzWgtIdx, coordDim,
745 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
748 std::cout <<
"TESTING with consecutiveIdsRequested and removeSelfEdges "
749 <<
"(global)" << std::endl;
750 removeSelfEdges =
true;
752 nVtxWeights, nnzWgtIdx, coordDim,
753 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
756 std::cout <<
"TESTING with removeSelfEdges (global)" << std::endl;
757 consecutiveIdsRequested =
false;
759 nVtxWeights, nnzWgtIdx, coordDim,
760 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
763 std::cout <<
"TESTING base case (local)" << std::endl;
764 buildLocalGraph =
true;
765 consecutiveIdsRequested =
false;
766 removeSelfEdges =
false;
768 nVtxWeights, nnzWgtIdx, coordDim,
769 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
772 std::cout <<
"TESTING with row weights (local)" << std::endl;
775 nVtxWeights, nnzWgtIdx, coordDim,
776 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
779 std::cout <<
"TESTING with weights = nnz (local)" << std::endl;
782 nVtxWeights, nnzWgtIdx, coordDim,
783 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
786 std::cout <<
"TESTING with multiple row weights and coords (local)"
791 nVtxWeights, nnzWgtIdx, coordDim,
792 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
795 std::cout <<
"TESTING with consecutiveIdsRequested (local)" << std::endl;
796 consecutiveIdsRequested =
true;
798 nVtxWeights, nnzWgtIdx, coordDim,
799 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
802 std::cout <<
"TESTING with consecutiveIdsRequested and removeSelfEdges"
805 removeSelfEdges =
true;
807 nVtxWeights, nnzWgtIdx, coordDim,
808 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
811 std::cout <<
"TESTING with removeSelfEdges (local)" << std::endl;
812 consecutiveIdsRequested =
false;
814 nVtxWeights, nnzWgtIdx, coordDim,
815 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
817 std::cout <<
"PASS" << std::endl;
size_t getLocalNumEdges() const
Returns the number of edges on this process. In global or subset graphs, includes off-process edges...
Zoltan2::GraphAdapter< tcrsGraph_t, simpleUser_t > baseGAdapter_t
size_t getVertexList(ArrayView< const gno_t > &Ids, ArrayView< input_t > &wgts) const
Sets pointers to this process' 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)
MatrixAdapter defines the adapter interface for matrices.
void computeNumDiags< tcrsMatrix_t >(RCP< const tcrsMatrix_t > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
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)
map_t::global_ordinal_type gno_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.
Zoltan2::BasicUserTypes< zscalar_t, zlno_t, zgno_t > simpleUser_t
int main(int narg, char **arg)
common code used by tests
size_t getGlobalNumVertices() const
Returns the global number vertices.
void computeNumDiags(RCP< const MatrixOrGraph > &M, size_t &numLocalDiags, size_t &numGlobalDiags)
Zoltan2::XpetraCrsGraphAdapter< tcrsGraph_t, simpleUser_t > xGAdapter_t
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)
algorithm requires no self edges
Defines the XpetraCrsMatrixAdapter class.
int getCoordinateDim() const
Returns the dimension (0 to 3) of vertex coordinates.
Zoltan2::BasicVectorAdapter< simpleUser_t > simpleVAdapter_t
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 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 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.
Zoltan2::MatrixAdapter< tcrsMatrix_t, simpleUser_t > baseMAdapter_t
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...
const int SMALL_NUMBER_OF_ROWS
Test of GraphModel interface.
size_t getLocalNumVertices() const
Returns the number vertices on this process.
Tpetra::Map::local_ordinal_type zlno_t
static const std::string fail
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Tpetra::Map< zlno_t, zgno_t, znode_t > tmap_t
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > tcrsGraph_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
Defines the BasicVectorAdapter class.
model represents graph within only one rank
Tpetra::Map::global_ordinal_type zgno_t
std::string testDataFilePath(".")