10 #ifndef __MatrixMarket_Tpetra_hpp
11 #define __MatrixMarket_Tpetra_hpp
25 #include "Tpetra_CrsMatrix.hpp"
26 #include "Tpetra_Operator.hpp"
27 #include "Tpetra_Vector.hpp"
29 #include "Teuchos_MatrixMarket_Raw_Adder.hpp"
30 #include "Teuchos_MatrixMarket_Raw_Graph_Adder.hpp"
31 #include "Teuchos_MatrixMarket_SymmetrizingAdder.hpp"
32 #include "Teuchos_MatrixMarket_SymmetrizingGraphAdder.hpp"
33 #include "Teuchos_MatrixMarket_assignScalar.hpp"
34 #include "Teuchos_MatrixMarket_Banner.hpp"
35 #include "Teuchos_MatrixMarket_CoordDataReader.hpp"
36 #include "Teuchos_SetScientific.hpp"
37 #include "Teuchos_TimeMonitor.hpp"
40 #include "mmio_Tpetra.h"
42 #include "Tpetra_Distribution.hpp"
82 namespace MatrixMarket {
138 template <
class SparseMatrixType>
143 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
158 typedef typename SparseMatrixType::global_ordinal_type
194 typedef Teuchos::ArrayRCP<int>::size_type size_type;
206 static Teuchos::RCP<const map_type>
210 return rcp(
new map_type(static_cast<global_size_t>(numRows),
211 static_cast<global_ordinal_type>(0),
212 pComm, GloballyDistributed));
242 static Teuchos::RCP<const map_type>
243 makeRowMap(
const Teuchos::RCP<const map_type>& pRowMap,
248 if (pRowMap.is_null()) {
249 return rcp(
new map_type(static_cast<global_size_t>(numRows),
250 static_cast<global_ordinal_type>(0),
251 pComm, GloballyDistributed));
253 TEUCHOS_TEST_FOR_EXCEPTION(!pRowMap->isDistributed() && pComm->getSize() > 1,
254 std::invalid_argument,
255 "The specified row map is not distributed, "
256 "but the given communicator includes more than one process (in "
258 << pComm->getSize() <<
" processes).");
259 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap->getComm() != pComm, std::invalid_argument,
260 "The specified row Map's communicator (pRowMap->getComm()) "
261 "differs from the given separately supplied communicator pComm.");
280 static Teuchos::RCP<const map_type>
281 makeDomainMap(
const Teuchos::RCP<const map_type>& pRangeMap,
289 if (numRows == numCols) {
292 return createUniformContigMapWithNode<LO, GO, NT>(numCols,
293 pRangeMap->getComm());
370 distribute(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
371 Teuchos::ArrayRCP<size_t>& myRowPtr,
372 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
373 Teuchos::ArrayRCP<scalar_type>& myValues,
374 const Teuchos::RCP<const map_type>& pRowMap,
375 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
376 Teuchos::ArrayRCP<size_t>& rowPtr,
377 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
378 Teuchos::ArrayRCP<scalar_type>& values,
379 const bool debug =
false) {
383 using Teuchos::ArrayRCP;
384 using Teuchos::ArrayView;
387 using Teuchos::CommRequest;
390 using Teuchos::receive;
393 const bool extraDebug =
false;
395 const int numProcs = pComm->getSize();
396 const int myRank = pComm->getRank();
397 const int rootRank = 0;
404 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
405 const size_type myNumRows = myRows.size();
406 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<size_t>(myNumRows) !=
407 pRowMap->getLocalNumElements(),
409 "pRowMap->getLocalElementList().size() = "
411 <<
" != pRowMap->getLocalNumElements() = "
412 << pRowMap->getLocalNumElements() <<
". "
413 "Please report this bug to the Tpetra developers.");
414 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
416 "On Proc 0: numEntriesPerRow.size() = "
417 << numEntriesPerRow.size()
418 <<
" != pRowMap->getLocalElementList().size() = "
419 << myNumRows <<
". Please report this bug to the "
420 "Tpetra developers.");
424 myNumEntriesPerRow = arcp<size_t>(myNumRows);
426 if (myRank != rootRank) {
430 send(*pComm, myNumRows, rootRank);
431 if (myNumRows != 0) {
435 send(*pComm, static_cast<int>(myNumRows),
436 myRows.getRawPtr(), rootRank);
446 receive(*pComm, rootRank,
447 static_cast<int>(myNumRows),
448 myNumEntriesPerRow.getRawPtr());
453 std::accumulate(myNumEntriesPerRow.begin(),
454 myNumEntriesPerRow.end(), 0);
460 myColInd = arcp<GO>(myNumEntries);
461 myValues = arcp<scalar_type>(myNumEntries);
462 if (myNumEntries > 0) {
465 receive(*pComm, rootRank,
466 static_cast<int>(myNumEntries),
467 myColInd.getRawPtr());
468 receive(*pComm, rootRank,
469 static_cast<int>(myNumEntries),
470 myValues.getRawPtr());
476 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
480 for (size_type k = 0; k < myNumRows; ++k) {
481 const GO myCurRow = myRows[k];
483 myNumEntriesPerRow[k] = numEntriesInThisRow;
485 if (extraDebug && debug) {
486 cerr <<
"Proc " << pRowMap->getComm()->getRank()
487 <<
": myNumEntriesPerRow[0.." << (myNumRows - 1) <<
"] = [";
488 for (size_type k = 0; k < myNumRows; ++k) {
489 cerr << myNumEntriesPerRow[k];
490 if (k < myNumRows - 1) {
498 std::accumulate(myNumEntriesPerRow.begin(),
499 myNumEntriesPerRow.end(), 0);
501 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
502 << myNumEntries <<
" entries" << endl;
504 myColInd = arcp<GO>(myNumEntries);
505 myValues = arcp<scalar_type>(myNumEntries);
513 for (size_type k = 0; k < myNumRows;
514 myCurPos += myNumEntriesPerRow[k], ++k) {
516 const GO myRow = myRows[k];
517 const size_t curPos = rowPtr[myRow];
520 if (curNumEntries > 0) {
521 ArrayView<GO> colIndView = colInd(curPos, curNumEntries);
522 ArrayView<GO> myColIndView = myColInd(myCurPos, curNumEntries);
523 std::copy(colIndView.begin(), colIndView.end(),
524 myColIndView.begin());
526 ArrayView<scalar_type> valuesView =
527 values(curPos, curNumEntries);
528 ArrayView<scalar_type> myValuesView =
529 myValues(myCurPos, curNumEntries);
530 std::copy(valuesView.begin(), valuesView.end(),
531 myValuesView.begin());
536 for (
int p = 1; p < numProcs; ++p) {
538 cerr <<
"-- Proc 0: Processing proc " << p << endl;
541 size_type theirNumRows = 0;
546 receive(*pComm, p, &theirNumRows);
548 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
549 << theirNumRows <<
" rows" << endl;
551 if (theirNumRows != 0) {
556 ArrayRCP<GO> theirRows = arcp<GO>(theirNumRows);
557 receive(*pComm, p, as<int>(theirNumRows),
558 theirRows.getRawPtr());
567 const global_size_t numRows = pRowMap->getGlobalNumElements();
568 const GO indexBase = pRowMap->getIndexBase();
569 bool theirRowsValid =
true;
570 for (size_type k = 0; k < theirNumRows; ++k) {
571 if (theirRows[k] < indexBase ||
572 as<global_size_t>(theirRows[k] - indexBase) >= numRows) {
573 theirRowsValid =
false;
576 if (!theirRowsValid) {
577 TEUCHOS_TEST_FOR_EXCEPTION(
578 !theirRowsValid, std::logic_error,
579 "Proc " << p <<
" has at least one invalid row index. "
580 "Here are all of them: "
581 << Teuchos::toString(theirRows()) <<
". Valid row index "
582 "range (zero-based): [0, "
583 << (numRows - 1) <<
"].");
598 ArrayRCP<size_t> theirNumEntriesPerRow;
599 theirNumEntriesPerRow = arcp<size_t>(theirNumRows);
600 for (size_type k = 0; k < theirNumRows; ++k) {
601 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
608 send(*pComm, static_cast<int>(theirNumRows),
609 theirNumEntriesPerRow.getRawPtr(), p);
613 std::accumulate(theirNumEntriesPerRow.begin(),
614 theirNumEntriesPerRow.end(), 0);
617 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
618 << theirNumEntries <<
" entries" << endl;
623 if (theirNumEntries == 0) {
632 ArrayRCP<GO> theirColInd(theirNumEntries);
633 ArrayRCP<scalar_type> theirValues(theirNumEntries);
641 for (size_type k = 0; k < theirNumRows;
642 theirCurPos += theirNumEntriesPerRow[k], k++) {
644 const GO theirRow = theirRows[k];
650 if (curNumEntries > 0) {
651 ArrayView<GO> colIndView =
652 colInd(curPos, curNumEntries);
653 ArrayView<GO> theirColIndView =
654 theirColInd(theirCurPos, curNumEntries);
655 std::copy(colIndView.begin(), colIndView.end(),
656 theirColIndView.begin());
658 ArrayView<scalar_type> valuesView =
659 values(curPos, curNumEntries);
660 ArrayView<scalar_type> theirValuesView =
661 theirValues(theirCurPos, curNumEntries);
662 std::copy(valuesView.begin(), valuesView.end(),
663 theirValuesView.begin());
670 send(*pComm, static_cast<int>(theirNumEntries),
671 theirColInd.getRawPtr(), p);
672 send(*pComm, static_cast<int>(theirNumEntries),
673 theirValues.getRawPtr(), p);
676 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
684 numEntriesPerRow = null;
689 if (debug && myRank == 0) {
690 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
698 myRowPtr = arcp<size_t>(myNumRows + 1);
700 for (size_type k = 1; k < myNumRows + 1; ++k) {
701 myRowPtr[k] = myRowPtr[k - 1] + myNumEntriesPerRow[k - 1];
703 if (extraDebug && debug) {
704 cerr <<
"Proc " << Teuchos::rank(*(pRowMap->getComm()))
705 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
706 for (size_type k = 0; k < myNumRows + 1; ++k) {
716 if (debug && myRank == 0) {
717 cerr <<
"-- Proc 0: Done with distribute" << endl;
734 static Teuchos::RCP<sparse_matrix_type>
735 makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
736 Teuchos::ArrayRCP<size_t>& myRowPtr,
737 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
738 Teuchos::ArrayRCP<scalar_type>& myValues,
739 const Teuchos::RCP<const map_type>& pRowMap,
740 const Teuchos::RCP<const map_type>& pRangeMap,
741 const Teuchos::RCP<const map_type>& pDomainMap,
742 const bool callFillComplete =
true) {
745 using Teuchos::ArrayView;
757 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
758 "makeMatrix: myRowPtr array is null. "
759 "Please report this bug to the Tpetra developers.");
760 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
761 "makeMatrix: domain map is null. "
762 "Please report this bug to the Tpetra developers.");
763 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
764 "makeMatrix: range map is null. "
765 "Please report this bug to the Tpetra developers.");
766 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
767 "makeMatrix: row map is null. "
768 "Please report this bug to the Tpetra developers.");
772 RCP<sparse_matrix_type> A =
777 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
778 const size_type myNumRows = myRows.size();
781 const GO indexBase = pRowMap->getIndexBase();
782 for (size_type i = 0; i < myNumRows; ++i) {
783 const size_type myCurPos = myRowPtr[i];
785 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
786 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
789 for (size_type k = 0; k < curNumEntries; ++k) {
790 curColInd[k] += indexBase;
793 if (curNumEntries > 0) {
794 A->insertGlobalValues(myRows[i], curColInd, curValues);
801 myNumEntriesPerRow = null;
806 if (callFillComplete) {
807 A->fillComplete(pDomainMap, pRangeMap);
817 static Teuchos::RCP<sparse_matrix_type>
818 makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
819 Teuchos::ArrayRCP<size_t>& myRowPtr,
820 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
821 Teuchos::ArrayRCP<scalar_type>& myValues,
822 const Teuchos::RCP<const map_type>& pRowMap,
823 const Teuchos::RCP<const map_type>& pRangeMap,
824 const Teuchos::RCP<const map_type>& pDomainMap,
825 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
826 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams) {
829 using Teuchos::ArrayView;
841 TEUCHOS_TEST_FOR_EXCEPTION(
842 myRowPtr.is_null(), std::logic_error,
843 "makeMatrix: myRowPtr array is null. "
844 "Please report this bug to the Tpetra developers.");
845 TEUCHOS_TEST_FOR_EXCEPTION(
846 pDomainMap.is_null(), std::logic_error,
847 "makeMatrix: domain map is null. "
848 "Please report this bug to the Tpetra developers.");
849 TEUCHOS_TEST_FOR_EXCEPTION(
850 pRangeMap.is_null(), std::logic_error,
851 "makeMatrix: range map is null. "
852 "Please report this bug to the Tpetra developers.");
853 TEUCHOS_TEST_FOR_EXCEPTION(
854 pRowMap.is_null(), std::logic_error,
855 "makeMatrix: row map is null. "
856 "Please report this bug to the Tpetra developers.");
860 RCP<sparse_matrix_type> A =
866 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
867 const size_type myNumRows = myRows.size();
870 const GO indexBase = pRowMap->getIndexBase();
871 for (size_type i = 0; i < myNumRows; ++i) {
872 const size_type myCurPos = myRowPtr[i];
874 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
875 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
878 for (size_type k = 0; k < curNumEntries; ++k) {
879 curColInd[k] += indexBase;
881 if (curNumEntries > 0) {
882 A->insertGlobalValues(myRows[i], curColInd, curValues);
889 myNumEntriesPerRow = null;
894 A->fillComplete(pDomainMap, pRangeMap, fillCompleteParams);
902 static Teuchos::RCP<sparse_matrix_type>
903 makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
904 Teuchos::ArrayRCP<size_t>& myRowPtr,
905 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
906 Teuchos::ArrayRCP<scalar_type>& myValues,
907 const Teuchos::RCP<const map_type>& rowMap,
908 Teuchos::RCP<const map_type>& colMap,
909 const Teuchos::RCP<const map_type>& domainMap,
910 const Teuchos::RCP<const map_type>& rangeMap,
911 const bool callFillComplete =
true) {
912 using Teuchos::ArrayView;
921 RCP<sparse_matrix_type> A;
922 if (colMap.is_null()) {
930 ArrayView<const GO> myRows = rowMap->getLocalElementList();
931 const size_type myNumRows = myRows.size();
934 const GO indexBase = rowMap->getIndexBase();
935 for (size_type i = 0; i < myNumRows; ++i) {
936 const size_type myCurPos = myRowPtr[i];
937 const size_type curNumEntries = as<size_type>(myNumEntriesPerRow[i]);
938 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
939 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
942 for (size_type k = 0; k < curNumEntries; ++k) {
943 curColInd[k] += indexBase;
945 if (curNumEntries > 0) {
946 A->insertGlobalValues(myRows[i], curColInd, curValues);
953 myNumEntriesPerRow = null;
958 if (callFillComplete) {
959 A->fillComplete(domainMap, rangeMap);
960 if (colMap.is_null()) {
961 colMap = A->getColMap();
984 static Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
985 readBanner(std::istream& in,
987 const bool tolerant =
false,
989 const bool isGraph =
false) {
994 using Teuchos::MatrixMarket::Banner;
995 typedef Teuchos::ScalarTraits<scalar_type> STS;
1001 const bool readFailed = !getline(in, line);
1002 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
1003 "Failed to get Matrix Market banner line from input.");
1010 pBanner = rcp(
new Banner(line, tolerant));
1011 }
catch (std::exception& e) {
1012 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1013 "Matrix Market banner line contains syntax error(s): "
1017 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
1018 std::invalid_argument,
1019 "The Matrix Market file does not contain "
1020 "matrix data. Its Banner (first) line says that its object type is \""
1021 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
1025 TEUCHOS_TEST_FOR_EXCEPTION(
1026 !STS::isComplex && pBanner->dataType() ==
"complex",
1027 std::invalid_argument,
1028 "The Matrix Market file contains complex-valued data, but you are "
1029 "trying to read it into a matrix containing entries of the real-"
1030 "valued Scalar type \""
1031 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
1032 TEUCHOS_TEST_FOR_EXCEPTION(
1034 pBanner->dataType() !=
"real" &&
1035 pBanner->dataType() !=
"complex" &&
1036 pBanner->dataType() !=
"integer",
1037 std::invalid_argument,
1038 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
1039 "Matrix Market file may not contain a \"pattern\" matrix. A "
1040 "pattern matrix is really just a graph with no weights. It "
1041 "should be stored in a CrsGraph, not a CrsMatrix.");
1043 TEUCHOS_TEST_FOR_EXCEPTION(
1045 pBanner->dataType() !=
"pattern",
1046 std::invalid_argument,
1047 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
1048 "Matrix Market file must contain a \"pattern\" matrix.");
1075 static Teuchos::Tuple<global_ordinal_type, 3>
1076 readCoordDims(std::istream& in,
1078 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1080 const bool tolerant =
false,
1081 const bool =
false) {
1082 using Teuchos::Tuple;
1083 using Teuchos::MatrixMarket::readCoordinateDimensions;
1088 Tuple<global_ordinal_type, 3> dims;
1094 bool success =
false;
1095 if (pComm->getRank() == 0) {
1096 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
1097 std::invalid_argument,
1098 "The Tpetra::CrsMatrix Matrix Market reader "
1099 "only accepts \"coordinate\" (sparse) matrix data.");
1103 success = readCoordinateDimensions(in, numRows, numCols,
1104 numNonzeros, lineNumber,
1110 dims[2] = numNonzeros;
1118 int the_success = success ? 1 : 0;
1119 Teuchos::broadcast(*pComm, 0, &the_success);
1120 success = (the_success == 1);
1125 Teuchos::broadcast(*pComm, 0, dims);
1132 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1133 "Error reading Matrix Market sparse matrix: failed to read "
1134 "coordinate matrix dimensions.");
1149 typedef Teuchos::MatrixMarket::SymmetrizingAdder<Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type>> adder_type;
1151 typedef Teuchos::MatrixMarket::SymmetrizingGraphAdder<Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type>> graph_adder_type;
1178 static Teuchos::RCP<adder_type>
1179 makeAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1180 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1181 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1182 const bool tolerant =
false,
1183 const bool debug =
false) {
1184 if (pComm->getRank() == 0) {
1185 typedef Teuchos::MatrixMarket::Raw::Adder<
scalar_type,
1188 Teuchos::RCP<raw_adder_type> pRaw =
1189 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
1191 return Teuchos::rcp(
new adder_type(pRaw, pBanner->symmType()));
1193 return Teuchos::null;
1222 static Teuchos::RCP<graph_adder_type>
1223 makeGraphAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1224 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1225 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1226 const bool tolerant =
false,
1227 const bool debug =
false) {
1228 if (pComm->getRank() == 0) {
1229 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
1230 Teuchos::RCP<raw_adder_type> pRaw =
1231 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
1233 return Teuchos::rcp(
new graph_adder_type(pRaw, pBanner->symmType()));
1235 return Teuchos::null;
1240 static Teuchos::RCP<sparse_graph_type>
1241 readSparseGraphHelper(std::istream& in,
1242 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1243 const Teuchos::RCP<const map_type>& rowMap,
1244 Teuchos::RCP<const map_type>& colMap,
1245 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1246 const bool tolerant,
1252 using Teuchos::Tuple;
1253 using Teuchos::MatrixMarket::Banner;
1255 const int myRank = pComm->getRank();
1256 const int rootRank = 0;
1261 size_t lineNumber = 1;
1263 if (debug && myRank == rootRank) {
1264 cerr <<
"Matrix Market reader: readGraph:" << endl
1265 <<
"-- Reading banner line" << endl;
1274 RCP<const Banner> pBanner;
1280 int bannerIsCorrect = 1;
1281 std::ostringstream errMsg;
1283 if (myRank == rootRank) {
1286 pBanner = readBanner(in, lineNumber, tolerant, debug,
true);
1287 }
catch (std::exception& e) {
1288 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1289 "threw an exception: "
1291 bannerIsCorrect = 0;
1294 if (bannerIsCorrect) {
1299 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
1300 bannerIsCorrect = 0;
1301 errMsg <<
"The Matrix Market input file must contain a "
1302 "\"coordinate\"-format sparse graph in order to create a "
1303 "Tpetra::CrsGraph object from it, but the file's matrix "
1305 << pBanner->matrixType() <<
"\" instead.";
1310 if (tolerant && pBanner->matrixType() ==
"array") {
1311 bannerIsCorrect = 0;
1312 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1313 "format sparse graph in order to create a Tpetra::CrsGraph "
1314 "object from it, but the file's matrix type is \"array\" "
1315 "instead. That probably means the file contains dense matrix "
1322 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
1329 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
1330 std::invalid_argument, errMsg.str());
1332 if (debug && myRank == rootRank) {
1333 cerr <<
"-- Reading dimensions line" << endl;
1341 Tuple<global_ordinal_type, 3> dims =
1342 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
1344 if (debug && myRank == rootRank) {
1345 cerr <<
"-- Making Adder for collecting graph data" << endl;
1352 RCP<graph_adder_type> pAdder =
1353 makeGraphAdder(pComm, pBanner, dims, tolerant, debug);
1355 if (debug && myRank == rootRank) {
1356 cerr <<
"-- Reading graph data" << endl;
1366 int readSuccess = 1;
1367 std::ostringstream errMsg;
1368 if (myRank == rootRank) {
1371 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
1374 reader_type reader(pAdder);
1377 std::pair<bool, std::vector<size_t>> results =
1378 reader.read(in, lineNumber, tolerant, debug);
1379 readSuccess = results.first ? 1 : 0;
1380 }
catch (std::exception& e) {
1385 broadcast(*pComm, rootRank, ptr(&readSuccess));
1394 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1395 "Failed to read the Matrix Market sparse graph file: "
1399 if (debug && myRank == rootRank) {
1400 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1413 if (debug && myRank == rootRank) {
1414 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1416 <<
"----- Dimensions before: "
1417 << dims[0] <<
" x " << dims[1]
1421 Tuple<global_ordinal_type, 2> updatedDims;
1422 if (myRank == rootRank) {
1429 std::max(dims[0], pAdder->getAdder()->numRows());
1430 updatedDims[1] = pAdder->getAdder()->numCols();
1432 broadcast(*pComm, rootRank, updatedDims);
1433 dims[0] = updatedDims[0];
1434 dims[1] = updatedDims[1];
1435 if (debug && myRank == rootRank) {
1436 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1449 if (myRank == rootRank) {
1456 if (dims[0] < pAdder->getAdder()->numRows()) {
1460 broadcast(*pComm, 0, ptr(&dimsMatch));
1461 if (dimsMatch == 0) {
1468 Tuple<global_ordinal_type, 2> addersDims;
1469 if (myRank == rootRank) {
1470 addersDims[0] = pAdder->getAdder()->numRows();
1471 addersDims[1] = pAdder->getAdder()->numCols();
1473 broadcast(*pComm, 0, addersDims);
1474 TEUCHOS_TEST_FOR_EXCEPTION(
1475 dimsMatch == 0, std::runtime_error,
1476 "The graph metadata says that the graph is " << dims[0] <<
" x "
1477 << dims[1] <<
", but the actual data says that the graph is "
1478 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1479 "data includes more rows than reported in the metadata. This "
1480 "is not allowed when parsing in strict mode. Parse the graph in "
1481 "tolerant mode to ignore the metadata when it disagrees with the "
1487 RCP<map_type> proc0Map;
1489 if (Teuchos::is_null(rowMap)) {
1492 indexBase = rowMap->getIndexBase();
1494 if (myRank == rootRank) {
1495 proc0Map = rcp(
new map_type(dims[0], dims[0], indexBase, pComm));
1497 proc0Map = rcp(
new map_type(dims[0], 0, indexBase, pComm));
1501 std::map<global_ordinal_type, size_t> numEntriesPerRow_map;
1502 if (myRank == rootRank) {
1503 const auto& entries = pAdder()->getAdder()->getEntries();
1508 for (
const auto& entry : entries) {
1510 ++numEntriesPerRow_map[gblRow];
1514 Teuchos::Array<size_t> numEntriesPerRow(proc0Map->getLocalNumElements());
1515 for (
const auto& ent : numEntriesPerRow_map) {
1517 numEntriesPerRow[lclRow] = ent.second;
1524 std::map<global_ordinal_type, size_t> empty_map;
1525 std::swap(numEntriesPerRow_map, empty_map);
1528 RCP<sparse_graph_type> proc0Graph =
1530 constructorParams));
1531 if (myRank == rootRank) {
1532 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1535 const std::vector<element_type>& entries =
1536 pAdder->getAdder()->getEntries();
1539 for (
size_t curPos = 0; curPos < entries.size(); curPos++) {
1540 const element_type& curEntry = entries[curPos];
1543 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol, 1);
1544 proc0Graph->insertGlobalIndices(curRow, colView);
1547 proc0Graph->fillComplete();
1549 RCP<sparse_graph_type> distGraph;
1550 if (Teuchos::is_null(rowMap)) {
1552 RCP<map_type> distMap =
1553 rcp(
new map_type(dims[0], 0, pComm, GloballyDistributed));
1559 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1560 import_type importer(proc0Map, distMap);
1563 distGraph->doImport(*proc0Graph, importer,
INSERT);
1568 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1569 import_type importer(proc0Map, rowMap);
1572 distGraph->doImport(*proc0Graph, importer,
INSERT);
1602 static Teuchos::RCP<sparse_graph_type>
1605 const bool callFillComplete =
true,
1606 const bool tolerant =
false,
1607 const bool debug =
false) {
1646 static Teuchos::RCP<sparse_graph_type>
1648 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1649 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1650 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1651 const bool tolerant =
false,
1652 const bool debug =
false) {
1657 fillCompleteParams, tolerant, debug);
1700 static Teuchos::RCP<sparse_graph_type>
1702 const Teuchos::RCP<const map_type>& rowMap,
1703 Teuchos::RCP<const map_type>& colMap,
1704 const Teuchos::RCP<const map_type>& domainMap,
1705 const Teuchos::RCP<const map_type>& rangeMap,
1706 const bool callFillComplete =
true,
1707 const bool tolerant =
false,
1708 const bool debug =
false) {
1709 TEUCHOS_TEST_FOR_EXCEPTION(rowMap.is_null(), std::invalid_argument,
1710 "Input rowMap must be nonnull.");
1712 if (comm.is_null()) {
1715 return Teuchos::null;
1721 callFillComplete, tolerant, debug);
1749 static Teuchos::RCP<sparse_graph_type>
1751 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1752 const bool callFillComplete =
true,
1753 const bool tolerant =
false,
1754 const bool debug =
false) {
1755 Teuchos::RCP<const map_type> fakeRowMap;
1756 Teuchos::RCP<const map_type> fakeColMap;
1757 Teuchos::RCP<Teuchos::ParameterList> fakeCtorParams;
1759 Teuchos::RCP<sparse_graph_type> graph =
1760 readSparseGraphHelper(in, pComm,
1761 fakeRowMap, fakeColMap,
1762 fakeCtorParams, tolerant, debug);
1763 if (callFillComplete) {
1764 graph->fillComplete();
1798 static Teuchos::RCP<sparse_graph_type>
1800 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1801 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1802 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1803 const bool tolerant =
false,
1804 const bool debug =
false) {
1805 Teuchos::RCP<const map_type> fakeRowMap;
1806 Teuchos::RCP<const map_type> fakeColMap;
1807 Teuchos::RCP<sparse_graph_type> graph =
1808 readSparseGraphHelper(in, pComm,
1809 fakeRowMap, fakeColMap,
1810 constructorParams, tolerant, debug);
1811 graph->fillComplete(fillCompleteParams);
1855 static Teuchos::RCP<sparse_graph_type>
1857 const Teuchos::RCP<const map_type>& rowMap,
1858 Teuchos::RCP<const map_type>& colMap,
1859 const Teuchos::RCP<const map_type>& domainMap,
1860 const Teuchos::RCP<const map_type>& rangeMap,
1861 const bool callFillComplete =
true,
1862 const bool tolerant =
false,
1863 const bool debug =
false) {
1864 Teuchos::RCP<sparse_graph_type> graph =
1865 readSparseGraphHelper(in, rowMap->getComm(),
1866 rowMap, colMap, Teuchos::null, tolerant,
1868 if (callFillComplete) {
1869 graph->fillComplete(domainMap, rangeMap);
1874 #include "MatrixMarket_TpetraNew.hpp"
1899 static Teuchos::RCP<sparse_matrix_type>
1902 const bool callFillComplete =
true,
1903 const bool tolerant =
false,
1904 const bool debug =
false) {
1907 return readSparse(in, comm, callFillComplete, tolerant, debug);
1941 static Teuchos::RCP<sparse_matrix_type>
1944 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1945 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1946 const bool tolerant =
false,
1947 const bool debug =
false) {
1950 return readSparse(in, comm, constructorParams,
1951 fillCompleteParams, tolerant, debug);
1991 static Teuchos::RCP<sparse_matrix_type>
1993 const Teuchos::RCP<const map_type>& rowMap,
1994 Teuchos::RCP<const map_type>& colMap,
1995 const Teuchos::RCP<const map_type>& domainMap,
1996 const Teuchos::RCP<const map_type>& rangeMap,
1997 const bool callFillComplete =
true,
1998 const bool tolerant =
false,
1999 const bool debug =
false) {
2000 TEUCHOS_TEST_FOR_EXCEPTION(
2001 rowMap.is_null(), std::invalid_argument,
2002 "Row Map must be nonnull.");
2008 return readSparse(in, rowMap, colMap, domainMap, rangeMap,
2009 callFillComplete, tolerant, debug);
2037 static Teuchos::RCP<sparse_matrix_type>
2039 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
2040 const bool callFillComplete =
true,
2041 const bool tolerant =
false,
2042 const bool debug =
false) {
2045 using Teuchos::arcp;
2046 using Teuchos::ArrayRCP;
2047 using Teuchos::broadcast;
2048 using Teuchos::null;
2051 using Teuchos::REDUCE_MAX;
2052 using Teuchos::reduceAll;
2053 using Teuchos::Tuple;
2054 using Teuchos::MatrixMarket::Banner;
2055 typedef Teuchos::ScalarTraits<scalar_type> STS;
2057 const bool extraDebug =
false;
2058 const int myRank = pComm->getRank();
2059 const int rootRank = 0;
2064 size_t lineNumber = 1;
2066 if (debug && myRank == rootRank) {
2067 cerr <<
"Matrix Market reader: readSparse:" << endl
2068 <<
"-- Reading banner line" << endl;
2077 RCP<const Banner> pBanner;
2083 int bannerIsCorrect = 1;
2084 std::ostringstream errMsg;
2086 if (myRank == rootRank) {
2089 pBanner = readBanner(in, lineNumber, tolerant, debug);
2090 }
catch (std::exception& e) {
2091 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2092 "threw an exception: "
2094 bannerIsCorrect = 0;
2097 if (bannerIsCorrect) {
2102 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
2103 bannerIsCorrect = 0;
2104 errMsg <<
"The Matrix Market input file must contain a "
2105 "\"coordinate\"-format sparse matrix in order to create a "
2106 "Tpetra::CrsMatrix object from it, but the file's matrix "
2108 << pBanner->matrixType() <<
"\" instead.";
2113 if (tolerant && pBanner->matrixType() ==
"array") {
2114 bannerIsCorrect = 0;
2115 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2116 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2117 "object from it, but the file's matrix type is \"array\" "
2118 "instead. That probably means the file contains dense matrix "
2125 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
2132 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2133 std::invalid_argument, errMsg.str());
2135 if (debug && myRank == rootRank) {
2136 cerr <<
"-- Reading dimensions line" << endl;
2144 Tuple<global_ordinal_type, 3> dims =
2145 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
2147 if (debug && myRank == rootRank) {
2148 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2153 RCP<adder_type> pAdder =
2154 makeAdder(pComm, pBanner, dims, tolerant, debug);
2156 if (debug && myRank == rootRank) {
2157 cerr <<
"-- Reading matrix data" << endl;
2167 int readSuccess = 1;
2168 std::ostringstream errMsg;
2169 if (myRank == rootRank) {
2172 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2175 reader_type reader(pAdder);
2178 std::pair<bool, std::vector<size_t>> results =
2179 reader.read(in, lineNumber, tolerant, debug);
2180 readSuccess = results.first ? 1 : 0;
2181 }
catch (std::exception& e) {
2186 broadcast(*pComm, rootRank, ptr(&readSuccess));
2195 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2196 "Failed to read the Matrix Market sparse matrix file: "
2200 if (debug && myRank == rootRank) {
2201 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2214 if (debug && myRank == rootRank) {
2215 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2217 <<
"----- Dimensions before: "
2218 << dims[0] <<
" x " << dims[1]
2222 Tuple<global_ordinal_type, 2> updatedDims;
2223 if (myRank == rootRank) {
2230 std::max(dims[0], pAdder->getAdder()->numRows());
2231 updatedDims[1] = pAdder->getAdder()->numCols();
2233 broadcast(*pComm, rootRank, updatedDims);
2234 dims[0] = updatedDims[0];
2235 dims[1] = updatedDims[1];
2236 if (debug && myRank == rootRank) {
2237 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2250 if (myRank == rootRank) {
2257 if (dims[0] < pAdder->getAdder()->numRows()) {
2261 broadcast(*pComm, 0, ptr(&dimsMatch));
2262 if (dimsMatch == 0) {
2269 Tuple<global_ordinal_type, 2> addersDims;
2270 if (myRank == rootRank) {
2271 addersDims[0] = pAdder->getAdder()->numRows();
2272 addersDims[1] = pAdder->getAdder()->numCols();
2274 broadcast(*pComm, 0, addersDims);
2275 TEUCHOS_TEST_FOR_EXCEPTION(
2276 dimsMatch == 0, std::runtime_error,
2277 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2278 << dims[1] <<
", but the actual data says that the matrix is "
2279 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2280 "data includes more rows than reported in the metadata. This "
2281 "is not allowed when parsing in strict mode. Parse the matrix in "
2282 "tolerant mode to ignore the metadata when it disagrees with the "
2287 if (debug && myRank == rootRank) {
2288 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2300 ArrayRCP<size_t> numEntriesPerRow;
2301 ArrayRCP<size_t> rowPtr;
2302 ArrayRCP<global_ordinal_type> colInd;
2303 ArrayRCP<scalar_type> values;
2308 int mergeAndConvertSucceeded = 1;
2309 std::ostringstream errMsg;
2311 if (myRank == rootRank) {
2313 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2324 const size_type numRows = dims[0];
2327 pAdder->getAdder()->merge();
2330 const std::vector<element_type>& entries =
2331 pAdder->getAdder()->getEntries();
2334 const size_t numEntries = (size_t)entries.size();
2337 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2338 <<
" rows and numEntries=" << numEntries
2339 <<
" entries." << endl;
2345 numEntriesPerRow = arcp<size_t>(numRows);
2346 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2347 rowPtr = arcp<size_t>(numRows + 1);
2348 std::fill(rowPtr.begin(), rowPtr.end(), 0);
2349 colInd = arcp<global_ordinal_type>(numEntries);
2350 values = arcp<scalar_type>(numEntries);
2357 for (curPos = 0; curPos < numEntries; ++curPos) {
2358 const element_type& curEntry = entries[curPos];
2360 TEUCHOS_TEST_FOR_EXCEPTION(
2361 curRow < prvRow, std::logic_error,
2362 "Row indices are out of order, even though they are supposed "
2363 "to be sorted. curRow = "
2364 << curRow <<
", prvRow = "
2365 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2366 "this bug to the Tpetra developers.");
2367 if (curRow > prvRow) {
2373 numEntriesPerRow[curRow]++;
2374 colInd[curPos] = curEntry.colIndex();
2375 values[curPos] = curEntry.value();
2380 rowPtr[numRows] = numEntries;
2382 catch (std::exception& e) {
2383 mergeAndConvertSucceeded = 0;
2384 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2389 if (debug && mergeAndConvertSucceeded) {
2391 const size_type numRows = dims[0];
2392 const size_type maxToDisplay = 100;
2394 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2395 << (numEntriesPerRow.size() - 1) <<
"] ";
2396 if (numRows > maxToDisplay) {
2397 cerr <<
"(only showing first and last few entries) ";
2401 if (numRows > maxToDisplay) {
2402 for (size_type k = 0; k < 2; ++k) {
2403 cerr << numEntriesPerRow[k] <<
" ";
2406 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
2407 cerr << numEntriesPerRow[k] <<
" ";
2410 for (size_type k = 0; k < numRows - 1; ++k) {
2411 cerr << numEntriesPerRow[k] <<
" ";
2414 cerr << numEntriesPerRow[numRows - 1];
2416 cerr <<
"]" << endl;
2418 cerr <<
"----- Proc 0: rowPtr ";
2419 if (numRows > maxToDisplay) {
2420 cerr <<
"(only showing first and last few entries) ";
2423 if (numRows > maxToDisplay) {
2424 for (size_type k = 0; k < 2; ++k) {
2425 cerr << rowPtr[k] <<
" ";
2428 for (size_type k = numRows - 2; k < numRows; ++k) {
2429 cerr << rowPtr[k] <<
" ";
2432 for (size_type k = 0; k < numRows; ++k) {
2433 cerr << rowPtr[k] <<
" ";
2436 cerr << rowPtr[numRows] <<
"]" << endl;
2447 if (debug && myRank == rootRank) {
2448 cerr <<
"-- Making range, domain, and row maps" << endl;
2455 RCP<const map_type> pRangeMap = makeRangeMap(pComm, dims[0]);
2456 RCP<const map_type> pDomainMap =
2457 makeDomainMap(pRangeMap, dims[0], dims[1]);
2458 RCP<const map_type> pRowMap = makeRowMap(null, pComm, dims[0]);
2460 if (debug && myRank == rootRank) {
2461 cerr <<
"-- Distributing the matrix data" << endl;
2475 ArrayRCP<size_t> myNumEntriesPerRow;
2476 ArrayRCP<size_t> myRowPtr;
2477 ArrayRCP<global_ordinal_type> myColInd;
2478 ArrayRCP<scalar_type> myValues;
2480 distribute(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
2481 numEntriesPerRow, rowPtr, colInd, values, debug);
2483 if (debug && myRank == rootRank) {
2484 cerr <<
"-- Inserting matrix entries on each processor";
2485 if (callFillComplete) {
2486 cerr <<
" and calling fillComplete()";
2497 RCP<sparse_matrix_type> pMatrix =
2498 makeMatrix(myNumEntriesPerRow, myRowPtr, myColInd, myValues,
2499 pRowMap, pRangeMap, pDomainMap, callFillComplete);
2504 int localIsNull = pMatrix.is_null() ? 1 : 0;
2505 int globalIsNull = 0;
2506 reduceAll(*pComm, REDUCE_MAX, localIsNull, ptr(&globalIsNull));
2507 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
2508 "Reader::makeMatrix() returned a null pointer on at least one "
2509 "process. Please report this bug to the Tpetra developers.");
2511 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
2512 "Reader::makeMatrix() returned a null pointer. "
2513 "Please report this bug to the Tpetra developers.");
2525 if (callFillComplete) {
2526 const int numProcs = pComm->getSize();
2528 if (extraDebug && debug) {
2530 pRangeMap->getGlobalNumElements();
2532 pDomainMap->getGlobalNumElements();
2533 if (myRank == rootRank) {
2534 cerr <<
"-- Matrix is "
2535 << globalNumRows <<
" x " << globalNumCols
2536 <<
" with " << pMatrix->getGlobalNumEntries()
2537 <<
" entries, and index base "
2538 << pMatrix->getIndexBase() <<
"." << endl;
2541 for (
int p = 0; p < numProcs; ++p) {
2543 cerr <<
"-- Proc " << p <<
" owns "
2544 << pMatrix->getLocalNumCols() <<
" columns, and "
2545 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
2552 if (debug && myRank == rootRank) {
2553 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2587 static Teuchos::RCP<sparse_matrix_type>
2589 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
2590 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2591 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2592 const bool tolerant =
false,
2593 const bool debug =
false) {
2596 using Teuchos::arcp;
2597 using Teuchos::ArrayRCP;
2598 using Teuchos::broadcast;
2599 using Teuchos::null;
2602 using Teuchos::reduceAll;
2603 using Teuchos::Tuple;
2604 using Teuchos::MatrixMarket::Banner;
2605 typedef Teuchos::ScalarTraits<scalar_type> STS;
2607 const bool extraDebug =
false;
2608 const int myRank = pComm->getRank();
2609 const int rootRank = 0;
2614 size_t lineNumber = 1;
2616 if (debug && myRank == rootRank) {
2617 cerr <<
"Matrix Market reader: readSparse:" << endl
2618 <<
"-- Reading banner line" << endl;
2627 RCP<const Banner> pBanner;
2633 int bannerIsCorrect = 1;
2634 std::ostringstream errMsg;
2636 if (myRank == rootRank) {
2639 pBanner = readBanner(in, lineNumber, tolerant, debug);
2640 }
catch (std::exception& e) {
2641 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2642 "threw an exception: "
2644 bannerIsCorrect = 0;
2647 if (bannerIsCorrect) {
2652 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
2653 bannerIsCorrect = 0;
2654 errMsg <<
"The Matrix Market input file must contain a "
2655 "\"coordinate\"-format sparse matrix in order to create a "
2656 "Tpetra::CrsMatrix object from it, but the file's matrix "
2658 << pBanner->matrixType() <<
"\" instead.";
2663 if (tolerant && pBanner->matrixType() ==
"array") {
2664 bannerIsCorrect = 0;
2665 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2666 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2667 "object from it, but the file's matrix type is \"array\" "
2668 "instead. That probably means the file contains dense matrix "
2675 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
2682 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2683 std::invalid_argument, errMsg.str());
2685 if (debug && myRank == rootRank) {
2686 cerr <<
"-- Reading dimensions line" << endl;
2694 Tuple<global_ordinal_type, 3> dims =
2695 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
2697 if (debug && myRank == rootRank) {
2698 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2703 RCP<adder_type> pAdder =
2704 makeAdder(pComm, pBanner, dims, tolerant, debug);
2706 if (debug && myRank == rootRank) {
2707 cerr <<
"-- Reading matrix data" << endl;
2717 int readSuccess = 1;
2718 std::ostringstream errMsg;
2719 if (myRank == rootRank) {
2722 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2725 reader_type reader(pAdder);
2728 std::pair<bool, std::vector<size_t>> results =
2729 reader.read(in, lineNumber, tolerant, debug);
2730 readSuccess = results.first ? 1 : 0;
2731 }
catch (std::exception& e) {
2736 broadcast(*pComm, rootRank, ptr(&readSuccess));
2745 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2746 "Failed to read the Matrix Market sparse matrix file: "
2750 if (debug && myRank == rootRank) {
2751 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2764 if (debug && myRank == rootRank) {
2765 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2767 <<
"----- Dimensions before: "
2768 << dims[0] <<
" x " << dims[1]
2772 Tuple<global_ordinal_type, 2> updatedDims;
2773 if (myRank == rootRank) {
2780 std::max(dims[0], pAdder->getAdder()->numRows());
2781 updatedDims[1] = pAdder->getAdder()->numCols();
2783 broadcast(*pComm, rootRank, updatedDims);
2784 dims[0] = updatedDims[0];
2785 dims[1] = updatedDims[1];
2786 if (debug && myRank == rootRank) {
2787 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2800 if (myRank == rootRank) {
2807 if (dims[0] < pAdder->getAdder()->numRows()) {
2811 broadcast(*pComm, 0, ptr(&dimsMatch));
2812 if (dimsMatch == 0) {
2819 Tuple<global_ordinal_type, 2> addersDims;
2820 if (myRank == rootRank) {
2821 addersDims[0] = pAdder->getAdder()->numRows();
2822 addersDims[1] = pAdder->getAdder()->numCols();
2824 broadcast(*pComm, 0, addersDims);
2825 TEUCHOS_TEST_FOR_EXCEPTION(
2826 dimsMatch == 0, std::runtime_error,
2827 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2828 << dims[1] <<
", but the actual data says that the matrix is "
2829 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2830 "data includes more rows than reported in the metadata. This "
2831 "is not allowed when parsing in strict mode. Parse the matrix in "
2832 "tolerant mode to ignore the metadata when it disagrees with the "
2837 if (debug && myRank == rootRank) {
2838 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2850 ArrayRCP<size_t> numEntriesPerRow;
2851 ArrayRCP<size_t> rowPtr;
2852 ArrayRCP<global_ordinal_type> colInd;
2853 ArrayRCP<scalar_type> values;
2858 int mergeAndConvertSucceeded = 1;
2859 std::ostringstream errMsg;
2861 if (myRank == rootRank) {
2863 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2874 const size_type numRows = dims[0];
2877 pAdder->getAdder()->merge();
2880 const std::vector<element_type>& entries =
2881 pAdder->getAdder()->getEntries();
2884 const size_t numEntries = (size_t)entries.size();
2887 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2888 <<
" rows and numEntries=" << numEntries
2889 <<
" entries." << endl;
2895 numEntriesPerRow = arcp<size_t>(numRows);
2896 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2897 rowPtr = arcp<size_t>(numRows + 1);
2898 std::fill(rowPtr.begin(), rowPtr.end(), 0);
2899 colInd = arcp<global_ordinal_type>(numEntries);
2900 values = arcp<scalar_type>(numEntries);
2907 for (curPos = 0; curPos < numEntries; ++curPos) {
2908 const element_type& curEntry = entries[curPos];
2910 TEUCHOS_TEST_FOR_EXCEPTION(
2911 curRow < prvRow, std::logic_error,
2912 "Row indices are out of order, even though they are supposed "
2913 "to be sorted. curRow = "
2914 << curRow <<
", prvRow = "
2915 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2916 "this bug to the Tpetra developers.");
2917 if (curRow > prvRow) {
2923 numEntriesPerRow[curRow]++;
2924 colInd[curPos] = curEntry.colIndex();
2925 values[curPos] = curEntry.value();
2930 rowPtr[numRows] = numEntries;
2932 catch (std::exception& e) {
2933 mergeAndConvertSucceeded = 0;
2934 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2939 if (debug && mergeAndConvertSucceeded) {
2941 const size_type numRows = dims[0];
2942 const size_type maxToDisplay = 100;
2944 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2945 << (numEntriesPerRow.size() - 1) <<
"] ";
2946 if (numRows > maxToDisplay) {
2947 cerr <<
"(only showing first and last few entries) ";
2951 if (numRows > maxToDisplay) {
2952 for (size_type k = 0; k < 2; ++k) {
2953 cerr << numEntriesPerRow[k] <<
" ";
2956 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
2957 cerr << numEntriesPerRow[k] <<
" ";
2960 for (size_type k = 0; k < numRows - 1; ++k) {
2961 cerr << numEntriesPerRow[k] <<
" ";
2964 cerr << numEntriesPerRow[numRows - 1];
2966 cerr <<
"]" << endl;
2968 cerr <<
"----- Proc 0: rowPtr ";
2969 if (numRows > maxToDisplay) {
2970 cerr <<
"(only showing first and last few entries) ";
2973 if (numRows > maxToDisplay) {
2974 for (size_type k = 0; k < 2; ++k) {
2975 cerr << rowPtr[k] <<
" ";
2978 for (size_type k = numRows - 2; k < numRows; ++k) {
2979 cerr << rowPtr[k] <<
" ";
2982 for (size_type k = 0; k < numRows; ++k) {
2983 cerr << rowPtr[k] <<
" ";
2986 cerr << rowPtr[numRows] <<
"]" << endl;
2997 if (debug && myRank == rootRank) {
2998 cerr <<
"-- Making range, domain, and row maps" << endl;
3005 RCP<const map_type> pRangeMap = makeRangeMap(pComm, dims[0]);
3006 RCP<const map_type> pDomainMap =
3007 makeDomainMap(pRangeMap, dims[0], dims[1]);
3008 RCP<const map_type> pRowMap = makeRowMap(null, pComm, dims[0]);
3010 if (debug && myRank == rootRank) {
3011 cerr <<
"-- Distributing the matrix data" << endl;
3025 ArrayRCP<size_t> myNumEntriesPerRow;
3026 ArrayRCP<size_t> myRowPtr;
3027 ArrayRCP<global_ordinal_type> myColInd;
3028 ArrayRCP<scalar_type> myValues;
3030 distribute(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
3031 numEntriesPerRow, rowPtr, colInd, values, debug);
3033 if (debug && myRank == rootRank) {
3034 cerr <<
"-- Inserting matrix entries on each process "
3035 "and calling fillComplete()"
3045 Teuchos::RCP<sparse_matrix_type> pMatrix =
3046 makeMatrix(myNumEntriesPerRow, myRowPtr, myColInd, myValues,
3047 pRowMap, pRangeMap, pDomainMap, constructorParams,
3048 fillCompleteParams);
3053 int localIsNull = pMatrix.is_null() ? 1 : 0;
3054 int globalIsNull = 0;
3055 reduceAll(*pComm, Teuchos::REDUCE_MAX, localIsNull, ptr(&globalIsNull));
3056 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
3057 "Reader::makeMatrix() returned a null pointer on at least one "
3058 "process. Please report this bug to the Tpetra developers.");
3060 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
3061 "Reader::makeMatrix() returned a null pointer. "
3062 "Please report this bug to the Tpetra developers.");
3071 if (extraDebug && debug) {
3072 const int numProcs = pComm->getSize();
3074 pRangeMap->getGlobalNumElements();
3076 pDomainMap->getGlobalNumElements();
3077 if (myRank == rootRank) {
3078 cerr <<
"-- Matrix is "
3079 << globalNumRows <<
" x " << globalNumCols
3080 <<
" with " << pMatrix->getGlobalNumEntries()
3081 <<
" entries, and index base "
3082 << pMatrix->getIndexBase() <<
"." << endl;
3085 for (
int p = 0; p < numProcs; ++p) {
3087 cerr <<
"-- Proc " << p <<
" owns "
3088 << pMatrix->getLocalNumCols() <<
" columns, and "
3089 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
3095 if (debug && myRank == rootRank) {
3096 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3142 static Teuchos::RCP<sparse_matrix_type>
3144 const Teuchos::RCP<const map_type>& rowMap,
3145 Teuchos::RCP<const map_type>& colMap,
3146 const Teuchos::RCP<const map_type>& domainMap,
3147 const Teuchos::RCP<const map_type>& rangeMap,
3148 const bool callFillComplete =
true,
3149 const bool tolerant =
false,
3150 const bool debug =
false) {
3153 using Teuchos::arcp;
3154 using Teuchos::ArrayRCP;
3155 using Teuchos::ArrayView;
3157 using Teuchos::broadcast;
3158 using Teuchos::Comm;
3159 using Teuchos::null;
3162 using Teuchos::reduceAll;
3163 using Teuchos::Tuple;
3164 using Teuchos::MatrixMarket::Banner;
3165 typedef Teuchos::ScalarTraits<scalar_type> STS;
3167 RCP<const Comm<int>> pComm = rowMap->getComm();
3168 const int myRank = pComm->getRank();
3169 const int rootRank = 0;
3170 const bool extraDebug =
false;
3175 TEUCHOS_TEST_FOR_EXCEPTION(
3176 rowMap.is_null(), std::invalid_argument,
3177 "Row Map must be nonnull.");
3178 TEUCHOS_TEST_FOR_EXCEPTION(
3179 rangeMap.is_null(), std::invalid_argument,
3180 "Range Map must be nonnull.");
3181 TEUCHOS_TEST_FOR_EXCEPTION(
3182 domainMap.is_null(), std::invalid_argument,
3183 "Domain Map must be nonnull.");
3184 TEUCHOS_TEST_FOR_EXCEPTION(
3185 rowMap->getComm().getRawPtr() != pComm.getRawPtr(),
3186 std::invalid_argument,
3187 "The specified row Map's communicator (rowMap->getComm())"
3188 "differs from the given separately supplied communicator pComm.");
3189 TEUCHOS_TEST_FOR_EXCEPTION(
3190 domainMap->getComm().getRawPtr() != pComm.getRawPtr(),
3191 std::invalid_argument,
3192 "The specified domain Map's communicator (domainMap->getComm())"
3193 "differs from the given separately supplied communicator pComm.");
3194 TEUCHOS_TEST_FOR_EXCEPTION(
3195 rangeMap->getComm().getRawPtr() != pComm.getRawPtr(),
3196 std::invalid_argument,
3197 "The specified range Map's communicator (rangeMap->getComm())"
3198 "differs from the given separately supplied communicator pComm.");
3203 size_t lineNumber = 1;
3205 if (debug && myRank == rootRank) {
3206 cerr <<
"Matrix Market reader: readSparse:" << endl
3207 <<
"-- Reading banner line" << endl;
3216 RCP<const Banner> pBanner;
3222 int bannerIsCorrect = 1;
3223 std::ostringstream errMsg;
3225 if (myRank == rootRank) {
3228 pBanner = readBanner(in, lineNumber, tolerant, debug);
3229 }
catch (std::exception& e) {
3230 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
3231 "threw an exception: "
3233 bannerIsCorrect = 0;
3236 if (bannerIsCorrect) {
3241 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
3242 bannerIsCorrect = 0;
3243 errMsg <<
"The Matrix Market input file must contain a "
3244 "\"coordinate\"-format sparse matrix in order to create a "
3245 "Tpetra::CrsMatrix object from it, but the file's matrix "
3247 << pBanner->matrixType() <<
"\" instead.";
3252 if (tolerant && pBanner->matrixType() ==
"array") {
3253 bannerIsCorrect = 0;
3254 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
3255 "format sparse matrix in order to create a Tpetra::CrsMatrix "
3256 "object from it, but the file's matrix type is \"array\" "
3257 "instead. That probably means the file contains dense matrix "
3264 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
3271 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
3272 std::invalid_argument, errMsg.str());
3274 if (debug && myRank == rootRank) {
3275 cerr <<
"-- Reading dimensions line" << endl;
3283 Tuple<global_ordinal_type, 3> dims =
3284 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
3286 if (debug && myRank == rootRank) {
3287 cerr <<
"-- Making Adder for collecting matrix data" << endl;
3294 RCP<adder_type> pAdder =
3295 makeAdder(pComm, pBanner, dims, tolerant, debug);
3297 if (debug && myRank == rootRank) {
3298 cerr <<
"-- Reading matrix data" << endl;
3308 int readSuccess = 1;
3309 std::ostringstream errMsg;
3310 if (myRank == rootRank) {
3313 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
3316 reader_type reader(pAdder);
3319 std::pair<bool, std::vector<size_t>> results =
3320 reader.read(in, lineNumber, tolerant, debug);
3321 readSuccess = results.first ? 1 : 0;
3322 }
catch (std::exception& e) {
3327 broadcast(*pComm, rootRank, ptr(&readSuccess));
3336 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
3337 "Failed to read the Matrix Market sparse matrix file: "
3341 if (debug && myRank == rootRank) {
3342 cerr <<
"-- Successfully read the Matrix Market data" << endl;
3355 if (debug && myRank == rootRank) {
3356 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
3358 <<
"----- Dimensions before: "
3359 << dims[0] <<
" x " << dims[1]
3363 Tuple<global_ordinal_type, 2> updatedDims;
3364 if (myRank == rootRank) {
3371 std::max(dims[0], pAdder->getAdder()->numRows());
3372 updatedDims[1] = pAdder->getAdder()->numCols();
3374 broadcast(*pComm, rootRank, updatedDims);
3375 dims[0] = updatedDims[0];
3376 dims[1] = updatedDims[1];
3377 if (debug && myRank == rootRank) {
3378 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
3391 if (myRank == rootRank) {
3398 if (dims[0] < pAdder->getAdder()->numRows()) {
3402 broadcast(*pComm, 0, ptr(&dimsMatch));
3403 if (dimsMatch == 0) {
3410 Tuple<global_ordinal_type, 2> addersDims;
3411 if (myRank == rootRank) {
3412 addersDims[0] = pAdder->getAdder()->numRows();
3413 addersDims[1] = pAdder->getAdder()->numCols();
3415 broadcast(*pComm, 0, addersDims);
3416 TEUCHOS_TEST_FOR_EXCEPTION(
3417 dimsMatch == 0, std::runtime_error,
3418 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
3419 << dims[1] <<
", but the actual data says that the matrix is "
3420 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
3421 "data includes more rows than reported in the metadata. This "
3422 "is not allowed when parsing in strict mode. Parse the matrix in "
3423 "tolerant mode to ignore the metadata when it disagrees with the "
3428 if (debug && myRank == rootRank) {
3429 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3441 ArrayRCP<size_t> numEntriesPerRow;
3442 ArrayRCP<size_t> rowPtr;
3443 ArrayRCP<global_ordinal_type> colInd;
3444 ArrayRCP<scalar_type> values;
3449 int mergeAndConvertSucceeded = 1;
3450 std::ostringstream errMsg;
3452 if (myRank == rootRank) {
3454 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3465 const size_type numRows = dims[0];
3468 pAdder->getAdder()->merge();
3471 const std::vector<element_type>& entries =
3472 pAdder->getAdder()->getEntries();
3475 const size_t numEntries = (size_t)entries.size();
3478 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3479 <<
" rows and numEntries=" << numEntries
3480 <<
" entries." << endl;
3486 numEntriesPerRow = arcp<size_t>(numRows);
3487 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3488 rowPtr = arcp<size_t>(numRows + 1);
3489 std::fill(rowPtr.begin(), rowPtr.end(), 0);
3490 colInd = arcp<global_ordinal_type>(numEntries);
3491 values = arcp<scalar_type>(numEntries);
3498 for (curPos = 0; curPos < numEntries; ++curPos) {
3499 const element_type& curEntry = entries[curPos];
3501 TEUCHOS_TEST_FOR_EXCEPTION(
3502 curRow < prvRow, std::logic_error,
3503 "Row indices are out of order, even though they are supposed "
3504 "to be sorted. curRow = "
3505 << curRow <<
", prvRow = "
3506 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3507 "this bug to the Tpetra developers.");
3508 if (curRow > prvRow) {
3511 numEntriesPerRow[curRow]++;
3512 colInd[curPos] = curEntry.colIndex();
3513 values[curPos] = curEntry.value();
3518 rowPtr[row] = numEntriesPerRow[row - 1] + rowPtr[row - 1];
3521 catch (std::exception& e) {
3522 mergeAndConvertSucceeded = 0;
3523 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3528 if (debug && mergeAndConvertSucceeded) {
3530 const size_type numRows = dims[0];
3531 const size_type maxToDisplay = 100;
3533 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3534 << (numEntriesPerRow.size() - 1) <<
"] ";
3535 if (numRows > maxToDisplay) {
3536 cerr <<
"(only showing first and last few entries) ";
3540 if (numRows > maxToDisplay) {
3541 for (size_type k = 0; k < 2; ++k) {
3542 cerr << numEntriesPerRow[k] <<
" ";
3545 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
3546 cerr << numEntriesPerRow[k] <<
" ";
3549 for (size_type k = 0; k < numRows - 1; ++k) {
3550 cerr << numEntriesPerRow[k] <<
" ";
3553 cerr << numEntriesPerRow[numRows - 1];
3555 cerr <<
"]" << endl;
3557 cerr <<
"----- Proc 0: rowPtr ";
3558 if (numRows > maxToDisplay) {
3559 cerr <<
"(only showing first and last few entries) ";
3562 if (numRows > maxToDisplay) {
3563 for (size_type k = 0; k < 2; ++k) {
3564 cerr << rowPtr[k] <<
" ";
3567 for (size_type k = numRows - 2; k < numRows; ++k) {
3568 cerr << rowPtr[k] <<
" ";
3571 for (size_type k = 0; k < numRows; ++k) {
3572 cerr << rowPtr[k] <<
" ";
3575 cerr << rowPtr[numRows] <<
"]" << endl;
3577 cerr <<
"----- Proc 0: colInd = [";
3578 for (
size_t k = 0; k < rowPtr[numRows]; ++k) {
3579 cerr << colInd[k] <<
" ";
3581 cerr <<
"]" << endl;
3595 if (debug && myRank == rootRank) {
3596 cerr <<
"-- Verifying Maps" << endl;
3598 TEUCHOS_TEST_FOR_EXCEPTION(
3599 as<global_ordinal_type>(dims[0]) != rangeMap->getMaxAllGlobalIndex() + 1 - rangeMap->getIndexBase(),
3600 std::invalid_argument,
3601 "The range Map has " << rangeMap->getMaxAllGlobalIndex()
3602 <<
" max entry, but the matrix has a global number of rows " << dims[0]
3604 TEUCHOS_TEST_FOR_EXCEPTION(
3605 as<global_ordinal_type>(dims[1]) != domainMap->getMaxAllGlobalIndex() + 1 - domainMap->getIndexBase(),
3606 std::invalid_argument,
3607 "The domain Map has " << domainMap->getMaxAllGlobalIndex()
3608 <<
" max entry, but the matrix has a global number of columns "
3612 RCP<Teuchos::FancyOStream> err = debug ? Teuchos::getFancyOStream(Teuchos::rcpFromRef(cerr)) : null;
3614 RCP<const map_type> gatherRowMap = Details::computeGatherMap(rowMap, err, debug);
3615 ArrayView<const global_ordinal_type> myRows =
3616 gatherRowMap->getLocalElementList();
3617 const size_type myNumRows = myRows.size();
3620 ArrayRCP<size_t> gatherNumEntriesPerRow = arcp<size_t>(myNumRows);
3621 for (size_type i_ = 0; i_ < myNumRows; i_++) {
3622 gatherNumEntriesPerRow[i_] = numEntriesPerRow[myRows[i_] - indexBase];
3628 RCP<sparse_matrix_type> A_proc0 =
3630 if (myRank == rootRank) {
3632 cerr <<
"-- Proc 0: Filling gather matrix" << endl;
3635 cerr <<
"---- Rows: " << Teuchos::toString(myRows) << endl;
3639 for (size_type i_ = 0; i_ < myNumRows; ++i_) {
3640 size_type i = myRows[i_] - indexBase;
3642 const size_type curPos = as<size_type>(rowPtr[i]);
3644 ArrayView<global_ordinal_type> curColInd =
3645 colInd.view(curPos, curNumEntries);
3646 ArrayView<scalar_type> curValues =
3647 values.view(curPos, curNumEntries);
3650 for (size_type k = 0; k < curNumEntries; ++k) {
3651 curColInd[k] += indexBase;
3654 cerr <<
"------ Columns: " << Teuchos::toString(curColInd) << endl;
3655 cerr <<
"------ Values: " << Teuchos::toString(curValues) << endl;
3658 if (curNumEntries > 0) {
3659 A_proc0->insertGlobalValues(myRows[i_], curColInd, curValues);
3665 numEntriesPerRow = null;
3671 RCP<sparse_matrix_type> A;
3673 export_type exp(gatherRowMap, rowMap);
3680 mv_type_go target_nnzPerRow(rowMap, 1);
3681 mv_type_go source_nnzPerRow(gatherRowMap, 1);
3682 Teuchos::ArrayRCP<GO> srcData = source_nnzPerRow.getDataNonConst(0);
3683 for (
int i = 0; i < myNumRows; i++)
3684 srcData[i] = gatherNumEntriesPerRow[i];
3685 srcData = Teuchos::null;
3686 target_nnzPerRow.doExport(source_nnzPerRow, exp,
Tpetra::INSERT);
3687 Teuchos::ArrayRCP<GO> targetData = target_nnzPerRow.getDataNonConst(0);
3688 ArrayRCP<size_t> targetData_size_t = arcp<size_t>(targetData.size());
3689 for (
int i = 0; i < targetData.size(); i++)
3690 targetData_size_t[i] = targetData[i];
3692 if (colMap.is_null()) {
3697 A->doExport(*A_proc0, exp,
INSERT);
3698 if (callFillComplete) {
3699 A->fillComplete(domainMap, rangeMap);
3711 if (callFillComplete) {
3712 const int numProcs = pComm->getSize();
3714 if (extraDebug && debug) {
3715 const global_size_t globalNumRows = rangeMap->getGlobalNumElements();
3716 const global_size_t globalNumCols = domainMap->getGlobalNumElements();
3717 if (myRank == rootRank) {
3718 cerr <<
"-- Matrix is "
3719 << globalNumRows <<
" x " << globalNumCols
3720 <<
" with " << A->getGlobalNumEntries()
3721 <<
" entries, and index base "
3722 << A->getIndexBase() <<
"." << endl;
3725 for (
int p = 0; p < numProcs; ++p) {
3727 cerr <<
"-- Proc " << p <<
" owns "
3728 << A->getLocalNumCols() <<
" columns, and "
3729 << A->getLocalNumEntries() <<
" entries." << endl;
3736 if (debug && myRank == rootRank) {
3737 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3772 static Teuchos::RCP<multivector_type>
3775 Teuchos::RCP<const map_type>& map,
3776 const bool tolerant =
false,
3777 const bool debug =
false,
3778 const bool binary =
false) {
3781 return readDense(in, comm, map, tolerant, debug, binary);
3796 const std::string& filename,
const bool safe =
true,
3797 std::ios_base::openmode mode = std::ios_base::in) {
3802 int all_should_stop =
false;
3805 if (comm->getRank() == 0) {
3806 in.open(filename, mode);
3807 all_should_stop = !in && safe;
3811 if (comm) Teuchos::broadcast(*comm, 0, &all_should_stop);
3813 TEUCHOS_TEST_FOR_EXCEPTION(
3816 "Could not open input file '" + filename +
"' on root rank 0.");
3850 static Teuchos::RCP<vector_type>
3853 Teuchos::RCP<const map_type>& map,
3854 const bool tolerant =
false,
3855 const bool debug =
false) {
3858 return readVector(in, comm, map, tolerant, debug);
3929 static Teuchos::RCP<multivector_type>
3932 Teuchos::RCP<const map_type>& map,
3933 const bool tolerant =
false,
3934 const bool debug =
false,
3935 const bool binary =
false) {
3936 Teuchos::RCP<Teuchos::FancyOStream> err =
3937 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3938 return readDenseImpl<scalar_type>(in, comm, map, err, tolerant, debug, binary);
3942 static Teuchos::RCP<vector_type>
3945 Teuchos::RCP<const map_type>& map,
3946 const bool tolerant =
false,
3947 const bool debug =
false) {
3948 Teuchos::RCP<Teuchos::FancyOStream> err =
3949 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3950 return readVectorImpl<scalar_type>(in, comm, map, err, tolerant, debug);
3974 static Teuchos::RCP<const map_type>
3977 const bool tolerant =
false,
3978 const bool debug =
false,
3979 const bool binary =
false) {
3982 return readMap(in, comm, tolerant, debug, binary);
3986 template <
class MultiVectorScalarType>
3991 readDenseImpl(std::istream& in,
3993 Teuchos::RCP<const map_type>& map,
3994 const Teuchos::RCP<Teuchos::FancyOStream>& err,
3995 const bool tolerant =
false,
3996 const bool debug =
false,
3997 const bool binary =
false) {
3999 using Teuchos::ArrayRCP;
4001 using Teuchos::broadcast;
4002 using Teuchos::outArg;
4004 using Teuchos::Tuple;
4005 using Teuchos::MatrixMarket::Banner;
4006 using Teuchos::MatrixMarket::checkCommentLine;
4007 typedef MultiVectorScalarType ST;
4011 typedef Teuchos::ScalarTraits<ST> STS;
4012 typedef typename STS::magnitudeType MT;
4013 typedef Teuchos::ScalarTraits<MT> STM;
4018 const int myRank = comm->getRank();
4020 if (!err.is_null()) {
4024 *err << myRank <<
": readDenseImpl" << endl;
4026 if (!err.is_null()) {
4061 size_t lineNumber = 1;
4064 std::ostringstream exMsg;
4065 int localBannerReadSuccess = 1;
4066 int localDimsReadSuccess = 1;
4072 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
4078 RCP<const Banner> pBanner;
4080 pBanner = readBanner(in, lineNumber, tolerant, debug);
4081 }
catch (std::exception& e) {
4083 localBannerReadSuccess = 0;
4086 if (localBannerReadSuccess) {
4087 if (pBanner->matrixType() !=
"array") {
4088 exMsg <<
"The Matrix Market file does not contain dense matrix "
4089 "data. Its banner (first) line says that its matrix type is \""
4090 << pBanner->matrixType() <<
"\", rather that the required "
4092 localBannerReadSuccess = 0;
4093 }
else if (pBanner->dataType() ==
"pattern") {
4094 exMsg <<
"The Matrix Market file's banner (first) "
4095 "line claims that the matrix's data type is \"pattern\". This does "
4096 "not make sense for a dense matrix, yet the file reports the matrix "
4097 "as dense. The only valid data types for a dense matrix are "
4098 "\"real\", \"complex\", and \"integer\".";
4099 localBannerReadSuccess = 0;
4103 dims[2] = encodeDataType(pBanner->dataType());
4109 if (localBannerReadSuccess) {
4111 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
4120 bool commentLine =
true;
4122 while (commentLine) {
4125 if (in.eof() || in.fail()) {
4126 exMsg <<
"Unable to get array dimensions line (at all) from line "
4127 << lineNumber <<
" of input stream. The input stream "
4128 <<
"claims that it is "
4129 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4130 localDimsReadSuccess = 0;
4133 if (getline(in, line)) {
4140 size_t start = 0, size = 0;
4141 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
4148 std::istringstream istr(line);
4152 if (istr.eof() || istr.fail()) {
4153 exMsg <<
"Unable to read any data from line " << lineNumber
4154 <<
" of input; the line should contain the matrix dimensions "
4155 <<
"\"<numRows> <numCols>\".";
4156 localDimsReadSuccess = 0;
4161 exMsg <<
"Failed to get number of rows from line "
4162 << lineNumber <<
" of input; the line should contains the "
4163 <<
"matrix dimensions \"<numRows> <numCols>\".";
4164 localDimsReadSuccess = 0;
4166 dims[0] = theNumRows;
4168 exMsg <<
"No more data after number of rows on line "
4169 << lineNumber <<
" of input; the line should contain the "
4170 <<
"matrix dimensions \"<numRows> <numCols>\".";
4171 localDimsReadSuccess = 0;
4176 exMsg <<
"Failed to get number of columns from line "
4177 << lineNumber <<
" of input; the line should contain "
4178 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4179 localDimsReadSuccess = 0;
4181 dims[1] = theNumCols;
4190 in.read(reinterpret_cast<char*>(&numRows),
sizeof(numRows));
4191 in.read(reinterpret_cast<char*>(&numCols),
sizeof(numCols));
4192 dims[0] = Teuchos::as<GO>(numRows);
4193 dims[1] = Teuchos::as<GO>(numCols);
4194 if ((
typeid(ST) ==
typeid(double)) || Teuchos::ScalarTraits<ST>::isOrdinal) {
4196 }
else if (Teuchos::ScalarTraits<ST>::isComplex) {
4199 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
4200 "Unrecognized Matrix Market data type. "
4201 "We should never get here. "
4202 "Please report this bug to the Tpetra developers.");
4204 localDimsReadSuccess =
true;
4205 localDimsReadSuccess =
true;
4212 Tuple<GO, 5> bannerDimsReadResult;
4214 bannerDimsReadResult[0] = dims[0];
4215 bannerDimsReadResult[1] = dims[1];
4216 bannerDimsReadResult[2] = dims[2];
4217 bannerDimsReadResult[3] = localBannerReadSuccess;
4218 bannerDimsReadResult[4] = localDimsReadSuccess;
4222 broadcast(*comm, 0, bannerDimsReadResult);
4224 TEUCHOS_TEST_FOR_EXCEPTION(
4225 bannerDimsReadResult[3] == 0, std::runtime_error,
4226 "Failed to read banner line: " << exMsg.str());
4227 TEUCHOS_TEST_FOR_EXCEPTION(
4228 bannerDimsReadResult[4] == 0, std::runtime_error,
4229 "Failed to read matrix dimensions line: " << exMsg.str());
4231 dims[0] = bannerDimsReadResult[0];
4232 dims[1] = bannerDimsReadResult[1];
4233 dims[2] = bannerDimsReadResult[2];
4238 const size_t numCols =
static_cast<size_t>(dims[1]);
4243 RCP<const map_type> proc0Map;
4244 if (map.is_null()) {
4248 map = createUniformContigMapWithNode<LO, GO, NT>(numRows, comm);
4249 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4251 proc0Map = createContigMapWithNode<LO, GO, NT>(numRows, localNumRows,
4254 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
4258 RCP<MV> X = createMultiVector<ST, LO, GO, NT>(proc0Map, numCols);
4264 int localReadDataSuccess = 1;
4269 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4274 TEUCHOS_TEST_FOR_EXCEPTION(
4275 !X->isConstantStride(), std::logic_error,
4276 "Can't get a 1-D view of the entries of the MultiVector X on "
4277 "Process 0, because the stride between the columns of X is not "
4278 "constant. This shouldn't happen because we just created X and "
4279 "haven't filled it in yet. Please report this bug to the Tpetra "
4286 ArrayRCP<ST> X_view = X->get1dViewNonConst();
4287 TEUCHOS_TEST_FOR_EXCEPTION(
4288 as<global_size_t>(X_view.size()) < numRows * numCols,
4290 "The view of X has size " << X_view.size() <<
" which is not enough to "
4291 "accommodate the expected number of entries numRows*numCols = "
4292 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
4293 "Please report this bug to the Tpetra developers.");
4294 const size_t stride = X->getStride();
4301 const bool isComplex = (dims[2] == 1);
4302 size_type count = 0, curRow = 0, curCol = 0;
4305 while (getline(in, line)) {
4309 size_t start = 0, size = 0;
4310 const bool commentLine =
4311 checkCommentLine(line, start, size, lineNumber, tolerant);
4318 if (count >= X_view.size()) {
4322 TEUCHOS_TEST_FOR_EXCEPTION(
4323 count >= X_view.size(),
4325 "The Matrix Market input stream has more data in it than "
4326 "its metadata reported. Current line number is "
4327 << lineNumber <<
".");
4336 const size_t pos = line.substr(start, size).find(
':');
4337 if (pos != std::string::npos) {
4341 std::istringstream istr(line.substr(start, size));
4345 if (istr.eof() || istr.fail()) {
4352 TEUCHOS_TEST_FOR_EXCEPTION(
4353 !tolerant && (istr.eof() || istr.fail()),
4355 "Line " << lineNumber <<
" of the Matrix Market file is "
4356 "empty, or we cannot read from it for some other reason.");
4359 ST val = STS::zero();
4362 MT real = STM::zero(), imag = STM::zero();
4379 TEUCHOS_TEST_FOR_EXCEPTION(
4380 !tolerant && istr.eof(), std::runtime_error,
4381 "Failed to get the real part of a complex-valued matrix "
4383 << lineNumber <<
" of the Matrix Market "
4389 }
else if (istr.eof()) {
4390 TEUCHOS_TEST_FOR_EXCEPTION(
4391 !tolerant && istr.eof(), std::runtime_error,
4392 "Missing imaginary part of a complex-valued matrix entry "
4394 << lineNumber <<
" of the Matrix Market file.");
4400 TEUCHOS_TEST_FOR_EXCEPTION(
4401 !tolerant && istr.fail(), std::runtime_error,
4402 "Failed to get the imaginary part of a complex-valued "
4403 "matrix entry from line "
4404 << lineNumber <<
" of the "
4405 "Matrix Market file.");
4412 TEUCHOS_TEST_FOR_EXCEPTION(
4413 !tolerant && istr.fail(), std::runtime_error,
4414 "Failed to get a real-valued matrix entry from line "
4415 << lineNumber <<
" of the Matrix Market file.");
4418 if (istr.fail() && tolerant) {
4424 TEUCHOS_TEST_FOR_EXCEPTION(
4425 !tolerant && istr.fail(), std::runtime_error,
4426 "Failed to read matrix data from line " << lineNumber
4427 <<
" of the Matrix Market file.");
4430 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
4432 curRow = count % numRows;
4433 curCol = count / numRows;
4434 X_view[curRow + curCol * stride] = val;
4439 TEUCHOS_TEST_FOR_EXCEPTION(
4440 !tolerant && static_cast<global_size_t>(count) < numRows * numCols,
4442 "The Matrix Market metadata reports that the dense matrix is "
4443 << numRows <<
" x " << numCols <<
", and thus has "
4444 << numRows * numCols <<
" total entries, but we only found " << count
4445 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4446 }
catch (std::exception& e) {
4448 localReadDataSuccess = 0;
4453 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4458 TEUCHOS_TEST_FOR_EXCEPTION(
4459 !X->isConstantStride(), std::logic_error,
4460 "Can't get a 1-D view of the entries of the MultiVector X on "
4461 "Process 0, because the stride between the columns of X is not "
4462 "constant. This shouldn't happen because we just created X and "
4463 "haven't filled it in yet. Please report this bug to the Tpetra "
4470 auto X_view = X->getLocalViewHost(Access::OverwriteAll);
4472 TEUCHOS_TEST_FOR_EXCEPTION(
4473 as<global_size_t>(X_view.extent(0)) < numRows,
4475 "The view of X has " << X_view.extent(0) <<
" rows which is not enough to "
4476 "accommodate the expected number of entries numRows = "
4478 "Please report this bug to the Tpetra developers.");
4479 TEUCHOS_TEST_FOR_EXCEPTION(
4480 as<global_size_t>(X_view.extent(1)) < numCols,
4482 "The view of X has " << X_view.extent(1) <<
" colums which is not enough to "
4483 "accommodate the expected number of entries numRows = "
4485 "Please report this bug to the Tpetra developers.");
4487 for (
size_t curRow = 0; curRow < numRows; ++curRow) {
4488 for (
size_t curCol = 0; curCol < numCols; ++curCol) {
4489 if (Teuchos::ScalarTraits<ST>::isOrdinal) {
4491 in.read(reinterpret_cast<char*>(&val),
sizeof(val));
4492 X_view(curRow, curCol) = val;
4495 in.read(reinterpret_cast<char*>(&val),
sizeof(val));
4496 X_view(curRow, curCol) = val;
4504 *err << myRank <<
": readDenseImpl: done reading data" << endl;
4508 int globalReadDataSuccess = localReadDataSuccess;
4509 broadcast(*comm, 0, outArg(globalReadDataSuccess));
4510 TEUCHOS_TEST_FOR_EXCEPTION(
4511 globalReadDataSuccess == 0, std::runtime_error,
4512 "Failed to read the multivector's data: " << exMsg.str());
4517 if (comm->getSize() == 1 && map.is_null()) {
4519 if (!err.is_null()) {
4523 *err << myRank <<
": readDenseImpl: done" << endl;
4525 if (!err.is_null()) {
4532 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
4536 RCP<MV> Y = createMultiVector<ST, LO, GO, NT>(map, numCols);
4539 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
4545 Export<LO, GO, NT> exporter(proc0Map, map, err);
4548 *err << myRank <<
": readDenseImpl: Exporting" << endl;
4551 Y->doExport(*X, exporter,
INSERT);
4553 if (!err.is_null()) {
4557 *err << myRank <<
": readDenseImpl: done" << endl;
4559 if (!err.is_null()) {
4567 template <
class VectorScalarType>
4572 readVectorImpl(std::istream& in,
4574 Teuchos::RCP<const map_type>& map,
4575 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4576 const bool tolerant =
false,
4577 const bool debug =
false) {
4580 using Teuchos::broadcast;
4581 using Teuchos::outArg;
4583 using Teuchos::Tuple;
4584 using Teuchos::MatrixMarket::Banner;
4585 using Teuchos::MatrixMarket::checkCommentLine;
4586 typedef VectorScalarType ST;
4590 typedef Teuchos::ScalarTraits<ST> STS;
4591 typedef typename STS::magnitudeType MT;
4592 typedef Teuchos::ScalarTraits<MT> STM;
4597 const int myRank = comm->getRank();
4599 if (!err.is_null()) {
4603 *err << myRank <<
": readVectorImpl" << endl;
4605 if (!err.is_null()) {
4639 size_t lineNumber = 1;
4642 std::ostringstream exMsg;
4643 int localBannerReadSuccess = 1;
4644 int localDimsReadSuccess = 1;
4649 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
4655 RCP<const Banner> pBanner;
4657 pBanner = readBanner(in, lineNumber, tolerant, debug);
4658 }
catch (std::exception& e) {
4660 localBannerReadSuccess = 0;
4663 if (localBannerReadSuccess) {
4664 if (pBanner->matrixType() !=
"array") {
4665 exMsg <<
"The Matrix Market file does not contain dense matrix "
4666 "data. Its banner (first) line says that its matrix type is \""
4667 << pBanner->matrixType() <<
"\", rather that the required "
4669 localBannerReadSuccess = 0;
4670 }
else if (pBanner->dataType() ==
"pattern") {
4671 exMsg <<
"The Matrix Market file's banner (first) "
4672 "line claims that the matrix's data type is \"pattern\". This does "
4673 "not make sense for a dense matrix, yet the file reports the matrix "
4674 "as dense. The only valid data types for a dense matrix are "
4675 "\"real\", \"complex\", and \"integer\".";
4676 localBannerReadSuccess = 0;
4680 dims[2] = encodeDataType(pBanner->dataType());
4686 if (localBannerReadSuccess) {
4688 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
4697 bool commentLine =
true;
4699 while (commentLine) {
4702 if (in.eof() || in.fail()) {
4703 exMsg <<
"Unable to get array dimensions line (at all) from line "
4704 << lineNumber <<
" of input stream. The input stream "
4705 <<
"claims that it is "
4706 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4707 localDimsReadSuccess = 0;
4710 if (getline(in, line)) {
4717 size_t start = 0, size = 0;
4718 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
4725 std::istringstream istr(line);
4729 if (istr.eof() || istr.fail()) {
4730 exMsg <<
"Unable to read any data from line " << lineNumber
4731 <<
" of input; the line should contain the matrix dimensions "
4732 <<
"\"<numRows> <numCols>\".";
4733 localDimsReadSuccess = 0;
4738 exMsg <<
"Failed to get number of rows from line "
4739 << lineNumber <<
" of input; the line should contains the "
4740 <<
"matrix dimensions \"<numRows> <numCols>\".";
4741 localDimsReadSuccess = 0;
4743 dims[0] = theNumRows;
4745 exMsg <<
"No more data after number of rows on line "
4746 << lineNumber <<
" of input; the line should contain the "
4747 <<
"matrix dimensions \"<numRows> <numCols>\".";
4748 localDimsReadSuccess = 0;
4753 exMsg <<
"Failed to get number of columns from line "
4754 << lineNumber <<
" of input; the line should contain "
4755 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4756 localDimsReadSuccess = 0;
4758 dims[1] = theNumCols;
4768 exMsg <<
"File does not contain a 1D Vector";
4769 localDimsReadSuccess = 0;
4775 Tuple<GO, 5> bannerDimsReadResult;
4777 bannerDimsReadResult[0] = dims[0];
4778 bannerDimsReadResult[1] = dims[1];
4779 bannerDimsReadResult[2] = dims[2];
4780 bannerDimsReadResult[3] = localBannerReadSuccess;
4781 bannerDimsReadResult[4] = localDimsReadSuccess;
4786 broadcast(*comm, 0, bannerDimsReadResult);
4788 TEUCHOS_TEST_FOR_EXCEPTION(
4789 bannerDimsReadResult[3] == 0, std::runtime_error,
4790 "Failed to read banner line: " << exMsg.str());
4791 TEUCHOS_TEST_FOR_EXCEPTION(
4792 bannerDimsReadResult[4] == 0, std::runtime_error,
4793 "Failed to read matrix dimensions line: " << exMsg.str());
4795 dims[0] = bannerDimsReadResult[0];
4796 dims[1] = bannerDimsReadResult[1];
4797 dims[2] = bannerDimsReadResult[2];
4802 const size_t numCols =
static_cast<size_t>(dims[1]);
4807 RCP<const map_type> proc0Map;
4808 if (map.is_null()) {
4812 map = createUniformContigMapWithNode<LO, GO, NT>(numRows, comm);
4813 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4815 proc0Map = createContigMapWithNode<LO, GO, NT>(numRows, localNumRows,
4818 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
4822 RCP<MV> X = createVector<ST, LO, GO, NT>(proc0Map);
4828 int localReadDataSuccess = 1;
4832 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
4837 TEUCHOS_TEST_FOR_EXCEPTION(
4838 !X->isConstantStride(), std::logic_error,
4839 "Can't get a 1-D view of the entries of the MultiVector X on "
4840 "Process 0, because the stride between the columns of X is not "
4841 "constant. This shouldn't happen because we just created X and "
4842 "haven't filled it in yet. Please report this bug to the Tpetra "
4849 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst();
4850 TEUCHOS_TEST_FOR_EXCEPTION(
4851 as<global_size_t>(X_view.size()) < numRows * numCols,
4853 "The view of X has size " << X_view <<
" which is not enough to "
4854 "accommodate the expected number of entries numRows*numCols = "
4855 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
4856 "Please report this bug to the Tpetra developers.");
4857 const size_t stride = X->getStride();
4864 const bool isComplex = (dims[2] == 1);
4865 size_type count = 0, curRow = 0, curCol = 0;
4868 while (getline(in, line)) {
4872 size_t start = 0, size = 0;
4873 const bool commentLine =
4874 checkCommentLine(line, start, size, lineNumber, tolerant);
4881 if (count >= X_view.size()) {
4885 TEUCHOS_TEST_FOR_EXCEPTION(
4886 count >= X_view.size(),
4888 "The Matrix Market input stream has more data in it than "
4889 "its metadata reported. Current line number is "
4890 << lineNumber <<
".");
4899 const size_t pos = line.substr(start, size).find(
':');
4900 if (pos != std::string::npos) {
4904 std::istringstream istr(line.substr(start, size));
4908 if (istr.eof() || istr.fail()) {
4915 TEUCHOS_TEST_FOR_EXCEPTION(
4916 !tolerant && (istr.eof() || istr.fail()),
4918 "Line " << lineNumber <<
" of the Matrix Market file is "
4919 "empty, or we cannot read from it for some other reason.");
4922 ST val = STS::zero();
4925 MT real = STM::zero(), imag = STM::zero();
4942 TEUCHOS_TEST_FOR_EXCEPTION(
4943 !tolerant && istr.eof(), std::runtime_error,
4944 "Failed to get the real part of a complex-valued matrix "
4946 << lineNumber <<
" of the Matrix Market "
4952 }
else if (istr.eof()) {
4953 TEUCHOS_TEST_FOR_EXCEPTION(
4954 !tolerant && istr.eof(), std::runtime_error,
4955 "Missing imaginary part of a complex-valued matrix entry "
4957 << lineNumber <<
" of the Matrix Market file.");
4963 TEUCHOS_TEST_FOR_EXCEPTION(
4964 !tolerant && istr.fail(), std::runtime_error,
4965 "Failed to get the imaginary part of a complex-valued "
4966 "matrix entry from line "
4967 << lineNumber <<
" of the "
4968 "Matrix Market file.");
4975 TEUCHOS_TEST_FOR_EXCEPTION(
4976 !tolerant && istr.fail(), std::runtime_error,
4977 "Failed to get a real-valued matrix entry from line "
4978 << lineNumber <<
" of the Matrix Market file.");
4981 if (istr.fail() && tolerant) {
4987 TEUCHOS_TEST_FOR_EXCEPTION(
4988 !tolerant && istr.fail(), std::runtime_error,
4989 "Failed to read matrix data from line " << lineNumber
4990 <<
" of the Matrix Market file.");
4993 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
4995 curRow = count % numRows;
4996 curCol = count / numRows;
4997 X_view[curRow + curCol * stride] = val;
5002 TEUCHOS_TEST_FOR_EXCEPTION(
5003 !tolerant && static_cast<global_size_t>(count) < numRows * numCols,
5005 "The Matrix Market metadata reports that the dense matrix is "
5006 << numRows <<
" x " << numCols <<
", and thus has "
5007 << numRows * numCols <<
" total entries, but we only found " << count
5008 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
5009 }
catch (std::exception& e) {
5011 localReadDataSuccess = 0;
5016 *err << myRank <<
": readVectorImpl: done reading data" << endl;
5020 int globalReadDataSuccess = localReadDataSuccess;
5021 broadcast(*comm, 0, outArg(globalReadDataSuccess));
5022 TEUCHOS_TEST_FOR_EXCEPTION(
5023 globalReadDataSuccess == 0, std::runtime_error,
5024 "Failed to read the multivector's data: " << exMsg.str());
5029 if (comm->getSize() == 1 && map.is_null()) {
5031 if (!err.is_null()) {
5035 *err << myRank <<
": readVectorImpl: done" << endl;
5037 if (!err.is_null()) {
5044 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
5048 RCP<MV> Y = createVector<ST, LO, GO, NT>(map);
5051 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
5057 Export<LO, GO, NT> exporter(proc0Map, map, err);
5060 *err << myRank <<
": readVectorImpl: Exporting" << endl;
5063 Y->doExport(*X, exporter,
INSERT);
5065 if (!err.is_null()) {
5069 *err << myRank <<
": readVectorImpl: done" << endl;
5071 if (!err.is_null()) {
5100 static Teuchos::RCP<const map_type>
5103 const bool tolerant =
false,
5104 const bool debug =
false,
5105 const bool binary =
false) {
5106 Teuchos::RCP<Teuchos::FancyOStream> err =
5107 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
5108 return readMap(in, comm, err, tolerant, debug, binary);
5137 static Teuchos::RCP<const map_type>
5140 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5141 const bool tolerant =
false,
5142 const bool debug =
false,
5143 const bool binary =
false) {
5145 using Teuchos::arcp;
5146 using Teuchos::Array;
5147 using Teuchos::ArrayRCP;
5149 using Teuchos::broadcast;
5150 using Teuchos::Comm;
5151 using Teuchos::CommRequest;
5152 using Teuchos::inOutArg;
5153 using Teuchos::ireceive;
5154 using Teuchos::isend;
5155 using Teuchos::outArg;
5157 using Teuchos::receive;
5158 using Teuchos::REDUCE_MIN;
5159 using Teuchos::reduceAll;
5160 using Teuchos::SerialComm;
5161 using Teuchos::toString;
5162 using Teuchos::wait;
5164 typedef ptrdiff_t int_type;
5170 const int numProcs = comm->getSize();
5171 const int myRank = comm->getRank();
5173 if (err.is_null()) {
5177 std::ostringstream os;
5178 os << myRank <<
": readMap: " << endl;
5181 if (err.is_null()) {
5187 const int sizeTag = 1339;
5189 const int dataTag = 1340;
5195 RCP<CommRequest<int>> sizeReq;
5196 RCP<CommRequest<int>> dataReq;
5201 ArrayRCP<int_type> numGidsToRecv(1);
5202 numGidsToRecv[0] = 0;
5204 sizeReq = ireceive<int, int_type>(numGidsToRecv, 0, sizeTag, *comm);
5207 int readSuccess = 1;
5208 std::ostringstream exMsg;
5217 RCP<const Comm<int>> proc0Comm(
new SerialComm<int>());
5219 RCP<const map_type> dataMap;
5223 data = readDenseImpl<GO>(in, proc0Comm, dataMap, err, tolerant, debug, binary);
5225 if (data.is_null()) {
5227 exMsg <<
"readDenseImpl() returned null." << endl;
5229 }
catch (std::exception& e) {
5231 exMsg << e.what() << endl;
5237 std::map<int, Array<GO>> pid2gids;
5242 int_type globalNumGIDs = 0;
5252 if (myRank == 0 && readSuccess == 1) {
5253 if (data->getNumVectors() == 2) {
5254 ArrayRCP<const GO> GIDs = data->getData(0);
5255 ArrayRCP<const GO> PIDs = data->getData(1);
5256 globalNumGIDs = GIDs.size();
5260 if (globalNumGIDs > 0) {
5261 const int pid =
static_cast<int>(PIDs[0]);
5263 if (pid < 0 || pid >= numProcs) {
5265 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5266 <<
"Encountered invalid PID " << pid <<
"." << endl;
5268 const GO gid = GIDs[0];
5269 pid2gids[pid].push_back(gid);
5273 if (readSuccess == 1) {
5276 for (size_type k = 1; k < globalNumGIDs; ++k) {
5277 const int pid =
static_cast<int>(PIDs[k]);
5278 if (pid < 0 || pid >= numProcs) {
5280 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5281 <<
"Encountered invalid PID " << pid <<
"." << endl;
5283 const int_type gid = GIDs[k];
5284 pid2gids[pid].push_back(gid);
5285 if (gid < indexBase) {
5291 }
else if (data->getNumVectors() == 1) {
5292 if (data->getGlobalLength() % 2 !=
static_cast<GST
>(0)) {
5294 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
5295 "wrong format (for Map format 2.0). The global number of rows "
5296 "in the MultiVector must be even (divisible by 2)."
5299 ArrayRCP<const GO> theData = data->getData(0);
5300 globalNumGIDs =
static_cast<GO
>(data->getGlobalLength()) /
5305 if (globalNumGIDs > 0) {
5306 const int pid =
static_cast<int>(theData[1]);
5307 if (pid < 0 || pid >= numProcs) {
5309 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5310 <<
"Encountered invalid PID " << pid <<
"." << endl;
5312 const GO gid = theData[0];
5313 pid2gids[pid].push_back(gid);
5319 for (int_type k = 1; k < globalNumGIDs; ++k) {
5320 const int pid =
static_cast<int>(theData[2 * k + 1]);
5321 if (pid < 0 || pid >= numProcs) {
5323 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5324 <<
"Encountered invalid PID " << pid <<
"." << endl;
5326 const GO gid = theData[2 * k];
5327 pid2gids[pid].push_back(gid);
5328 if (gid < indexBase) {
5336 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
5337 "either 1 column (for the new Map format 2.0) or 2 columns (for "
5338 "the old Map format 1.0).";
5345 int_type readResults[3];
5346 readResults[0] =
static_cast<int_type
>(indexBase);
5347 readResults[1] =
static_cast<int_type
>(globalNumGIDs);
5348 readResults[2] =
static_cast<int_type
>(readSuccess);
5349 broadcast<int, int_type>(*comm, 0, 3, readResults);
5351 indexBase =
static_cast<GO
>(readResults[0]);
5352 globalNumGIDs =
static_cast<int_type
>(readResults[1]);
5353 readSuccess =
static_cast<int>(readResults[2]);
5359 TEUCHOS_TEST_FOR_EXCEPTION(
5360 readSuccess != 1, std::runtime_error,
5361 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
5362 "following exception message: "
5367 for (
int p = 1; p < numProcs; ++p) {
5368 ArrayRCP<int_type> numGidsToSend(1);
5370 auto it = pid2gids.find(p);
5371 if (it == pid2gids.end()) {
5372 numGidsToSend[0] = 0;
5374 numGidsToSend[0] = it->second.size();
5376 sizeReq = isend<int, int_type>(numGidsToSend, p, sizeTag, *comm);
5377 wait<int>(*comm, outArg(sizeReq));
5381 wait<int>(*comm, outArg(sizeReq));
5386 ArrayRCP<GO> myGids;
5387 int_type myNumGids = 0;
5389 GO* myGidsRaw = NULL;
5391 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(0);
5392 if (it != pid2gids.end()) {
5393 myGidsRaw = it->second.getRawPtr();
5394 myNumGids = it->second.size();
5396 myGids = arcp<GO>(myGidsRaw, 0, myNumGids,
false);
5399 myNumGids = numGidsToRecv[0];
5400 myGids = arcp<GO>(myNumGids);
5407 if (myNumGids > 0) {
5408 dataReq = ireceive<int, GO>(myGids, 0, dataTag, *comm);
5412 for (
int p = 1; p < numProcs; ++p) {
5414 ArrayRCP<GO> sendGids;
5415 GO* sendGidsRaw = NULL;
5416 int_type numSendGids = 0;
5418 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(p);
5419 if (it != pid2gids.end()) {
5420 numSendGids = it->second.size();
5421 sendGidsRaw = it->second.getRawPtr();
5422 sendGids = arcp<GO>(sendGidsRaw, 0, numSendGids,
false);
5425 if (numSendGids > 0) {
5426 dataReq = isend<int, GO>(sendGids, p, dataTag, *comm);
5428 wait<int>(*comm, outArg(dataReq));
5429 }
else if (myRank == p) {
5431 wait<int>(*comm, outArg(dataReq));
5436 std::ostringstream os;
5437 os << myRank <<
": readMap: creating Map" << endl;
5440 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid();
5441 RCP<const map_type> newMap;
5448 std::ostringstream errStrm;
5450 newMap = rcp(
new map_type(INVALID, myGids(), indexBase, comm));
5451 }
catch (std::exception& e) {
5453 errStrm <<
"Process " << comm->getRank() <<
" threw an exception: "
5454 << e.what() << std::endl;
5457 errStrm <<
"Process " << comm->getRank() <<
" threw an exception "
5458 "not a subclass of std::exception"
5461 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MIN,
5462 lclSuccess, Teuchos::outArg(gblSuccess));
5463 if (gblSuccess != 1) {
5466 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
5468 if (err.is_null()) {
5472 std::ostringstream os;
5473 os << myRank <<
": readMap: done" << endl;
5476 if (err.is_null()) {
5494 encodeDataType(
const std::string& dataType) {
5495 if (dataType ==
"real" || dataType ==
"integer") {
5497 }
else if (dataType ==
"complex") {
5499 }
else if (dataType ==
"pattern") {
5505 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
5506 "Unrecognized Matrix Market data type \"" << dataType
5507 <<
"\". We should never get here. "
5508 "Please report this bug to the Tpetra developers.");
5542 static Teuchos::RCP<sparse_matrix_type>
5544 const std::string& filename_suffix,
5545 const Teuchos::RCP<const map_type>& rowMap,
5546 Teuchos::RCP<const map_type>& colMap,
5547 const Teuchos::RCP<const map_type>& domainMap,
5548 const Teuchos::RCP<const map_type>& rangeMap,
5549 const bool callFillComplete =
true,
5550 const bool tolerant =
false,
5551 const int ranksToReadAtOnce = 8,
5552 const bool debug =
false) {
5556 using STS =
typename Teuchos::ScalarTraits<ST>;
5557 using Teuchos::arcp;
5558 using Teuchos::ArrayRCP;
5566 TEUCHOS_TEST_FOR_EXCEPTION(
5567 rowMap.is_null(), std::invalid_argument,
5568 "Row Map must be nonnull.");
5569 Teuchos::RCP<const Teuchos::Comm<int>> comm = rowMap->getComm();
5570 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
5571 "The input row map's communicator (Teuchos::Comm object) is null.");
5572 TEUCHOS_TEST_FOR_EXCEPTION(
5573 rangeMap.is_null(), std::invalid_argument,
5574 "Range Map must be nonnull.");
5575 TEUCHOS_TEST_FOR_EXCEPTION(
5576 domainMap.is_null(), std::invalid_argument,
5577 "Domain Map must be nonnull.");
5578 TEUCHOS_TEST_FOR_EXCEPTION(
5579 domainMap->getComm().getRawPtr() != comm.getRawPtr(),
5580 std::invalid_argument,
5581 "The specified domain Map's communicator (domainMap->getComm())"
5582 "differs from row Map's communicator");
5583 TEUCHOS_TEST_FOR_EXCEPTION(
5584 rangeMap->getComm().getRawPtr() != comm.getRawPtr(),
5585 std::invalid_argument,
5586 "The specified range Map's communicator (rangeMap->getComm())"
5587 "differs from row Map's communicator");
5590 const int myRank = comm->getRank();
5591 const int numProc = comm->getSize();
5592 std::string filename = filename_prefix + std::to_string(myRank) + filename_suffix;
5595 int rank_limit = std::min(std::max(ranksToReadAtOnce, 1), numProc);
5598 ArrayRCP<size_t> numEntriesPerRow;
5599 ArrayRCP<size_t> rowPtr;
5600 ArrayRCP<global_ordinal_type> colInd;
5601 ArrayRCP<scalar_type> values;
5602 std::ostringstream errMsg;
5609 bool success =
true;
5610 int bannerIsCorrect = 1, readSuccess = 1;
5611 LO numRows, numCols, numNonzeros;
5612 for (
int base_rank = 0; base_rank < numProc; base_rank += rank_limit) {
5613 int stop = std::min(base_rank + rank_limit, numProc);
5616 if (base_rank <= myRank && myRank < stop) {
5618 std::ifstream in(filename);
5619 using Teuchos::MatrixMarket::Banner;
5620 size_t lineNumber = 1;
5621 RCP<const Banner> pBanner;
5623 pBanner = readBanner(in, lineNumber, tolerant, debug);
5624 }
catch (std::exception& e) {
5625 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
5626 "threw an exception: "
5628 bannerIsCorrect = 0;
5630 if (bannerIsCorrect) {
5635 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
5636 bannerIsCorrect = 0;
5637 errMsg <<
"The Matrix Market input file must contain a "
5638 "\"coordinate\"-format sparse matrix in order to create a "
5639 "Tpetra::CrsMatrix object from it, but the file's matrix "
5641 << pBanner->matrixType() <<
"\" instead.";
5646 if (tolerant && pBanner->matrixType() ==
"array") {
5647 bannerIsCorrect = 0;
5648 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
5649 "format sparse matrix in order to create a Tpetra::CrsMatrix "
5650 "object from it, but the file's matrix type is \"array\" "
5651 "instead. That probably means the file contains dense matrix "
5657 using Teuchos::MatrixMarket::readCoordinateDimensions;
5658 success = readCoordinateDimensions(in, numRows, numCols,
5659 numNonzeros, lineNumber,
5663 TEUCHOS_TEST_FOR_EXCEPTION(numRows != (LO)rowMap->getLocalNumElements(), std::invalid_argument,
5664 "# rows in file does not match rowmap.");
5665 TEUCHOS_TEST_FOR_EXCEPTION(!colMap.is_null() && numCols != (LO)colMap->getLocalNumElements(), std::invalid_argument,
5666 "# rows in file does not match colmap.");
5669 typedef Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type> raw_adder_type;
5670 bool tolerant_required =
true;
5671 Teuchos::RCP<raw_adder_type> pRaw =
5672 Teuchos::rcp(
new raw_adder_type(numRows, numCols, numNonzeros, tolerant_required, debug));
5673 RCP<adder_type> pAdder = Teuchos::rcp(
new adder_type(pRaw, pBanner->symmType()));
5676 std::cerr <<
"-- Reading matrix data" << std::endl;
5681 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
5684 reader_type reader(pAdder);
5687 std::pair<bool, std::vector<size_t>> results = reader.read(in, lineNumber, tolerant_required, debug);
5689 readSuccess = results.first ? 1 : 0;
5690 }
catch (std::exception& e) {
5697 typedef Teuchos::MatrixMarket::Raw::Element<scalar_type, global_ordinal_type> element_type;
5700 pAdder->getAdder()->merge();
5703 const std::vector<element_type>& entries = pAdder->getAdder()->getEntries();
5706 const size_t numEntries = (size_t)entries.size();
5709 std::cerr <<
"----- Proc " << myRank <<
": Matrix has numRows=" << numRows
5710 <<
" rows and numEntries=" << numEntries
5711 <<
" entries." << std::endl;
5717 numEntriesPerRow = arcp<size_t>(numRows);
5718 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
5719 rowPtr = arcp<size_t>(numRows + 1);
5720 std::fill(rowPtr.begin(), rowPtr.end(), 0);
5721 colInd = arcp<global_ordinal_type>(numEntries);
5722 values = arcp<scalar_type>(numEntries);
5728 LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
5730 LO indexBase = rowMap->getIndexBase();
5731 for (curPos = 0; curPos < numEntries; ++curPos) {
5732 const element_type& curEntry = entries[curPos];
5734 LO l_curRow = rowMap->getLocalElement(curRow);
5736 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow == INVALID, std::logic_error,
5737 "Current global row " << curRow <<
" is invalid.");
5739 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow < l_prvRow, std::logic_error,
5740 "Row indices are out of order, even though they are supposed "
5741 "to be sorted. curRow = "
5742 << l_curRow <<
", prvRow = "
5743 << l_prvRow <<
", at curPos = " << curPos <<
". Please report "
5744 "this bug to the Tpetra developers.");
5745 if (l_curRow > l_prvRow) {
5746 for (LO r = l_prvRow + 1; r <= l_curRow; ++r) {
5749 l_prvRow = l_curRow;
5751 numEntriesPerRow[l_curRow]++;
5752 colInd[curPos] = curEntry.colIndex() + indexBase;
5753 values[curPos] = curEntry.value();
5758 rowPtr[numRows] = numEntries;
5768 RCP<sparse_matrix_type> A;
5769 if (colMap.is_null()) {
5771 for (
size_t i = 0; i < rowMap->getLocalNumElements(); i++) {
5772 GO g_row = rowMap->getGlobalElement(i);
5773 size_t start = rowPtr[i];
5774 size_t size = rowPtr[i + 1] - rowPtr[i];
5776 A->insertGlobalValues(g_row, size, &values[start], &colInd[start]);
5780 throw std::runtime_error(
"Reading with a column map is not yet implemented");
5782 RCP<const map_type> myDomainMap = domainMap.is_null() ? rowMap : domainMap;
5783 RCP<const map_type> myRangeMap = rangeMap.is_null() ? rowMap : rangeMap;
5785 A->fillComplete(myDomainMap, myRangeMap);
5789 TEUCHOS_TEST_FOR_EXCEPTION(success ==
false, std::runtime_error,
5825 template <
class SparseMatrixType>
5830 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
5896 const std::string& matrixName,
5897 const std::string& matrixDescription,
5898 const bool debug =
false) {
5900 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
5901 "The input matrix's communicator (Teuchos::Comm object) is null.");
5902 const int myRank = comm->getRank();
5904 auto out = Writer::openOutFileOnRankZero(comm, filename, myRank,
true);
5906 writeSparse(out, matrix, matrixName, matrixDescription, debug);
5915 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5916 const std::string& matrixName,
5917 const std::string& matrixDescription,
5918 const bool debug =
false) {
5919 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::invalid_argument,
5920 "The input matrix is null.");
5922 matrixDescription, debug);
5947 const bool debug =
false) {
5954 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5955 const bool debug =
false) {
5992 const std::string& matrixName,
5993 const std::string& matrixDescription,
5994 const bool debug =
false) {
5997 using Teuchos::ArrayView;
5998 using Teuchos::Comm;
5999 using Teuchos::FancyOStream;
6000 using Teuchos::getFancyOStream;
6001 using Teuchos::null;
6003 using Teuchos::rcpFromRef;
6007 using STS =
typename Teuchos::ScalarTraits<ST>;
6013 Teuchos::SetScientific<ST> sci(out);
6017 TEUCHOS_TEST_FOR_EXCEPTION(
6018 comm.is_null(), std::invalid_argument,
6019 "The input matrix's communicator (Teuchos::Comm object) is null.");
6020 const int myRank = comm->getRank();
6023 RCP<FancyOStream> err =
6024 debug ? getFancyOStream(rcpFromRef(std::cerr)) : null;
6026 std::ostringstream os;
6027 os << myRank <<
": writeSparse" << endl;
6030 os <<
"-- " << myRank <<
": past barrier" << endl;
6035 const bool debugPrint = debug && myRank == 0;
6037 RCP<const map_type> rowMap = matrix.getRowMap();
6038 RCP<const map_type> colMap = matrix.getColMap();
6039 RCP<const map_type> domainMap = matrix.getDomainMap();
6040 RCP<const map_type> rangeMap = matrix.getRangeMap();
6042 const global_size_t numRows = rangeMap->getMaxAllGlobalIndex() + 1 - rangeMap->getIndexBase();
6043 const global_size_t numCols = domainMap->getMaxAllGlobalIndex() + 1 - domainMap->getIndexBase();
6045 if (debug && myRank == 0) {
6046 std::ostringstream os;
6047 os <<
"-- Input sparse matrix is:"
6048 <<
"---- " << numRows <<
" x " << numCols << endl
6050 << (matrix.isGloballyIndexed() ?
"Globally" :
"Locally")
6051 <<
" indexed." << endl
6052 <<
"---- Its row map has " << rowMap->getGlobalNumElements()
6053 <<
" elements." << endl
6054 <<
"---- Its col map has " << colMap->getGlobalNumElements()
6055 <<
" elements." << endl;
6060 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6062 std::ostringstream os;
6063 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6066 RCP<const map_type> gatherRowMap =
6067 Details::computeGatherMap(rowMap, err, debug);
6075 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6076 RCP<const map_type> gatherColMap =
6077 Details::computeGatherMap(colMap, err, debug);
6081 import_type importer(rowMap, gatherRowMap);
6086 RCP<sparse_matrix_type> newMatrix =
6088 static_cast<size_t>(0)));
6090 newMatrix->doImport(matrix, importer,
INSERT);
6095 RCP<const map_type> gatherDomainMap =
6096 rcp(
new map_type(numCols, localNumCols,
6097 domainMap->getIndexBase(),
6099 RCP<const map_type> gatherRangeMap =
6100 rcp(
new map_type(numRows, localNumRows,
6101 rangeMap->getIndexBase(),
6103 newMatrix->fillComplete(gatherDomainMap, gatherRangeMap);
6107 cerr <<
"-- Output sparse matrix is:"
6108 <<
"---- " << newMatrix->getRangeMap()->getGlobalNumElements()
6110 << newMatrix->getDomainMap()->getGlobalNumElements()
6112 << newMatrix->getGlobalNumEntries() <<
" entries;" << endl
6114 << (newMatrix->isGloballyIndexed() ?
"Globally" :
"Locally")
6115 <<
" indexed." << endl
6116 <<
"---- Its row map has "
6117 << newMatrix->getRowMap()->getGlobalNumElements()
6118 <<
" elements, with index base "
6119 << newMatrix->getRowMap()->getIndexBase() <<
"." << endl
6120 <<
"---- Its col map has "
6121 << newMatrix->getColMap()->getGlobalNumElements()
6122 <<
" elements, with index base "
6123 << newMatrix->getColMap()->getIndexBase() <<
"." << endl
6124 <<
"---- Element count of output matrix's column Map may differ "
6125 <<
"from that of the input matrix's column Map, if some columns "
6126 <<
"of the matrix contain no entries." << endl;
6139 out <<
"%%MatrixMarket matrix coordinate "
6140 << (STS::isComplex ?
"complex" :
"real")
6141 <<
" general" << endl;
6144 if (matrixName !=
"") {
6145 printAsComment(out, matrixName);
6147 if (matrixDescription !=
"") {
6148 printAsComment(out, matrixDescription);
6158 out << newMatrix->getRangeMap()->getMaxAllGlobalIndex() + 1 - newMatrix->getRangeMap()->getIndexBase() <<
" "
6159 << newMatrix->getDomainMap()->getMaxAllGlobalIndex() + 1 - newMatrix->getDomainMap()->getIndexBase() <<
" "
6160 << newMatrix->getGlobalNumEntries() << endl;
6165 const GO rowIndexBase = gatherRowMap->getIndexBase();
6166 const GO colIndexBase = newMatrix->getColMap()->getIndexBase();
6174 if (newMatrix->isGloballyIndexed()) {
6177 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex();
6178 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex();
6179 for (GO globalRowIndex = minAllGlobalIndex;
6180 globalRowIndex <= maxAllGlobalIndex;
6182 typename sparse_matrix_type::global_inds_host_view_type ind;
6183 typename sparse_matrix_type::values_host_view_type val;
6184 newMatrix->getGlobalRowView(globalRowIndex, ind, val);
6185 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6186 const GO globalColIndex = ind(ii);
6189 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6190 << (globalColIndex + 1 - colIndexBase) <<
" ";
6191 if (STS::isComplex) {
6192 out << STS::real(val(ii)) <<
" " << STS::imag(val(ii));
6200 using OTG = Teuchos::OrdinalTraits<GO>;
6201 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
6202 localRowIndex <= gatherRowMap->getMaxLocalIndex();
6205 const GO globalRowIndex =
6206 gatherRowMap->getGlobalElement(localRowIndex);
6207 TEUCHOS_TEST_FOR_EXCEPTION(
6208 globalRowIndex == OTG::invalid(), std::logic_error,
6209 "Failed to convert the supposed local row index "
6210 << localRowIndex <<
" into a global row index. "
6211 "Please report this bug to the Tpetra developers.");
6212 typename sparse_matrix_type::local_inds_host_view_type ind;
6213 typename sparse_matrix_type::values_host_view_type val;
6214 newMatrix->getLocalRowView(localRowIndex, ind, val);
6215 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6217 const GO globalColIndex =
6218 newMatrix->getColMap()->getGlobalElement(ind(ii));
6219 TEUCHOS_TEST_FOR_EXCEPTION(
6220 globalColIndex == OTG::invalid(), std::logic_error,
6221 "On local row " << localRowIndex <<
" of the sparse matrix: "
6222 "Failed to convert the supposed local column index "
6223 << ind(ii) <<
" into a global column index. Please report "
6224 "this bug to the Tpetra developers.");
6227 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6228 << (globalColIndex + 1 - colIndexBase) <<
" ";
6229 if (STS::isComplex) {
6230 out << STS::real(val(ii)) <<
" " << STS::imag(val(ii));
6244 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6245 const std::string& matrixName,
6246 const std::string& matrixDescription,
6247 const bool debug =
false) {
6248 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::invalid_argument,
6249 "The input matrix is null.");
6250 writeSparse(out, *pMatrix, matrixName, matrixDescription, debug);
6286 const std::string& graphName,
6287 const std::string& graphDescription,
6288 const bool debug =
false) {
6291 using Teuchos::ArrayView;
6292 using Teuchos::Comm;
6293 using Teuchos::FancyOStream;
6294 using Teuchos::getFancyOStream;
6295 using Teuchos::null;
6297 using Teuchos::rcpFromRef;
6306 if (rowMap.is_null()) {
6309 auto comm = rowMap->getComm();
6310 if (comm.is_null()) {
6313 const int myRank = comm->getRank();
6316 RCP<FancyOStream> err =
6317 debug ? getFancyOStream(rcpFromRef(std::cerr)) : null;
6319 std::ostringstream os;
6320 os << myRank <<
": writeSparseGraph" << endl;
6323 os <<
"-- " << myRank <<
": past barrier" << endl;
6328 const bool debugPrint = debug && myRank == 0;
6335 const global_size_t numRows = rangeMap->getGlobalNumElements();
6336 const global_size_t numCols = domainMap->getGlobalNumElements();
6338 if (debug && myRank == 0) {
6339 std::ostringstream os;
6340 os <<
"-- Input sparse graph is:"
6341 <<
"---- " << numRows <<
" x " << numCols <<
" with "
6345 <<
" indexed." << endl
6346 <<
"---- Its row Map has " << rowMap->getGlobalNumElements()
6347 <<
" elements." << endl
6348 <<
"---- Its col Map has " << colMap->getGlobalNumElements()
6349 <<
" elements." << endl;
6354 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6356 std::ostringstream os;
6357 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6360 auto gatherRowMap = Details::computeGatherMap(rowMap, err, debug);
6368 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6369 auto gatherColMap = Details::computeGatherMap(colMap, err, debug);
6378 static_cast<size_t>(0));
6385 RCP<const map_type> gatherDomainMap =
6386 rcp(
new map_type(numCols, localNumCols,
6387 domainMap->getIndexBase(),
6389 RCP<const map_type> gatherRangeMap =
6390 rcp(
new map_type(numRows, localNumRows,
6391 rangeMap->getIndexBase(),
6393 newGraph.
fillComplete(gatherDomainMap, gatherRangeMap);
6397 cerr <<
"-- Output sparse graph is:"
6398 <<
"---- " << newGraph.
getRangeMap()->getGlobalNumElements()
6405 <<
" indexed." << endl
6406 <<
"---- Its row map has "
6407 << newGraph.
getRowMap()->getGlobalNumElements()
6408 <<
" elements, with index base "
6409 << newGraph.
getRowMap()->getIndexBase() <<
"." << endl
6410 <<
"---- Its col map has "
6411 << newGraph.
getColMap()->getGlobalNumElements()
6412 <<
" elements, with index base "
6413 << newGraph.
getColMap()->getIndexBase() <<
"." << endl
6414 <<
"---- Element count of output graph's column Map may differ "
6415 <<
"from that of the input matrix's column Map, if some columns "
6416 <<
"of the matrix contain no entries." << endl;
6430 out <<
"%%MatrixMarket matrix coordinate pattern general" << endl;
6433 if (graphName !=
"") {
6434 printAsComment(out, graphName);
6436 if (graphDescription !=
"") {
6437 printAsComment(out, graphDescription);
6448 out << newGraph.
getRangeMap()->getMaxAllGlobalIndex() + 1 - newGraph.
getRangeMap()->getIndexBase() <<
" "
6455 const GO rowIndexBase = gatherRowMap->getIndexBase();
6456 const GO colIndexBase = newGraph.
getColMap()->getIndexBase();
6467 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex();
6468 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex();
6469 for (GO globalRowIndex = minAllGlobalIndex;
6470 globalRowIndex <= maxAllGlobalIndex;
6472 typename crs_graph_type::global_inds_host_view_type ind;
6474 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6475 const GO globalColIndex = ind(ii);
6478 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6479 << (globalColIndex + 1 - colIndexBase) <<
" ";
6484 typedef Teuchos::OrdinalTraits<GO> OTG;
6485 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
6486 localRowIndex <= gatherRowMap->getMaxLocalIndex();
6489 const GO globalRowIndex =
6490 gatherRowMap->getGlobalElement(localRowIndex);
6491 TEUCHOS_TEST_FOR_EXCEPTION(globalRowIndex == OTG::invalid(), std::logic_error,
6493 "to convert the supposed local row index "
6494 << localRowIndex <<
" into a global row index. Please report this bug to the "
6495 "Tpetra developers.");
6496 typename crs_graph_type::local_inds_host_view_type ind;
6498 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6500 const GO globalColIndex =
6501 newGraph.
getColMap()->getGlobalElement(ind(ii));
6502 TEUCHOS_TEST_FOR_EXCEPTION(
6503 globalColIndex == OTG::invalid(), std::logic_error,
6504 "On local row " << localRowIndex <<
" of the sparse graph: "
6505 "Failed to convert the supposed local column index "
6506 << ind(ii) <<
" into a global column index. Please report "
6507 "this bug to the Tpetra developers.");
6510 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6511 << (globalColIndex + 1 - colIndexBase) <<
" ";
6527 const bool debug =
false) {
6568 const std::string& graphName,
6569 const std::string& graphDescription,
6570 const bool debug =
false) {
6572 if (comm.is_null()) {
6580 const int myRank = comm->getRank();
6582 auto out = Writer::openOutFileOnRankZero(comm, filename, myRank,
true);
6597 const bool debug =
false) {
6611 const Teuchos::RCP<const crs_graph_type>& pGraph,
6612 const std::string& graphName,
6613 const std::string& graphDescription,
6614 const bool debug =
false) {
6629 const Teuchos::RCP<const crs_graph_type>& pGraph,
6630 const bool debug =
false) {
6659 const bool debug =
false) {
6666 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6667 const bool debug =
false) {
6702 const std::string& matrixName,
6703 const std::string& matrixDescription,
6704 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6705 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6709 auto out = Writer::openOutFileOnRankZero(comm, filename, myRank,
true);
6711 writeDense(out, X, matrixName, matrixDescription, err, dbg);
6724 const Teuchos::RCP<const multivector_type>& X,
6725 const std::string& matrixName,
6726 const std::string& matrixDescription,
6727 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6728 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6729 TEUCHOS_TEST_FOR_EXCEPTION(
6730 X.is_null(), std::invalid_argument,
6731 "Tpetra::MatrixMarket::"
6732 "writeDenseFile: The input MultiVector X is null.");
6733 writeDenseFile(filename, *X, matrixName, matrixDescription, err, dbg);
6744 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6745 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6756 const Teuchos::RCP<const multivector_type>& X,
6757 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6758 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6759 TEUCHOS_TEST_FOR_EXCEPTION(
6760 X.is_null(), std::invalid_argument,
6761 "Tpetra::MatrixMarket::"
6762 "writeDenseFile: The input MultiVector X is null.");
6799 const std::string& matrixName,
6800 const std::string& matrixDescription,
6801 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6802 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6804 using Teuchos::Comm;
6805 using Teuchos::outArg;
6806 using Teuchos::REDUCE_MAX;
6807 using Teuchos::reduceAll;
6815 const bool debug = !dbg.is_null();
6818 std::ostringstream os;
6819 os << myRank <<
": writeDense" << endl;
6824 writeDenseHeader(out, X, matrixName, matrixDescription, err, dbg);
6829 for (
size_t j = 0; j < numVecs; ++j) {
6830 writeDenseColumn(out, *(X.
getVector(j)), err, dbg);
6835 std::ostringstream os;
6836 os << myRank <<
": writeDense: Done" << endl;
6848 static std::ofstream openOutFileOnRankZero(
6850 const std::string& filename,
const int rank,
const bool safe =
true,
6851 const std::ios_base::openmode mode = std::ios_base::out) {
6856 int all_should_stop = 0;
6860 out.open(filename, mode);
6861 all_should_stop = !out && safe;
6865 if (comm) Teuchos::broadcast(*comm, 0, &all_should_stop);
6867 TEUCHOS_TEST_FOR_EXCEPTION(
6870 "Could not open output file '" + filename +
"' on root rank 0.");
6901 writeDenseHeader(std::ostream& out,
6903 const std::string& matrixName,
6904 const std::string& matrixDescription,
6905 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6906 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
6908 using Teuchos::Comm;
6909 using Teuchos::outArg;
6911 using Teuchos::REDUCE_MAX;
6912 using Teuchos::reduceAll;
6913 typedef Teuchos::ScalarTraits<scalar_type> STS;
6914 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
6924 const bool debug = !dbg.is_null();
6928 std::ostringstream os;
6929 os << myRank <<
": writeDenseHeader" << endl;
6948 std::ostringstream hdr;
6950 std::string dataType;
6951 if (STS::isComplex) {
6952 dataType =
"complex";
6953 }
else if (STS::isOrdinal) {
6954 dataType =
"integer";
6958 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
6963 if (matrixName !=
"") {
6964 printAsComment(hdr, matrixName);
6966 if (matrixDescription !=
"") {
6967 printAsComment(hdr, matrixDescription);
6970 hdr << X.getGlobalLength() <<
" " << X.getNumVectors() << endl;
6974 }
catch (std::exception& e) {
6975 if (!err.is_null()) {
6976 *err << prefix <<
"While writing the Matrix Market header, "
6977 "Process 0 threw an exception: "
6978 << e.what() << endl;
6987 reduceAll<int, int>(*comm, REDUCE_MAX, lclErr, outArg(gblErr));
6988 TEUCHOS_TEST_FOR_EXCEPTION(
6989 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
6990 "which prevented this method from completing.");
6994 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
7017 writeDenseColumn(std::ostream& out,
7019 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7020 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
7022 using Teuchos::arcp;
7023 using Teuchos::Array;
7024 using Teuchos::ArrayRCP;
7025 using Teuchos::ArrayView;
7026 using Teuchos::Comm;
7027 using Teuchos::CommRequest;
7028 using Teuchos::ireceive;
7029 using Teuchos::isend;
7030 using Teuchos::outArg;
7032 using Teuchos::REDUCE_MAX;
7033 using Teuchos::reduceAll;
7034 using Teuchos::TypeNameTraits;
7035 using Teuchos::wait;
7036 typedef Teuchos::ScalarTraits<scalar_type> STS;
7038 const Comm<int>& comm = *(X.getMap()->getComm());
7039 const int myRank = comm.getRank();
7040 const int numProcs = comm.getSize();
7047 const bool debug = !dbg.is_null();
7051 std::ostringstream os;
7052 os << myRank <<
": writeDenseColumn" << endl;
7061 Teuchos::SetScientific<scalar_type> sci(out);
7063 const size_t myNumRows = X.getLocalLength();
7064 const size_t numCols = X.getNumVectors();
7067 const int sizeTag = 1337;
7068 const int dataTag = 1338;
7129 RCP<CommRequest<int>> sendReqSize, sendReqData;
7135 Array<ArrayRCP<size_t>> recvSizeBufs(3);
7136 Array<ArrayRCP<scalar_type>> recvDataBufs(3);
7137 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
7138 Array<RCP<CommRequest<int>>> recvDataReqs(3);
7141 ArrayRCP<size_t> sendDataSize(1);
7142 sendDataSize[0] = myNumRows;
7146 std::ostringstream os;
7147 os << myRank <<
": Post receive-size receives from "
7148 "Procs 1 and 2: tag = "
7153 recvSizeBufs[0].resize(1);
7157 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
7158 recvSizeBufs[1].resize(1);
7159 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
7160 recvSizeBufs[2].resize(1);
7161 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
7164 ireceive<int, size_t>(recvSizeBufs[1], 1, sizeTag, comm);
7168 ireceive<int, size_t>(recvSizeBufs[2], 2, sizeTag, comm);
7170 }
else if (myRank == 1 || myRank == 2) {
7172 std::ostringstream os;
7173 os << myRank <<
": Post send-size send: size = "
7174 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7181 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
7184 std::ostringstream os;
7185 os << myRank <<
": Not posting my send-size send yet" << endl;
7194 std::ostringstream os;
7195 os << myRank <<
": Pack my entries" << endl;
7198 ArrayRCP<scalar_type> sendDataBuf;
7200 sendDataBuf = arcp<scalar_type>(myNumRows * numCols);
7201 X.get1dCopy(sendDataBuf(), myNumRows);
7202 }
catch (std::exception& e) {
7204 if (!err.is_null()) {
7205 std::ostringstream os;
7206 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
7207 "entries threw an exception: "
7208 << e.what() << endl;
7213 std::ostringstream os;
7214 os << myRank <<
": Done packing my entries" << endl;
7223 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
7226 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
7234 std::ostringstream os;
7235 os << myRank <<
": Write my entries" << endl;
7241 const size_t printNumRows = myNumRows;
7242 ArrayView<const scalar_type> printData = sendDataBuf();
7243 const size_t printStride = printNumRows;
7244 if (static_cast<size_t>(printData.size()) < printStride * numCols) {
7246 if (!err.is_null()) {
7247 std::ostringstream os;
7248 os <<
"Process " << myRank <<
": My MultiVector data's size "
7249 << printData.size() <<
" does not match my local dimensions "
7250 << printStride <<
" x " << numCols <<
"." << endl;
7257 for (
size_t col = 0; col < numCols; ++col) {
7258 for (
size_t row = 0; row < printNumRows; ++row) {
7259 if (STS::isComplex) {
7260 out << STS::real(printData[row + col * printStride]) <<
" "
7261 << STS::imag(printData[row + col * printStride]) << endl;
7263 out << printData[row + col * printStride] << endl;
7272 const int recvRank = 1;
7273 const int circBufInd = recvRank % 3;
7275 std::ostringstream os;
7276 os << myRank <<
": Wait on receive-size receive from Process "
7277 << recvRank << endl;
7281 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
7285 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7286 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
7288 if (!err.is_null()) {
7289 std::ostringstream os;
7290 os << myRank <<
": Result of receive-size receive from Process "
7291 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7292 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
7293 "This should never happen, and suggests that the receive never "
7294 "got posted. Please report this bug to the Tpetra developers."
7309 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
7311 std::ostringstream os;
7312 os << myRank <<
": Post receive-data receive from Process "
7313 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7314 << recvDataBufs[circBufInd].size() << endl;
7317 if (!recvSizeReqs[circBufInd].is_null()) {
7319 if (!err.is_null()) {
7320 std::ostringstream os;
7321 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7322 "null, before posting the receive-data receive from Process "
7323 << recvRank <<
". This should never happen. Please report "
7324 "this bug to the Tpetra developers."
7329 recvDataReqs[circBufInd] =
7330 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
7331 recvRank, dataTag, comm);
7333 }
else if (myRank == 1) {
7336 std::ostringstream os;
7337 os << myRank <<
": Wait on my send-size send" << endl;
7340 wait<int>(comm, outArg(sendReqSize));
7346 for (
int p = 1; p < numProcs; ++p) {
7348 if (p + 2 < numProcs) {
7350 const int recvRank = p + 2;
7351 const int circBufInd = recvRank % 3;
7353 std::ostringstream os;
7354 os << myRank <<
": Post receive-size receive from Process "
7355 << recvRank <<
": tag = " << sizeTag << endl;
7358 if (!recvSizeReqs[circBufInd].is_null()) {
7360 if (!err.is_null()) {
7361 std::ostringstream os;
7362 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7363 <<
"null, for the receive-size receive from Process "
7364 << recvRank <<
"! This may mean that this process never "
7365 <<
"finished waiting for the receive from Process "
7366 << (recvRank - 3) <<
"." << endl;
7370 recvSizeReqs[circBufInd] =
7371 ireceive<int, size_t>(recvSizeBufs[circBufInd],
7372 recvRank, sizeTag, comm);
7375 if (p + 1 < numProcs) {
7376 const int recvRank = p + 1;
7377 const int circBufInd = recvRank % 3;
7381 std::ostringstream os;
7382 os << myRank <<
": Wait on receive-size receive from Process "
7383 << recvRank << endl;
7386 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
7390 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7391 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
7393 if (!err.is_null()) {
7394 std::ostringstream os;
7395 os << myRank <<
": Result of receive-size receive from Process "
7396 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7397 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
7398 "This should never happen, and suggests that the receive never "
7399 "got posted. Please report this bug to the Tpetra developers."
7413 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
7415 std::ostringstream os;
7416 os << myRank <<
": Post receive-data receive from Process "
7417 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7418 << recvDataBufs[circBufInd].size() << endl;
7421 if (!recvDataReqs[circBufInd].is_null()) {
7423 if (!err.is_null()) {
7424 std::ostringstream os;
7425 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
7426 <<
"null, for the receive-data receive from Process "
7427 << recvRank <<
"! This may mean that this process never "
7428 <<
"finished waiting for the receive from Process "
7429 << (recvRank - 3) <<
"." << endl;
7433 recvDataReqs[circBufInd] =
7434 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
7435 recvRank, dataTag, comm);
7439 const int recvRank = p;
7440 const int circBufInd = recvRank % 3;
7442 std::ostringstream os;
7443 os << myRank <<
": Wait on receive-data receive from Process "
7444 << recvRank << endl;
7447 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
7454 std::ostringstream os;
7455 os << myRank <<
": Write entries from Process " << recvRank
7457 *dbg << os.str() << endl;
7459 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
7460 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
7462 if (!err.is_null()) {
7463 std::ostringstream os;
7464 os << myRank <<
": Result of receive-size receive from Process "
7465 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
7467 << Teuchos::OrdinalTraits<size_t>::invalid()
7468 <<
". This should never happen, and suggests that its "
7469 "receive-size receive was never posted. "
7470 "Please report this bug to the Tpetra developers."
7478 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
7480 if (!err.is_null()) {
7481 std::ostringstream os;
7482 os << myRank <<
": Result of receive-size receive from Proc "
7483 << recvRank <<
" was " << printNumRows <<
" > 0, but "
7485 << circBufInd <<
"] is null. This should "
7486 "never happen. Please report this bug to the Tpetra "
7498 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd])();
7499 const size_t printStride = printNumRows;
7503 for (
size_t col = 0; col < numCols; ++col) {
7504 for (
size_t row = 0; row < printNumRows; ++row) {
7505 if (STS::isComplex) {
7506 out << STS::real(printData[row + col * printStride]) <<
" "
7507 << STS::imag(printData[row + col * printStride]) << endl;
7509 out << printData[row + col * printStride] << endl;
7513 }
else if (myRank == p) {
7516 std::ostringstream os;
7517 os << myRank <<
": Wait on my send-data send" << endl;
7520 wait<int>(comm, outArg(sendReqData));
7521 }
else if (myRank == p + 1) {
7524 std::ostringstream os;
7525 os << myRank <<
": Post send-data send: tag = " << dataTag
7529 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
7532 std::ostringstream os;
7533 os << myRank <<
": Wait on my send-size send" << endl;
7536 wait<int>(comm, outArg(sendReqSize));
7537 }
else if (myRank == p + 2) {
7540 std::ostringstream os;
7541 os << myRank <<
": Post send-size send: size = "
7542 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7545 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
7550 reduceAll<int, int>(comm, REDUCE_MAX, lclErr, outArg(gblErr));
7551 TEUCHOS_TEST_FOR_EXCEPTION(
7552 gblErr == 1, std::runtime_error,
7553 "Tpetra::MatrixMarket::writeDense "
7554 "experienced some kind of error and was unable to complete.");
7558 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
7571 const Teuchos::RCP<const multivector_type>& X,
7572 const std::string& matrixName,
7573 const std::string& matrixDescription,
7574 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7575 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
7576 TEUCHOS_TEST_FOR_EXCEPTION(
7577 X.is_null(), std::invalid_argument,
7578 "Tpetra::MatrixMarket::"
7579 "writeDense: The input MultiVector X is null.");
7580 writeDense(out, *X, matrixName, matrixDescription, err, dbg);
7591 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7592 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
7603 const Teuchos::RCP<const multivector_type>& X,
7604 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7605 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null) {
7606 TEUCHOS_TEST_FOR_EXCEPTION(
7607 X.is_null(), std::invalid_argument,
7608 "Tpetra::MatrixMarket::"
7609 "writeDense: The input MultiVector X is null.");
7634 Teuchos::RCP<Teuchos::FancyOStream> err =
7635 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
7650 const Teuchos::RCP<Teuchos::FancyOStream>& err,
7651 const bool debug =
false) {
7653 using Teuchos::Array;
7654 using Teuchos::ArrayRCP;
7655 using Teuchos::ArrayView;
7656 using Teuchos::Comm;
7657 using Teuchos::CommRequest;
7658 using Teuchos::ireceive;
7659 using Teuchos::isend;
7661 using Teuchos::TypeNameTraits;
7662 using Teuchos::wait;
7664 typedef int pid_type;
7679 typedef ptrdiff_t int_type;
7680 TEUCHOS_TEST_FOR_EXCEPTION(
7681 sizeof(GO) >
sizeof(int_type), std::logic_error,
7682 "The global ordinal type GO=" << TypeNameTraits<GO>::name()
7683 <<
" is too big for ptrdiff_t. sizeof(GO) = " <<
sizeof(GO)
7684 <<
" > sizeof(ptrdiff_t) = " <<
sizeof(ptrdiff_t) <<
".");
7685 TEUCHOS_TEST_FOR_EXCEPTION(
7686 sizeof(pid_type) >
sizeof(int_type), std::logic_error,
7687 "The (MPI) process rank type pid_type=" << TypeNameTraits<pid_type>::name() <<
" is too big for ptrdiff_t. "
7688 "sizeof(pid_type) = "
7689 <<
sizeof(pid_type) <<
" > sizeof(ptrdiff_t)"
7691 <<
sizeof(ptrdiff_t) <<
".");
7693 const Comm<int>& comm = *(map.
getComm());
7694 const int myRank = comm.getRank();
7695 const int numProcs = comm.getSize();
7697 if (!err.is_null()) {
7701 std::ostringstream os;
7702 os << myRank <<
": writeMap" << endl;
7705 if (!err.is_null()) {
7712 const int sizeTag = 1337;
7713 const int dataTag = 1338;
7772 RCP<CommRequest<int>> sendReqSize, sendReqData;
7778 Array<ArrayRCP<int_type>> recvSizeBufs(3);
7779 Array<ArrayRCP<int_type>> recvDataBufs(3);
7780 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
7781 Array<RCP<CommRequest<int>>> recvDataReqs(3);
7784 ArrayRCP<int_type> sendDataSize(1);
7785 sendDataSize[0] = myNumRows;
7789 std::ostringstream os;
7790 os << myRank <<
": Post receive-size receives from "
7791 "Procs 1 and 2: tag = "
7796 recvSizeBufs[0].resize(1);
7797 (recvSizeBufs[0])[0] = -1;
7798 recvSizeBufs[1].resize(1);
7799 (recvSizeBufs[1])[0] = -1;
7800 recvSizeBufs[2].resize(1);
7801 (recvSizeBufs[2])[0] = -1;
7804 ireceive<int, int_type>(recvSizeBufs[1], 1, sizeTag, comm);
7808 ireceive<int, int_type>(recvSizeBufs[2], 2, sizeTag, comm);
7810 }
else if (myRank == 1 || myRank == 2) {
7812 std::ostringstream os;
7813 os << myRank <<
": Post send-size send: size = "
7814 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7821 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
7824 std::ostringstream os;
7825 os << myRank <<
": Not posting my send-size send yet" << endl;
7836 std::ostringstream os;
7837 os << myRank <<
": Pack my GIDs and PIDs" << endl;
7841 ArrayRCP<int_type> sendDataBuf(myNumRows * 2);
7844 const int_type myMinGblIdx =
7846 for (
size_t k = 0; k < myNumRows; ++k) {
7847 const int_type gid = myMinGblIdx +
static_cast<int_type
>(k);
7848 const int_type pid =
static_cast<int_type
>(myRank);
7849 sendDataBuf[2 * k] = gid;
7850 sendDataBuf[2 * k + 1] = pid;
7854 for (
size_t k = 0; k < myNumRows; ++k) {
7855 const int_type gid =
static_cast<int_type
>(myGblInds[k]);
7856 const int_type pid =
static_cast<int_type
>(myRank);
7857 sendDataBuf[2 * k] = gid;
7858 sendDataBuf[2 * k + 1] = pid;
7863 std::ostringstream os;
7864 os << myRank <<
": Done packing my GIDs and PIDs" << endl;
7871 *err << myRank <<
": Post send-data send: tag = " << dataTag
7874 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
7879 *err << myRank <<
": Write MatrixMarket header" << endl;
7884 std::ostringstream hdr;
7888 hdr <<
"%%MatrixMarket matrix array integer general" << endl
7889 <<
"% Format: Version 2.0" << endl
7891 <<
"% This file encodes a Tpetra::Map." << endl
7892 <<
"% It is stored as a dense vector, with twice as many " << endl
7893 <<
"% entries as the global number of GIDs (global indices)." << endl
7894 <<
"% (GID, PID) pairs are stored contiguously, where the PID " << endl
7895 <<
"% is the rank of the process owning that GID." << endl
7900 std::ostringstream os;
7901 os << myRank <<
": Write my GIDs and PIDs" << endl;
7907 const int_type printNumRows = myNumRows;
7908 ArrayView<const int_type> printData = sendDataBuf();
7909 for (int_type k = 0; k < printNumRows; ++k) {
7910 const int_type gid = printData[2 * k];
7911 const int_type pid = printData[2 * k + 1];
7919 const int recvRank = 1;
7920 const int circBufInd = recvRank % 3;
7922 std::ostringstream os;
7923 os << myRank <<
": Wait on receive-size receive from Process "
7924 << recvRank << endl;
7928 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
7932 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
7933 if (debug && recvNumRows == -1) {
7934 std::ostringstream os;
7935 os << myRank <<
": Result of receive-size receive from Process "
7936 << recvRank <<
" is -1. This should never happen, and "
7937 "suggests that the receive never got posted. Please report "
7938 "this bug to the Tpetra developers."
7944 recvDataBufs[circBufInd].resize(recvNumRows * 2);
7946 std::ostringstream os;
7947 os << myRank <<
": Post receive-data receive from Process "
7948 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7949 << recvDataBufs[circBufInd].size() << endl;
7952 if (!recvSizeReqs[circBufInd].is_null()) {
7953 std::ostringstream os;
7954 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7955 "null, before posting the receive-data receive from Process "
7956 << recvRank <<
". This should never happen. Please report "
7957 "this bug to the Tpetra developers."
7961 recvDataReqs[circBufInd] =
7962 ireceive<int, int_type>(recvDataBufs[circBufInd],
7963 recvRank, dataTag, comm);
7965 }
else if (myRank == 1) {
7968 std::ostringstream os;
7969 os << myRank <<
": Wait on my send-size send" << endl;
7972 wait<int>(comm, outArg(sendReqSize));
7978 for (
int p = 1; p < numProcs; ++p) {
7980 if (p + 2 < numProcs) {
7982 const int recvRank = p + 2;
7983 const int circBufInd = recvRank % 3;
7985 std::ostringstream os;
7986 os << myRank <<
": Post receive-size receive from Process "
7987 << recvRank <<
": tag = " << sizeTag << endl;
7990 if (!recvSizeReqs[circBufInd].is_null()) {
7991 std::ostringstream os;
7992 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7993 <<
"null, for the receive-size receive from Process "
7994 << recvRank <<
"! This may mean that this process never "
7995 <<
"finished waiting for the receive from Process "
7996 << (recvRank - 3) <<
"." << endl;
7999 recvSizeReqs[circBufInd] =
8000 ireceive<int, int_type>(recvSizeBufs[circBufInd],
8001 recvRank, sizeTag, comm);
8004 if (p + 1 < numProcs) {
8005 const int recvRank = p + 1;
8006 const int circBufInd = recvRank % 3;
8010 std::ostringstream os;
8011 os << myRank <<
": Wait on receive-size receive from Process "
8012 << recvRank << endl;
8015 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
8019 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
8020 if (debug && recvNumRows == -1) {
8021 std::ostringstream os;
8022 os << myRank <<
": Result of receive-size receive from Process "
8023 << recvRank <<
" is -1. This should never happen, and "
8024 "suggests that the receive never got posted. Please report "
8025 "this bug to the Tpetra developers."
8031 recvDataBufs[circBufInd].resize(recvNumRows * 2);
8033 std::ostringstream os;
8034 os << myRank <<
": Post receive-data receive from Process "
8035 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
8036 << recvDataBufs[circBufInd].size() << endl;
8039 if (!recvDataReqs[circBufInd].is_null()) {
8040 std::ostringstream os;
8041 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
8042 <<
"null, for the receive-data receive from Process "
8043 << recvRank <<
"! This may mean that this process never "
8044 <<
"finished waiting for the receive from Process "
8045 << (recvRank - 3) <<
"." << endl;
8048 recvDataReqs[circBufInd] =
8049 ireceive<int, int_type>(recvDataBufs[circBufInd],
8050 recvRank, dataTag, comm);
8054 const int recvRank = p;
8055 const int circBufInd = recvRank % 3;
8057 std::ostringstream os;
8058 os << myRank <<
": Wait on receive-data receive from Process "
8059 << recvRank << endl;
8062 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
8069 std::ostringstream os;
8070 os << myRank <<
": Write GIDs and PIDs from Process "
8071 << recvRank << endl;
8072 *err << os.str() << endl;
8074 const int_type printNumRows = (recvSizeBufs[circBufInd])[0];
8075 if (debug && printNumRows == -1) {
8076 std::ostringstream os;
8077 os << myRank <<
": Result of receive-size receive from Process "
8078 << recvRank <<
" was -1. This should never happen, and "
8079 "suggests that its receive-size receive was never posted. "
8080 "Please report this bug to the Tpetra developers."
8084 if (debug && printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
8085 std::ostringstream os;
8086 os << myRank <<
": Result of receive-size receive from Proc "
8087 << recvRank <<
" was " << printNumRows <<
" > 0, but "
8089 << circBufInd <<
"] is null. This should "
8090 "never happen. Please report this bug to the Tpetra "
8095 ArrayView<const int_type> printData = (recvDataBufs[circBufInd])();
8096 for (int_type k = 0; k < printNumRows; ++k) {
8097 const int_type gid = printData[2 * k];
8098 const int_type pid = printData[2 * k + 1];
8102 }
else if (myRank == p) {
8105 std::ostringstream os;
8106 os << myRank <<
": Wait on my send-data send" << endl;
8109 wait<int>(comm, outArg(sendReqData));
8110 }
else if (myRank == p + 1) {
8113 std::ostringstream os;
8114 os << myRank <<
": Post send-data send: tag = " << dataTag
8118 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
8121 std::ostringstream os;
8122 os << myRank <<
": Wait on my send-size send" << endl;
8125 wait<int>(comm, outArg(sendReqSize));
8126 }
else if (myRank == p + 2) {
8129 std::ostringstream os;
8130 os << myRank <<
": Post send-size send: size = "
8131 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
8134 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
8138 if (!err.is_null()) {
8142 *err << myRank <<
": writeMap: Done" << endl;
8144 if (!err.is_null()) {
8153 const int myRank = map.
getComm()->getRank();
8155 auto out = Writer::openOutFileOnRankZero(map.
getComm(), filename, myRank,
true);
8188 printAsComment(std::ostream& out,
const std::string& str) {
8190 std::istringstream inpstream(str);
8193 while (getline(inpstream, line)) {
8194 if (!line.empty()) {
8197 if (line[0] ==
'%') {
8198 out << line << endl;
8200 out <<
"%% " << line << endl;
8227 Teuchos::ParameterList pl;
8253 Teuchos::ParameterList pl;
8296 const Teuchos::ParameterList& params) {
8298 std::string tmpFile =
"__TMP__" + fileName;
8299 const int myRank = A.
getDomainMap()->getComm()->getRank();
8300 bool precisionChanged =
false;
8310 if (std::ifstream(tmpFile))
8311 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
8312 "writeOperator: temporary file " << tmpFile <<
" already exists");
8313 out.open(tmpFile.c_str());
8314 if (params.isParameter(
"precision")) {
8315 oldPrecision = out.precision(params.get<
int>(
"precision"));
8316 precisionChanged =
true;
8320 const std::string header = writeOperatorImpl(out, A, params);
8323 if (precisionChanged)
8324 out.precision(oldPrecision);
8326 out.open(fileName.c_str(), std::ios::binary);
8327 bool printMatrixMarketHeader =
true;
8328 if (params.isParameter(
"print MatrixMarket header"))
8329 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
8330 if (printMatrixMarketHeader && myRank == 0) {
8335 std::ifstream src(tmpFile, std::ios_base::binary);
8339 remove(tmpFile.c_str());
8384 const Teuchos::ParameterList& params) {
8385 const int myRank = A.
getDomainMap()->getComm()->getRank();
8402 std::ostringstream tmpOut;
8404 if (params.isParameter(
"precision") && params.isType<
int>(
"precision")) {
8405 (void)tmpOut.precision(params.get<
int>(
"precision"));
8409 const std::string header = writeOperatorImpl(tmpOut, A, params);
8412 bool printMatrixMarketHeader =
true;
8413 if (params.isParameter(
"print MatrixMarket header") &&
8414 params.isType<
bool>(
"print MatrixMarket header")) {
8415 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
8417 if (printMatrixMarketHeader && myRank == 0) {
8433 out << tmpOut.str();
8446 writeOperatorImpl(std::ostream& os,
8447 const operator_type& A,
8448 const Teuchos::ParameterList& params) {
8449 using Teuchos::Array;
8450 using Teuchos::ArrayRCP;
8456 typedef scalar_type Scalar;
8457 typedef Teuchos::OrdinalTraits<LO> TLOT;
8458 typedef Teuchos::OrdinalTraits<GO> TGOT;
8462 const map_type& domainMap = *(A.getDomainMap());
8463 RCP<const map_type> rangeMap = A.getRangeMap();
8465 const int myRank = comm->getRank();
8466 const size_t numProcs = comm->getSize();
8469 if (params.isParameter(
"probing size"))
8470 numMVs = params.get<
int>(
"probing size");
8473 GO minColGid = domainMap.getMinAllGlobalIndex();
8474 GO maxColGid = domainMap.getMaxAllGlobalIndex();
8479 GO numGlobElts = maxColGid - minColGid + TGOT::one();
8480 GO numChunks = numGlobElts / numMVs;
8481 GO rem = numGlobElts % numMVs;
8482 GO indexBase = rangeMap->getIndexBase();
8484 int offsetToUseInPrinting = 1 - indexBase;
8485 if (params.isParameter(
"zero-based indexing")) {
8486 if (params.get<
bool>(
"zero-based indexing") ==
true)
8487 offsetToUseInPrinting = -indexBase;
8491 size_t numLocalRangeEntries = rangeMap->getLocalNumElements();
8494 RCP<const map_type> allGidsMap = rcp(
new map_type(TGOT::invalid(), numLocalRangeEntries,
8497 mv_type_go allGids(allGidsMap, 1);
8498 Teuchos::ArrayRCP<GO> allGidsData = allGids.getDataNonConst(0);
8500 for (
size_t i = 0; i < numLocalRangeEntries; i++)
8501 allGidsData[i] = rangeMap->getGlobalElement(i);
8502 allGidsData = Teuchos::null;
8505 GO numTargetMapEntries = TGOT::zero();
8506 Teuchos::Array<GO> importGidList;
8508 numTargetMapEntries = rangeMap->getGlobalNumElements();
8509 importGidList.reserve(numTargetMapEntries);
8510 for (GO j = 0; j < numTargetMapEntries; ++j) importGidList.push_back(j + indexBase);
8512 importGidList.reserve(numTargetMapEntries);
8514 RCP<map_type> importGidMap = rcp(
new map_type(TGOT::invalid(), importGidList(), indexBase, comm));
8517 import_type gidImporter(allGidsMap, importGidMap);
8518 mv_type_go importedGids(importGidMap, 1);
8519 importedGids.doImport(allGids, gidImporter,
INSERT);
8522 ArrayRCP<const GO> importedGidsData = importedGids.getData(0);
8523 RCP<const map_type> importMap = rcp(
new map_type(TGOT::invalid(), importedGidsData(), indexBase, comm));
8526 import_type importer(rangeMap, importMap);
8528 RCP<mv_type> colsOnPid0 = rcp(
new mv_type(importMap, numMVs));
8530 RCP<mv_type> ei = rcp(
new mv_type(A.getDomainMap(), numMVs));
8531 RCP<mv_type> colsA = rcp(
new mv_type(A.getRangeMap(), numMVs));
8533 Array<GO> globalColsArray, localColsArray;
8534 globalColsArray.reserve(numMVs);
8535 localColsArray.reserve(numMVs);
8537 ArrayRCP<ArrayRCP<Scalar>> eiData(numMVs);
8538 for (
size_t i = 0; i < numMVs; ++i)
8539 eiData[i] = ei->getDataNonConst(i);
8544 for (GO k = 0; k < numChunks; ++k) {
8545 for (
size_t j = 0; j < numMVs; ++j) {
8547 GO curGlobalCol = minColGid + k * numMVs + j;
8548 globalColsArray.push_back(curGlobalCol);
8550 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8551 if (curLocalCol != TLOT::invalid()) {
8552 eiData[j][curLocalCol] = TGOT::one();
8553 localColsArray.push_back(curLocalCol);
8558 for (
size_t i = 0; i < numMVs; ++i)
8559 eiData[i] = Teuchos::null;
8561 A.apply(*ei, *colsA);
8563 colsOnPid0->doImport(*colsA, importer,
INSERT);
8566 globalNnz += writeColumns(os, *colsOnPid0, numMVs, importedGidsData(),
8567 globalColsArray, offsetToUseInPrinting);
8570 for (
size_t i = 0; i < numMVs; ++i)
8571 eiData[i] = ei->getDataNonConst(i);
8572 for (
size_t j = 0; j < numMVs; ++j) {
8573 GO curGlobalCol = minColGid + k * numMVs + j;
8575 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8576 if (curLocalCol != TLOT::invalid()) {
8577 eiData[j][curLocalCol] = TGOT::one();
8582 for (
size_t j = 0; j < numMVs; ++j) {
8583 for (
int i = 0; i < localColsArray.size(); ++i)
8584 eiData[j][localColsArray[i]] = TGOT::zero();
8586 globalColsArray.clear();
8587 localColsArray.clear();
8594 for (
int j = 0; j < rem; ++j) {
8595 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
8596 globalColsArray.push_back(curGlobalCol);
8598 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8599 if (curLocalCol != TLOT::invalid()) {
8600 eiData[j][curLocalCol] = TGOT::one();
8601 localColsArray.push_back(curLocalCol);
8606 for (
size_t i = 0; i < numMVs; ++i)
8607 eiData[i] = Teuchos::null;
8609 A.apply(*ei, *colsA);
8611 colsOnPid0->doImport(*colsA, importer,
INSERT);
8613 globalNnz += writeColumns(os, *colsOnPid0, rem, importedGidsData(),
8614 globalColsArray, offsetToUseInPrinting);
8617 for (
size_t i = 0; i < numMVs; ++i)
8618 eiData[i] = ei->getDataNonConst(i);
8619 for (
int j = 0; j < rem; ++j) {
8620 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
8622 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8623 if (curLocalCol != TLOT::invalid()) {
8624 eiData[j][curLocalCol] = TGOT::one();
8629 for (
int j = 0; j < rem; ++j) {
8630 for (
int i = 0; i < localColsArray.size(); ++i)
8631 eiData[j][localColsArray[i]] = TGOT::zero();
8633 globalColsArray.clear();
8634 localColsArray.clear();
8642 std::ostringstream oss;
8644 oss <<
"%%MatrixMarket matrix coordinate ";
8645 if (Teuchos::ScalarTraits<typename operator_type::scalar_type>::isComplex) {
8650 oss <<
" general" << std::endl;
8651 oss <<
"% Tpetra::Operator" << std::endl;
8652 std::time_t now = std::time(NULL);
8653 oss <<
"% time stamp: " << ctime(&now);
8654 oss <<
"% written from " << numProcs <<
" processes" << std::endl;
8655 size_t numRows = rangeMap->getGlobalNumElements();
8656 size_t numCols = domainMap.getGlobalNumElements();
8657 oss << numRows <<
" " << numCols <<
" " << globalNnz << std::endl;
8664 writeColumns(std::ostream& os, mv_type
const& colsA,
size_t const& numCols,
8665 Teuchos::ArrayView<const global_ordinal_type>
const& rowGids,
8666 Teuchos::Array<global_ordinal_type>
const& colsArray,
8669 typedef scalar_type Scalar;
8670 typedef Teuchos::ScalarTraits<Scalar> STS;
8673 const Scalar zero = STS::zero();
8674 const size_t numRows = colsA.getGlobalLength();
8675 for (
size_t j = 0; j < numCols; ++j) {
8676 Teuchos::ArrayRCP<const Scalar>
const curCol = colsA.getData(j);
8677 const GO J = colsArray[j];
8678 for (
size_t i = 0; i < numRows; ++i) {
8679 const Scalar val = curCol[i];
8681 os << rowGids[i] + indexBase <<
" " << J + indexBase <<
" " << val << std::endl;
8700 const std::string& filename_suffix,
8702 const std::string& matrixName,
8703 const std::string& matrixDescription,
8704 const int ranksToWriteAtOnce = 8,
8705 const bool debug =
false) {
8709 using STS =
typename Teuchos::ScalarTraits<ST>;
8714 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
8715 "The input matrix's communicator (Teuchos::Comm object) is null.");
8716 TEUCHOS_TEST_FOR_EXCEPTION(matrix.isGloballyIndexed() || !matrix.isFillComplete(), std::invalid_argument,
8717 "The input matrix must not be GloballyIndexed and must be fillComplete.");
8720 const int myRank = comm->getRank();
8721 const int numProc = comm->getSize();
8722 std::string filename = filename_prefix + std::to_string(myRank) + filename_suffix;
8723 RCP<const map_type> rowMap = matrix.getRowMap();
8724 RCP<const map_type> colMap = matrix.getColMap();
8725 size_t local_nnz = matrix.getLocalNumEntries();
8726 size_t local_num_rows = rowMap->getLocalNumElements();
8727 size_t local_num_cols = colMap->getLocalNumElements();
8728 const GO rowIndexBase = rowMap->getIndexBase();
8729 const GO colIndexBase = colMap->getIndexBase();
8732 int rank_limit = std::min(std::max(ranksToWriteAtOnce, 1), numProc);
8735 for (
int base_rank = 0; base_rank < numProc; base_rank += rank_limit) {
8736 int stop = std::min(base_rank + rank_limit, numProc);
8738 if (base_rank <= myRank && myRank < stop) {
8740 std::ofstream out(filename);
8743 out <<
"%%MatrixMarket matrix coordinate "
8744 << (STS::isComplex ?
"complex" :
"real")
8745 <<
" general" << std::endl;
8748 if (matrixName !=
"") {
8749 printAsComment(out, matrixName);
8751 if (matrixDescription !=
"") {
8752 printAsComment(out, matrixDescription);
8758 out << local_num_rows <<
" " << local_num_cols <<
" " << local_nnz << std::endl;
8765 Teuchos::SetScientific<ST> sci(out);
8767 for (
size_t l_row = 0; l_row < local_num_rows; l_row++) {
8768 GO g_row = rowMap->getGlobalElement(l_row);
8770 typename sparse_matrix_type::local_inds_host_view_type indices;
8771 typename sparse_matrix_type::values_host_view_type values;
8772 matrix.getLocalRowView(l_row, indices, values);
8773 for (
size_t ii = 0; ii < indices.extent(0); ii++) {
8774 const GO g_col = colMap->getGlobalElement(indices(ii));
8777 out << (g_row + 1 - rowIndexBase) <<
" "
8778 << (g_col + 1 - colIndexBase) <<
" ";
8779 if (STS::isComplex) {
8780 out << STS::real(values(ii)) <<
" " << STS::imag(values(ii));
8801 template <
typename T>
8803 return obj.is_null() ? Teuchos::null : obj->getComm();
8808 return comm.is_null() ? 0 : comm->getRank();
8816 #endif // __MatrixMarket_Tpetra_hpp
static std::ifstream openInFileOnRankZero(const trcp_tcomm_t &comm, const std::string &filename, const bool safe=true, std::ios_base::openmode mode=std::ios_base::in)
Open an input file stream safely on rank zero.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::RCP< const map_type > getRowMap() const override
Returns the Map that describes the row distribution in this graph.
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
static Teuchos::RCP< multivector_type > readDense(std::istream &in, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read dense matrix (as a MultiVector) from the given Matrix Market input stream.
static void writeSparseGraphFile(const std::string &filename, const Teuchos::RCP< const crs_graph_type > &pGraph, const bool debug=false)
Print the sparse graph in Matrix Market format to the given file (by filename), with no comments...
static Teuchos::RCP< sparse_matrix_type > readSparseFile(const std::string &filename, const trcp_tcomm_t &comm, const Teuchos::RCP< Teuchos::ParameterList > &constructorParams, const Teuchos::RCP< Teuchos::ParameterList > &fillCompleteParams, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market file.
static Teuchos::RCP< vector_type > readVectorFile(const std::string &filename, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read a Vector from the given Matrix Market file.
static void writeOperator(std::ostream &out, const operator_type &A)
Write a Tpetra::Operator to an output stream.
Teuchos::RCP< const map_type > getColMap() const override
Returns the Map that describes the column distribution in this graph.
static void writeSparseFile(const std::string &filename, const Teuchos::RCP< const sparse_matrix_type > &pMatrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Only for backwards compatibility; prefer the overload above.
SparseMatrixType::node_type node_type
The fourth template parameter of CrsMatrix and MultiVector.
static void writeDense(std::ostream &out, const multivector_type &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
void doImport(const SrcDistObject &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, const CombineMode CM, const bool restrictedMode=false)
Import data into this object using an Import object ("forward mode").
size_t getNumVectors() const
Number of columns in the multivector.
Declaration of a function that prints strings from each process.
size_t getLocalNumElements() const
The number of elements belonging to the calling process.
SparseMatrixType::local_ordinal_type local_ordinal_type
SparseMatrixType::global_ordinal_type global_ordinal_type
One or more distributed dense vectors.
Teuchos::RCP< const map_type > getDomainMap() const override
Returns the Map associated with the domain of this graph.
SparseMatrixType::local_ordinal_type local_ordinal_type
Type of the local indices of the sparse matrix.
static Teuchos::RCP< const map_type > readMapFile(const std::string &filename, const trcp_tcomm_t &comm, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read Map (as a MultiVector) from the given Matrix Market file.
static void writeDenseFile(const std::string &filename, const Teuchos::RCP< const multivector_type > &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
SparseMatrixType::scalar_type scalar_type
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
static Teuchos::RCP< sparse_graph_type > readSparseGraphFile(const std::string &filename, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market file, with provided Maps.
MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > multivector_type
Specialization of Tpetra::MultiVector that matches SparseMatrixType.
static Teuchos::RCP< sparse_graph_type > readSparseGraphFile(const std::string &filename, const trcp_tcomm_t &comm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market file.
static Teuchos::RCP< const map_type > readMap(std::istream &in, const trcp_tcomm_t &comm, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read Map (as a MultiVector) from the given input stream.
bool isGloballyIndexed() const override
Whether the graph's column indices are stored as global indices.
static void writeMap(std::ostream &out, const map_type &map, const bool debug=false)
Print the Map to the given output stream.
static void writeDenseFile(const std::string &filename, const multivector_type &X, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with no matrix name or description.
static void writeSparse(std::ostream &out, const sparse_matrix_type &matrix, const bool debug=false)
Print the sparse matrix in Matrix Market format.
static Teuchos::RCP< sparse_matrix_type > readSparse(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int >> &pComm, const Teuchos::RCP< Teuchos::ParameterList > &constructorParams, const Teuchos::RCP< Teuchos::ParameterList > &fillCompleteParams, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market input stream.
static trcp_tcomm_t getComm(const Teuchos::RCP< T > &obj)
Return obj MPI communicator or Teuchos::null.
static Teuchos::RCP< const map_type > readMap(std::istream &in, const trcp_tcomm_t &comm, const Teuchos::RCP< Teuchos::FancyOStream > &err, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read Map (as a MultiVector) from the given input stream, with optional debugging output stream...
static void writeDenseFile(const std::string &filename, const Teuchos::RCP< const multivector_type > &X, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with no matrix name or description.
SparseMatrixType::global_ordinal_type global_ordinal_type
Type of indices as read from the Matrix Market file.
static Teuchos::RCP< sparse_matrix_type > readSparse(std::istream &in, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market input stream, with provided Maps. ...
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator, in rank order.
static Teuchos::RCP< sparse_matrix_type > readSparseFile(const std::string &filename, const trcp_tcomm_t &comm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market file.
static void writeSparseGraph(std::ostream &out, const crs_graph_type &graph, const bool debug=false)
Print the sparse graph in Matrix Market format to the given output stream, with no comments...
Teuchos::ArrayView< const global_ordinal_type > getLocalElementList() const
Return a NONOWNING view of the global indices owned by this process.
static Teuchos::RCP< sparse_matrix_type > readSparsePerRank(const std::string &filename_prefix, const std::string &filename_suffix, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const int ranksToReadAtOnce=8, const bool debug=false)
Read a Tpetra::CrsMatrix from a file per rank setup.
size_t global_size_t
Global size_t object.
SparseMatrixType::node_type node_type
The Kokkos Node type; fourth template parameter of Tpetra::CrsMatrix.
static void writeSparsePerRank(const std::string &filename_prefix, const std::string &filename_suffix, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const int ranksToWriteAtOnce=8, const bool debug=false)
Write a Tpetra::CrsMatrix to a file per rank.
static void writeOperator(const std::string &fileName, const operator_type &A, const Teuchos::ParameterList ¶ms)
Write a Tpetra::Operator to a file, with options.
Map< local_ordinal_type, global_ordinal_type, node_type > map_type
Specialization of Tpetra::Map that matches SparseMatrixType.
static Teuchos::RCP< multivector_type > readDenseFile(const std::string &filename, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read dense matrix (as a MultiVector) from the given Matrix Market file.
Insert new values that don't currently exist.
SparseMatrixType::scalar_type scalar_type
Type of the entries of the sparse matrix.
static void writeMapFile(const std::string &filename, const map_type &map)
Write the Map to the given file.
Abstract interface for operators (e.g., matrices and preconditioners).
static Teuchos::RCP< sparse_graph_type > readSparseGraph(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int >> &pComm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market input stream.
static void writeSparseGraphFile(const std::string &filename, const Teuchos::RCP< const crs_graph_type > &pGraph, const std::string &graphName, const std::string &graphDescription, const bool debug=false)
Print the sparse graph in Matrix Market format to the given file (by filename), taking the graph by T...
Teuchos::RCP< const Teuchos::Comm< int >> trcp_tcomm_t
Type of the MPI communicator.
static void writeSparse(std::ostream &out, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Print the sparse matrix in Matrix Market format, with comments.
CrsGraph< local_ordinal_type, global_ordinal_type, node_type > crs_graph_type
Specialization of Tpetra::CrsGraph that matches SparseMatrixType.
static Teuchos::RCP< vector_type > readVector(std::istream &in, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read Vector from the given Matrix Market input stream.
static void writeDense(std::ostream &out, const Teuchos::RCP< const multivector_type > &X, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with no matrix name or description.
static Teuchos::RCP< sparse_matrix_type > readSparseFile(const std::string &filename, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market file, with provided Maps.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
static void writeSparseFile(const std::string &filename, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Print the sparse matrix in Matrix Market format, with comments.
From a distributed map build a map with all GIDs on the root node.
static int getRank(const trcp_tcomm_t &comm)
Return MPI rank or 0.
static void writeSparseFile(const std::string &filename, const sparse_matrix_type &matrix, const bool debug=false)
Print the sparse matrix in Matrix Market format.
Teuchos::RCP< const Teuchos::Comm< int >> trcp_tcomm_t
Type of the MPI communicator.
static void writeMap(std::ostream &out, const map_type &map, const Teuchos::RCP< Teuchos::FancyOStream > &err, const bool debug=false)
Print the Map to the given output stream out.
static void writeSparseGraphFile(const std::string &filename, const crs_graph_type &graph, const bool debug=false)
Print the sparse graph in Matrix Market format to the given file (by filename), with no comments...
Teuchos::RCP< const map_type > getRangeMap() const override
Returns the Map associated with the domain of this graph.
static void writeDense(std::ostream &out, const multivector_type &X, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with no matrix name or description.
static void writeSparse(std::ostream &out, const Teuchos::RCP< const sparse_matrix_type > &pMatrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Only for backwards compatibility; prefer the overload above.
static void writeSparseFile(const std::string &filename, const Teuchos::RCP< const sparse_matrix_type > &pMatrix, const bool debug=false)
Only for backwards compatibility; prefer the overload above.
Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(const size_t j) const
Return a Vector which is a const view of column j.
static Teuchos::RCP< sparse_graph_type > readSparseGraph(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int >> &pComm, const Teuchos::RCP< Teuchos::ParameterList > &constructorParams, const Teuchos::RCP< Teuchos::ParameterList > &fillCompleteParams, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market input stream.
MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > multivector_type
The MultiVector specialization associated with SparseMatrixType.
void start()
Start the deep_copy counter.
static void writeSparseGraphFile(const std::string &filename, const crs_graph_type &graph, const std::string &graphName, const std::string &graphDescription, const bool debug=false)
Print the sparse graph in Matrix Market format to the given file (by filename).
global_ordinal_type getMinGlobalIndex() const
The minimum global index owned by the calling process.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > vector_type
The Vector specialization associated with SparseMatrixType.
static Teuchos::RCP< sparse_graph_type > readSparseGraphFile(const std::string &filename, const Teuchos::RCP< const Teuchos::Comm< int >> &pComm, const Teuchos::RCP< Teuchos::ParameterList > &constructorParams, const Teuchos::RCP< Teuchos::ParameterList > &fillCompleteParams, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market file.
A parallel distribution of indices over processes.
static Teuchos::RCP< sparse_matrix_type > readSparse(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int >> &pComm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market input stream.
void fillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Tell the graph that you are done changing its structure.
void getLocalRowView(const LocalOrdinal lclRow, local_inds_host_view_type &lclColInds) const override
Get a const view of the given local row's local column indices.
A distributed dense vector.
static void writeSparseGraph(std::ostream &out, const crs_graph_type &graph, const std::string &graphName, const std::string &graphDescription, const bool debug=false)
Print the sparse graph in Matrix Market format to the given output stream.
CrsGraph< local_ordinal_type, global_ordinal_type, node_type > sparse_graph_type
The CrsGraph specialization associated with SparseMatrixType.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
Returns the communicator.
SparseMatrixType sparse_matrix_type
This class' template parameter; a specialization of CrsMatrix.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
SparseMatrixType sparse_matrix_type
Template parameter of this class; specialization of CrsMatrix.
static Teuchos::RCP< sparse_graph_type > readSparseGraph(std::istream &in, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market input stream, with provided Maps. ...
static void writeDenseFile(const std::string &filename, const multivector_type &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
static void writeOperator(std::ostream &out, const operator_type &A, const Teuchos::ParameterList ¶ms)
Write a Tpetra::Operator to an output stream, with options.
global_size_t getGlobalNumEntries() const override
Returns the global number of entries in the graph.
Matrix Market file reader for CrsMatrix and MultiVector.
Matrix Market file writer for CrsMatrix and MultiVector.
static void writeSparse(std::ostream &out, const Teuchos::RCP< const sparse_matrix_type > &pMatrix, const bool debug=false)
Only for backwards compatibility; prefer the overload above.
void getGlobalRowView(const global_ordinal_type gblRow, global_inds_host_view_type &gblColInds) const override
Get a const view of the given global row's global column indices.
void stop()
Stop the deep_copy counter.
static void writeDense(std::ostream &out, const Teuchos::RCP< const multivector_type > &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and or description.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
static void writeOperator(const std::string &fileName, operator_type const &A)
Write a Tpetra::Operator to a file.