70 #include <Teuchos_Comm.hpp>
71 #include <Teuchos_DefaultComm.hpp>
72 #include <Teuchos_ArrayView.hpp>
78 using Teuchos::ArrayView;
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;
98 template<
typename offset_t>
102 const RCP<
const Comm<int> > &comm)
104 int rank = comm->getRank();
105 int nprocs = comm->getSize();
108 for (
int p=0; p < nprocs; p++){
110 std::cout <<
"Rank " << p << std::endl;
111 for (
zlno_t i=0; i < nrows; i++){
112 std::cout <<
" Vtx " << i <<
": ";
114 for (offset_t j=idx[i]; j < idx[i+1]; j++)
115 std::cout << *elid++ <<
" ";
117 for (offset_t j=idx[i]; j < idx[i+1]; j++)
118 std::cout << *egid++ <<
" ";
119 std::cout << std::endl;
130 template <
typename MatrixOrGraph>
132 RCP<const MatrixOrGraph> &M,
133 size_t &numLocalDiags,
134 size_t &numGlobalDiags
142 RCP<const tcrsGraph_t> &M,
143 size_t &numLocalDiags,
144 size_t &numGlobalDiags
147 typedef typename tcrsGraph_t::global_ordinal_type gno_t;
149 size_t maxnnz = M->getNodeMaxNumRowEntries();
150 Teuchos::Array<gno_t> colGids(maxnnz);
155 int nLocalRows = M->getNodeNumRows();
156 for (
int i = 0; i < nLocalRows; i++) {
158 gno_t rowGid = M->getRowMap()->getGlobalElement(i);
160 M->getGlobalRowCopy(rowGid, colGids(), nnz);
162 for (
size_t j = 0; j < nnz; j++) {
163 if (rowGid == colGids[j]) {
169 Teuchos::reduceAll<int, size_t>(*(M->getComm()), Teuchos::REDUCE_SUM, 1,
170 &numLocalDiags, &numGlobalDiags);
175 RCP<const tcrsMatrix_t> &M,
176 size_t &numLocalDiags,
177 size_t &numGlobalDiags
180 RCP<const tcrsGraph_t> graph = M->getCrsGraph();
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)
200 int rank = comm->getRank();
201 int nprocs = comm->getSize();
204 zlno_t nLocalRows = M->getNodeNumRows();
205 zlno_t nLocalNZ = M->getNodeNumEntries();
206 zgno_t nGlobalRows = M->getGlobalNumRows();
207 zgno_t nGlobalNZ = M->getGlobalNumEntries();
209 std::bitset<Zoltan2::NUM_MODEL_FLAGS> modelFlags;
210 if (consecutiveIdsRequested)
223 for (
int i=0; i < coordDim; i++){
225 for (
zlno_t j=0; j < nLocalRows; j++){
226 coords[i][j] = 100000*i + j;
231 if (nVtxWeights > 0){
232 rowWeights =
new zscalar_t * [nVtxWeights];
233 for (
int i=0; i < nVtxWeights; i++){
235 rowWeights[i] = NULL;
237 rowWeights[i] =
new zscalar_t [nLocalRows];
238 for (
zlno_t j=0; j < nLocalRows; j++){
239 rowWeights[i][j] = 200000*i + j;
245 if (nEdgeWeights > 0){
246 printf(
"TODO: STILL NEED TO TEST EDGE WEIGHTS!\n");
251 Adapter tmi(M, nVtxWeights);
253 for (
int i=0; i < nVtxWeights; i++){
255 tmi.setWeightIsDegree(i);
257 tmi.setWeights(rowWeights[i], 1, i);
265 gids =
new zgno_t[nLocalRows];
266 for (
zlno_t i = 0; i < nLocalRows; i++)
267 gids[i] = M->getRowMap()->getGlobalElement(i);
269 (coordDim > 1 ? coords[1] : NULL),
270 (coordDim > 2 ? coords[2] : NULL),
272 tmi.setCoordinateInput(via);
275 size_t numLocalDiags = 0;
276 size_t numGlobalDiags = 0;
277 if (removeSelfEdges) {
278 computeNumDiags<MatrixOrGraph>(M, numLocalDiags, numGlobalDiags);
281 const RCP<const tmap_t> rowMap = M->getRowMap();
282 const RCP<const tmap_t> colMap = M->getColMap();
286 int *numNbors =
new int [nLocalRows];
287 int *numLocalNbors =
new int [nLocalRows];
288 bool *haveDiag =
new bool [nLocalRows];
289 size_t totalLocalNbors = 0;
291 for (
zlno_t i=0; i < nLocalRows; i++){
292 numLocalNbors[i] = 0;
294 ArrayView<const zlno_t> idx;
295 Mgraph->getLocalRowView(i, idx);
296 numNbors[i] = idx.size();
298 for (
zlno_t j=0; j < idx.size(); j++){
305 zgno_t gidVal = colMap->getGlobalElement(idx[j]);
306 if (rowMap->getLocalElement(gidVal) !=
307 Teuchos::OrdinalTraits<zlno_t>::invalid()) {
318 if (rank == 0) std::cout <<
" Creating GraphModel" << std::endl;
320 RCP<const BaseAdapter> baseTmi = rcp(dynamic_cast<BaseAdapter *>(&tmi),
false);
326 catch (std::exception &e){
327 std::cerr << rank <<
") " << e.what() << std::endl;
334 if (rank == 0) std::cout <<
" Checking counts" << std::endl;
338 if (buildLocalGraph) {
342 size_t num = (removeSelfEdges ? totalLocalNbors - numLocalDiags
354 size_t num = (removeSelfEdges ? nLocalNZ-numLocalDiags : nLocalNZ);
358 num = (removeSelfEdges ? (nGlobalNZ-numGlobalDiags) : nGlobalNZ);
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;
382 catch (std::exception &e){
383 std::cerr << rank <<
") Error " << e.what() << std::endl;
388 if (vertexGids.size() != nLocalRows)
fail = 1;
391 if (buildLocalGraph) {
393 for (
zlno_t i = 0; i < nLocalRows; i++) {
394 if (vertexGids[i] != i) {
402 if (idsAreConsecutive){
403 zgno_t minLocalGID = rowMap->getMinGlobalIndex();
404 for (
zlno_t i=0; i < nLocalRows; i++){
405 if (vertexGids[i] != minLocalGID + i) {
412 if (consecutiveIdsRequested) {
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]
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]
445 if ((crds.size() != coordDim) || (wgts.size() != nVtxWeights))
fail = 1;
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){
458 for (
int i=0; !
fail && i < nVtxWeights; i++){
460 for (
zlno_t j=0; j < nLocalRows; j++){
461 zscalar_t val = (buildLocalGraph ? numLocalNbors[j] : numNbors[j]);
462 if (removeSelfEdges && haveDiag[j])
464 if (wgts[i][j] != val){
471 for (
zlno_t j=0; j < nLocalRows; j++){
472 if (wgts[i][j] != 200000*i + j){
483 if (rank == 0) std::cout <<
" Checking edges" << std::endl;
485 if (!buildLocalGraph) {
486 ArrayView<const zgno_t> edgeGids;
487 ArrayView<const offset_t> offsets;
491 numEdges = model->
getEdgeList(edgeGids, offsets, wgts);
493 catch(std::exception &e){
494 std::cerr << rank <<
") Error " << e.what() << std::endl;
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];
506 size_t val = numNbors[i];
507 if (removeSelfEdges && haveDiag[i])
509 if (edgeListSize != val){
518 std::cout <<
"Printing graph now " << nGlobalRows << std::endl;
519 printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(), NULL,
520 edgeGids.getRawPtr(), offsets.getRawPtr(), comm);
524 std::cout <<
" " << nGlobalRows <<
" total rows" << std::endl;
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;
537 numLocalNeighbors= model->
getEdgeList(localEdges, localOffsets, wgts);
539 catch(std::exception &e){
540 std::cout << rank <<
") Error " << e.what() << std::endl;
541 std::cerr << rank <<
") Error " << e.what() << std::endl;
546 "getLocalEdgeList localOffsets.size", 1)
549 for (
zlno_t i=0; i < nLocalRows; i++){
550 offset_t edgeListSize = localOffsets[i+1] - localOffsets[i];
552 size_t val = numLocalNbors[i];
553 if (removeSelfEdges && haveDiag[i])
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
567 "getLocalEdgeList sum size", 1)
569 fail = ((removeSelfEdges ? totalLocalNbors-numLocalDiags
571 != numLocalNeighbors);
575 if (totalLocalNbors == 0){
577 std::cout <<
" Graph of local edges is empty" << std::endl;
580 printGraph<offset_t>(nLocalRows, vertexGids.getRawPtr(),
581 localEdges.getRawPtr(), NULL, localOffsets.getRawPtr(), comm);
586 if (rank == 0) std::cout <<
" Cleaning up" << std::endl;
591 delete [] numLocalNbors;
594 if (nVtxWeights > 0){
595 for (
int i=0; i < nVtxWeights; i++){
597 delete [] rowWeights[i];
599 delete [] rowWeights;
605 for (
int i=0; i < coordDim; i++){
613 if (rank==0) std::cout <<
" OK" << std::endl;
618 const RCP<
const Comm<int> > &comm,
619 int nVtxWeights,
int nnzWgtIdx,
int coordDim,
620 bool consecutiveIdsRequested,
bool removeSelfEdges,
bool buildLocalGraph)
622 int rank = comm->getRank();
625 std::cout << std::endl <<
"=======================" << std::endl;
626 if (fname.size() > 0)
627 std::cout << std::endl <<
"Test parameters: file name " << fname << std::endl;
629 std::cout << std::endl <<
"Test parameters: dimension ";
630 std::cout << xdim <<
"x" << ydim <<
"x" << zdim << std::endl;
633 std::cout <<
"Num Vertex Weights: " << nVtxWeights << std::endl;
635 std::cout <<
" Dimension " << nnzWgtIdx <<
" is number of neighbors" << std::endl;
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;
647 if (fname.size() > 0)
656 RCP<const tcrsMatrix_t> Mconsec = rcp_const_cast<const tcrsMatrix_t>(M);
658 RCP<const Tpetra::CrsGraph<zlno_t, zgno_t> > graph = Mconsec->getCrsGraph();
664 std::cout <<
" TEST MatrixAdapter for graph having Consecutive IDs"
666 bool idsAreConsecutive =
true;
668 testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mconsec, graph, comm,
672 consecutiveIdsRequested,
677 std::cout <<
" TEST GraphAdapter for graph having Consecutive IDs"
679 testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
683 consecutiveIdsRequested,
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);
694 RCP<const tcrsMatrix_t> Mnonconsec = rcp_const_cast<const tcrsMatrix_t>(
696 *Mconsec, myNewRows.size(), myNewRows.getRawPtr()));
698 graph = Mnonconsec->getCrsGraph();
704 std::cout <<
" TEST MatrixAdapter graph having Round-Robin IDs"
706 idsAreConsecutive =
false;
708 testAdapter<baseMAdapter_t,xMAdapter_t,tcrsMatrix_t>(Mnonconsec, graph, comm,
712 consecutiveIdsRequested,
717 std::cout <<
" TEST GraphAdapter graph having Round-Robin IDs"
719 testAdapter<baseGAdapter_t,xGAdapter_t,tcrsGraph_t>(graph, graph, comm,
723 consecutiveIdsRequested,
731 int main(
int narg,
char *arg[])
733 Tpetra::ScopeGuard tscope(&narg, &arg);
734 Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
736 int rank = comm->getRank();
741 bool consecutiveIdsRequested =
false;
742 bool removeSelfEdges =
false;
743 bool buildLocalGraph =
false;
744 string fname(
"simple");
747 std::cout <<
"TESTING base case (global)" << std::endl;
749 nVtxWeights, nnzWgtIdx, coordDim,
750 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
753 std::cout <<
"TESTING with row weights (global)" << std::endl;
756 nVtxWeights, nnzWgtIdx, coordDim,
757 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
760 std::cout <<
"TESTING with weights = nnz (global)" << std::endl;
763 nVtxWeights, nnzWgtIdx, coordDim,
764 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
767 std::cout <<
"TESTING with multiple row weights and coords (global)"
772 nVtxWeights, nnzWgtIdx, coordDim,
773 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
776 std::cout <<
"TESTING with consecutiveIdsRequested (global)" << std::endl;
777 consecutiveIdsRequested =
true;
779 nVtxWeights, nnzWgtIdx, coordDim,
780 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
783 std::cout <<
"TESTING with consecutiveIdsRequested and removeSelfEdges "
784 <<
"(global)" << std::endl;
785 removeSelfEdges =
true;
787 nVtxWeights, nnzWgtIdx, coordDim,
788 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
791 std::cout <<
"TESTING with removeSelfEdges (global)" << std::endl;
792 consecutiveIdsRequested =
false;
794 nVtxWeights, nnzWgtIdx, coordDim,
795 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
798 std::cout <<
"TESTING base case (local)" << std::endl;
799 buildLocalGraph =
true;
800 consecutiveIdsRequested =
false;
801 removeSelfEdges =
false;
803 nVtxWeights, nnzWgtIdx, coordDim,
804 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
807 std::cout <<
"TESTING with row weights (local)" << std::endl;
810 nVtxWeights, nnzWgtIdx, coordDim,
811 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
814 std::cout <<
"TESTING with weights = nnz (local)" << std::endl;
817 nVtxWeights, nnzWgtIdx, coordDim,
818 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
821 std::cout <<
"TESTING with multiple row weights and coords (local)"
826 nVtxWeights, nnzWgtIdx, coordDim,
827 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
830 std::cout <<
"TESTING with consecutiveIdsRequested (local)" << std::endl;
831 consecutiveIdsRequested =
true;
833 nVtxWeights, nnzWgtIdx, coordDim,
834 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
837 std::cout <<
"TESTING with consecutiveIdsRequested and removeSelfEdges"
840 removeSelfEdges =
true;
842 nVtxWeights, nnzWgtIdx, coordDim,
843 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
846 std::cout <<
"TESTING with removeSelfEdges (local)" << std::endl;
847 consecutiveIdsRequested =
false;
849 nVtxWeights, nnzWgtIdx, coordDim,
850 consecutiveIdsRequested, removeSelfEdges, buildLocalGraph);
852 std::cout <<
"PASS" << std::endl;