42 #ifndef __MatrixMarket_Tpetra_hpp
43 #define __MatrixMarket_Tpetra_hpp
57 #include "Tpetra_CrsMatrix.hpp"
58 #include "Tpetra_Operator.hpp"
59 #include "Tpetra_Vector.hpp"
61 #include "Teuchos_MatrixMarket_Raw_Adder.hpp"
62 #include "Teuchos_MatrixMarket_Raw_Graph_Adder.hpp"
63 #include "Teuchos_MatrixMarket_SymmetrizingAdder.hpp"
64 #include "Teuchos_MatrixMarket_SymmetrizingGraphAdder.hpp"
65 #include "Teuchos_MatrixMarket_assignScalar.hpp"
66 #include "Teuchos_MatrixMarket_Banner.hpp"
67 #include "Teuchos_MatrixMarket_CoordDataReader.hpp"
68 #include "Teuchos_SetScientific.hpp"
108 namespace MatrixMarket {
164 template<
class SparseMatrixType>
169 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
184 typedef typename SparseMatrixType::global_ordinal_type
206 typedef Teuchos::Comm<int> comm_type;
216 typedef Teuchos::ArrayRCP<int>::size_type size_type;
228 static Teuchos::RCP<const map_type>
229 makeRangeMap (
const Teuchos::RCP<const comm_type>& pComm,
233 return rcp (
new map_type (static_cast<global_size_t> (numRows),
234 static_cast<global_ordinal_type> (0),
235 pComm, GloballyDistributed));
265 static Teuchos::RCP<const map_type>
266 makeRowMap (
const Teuchos::RCP<const map_type>& pRowMap,
267 const Teuchos::RCP<const comm_type>& pComm,
272 if (pRowMap.is_null ()) {
273 return rcp (
new map_type (static_cast<global_size_t> (numRows),
274 static_cast<global_ordinal_type> (0),
275 pComm, GloballyDistributed));
278 TEUCHOS_TEST_FOR_EXCEPTION
279 (! pRowMap->isDistributed () && pComm->getSize () > 1,
280 std::invalid_argument,
"The specified row map is not distributed, "
281 "but the given communicator includes more than one process (in "
282 "fact, there are " << pComm->getSize () <<
" processes).");
283 TEUCHOS_TEST_FOR_EXCEPTION
284 (pRowMap->getComm () != pComm, std::invalid_argument,
285 "The specified row Map's communicator (pRowMap->getComm()) "
286 "differs from the given separately supplied communicator pComm.");
305 static Teuchos::RCP<const map_type>
306 makeDomainMap (
const Teuchos::RCP<const map_type>& pRangeMap,
315 if (numRows == numCols) {
318 return createUniformContigMapWithNode<LO,GO,NT> (numCols,
319 pRangeMap->getComm ());
396 distribute (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
397 Teuchos::ArrayRCP<size_t>& myRowPtr,
398 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
399 Teuchos::ArrayRCP<scalar_type>& myValues,
400 const Teuchos::RCP<const map_type>& pRowMap,
401 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
402 Teuchos::ArrayRCP<size_t>& rowPtr,
403 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
404 Teuchos::ArrayRCP<scalar_type>& values,
405 const bool debug=
false)
408 using Teuchos::ArrayRCP;
409 using Teuchos::ArrayView;
412 using Teuchos::CommRequest;
415 using Teuchos::receive;
420 const bool extraDebug =
false;
421 RCP<const comm_type> pComm = pRowMap->getComm ();
422 const int numProcs = pComm->getSize ();
423 const int myRank = pComm->getRank ();
424 const int rootRank = 0;
431 ArrayView<const GO> myRows = pRowMap->getNodeElementList();
432 const size_type myNumRows = myRows.size();
433 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<size_t>(myNumRows) !=
434 pRowMap->getNodeNumElements(),
436 "pRowMap->getNodeElementList().size() = "
438 <<
" != pRowMap->getNodeNumElements() = "
439 << pRowMap->getNodeNumElements() <<
". "
440 "Please report this bug to the Tpetra developers.");
441 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
443 "On Proc 0: numEntriesPerRow.size() = "
444 << numEntriesPerRow.size()
445 <<
" != pRowMap->getNodeElementList().size() = "
446 << myNumRows <<
". Please report this bug to the "
447 "Tpetra developers.");
451 myNumEntriesPerRow = arcp<size_t> (myNumRows);
453 if (myRank != rootRank) {
457 send (*pComm, myNumRows, rootRank);
458 if (myNumRows != 0) {
462 send (*pComm, static_cast<int> (myNumRows),
463 myRows.getRawPtr(), rootRank);
473 receive (*pComm, rootRank,
474 static_cast<int> (myNumRows),
475 myNumEntriesPerRow.getRawPtr());
480 std::accumulate (myNumEntriesPerRow.begin(),
481 myNumEntriesPerRow.end(), 0);
487 myColInd = arcp<GO> (myNumEntries);
488 myValues = arcp<scalar_type> (myNumEntries);
489 if (myNumEntries > 0) {
492 receive (*pComm, rootRank,
493 static_cast<int> (myNumEntries),
494 myColInd.getRawPtr());
495 receive (*pComm, rootRank,
496 static_cast<int> (myNumEntries),
497 myValues.getRawPtr());
503 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
507 for (size_type k = 0; k < myNumRows; ++k) {
508 const GO myCurRow = myRows[k];
510 myNumEntriesPerRow[k] = numEntriesInThisRow;
512 if (extraDebug && debug) {
513 cerr <<
"Proc " << pRowMap->getComm ()->getRank ()
514 <<
": myNumEntriesPerRow[0.." << (myNumRows-1) <<
"] = [";
515 for (size_type k = 0; k < myNumRows; ++k) {
516 cerr << myNumEntriesPerRow[k];
517 if (k < myNumRows-1) {
525 std::accumulate (myNumEntriesPerRow.begin(),
526 myNumEntriesPerRow.end(), 0);
528 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
529 << myNumEntries <<
" entries" << endl;
531 myColInd = arcp<GO> (myNumEntries);
532 myValues = arcp<scalar_type> (myNumEntries);
540 for (size_type k = 0; k < myNumRows;
541 myCurPos += myNumEntriesPerRow[k], ++k) {
543 const GO myRow = myRows[k];
544 const size_t curPos = rowPtr[myRow];
547 if (curNumEntries > 0) {
548 ArrayView<GO> colIndView = colInd (curPos, curNumEntries);
549 ArrayView<GO> myColIndView = myColInd (myCurPos, curNumEntries);
550 std::copy (colIndView.begin(), colIndView.end(),
551 myColIndView.begin());
553 ArrayView<scalar_type> valuesView =
554 values (curPos, curNumEntries);
555 ArrayView<scalar_type> myValuesView =
556 myValues (myCurPos, curNumEntries);
557 std::copy (valuesView.begin(), valuesView.end(),
558 myValuesView.begin());
563 for (
int p = 1; p < numProcs; ++p) {
565 cerr <<
"-- Proc 0: Processing proc " << p << endl;
568 size_type theirNumRows = 0;
573 receive (*pComm, p, &theirNumRows);
575 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
576 << theirNumRows <<
" rows" << endl;
578 if (theirNumRows != 0) {
583 ArrayRCP<GO> theirRows = arcp<GO> (theirNumRows);
584 receive (*pComm, p, as<int> (theirNumRows),
585 theirRows.getRawPtr ());
594 const global_size_t numRows = pRowMap->getGlobalNumElements ();
595 const GO indexBase = pRowMap->getIndexBase ();
596 bool theirRowsValid =
true;
597 for (size_type k = 0; k < theirNumRows; ++k) {
598 if (theirRows[k] < indexBase ||
599 as<global_size_t> (theirRows[k] - indexBase) >= numRows) {
600 theirRowsValid =
false;
603 if (! theirRowsValid) {
604 TEUCHOS_TEST_FOR_EXCEPTION(
605 ! theirRowsValid, std::logic_error,
606 "Proc " << p <<
" has at least one invalid row index. "
607 "Here are all of them: " <<
608 Teuchos::toString (theirRows ()) <<
". Valid row index "
609 "range (zero-based): [0, " << (numRows - 1) <<
"].");
624 ArrayRCP<size_t> theirNumEntriesPerRow;
625 theirNumEntriesPerRow = arcp<size_t> (theirNumRows);
626 for (size_type k = 0; k < theirNumRows; ++k) {
627 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
634 send (*pComm, static_cast<int> (theirNumRows),
635 theirNumEntriesPerRow.getRawPtr(), p);
639 std::accumulate (theirNumEntriesPerRow.begin(),
640 theirNumEntriesPerRow.end(), 0);
643 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
644 << theirNumEntries <<
" entries" << endl;
649 if (theirNumEntries == 0) {
658 ArrayRCP<GO> theirColInd (theirNumEntries);
659 ArrayRCP<scalar_type> theirValues (theirNumEntries);
667 for (size_type k = 0; k < theirNumRows;
668 theirCurPos += theirNumEntriesPerRow[k], k++) {
670 const GO theirRow = theirRows[k];
676 if (curNumEntries > 0) {
677 ArrayView<GO> colIndView =
678 colInd (curPos, curNumEntries);
679 ArrayView<GO> theirColIndView =
680 theirColInd (theirCurPos, curNumEntries);
681 std::copy (colIndView.begin(), colIndView.end(),
682 theirColIndView.begin());
684 ArrayView<scalar_type> valuesView =
685 values (curPos, curNumEntries);
686 ArrayView<scalar_type> theirValuesView =
687 theirValues (theirCurPos, curNumEntries);
688 std::copy (valuesView.begin(), valuesView.end(),
689 theirValuesView.begin());
696 send (*pComm, static_cast<int> (theirNumEntries),
697 theirColInd.getRawPtr(), p);
698 send (*pComm, static_cast<int> (theirNumEntries),
699 theirValues.getRawPtr(), p);
702 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
710 numEntriesPerRow = null;
715 if (debug && myRank == 0) {
716 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
724 myRowPtr = arcp<size_t> (myNumRows+1);
726 for (size_type k = 1; k < myNumRows+1; ++k) {
727 myRowPtr[k] = myRowPtr[k-1] + myNumEntriesPerRow[k-1];
729 if (extraDebug && debug) {
730 cerr <<
"Proc " << Teuchos::rank (*(pRowMap->getComm()))
731 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
732 for (size_type k = 0; k < myNumRows+1; ++k) {
738 cerr <<
"]" << endl << endl;
741 if (debug && myRank == 0) {
742 cerr <<
"-- Proc 0: Done with distribute" << endl;
759 static Teuchos::RCP<sparse_matrix_type>
760 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
761 Teuchos::ArrayRCP<size_t>& myRowPtr,
762 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
763 Teuchos::ArrayRCP<scalar_type>& myValues,
764 const Teuchos::RCP<const map_type>& pRowMap,
765 const Teuchos::RCP<const map_type>& pRangeMap,
766 const Teuchos::RCP<const map_type>& pDomainMap,
767 const bool callFillComplete =
true)
769 using Teuchos::ArrayView;
783 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
784 "makeMatrix: myRowPtr array is null. "
785 "Please report this bug to the Tpetra developers.");
786 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
787 "makeMatrix: domain map is null. "
788 "Please report this bug to the Tpetra developers.");
789 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
790 "makeMatrix: range map is null. "
791 "Please report this bug to the Tpetra developers.");
792 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
793 "makeMatrix: row map is null. "
794 "Please report this bug to the Tpetra developers.");
798 RCP<sparse_matrix_type> A =
804 ArrayView<const GO> myRows = pRowMap->getNodeElementList ();
805 const size_type myNumRows = myRows.size ();
808 const GO indexBase = pRowMap->getIndexBase ();
809 for (size_type i = 0; i < myNumRows; ++i) {
810 const size_type myCurPos = myRowPtr[i];
812 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
813 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
816 for (size_type k = 0; k < curNumEntries; ++k) {
817 curColInd[k] += indexBase;
820 if (curNumEntries > 0) {
821 A->insertGlobalValues (myRows[i], curColInd, curValues);
828 myNumEntriesPerRow = null;
833 if (callFillComplete) {
834 A->fillComplete (pDomainMap, pRangeMap);
844 static Teuchos::RCP<sparse_matrix_type>
845 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
846 Teuchos::ArrayRCP<size_t>& myRowPtr,
847 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
848 Teuchos::ArrayRCP<scalar_type>& myValues,
849 const Teuchos::RCP<const map_type>& pRowMap,
850 const Teuchos::RCP<const map_type>& pRangeMap,
851 const Teuchos::RCP<const map_type>& pDomainMap,
852 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
853 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams)
855 using Teuchos::ArrayView;
869 TEUCHOS_TEST_FOR_EXCEPTION(
870 myRowPtr.is_null(), std::logic_error,
871 "makeMatrix: myRowPtr array is null. "
872 "Please report this bug to the Tpetra developers.");
873 TEUCHOS_TEST_FOR_EXCEPTION(
874 pDomainMap.is_null(), std::logic_error,
875 "makeMatrix: domain map is null. "
876 "Please report this bug to the Tpetra developers.");
877 TEUCHOS_TEST_FOR_EXCEPTION(
878 pRangeMap.is_null(), std::logic_error,
879 "makeMatrix: range map is null. "
880 "Please report this bug to the Tpetra developers.");
881 TEUCHOS_TEST_FOR_EXCEPTION(
882 pRowMap.is_null(), std::logic_error,
883 "makeMatrix: row map is null. "
884 "Please report this bug to the Tpetra developers.");
888 RCP<sparse_matrix_type> A =
890 StaticProfile, constructorParams));
894 ArrayView<const GO> myRows = pRowMap->getNodeElementList();
895 const size_type myNumRows = myRows.size();
898 const GO indexBase = pRowMap->getIndexBase ();
899 for (size_type i = 0; i < myNumRows; ++i) {
900 const size_type myCurPos = myRowPtr[i];
902 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
903 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
906 for (size_type k = 0; k < curNumEntries; ++k) {
907 curColInd[k] += indexBase;
909 if (curNumEntries > 0) {
910 A->insertGlobalValues (myRows[i], curColInd, curValues);
917 myNumEntriesPerRow = null;
922 A->fillComplete (pDomainMap, pRangeMap, fillCompleteParams);
930 static Teuchos::RCP<sparse_matrix_type>
931 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
932 Teuchos::ArrayRCP<size_t>& myRowPtr,
933 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
934 Teuchos::ArrayRCP<scalar_type>& myValues,
935 const Teuchos::RCP<const map_type>& rowMap,
936 Teuchos::RCP<const map_type>& colMap,
937 const Teuchos::RCP<const map_type>& domainMap,
938 const Teuchos::RCP<const map_type>& rangeMap,
939 const bool callFillComplete =
true)
941 using Teuchos::ArrayView;
950 RCP<sparse_matrix_type> A;
951 if (colMap.is_null ()) {
959 ArrayView<const GO> myRows = rowMap->getNodeElementList ();
960 const size_type myNumRows = myRows.size ();
963 const GO indexBase = rowMap->getIndexBase ();
964 for (size_type i = 0; i < myNumRows; ++i) {
965 const size_type myCurPos = myRowPtr[i];
966 const size_type curNumEntries = as<size_type> (myNumEntriesPerRow[i]);
967 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
968 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
971 for (size_type k = 0; k < curNumEntries; ++k) {
972 curColInd[k] += indexBase;
974 if (curNumEntries > 0) {
975 A->insertGlobalValues (myRows[i], curColInd, curValues);
982 myNumEntriesPerRow = null;
987 if (callFillComplete) {
988 A->fillComplete (domainMap, rangeMap);
989 if (colMap.is_null ()) {
990 colMap = A->getColMap ();
1014 static Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
1015 readBanner (std::istream& in,
1017 const bool tolerant=
false,
1019 const bool isGraph=
false)
1021 using Teuchos::MatrixMarket::Banner;
1026 typedef Teuchos::ScalarTraits<scalar_type> STS;
1028 RCP<Banner> pBanner;
1032 const bool readFailed = ! getline(in, line);
1033 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
1034 "Failed to get Matrix Market banner line from input.");
1041 pBanner = rcp (
new Banner (line, tolerant));
1042 }
catch (std::exception& e) {
1043 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1044 "Matrix Market banner line contains syntax error(s): "
1047 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
1048 std::invalid_argument,
"The Matrix Market file does not contain "
1049 "matrix data. Its Banner (first) line says that its object type is \""
1050 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
1054 TEUCHOS_TEST_FOR_EXCEPTION(
1055 ! STS::isComplex && pBanner->dataType() ==
"complex",
1056 std::invalid_argument,
1057 "The Matrix Market file contains complex-valued data, but you are "
1058 "trying to read it into a matrix containing entries of the real-"
1059 "valued Scalar type \""
1060 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
1061 TEUCHOS_TEST_FOR_EXCEPTION(
1063 pBanner->dataType() !=
"real" &&
1064 pBanner->dataType() !=
"complex" &&
1065 pBanner->dataType() !=
"integer",
1066 std::invalid_argument,
1067 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
1068 "Matrix Market file may not contain a \"pattern\" matrix. A "
1069 "pattern matrix is really just a graph with no weights. It "
1070 "should be stored in a CrsGraph, not a CrsMatrix.");
1072 TEUCHOS_TEST_FOR_EXCEPTION(
1074 pBanner->dataType() !=
"pattern",
1075 std::invalid_argument,
1076 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
1077 "Matrix Market file must contain a \"pattern\" matrix.");
1104 static Teuchos::Tuple<global_ordinal_type, 3>
1105 readCoordDims (std::istream& in,
1107 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1108 const Teuchos::RCP<const comm_type>& pComm,
1109 const bool tolerant =
false,
1112 using Teuchos::MatrixMarket::readCoordinateDimensions;
1113 using Teuchos::Tuple;
1118 Tuple<global_ordinal_type, 3> dims;
1124 bool success =
false;
1125 if (pComm->getRank() == 0) {
1126 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
1127 std::invalid_argument,
"The Tpetra::CrsMatrix Matrix Market reader "
1128 "only accepts \"coordinate\" (sparse) matrix data.");
1132 success = readCoordinateDimensions (in, numRows, numCols,
1133 numNonzeros, lineNumber,
1139 dims[2] = numNonzeros;
1147 int the_success = success ? 1 : 0;
1148 Teuchos::broadcast (*pComm, 0, &the_success);
1149 success = (the_success == 1);
1154 Teuchos::broadcast (*pComm, 0, dims);
1162 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1163 "Error reading Matrix Market sparse matrix: failed to read "
1164 "coordinate matrix dimensions.");
1179 typedef Teuchos::MatrixMarket::SymmetrizingAdder<Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type> > adder_type;
1181 typedef Teuchos::MatrixMarket::SymmetrizingGraphAdder<Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> > graph_adder_type;
1208 static Teuchos::RCP<adder_type>
1209 makeAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1210 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1211 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1212 const bool tolerant=
false,
1213 const bool debug=
false)
1215 if (pComm->getRank () == 0) {
1216 typedef Teuchos::MatrixMarket::Raw::Adder<
scalar_type,
1219 Teuchos::RCP<raw_adder_type> pRaw =
1220 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1222 return Teuchos::rcp (
new adder_type (pRaw, pBanner->symmType ()));
1225 return Teuchos::null;
1254 static Teuchos::RCP<graph_adder_type>
1255 makeGraphAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1256 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1257 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1258 const bool tolerant=
false,
1259 const bool debug=
false)
1261 if (pComm->getRank () == 0) {
1262 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
1263 Teuchos::RCP<raw_adder_type> pRaw =
1264 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1266 return Teuchos::rcp (
new graph_adder_type (pRaw, pBanner->symmType ()));
1269 return Teuchos::null;
1274 static Teuchos::RCP<sparse_graph_type>
1275 readSparseGraphHelper (std::istream& in,
1276 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1277 const Teuchos::RCP<const map_type>& rowMap,
1278 Teuchos::RCP<const map_type>& colMap,
1279 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1280 const bool tolerant,
1283 using Teuchos::MatrixMarket::Banner;
1286 using Teuchos::Tuple;
1290 const int myRank = pComm->getRank ();
1291 const int rootRank = 0;
1296 size_t lineNumber = 1;
1298 if (debug && myRank == rootRank) {
1299 cerr <<
"Matrix Market reader: readGraph:" << endl
1300 <<
"-- Reading banner line" << endl;
1309 RCP<const Banner> pBanner;
1315 int bannerIsCorrect = 1;
1316 std::ostringstream errMsg;
1318 if (myRank == rootRank) {
1321 pBanner = readBanner (in, lineNumber, tolerant, debug,
true);
1323 catch (std::exception& e) {
1324 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1325 "threw an exception: " << e.what();
1326 bannerIsCorrect = 0;
1329 if (bannerIsCorrect) {
1334 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
1335 bannerIsCorrect = 0;
1336 errMsg <<
"The Matrix Market input file must contain a "
1337 "\"coordinate\"-format sparse graph in order to create a "
1338 "Tpetra::CrsGraph object from it, but the file's matrix "
1339 "type is \"" << pBanner->matrixType() <<
"\" instead.";
1344 if (tolerant && pBanner->matrixType() ==
"array") {
1345 bannerIsCorrect = 0;
1346 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1347 "format sparse graph in order to create a Tpetra::CrsGraph "
1348 "object from it, but the file's matrix type is \"array\" "
1349 "instead. That probably means the file contains dense matrix "
1356 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
1363 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
1364 std::invalid_argument, errMsg.str ());
1366 if (debug && myRank == rootRank) {
1367 cerr <<
"-- Reading dimensions line" << endl;
1375 Tuple<global_ordinal_type, 3> dims =
1376 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
1378 if (debug && myRank == rootRank) {
1379 cerr <<
"-- Making Adder for collecting graph data" << endl;
1386 RCP<graph_adder_type> pAdder =
1387 makeGraphAdder (pComm, pBanner, dims, tolerant, debug);
1389 if (debug && myRank == rootRank) {
1390 cerr <<
"-- Reading graph data" << endl;
1400 int readSuccess = 1;
1401 std::ostringstream errMsg;
1402 if (myRank == rootRank) {
1405 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
1407 reader_type reader (pAdder);
1410 std::pair<bool, std::vector<size_t> > results =
1411 reader.read (in, lineNumber, tolerant, debug);
1412 readSuccess = results.first ? 1 : 0;
1414 catch (std::exception& e) {
1419 broadcast (*pComm, rootRank, ptr (&readSuccess));
1428 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1429 "Failed to read the Matrix Market sparse graph file: "
1433 if (debug && myRank == rootRank) {
1434 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1447 if (debug && myRank == rootRank) {
1448 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1450 <<
"----- Dimensions before: "
1451 << dims[0] <<
" x " << dims[1]
1455 Tuple<global_ordinal_type, 2> updatedDims;
1456 if (myRank == rootRank) {
1463 std::max (dims[0], pAdder->getAdder()->numRows());
1464 updatedDims[1] = pAdder->getAdder()->numCols();
1466 broadcast (*pComm, rootRank, updatedDims);
1467 dims[0] = updatedDims[0];
1468 dims[1] = updatedDims[1];
1469 if (debug && myRank == rootRank) {
1470 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1484 if (myRank == rootRank) {
1491 if (dims[0] < pAdder->getAdder ()->numRows ()) {
1495 broadcast (*pComm, 0, ptr (&dimsMatch));
1496 if (dimsMatch == 0) {
1503 Tuple<global_ordinal_type, 2> addersDims;
1504 if (myRank == rootRank) {
1505 addersDims[0] = pAdder->getAdder()->numRows();
1506 addersDims[1] = pAdder->getAdder()->numCols();
1508 broadcast (*pComm, 0, addersDims);
1509 TEUCHOS_TEST_FOR_EXCEPTION(
1510 dimsMatch == 0, std::runtime_error,
1511 "The graph metadata says that the graph is " << dims[0] <<
" x "
1512 << dims[1] <<
", but the actual data says that the graph is "
1513 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1514 "data includes more rows than reported in the metadata. This "
1515 "is not allowed when parsing in strict mode. Parse the graph in "
1516 "tolerant mode to ignore the metadata when it disagrees with the "
1522 RCP<map_type> proc0Map;
1524 if(Teuchos::is_null(rowMap)) {
1528 indexBase = rowMap->getIndexBase();
1530 if(myRank == rootRank) {
1531 proc0Map = rcp(
new map_type(dims[0],dims[0],indexBase,pComm));
1534 proc0Map = rcp(
new map_type(dims[0],0,indexBase,pComm));
1538 std::map<global_ordinal_type, size_t> numEntriesPerRow_map;
1539 if (myRank == rootRank) {
1540 const auto& entries = pAdder()->getAdder()->getEntries();
1545 for (
const auto& entry : entries) {
1547 ++numEntriesPerRow_map[gblRow];
1551 Teuchos::Array<size_t> numEntriesPerRow (proc0Map->getNodeNumElements ());
1552 for (
const auto& ent : numEntriesPerRow_map) {
1554 numEntriesPerRow[lclRow] = ent.second;
1561 std::map<global_ordinal_type, size_t> empty_map;
1562 std::swap (numEntriesPerRow_map, empty_map);
1565 RCP<sparse_graph_type> proc0Graph =
1567 StaticProfile,constructorParams));
1568 if(myRank == rootRank) {
1569 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1572 const std::vector<element_type>& entries =
1573 pAdder->getAdder()->getEntries();
1576 for(
size_t curPos=0; curPos<entries.size(); curPos++) {
1577 const element_type& curEntry = entries[curPos];
1580 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol,1);
1581 proc0Graph->insertGlobalIndices(curRow,colView);
1584 proc0Graph->fillComplete();
1586 RCP<sparse_graph_type> distGraph;
1587 if(Teuchos::is_null(rowMap))
1590 RCP<map_type> distMap =
1591 rcp(
new map_type(dims[0],0,pComm,GloballyDistributed));
1594 distGraph = rcp(
new sparse_graph_type(distMap,colMap,0,StaticProfile,constructorParams));
1597 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1598 import_type importer (proc0Map, distMap);
1601 distGraph->doImport(*proc0Graph,importer,
INSERT);
1604 distGraph = rcp(
new sparse_graph_type(rowMap,colMap,0,StaticProfile,constructorParams));
1607 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1608 import_type importer (proc0Map, rowMap);
1611 distGraph->doImport(*proc0Graph,importer,
INSERT);
1641 static Teuchos::RCP<sparse_graph_type>
1643 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1644 const bool callFillComplete=
true,
1645 const bool tolerant=
false,
1646 const bool debug=
false)
1648 using Teuchos::broadcast;
1649 using Teuchos::outArg;
1657 if (comm->getRank () == 0) {
1659 in.open (filename.c_str ());
1666 broadcast<int, int> (*comm, 0, outArg (opened));
1667 TEUCHOS_TEST_FOR_EXCEPTION
1668 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1669 "Failed to open file \"" << filename <<
"\" on Process 0.");
1707 static Teuchos::RCP<sparse_graph_type>
1709 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1710 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1711 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1712 const bool tolerant=
false,
1713 const bool debug=
false)
1715 using Teuchos::broadcast;
1716 using Teuchos::outArg;
1724 if (pComm->getRank () == 0) {
1726 in.open (filename.c_str ());
1733 broadcast<int, int> (*pComm, 0, outArg (opened));
1734 TEUCHOS_TEST_FOR_EXCEPTION
1735 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1736 "Failed to open file \"" << filename <<
"\" on Process 0.");
1737 if (pComm->getRank () == 0) {
1738 in.open (filename.c_str ());
1742 fillCompleteParams, tolerant, debug);
1786 static Teuchos::RCP<sparse_graph_type>
1788 const Teuchos::RCP<const map_type>& rowMap,
1789 Teuchos::RCP<const map_type>& colMap,
1790 const Teuchos::RCP<const map_type>& domainMap,
1791 const Teuchos::RCP<const map_type>& rangeMap,
1792 const bool callFillComplete=
true,
1793 const bool tolerant=
false,
1794 const bool debug=
false)
1796 using Teuchos::broadcast;
1797 using Teuchos::Comm;
1798 using Teuchos::outArg;
1801 TEUCHOS_TEST_FOR_EXCEPTION
1802 (rowMap.is_null (), std::invalid_argument,
1803 "Input rowMap must be nonnull.");
1804 RCP<const Comm<int> > comm = rowMap->getComm ();
1805 if (comm.is_null ()) {
1808 return Teuchos::null;
1817 if (comm->getRank () == 0) {
1819 in.open (filename.c_str ());
1826 broadcast<int, int> (*comm, 0, outArg (opened));
1827 TEUCHOS_TEST_FOR_EXCEPTION
1828 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1829 "Failed to open file \"" << filename <<
"\" on Process 0.");
1831 callFillComplete, tolerant, debug);
1859 static Teuchos::RCP<sparse_graph_type>
1861 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1862 const bool callFillComplete=
true,
1863 const bool tolerant=
false,
1864 const bool debug=
false)
1866 Teuchos::RCP<const map_type> fakeRowMap;
1867 Teuchos::RCP<const map_type> fakeColMap;
1868 Teuchos::RCP<Teuchos::ParameterList> fakeCtorParams;
1870 Teuchos::RCP<sparse_graph_type> graph =
1871 readSparseGraphHelper (in, pComm,
1872 fakeRowMap, fakeColMap,
1873 fakeCtorParams, tolerant, debug);
1874 if (callFillComplete) {
1875 graph->fillComplete ();
1910 static Teuchos::RCP<sparse_graph_type>
1912 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1913 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1914 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1915 const bool tolerant=
false,
1916 const bool debug=
false)
1918 Teuchos::RCP<const map_type> fakeRowMap;
1919 Teuchos::RCP<const map_type> fakeColMap;
1920 Teuchos::RCP<sparse_graph_type> graph =
1921 readSparseGraphHelper (in, pComm,
1922 fakeRowMap, fakeColMap,
1923 constructorParams, tolerant, debug);
1924 graph->fillComplete (fillCompleteParams);
1969 static Teuchos::RCP<sparse_graph_type>
1971 const Teuchos::RCP<const map_type>& rowMap,
1972 Teuchos::RCP<const map_type>& colMap,
1973 const Teuchos::RCP<const map_type>& domainMap,
1974 const Teuchos::RCP<const map_type>& rangeMap,
1975 const bool callFillComplete=
true,
1976 const bool tolerant=
false,
1977 const bool debug=
false)
1979 Teuchos::RCP<sparse_graph_type> graph =
1980 readSparseGraphHelper (in, rowMap->getComm (),
1981 rowMap, colMap, Teuchos::null, tolerant,
1983 if (callFillComplete) {
1984 graph->fillComplete (domainMap, rangeMap);
2012 static Teuchos::RCP<sparse_matrix_type>
2014 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2015 const bool callFillComplete=
true,
2016 const bool tolerant=
false,
2017 const bool debug=
false)
2019 const int myRank = pComm->getRank ();
2024 in.open (filename.c_str ());
2032 return readSparse (in, pComm, callFillComplete, tolerant, debug);
2067 static Teuchos::RCP<sparse_matrix_type>
2069 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2070 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2071 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2072 const bool tolerant=
false,
2073 const bool debug=
false)
2076 if (pComm->getRank () == 0) {
2077 in.open (filename.c_str ());
2079 return readSparse (in, pComm, constructorParams,
2080 fillCompleteParams, tolerant, debug);
2121 static Teuchos::RCP<sparse_matrix_type>
2123 const Teuchos::RCP<const map_type>& rowMap,
2124 Teuchos::RCP<const map_type>& colMap,
2125 const Teuchos::RCP<const map_type>& domainMap,
2126 const Teuchos::RCP<const map_type>& rangeMap,
2127 const bool callFillComplete=
true,
2128 const bool tolerant=
false,
2129 const bool debug=
false)
2131 using Teuchos::broadcast;
2132 using Teuchos::Comm;
2133 using Teuchos::outArg;
2136 TEUCHOS_TEST_FOR_EXCEPTION(
2137 rowMap.is_null (), std::invalid_argument,
2138 "Row Map must be nonnull.");
2140 RCP<const Comm<int> > comm = rowMap->getComm ();
2141 const int myRank = comm->getRank ();
2151 in.open (filename.c_str ());
2158 broadcast<int, int> (*comm, 0, outArg (opened));
2159 TEUCHOS_TEST_FOR_EXCEPTION(
2160 opened == 0, std::runtime_error,
2161 "readSparseFile: Failed to open file \"" << filename <<
"\" on "
2163 return readSparse (in, rowMap, colMap, domainMap, rangeMap,
2164 callFillComplete, tolerant, debug);
2192 static Teuchos::RCP<sparse_matrix_type>
2194 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2195 const bool callFillComplete=
true,
2196 const bool tolerant=
false,
2197 const bool debug=
false)
2199 using Teuchos::MatrixMarket::Banner;
2200 using Teuchos::arcp;
2201 using Teuchos::ArrayRCP;
2202 using Teuchos::broadcast;
2203 using Teuchos::null;
2206 using Teuchos::REDUCE_MAX;
2207 using Teuchos::reduceAll;
2208 using Teuchos::Tuple;
2211 typedef Teuchos::ScalarTraits<scalar_type> STS;
2213 const bool extraDebug =
false;
2214 const int myRank = pComm->getRank ();
2215 const int rootRank = 0;
2220 size_t lineNumber = 1;
2222 if (debug && myRank == rootRank) {
2223 cerr <<
"Matrix Market reader: readSparse:" << endl
2224 <<
"-- Reading banner line" << endl;
2233 RCP<const Banner> pBanner;
2239 int bannerIsCorrect = 1;
2240 std::ostringstream errMsg;
2242 if (myRank == rootRank) {
2245 pBanner = readBanner (in, lineNumber, tolerant, debug);
2247 catch (std::exception& e) {
2248 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2249 "threw an exception: " << e.what();
2250 bannerIsCorrect = 0;
2253 if (bannerIsCorrect) {
2258 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2259 bannerIsCorrect = 0;
2260 errMsg <<
"The Matrix Market input file must contain a "
2261 "\"coordinate\"-format sparse matrix in order to create a "
2262 "Tpetra::CrsMatrix object from it, but the file's matrix "
2263 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2268 if (tolerant && pBanner->matrixType() ==
"array") {
2269 bannerIsCorrect = 0;
2270 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2271 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2272 "object from it, but the file's matrix type is \"array\" "
2273 "instead. That probably means the file contains dense matrix "
2280 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2287 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2288 std::invalid_argument, errMsg.str ());
2290 if (debug && myRank == rootRank) {
2291 cerr <<
"-- Reading dimensions line" << endl;
2299 Tuple<global_ordinal_type, 3> dims =
2300 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2302 if (debug && myRank == rootRank) {
2303 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2308 RCP<adder_type> pAdder =
2309 makeAdder (pComm, pBanner, dims, tolerant, debug);
2311 if (debug && myRank == rootRank) {
2312 cerr <<
"-- Reading matrix data" << endl;
2322 int readSuccess = 1;
2323 std::ostringstream errMsg;
2324 if (myRank == rootRank) {
2327 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2329 reader_type reader (pAdder);
2332 std::pair<bool, std::vector<size_t> > results =
2333 reader.read (in, lineNumber, tolerant, debug);
2334 readSuccess = results.first ? 1 : 0;
2336 catch (std::exception& e) {
2341 broadcast (*pComm, rootRank, ptr (&readSuccess));
2350 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2351 "Failed to read the Matrix Market sparse matrix file: "
2355 if (debug && myRank == rootRank) {
2356 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2369 if (debug && myRank == rootRank) {
2370 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2372 <<
"----- Dimensions before: "
2373 << dims[0] <<
" x " << dims[1]
2377 Tuple<global_ordinal_type, 2> updatedDims;
2378 if (myRank == rootRank) {
2385 std::max (dims[0], pAdder->getAdder()->numRows());
2386 updatedDims[1] = pAdder->getAdder()->numCols();
2388 broadcast (*pComm, rootRank, updatedDims);
2389 dims[0] = updatedDims[0];
2390 dims[1] = updatedDims[1];
2391 if (debug && myRank == rootRank) {
2392 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2406 if (myRank == rootRank) {
2413 if (dims[0] < pAdder->getAdder ()->numRows ()) {
2417 broadcast (*pComm, 0, ptr (&dimsMatch));
2418 if (dimsMatch == 0) {
2425 Tuple<global_ordinal_type, 2> addersDims;
2426 if (myRank == rootRank) {
2427 addersDims[0] = pAdder->getAdder()->numRows();
2428 addersDims[1] = pAdder->getAdder()->numCols();
2430 broadcast (*pComm, 0, addersDims);
2431 TEUCHOS_TEST_FOR_EXCEPTION(
2432 dimsMatch == 0, std::runtime_error,
2433 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2434 << dims[1] <<
", but the actual data says that the matrix is "
2435 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2436 "data includes more rows than reported in the metadata. This "
2437 "is not allowed when parsing in strict mode. Parse the matrix in "
2438 "tolerant mode to ignore the metadata when it disagrees with the "
2443 if (debug && myRank == rootRank) {
2444 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2456 ArrayRCP<size_t> numEntriesPerRow;
2457 ArrayRCP<size_t> rowPtr;
2458 ArrayRCP<global_ordinal_type> colInd;
2459 ArrayRCP<scalar_type> values;
2464 int mergeAndConvertSucceeded = 1;
2465 std::ostringstream errMsg;
2467 if (myRank == rootRank) {
2469 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2479 const size_type numRows = dims[0];
2482 pAdder->getAdder()->merge ();
2485 const std::vector<element_type>& entries =
2486 pAdder->getAdder()->getEntries();
2489 const size_t numEntries = (size_t)entries.size();
2492 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2493 <<
" rows and numEntries=" << numEntries
2494 <<
" entries." << endl;
2500 numEntriesPerRow = arcp<size_t> (numRows);
2501 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2502 rowPtr = arcp<size_t> (numRows+1);
2503 std::fill (rowPtr.begin(), rowPtr.end(), 0);
2504 colInd = arcp<global_ordinal_type> (numEntries);
2505 values = arcp<scalar_type> (numEntries);
2512 for (curPos = 0; curPos < numEntries; ++curPos) {
2513 const element_type& curEntry = entries[curPos];
2515 TEUCHOS_TEST_FOR_EXCEPTION(
2516 curRow < prvRow, std::logic_error,
2517 "Row indices are out of order, even though they are supposed "
2518 "to be sorted. curRow = " << curRow <<
", prvRow = "
2519 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2520 "this bug to the Tpetra developers.");
2521 if (curRow > prvRow) {
2527 numEntriesPerRow[curRow]++;
2528 colInd[curPos] = curEntry.colIndex();
2529 values[curPos] = curEntry.value();
2534 rowPtr[numRows] = numEntries;
2536 catch (std::exception& e) {
2537 mergeAndConvertSucceeded = 0;
2538 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2539 "CSR format: " << e.what();
2542 if (debug && mergeAndConvertSucceeded) {
2544 const size_type numRows = dims[0];
2545 const size_type maxToDisplay = 100;
2547 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2548 << (numEntriesPerRow.size()-1) <<
"] ";
2549 if (numRows > maxToDisplay) {
2550 cerr <<
"(only showing first and last few entries) ";
2554 if (numRows > maxToDisplay) {
2555 for (size_type k = 0; k < 2; ++k) {
2556 cerr << numEntriesPerRow[k] <<
" ";
2559 for (size_type k = numRows-2; k < numRows-1; ++k) {
2560 cerr << numEntriesPerRow[k] <<
" ";
2564 for (size_type k = 0; k < numRows-1; ++k) {
2565 cerr << numEntriesPerRow[k] <<
" ";
2568 cerr << numEntriesPerRow[numRows-1];
2570 cerr <<
"]" << endl;
2572 cerr <<
"----- Proc 0: rowPtr ";
2573 if (numRows > maxToDisplay) {
2574 cerr <<
"(only showing first and last few entries) ";
2577 if (numRows > maxToDisplay) {
2578 for (size_type k = 0; k < 2; ++k) {
2579 cerr << rowPtr[k] <<
" ";
2582 for (size_type k = numRows-2; k < numRows; ++k) {
2583 cerr << rowPtr[k] <<
" ";
2587 for (size_type k = 0; k < numRows; ++k) {
2588 cerr << rowPtr[k] <<
" ";
2591 cerr << rowPtr[numRows] <<
"]" << endl;
2602 if (debug && myRank == rootRank) {
2603 cerr <<
"-- Making range, domain, and row maps" << endl;
2610 RCP<const map_type> pRangeMap = makeRangeMap (pComm, dims[0]);
2611 RCP<const map_type> pDomainMap =
2612 makeDomainMap (pRangeMap, dims[0], dims[1]);
2613 RCP<const map_type> pRowMap = makeRowMap (null, pComm, dims[0]);
2615 if (debug && myRank == rootRank) {
2616 cerr <<
"-- Distributing the matrix data" << endl;
2630 ArrayRCP<size_t> myNumEntriesPerRow;
2631 ArrayRCP<size_t> myRowPtr;
2632 ArrayRCP<global_ordinal_type> myColInd;
2633 ArrayRCP<scalar_type> myValues;
2635 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
2636 numEntriesPerRow, rowPtr, colInd, values, debug);
2638 if (debug && myRank == rootRank) {
2639 cerr <<
"-- Inserting matrix entries on each processor";
2640 if (callFillComplete) {
2641 cerr <<
" and calling fillComplete()";
2652 RCP<sparse_matrix_type> pMatrix =
2653 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
2654 pRowMap, pRangeMap, pDomainMap, callFillComplete);
2659 int localIsNull = pMatrix.is_null () ? 1 : 0;
2660 int globalIsNull = 0;
2661 reduceAll (*pComm, REDUCE_MAX, localIsNull, ptr (&globalIsNull));
2662 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
2663 "Reader::makeMatrix() returned a null pointer on at least one "
2664 "process. Please report this bug to the Tpetra developers.");
2667 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
2668 "Reader::makeMatrix() returned a null pointer. "
2669 "Please report this bug to the Tpetra developers.");
2681 if (callFillComplete) {
2682 const int numProcs = pComm->getSize ();
2684 if (extraDebug && debug) {
2686 pRangeMap->getGlobalNumElements ();
2688 pDomainMap->getGlobalNumElements ();
2689 if (myRank == rootRank) {
2690 cerr <<
"-- Matrix is "
2691 << globalNumRows <<
" x " << globalNumCols
2692 <<
" with " << pMatrix->getGlobalNumEntries()
2693 <<
" entries, and index base "
2694 << pMatrix->getIndexBase() <<
"." << endl;
2697 for (
int p = 0; p < numProcs; ++p) {
2699 cerr <<
"-- Proc " << p <<
" owns "
2700 << pMatrix->getNodeNumCols() <<
" columns, and "
2701 << pMatrix->getNodeNumEntries() <<
" entries." << endl;
2708 if (debug && myRank == rootRank) {
2709 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2744 static Teuchos::RCP<sparse_matrix_type>
2746 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2747 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2748 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2749 const bool tolerant=
false,
2750 const bool debug=
false)
2752 using Teuchos::MatrixMarket::Banner;
2753 using Teuchos::arcp;
2754 using Teuchos::ArrayRCP;
2755 using Teuchos::broadcast;
2756 using Teuchos::null;
2759 using Teuchos::reduceAll;
2760 using Teuchos::Tuple;
2763 typedef Teuchos::ScalarTraits<scalar_type> STS;
2765 const bool extraDebug =
false;
2766 const int myRank = pComm->getRank ();
2767 const int rootRank = 0;
2772 size_t lineNumber = 1;
2774 if (debug && myRank == rootRank) {
2775 cerr <<
"Matrix Market reader: readSparse:" << endl
2776 <<
"-- Reading banner line" << endl;
2785 RCP<const Banner> pBanner;
2791 int bannerIsCorrect = 1;
2792 std::ostringstream errMsg;
2794 if (myRank == rootRank) {
2797 pBanner = readBanner (in, lineNumber, tolerant, debug);
2799 catch (std::exception& e) {
2800 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2801 "threw an exception: " << e.what();
2802 bannerIsCorrect = 0;
2805 if (bannerIsCorrect) {
2810 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2811 bannerIsCorrect = 0;
2812 errMsg <<
"The Matrix Market input file must contain a "
2813 "\"coordinate\"-format sparse matrix in order to create a "
2814 "Tpetra::CrsMatrix object from it, but the file's matrix "
2815 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2820 if (tolerant && pBanner->matrixType() ==
"array") {
2821 bannerIsCorrect = 0;
2822 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2823 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2824 "object from it, but the file's matrix type is \"array\" "
2825 "instead. That probably means the file contains dense matrix "
2832 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2839 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2840 std::invalid_argument, errMsg.str ());
2842 if (debug && myRank == rootRank) {
2843 cerr <<
"-- Reading dimensions line" << endl;
2851 Tuple<global_ordinal_type, 3> dims =
2852 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2854 if (debug && myRank == rootRank) {
2855 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2860 RCP<adder_type> pAdder =
2861 makeAdder (pComm, pBanner, dims, tolerant, debug);
2863 if (debug && myRank == rootRank) {
2864 cerr <<
"-- Reading matrix data" << endl;
2874 int readSuccess = 1;
2875 std::ostringstream errMsg;
2876 if (myRank == rootRank) {
2879 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2881 reader_type reader (pAdder);
2884 std::pair<bool, std::vector<size_t> > results =
2885 reader.read (in, lineNumber, tolerant, debug);
2886 readSuccess = results.first ? 1 : 0;
2888 catch (std::exception& e) {
2893 broadcast (*pComm, rootRank, ptr (&readSuccess));
2902 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2903 "Failed to read the Matrix Market sparse matrix file: "
2907 if (debug && myRank == rootRank) {
2908 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2921 if (debug && myRank == rootRank) {
2922 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2924 <<
"----- Dimensions before: "
2925 << dims[0] <<
" x " << dims[1]
2929 Tuple<global_ordinal_type, 2> updatedDims;
2930 if (myRank == rootRank) {
2937 std::max (dims[0], pAdder->getAdder()->numRows());
2938 updatedDims[1] = pAdder->getAdder()->numCols();
2940 broadcast (*pComm, rootRank, updatedDims);
2941 dims[0] = updatedDims[0];
2942 dims[1] = updatedDims[1];
2943 if (debug && myRank == rootRank) {
2944 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2958 if (myRank == rootRank) {
2965 if (dims[0] < pAdder->getAdder ()->numRows ()) {
2969 broadcast (*pComm, 0, ptr (&dimsMatch));
2970 if (dimsMatch == 0) {
2977 Tuple<global_ordinal_type, 2> addersDims;
2978 if (myRank == rootRank) {
2979 addersDims[0] = pAdder->getAdder()->numRows();
2980 addersDims[1] = pAdder->getAdder()->numCols();
2982 broadcast (*pComm, 0, addersDims);
2983 TEUCHOS_TEST_FOR_EXCEPTION(
2984 dimsMatch == 0, std::runtime_error,
2985 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2986 << dims[1] <<
", but the actual data says that the matrix is "
2987 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2988 "data includes more rows than reported in the metadata. This "
2989 "is not allowed when parsing in strict mode. Parse the matrix in "
2990 "tolerant mode to ignore the metadata when it disagrees with the "
2995 if (debug && myRank == rootRank) {
2996 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3008 ArrayRCP<size_t> numEntriesPerRow;
3009 ArrayRCP<size_t> rowPtr;
3010 ArrayRCP<global_ordinal_type> colInd;
3011 ArrayRCP<scalar_type> values;
3016 int mergeAndConvertSucceeded = 1;
3017 std::ostringstream errMsg;
3019 if (myRank == rootRank) {
3021 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3031 const size_type numRows = dims[0];
3034 pAdder->getAdder()->merge ();
3037 const std::vector<element_type>& entries =
3038 pAdder->getAdder()->getEntries();
3041 const size_t numEntries = (size_t)entries.size();
3044 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3045 <<
" rows and numEntries=" << numEntries
3046 <<
" entries." << endl;
3052 numEntriesPerRow = arcp<size_t> (numRows);
3053 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3054 rowPtr = arcp<size_t> (numRows+1);
3055 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3056 colInd = arcp<global_ordinal_type> (numEntries);
3057 values = arcp<scalar_type> (numEntries);
3064 for (curPos = 0; curPos < numEntries; ++curPos) {
3065 const element_type& curEntry = entries[curPos];
3067 TEUCHOS_TEST_FOR_EXCEPTION(
3068 curRow < prvRow, std::logic_error,
3069 "Row indices are out of order, even though they are supposed "
3070 "to be sorted. curRow = " << curRow <<
", prvRow = "
3071 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3072 "this bug to the Tpetra developers.");
3073 if (curRow > prvRow) {
3079 numEntriesPerRow[curRow]++;
3080 colInd[curPos] = curEntry.colIndex();
3081 values[curPos] = curEntry.value();
3086 rowPtr[numRows] = numEntries;
3088 catch (std::exception& e) {
3089 mergeAndConvertSucceeded = 0;
3090 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3091 "CSR format: " << e.what();
3094 if (debug && mergeAndConvertSucceeded) {
3096 const size_type numRows = dims[0];
3097 const size_type maxToDisplay = 100;
3099 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3100 << (numEntriesPerRow.size()-1) <<
"] ";
3101 if (numRows > maxToDisplay) {
3102 cerr <<
"(only showing first and last few entries) ";
3106 if (numRows > maxToDisplay) {
3107 for (size_type k = 0; k < 2; ++k) {
3108 cerr << numEntriesPerRow[k] <<
" ";
3111 for (size_type k = numRows-2; k < numRows-1; ++k) {
3112 cerr << numEntriesPerRow[k] <<
" ";
3116 for (size_type k = 0; k < numRows-1; ++k) {
3117 cerr << numEntriesPerRow[k] <<
" ";
3120 cerr << numEntriesPerRow[numRows-1];
3122 cerr <<
"]" << endl;
3124 cerr <<
"----- Proc 0: rowPtr ";
3125 if (numRows > maxToDisplay) {
3126 cerr <<
"(only showing first and last few entries) ";
3129 if (numRows > maxToDisplay) {
3130 for (size_type k = 0; k < 2; ++k) {
3131 cerr << rowPtr[k] <<
" ";
3134 for (size_type k = numRows-2; k < numRows; ++k) {
3135 cerr << rowPtr[k] <<
" ";
3139 for (size_type k = 0; k < numRows; ++k) {
3140 cerr << rowPtr[k] <<
" ";
3143 cerr << rowPtr[numRows] <<
"]" << endl;
3154 if (debug && myRank == rootRank) {
3155 cerr <<
"-- Making range, domain, and row maps" << endl;
3162 RCP<const map_type> pRangeMap = makeRangeMap (pComm, dims[0]);
3163 RCP<const map_type> pDomainMap =
3164 makeDomainMap (pRangeMap, dims[0], dims[1]);
3165 RCP<const map_type> pRowMap = makeRowMap (null, pComm, dims[0]);
3167 if (debug && myRank == rootRank) {
3168 cerr <<
"-- Distributing the matrix data" << endl;
3182 ArrayRCP<size_t> myNumEntriesPerRow;
3183 ArrayRCP<size_t> myRowPtr;
3184 ArrayRCP<global_ordinal_type> myColInd;
3185 ArrayRCP<scalar_type> myValues;
3187 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
3188 numEntriesPerRow, rowPtr, colInd, values, debug);
3190 if (debug && myRank == rootRank) {
3191 cerr <<
"-- Inserting matrix entries on each process "
3192 "and calling fillComplete()" << endl;
3201 Teuchos::RCP<sparse_matrix_type> pMatrix =
3202 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
3203 pRowMap, pRangeMap, pDomainMap, constructorParams,
3204 fillCompleteParams);
3209 int localIsNull = pMatrix.is_null () ? 1 : 0;
3210 int globalIsNull = 0;
3211 reduceAll (*pComm, Teuchos::REDUCE_MAX, localIsNull, ptr (&globalIsNull));
3212 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
3213 "Reader::makeMatrix() returned a null pointer on at least one "
3214 "process. Please report this bug to the Tpetra developers.");
3217 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
3218 "Reader::makeMatrix() returned a null pointer. "
3219 "Please report this bug to the Tpetra developers.");
3228 if (extraDebug && debug) {
3229 const int numProcs = pComm->getSize ();
3231 pRangeMap->getGlobalNumElements();
3233 pDomainMap->getGlobalNumElements();
3234 if (myRank == rootRank) {
3235 cerr <<
"-- Matrix is "
3236 << globalNumRows <<
" x " << globalNumCols
3237 <<
" with " << pMatrix->getGlobalNumEntries()
3238 <<
" entries, and index base "
3239 << pMatrix->getIndexBase() <<
"." << endl;
3242 for (
int p = 0; p < numProcs; ++p) {
3244 cerr <<
"-- Proc " << p <<
" owns "
3245 << pMatrix->getNodeNumCols() <<
" columns, and "
3246 << pMatrix->getNodeNumEntries() <<
" entries." << endl;
3252 if (debug && myRank == rootRank) {
3253 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3300 static Teuchos::RCP<sparse_matrix_type>
3302 const Teuchos::RCP<const map_type>& rowMap,
3303 Teuchos::RCP<const map_type>& colMap,
3304 const Teuchos::RCP<const map_type>& domainMap,
3305 const Teuchos::RCP<const map_type>& rangeMap,
3306 const bool callFillComplete=
true,
3307 const bool tolerant=
false,
3308 const bool debug=
false)
3310 using Teuchos::MatrixMarket::Banner;
3311 using Teuchos::arcp;
3312 using Teuchos::ArrayRCP;
3313 using Teuchos::ArrayView;
3315 using Teuchos::broadcast;
3316 using Teuchos::Comm;
3317 using Teuchos::null;
3320 using Teuchos::reduceAll;
3321 using Teuchos::Tuple;
3324 typedef Teuchos::ScalarTraits<scalar_type> STS;
3326 RCP<const Comm<int> > pComm = rowMap->getComm ();
3327 const int myRank = pComm->getRank ();
3328 const int rootRank = 0;
3329 const bool extraDebug =
false;
3334 TEUCHOS_TEST_FOR_EXCEPTION(
3335 rowMap.is_null (), std::invalid_argument,
3336 "Row Map must be nonnull.");
3337 TEUCHOS_TEST_FOR_EXCEPTION(
3338 rangeMap.is_null (), std::invalid_argument,
3339 "Range Map must be nonnull.");
3340 TEUCHOS_TEST_FOR_EXCEPTION(
3341 domainMap.is_null (), std::invalid_argument,
3342 "Domain Map must be nonnull.");
3343 TEUCHOS_TEST_FOR_EXCEPTION(
3344 rowMap->getComm().getRawPtr() != pComm.getRawPtr(),
3345 std::invalid_argument,
3346 "The specified row Map's communicator (rowMap->getComm())"
3347 "differs from the given separately supplied communicator pComm.");
3348 TEUCHOS_TEST_FOR_EXCEPTION(
3349 domainMap->getComm().getRawPtr() != pComm.getRawPtr(),
3350 std::invalid_argument,
3351 "The specified domain Map's communicator (domainMap->getComm())"
3352 "differs from the given separately supplied communicator pComm.");
3353 TEUCHOS_TEST_FOR_EXCEPTION(
3354 rangeMap->getComm().getRawPtr() != pComm.getRawPtr(),
3355 std::invalid_argument,
3356 "The specified range Map's communicator (rangeMap->getComm())"
3357 "differs from the given separately supplied communicator pComm.");
3362 size_t lineNumber = 1;
3364 if (debug && myRank == rootRank) {
3365 cerr <<
"Matrix Market reader: readSparse:" << endl
3366 <<
"-- Reading banner line" << endl;
3375 RCP<const Banner> pBanner;
3381 int bannerIsCorrect = 1;
3382 std::ostringstream errMsg;
3384 if (myRank == rootRank) {
3387 pBanner = readBanner (in, lineNumber, tolerant, debug);
3389 catch (std::exception& e) {
3390 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
3391 "threw an exception: " << e.what();
3392 bannerIsCorrect = 0;
3395 if (bannerIsCorrect) {
3400 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
3401 bannerIsCorrect = 0;
3402 errMsg <<
"The Matrix Market input file must contain a "
3403 "\"coordinate\"-format sparse matrix in order to create a "
3404 "Tpetra::CrsMatrix object from it, but the file's matrix "
3405 "type is \"" << pBanner->matrixType() <<
"\" instead.";
3410 if (tolerant && pBanner->matrixType() ==
"array") {
3411 bannerIsCorrect = 0;
3412 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
3413 "format sparse matrix in order to create a Tpetra::CrsMatrix "
3414 "object from it, but the file's matrix type is \"array\" "
3415 "instead. That probably means the file contains dense matrix "
3422 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
3429 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
3430 std::invalid_argument, errMsg.str ());
3432 if (debug && myRank == rootRank) {
3433 cerr <<
"-- Reading dimensions line" << endl;
3441 Tuple<global_ordinal_type, 3> dims =
3442 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
3444 if (debug && myRank == rootRank) {
3445 cerr <<
"-- Making Adder for collecting matrix data" << endl;
3452 RCP<adder_type> pAdder =
3453 makeAdder (pComm, pBanner, dims, tolerant, debug);
3455 if (debug && myRank == rootRank) {
3456 cerr <<
"-- Reading matrix data" << endl;
3466 int readSuccess = 1;
3467 std::ostringstream errMsg;
3468 if (myRank == rootRank) {
3471 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
3473 reader_type reader (pAdder);
3476 std::pair<bool, std::vector<size_t> > results =
3477 reader.read (in, lineNumber, tolerant, debug);
3478 readSuccess = results.first ? 1 : 0;
3480 catch (std::exception& e) {
3485 broadcast (*pComm, rootRank, ptr (&readSuccess));
3494 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
3495 "Failed to read the Matrix Market sparse matrix file: "
3499 if (debug && myRank == rootRank) {
3500 cerr <<
"-- Successfully read the Matrix Market data" << endl;
3513 if (debug && myRank == rootRank) {
3514 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
3516 <<
"----- Dimensions before: "
3517 << dims[0] <<
" x " << dims[1]
3521 Tuple<global_ordinal_type, 2> updatedDims;
3522 if (myRank == rootRank) {
3529 std::max (dims[0], pAdder->getAdder()->numRows());
3530 updatedDims[1] = pAdder->getAdder()->numCols();
3532 broadcast (*pComm, rootRank, updatedDims);
3533 dims[0] = updatedDims[0];
3534 dims[1] = updatedDims[1];
3535 if (debug && myRank == rootRank) {
3536 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
3550 if (myRank == rootRank) {
3557 if (dims[0] < pAdder->getAdder ()->numRows ()) {
3561 broadcast (*pComm, 0, ptr (&dimsMatch));
3562 if (dimsMatch == 0) {
3569 Tuple<global_ordinal_type, 2> addersDims;
3570 if (myRank == rootRank) {
3571 addersDims[0] = pAdder->getAdder()->numRows();
3572 addersDims[1] = pAdder->getAdder()->numCols();
3574 broadcast (*pComm, 0, addersDims);
3575 TEUCHOS_TEST_FOR_EXCEPTION(
3576 dimsMatch == 0, std::runtime_error,
3577 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
3578 << dims[1] <<
", but the actual data says that the matrix is "
3579 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
3580 "data includes more rows than reported in the metadata. This "
3581 "is not allowed when parsing in strict mode. Parse the matrix in "
3582 "tolerant mode to ignore the metadata when it disagrees with the "
3587 if (debug && myRank == rootRank) {
3588 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3600 ArrayRCP<size_t> numEntriesPerRow;
3601 ArrayRCP<size_t> rowPtr;
3602 ArrayRCP<global_ordinal_type> colInd;
3603 ArrayRCP<scalar_type> values;
3604 size_t maxNumEntriesPerRow = 0;
3609 int mergeAndConvertSucceeded = 1;
3610 std::ostringstream errMsg;
3612 if (myRank == rootRank) {
3614 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3624 const size_type numRows = dims[0];
3627 pAdder->getAdder()->merge ();
3630 const std::vector<element_type>& entries =
3631 pAdder->getAdder()->getEntries();
3634 const size_t numEntries = (size_t)entries.size();
3637 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3638 <<
" rows and numEntries=" << numEntries
3639 <<
" entries." << endl;
3645 numEntriesPerRow = arcp<size_t> (numRows);
3646 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3647 rowPtr = arcp<size_t> (numRows+1);
3648 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3649 colInd = arcp<global_ordinal_type> (numEntries);
3650 values = arcp<scalar_type> (numEntries);
3657 for (curPos = 0; curPos < numEntries; ++curPos) {
3658 const element_type& curEntry = entries[curPos];
3660 TEUCHOS_TEST_FOR_EXCEPTION(
3661 curRow < prvRow, std::logic_error,
3662 "Row indices are out of order, even though they are supposed "
3663 "to be sorted. curRow = " << curRow <<
", prvRow = "
3664 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3665 "this bug to the Tpetra developers.");
3666 if (curRow > prvRow) {
3672 numEntriesPerRow[curRow]++;
3673 colInd[curPos] = curEntry.colIndex();
3674 values[curPos] = curEntry.value();
3679 rowPtr[numRows] = numEntries;
3681 catch (std::exception& e) {
3682 mergeAndConvertSucceeded = 0;
3683 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3684 "CSR format: " << e.what();
3687 if (debug && mergeAndConvertSucceeded) {
3689 const size_type numRows = dims[0];
3690 const size_type maxToDisplay = 100;
3692 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3693 << (numEntriesPerRow.size()-1) <<
"] ";
3694 if (numRows > maxToDisplay) {
3695 cerr <<
"(only showing first and last few entries) ";
3699 if (numRows > maxToDisplay) {
3700 for (size_type k = 0; k < 2; ++k) {
3701 cerr << numEntriesPerRow[k] <<
" ";
3704 for (size_type k = numRows-2; k < numRows-1; ++k) {
3705 cerr << numEntriesPerRow[k] <<
" ";
3709 for (size_type k = 0; k < numRows-1; ++k) {
3710 cerr << numEntriesPerRow[k] <<
" ";
3713 cerr << numEntriesPerRow[numRows-1];
3715 cerr <<
"]" << endl;
3717 cerr <<
"----- Proc 0: rowPtr ";
3718 if (numRows > maxToDisplay) {
3719 cerr <<
"(only showing first and last few entries) ";
3722 if (numRows > maxToDisplay) {
3723 for (size_type k = 0; k < 2; ++k) {
3724 cerr << rowPtr[k] <<
" ";
3727 for (size_type k = numRows-2; k < numRows; ++k) {
3728 cerr << rowPtr[k] <<
" ";
3732 for (size_type k = 0; k < numRows; ++k) {
3733 cerr << rowPtr[k] <<
" ";
3736 cerr << rowPtr[numRows] <<
"]" << endl;
3738 cerr <<
"----- Proc 0: colInd = [";
3739 for (
size_t k = 0; k < rowPtr[numRows]; ++k) {
3740 cerr << colInd[k] <<
" ";
3742 cerr <<
"]" << endl;
3756 if (debug && myRank == rootRank) {
3757 cerr <<
"-- Verifying Maps" << endl;
3759 TEUCHOS_TEST_FOR_EXCEPTION(
3760 as<global_size_t> (dims[0]) != rangeMap->getGlobalNumElements(),
3761 std::invalid_argument,
3762 "The range Map has " << rangeMap->getGlobalNumElements ()
3763 <<
" entries, but the matrix has a global number of rows " << dims[0]
3765 TEUCHOS_TEST_FOR_EXCEPTION(
3766 as<global_size_t> (dims[1]) != domainMap->getGlobalNumElements (),
3767 std::invalid_argument,
3768 "The domain Map has " << domainMap->getGlobalNumElements ()
3769 <<
" entries, but the matrix has a global number of columns "
3773 RCP<Teuchos::FancyOStream> err = debug ?
3774 Teuchos::getFancyOStream (Teuchos::rcpFromRef (cerr)) : null;
3776 RCP<const map_type> gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
3777 ArrayView<const global_ordinal_type> myRows =
3778 gatherRowMap->getNodeElementList ();
3779 const size_type myNumRows = myRows.size ();
3782 ArrayRCP<size_t> gatherNumEntriesPerRow = arcp<size_t>(myNumRows);
3783 for (size_type i_ = 0; i_ < myNumRows; i_++) {
3784 gatherNumEntriesPerRow[i_] = numEntriesPerRow[myRows[i_]-indexBase];
3785 if (gatherNumEntriesPerRow[i_] > maxNumEntriesPerRow)
3786 maxNumEntriesPerRow = gatherNumEntriesPerRow[i_];
3792 RCP<sparse_matrix_type> A_proc0 =
3794 Tpetra::StaticProfile));
3795 if (myRank == rootRank) {
3797 cerr <<
"-- Proc 0: Filling gather matrix" << endl;
3800 cerr <<
"---- Rows: " << Teuchos::toString (myRows) << endl;
3804 for (size_type i_ = 0; i_ < myNumRows; ++i_) {
3805 size_type i = myRows[i_] - indexBase;
3807 const size_type curPos = as<size_type> (rowPtr[i]);
3809 ArrayView<global_ordinal_type> curColInd =
3810 colInd.view (curPos, curNumEntries);
3811 ArrayView<scalar_type> curValues =
3812 values.view (curPos, curNumEntries);
3815 for (size_type k = 0; k < curNumEntries; ++k) {
3816 curColInd[k] += indexBase;
3819 cerr <<
"------ Columns: " << Teuchos::toString (curColInd) << endl;
3820 cerr <<
"------ Values: " << Teuchos::toString (curValues) << endl;
3823 if (curNumEntries > 0) {
3824 A_proc0->insertGlobalValues (myRows[i_], curColInd, curValues);
3830 numEntriesPerRow = null;
3836 broadcast<int,size_t> (*pComm, 0, &maxNumEntriesPerRow);
3838 RCP<sparse_matrix_type> A;
3839 if (colMap.is_null ()) {
3845 export_type exp (gatherRowMap, rowMap);
3846 A->doExport (*A_proc0, exp,
INSERT);
3848 if (callFillComplete) {
3849 A->fillComplete (domainMap, rangeMap);
3861 if (callFillComplete) {
3862 const int numProcs = pComm->getSize ();
3864 if (extraDebug && debug) {
3865 const global_size_t globalNumRows = rangeMap->getGlobalNumElements ();
3866 const global_size_t globalNumCols = domainMap->getGlobalNumElements ();
3867 if (myRank == rootRank) {
3868 cerr <<
"-- Matrix is "
3869 << globalNumRows <<
" x " << globalNumCols
3870 <<
" with " << A->getGlobalNumEntries()
3871 <<
" entries, and index base "
3872 << A->getIndexBase() <<
"." << endl;
3875 for (
int p = 0; p < numProcs; ++p) {
3877 cerr <<
"-- Proc " << p <<
" owns "
3878 << A->getNodeNumCols() <<
" columns, and "
3879 << A->getNodeNumEntries() <<
" entries." << endl;
3886 if (debug && myRank == rootRank) {
3887 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3921 static Teuchos::RCP<multivector_type>
3923 const Teuchos::RCP<const comm_type>& comm,
3924 Teuchos::RCP<const map_type>& map,
3925 const bool tolerant=
false,
3926 const bool debug=
false)
3929 if (comm->getRank () == 0) {
3930 in.open (filename.c_str ());
3932 return readDense (in, comm, map, tolerant, debug);
3965 static Teuchos::RCP<vector_type>
3967 const Teuchos::RCP<const comm_type>& comm,
3968 Teuchos::RCP<const map_type>& map,
3969 const bool tolerant=
false,
3970 const bool debug=
false)
3973 if (comm->getRank () == 0) {
3974 in.open (filename.c_str ());
3976 return readVector (in, comm, map, tolerant, debug);
4046 static Teuchos::RCP<multivector_type>
4048 const Teuchos::RCP<const comm_type>& comm,
4049 Teuchos::RCP<const map_type>& map,
4050 const bool tolerant=
false,
4051 const bool debug=
false)
4053 Teuchos::RCP<Teuchos::FancyOStream> err =
4054 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4055 return readDenseImpl<scalar_type> (in, comm, map, err, tolerant, debug);
4060 static Teuchos::RCP<vector_type>
4062 const Teuchos::RCP<const comm_type>& comm,
4063 Teuchos::RCP<const map_type>& map,
4064 const bool tolerant=
false,
4065 const bool debug=
false)
4067 Teuchos::RCP<Teuchos::FancyOStream> err =
4068 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4069 return readVectorImpl<scalar_type> (in, comm, map, err, tolerant, debug);
4093 static Teuchos::RCP<const map_type>
4095 const Teuchos::RCP<const comm_type>& comm,
4096 const bool tolerant=
false,
4097 const bool debug=
false)
4099 using Teuchos::inOutArg;
4100 using Teuchos::broadcast;
4104 if (comm->getRank () == 0) {
4105 in.open (filename.c_str ());
4110 broadcast<int, int> (*comm, 0, inOutArg (success));
4111 TEUCHOS_TEST_FOR_EXCEPTION(
4112 success == 0, std::runtime_error,
4113 "Tpetra::MatrixMarket::Reader::readMapFile: "
4114 "Failed to read file \"" << filename <<
"\" on Process 0.");
4115 return readMap (in, comm, tolerant, debug);
4120 template<
class MultiVectorScalarType>
4125 readDenseImpl (std::istream& in,
4126 const Teuchos::RCP<const comm_type>& comm,
4127 Teuchos::RCP<const map_type>& map,
4128 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4129 const bool tolerant=
false,
4130 const bool debug=
false)
4132 using Teuchos::MatrixMarket::Banner;
4133 using Teuchos::MatrixMarket::checkCommentLine;
4134 using Teuchos::ArrayRCP;
4136 using Teuchos::broadcast;
4137 using Teuchos::outArg;
4139 using Teuchos::Tuple;
4141 typedef MultiVectorScalarType ST;
4145 typedef Teuchos::ScalarTraits<ST> STS;
4146 typedef typename STS::magnitudeType MT;
4147 typedef Teuchos::ScalarTraits<MT> STM;
4152 const int myRank = comm->getRank ();
4154 if (! err.is_null ()) {
4158 *err << myRank <<
": readDenseImpl" << endl;
4160 if (! err.is_null ()) {
4194 size_t lineNumber = 1;
4197 std::ostringstream exMsg;
4198 int localBannerReadSuccess = 1;
4199 int localDimsReadSuccess = 1;
4204 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
4210 RCP<const Banner> pBanner;
4212 pBanner = readBanner (in, lineNumber, tolerant, debug);
4213 }
catch (std::exception& e) {
4215 localBannerReadSuccess = 0;
4218 if (localBannerReadSuccess) {
4219 if (pBanner->matrixType () !=
"array") {
4220 exMsg <<
"The Matrix Market file does not contain dense matrix "
4221 "data. Its banner (first) line says that its matrix type is \""
4222 << pBanner->matrixType () <<
"\", rather that the required "
4224 localBannerReadSuccess = 0;
4225 }
else if (pBanner->dataType() ==
"pattern") {
4226 exMsg <<
"The Matrix Market file's banner (first) "
4227 "line claims that the matrix's data type is \"pattern\". This does "
4228 "not make sense for a dense matrix, yet the file reports the matrix "
4229 "as dense. The only valid data types for a dense matrix are "
4230 "\"real\", \"complex\", and \"integer\".";
4231 localBannerReadSuccess = 0;
4235 dims[2] = encodeDataType (pBanner->dataType ());
4241 if (localBannerReadSuccess) {
4243 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
4252 bool commentLine =
true;
4254 while (commentLine) {
4257 if (in.eof () || in.fail ()) {
4258 exMsg <<
"Unable to get array dimensions line (at all) from line "
4259 << lineNumber <<
" of input stream. The input stream "
4260 <<
"claims that it is "
4261 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4262 localDimsReadSuccess = 0;
4265 if (getline (in, line)) {
4272 size_t start = 0, size = 0;
4273 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4280 std::istringstream istr (line);
4284 if (istr.eof () || istr.fail ()) {
4285 exMsg <<
"Unable to read any data from line " << lineNumber
4286 <<
" of input; the line should contain the matrix dimensions "
4287 <<
"\"<numRows> <numCols>\".";
4288 localDimsReadSuccess = 0;
4293 exMsg <<
"Failed to get number of rows from line "
4294 << lineNumber <<
" of input; the line should contains the "
4295 <<
"matrix dimensions \"<numRows> <numCols>\".";
4296 localDimsReadSuccess = 0;
4298 dims[0] = theNumRows;
4300 exMsg <<
"No more data after number of rows on line "
4301 << lineNumber <<
" of input; the line should contain the "
4302 <<
"matrix dimensions \"<numRows> <numCols>\".";
4303 localDimsReadSuccess = 0;
4308 exMsg <<
"Failed to get number of columns from line "
4309 << lineNumber <<
" of input; the line should contain "
4310 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4311 localDimsReadSuccess = 0;
4313 dims[1] = theNumCols;
4324 Tuple<GO, 5> bannerDimsReadResult;
4326 bannerDimsReadResult[0] = dims[0];
4327 bannerDimsReadResult[1] = dims[1];
4328 bannerDimsReadResult[2] = dims[2];
4329 bannerDimsReadResult[3] = localBannerReadSuccess;
4330 bannerDimsReadResult[4] = localDimsReadSuccess;
4334 broadcast (*comm, 0, bannerDimsReadResult);
4336 TEUCHOS_TEST_FOR_EXCEPTION(
4337 bannerDimsReadResult[3] == 0, std::runtime_error,
4338 "Failed to read banner line: " << exMsg.str ());
4339 TEUCHOS_TEST_FOR_EXCEPTION(
4340 bannerDimsReadResult[4] == 0, std::runtime_error,
4341 "Failed to read matrix dimensions line: " << exMsg.str ());
4343 dims[0] = bannerDimsReadResult[0];
4344 dims[1] = bannerDimsReadResult[1];
4345 dims[2] = bannerDimsReadResult[2];
4350 const size_t numCols =
static_cast<size_t> (dims[1]);
4355 RCP<const map_type> proc0Map;
4356 if (map.is_null ()) {
4360 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
4361 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4363 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
4367 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
4371 RCP<MV> X = createMultiVector<ST, LO, GO, NT> (proc0Map, numCols);
4377 int localReadDataSuccess = 1;
4381 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4386 TEUCHOS_TEST_FOR_EXCEPTION(
4387 ! X->isConstantStride (), std::logic_error,
4388 "Can't get a 1-D view of the entries of the MultiVector X on "
4389 "Process 0, because the stride between the columns of X is not "
4390 "constant. This shouldn't happen because we just created X and "
4391 "haven't filled it in yet. Please report this bug to the Tpetra "
4398 ArrayRCP<ST> X_view = X->get1dViewNonConst ();
4399 TEUCHOS_TEST_FOR_EXCEPTION(
4400 as<global_size_t> (X_view.size ()) < numRows * numCols,
4402 "The view of X has size " << X_view <<
" which is not enough to "
4403 "accommodate the expected number of entries numRows*numCols = "
4404 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
4405 "Please report this bug to the Tpetra developers.");
4406 const size_t stride = X->getStride ();
4413 const bool isComplex = (dims[2] == 1);
4414 size_type count = 0, curRow = 0, curCol = 0;
4417 while (getline (in, line)) {
4421 size_t start = 0, size = 0;
4422 const bool commentLine =
4423 checkCommentLine (line, start, size, lineNumber, tolerant);
4424 if (! commentLine) {
4430 if (count >= X_view.size()) {
4435 TEUCHOS_TEST_FOR_EXCEPTION(
4436 count >= X_view.size(),
4438 "The Matrix Market input stream has more data in it than "
4439 "its metadata reported. Current line number is "
4440 << lineNumber <<
".");
4449 const size_t pos = line.substr (start, size).find (
':');
4450 if (pos != std::string::npos) {
4454 std::istringstream istr (line.substr (start, size));
4458 if (istr.eof() || istr.fail()) {
4465 TEUCHOS_TEST_FOR_EXCEPTION(
4466 ! tolerant && (istr.eof() || istr.fail()),
4468 "Line " << lineNumber <<
" of the Matrix Market file is "
4469 "empty, or we cannot read from it for some other reason.");
4472 ST val = STS::zero();
4475 MT real = STM::zero(), imag = STM::zero();
4492 TEUCHOS_TEST_FOR_EXCEPTION(
4493 ! tolerant && istr.eof(), std::runtime_error,
4494 "Failed to get the real part of a complex-valued matrix "
4495 "entry from line " << lineNumber <<
" of the Matrix Market "
4501 }
else if (istr.eof()) {
4502 TEUCHOS_TEST_FOR_EXCEPTION(
4503 ! tolerant && istr.eof(), std::runtime_error,
4504 "Missing imaginary part of a complex-valued matrix entry "
4505 "on line " << lineNumber <<
" of the Matrix Market file.");
4511 TEUCHOS_TEST_FOR_EXCEPTION(
4512 ! tolerant && istr.fail(), std::runtime_error,
4513 "Failed to get the imaginary part of a complex-valued "
4514 "matrix entry from line " << lineNumber <<
" of the "
4515 "Matrix Market file.");
4522 TEUCHOS_TEST_FOR_EXCEPTION(
4523 ! tolerant && istr.fail(), std::runtime_error,
4524 "Failed to get a real-valued matrix entry from line "
4525 << lineNumber <<
" of the Matrix Market file.");
4528 if (istr.fail() && tolerant) {
4534 TEUCHOS_TEST_FOR_EXCEPTION(
4535 ! tolerant && istr.fail(), std::runtime_error,
4536 "Failed to read matrix data from line " << lineNumber
4537 <<
" of the Matrix Market file.");
4540 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
4542 curRow = count % numRows;
4543 curCol = count / numRows;
4544 X_view[curRow + curCol*stride] = val;
4549 TEUCHOS_TEST_FOR_EXCEPTION(
4550 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
4552 "The Matrix Market metadata reports that the dense matrix is "
4553 << numRows <<
" x " << numCols <<
", and thus has "
4554 << numRows*numCols <<
" total entries, but we only found " << count
4555 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4556 }
catch (std::exception& e) {
4558 localReadDataSuccess = 0;
4563 *err << myRank <<
": readDenseImpl: done reading data" << endl;
4567 int globalReadDataSuccess = localReadDataSuccess;
4568 broadcast (*comm, 0, outArg (globalReadDataSuccess));
4569 TEUCHOS_TEST_FOR_EXCEPTION(
4570 globalReadDataSuccess == 0, std::runtime_error,
4571 "Failed to read the multivector's data: " << exMsg.str ());
4576 if (comm->getSize () == 1 && map.is_null ()) {
4578 if (! err.is_null ()) {
4582 *err << myRank <<
": readDenseImpl: done" << endl;
4584 if (! err.is_null ()) {
4591 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
4595 RCP<MV> Y = createMultiVector<ST, LO, GO, NT> (map, numCols);
4598 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
4604 Export<LO, GO, NT> exporter (proc0Map, map, err);
4607 *err << myRank <<
": readDenseImpl: Exporting" << endl;
4610 Y->doExport (*X, exporter,
INSERT);
4612 if (! err.is_null ()) {
4616 *err << myRank <<
": readDenseImpl: done" << endl;
4618 if (! err.is_null ()) {
4627 template<
class VectorScalarType>
4632 readVectorImpl (std::istream& in,
4633 const Teuchos::RCP<const comm_type>& comm,
4634 Teuchos::RCP<const map_type>& map,
4635 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4636 const bool tolerant=
false,
4637 const bool debug=
false)
4639 using Teuchos::MatrixMarket::Banner;
4640 using Teuchos::MatrixMarket::checkCommentLine;
4642 using Teuchos::broadcast;
4643 using Teuchos::outArg;
4645 using Teuchos::Tuple;
4647 typedef VectorScalarType ST;
4651 typedef Teuchos::ScalarTraits<ST> STS;
4652 typedef typename STS::magnitudeType MT;
4653 typedef Teuchos::ScalarTraits<MT> STM;
4658 const int myRank = comm->getRank ();
4660 if (! err.is_null ()) {
4664 *err << myRank <<
": readVectorImpl" << endl;
4666 if (! err.is_null ()) {
4700 size_t lineNumber = 1;
4703 std::ostringstream exMsg;
4704 int localBannerReadSuccess = 1;
4705 int localDimsReadSuccess = 1;
4710 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
4716 RCP<const Banner> pBanner;
4718 pBanner = readBanner (in, lineNumber, tolerant, debug);
4719 }
catch (std::exception& e) {
4721 localBannerReadSuccess = 0;
4724 if (localBannerReadSuccess) {
4725 if (pBanner->matrixType () !=
"array") {
4726 exMsg <<
"The Matrix Market file does not contain dense matrix "
4727 "data. Its banner (first) line says that its matrix type is \""
4728 << pBanner->matrixType () <<
"\", rather that the required "
4730 localBannerReadSuccess = 0;
4731 }
else if (pBanner->dataType() ==
"pattern") {
4732 exMsg <<
"The Matrix Market file's banner (first) "
4733 "line claims that the matrix's data type is \"pattern\". This does "
4734 "not make sense for a dense matrix, yet the file reports the matrix "
4735 "as dense. The only valid data types for a dense matrix are "
4736 "\"real\", \"complex\", and \"integer\".";
4737 localBannerReadSuccess = 0;
4741 dims[2] = encodeDataType (pBanner->dataType ());
4747 if (localBannerReadSuccess) {
4749 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
4758 bool commentLine =
true;
4760 while (commentLine) {
4763 if (in.eof () || in.fail ()) {
4764 exMsg <<
"Unable to get array dimensions line (at all) from line "
4765 << lineNumber <<
" of input stream. The input stream "
4766 <<
"claims that it is "
4767 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4768 localDimsReadSuccess = 0;
4771 if (getline (in, line)) {
4778 size_t start = 0, size = 0;
4779 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4786 std::istringstream istr (line);
4790 if (istr.eof () || istr.fail ()) {
4791 exMsg <<
"Unable to read any data from line " << lineNumber
4792 <<
" of input; the line should contain the matrix dimensions "
4793 <<
"\"<numRows> <numCols>\".";
4794 localDimsReadSuccess = 0;
4799 exMsg <<
"Failed to get number of rows from line "
4800 << lineNumber <<
" of input; the line should contains the "
4801 <<
"matrix dimensions \"<numRows> <numCols>\".";
4802 localDimsReadSuccess = 0;
4804 dims[0] = theNumRows;
4806 exMsg <<
"No more data after number of rows on line "
4807 << lineNumber <<
" of input; the line should contain the "
4808 <<
"matrix dimensions \"<numRows> <numCols>\".";
4809 localDimsReadSuccess = 0;
4814 exMsg <<
"Failed to get number of columns from line "
4815 << lineNumber <<
" of input; the line should contain "
4816 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4817 localDimsReadSuccess = 0;
4819 dims[1] = theNumCols;
4829 exMsg <<
"File does not contain a 1D Vector";
4830 localDimsReadSuccess = 0;
4836 Tuple<GO, 5> bannerDimsReadResult;
4838 bannerDimsReadResult[0] = dims[0];
4839 bannerDimsReadResult[1] = dims[1];
4840 bannerDimsReadResult[2] = dims[2];
4841 bannerDimsReadResult[3] = localBannerReadSuccess;
4842 bannerDimsReadResult[4] = localDimsReadSuccess;
4847 broadcast (*comm, 0, bannerDimsReadResult);
4849 TEUCHOS_TEST_FOR_EXCEPTION(
4850 bannerDimsReadResult[3] == 0, std::runtime_error,
4851 "Failed to read banner line: " << exMsg.str ());
4852 TEUCHOS_TEST_FOR_EXCEPTION(
4853 bannerDimsReadResult[4] == 0, std::runtime_error,
4854 "Failed to read matrix dimensions line: " << exMsg.str ());
4856 dims[0] = bannerDimsReadResult[0];
4857 dims[1] = bannerDimsReadResult[1];
4858 dims[2] = bannerDimsReadResult[2];
4863 const size_t numCols =
static_cast<size_t> (dims[1]);
4868 RCP<const map_type> proc0Map;
4869 if (map.is_null ()) {
4873 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
4874 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4876 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
4880 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
4884 RCP<MV> X = createVector<ST, LO, GO, NT> (proc0Map);
4890 int localReadDataSuccess = 1;
4894 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
4899 TEUCHOS_TEST_FOR_EXCEPTION(
4900 ! X->isConstantStride (), std::logic_error,
4901 "Can't get a 1-D view of the entries of the MultiVector X on "
4902 "Process 0, because the stride between the columns of X is not "
4903 "constant. This shouldn't happen because we just created X and "
4904 "haven't filled it in yet. Please report this bug to the Tpetra "
4911 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst ();
4912 TEUCHOS_TEST_FOR_EXCEPTION(
4913 as<global_size_t> (X_view.size ()) < numRows * numCols,
4915 "The view of X has size " << X_view <<
" which is not enough to "
4916 "accommodate the expected number of entries numRows*numCols = "
4917 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
4918 "Please report this bug to the Tpetra developers.");
4919 const size_t stride = X->getStride ();
4926 const bool isComplex = (dims[2] == 1);
4927 size_type count = 0, curRow = 0, curCol = 0;
4930 while (getline (in, line)) {
4934 size_t start = 0, size = 0;
4935 const bool commentLine =
4936 checkCommentLine (line, start, size, lineNumber, tolerant);
4937 if (! commentLine) {
4943 if (count >= X_view.size()) {
4948 TEUCHOS_TEST_FOR_EXCEPTION(
4949 count >= X_view.size(),
4951 "The Matrix Market input stream has more data in it than "
4952 "its metadata reported. Current line number is "
4953 << lineNumber <<
".");
4962 const size_t pos = line.substr (start, size).find (
':');
4963 if (pos != std::string::npos) {
4967 std::istringstream istr (line.substr (start, size));
4971 if (istr.eof() || istr.fail()) {
4978 TEUCHOS_TEST_FOR_EXCEPTION(
4979 ! tolerant && (istr.eof() || istr.fail()),
4981 "Line " << lineNumber <<
" of the Matrix Market file is "
4982 "empty, or we cannot read from it for some other reason.");
4985 ST val = STS::zero();
4988 MT real = STM::zero(), imag = STM::zero();
5005 TEUCHOS_TEST_FOR_EXCEPTION(
5006 ! tolerant && istr.eof(), std::runtime_error,
5007 "Failed to get the real part of a complex-valued matrix "
5008 "entry from line " << lineNumber <<
" of the Matrix Market "
5014 }
else if (istr.eof()) {
5015 TEUCHOS_TEST_FOR_EXCEPTION(
5016 ! tolerant && istr.eof(), std::runtime_error,
5017 "Missing imaginary part of a complex-valued matrix entry "
5018 "on line " << lineNumber <<
" of the Matrix Market file.");
5024 TEUCHOS_TEST_FOR_EXCEPTION(
5025 ! tolerant && istr.fail(), std::runtime_error,
5026 "Failed to get the imaginary part of a complex-valued "
5027 "matrix entry from line " << lineNumber <<
" of the "
5028 "Matrix Market file.");
5035 TEUCHOS_TEST_FOR_EXCEPTION(
5036 ! tolerant && istr.fail(), std::runtime_error,
5037 "Failed to get a real-valued matrix entry from line "
5038 << lineNumber <<
" of the Matrix Market file.");
5041 if (istr.fail() && tolerant) {
5047 TEUCHOS_TEST_FOR_EXCEPTION(
5048 ! tolerant && istr.fail(), std::runtime_error,
5049 "Failed to read matrix data from line " << lineNumber
5050 <<
" of the Matrix Market file.");
5053 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
5055 curRow = count % numRows;
5056 curCol = count / numRows;
5057 X_view[curRow + curCol*stride] = val;
5062 TEUCHOS_TEST_FOR_EXCEPTION(
5063 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
5065 "The Matrix Market metadata reports that the dense matrix is "
5066 << numRows <<
" x " << numCols <<
", and thus has "
5067 << numRows*numCols <<
" total entries, but we only found " << count
5068 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
5069 }
catch (std::exception& e) {
5071 localReadDataSuccess = 0;
5076 *err << myRank <<
": readVectorImpl: done reading data" << endl;
5080 int globalReadDataSuccess = localReadDataSuccess;
5081 broadcast (*comm, 0, outArg (globalReadDataSuccess));
5082 TEUCHOS_TEST_FOR_EXCEPTION(
5083 globalReadDataSuccess == 0, std::runtime_error,
5084 "Failed to read the multivector's data: " << exMsg.str ());
5089 if (comm->getSize () == 1 && map.is_null ()) {
5091 if (! err.is_null ()) {
5095 *err << myRank <<
": readVectorImpl: done" << endl;
5097 if (! err.is_null ()) {
5104 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
5108 RCP<MV> Y = createVector<ST, LO, GO, NT> (map);
5111 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
5117 Export<LO, GO, NT> exporter (proc0Map, map, err);
5120 *err << myRank <<
": readVectorImpl: Exporting" << endl;
5123 Y->doExport (*X, exporter,
INSERT);
5125 if (! err.is_null ()) {
5129 *err << myRank <<
": readVectorImpl: done" << endl;
5131 if (! err.is_null ()) {
5159 static Teuchos::RCP<const map_type>
5161 const Teuchos::RCP<const comm_type>& comm,
5162 const bool tolerant=
false,
5163 const bool debug=
false)
5165 Teuchos::RCP<Teuchos::FancyOStream> err =
5166 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
5167 return readMap (in, comm, err, tolerant, debug);
5196 static Teuchos::RCP<const map_type>
5198 const Teuchos::RCP<const comm_type>& comm,
5199 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5200 const bool tolerant=
false,
5201 const bool debug=
false)
5203 using Teuchos::arcp;
5204 using Teuchos::Array;
5205 using Teuchos::ArrayRCP;
5207 using Teuchos::broadcast;
5208 using Teuchos::Comm;
5209 using Teuchos::CommRequest;
5210 using Teuchos::inOutArg;
5211 using Teuchos::ireceive;
5212 using Teuchos::outArg;
5214 using Teuchos::receive;
5215 using Teuchos::reduceAll;
5216 using Teuchos::REDUCE_MIN;
5217 using Teuchos::isend;
5218 using Teuchos::SerialComm;
5219 using Teuchos::toString;
5220 using Teuchos::wait;
5223 typedef ptrdiff_t int_type;
5229 const int numProcs = comm->getSize ();
5230 const int myRank = comm->getRank ();
5232 if (err.is_null ()) {
5236 std::ostringstream os;
5237 os << myRank <<
": readMap: " << endl;
5240 if (err.is_null ()) {
5246 const int sizeTag = 1339;
5248 const int dataTag = 1340;
5254 RCP<CommRequest<int> > sizeReq;
5255 RCP<CommRequest<int> > dataReq;
5260 ArrayRCP<int_type> numGidsToRecv (1);
5261 numGidsToRecv[0] = 0;
5263 sizeReq = ireceive<int, int_type> (numGidsToRecv, 0, sizeTag, *comm);
5266 int readSuccess = 1;
5267 std::ostringstream exMsg;
5276 RCP<const Comm<int> > proc0Comm (
new SerialComm<int> ());
5278 RCP<const map_type> dataMap;
5282 data = readDenseImpl<GO> (in, proc0Comm, dataMap, err, tolerant, debug);
5284 if (data.is_null ()) {
5286 exMsg <<
"readDenseImpl() returned null." << endl;
5288 }
catch (std::exception& e) {
5290 exMsg << e.what () << endl;
5296 std::map<int, Array<GO> > pid2gids;
5301 int_type globalNumGIDs = 0;
5311 if (myRank == 0 && readSuccess == 1) {
5312 if (data->getNumVectors () == 2) {
5313 ArrayRCP<const GO> GIDs = data->getData (0);
5314 ArrayRCP<const GO> PIDs = data->getData (1);
5315 globalNumGIDs = GIDs.size ();
5319 if (globalNumGIDs > 0) {
5320 const int pid =
static_cast<int> (PIDs[0]);
5322 if (pid < 0 || pid >= numProcs) {
5324 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5325 <<
"Encountered invalid PID " << pid <<
"." << endl;
5328 const GO gid = GIDs[0];
5329 pid2gids[pid].push_back (gid);
5333 if (readSuccess == 1) {
5336 for (size_type k = 1; k < globalNumGIDs; ++k) {
5337 const int pid =
static_cast<int> (PIDs[k]);
5338 if (pid < 0 || pid >= numProcs) {
5340 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5341 <<
"Encountered invalid PID " << pid <<
"." << endl;
5344 const int_type gid = GIDs[k];
5345 pid2gids[pid].push_back (gid);
5346 if (gid < indexBase) {
5353 else if (data->getNumVectors () == 1) {
5354 if (data->getGlobalLength () % 2 !=
static_cast<GST
> (0)) {
5356 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
5357 "wrong format (for Map format 2.0). The global number of rows "
5358 "in the MultiVector must be even (divisible by 2)." << endl;
5361 ArrayRCP<const GO> theData = data->getData (0);
5362 globalNumGIDs =
static_cast<GO
> (data->getGlobalLength ()) /
5363 static_cast<GO> (2);
5367 if (globalNumGIDs > 0) {
5368 const int pid =
static_cast<int> (theData[1]);
5369 if (pid < 0 || pid >= numProcs) {
5371 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5372 <<
"Encountered invalid PID " << pid <<
"." << endl;
5375 const GO gid = theData[0];
5376 pid2gids[pid].push_back (gid);
5382 for (int_type k = 1; k < globalNumGIDs; ++k) {
5383 const int pid =
static_cast<int> (theData[2*k + 1]);
5384 if (pid < 0 || pid >= numProcs) {
5386 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5387 <<
"Encountered invalid PID " << pid <<
"." << endl;
5390 const GO gid = theData[2*k];
5391 pid2gids[pid].push_back (gid);
5392 if (gid < indexBase) {
5401 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
5402 "either 1 column (for the new Map format 2.0) or 2 columns (for "
5403 "the old Map format 1.0).";
5410 int_type readResults[3];
5411 readResults[0] =
static_cast<int_type
> (indexBase);
5412 readResults[1] =
static_cast<int_type
> (globalNumGIDs);
5413 readResults[2] =
static_cast<int_type
> (readSuccess);
5414 broadcast<int, int_type> (*comm, 0, 3, readResults);
5416 indexBase =
static_cast<GO
> (readResults[0]);
5417 globalNumGIDs =
static_cast<int_type
> (readResults[1]);
5418 readSuccess =
static_cast<int> (readResults[2]);
5424 TEUCHOS_TEST_FOR_EXCEPTION(
5425 readSuccess != 1, std::runtime_error,
5426 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
5427 "following exception message: " << exMsg.str ());
5431 for (
int p = 1; p < numProcs; ++p) {
5432 ArrayRCP<int_type> numGidsToSend (1);
5434 auto it = pid2gids.find (p);
5435 if (it == pid2gids.end ()) {
5436 numGidsToSend[0] = 0;
5438 numGidsToSend[0] = it->second.size ();
5440 sizeReq = isend<int, int_type> (numGidsToSend, p, sizeTag, *comm);
5441 wait<int> (*comm, outArg (sizeReq));
5446 wait<int> (*comm, outArg (sizeReq));
5451 ArrayRCP<GO> myGids;
5452 int_type myNumGids = 0;
5454 GO* myGidsRaw = NULL;
5456 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (0);
5457 if (it != pid2gids.end ()) {
5458 myGidsRaw = it->second.getRawPtr ();
5459 myNumGids = it->second.size ();
5461 myGids = arcp<GO> (myGidsRaw, 0, myNumGids,
false);
5465 myNumGids = numGidsToRecv[0];
5466 myGids = arcp<GO> (myNumGids);
5473 if (myNumGids > 0) {
5474 dataReq = ireceive<int, GO> (myGids, 0, dataTag, *comm);
5478 for (
int p = 1; p < numProcs; ++p) {
5480 ArrayRCP<GO> sendGids;
5481 GO* sendGidsRaw = NULL;
5482 int_type numSendGids = 0;
5484 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (p);
5485 if (it != pid2gids.end ()) {
5486 numSendGids = it->second.size ();
5487 sendGidsRaw = it->second.getRawPtr ();
5488 sendGids = arcp<GO> (sendGidsRaw, 0, numSendGids,
false);
5491 if (numSendGids > 0) {
5492 dataReq = isend<int, GO> (sendGids, p, dataTag, *comm);
5494 wait<int> (*comm, outArg (dataReq));
5496 else if (myRank == p) {
5498 wait<int> (*comm, outArg (dataReq));
5503 std::ostringstream os;
5504 os << myRank <<
": readMap: creating Map" << endl;
5507 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
5508 RCP<const map_type> newMap;
5515 std::ostringstream errStrm;
5517 newMap = rcp (
new map_type (INVALID, myGids (), indexBase, comm));
5519 catch (std::exception& e) {
5521 errStrm <<
"Process " << comm->getRank () <<
" threw an exception: "
5522 << e.what () << std::endl;
5526 errStrm <<
"Process " << comm->getRank () <<
" threw an exception "
5527 "not a subclass of std::exception" << std::endl;
5529 Teuchos::reduceAll<int, int> (*comm, Teuchos::REDUCE_MIN,
5530 lclSuccess, Teuchos::outArg (gblSuccess));
5531 if (gblSuccess != 1) {
5534 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
5536 if (err.is_null ()) {
5540 std::ostringstream os;
5541 os << myRank <<
": readMap: done" << endl;
5544 if (err.is_null ()) {
5564 encodeDataType (
const std::string& dataType)
5566 if (dataType ==
"real" || dataType ==
"integer") {
5568 }
else if (dataType ==
"complex") {
5570 }
else if (dataType ==
"pattern") {
5576 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
5577 "Unrecognized Matrix Market data type \"" << dataType
5578 <<
"\". We should never get here. "
5579 "Please report this bug to the Tpetra developers.");
5612 template<
class SparseMatrixType>
5617 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
5679 const std::string& matrixName,
5680 const std::string& matrixDescription,
5681 const bool debug=
false)
5683 Teuchos::RCP<const Teuchos::Comm<int> > comm = matrix.getComm ();
5684 TEUCHOS_TEST_FOR_EXCEPTION
5685 (comm.is_null (), std::invalid_argument,
5686 "The input matrix's communicator (Teuchos::Comm object) is null.");
5687 const int myRank = comm->getRank ();
5692 out.open (filename.c_str ());
5694 writeSparse (out, matrix, matrixName, matrixDescription, debug);
5703 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5704 const std::string& matrixName,
5705 const std::string& matrixDescription,
5706 const bool debug=
false)
5708 TEUCHOS_TEST_FOR_EXCEPTION
5709 (pMatrix.is_null (), std::invalid_argument,
5710 "The input matrix is null.");
5712 matrixDescription, debug);
5737 const bool debug=
false)
5745 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5746 const bool debug=
false)
5784 const std::string& matrixName,
5785 const std::string& matrixDescription,
5786 const bool debug=
false)
5788 using Teuchos::ArrayView;
5789 using Teuchos::Comm;
5790 using Teuchos::FancyOStream;
5791 using Teuchos::getFancyOStream;
5792 using Teuchos::null;
5794 using Teuchos::rcpFromRef;
5800 using STS =
typename Teuchos::ScalarTraits<ST>;
5806 Teuchos::SetScientific<ST> sci (out);
5809 RCP<const Comm<int> > comm = matrix.getComm ();
5810 TEUCHOS_TEST_FOR_EXCEPTION(
5811 comm.is_null (), std::invalid_argument,
5812 "The input matrix's communicator (Teuchos::Comm object) is null.");
5813 const int myRank = comm->getRank ();
5816 RCP<FancyOStream> err =
5817 debug ? getFancyOStream (rcpFromRef (std::cerr)) : null;
5819 std::ostringstream os;
5820 os << myRank <<
": writeSparse" << endl;
5823 os <<
"-- " << myRank <<
": past barrier" << endl;
5828 const bool debugPrint = debug && myRank == 0;
5830 RCP<const map_type> rowMap = matrix.getRowMap ();
5831 RCP<const map_type> colMap = matrix.getColMap ();
5832 RCP<const map_type> domainMap = matrix.getDomainMap ();
5833 RCP<const map_type> rangeMap = matrix.getRangeMap ();
5835 const global_size_t numRows = rangeMap->getGlobalNumElements ();
5836 const global_size_t numCols = domainMap->getGlobalNumElements ();
5838 if (debug && myRank == 0) {
5839 std::ostringstream os;
5840 os <<
"-- Input sparse matrix is:"
5841 <<
"---- " << numRows <<
" x " << numCols << endl
5843 << (matrix.isGloballyIndexed() ?
"Globally" :
"Locally")
5844 <<
" indexed." << endl
5845 <<
"---- Its row map has " << rowMap->getGlobalNumElements ()
5846 <<
" elements." << endl
5847 <<
"---- Its col map has " << colMap->getGlobalNumElements ()
5848 <<
" elements." << endl;
5853 const size_t localNumRows = (myRank == 0) ? numRows : 0;
5855 std::ostringstream os;
5856 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
5859 RCP<const map_type> gatherRowMap =
5860 Details::computeGatherMap (rowMap, err, debug);
5868 const size_t localNumCols = (myRank == 0) ? numCols : 0;
5869 RCP<const map_type> gatherColMap =
5870 Details::computeGatherMap (colMap, err, debug);
5874 import_type importer (rowMap, gatherRowMap);
5879 RCP<sparse_matrix_type> newMatrix =
5881 static_cast<size_t> (0)));
5883 newMatrix->doImport (matrix, importer,
INSERT);
5888 RCP<const map_type> gatherDomainMap =
5889 rcp (
new map_type (numCols, localNumCols,
5890 domainMap->getIndexBase (),
5892 RCP<const map_type> gatherRangeMap =
5893 rcp (
new map_type (numRows, localNumRows,
5894 rangeMap->getIndexBase (),
5896 newMatrix->fillComplete (gatherDomainMap, gatherRangeMap);
5900 cerr <<
"-- Output sparse matrix is:"
5901 <<
"---- " << newMatrix->getRangeMap ()->getGlobalNumElements ()
5903 << newMatrix->getDomainMap ()->getGlobalNumElements ()
5905 << newMatrix->getGlobalNumEntries () <<
" entries;" << endl
5907 << (newMatrix->isGloballyIndexed () ?
"Globally" :
"Locally")
5908 <<
" indexed." << endl
5909 <<
"---- Its row map has "
5910 << newMatrix->getRowMap ()->getGlobalNumElements ()
5911 <<
" elements, with index base "
5912 << newMatrix->getRowMap ()->getIndexBase () <<
"." << endl
5913 <<
"---- Its col map has "
5914 << newMatrix->getColMap ()->getGlobalNumElements ()
5915 <<
" elements, with index base "
5916 << newMatrix->getColMap ()->getIndexBase () <<
"." << endl
5917 <<
"---- Element count of output matrix's column Map may differ "
5918 <<
"from that of the input matrix's column Map, if some columns "
5919 <<
"of the matrix contain no entries." << endl;
5932 out <<
"%%MatrixMarket matrix coordinate "
5933 << (STS::isComplex ?
"complex" :
"real")
5934 <<
" general" << endl;
5937 if (matrixName !=
"") {
5938 printAsComment (out, matrixName);
5940 if (matrixDescription !=
"") {
5941 printAsComment (out, matrixDescription);
5951 out << newMatrix->getRangeMap ()->getGlobalNumElements () <<
" "
5952 << newMatrix->getDomainMap ()->getGlobalNumElements () <<
" "
5953 << newMatrix->getGlobalNumEntries () << endl;
5958 const GO rowIndexBase = gatherRowMap->getIndexBase ();
5959 const GO colIndexBase = newMatrix->getColMap()->getIndexBase ();
5967 if (newMatrix->isGloballyIndexed()) {
5970 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
5971 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
5972 for (GO globalRowIndex = minAllGlobalIndex;
5973 globalRowIndex <= maxAllGlobalIndex;
5975 ArrayView<const GO> ind;
5976 ArrayView<const ST> val;
5977 newMatrix->getGlobalRowView (globalRowIndex, ind, val);
5978 auto indIter = ind.begin ();
5979 auto valIter = val.begin ();
5980 for (; indIter != ind.end() && valIter != val.end();
5981 ++indIter, ++valIter) {
5982 const GO globalColIndex = *indIter;
5985 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
5986 << (globalColIndex + 1 - colIndexBase) <<
" ";
5987 if (STS::isComplex) {
5988 out << STS::real (*valIter) <<
" " << STS::imag (*valIter);
5997 using OTG = Teuchos::OrdinalTraits<GO>;
5998 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
5999 localRowIndex <= gatherRowMap->getMaxLocalIndex();
6002 const GO globalRowIndex =
6003 gatherRowMap->getGlobalElement (localRowIndex);
6004 TEUCHOS_TEST_FOR_EXCEPTION(
6005 globalRowIndex == OTG::invalid(), std::logic_error,
6006 "Failed to convert the supposed local row index "
6007 << localRowIndex <<
" into a global row index. "
6008 "Please report this bug to the Tpetra developers.");
6009 ArrayView<const LO> ind;
6010 ArrayView<const ST> val;
6011 newMatrix->getLocalRowView (localRowIndex, ind, val);
6012 auto indIter = ind.begin ();
6013 auto valIter = val.begin ();
6014 for (; indIter != ind.end() && valIter != val.end();
6015 ++indIter, ++valIter) {
6017 const GO globalColIndex =
6018 newMatrix->getColMap()->getGlobalElement (*indIter);
6019 TEUCHOS_TEST_FOR_EXCEPTION(
6020 globalColIndex == OTG::invalid(), std::logic_error,
6021 "On local row " << localRowIndex <<
" of the sparse matrix: "
6022 "Failed to convert the supposed local column index "
6023 << *indIter <<
" into a global column index. Please report "
6024 "this bug to the Tpetra developers.");
6027 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6028 << (globalColIndex + 1 - colIndexBase) <<
" ";
6029 if (STS::isComplex) {
6030 out << STS::real (*valIter) <<
" " << STS::imag (*valIter);
6044 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6045 const std::string& matrixName,
6046 const std::string& matrixDescription,
6047 const bool debug=
false)
6049 TEUCHOS_TEST_FOR_EXCEPTION
6050 (pMatrix.is_null (), std::invalid_argument,
6051 "The input matrix is null.");
6052 writeSparse (out, *pMatrix, matrixName, matrixDescription, debug);
6088 const std::string& graphName,
6089 const std::string& graphDescription,
6090 const bool debug=
false)
6092 using Teuchos::ArrayView;
6093 using Teuchos::Comm;
6094 using Teuchos::FancyOStream;
6095 using Teuchos::getFancyOStream;
6096 using Teuchos::null;
6098 using Teuchos::rcpFromRef;
6109 if (rowMap.is_null ()) {
6112 auto comm = rowMap->getComm ();
6113 if (comm.is_null ()) {
6116 const int myRank = comm->getRank ();
6119 RCP<FancyOStream> err =
6120 debug ? getFancyOStream (rcpFromRef (std::cerr)) : null;
6122 std::ostringstream os;
6123 os << myRank <<
": writeSparseGraph" << endl;
6126 os <<
"-- " << myRank <<
": past barrier" << endl;
6131 const bool debugPrint = debug && myRank == 0;
6138 const global_size_t numRows = rangeMap->getGlobalNumElements ();
6139 const global_size_t numCols = domainMap->getGlobalNumElements ();
6141 if (debug && myRank == 0) {
6142 std::ostringstream os;
6143 os <<
"-- Input sparse graph is:"
6144 <<
"---- " << numRows <<
" x " << numCols <<
" with "
6148 <<
" indexed." << endl
6149 <<
"---- Its row Map has " << rowMap->getGlobalNumElements ()
6150 <<
" elements." << endl
6151 <<
"---- Its col Map has " << colMap->getGlobalNumElements ()
6152 <<
" elements." << endl;
6157 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6159 std::ostringstream os;
6160 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6163 auto gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
6171 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6172 auto gatherColMap = Details::computeGatherMap (colMap, err, debug);
6181 static_cast<size_t> (0));
6188 RCP<const map_type> gatherDomainMap =
6189 rcp (
new map_type (numCols, localNumCols,
6190 domainMap->getIndexBase (),
6192 RCP<const map_type> gatherRangeMap =
6193 rcp (
new map_type (numRows, localNumRows,
6194 rangeMap->getIndexBase (),
6196 newGraph.
fillComplete (gatherDomainMap, gatherRangeMap);
6200 cerr <<
"-- Output sparse graph is:"
6201 <<
"---- " << newGraph.
getRangeMap ()->getGlobalNumElements ()
6208 <<
" indexed." << endl
6209 <<
"---- Its row map has "
6210 << newGraph.
getRowMap ()->getGlobalNumElements ()
6211 <<
" elements, with index base "
6212 << newGraph.
getRowMap ()->getIndexBase () <<
"." << endl
6213 <<
"---- Its col map has "
6214 << newGraph.
getColMap ()->getGlobalNumElements ()
6215 <<
" elements, with index base "
6216 << newGraph.
getColMap ()->getIndexBase () <<
"." << endl
6217 <<
"---- Element count of output graph's column Map may differ "
6218 <<
"from that of the input matrix's column Map, if some columns "
6219 <<
"of the matrix contain no entries." << endl;
6233 out <<
"%%MatrixMarket matrix coordinate pattern general" << endl;
6236 if (graphName !=
"") {
6237 printAsComment (out, graphName);
6239 if (graphDescription !=
"") {
6240 printAsComment (out, graphDescription);
6251 out << newGraph.
getRangeMap ()->getGlobalNumElements () <<
" "
6252 << newGraph.
getDomainMap ()->getGlobalNumElements () <<
" "
6258 const GO rowIndexBase = gatherRowMap->getIndexBase ();
6259 const GO colIndexBase = newGraph.
getColMap()->getIndexBase ();
6270 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
6271 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
6272 for (GO globalRowIndex = minAllGlobalIndex;
6273 globalRowIndex <= maxAllGlobalIndex;
6275 ArrayView<const GO> ind;
6277 for (
auto indIter = ind.begin (); indIter != ind.end (); ++indIter) {
6278 const GO globalColIndex = *indIter;
6281 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6282 << (globalColIndex + 1 - colIndexBase) <<
" ";
6288 typedef Teuchos::OrdinalTraits<GO> OTG;
6289 for (LO localRowIndex = gatherRowMap->getMinLocalIndex ();
6290 localRowIndex <= gatherRowMap->getMaxLocalIndex ();
6293 const GO globalRowIndex =
6294 gatherRowMap->getGlobalElement (localRowIndex);
6295 TEUCHOS_TEST_FOR_EXCEPTION
6296 (globalRowIndex == OTG::invalid (), std::logic_error,
"Failed "
6297 "to convert the supposed local row index " << localRowIndex <<
6298 " into a global row index. Please report this bug to the "
6299 "Tpetra developers.");
6300 ArrayView<const LO> ind;
6302 for (
auto indIter = ind.begin (); indIter != ind.end (); ++indIter) {
6304 const GO globalColIndex =
6305 newGraph.
getColMap ()->getGlobalElement (*indIter);
6306 TEUCHOS_TEST_FOR_EXCEPTION(
6307 globalColIndex == OTG::invalid(), std::logic_error,
6308 "On local row " << localRowIndex <<
" of the sparse graph: "
6309 "Failed to convert the supposed local column index "
6310 << *indIter <<
" into a global column index. Please report "
6311 "this bug to the Tpetra developers.");
6314 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6315 << (globalColIndex + 1 - colIndexBase) <<
" ";
6331 const bool debug=
false)
6373 const std::string& graphName,
6374 const std::string& graphDescription,
6375 const bool debug=
false)
6378 if (comm.is_null ()) {
6386 const int myRank = comm->getRank ();
6391 out.open (filename.c_str ());
6406 const bool debug=
false)
6421 const Teuchos::RCP<const crs_graph_type>& pGraph,
6422 const std::string& graphName,
6423 const std::string& graphDescription,
6424 const bool debug=
false)
6440 const Teuchos::RCP<const crs_graph_type>& pGraph,
6441 const bool debug=
false)
6471 const bool debug=
false)
6479 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6480 const bool debug=
false)
6516 const std::string& matrixName,
6517 const std::string& matrixDescription,
6518 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6519 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6521 const int myRank = X.
getMap ().is_null () ? 0 :
6522 (X.
getMap ()->getComm ().is_null () ? 0 :
6523 X.
getMap ()->getComm ()->getRank ());
6527 out.open (filename.c_str());
6530 writeDense (out, X, matrixName, matrixDescription, err, dbg);
6543 const Teuchos::RCP<const multivector_type>& X,
6544 const std::string& matrixName,
6545 const std::string& matrixDescription,
6546 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6547 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6549 TEUCHOS_TEST_FOR_EXCEPTION(
6550 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
6551 "writeDenseFile: The input MultiVector X is null.");
6552 writeDenseFile (filename, *X, matrixName, matrixDescription, err, dbg);
6563 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6564 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6576 const Teuchos::RCP<const multivector_type>& X,
6577 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6578 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6580 TEUCHOS_TEST_FOR_EXCEPTION(
6581 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
6582 "writeDenseFile: The input MultiVector X is null.");
6620 const std::string& matrixName,
6621 const std::string& matrixDescription,
6622 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6623 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6625 using Teuchos::Comm;
6626 using Teuchos::outArg;
6627 using Teuchos::REDUCE_MAX;
6628 using Teuchos::reduceAll;
6632 RCP<const Comm<int> > comm = X.
getMap ().is_null () ?
6633 Teuchos::null : X.
getMap ()->getComm ();
6634 const int myRank = comm.is_null () ? 0 : comm->getRank ();
6639 const bool debug = ! dbg.is_null ();
6642 std::ostringstream os;
6643 os << myRank <<
": writeDense" << endl;
6648 writeDenseHeader (out, X, matrixName, matrixDescription, err, dbg);
6653 for (
size_t j = 0; j < numVecs; ++j) {
6654 writeDenseColumn (out, * (X.
getVector (j)), err, dbg);
6659 std::ostringstream os;
6660 os << myRank <<
": writeDense: Done" << endl;
6694 writeDenseHeader (std::ostream& out,
6696 const std::string& matrixName,
6697 const std::string& matrixDescription,
6698 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6699 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6701 using Teuchos::Comm;
6702 using Teuchos::outArg;
6704 using Teuchos::REDUCE_MAX;
6705 using Teuchos::reduceAll;
6707 typedef Teuchos::ScalarTraits<scalar_type> STS;
6708 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
6710 RCP<const Comm<int> > comm = X.getMap ().is_null () ?
6711 Teuchos::null : X.getMap ()->getComm ();
6712 const int myRank = comm.is_null () ? 0 : comm->getRank ();
6719 const bool debug = ! dbg.is_null ();
6723 std::ostringstream os;
6724 os << myRank <<
": writeDenseHeader" << endl;
6743 std::ostringstream hdr;
6745 std::string dataType;
6746 if (STS::isComplex) {
6747 dataType =
"complex";
6748 }
else if (STS::isOrdinal) {
6749 dataType =
"integer";
6753 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
6758 if (matrixName !=
"") {
6759 printAsComment (hdr, matrixName);
6761 if (matrixDescription !=
"") {
6762 printAsComment (hdr, matrixDescription);
6765 hdr << X.getGlobalLength () <<
" " << X.getNumVectors () << endl;
6769 }
catch (std::exception& e) {
6770 if (! err.is_null ()) {
6771 *err << prefix <<
"While writing the Matrix Market header, "
6772 "Process 0 threw an exception: " << e.what () << endl;
6781 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
6782 TEUCHOS_TEST_FOR_EXCEPTION(
6783 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
6784 "which prevented this method from completing.");
6788 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
6811 writeDenseColumn (std::ostream& out,
6813 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6814 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6816 using Teuchos::arcp;
6817 using Teuchos::Array;
6818 using Teuchos::ArrayRCP;
6819 using Teuchos::ArrayView;
6820 using Teuchos::Comm;
6821 using Teuchos::CommRequest;
6822 using Teuchos::ireceive;
6823 using Teuchos::isend;
6824 using Teuchos::outArg;
6825 using Teuchos::REDUCE_MAX;
6826 using Teuchos::reduceAll;
6828 using Teuchos::TypeNameTraits;
6829 using Teuchos::wait;
6831 typedef Teuchos::ScalarTraits<scalar_type> STS;
6833 const Comm<int>& comm = * (X.getMap ()->getComm ());
6834 const int myRank = comm.getRank ();
6835 const int numProcs = comm.getSize ();
6842 const bool debug = ! dbg.is_null ();
6846 std::ostringstream os;
6847 os << myRank <<
": writeDenseColumn" << endl;
6856 Teuchos::SetScientific<scalar_type> sci (out);
6858 const size_t myNumRows = X.getLocalLength ();
6859 const size_t numCols = X.getNumVectors ();
6862 const int sizeTag = 1337;
6863 const int dataTag = 1338;
6924 RCP<CommRequest<int> > sendReqSize, sendReqData;
6930 Array<ArrayRCP<size_t> > recvSizeBufs (3);
6931 Array<ArrayRCP<scalar_type> > recvDataBufs (3);
6932 Array<RCP<CommRequest<int> > > recvSizeReqs (3);
6933 Array<RCP<CommRequest<int> > > recvDataReqs (3);
6936 ArrayRCP<size_t> sendDataSize (1);
6937 sendDataSize[0] = myNumRows;
6941 std::ostringstream os;
6942 os << myRank <<
": Post receive-size receives from "
6943 "Procs 1 and 2: tag = " << sizeTag << endl;
6947 recvSizeBufs[0].resize (1);
6951 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
6952 recvSizeBufs[1].resize (1);
6953 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
6954 recvSizeBufs[2].resize (1);
6955 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
6958 ireceive<int, size_t> (recvSizeBufs[1], 1, sizeTag, comm);
6962 ireceive<int, size_t> (recvSizeBufs[2], 2, sizeTag, comm);
6965 else if (myRank == 1 || myRank == 2) {
6967 std::ostringstream os;
6968 os << myRank <<
": Post send-size send: size = "
6969 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6976 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
6980 std::ostringstream os;
6981 os << myRank <<
": Not posting my send-size send yet" << endl;
6990 std::ostringstream os;
6991 os << myRank <<
": Pack my entries" << endl;
6994 ArrayRCP<scalar_type> sendDataBuf;
6996 sendDataBuf = arcp<scalar_type> (myNumRows * numCols);
6997 X.get1dCopy (sendDataBuf (), myNumRows);
6999 catch (std::exception& e) {
7001 if (! err.is_null ()) {
7002 std::ostringstream os;
7003 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
7004 "entries threw an exception: " << e.what () << endl;
7009 std::ostringstream os;
7010 os << myRank <<
": Done packing my entries" << endl;
7019 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
7022 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7030 std::ostringstream os;
7031 os << myRank <<
": Write my entries" << endl;
7037 const size_t printNumRows = myNumRows;
7038 ArrayView<const scalar_type> printData = sendDataBuf ();
7039 const size_t printStride = printNumRows;
7040 if (static_cast<size_t> (printData.size ()) < printStride * numCols) {
7042 if (! err.is_null ()) {
7043 std::ostringstream os;
7044 os <<
"Process " << myRank <<
": My MultiVector data's size "
7045 << printData.size () <<
" does not match my local dimensions "
7046 << printStride <<
" x " << numCols <<
"." << endl;
7054 for (
size_t col = 0; col < numCols; ++col) {
7055 for (
size_t row = 0; row < printNumRows; ++row) {
7056 if (STS::isComplex) {
7057 out << STS::real (printData[row + col * printStride]) <<
" "
7058 << STS::imag (printData[row + col * printStride]) << endl;
7060 out << printData[row + col * printStride] << endl;
7069 const int recvRank = 1;
7070 const int circBufInd = recvRank % 3;
7072 std::ostringstream os;
7073 os << myRank <<
": Wait on receive-size receive from Process "
7074 << recvRank << endl;
7078 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7082 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7083 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7085 if (! err.is_null ()) {
7086 std::ostringstream os;
7087 os << myRank <<
": Result of receive-size receive from Process "
7088 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7089 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7090 "This should never happen, and suggests that the receive never "
7091 "got posted. Please report this bug to the Tpetra developers."
7106 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7108 std::ostringstream os;
7109 os << myRank <<
": Post receive-data receive from Process "
7110 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7111 << recvDataBufs[circBufInd].size () << endl;
7114 if (! recvSizeReqs[circBufInd].is_null ()) {
7116 if (! err.is_null ()) {
7117 std::ostringstream os;
7118 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7119 "null, before posting the receive-data receive from Process "
7120 << recvRank <<
". This should never happen. Please report "
7121 "this bug to the Tpetra developers." << endl;
7125 recvDataReqs[circBufInd] =
7126 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7127 recvRank, dataTag, comm);
7130 else if (myRank == 1) {
7133 std::ostringstream os;
7134 os << myRank <<
": Wait on my send-size send" << endl;
7137 wait<int> (comm, outArg (sendReqSize));
7143 for (
int p = 1; p < numProcs; ++p) {
7145 if (p + 2 < numProcs) {
7147 const int recvRank = p + 2;
7148 const int circBufInd = recvRank % 3;
7150 std::ostringstream os;
7151 os << myRank <<
": Post receive-size receive from Process "
7152 << recvRank <<
": tag = " << sizeTag << endl;
7155 if (! recvSizeReqs[circBufInd].is_null ()) {
7157 if (! err.is_null ()) {
7158 std::ostringstream os;
7159 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7160 <<
"null, for the receive-size receive from Process "
7161 << recvRank <<
"! This may mean that this process never "
7162 <<
"finished waiting for the receive from Process "
7163 << (recvRank - 3) <<
"." << endl;
7167 recvSizeReqs[circBufInd] =
7168 ireceive<int, size_t> (recvSizeBufs[circBufInd],
7169 recvRank, sizeTag, comm);
7172 if (p + 1 < numProcs) {
7173 const int recvRank = p + 1;
7174 const int circBufInd = recvRank % 3;
7178 std::ostringstream os;
7179 os << myRank <<
": Wait on receive-size receive from Process "
7180 << recvRank << endl;
7183 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7187 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7188 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7190 if (! err.is_null ()) {
7191 std::ostringstream os;
7192 os << myRank <<
": Result of receive-size receive from Process "
7193 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7194 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7195 "This should never happen, and suggests that the receive never "
7196 "got posted. Please report this bug to the Tpetra developers."
7210 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7212 std::ostringstream os;
7213 os << myRank <<
": Post receive-data receive from Process "
7214 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7215 << recvDataBufs[circBufInd].size () << endl;
7218 if (! recvDataReqs[circBufInd].is_null ()) {
7220 if (! err.is_null ()) {
7221 std::ostringstream os;
7222 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
7223 <<
"null, for the receive-data receive from Process "
7224 << recvRank <<
"! This may mean that this process never "
7225 <<
"finished waiting for the receive from Process "
7226 << (recvRank - 3) <<
"." << endl;
7230 recvDataReqs[circBufInd] =
7231 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7232 recvRank, dataTag, comm);
7236 const int recvRank = p;
7237 const int circBufInd = recvRank % 3;
7239 std::ostringstream os;
7240 os << myRank <<
": Wait on receive-data receive from Process "
7241 << recvRank << endl;
7244 wait<int> (comm, outArg (recvDataReqs[circBufInd]));
7251 std::ostringstream os;
7252 os << myRank <<
": Write entries from Process " << recvRank
7254 *dbg << os.str () << endl;
7256 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
7257 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7259 if (! err.is_null ()) {
7260 std::ostringstream os;
7261 os << myRank <<
": Result of receive-size receive from Process "
7262 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
7263 "invalid() = " << Teuchos::OrdinalTraits<size_t>::invalid ()
7264 <<
". This should never happen, and suggests that its "
7265 "receive-size receive was never posted. "
7266 "Please report this bug to the Tpetra developers." << endl;
7273 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null ()) {
7275 if (! err.is_null ()) {
7276 std::ostringstream os;
7277 os << myRank <<
": Result of receive-size receive from Proc "
7278 << recvRank <<
" was " << printNumRows <<
" > 0, but "
7279 "recvDataBufs[" << circBufInd <<
"] is null. This should "
7280 "never happen. Please report this bug to the Tpetra "
7281 "developers." << endl;
7291 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd]) ();
7292 const size_t printStride = printNumRows;
7296 for (
size_t col = 0; col < numCols; ++col) {
7297 for (
size_t row = 0; row < printNumRows; ++row) {
7298 if (STS::isComplex) {
7299 out << STS::real (printData[row + col * printStride]) <<
" "
7300 << STS::imag (printData[row + col * printStride]) << endl;
7302 out << printData[row + col * printStride] << endl;
7307 else if (myRank == p) {
7310 std::ostringstream os;
7311 os << myRank <<
": Wait on my send-data send" << endl;
7314 wait<int> (comm, outArg (sendReqData));
7316 else if (myRank == p + 1) {
7319 std::ostringstream os;
7320 os << myRank <<
": Post send-data send: tag = " << dataTag
7324 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7327 std::ostringstream os;
7328 os << myRank <<
": Wait on my send-size send" << endl;
7331 wait<int> (comm, outArg (sendReqSize));
7333 else if (myRank == p + 2) {
7336 std::ostringstream os;
7337 os << myRank <<
": Post send-size send: size = "
7338 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7341 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
7346 reduceAll<int, int> (comm, REDUCE_MAX, lclErr, outArg (gblErr));
7347 TEUCHOS_TEST_FOR_EXCEPTION(
7348 gblErr == 1, std::runtime_error,
"Tpetra::MatrixMarket::writeDense "
7349 "experienced some kind of error and was unable to complete.");
7353 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
7367 const Teuchos::RCP<const multivector_type>& X,
7368 const std::string& matrixName,
7369 const std::string& matrixDescription,
7370 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7371 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7373 TEUCHOS_TEST_FOR_EXCEPTION(
7374 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7375 "writeDense: The input MultiVector X is null.");
7376 writeDense (out, *X, matrixName, matrixDescription, err, dbg);
7387 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7388 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7400 const Teuchos::RCP<const multivector_type>& X,
7401 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7402 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7404 TEUCHOS_TEST_FOR_EXCEPTION(
7405 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7406 "writeDense: The input MultiVector X is null.");
7432 Teuchos::RCP<Teuchos::FancyOStream> err =
7433 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
7448 const Teuchos::RCP<Teuchos::FancyOStream>& err,
7449 const bool debug=
false)
7451 using Teuchos::Array;
7452 using Teuchos::ArrayRCP;
7453 using Teuchos::ArrayView;
7454 using Teuchos::Comm;
7455 using Teuchos::CommRequest;
7456 using Teuchos::ireceive;
7457 using Teuchos::isend;
7459 using Teuchos::TypeNameTraits;
7460 using Teuchos::wait;
7463 typedef int pid_type;
7478 typedef ptrdiff_t int_type;
7479 TEUCHOS_TEST_FOR_EXCEPTION(
7480 sizeof (GO) >
sizeof (int_type), std::logic_error,
7481 "The global ordinal type GO=" << TypeNameTraits<GO>::name ()
7482 <<
" is too big for ptrdiff_t. sizeof(GO) = " <<
sizeof (GO)
7483 <<
" > sizeof(ptrdiff_t) = " <<
sizeof (ptrdiff_t) <<
".");
7484 TEUCHOS_TEST_FOR_EXCEPTION(
7485 sizeof (pid_type) >
sizeof (int_type), std::logic_error,
7486 "The (MPI) process rank type pid_type=" <<
7487 TypeNameTraits<pid_type>::name () <<
" is too big for ptrdiff_t. "
7488 "sizeof(pid_type) = " <<
sizeof (pid_type) <<
" > sizeof(ptrdiff_t)"
7489 " = " <<
sizeof (ptrdiff_t) <<
".");
7491 const Comm<int>& comm = * (map.
getComm ());
7492 const int myRank = comm.getRank ();
7493 const int numProcs = comm.getSize ();
7495 if (! err.is_null ()) {
7499 std::ostringstream os;
7500 os << myRank <<
": writeMap" << endl;
7503 if (! err.is_null ()) {
7510 const int sizeTag = 1337;
7511 const int dataTag = 1338;
7570 RCP<CommRequest<int> > sendReqSize, sendReqData;
7576 Array<ArrayRCP<int_type> > recvSizeBufs (3);
7577 Array<ArrayRCP<int_type> > recvDataBufs (3);
7578 Array<RCP<CommRequest<int> > > recvSizeReqs (3);
7579 Array<RCP<CommRequest<int> > > recvDataReqs (3);
7582 ArrayRCP<int_type> sendDataSize (1);
7583 sendDataSize[0] = myNumRows;
7587 std::ostringstream os;
7588 os << myRank <<
": Post receive-size receives from "
7589 "Procs 1 and 2: tag = " << sizeTag << endl;
7593 recvSizeBufs[0].resize (1);
7594 (recvSizeBufs[0])[0] = -1;
7595 recvSizeBufs[1].resize (1);
7596 (recvSizeBufs[1])[0] = -1;
7597 recvSizeBufs[2].resize (1);
7598 (recvSizeBufs[2])[0] = -1;
7601 ireceive<int, int_type> (recvSizeBufs[1], 1, sizeTag, comm);
7605 ireceive<int, int_type> (recvSizeBufs[2], 2, sizeTag, comm);
7608 else if (myRank == 1 || myRank == 2) {
7610 std::ostringstream os;
7611 os << myRank <<
": Post send-size send: size = "
7612 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7619 sendReqSize = isend<int, int_type> (sendDataSize, 0, sizeTag, comm);
7623 std::ostringstream os;
7624 os << myRank <<
": Not posting my send-size send yet" << endl;
7635 std::ostringstream os;
7636 os << myRank <<
": Pack my GIDs and PIDs" << endl;
7640 ArrayRCP<int_type> sendDataBuf (myNumRows * 2);
7643 const int_type myMinGblIdx =
7645 for (
size_t k = 0; k < myNumRows; ++k) {
7646 const int_type gid = myMinGblIdx +
static_cast<int_type
> (k);
7647 const int_type pid =
static_cast<int_type
> (myRank);
7648 sendDataBuf[2*k] = gid;
7649 sendDataBuf[2*k+1] = pid;
7654 for (
size_t k = 0; k < myNumRows; ++k) {
7655 const int_type gid =
static_cast<int_type
> (myGblInds[k]);
7656 const int_type pid =
static_cast<int_type
> (myRank);
7657 sendDataBuf[2*k] = gid;
7658 sendDataBuf[2*k+1] = pid;
7663 std::ostringstream os;
7664 os << myRank <<
": Done packing my GIDs and PIDs" << endl;
7671 *err << myRank <<
": Post send-data send: tag = " << dataTag
7674 sendReqData = isend<int, int_type> (sendDataBuf, 0, dataTag, comm);
7679 *err << myRank <<
": Write MatrixMarket header" << endl;
7684 std::ostringstream hdr;
7688 hdr <<
"%%MatrixMarket matrix array integer general" << endl
7689 <<
"% Format: Version 2.0" << endl
7691 <<
"% This file encodes a Tpetra::Map." << endl
7692 <<
"% It is stored as a dense vector, with twice as many " << endl
7693 <<
"% entries as the global number of GIDs (global indices)." << endl
7694 <<
"% (GID, PID) pairs are stored contiguously, where the PID " << endl
7695 <<
"% is the rank of the process owning that GID." << endl
7700 std::ostringstream os;
7701 os << myRank <<
": Write my GIDs and PIDs" << endl;
7707 const int_type printNumRows = myNumRows;
7708 ArrayView<const int_type> printData = sendDataBuf ();
7709 for (int_type k = 0; k < printNumRows; ++k) {
7710 const int_type gid = printData[2*k];
7711 const int_type pid = printData[2*k+1];
7712 out << gid << endl << pid << endl;
7718 const int recvRank = 1;
7719 const int circBufInd = recvRank % 3;
7721 std::ostringstream os;
7722 os << myRank <<
": Wait on receive-size receive from Process "
7723 << recvRank << endl;
7727 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7731 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
7732 if (debug && recvNumRows == -1) {
7733 std::ostringstream os;
7734 os << myRank <<
": Result of receive-size receive from Process "
7735 << recvRank <<
" is -1. This should never happen, and "
7736 "suggests that the receive never got posted. Please report "
7737 "this bug to the Tpetra developers." << endl;
7742 recvDataBufs[circBufInd].resize (recvNumRows * 2);
7744 std::ostringstream os;
7745 os << myRank <<
": Post receive-data receive from Process "
7746 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7747 << recvDataBufs[circBufInd].size () << endl;
7750 if (! recvSizeReqs[circBufInd].is_null ()) {
7751 std::ostringstream os;
7752 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7753 "null, before posting the receive-data receive from Process "
7754 << recvRank <<
". This should never happen. Please report "
7755 "this bug to the Tpetra developers." << endl;
7758 recvDataReqs[circBufInd] =
7759 ireceive<int, int_type> (recvDataBufs[circBufInd],
7760 recvRank, dataTag, comm);
7763 else if (myRank == 1) {
7766 std::ostringstream os;
7767 os << myRank <<
": Wait on my send-size send" << endl;
7770 wait<int> (comm, outArg (sendReqSize));
7776 for (
int p = 1; p < numProcs; ++p) {
7778 if (p + 2 < numProcs) {
7780 const int recvRank = p + 2;
7781 const int circBufInd = recvRank % 3;
7783 std::ostringstream os;
7784 os << myRank <<
": Post receive-size receive from Process "
7785 << recvRank <<
": tag = " << sizeTag << endl;
7788 if (! recvSizeReqs[circBufInd].is_null ()) {
7789 std::ostringstream os;
7790 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7791 <<
"null, for the receive-size receive from Process "
7792 << recvRank <<
"! This may mean that this process never "
7793 <<
"finished waiting for the receive from Process "
7794 << (recvRank - 3) <<
"." << endl;
7797 recvSizeReqs[circBufInd] =
7798 ireceive<int, int_type> (recvSizeBufs[circBufInd],
7799 recvRank, sizeTag, comm);
7802 if (p + 1 < numProcs) {
7803 const int recvRank = p + 1;
7804 const int circBufInd = recvRank % 3;
7808 std::ostringstream os;
7809 os << myRank <<
": Wait on receive-size receive from Process "
7810 << recvRank << endl;
7813 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7817 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
7818 if (debug && recvNumRows == -1) {
7819 std::ostringstream os;
7820 os << myRank <<
": Result of receive-size receive from Process "
7821 << recvRank <<
" is -1. This should never happen, and "
7822 "suggests that the receive never got posted. Please report "
7823 "this bug to the Tpetra developers." << endl;
7828 recvDataBufs[circBufInd].resize (recvNumRows * 2);
7830 std::ostringstream os;
7831 os << myRank <<
": Post receive-data receive from Process "
7832 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7833 << recvDataBufs[circBufInd].size () << endl;
7836 if (! recvDataReqs[circBufInd].is_null ()) {
7837 std::ostringstream os;
7838 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
7839 <<
"null, for the receive-data receive from Process "
7840 << recvRank <<
"! This may mean that this process never "
7841 <<
"finished waiting for the receive from Process "
7842 << (recvRank - 3) <<
"." << endl;
7845 recvDataReqs[circBufInd] =
7846 ireceive<int, int_type> (recvDataBufs[circBufInd],
7847 recvRank, dataTag, comm);
7851 const int recvRank = p;
7852 const int circBufInd = recvRank % 3;
7854 std::ostringstream os;
7855 os << myRank <<
": Wait on receive-data receive from Process "
7856 << recvRank << endl;
7859 wait<int> (comm, outArg (recvDataReqs[circBufInd]));
7866 std::ostringstream os;
7867 os << myRank <<
": Write GIDs and PIDs from Process "
7868 << recvRank << endl;
7869 *err << os.str () << endl;
7871 const int_type printNumRows = (recvSizeBufs[circBufInd])[0];
7872 if (debug && printNumRows == -1) {
7873 std::ostringstream os;
7874 os << myRank <<
": Result of receive-size receive from Process "
7875 << recvRank <<
" was -1. This should never happen, and "
7876 "suggests that its receive-size receive was never posted. "
7877 "Please report this bug to the Tpetra developers." << endl;
7880 if (debug && printNumRows > 0 && recvDataBufs[circBufInd].is_null ()) {
7881 std::ostringstream os;
7882 os << myRank <<
": Result of receive-size receive from Proc "
7883 << recvRank <<
" was " << printNumRows <<
" > 0, but "
7884 "recvDataBufs[" << circBufInd <<
"] is null. This should "
7885 "never happen. Please report this bug to the Tpetra "
7886 "developers." << endl;
7889 ArrayView<const int_type> printData = (recvDataBufs[circBufInd]) ();
7890 for (int_type k = 0; k < printNumRows; ++k) {
7891 const int_type gid = printData[2*k];
7892 const int_type pid = printData[2*k+1];
7893 out << gid << endl << pid << endl;
7896 else if (myRank == p) {
7899 std::ostringstream os;
7900 os << myRank <<
": Wait on my send-data send" << endl;
7903 wait<int> (comm, outArg (sendReqData));
7905 else if (myRank == p + 1) {
7908 std::ostringstream os;
7909 os << myRank <<
": Post send-data send: tag = " << dataTag
7913 sendReqData = isend<int, int_type> (sendDataBuf, 0, dataTag, comm);
7916 std::ostringstream os;
7917 os << myRank <<
": Wait on my send-size send" << endl;
7920 wait<int> (comm, outArg (sendReqSize));
7922 else if (myRank == p + 2) {
7925 std::ostringstream os;
7926 os << myRank <<
": Post send-size send: size = "
7927 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7930 sendReqSize = isend<int, int_type> (sendDataSize, 0, sizeTag, comm);
7934 if (! err.is_null ()) {
7938 *err << myRank <<
": writeMap: Done" << endl;
7940 if (! err.is_null ()) {
7950 const int myRank = map.
getComm ()->getRank ();
7953 out.open (filename.c_str());
7986 printAsComment (std::ostream& out,
const std::string& str)
7989 std::istringstream inpstream (str);
7992 while (getline (inpstream, line)) {
7993 if (! line.empty()) {
7996 if (line[0] ==
'%') {
7997 out << line << endl;
8000 out <<
"%% " << line << endl;
8028 Teuchos::ParameterList pl;
8054 Teuchos::ParameterList pl;
8097 const Teuchos::ParameterList& params)
8100 std::string tmpFile =
"__TMP__" + fileName;
8101 const int myRank = A.
getDomainMap()->getComm()->getRank();
8102 bool precisionChanged=
false;
8112 if (std::ifstream(tmpFile))
8113 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
8114 "writeOperator: temporary file " << tmpFile <<
" already exists");
8115 out.open(tmpFile.c_str());
8116 if (params.isParameter(
"precision")) {
8117 oldPrecision = out.precision(params.get<
int>(
"precision"));
8118 precisionChanged=
true;
8122 const std::string header = writeOperatorImpl(out, A, params);
8125 if (precisionChanged)
8126 out.precision(oldPrecision);
8128 out.open(fileName.c_str(), std::ios::binary);
8129 bool printMatrixMarketHeader =
true;
8130 if (params.isParameter(
"print MatrixMarket header"))
8131 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
8132 if (printMatrixMarketHeader && myRank == 0) {
8137 std::ifstream src(tmpFile, std::ios_base::binary);
8141 remove(tmpFile.c_str());
8186 const Teuchos::ParameterList& params)
8188 const int myRank = A.
getDomainMap ()->getComm ()->getRank ();
8205 std::ostringstream tmpOut;
8207 if (params.isParameter (
"precision") && params.isType<
int> (
"precision")) {
8208 (void) tmpOut.precision (params.get<
int> (
"precision"));
8212 const std::string header = writeOperatorImpl (tmpOut, A, params);
8215 bool printMatrixMarketHeader =
true;
8216 if (params.isParameter (
"print MatrixMarket header") &&
8217 params.isType<
bool> (
"print MatrixMarket header")) {
8218 printMatrixMarketHeader = params.get<
bool> (
"print MatrixMarket header");
8220 if (printMatrixMarketHeader && myRank == 0) {
8236 out << tmpOut.str ();
8250 writeOperatorImpl (std::ostream& os,
8251 const operator_type& A,
8252 const Teuchos::ParameterList& params)
8256 using Teuchos::ArrayRCP;
8257 using Teuchos::Array;
8261 typedef scalar_type Scalar;
8262 typedef Teuchos::OrdinalTraits<LO> TLOT;
8263 typedef Teuchos::OrdinalTraits<GO> TGOT;
8267 const map_type& domainMap = *(A.getDomainMap());
8268 RCP<const map_type> rangeMap = A.getRangeMap();
8269 RCP<const Teuchos::Comm<int> > comm = rangeMap->getComm();
8270 const int myRank = comm->getRank();
8271 const size_t numProcs = comm->getSize();
8274 if (params.isParameter(
"probing size"))
8275 numMVs = params.get<
int>(
"probing size");
8278 GO minColGid = domainMap.getMinAllGlobalIndex();
8279 GO maxColGid = domainMap.getMaxAllGlobalIndex();
8284 GO numGlobElts = maxColGid - minColGid + TGOT::one();
8285 GO numChunks = numGlobElts / numMVs;
8286 GO rem = numGlobElts % numMVs;
8287 GO indexBase = rangeMap->getIndexBase();
8289 int offsetToUseInPrinting = 1 - indexBase;
8290 if (params.isParameter(
"zero-based indexing")) {
8291 if (params.get<
bool>(
"zero-based indexing") ==
true)
8292 offsetToUseInPrinting = -indexBase;
8296 size_t numLocalRangeEntries = rangeMap->getNodeNumElements();
8299 RCP<const map_type> allGidsMap = rcp(
new map_type(TGOT::invalid(), numLocalRangeEntries,
8302 mv_type_go allGids(allGidsMap,1);
8303 Teuchos::ArrayRCP<GO> allGidsData = allGids.getDataNonConst(0);
8305 for (
size_t i=0; i<numLocalRangeEntries; i++)
8306 allGidsData[i] = rangeMap->getGlobalElement(i);
8307 allGidsData = Teuchos::null;
8310 GO numTargetMapEntries=TGOT::zero();
8311 Teuchos::Array<GO> importGidList;
8313 numTargetMapEntries = rangeMap->getGlobalNumElements();
8314 importGidList.reserve(numTargetMapEntries);
8315 for (GO j=0; j<numTargetMapEntries; ++j) importGidList.push_back(j + indexBase);
8317 importGidList.reserve(numTargetMapEntries);
8319 RCP<map_type> importGidMap = rcp(
new map_type(TGOT::invalid(), importGidList(), indexBase, comm));
8322 import_type gidImporter(allGidsMap, importGidMap);
8323 mv_type_go importedGids(importGidMap, 1);
8324 importedGids.doImport(allGids, gidImporter,
INSERT);
8327 ArrayRCP<const GO> importedGidsData = importedGids.getData(0);
8328 RCP<const map_type> importMap = rcp(
new map_type(TGOT::invalid(), importedGidsData(), indexBase, comm) );
8331 import_type importer(rangeMap, importMap);
8333 RCP<mv_type> colsOnPid0 = rcp(
new mv_type(importMap,numMVs));
8335 RCP<mv_type> ei = rcp(
new mv_type(A.getDomainMap(),numMVs));
8336 RCP<mv_type> colsA = rcp(
new mv_type(A.getRangeMap(),numMVs));
8338 Array<GO> globalColsArray, localColsArray;
8339 globalColsArray.reserve(numMVs);
8340 localColsArray.reserve(numMVs);
8342 ArrayRCP<ArrayRCP<Scalar> > eiData(numMVs);
8343 for (
size_t i=0; i<numMVs; ++i)
8344 eiData[i] = ei->getDataNonConst(i);
8349 for (GO k=0; k<numChunks; ++k) {
8350 for (
size_t j=0; j<numMVs; ++j ) {
8352 GO curGlobalCol = minColGid + k*numMVs + j;
8353 globalColsArray.push_back(curGlobalCol);
8355 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8356 if (curLocalCol != TLOT::invalid()) {
8357 eiData[j][curLocalCol] = TGOT::one();
8358 localColsArray.push_back(curLocalCol);
8364 A.apply(*ei,*colsA);
8366 colsOnPid0->doImport(*colsA,importer,
INSERT);
8369 globalNnz += writeColumns(os,*colsOnPid0, numMVs, importedGidsData(),
8370 globalColsArray, offsetToUseInPrinting);
8373 for (
size_t j=0; j<numMVs; ++j ) {
8374 for (
int i=0; i<localColsArray.size(); ++i)
8375 eiData[j][localColsArray[i]] = TGOT::zero();
8377 globalColsArray.clear();
8378 localColsArray.clear();
8386 for (
int j=0; j<rem; ++j ) {
8387 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
8388 globalColsArray.push_back(curGlobalCol);
8390 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8391 if (curLocalCol != TLOT::invalid()) {
8392 eiData[j][curLocalCol] = TGOT::one();
8393 localColsArray.push_back(curLocalCol);
8399 A.apply(*ei,*colsA);
8401 colsOnPid0->doImport(*colsA,importer,
INSERT);
8403 globalNnz += writeColumns(os,*colsOnPid0, rem, importedGidsData(),
8404 globalColsArray, offsetToUseInPrinting);
8407 for (
int j=0; j<rem; ++j ) {
8408 for (
int i=0; i<localColsArray.size(); ++i)
8409 eiData[j][localColsArray[i]] = TGOT::zero();
8411 globalColsArray.clear();
8412 localColsArray.clear();
8421 std::ostringstream oss;
8423 oss <<
"%%MatrixMarket matrix coordinate ";
8424 if (Teuchos::ScalarTraits<typename operator_type::scalar_type>::isComplex) {
8429 oss <<
" general" << std::endl;
8430 oss <<
"% Tpetra::Operator" << std::endl;
8431 std::time_t now = std::time(NULL);
8432 oss <<
"% time stamp: " << ctime(&now);
8433 oss <<
"% written from " << numProcs <<
" processes" << std::endl;
8434 size_t numRows = rangeMap->getGlobalNumElements();
8435 size_t numCols = domainMap.getGlobalNumElements();
8436 oss << numRows <<
" " << numCols <<
" " << globalNnz << std::endl;
8443 writeColumns(std::ostream& os, mv_type
const &colsA,
size_t const &numCols,
8444 Teuchos::ArrayView<const global_ordinal_type>
const &rowGids,
8445 Teuchos::Array<global_ordinal_type>
const &colsArray,
8449 typedef scalar_type Scalar;
8450 typedef Teuchos::ScalarTraits<Scalar> STS;
8453 const Scalar zero = STS::zero();
8454 const size_t numRows = colsA.getGlobalLength();
8455 for (
size_t j=0; j<numCols; ++j) {
8456 Teuchos::ArrayRCP<const Scalar>
const curCol = colsA.getData(j);
8457 const GO J = colsArray[j];
8458 for (
size_t i=0; i<numRows; ++i) {
8459 const Scalar val = curCol[i];
8461 os << rowGids[i]+indexBase <<
" " << J+indexBase <<
" " << val << std::endl;
8478 #endif // __MatrixMarket_Tpetra_hpp
static Teuchos::RCP< vector_type > readVectorFile(const std::string &filename, const Teuchos::RCP< const comm_type > &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read a Vector from the given Matrix Market file.
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.
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.
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 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.
static Teuchos::RCP< sparse_matrix_type > readSparseFile(const std::string &filename, 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 file.
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.
SparseMatrixType::local_ordinal_type local_ordinal_type
SparseMatrixType::global_ordinal_type global_ordinal_type
One or more distributed dense vectors.
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.
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.
void getLocalRowView(const local_ordinal_type lclRow, Teuchos::ArrayView< const local_ordinal_type > &lclColInds) const override
Get a const, non-persisting view of the given local row's local column indices, as a Teuchos::ArrayVi...
static Teuchos::RCP< sparse_matrix_type > readSparseFile(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 matrix 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< const map_type > readMapFile(const std::string &filename, const Teuchos::RCP< const comm_type > &comm, const bool tolerant=false, const bool debug=false)
Read Map (as a MultiVector) from the given Matrix Market file.
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 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.
static Teuchos::RCP< sparse_graph_type > readSparseGraphFile(const std::string &filename, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market file.
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. ...
static Teuchos::RCP< multivector_type > readDense(std::istream &in, const Teuchos::RCP< const comm_type > &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read dense matrix (as a MultiVector) from the given Matrix Market input stream.
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 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...
size_t global_size_t
Global size_t object.
static Teuchos::RCP< vector_type > readVector(std::istream &in, const Teuchos::RCP< const comm_type > &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read Vector from the given Matrix Market input stream.
SparseMatrixType::node_type node_type
The Kokkos Node type; fourth template parameter of Tpetra::CrsMatrix.
static void writeOperator(const std::string &fileName, const operator_type &A, const Teuchos::ParameterList ¶ms)
Write a Tpetra::Operator to a file, with options.
static Teuchos::RCP< const map_type > readMap(std::istream &in, const Teuchos::RCP< const comm_type > &comm, const bool tolerant=false, const bool debug=false)
Read Map (as a MultiVector) from the given input stream.
Map< local_ordinal_type, global_ordinal_type, node_type > map_type
Specialization of Tpetra::Map that matches SparseMatrixType.
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 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...
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 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.
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 void writeSparseFile(const std::string &filename, const sparse_matrix_type &matrix, const bool debug=false)
Print the sparse matrix in Matrix Market format.
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.
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 Teuchos::RCP< const map_type > readMap(std::istream &in, const Teuchos::RCP< const comm_type > &comm, const Teuchos::RCP< Teuchos::FancyOStream > &err, const bool tolerant=false, const bool debug=false)
Read Map (as a MultiVector) from the given input stream, with optional debugging output stream...
static Teuchos::RCP< multivector_type > readDenseFile(const std::string &filename, const Teuchos::RCP< const comm_type > &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read dense matrix (as a MultiVector) from the given Matrix Market file.
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.
void getGlobalRowView(const global_ordinal_type gblRow, Teuchos::ArrayView< const global_ordinal_type > &gblColInds) const override
Get a const, non-persisting view of the given global row's global column indices, as a Teuchos::Array...
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.
MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > multivector_type
The MultiVector specialization associated with SparseMatrixType.
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).
Teuchos::ArrayView< const global_ordinal_type > getNodeElementList() const
Return a NONOWNING view of the global indices owned by this process.
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.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
A parallel distribution of indices over processes.
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.
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.
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.
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.
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.