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"
69 #include "Teuchos_TimeMonitor.hpp"
72 #include "mmio_Tpetra.h"
74 #include "Tpetra_Distribution.hpp"
115 namespace MatrixMarket {
171 template<
class SparseMatrixType>
176 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
191 typedef typename SparseMatrixType::global_ordinal_type
213 typedef Teuchos::Comm<int> comm_type;
223 typedef Teuchos::ArrayRCP<int>::size_type size_type;
235 static Teuchos::RCP<const map_type>
236 makeRangeMap (
const Teuchos::RCP<const comm_type>& pComm,
240 return rcp (
new map_type (static_cast<global_size_t> (numRows),
241 static_cast<global_ordinal_type> (0),
242 pComm, GloballyDistributed));
272 static Teuchos::RCP<const map_type>
273 makeRowMap (
const Teuchos::RCP<const map_type>& pRowMap,
274 const Teuchos::RCP<const comm_type>& pComm,
279 if (pRowMap.is_null ()) {
280 return rcp (
new map_type (static_cast<global_size_t> (numRows),
281 static_cast<global_ordinal_type> (0),
282 pComm, GloballyDistributed));
285 TEUCHOS_TEST_FOR_EXCEPTION
286 (! pRowMap->isDistributed () && pComm->getSize () > 1,
287 std::invalid_argument,
"The specified row map is not distributed, "
288 "but the given communicator includes more than one process (in "
289 "fact, there are " << pComm->getSize () <<
" processes).");
290 TEUCHOS_TEST_FOR_EXCEPTION
291 (pRowMap->getComm () != pComm, std::invalid_argument,
292 "The specified row Map's communicator (pRowMap->getComm()) "
293 "differs from the given separately supplied communicator pComm.");
312 static Teuchos::RCP<const map_type>
313 makeDomainMap (
const Teuchos::RCP<const map_type>& pRangeMap,
322 if (numRows == numCols) {
325 return createUniformContigMapWithNode<LO,GO,NT> (numCols,
326 pRangeMap->getComm ());
403 distribute (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
404 Teuchos::ArrayRCP<size_t>& myRowPtr,
405 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
406 Teuchos::ArrayRCP<scalar_type>& myValues,
407 const Teuchos::RCP<const map_type>& pRowMap,
408 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
409 Teuchos::ArrayRCP<size_t>& rowPtr,
410 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
411 Teuchos::ArrayRCP<scalar_type>& values,
412 const bool debug=
false)
415 using Teuchos::ArrayRCP;
416 using Teuchos::ArrayView;
419 using Teuchos::CommRequest;
422 using Teuchos::receive;
427 const bool extraDebug =
false;
428 RCP<const comm_type> pComm = pRowMap->getComm ();
429 const int numProcs = pComm->getSize ();
430 const int myRank = pComm->getRank ();
431 const int rootRank = 0;
438 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
439 const size_type myNumRows = myRows.size();
440 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<size_t>(myNumRows) !=
441 pRowMap->getLocalNumElements(),
443 "pRowMap->getLocalElementList().size() = "
445 <<
" != pRowMap->getLocalNumElements() = "
446 << pRowMap->getLocalNumElements() <<
". "
447 "Please report this bug to the Tpetra developers.");
448 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
450 "On Proc 0: numEntriesPerRow.size() = "
451 << numEntriesPerRow.size()
452 <<
" != pRowMap->getLocalElementList().size() = "
453 << myNumRows <<
". Please report this bug to the "
454 "Tpetra developers.");
458 myNumEntriesPerRow = arcp<size_t> (myNumRows);
460 if (myRank != rootRank) {
464 send (*pComm, myNumRows, rootRank);
465 if (myNumRows != 0) {
469 send (*pComm, static_cast<int> (myNumRows),
470 myRows.getRawPtr(), rootRank);
480 receive (*pComm, rootRank,
481 static_cast<int> (myNumRows),
482 myNumEntriesPerRow.getRawPtr());
487 std::accumulate (myNumEntriesPerRow.begin(),
488 myNumEntriesPerRow.end(), 0);
494 myColInd = arcp<GO> (myNumEntries);
495 myValues = arcp<scalar_type> (myNumEntries);
496 if (myNumEntries > 0) {
499 receive (*pComm, rootRank,
500 static_cast<int> (myNumEntries),
501 myColInd.getRawPtr());
502 receive (*pComm, rootRank,
503 static_cast<int> (myNumEntries),
504 myValues.getRawPtr());
510 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
514 for (size_type k = 0; k < myNumRows; ++k) {
515 const GO myCurRow = myRows[k];
517 myNumEntriesPerRow[k] = numEntriesInThisRow;
519 if (extraDebug && debug) {
520 cerr <<
"Proc " << pRowMap->getComm ()->getRank ()
521 <<
": myNumEntriesPerRow[0.." << (myNumRows-1) <<
"] = [";
522 for (size_type k = 0; k < myNumRows; ++k) {
523 cerr << myNumEntriesPerRow[k];
524 if (k < myNumRows-1) {
532 std::accumulate (myNumEntriesPerRow.begin(),
533 myNumEntriesPerRow.end(), 0);
535 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
536 << myNumEntries <<
" entries" << endl;
538 myColInd = arcp<GO> (myNumEntries);
539 myValues = arcp<scalar_type> (myNumEntries);
547 for (size_type k = 0; k < myNumRows;
548 myCurPos += myNumEntriesPerRow[k], ++k) {
550 const GO myRow = myRows[k];
551 const size_t curPos = rowPtr[myRow];
554 if (curNumEntries > 0) {
555 ArrayView<GO> colIndView = colInd (curPos, curNumEntries);
556 ArrayView<GO> myColIndView = myColInd (myCurPos, curNumEntries);
557 std::copy (colIndView.begin(), colIndView.end(),
558 myColIndView.begin());
560 ArrayView<scalar_type> valuesView =
561 values (curPos, curNumEntries);
562 ArrayView<scalar_type> myValuesView =
563 myValues (myCurPos, curNumEntries);
564 std::copy (valuesView.begin(), valuesView.end(),
565 myValuesView.begin());
570 for (
int p = 1; p < numProcs; ++p) {
572 cerr <<
"-- Proc 0: Processing proc " << p << endl;
575 size_type theirNumRows = 0;
580 receive (*pComm, p, &theirNumRows);
582 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
583 << theirNumRows <<
" rows" << endl;
585 if (theirNumRows != 0) {
590 ArrayRCP<GO> theirRows = arcp<GO> (theirNumRows);
591 receive (*pComm, p, as<int> (theirNumRows),
592 theirRows.getRawPtr ());
601 const global_size_t numRows = pRowMap->getGlobalNumElements ();
602 const GO indexBase = pRowMap->getIndexBase ();
603 bool theirRowsValid =
true;
604 for (size_type k = 0; k < theirNumRows; ++k) {
605 if (theirRows[k] < indexBase ||
606 as<global_size_t> (theirRows[k] - indexBase) >= numRows) {
607 theirRowsValid =
false;
610 if (! theirRowsValid) {
611 TEUCHOS_TEST_FOR_EXCEPTION(
612 ! theirRowsValid, std::logic_error,
613 "Proc " << p <<
" has at least one invalid row index. "
614 "Here are all of them: " <<
615 Teuchos::toString (theirRows ()) <<
". Valid row index "
616 "range (zero-based): [0, " << (numRows - 1) <<
"].");
631 ArrayRCP<size_t> theirNumEntriesPerRow;
632 theirNumEntriesPerRow = arcp<size_t> (theirNumRows);
633 for (size_type k = 0; k < theirNumRows; ++k) {
634 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
641 send (*pComm, static_cast<int> (theirNumRows),
642 theirNumEntriesPerRow.getRawPtr(), p);
646 std::accumulate (theirNumEntriesPerRow.begin(),
647 theirNumEntriesPerRow.end(), 0);
650 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
651 << theirNumEntries <<
" entries" << endl;
656 if (theirNumEntries == 0) {
665 ArrayRCP<GO> theirColInd (theirNumEntries);
666 ArrayRCP<scalar_type> theirValues (theirNumEntries);
674 for (size_type k = 0; k < theirNumRows;
675 theirCurPos += theirNumEntriesPerRow[k], k++) {
677 const GO theirRow = theirRows[k];
683 if (curNumEntries > 0) {
684 ArrayView<GO> colIndView =
685 colInd (curPos, curNumEntries);
686 ArrayView<GO> theirColIndView =
687 theirColInd (theirCurPos, curNumEntries);
688 std::copy (colIndView.begin(), colIndView.end(),
689 theirColIndView.begin());
691 ArrayView<scalar_type> valuesView =
692 values (curPos, curNumEntries);
693 ArrayView<scalar_type> theirValuesView =
694 theirValues (theirCurPos, curNumEntries);
695 std::copy (valuesView.begin(), valuesView.end(),
696 theirValuesView.begin());
703 send (*pComm, static_cast<int> (theirNumEntries),
704 theirColInd.getRawPtr(), p);
705 send (*pComm, static_cast<int> (theirNumEntries),
706 theirValues.getRawPtr(), p);
709 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
717 numEntriesPerRow = null;
722 if (debug && myRank == 0) {
723 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
731 myRowPtr = arcp<size_t> (myNumRows+1);
733 for (size_type k = 1; k < myNumRows+1; ++k) {
734 myRowPtr[k] = myRowPtr[k-1] + myNumEntriesPerRow[k-1];
736 if (extraDebug && debug) {
737 cerr <<
"Proc " << Teuchos::rank (*(pRowMap->getComm()))
738 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
739 for (size_type k = 0; k < myNumRows+1; ++k) {
745 cerr <<
"]" << endl << endl;
748 if (debug && myRank == 0) {
749 cerr <<
"-- Proc 0: Done with distribute" << endl;
766 static Teuchos::RCP<sparse_matrix_type>
767 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
768 Teuchos::ArrayRCP<size_t>& myRowPtr,
769 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
770 Teuchos::ArrayRCP<scalar_type>& myValues,
771 const Teuchos::RCP<const map_type>& pRowMap,
772 const Teuchos::RCP<const map_type>& pRangeMap,
773 const Teuchos::RCP<const map_type>& pDomainMap,
774 const bool callFillComplete =
true)
776 using Teuchos::ArrayView;
790 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
791 "makeMatrix: myRowPtr array is null. "
792 "Please report this bug to the Tpetra developers.");
793 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
794 "makeMatrix: domain map is null. "
795 "Please report this bug to the Tpetra developers.");
796 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
797 "makeMatrix: range map is null. "
798 "Please report this bug to the Tpetra developers.");
799 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
800 "makeMatrix: row map is null. "
801 "Please report this bug to the Tpetra developers.");
805 RCP<sparse_matrix_type> A =
810 ArrayView<const GO> myRows = pRowMap->getLocalElementList ();
811 const size_type myNumRows = myRows.size ();
814 const GO indexBase = pRowMap->getIndexBase ();
815 for (size_type i = 0; i < myNumRows; ++i) {
816 const size_type myCurPos = myRowPtr[i];
818 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
819 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
822 for (size_type k = 0; k < curNumEntries; ++k) {
823 curColInd[k] += indexBase;
826 if (curNumEntries > 0) {
827 A->insertGlobalValues (myRows[i], curColInd, curValues);
834 myNumEntriesPerRow = null;
839 if (callFillComplete) {
840 A->fillComplete (pDomainMap, pRangeMap);
850 static Teuchos::RCP<sparse_matrix_type>
851 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
852 Teuchos::ArrayRCP<size_t>& myRowPtr,
853 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
854 Teuchos::ArrayRCP<scalar_type>& myValues,
855 const Teuchos::RCP<const map_type>& pRowMap,
856 const Teuchos::RCP<const map_type>& pRangeMap,
857 const Teuchos::RCP<const map_type>& pDomainMap,
858 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
859 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams)
861 using Teuchos::ArrayView;
875 TEUCHOS_TEST_FOR_EXCEPTION(
876 myRowPtr.is_null(), std::logic_error,
877 "makeMatrix: myRowPtr array is null. "
878 "Please report this bug to the Tpetra developers.");
879 TEUCHOS_TEST_FOR_EXCEPTION(
880 pDomainMap.is_null(), std::logic_error,
881 "makeMatrix: domain map is null. "
882 "Please report this bug to the Tpetra developers.");
883 TEUCHOS_TEST_FOR_EXCEPTION(
884 pRangeMap.is_null(), std::logic_error,
885 "makeMatrix: range map is null. "
886 "Please report this bug to the Tpetra developers.");
887 TEUCHOS_TEST_FOR_EXCEPTION(
888 pRowMap.is_null(), std::logic_error,
889 "makeMatrix: row map is null. "
890 "Please report this bug to the Tpetra developers.");
894 RCP<sparse_matrix_type> A =
900 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
901 const size_type myNumRows = myRows.size();
904 const GO indexBase = pRowMap->getIndexBase ();
905 for (size_type i = 0; i < myNumRows; ++i) {
906 const size_type myCurPos = myRowPtr[i];
908 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
909 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
912 for (size_type k = 0; k < curNumEntries; ++k) {
913 curColInd[k] += indexBase;
915 if (curNumEntries > 0) {
916 A->insertGlobalValues (myRows[i], curColInd, curValues);
923 myNumEntriesPerRow = null;
928 A->fillComplete (pDomainMap, pRangeMap, fillCompleteParams);
936 static Teuchos::RCP<sparse_matrix_type>
937 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
938 Teuchos::ArrayRCP<size_t>& myRowPtr,
939 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
940 Teuchos::ArrayRCP<scalar_type>& myValues,
941 const Teuchos::RCP<const map_type>& rowMap,
942 Teuchos::RCP<const map_type>& colMap,
943 const Teuchos::RCP<const map_type>& domainMap,
944 const Teuchos::RCP<const map_type>& rangeMap,
945 const bool callFillComplete =
true)
947 using Teuchos::ArrayView;
956 RCP<sparse_matrix_type> A;
957 if (colMap.is_null ()) {
965 ArrayView<const GO> myRows = rowMap->getLocalElementList ();
966 const size_type myNumRows = myRows.size ();
969 const GO indexBase = rowMap->getIndexBase ();
970 for (size_type i = 0; i < myNumRows; ++i) {
971 const size_type myCurPos = myRowPtr[i];
972 const size_type curNumEntries = as<size_type> (myNumEntriesPerRow[i]);
973 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
974 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
977 for (size_type k = 0; k < curNumEntries; ++k) {
978 curColInd[k] += indexBase;
980 if (curNumEntries > 0) {
981 A->insertGlobalValues (myRows[i], curColInd, curValues);
988 myNumEntriesPerRow = null;
993 if (callFillComplete) {
994 A->fillComplete (domainMap, rangeMap);
995 if (colMap.is_null ()) {
996 colMap = A->getColMap ();
1020 static Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
1021 readBanner (std::istream& in,
1023 const bool tolerant=
false,
1025 const bool isGraph=
false)
1027 using Teuchos::MatrixMarket::Banner;
1032 typedef Teuchos::ScalarTraits<scalar_type> STS;
1034 RCP<Banner> pBanner;
1038 const bool readFailed = ! getline(in, line);
1039 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
1040 "Failed to get Matrix Market banner line from input.");
1047 pBanner = rcp (
new Banner (line, tolerant));
1048 }
catch (std::exception& e) {
1050 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1051 "Matrix Market banner line contains syntax error(s): "
1055 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
1056 std::invalid_argument,
"The Matrix Market file does not contain "
1057 "matrix data. Its Banner (first) line says that its object type is \""
1058 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
1062 TEUCHOS_TEST_FOR_EXCEPTION(
1063 ! STS::isComplex && pBanner->dataType() ==
"complex",
1064 std::invalid_argument,
1065 "The Matrix Market file contains complex-valued data, but you are "
1066 "trying to read it into a matrix containing entries of the real-"
1067 "valued Scalar type \""
1068 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
1069 TEUCHOS_TEST_FOR_EXCEPTION(
1071 pBanner->dataType() !=
"real" &&
1072 pBanner->dataType() !=
"complex" &&
1073 pBanner->dataType() !=
"integer",
1074 std::invalid_argument,
1075 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
1076 "Matrix Market file may not contain a \"pattern\" matrix. A "
1077 "pattern matrix is really just a graph with no weights. It "
1078 "should be stored in a CrsGraph, not a CrsMatrix.");
1080 TEUCHOS_TEST_FOR_EXCEPTION(
1082 pBanner->dataType() !=
"pattern",
1083 std::invalid_argument,
1084 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
1085 "Matrix Market file must contain a \"pattern\" matrix.");
1112 static Teuchos::Tuple<global_ordinal_type, 3>
1113 readCoordDims (std::istream& in,
1115 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1116 const Teuchos::RCP<const comm_type>& pComm,
1117 const bool tolerant =
false,
1120 using Teuchos::MatrixMarket::readCoordinateDimensions;
1121 using Teuchos::Tuple;
1126 Tuple<global_ordinal_type, 3> dims;
1132 bool success =
false;
1133 if (pComm->getRank() == 0) {
1134 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
1135 std::invalid_argument,
"The Tpetra::CrsMatrix Matrix Market reader "
1136 "only accepts \"coordinate\" (sparse) matrix data.");
1140 success = readCoordinateDimensions (in, numRows, numCols,
1141 numNonzeros, lineNumber,
1147 dims[2] = numNonzeros;
1155 int the_success = success ? 1 : 0;
1156 Teuchos::broadcast (*pComm, 0, &the_success);
1157 success = (the_success == 1);
1162 Teuchos::broadcast (*pComm, 0, dims);
1170 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1171 "Error reading Matrix Market sparse matrix: failed to read "
1172 "coordinate matrix dimensions.");
1187 typedef Teuchos::MatrixMarket::SymmetrizingAdder<Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type> > adder_type;
1189 typedef Teuchos::MatrixMarket::SymmetrizingGraphAdder<Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> > graph_adder_type;
1216 static Teuchos::RCP<adder_type>
1217 makeAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1218 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1219 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1220 const bool tolerant=
false,
1221 const bool debug=
false)
1223 if (pComm->getRank () == 0) {
1224 typedef Teuchos::MatrixMarket::Raw::Adder<
scalar_type,
1227 Teuchos::RCP<raw_adder_type> pRaw =
1228 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1230 return Teuchos::rcp (
new adder_type (pRaw, pBanner->symmType ()));
1233 return Teuchos::null;
1262 static Teuchos::RCP<graph_adder_type>
1263 makeGraphAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1264 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1265 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1266 const bool tolerant=
false,
1267 const bool debug=
false)
1269 if (pComm->getRank () == 0) {
1270 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
1271 Teuchos::RCP<raw_adder_type> pRaw =
1272 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1274 return Teuchos::rcp (
new graph_adder_type (pRaw, pBanner->symmType ()));
1277 return Teuchos::null;
1282 static Teuchos::RCP<sparse_graph_type>
1283 readSparseGraphHelper (std::istream& in,
1284 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1285 const Teuchos::RCP<const map_type>& rowMap,
1286 Teuchos::RCP<const map_type>& colMap,
1287 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1288 const bool tolerant,
1291 using Teuchos::MatrixMarket::Banner;
1294 using Teuchos::Tuple;
1298 const int myRank = pComm->getRank ();
1299 const int rootRank = 0;
1304 size_t lineNumber = 1;
1306 if (debug && myRank == rootRank) {
1307 cerr <<
"Matrix Market reader: readGraph:" << endl
1308 <<
"-- Reading banner line" << endl;
1317 RCP<const Banner> pBanner;
1323 int bannerIsCorrect = 1;
1324 std::ostringstream errMsg;
1326 if (myRank == rootRank) {
1329 pBanner = readBanner (in, lineNumber, tolerant, debug,
true);
1331 catch (std::exception& e) {
1332 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1333 "threw an exception: " << e.what();
1334 bannerIsCorrect = 0;
1337 if (bannerIsCorrect) {
1342 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
1343 bannerIsCorrect = 0;
1344 errMsg <<
"The Matrix Market input file must contain a "
1345 "\"coordinate\"-format sparse graph in order to create a "
1346 "Tpetra::CrsGraph object from it, but the file's matrix "
1347 "type is \"" << pBanner->matrixType() <<
"\" instead.";
1352 if (tolerant && pBanner->matrixType() ==
"array") {
1353 bannerIsCorrect = 0;
1354 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1355 "format sparse graph in order to create a Tpetra::CrsGraph "
1356 "object from it, but the file's matrix type is \"array\" "
1357 "instead. That probably means the file contains dense matrix "
1364 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
1371 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
1372 std::invalid_argument, errMsg.str ());
1374 if (debug && myRank == rootRank) {
1375 cerr <<
"-- Reading dimensions line" << endl;
1383 Tuple<global_ordinal_type, 3> dims =
1384 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
1386 if (debug && myRank == rootRank) {
1387 cerr <<
"-- Making Adder for collecting graph data" << endl;
1394 RCP<graph_adder_type> pAdder =
1395 makeGraphAdder (pComm, pBanner, dims, tolerant, debug);
1397 if (debug && myRank == rootRank) {
1398 cerr <<
"-- Reading graph data" << endl;
1408 int readSuccess = 1;
1409 std::ostringstream errMsg;
1410 if (myRank == rootRank) {
1413 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
1415 reader_type reader (pAdder);
1418 std::pair<bool, std::vector<size_t> > results =
1419 reader.read (in, lineNumber, tolerant, debug);
1420 readSuccess = results.first ? 1 : 0;
1422 catch (std::exception& e) {
1427 broadcast (*pComm, rootRank, ptr (&readSuccess));
1436 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1437 "Failed to read the Matrix Market sparse graph file: "
1441 if (debug && myRank == rootRank) {
1442 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1455 if (debug && myRank == rootRank) {
1456 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1458 <<
"----- Dimensions before: "
1459 << dims[0] <<
" x " << dims[1]
1463 Tuple<global_ordinal_type, 2> updatedDims;
1464 if (myRank == rootRank) {
1471 std::max (dims[0], pAdder->getAdder()->numRows());
1472 updatedDims[1] = pAdder->getAdder()->numCols();
1474 broadcast (*pComm, rootRank, updatedDims);
1475 dims[0] = updatedDims[0];
1476 dims[1] = updatedDims[1];
1477 if (debug && myRank == rootRank) {
1478 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1492 if (myRank == rootRank) {
1499 if (dims[0] < pAdder->getAdder ()->numRows ()) {
1503 broadcast (*pComm, 0, ptr (&dimsMatch));
1504 if (dimsMatch == 0) {
1511 Tuple<global_ordinal_type, 2> addersDims;
1512 if (myRank == rootRank) {
1513 addersDims[0] = pAdder->getAdder()->numRows();
1514 addersDims[1] = pAdder->getAdder()->numCols();
1516 broadcast (*pComm, 0, addersDims);
1517 TEUCHOS_TEST_FOR_EXCEPTION(
1518 dimsMatch == 0, std::runtime_error,
1519 "The graph metadata says that the graph is " << dims[0] <<
" x "
1520 << dims[1] <<
", but the actual data says that the graph is "
1521 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1522 "data includes more rows than reported in the metadata. This "
1523 "is not allowed when parsing in strict mode. Parse the graph in "
1524 "tolerant mode to ignore the metadata when it disagrees with the "
1530 RCP<map_type> proc0Map;
1532 if(Teuchos::is_null(rowMap)) {
1536 indexBase = rowMap->getIndexBase();
1538 if(myRank == rootRank) {
1539 proc0Map = rcp(
new map_type(dims[0],dims[0],indexBase,pComm));
1542 proc0Map = rcp(
new map_type(dims[0],0,indexBase,pComm));
1546 std::map<global_ordinal_type, size_t> numEntriesPerRow_map;
1547 if (myRank == rootRank) {
1548 const auto& entries = pAdder()->getAdder()->getEntries();
1553 for (
const auto& entry : entries) {
1555 ++numEntriesPerRow_map[gblRow];
1559 Teuchos::Array<size_t> numEntriesPerRow (proc0Map->getLocalNumElements ());
1560 for (
const auto& ent : numEntriesPerRow_map) {
1562 numEntriesPerRow[lclRow] = ent.second;
1569 std::map<global_ordinal_type, size_t> empty_map;
1570 std::swap (numEntriesPerRow_map, empty_map);
1573 RCP<sparse_graph_type> proc0Graph =
1575 constructorParams));
1576 if(myRank == rootRank) {
1577 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1580 const std::vector<element_type>& entries =
1581 pAdder->getAdder()->getEntries();
1584 for(
size_t curPos=0; curPos<entries.size(); curPos++) {
1585 const element_type& curEntry = entries[curPos];
1588 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol,1);
1589 proc0Graph->insertGlobalIndices(curRow,colView);
1592 proc0Graph->fillComplete();
1594 RCP<sparse_graph_type> distGraph;
1595 if(Teuchos::is_null(rowMap))
1598 RCP<map_type> distMap =
1599 rcp(
new map_type(dims[0],0,pComm,GloballyDistributed));
1605 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1606 import_type importer (proc0Map, distMap);
1609 distGraph->doImport(*proc0Graph,importer,
INSERT);
1615 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1616 import_type importer (proc0Map, rowMap);
1619 distGraph->doImport(*proc0Graph,importer,
INSERT);
1649 static Teuchos::RCP<sparse_graph_type>
1651 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1652 const bool callFillComplete=
true,
1653 const bool tolerant=
false,
1654 const bool debug=
false)
1656 using Teuchos::broadcast;
1657 using Teuchos::outArg;
1665 if (comm->getRank () == 0) {
1667 in.open (filename.c_str ());
1668 opened = in.is_open();
1674 broadcast<int, int> (*comm, 0, outArg (opened));
1675 TEUCHOS_TEST_FOR_EXCEPTION
1676 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1677 "Failed to open file \"" << filename <<
"\" on Process 0.");
1715 static Teuchos::RCP<sparse_graph_type>
1717 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1718 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1719 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1720 const bool tolerant=
false,
1721 const bool debug=
false)
1723 using Teuchos::broadcast;
1724 using Teuchos::outArg;
1732 if (pComm->getRank () == 0) {
1734 in.open (filename.c_str ());
1735 opened = in.is_open();
1741 broadcast<int, int> (*pComm, 0, outArg (opened));
1742 TEUCHOS_TEST_FOR_EXCEPTION
1743 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1744 "Failed to open file \"" << filename <<
"\" on Process 0.");
1745 if (pComm->getRank () == 0) {
1746 in.open (filename.c_str ());
1750 fillCompleteParams, tolerant, debug);
1794 static Teuchos::RCP<sparse_graph_type>
1796 const Teuchos::RCP<const map_type>& rowMap,
1797 Teuchos::RCP<const map_type>& colMap,
1798 const Teuchos::RCP<const map_type>& domainMap,
1799 const Teuchos::RCP<const map_type>& rangeMap,
1800 const bool callFillComplete=
true,
1801 const bool tolerant=
false,
1802 const bool debug=
false)
1804 using Teuchos::broadcast;
1805 using Teuchos::Comm;
1806 using Teuchos::outArg;
1809 TEUCHOS_TEST_FOR_EXCEPTION
1810 (rowMap.is_null (), std::invalid_argument,
1811 "Input rowMap must be nonnull.");
1812 RCP<const Comm<int> > comm = rowMap->getComm ();
1813 if (comm.is_null ()) {
1816 return Teuchos::null;
1825 if (comm->getRank () == 0) {
1827 in.open (filename.c_str ());
1828 opened = in.is_open();
1834 broadcast<int, int> (*comm, 0, outArg (opened));
1835 TEUCHOS_TEST_FOR_EXCEPTION
1836 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1837 "Failed to open file \"" << filename <<
"\" on Process 0.");
1839 callFillComplete, tolerant, debug);
1867 static Teuchos::RCP<sparse_graph_type>
1869 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1870 const bool callFillComplete=
true,
1871 const bool tolerant=
false,
1872 const bool debug=
false)
1874 Teuchos::RCP<const map_type> fakeRowMap;
1875 Teuchos::RCP<const map_type> fakeColMap;
1876 Teuchos::RCP<Teuchos::ParameterList> fakeCtorParams;
1878 Teuchos::RCP<sparse_graph_type> graph =
1879 readSparseGraphHelper (in, pComm,
1880 fakeRowMap, fakeColMap,
1881 fakeCtorParams, tolerant, debug);
1882 if (callFillComplete) {
1883 graph->fillComplete ();
1918 static Teuchos::RCP<sparse_graph_type>
1920 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1921 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1922 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1923 const bool tolerant=
false,
1924 const bool debug=
false)
1926 Teuchos::RCP<const map_type> fakeRowMap;
1927 Teuchos::RCP<const map_type> fakeColMap;
1928 Teuchos::RCP<sparse_graph_type> graph =
1929 readSparseGraphHelper (in, pComm,
1930 fakeRowMap, fakeColMap,
1931 constructorParams, tolerant, debug);
1932 graph->fillComplete (fillCompleteParams);
1977 static Teuchos::RCP<sparse_graph_type>
1979 const Teuchos::RCP<const map_type>& rowMap,
1980 Teuchos::RCP<const map_type>& colMap,
1981 const Teuchos::RCP<const map_type>& domainMap,
1982 const Teuchos::RCP<const map_type>& rangeMap,
1983 const bool callFillComplete=
true,
1984 const bool tolerant=
false,
1985 const bool debug=
false)
1987 Teuchos::RCP<sparse_graph_type> graph =
1988 readSparseGraphHelper (in, rowMap->getComm (),
1989 rowMap, colMap, Teuchos::null, tolerant,
1991 if (callFillComplete) {
1992 graph->fillComplete (domainMap, rangeMap);
1997 #include "MatrixMarket_TpetraNew.hpp"
2022 static Teuchos::RCP<sparse_matrix_type>
2024 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2025 const bool callFillComplete=
true,
2026 const bool tolerant=
false,
2027 const bool debug=
false)
2029 const int myRank = pComm->getRank ();
2034 in.open (filename.c_str ());
2042 return readSparse (in, pComm, callFillComplete, tolerant, debug);
2077 static Teuchos::RCP<sparse_matrix_type>
2079 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2080 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2081 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2082 const bool tolerant=
false,
2083 const bool debug=
false)
2086 if (pComm->getRank () == 0) {
2087 in.open (filename.c_str ());
2089 return readSparse (in, pComm, constructorParams,
2090 fillCompleteParams, tolerant, debug);
2131 static Teuchos::RCP<sparse_matrix_type>
2133 const Teuchos::RCP<const map_type>& rowMap,
2134 Teuchos::RCP<const map_type>& colMap,
2135 const Teuchos::RCP<const map_type>& domainMap,
2136 const Teuchos::RCP<const map_type>& rangeMap,
2137 const bool callFillComplete=
true,
2138 const bool tolerant=
false,
2139 const bool debug=
false)
2141 using Teuchos::broadcast;
2142 using Teuchos::Comm;
2143 using Teuchos::outArg;
2146 TEUCHOS_TEST_FOR_EXCEPTION(
2147 rowMap.is_null (), std::invalid_argument,
2148 "Row Map must be nonnull.");
2150 RCP<const Comm<int> > comm = rowMap->getComm ();
2151 const int myRank = comm->getRank ();
2161 in.open (filename.c_str ());
2162 opened = in.is_open();
2168 broadcast<int, int> (*comm, 0, outArg (opened));
2169 TEUCHOS_TEST_FOR_EXCEPTION(
2170 opened == 0, std::runtime_error,
2171 "readSparseFile: Failed to open file \"" << filename <<
"\" on "
2173 return readSparse (in, rowMap, colMap, domainMap, rangeMap,
2174 callFillComplete, tolerant, debug);
2202 static Teuchos::RCP<sparse_matrix_type>
2204 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2205 const bool callFillComplete=
true,
2206 const bool tolerant=
false,
2207 const bool debug=
false)
2209 using Teuchos::MatrixMarket::Banner;
2210 using Teuchos::arcp;
2211 using Teuchos::ArrayRCP;
2212 using Teuchos::broadcast;
2213 using Teuchos::null;
2216 using Teuchos::REDUCE_MAX;
2217 using Teuchos::reduceAll;
2218 using Teuchos::Tuple;
2221 typedef Teuchos::ScalarTraits<scalar_type> STS;
2223 const bool extraDebug =
false;
2224 const int myRank = pComm->getRank ();
2225 const int rootRank = 0;
2230 size_t lineNumber = 1;
2232 if (debug && myRank == rootRank) {
2233 cerr <<
"Matrix Market reader: readSparse:" << endl
2234 <<
"-- Reading banner line" << endl;
2243 RCP<const Banner> pBanner;
2249 int bannerIsCorrect = 1;
2250 std::ostringstream errMsg;
2252 if (myRank == rootRank) {
2255 pBanner = readBanner (in, lineNumber, tolerant, debug);
2257 catch (std::exception& e) {
2258 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2259 "threw an exception: " << e.what();
2260 bannerIsCorrect = 0;
2263 if (bannerIsCorrect) {
2268 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2269 bannerIsCorrect = 0;
2270 errMsg <<
"The Matrix Market input file must contain a "
2271 "\"coordinate\"-format sparse matrix in order to create a "
2272 "Tpetra::CrsMatrix object from it, but the file's matrix "
2273 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2278 if (tolerant && pBanner->matrixType() ==
"array") {
2279 bannerIsCorrect = 0;
2280 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2281 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2282 "object from it, but the file's matrix type is \"array\" "
2283 "instead. That probably means the file contains dense matrix "
2290 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2297 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2298 std::invalid_argument, errMsg.str ());
2300 if (debug && myRank == rootRank) {
2301 cerr <<
"-- Reading dimensions line" << endl;
2309 Tuple<global_ordinal_type, 3> dims =
2310 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2312 if (debug && myRank == rootRank) {
2313 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2318 RCP<adder_type> pAdder =
2319 makeAdder (pComm, pBanner, dims, tolerant, debug);
2321 if (debug && myRank == rootRank) {
2322 cerr <<
"-- Reading matrix data" << endl;
2332 int readSuccess = 1;
2333 std::ostringstream errMsg;
2334 if (myRank == rootRank) {
2337 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2339 reader_type reader (pAdder);
2342 std::pair<bool, std::vector<size_t> > results =
2343 reader.read (in, lineNumber, tolerant, debug);
2344 readSuccess = results.first ? 1 : 0;
2346 catch (std::exception& e) {
2351 broadcast (*pComm, rootRank, ptr (&readSuccess));
2360 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2361 "Failed to read the Matrix Market sparse matrix file: "
2365 if (debug && myRank == rootRank) {
2366 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2379 if (debug && myRank == rootRank) {
2380 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2382 <<
"----- Dimensions before: "
2383 << dims[0] <<
" x " << dims[1]
2387 Tuple<global_ordinal_type, 2> updatedDims;
2388 if (myRank == rootRank) {
2395 std::max (dims[0], pAdder->getAdder()->numRows());
2396 updatedDims[1] = pAdder->getAdder()->numCols();
2398 broadcast (*pComm, rootRank, updatedDims);
2399 dims[0] = updatedDims[0];
2400 dims[1] = updatedDims[1];
2401 if (debug && myRank == rootRank) {
2402 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2416 if (myRank == rootRank) {
2423 if (dims[0] < pAdder->getAdder ()->numRows ()) {
2427 broadcast (*pComm, 0, ptr (&dimsMatch));
2428 if (dimsMatch == 0) {
2435 Tuple<global_ordinal_type, 2> addersDims;
2436 if (myRank == rootRank) {
2437 addersDims[0] = pAdder->getAdder()->numRows();
2438 addersDims[1] = pAdder->getAdder()->numCols();
2440 broadcast (*pComm, 0, addersDims);
2441 TEUCHOS_TEST_FOR_EXCEPTION(
2442 dimsMatch == 0, std::runtime_error,
2443 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2444 << dims[1] <<
", but the actual data says that the matrix is "
2445 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2446 "data includes more rows than reported in the metadata. This "
2447 "is not allowed when parsing in strict mode. Parse the matrix in "
2448 "tolerant mode to ignore the metadata when it disagrees with the "
2453 if (debug && myRank == rootRank) {
2454 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2466 ArrayRCP<size_t> numEntriesPerRow;
2467 ArrayRCP<size_t> rowPtr;
2468 ArrayRCP<global_ordinal_type> colInd;
2469 ArrayRCP<scalar_type> values;
2474 int mergeAndConvertSucceeded = 1;
2475 std::ostringstream errMsg;
2477 if (myRank == rootRank) {
2479 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2489 const size_type numRows = dims[0];
2492 pAdder->getAdder()->merge ();
2495 const std::vector<element_type>& entries =
2496 pAdder->getAdder()->getEntries();
2499 const size_t numEntries = (size_t)entries.size();
2502 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2503 <<
" rows and numEntries=" << numEntries
2504 <<
" entries." << endl;
2510 numEntriesPerRow = arcp<size_t> (numRows);
2511 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2512 rowPtr = arcp<size_t> (numRows+1);
2513 std::fill (rowPtr.begin(), rowPtr.end(), 0);
2514 colInd = arcp<global_ordinal_type> (numEntries);
2515 values = arcp<scalar_type> (numEntries);
2522 for (curPos = 0; curPos < numEntries; ++curPos) {
2523 const element_type& curEntry = entries[curPos];
2525 TEUCHOS_TEST_FOR_EXCEPTION(
2526 curRow < prvRow, std::logic_error,
2527 "Row indices are out of order, even though they are supposed "
2528 "to be sorted. curRow = " << curRow <<
", prvRow = "
2529 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2530 "this bug to the Tpetra developers.");
2531 if (curRow > prvRow) {
2537 numEntriesPerRow[curRow]++;
2538 colInd[curPos] = curEntry.colIndex();
2539 values[curPos] = curEntry.value();
2544 rowPtr[numRows] = numEntries;
2546 catch (std::exception& e) {
2547 mergeAndConvertSucceeded = 0;
2548 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2549 "CSR format: " << e.what();
2552 if (debug && mergeAndConvertSucceeded) {
2554 const size_type numRows = dims[0];
2555 const size_type maxToDisplay = 100;
2557 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2558 << (numEntriesPerRow.size()-1) <<
"] ";
2559 if (numRows > maxToDisplay) {
2560 cerr <<
"(only showing first and last few entries) ";
2564 if (numRows > maxToDisplay) {
2565 for (size_type k = 0; k < 2; ++k) {
2566 cerr << numEntriesPerRow[k] <<
" ";
2569 for (size_type k = numRows-2; k < numRows-1; ++k) {
2570 cerr << numEntriesPerRow[k] <<
" ";
2574 for (size_type k = 0; k < numRows-1; ++k) {
2575 cerr << numEntriesPerRow[k] <<
" ";
2578 cerr << numEntriesPerRow[numRows-1];
2580 cerr <<
"]" << endl;
2582 cerr <<
"----- Proc 0: rowPtr ";
2583 if (numRows > maxToDisplay) {
2584 cerr <<
"(only showing first and last few entries) ";
2587 if (numRows > maxToDisplay) {
2588 for (size_type k = 0; k < 2; ++k) {
2589 cerr << rowPtr[k] <<
" ";
2592 for (size_type k = numRows-2; k < numRows; ++k) {
2593 cerr << rowPtr[k] <<
" ";
2597 for (size_type k = 0; k < numRows; ++k) {
2598 cerr << rowPtr[k] <<
" ";
2601 cerr << rowPtr[numRows] <<
"]" << endl;
2612 if (debug && myRank == rootRank) {
2613 cerr <<
"-- Making range, domain, and row maps" << endl;
2620 RCP<const map_type> pRangeMap = makeRangeMap (pComm, dims[0]);
2621 RCP<const map_type> pDomainMap =
2622 makeDomainMap (pRangeMap, dims[0], dims[1]);
2623 RCP<const map_type> pRowMap = makeRowMap (null, pComm, dims[0]);
2625 if (debug && myRank == rootRank) {
2626 cerr <<
"-- Distributing the matrix data" << endl;
2640 ArrayRCP<size_t> myNumEntriesPerRow;
2641 ArrayRCP<size_t> myRowPtr;
2642 ArrayRCP<global_ordinal_type> myColInd;
2643 ArrayRCP<scalar_type> myValues;
2645 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
2646 numEntriesPerRow, rowPtr, colInd, values, debug);
2648 if (debug && myRank == rootRank) {
2649 cerr <<
"-- Inserting matrix entries on each processor";
2650 if (callFillComplete) {
2651 cerr <<
" and calling fillComplete()";
2662 RCP<sparse_matrix_type> pMatrix =
2663 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
2664 pRowMap, pRangeMap, pDomainMap, callFillComplete);
2669 int localIsNull = pMatrix.is_null () ? 1 : 0;
2670 int globalIsNull = 0;
2671 reduceAll (*pComm, REDUCE_MAX, localIsNull, ptr (&globalIsNull));
2672 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
2673 "Reader::makeMatrix() returned a null pointer on at least one "
2674 "process. Please report this bug to the Tpetra developers.");
2677 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
2678 "Reader::makeMatrix() returned a null pointer. "
2679 "Please report this bug to the Tpetra developers.");
2691 if (callFillComplete) {
2692 const int numProcs = pComm->getSize ();
2694 if (extraDebug && debug) {
2696 pRangeMap->getGlobalNumElements ();
2698 pDomainMap->getGlobalNumElements ();
2699 if (myRank == rootRank) {
2700 cerr <<
"-- Matrix is "
2701 << globalNumRows <<
" x " << globalNumCols
2702 <<
" with " << pMatrix->getGlobalNumEntries()
2703 <<
" entries, and index base "
2704 << pMatrix->getIndexBase() <<
"." << endl;
2707 for (
int p = 0; p < numProcs; ++p) {
2709 cerr <<
"-- Proc " << p <<
" owns "
2710 << pMatrix->getLocalNumCols() <<
" columns, and "
2711 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
2718 if (debug && myRank == rootRank) {
2719 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2754 static Teuchos::RCP<sparse_matrix_type>
2756 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2757 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2758 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2759 const bool tolerant=
false,
2760 const bool debug=
false)
2762 using Teuchos::MatrixMarket::Banner;
2763 using Teuchos::arcp;
2764 using Teuchos::ArrayRCP;
2765 using Teuchos::broadcast;
2766 using Teuchos::null;
2769 using Teuchos::reduceAll;
2770 using Teuchos::Tuple;
2773 typedef Teuchos::ScalarTraits<scalar_type> STS;
2775 const bool extraDebug =
false;
2776 const int myRank = pComm->getRank ();
2777 const int rootRank = 0;
2782 size_t lineNumber = 1;
2784 if (debug && myRank == rootRank) {
2785 cerr <<
"Matrix Market reader: readSparse:" << endl
2786 <<
"-- Reading banner line" << endl;
2795 RCP<const Banner> pBanner;
2801 int bannerIsCorrect = 1;
2802 std::ostringstream errMsg;
2804 if (myRank == rootRank) {
2807 pBanner = readBanner (in, lineNumber, tolerant, debug);
2809 catch (std::exception& e) {
2810 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2811 "threw an exception: " << e.what();
2812 bannerIsCorrect = 0;
2815 if (bannerIsCorrect) {
2820 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2821 bannerIsCorrect = 0;
2822 errMsg <<
"The Matrix Market input file must contain a "
2823 "\"coordinate\"-format sparse matrix in order to create a "
2824 "Tpetra::CrsMatrix object from it, but the file's matrix "
2825 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2830 if (tolerant && pBanner->matrixType() ==
"array") {
2831 bannerIsCorrect = 0;
2832 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2833 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2834 "object from it, but the file's matrix type is \"array\" "
2835 "instead. That probably means the file contains dense matrix "
2842 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2849 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2850 std::invalid_argument, errMsg.str ());
2852 if (debug && myRank == rootRank) {
2853 cerr <<
"-- Reading dimensions line" << endl;
2861 Tuple<global_ordinal_type, 3> dims =
2862 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2864 if (debug && myRank == rootRank) {
2865 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2870 RCP<adder_type> pAdder =
2871 makeAdder (pComm, pBanner, dims, tolerant, debug);
2873 if (debug && myRank == rootRank) {
2874 cerr <<
"-- Reading matrix data" << endl;
2884 int readSuccess = 1;
2885 std::ostringstream errMsg;
2886 if (myRank == rootRank) {
2889 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2891 reader_type reader (pAdder);
2894 std::pair<bool, std::vector<size_t> > results =
2895 reader.read (in, lineNumber, tolerant, debug);
2896 readSuccess = results.first ? 1 : 0;
2898 catch (std::exception& e) {
2903 broadcast (*pComm, rootRank, ptr (&readSuccess));
2912 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2913 "Failed to read the Matrix Market sparse matrix file: "
2917 if (debug && myRank == rootRank) {
2918 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2931 if (debug && myRank == rootRank) {
2932 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2934 <<
"----- Dimensions before: "
2935 << dims[0] <<
" x " << dims[1]
2939 Tuple<global_ordinal_type, 2> updatedDims;
2940 if (myRank == rootRank) {
2947 std::max (dims[0], pAdder->getAdder()->numRows());
2948 updatedDims[1] = pAdder->getAdder()->numCols();
2950 broadcast (*pComm, rootRank, updatedDims);
2951 dims[0] = updatedDims[0];
2952 dims[1] = updatedDims[1];
2953 if (debug && myRank == rootRank) {
2954 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2968 if (myRank == rootRank) {
2975 if (dims[0] < pAdder->getAdder ()->numRows ()) {
2979 broadcast (*pComm, 0, ptr (&dimsMatch));
2980 if (dimsMatch == 0) {
2987 Tuple<global_ordinal_type, 2> addersDims;
2988 if (myRank == rootRank) {
2989 addersDims[0] = pAdder->getAdder()->numRows();
2990 addersDims[1] = pAdder->getAdder()->numCols();
2992 broadcast (*pComm, 0, addersDims);
2993 TEUCHOS_TEST_FOR_EXCEPTION(
2994 dimsMatch == 0, std::runtime_error,
2995 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2996 << dims[1] <<
", but the actual data says that the matrix is "
2997 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2998 "data includes more rows than reported in the metadata. This "
2999 "is not allowed when parsing in strict mode. Parse the matrix in "
3000 "tolerant mode to ignore the metadata when it disagrees with the "
3005 if (debug && myRank == rootRank) {
3006 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3018 ArrayRCP<size_t> numEntriesPerRow;
3019 ArrayRCP<size_t> rowPtr;
3020 ArrayRCP<global_ordinal_type> colInd;
3021 ArrayRCP<scalar_type> values;
3026 int mergeAndConvertSucceeded = 1;
3027 std::ostringstream errMsg;
3029 if (myRank == rootRank) {
3031 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3041 const size_type numRows = dims[0];
3044 pAdder->getAdder()->merge ();
3047 const std::vector<element_type>& entries =
3048 pAdder->getAdder()->getEntries();
3051 const size_t numEntries = (size_t)entries.size();
3054 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3055 <<
" rows and numEntries=" << numEntries
3056 <<
" entries." << endl;
3062 numEntriesPerRow = arcp<size_t> (numRows);
3063 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3064 rowPtr = arcp<size_t> (numRows+1);
3065 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3066 colInd = arcp<global_ordinal_type> (numEntries);
3067 values = arcp<scalar_type> (numEntries);
3074 for (curPos = 0; curPos < numEntries; ++curPos) {
3075 const element_type& curEntry = entries[curPos];
3077 TEUCHOS_TEST_FOR_EXCEPTION(
3078 curRow < prvRow, std::logic_error,
3079 "Row indices are out of order, even though they are supposed "
3080 "to be sorted. curRow = " << curRow <<
", prvRow = "
3081 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3082 "this bug to the Tpetra developers.");
3083 if (curRow > prvRow) {
3089 numEntriesPerRow[curRow]++;
3090 colInd[curPos] = curEntry.colIndex();
3091 values[curPos] = curEntry.value();
3096 rowPtr[numRows] = numEntries;
3098 catch (std::exception& e) {
3099 mergeAndConvertSucceeded = 0;
3100 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3101 "CSR format: " << e.what();
3104 if (debug && mergeAndConvertSucceeded) {
3106 const size_type numRows = dims[0];
3107 const size_type maxToDisplay = 100;
3109 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3110 << (numEntriesPerRow.size()-1) <<
"] ";
3111 if (numRows > maxToDisplay) {
3112 cerr <<
"(only showing first and last few entries) ";
3116 if (numRows > maxToDisplay) {
3117 for (size_type k = 0; k < 2; ++k) {
3118 cerr << numEntriesPerRow[k] <<
" ";
3121 for (size_type k = numRows-2; k < numRows-1; ++k) {
3122 cerr << numEntriesPerRow[k] <<
" ";
3126 for (size_type k = 0; k < numRows-1; ++k) {
3127 cerr << numEntriesPerRow[k] <<
" ";
3130 cerr << numEntriesPerRow[numRows-1];
3132 cerr <<
"]" << endl;
3134 cerr <<
"----- Proc 0: rowPtr ";
3135 if (numRows > maxToDisplay) {
3136 cerr <<
"(only showing first and last few entries) ";
3139 if (numRows > maxToDisplay) {
3140 for (size_type k = 0; k < 2; ++k) {
3141 cerr << rowPtr[k] <<
" ";
3144 for (size_type k = numRows-2; k < numRows; ++k) {
3145 cerr << rowPtr[k] <<
" ";
3149 for (size_type k = 0; k < numRows; ++k) {
3150 cerr << rowPtr[k] <<
" ";
3153 cerr << rowPtr[numRows] <<
"]" << endl;
3164 if (debug && myRank == rootRank) {
3165 cerr <<
"-- Making range, domain, and row maps" << endl;
3172 RCP<const map_type> pRangeMap = makeRangeMap (pComm, dims[0]);
3173 RCP<const map_type> pDomainMap =
3174 makeDomainMap (pRangeMap, dims[0], dims[1]);
3175 RCP<const map_type> pRowMap = makeRowMap (null, pComm, dims[0]);
3177 if (debug && myRank == rootRank) {
3178 cerr <<
"-- Distributing the matrix data" << endl;
3192 ArrayRCP<size_t> myNumEntriesPerRow;
3193 ArrayRCP<size_t> myRowPtr;
3194 ArrayRCP<global_ordinal_type> myColInd;
3195 ArrayRCP<scalar_type> myValues;
3197 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
3198 numEntriesPerRow, rowPtr, colInd, values, debug);
3200 if (debug && myRank == rootRank) {
3201 cerr <<
"-- Inserting matrix entries on each process "
3202 "and calling fillComplete()" << endl;
3211 Teuchos::RCP<sparse_matrix_type> pMatrix =
3212 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
3213 pRowMap, pRangeMap, pDomainMap, constructorParams,
3214 fillCompleteParams);
3219 int localIsNull = pMatrix.is_null () ? 1 : 0;
3220 int globalIsNull = 0;
3221 reduceAll (*pComm, Teuchos::REDUCE_MAX, localIsNull, ptr (&globalIsNull));
3222 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
3223 "Reader::makeMatrix() returned a null pointer on at least one "
3224 "process. Please report this bug to the Tpetra developers.");
3227 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
3228 "Reader::makeMatrix() returned a null pointer. "
3229 "Please report this bug to the Tpetra developers.");
3238 if (extraDebug && debug) {
3239 const int numProcs = pComm->getSize ();
3241 pRangeMap->getGlobalNumElements();
3243 pDomainMap->getGlobalNumElements();
3244 if (myRank == rootRank) {
3245 cerr <<
"-- Matrix is "
3246 << globalNumRows <<
" x " << globalNumCols
3247 <<
" with " << pMatrix->getGlobalNumEntries()
3248 <<
" entries, and index base "
3249 << pMatrix->getIndexBase() <<
"." << endl;
3252 for (
int p = 0; p < numProcs; ++p) {
3254 cerr <<
"-- Proc " << p <<
" owns "
3255 << pMatrix->getLocalNumCols() <<
" columns, and "
3256 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
3262 if (debug && myRank == rootRank) {
3263 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3310 static Teuchos::RCP<sparse_matrix_type>
3312 const Teuchos::RCP<const map_type>& rowMap,
3313 Teuchos::RCP<const map_type>& colMap,
3314 const Teuchos::RCP<const map_type>& domainMap,
3315 const Teuchos::RCP<const map_type>& rangeMap,
3316 const bool callFillComplete=
true,
3317 const bool tolerant=
false,
3318 const bool debug=
false)
3320 using Teuchos::MatrixMarket::Banner;
3321 using Teuchos::arcp;
3322 using Teuchos::ArrayRCP;
3323 using Teuchos::ArrayView;
3325 using Teuchos::broadcast;
3326 using Teuchos::Comm;
3327 using Teuchos::null;
3330 using Teuchos::reduceAll;
3331 using Teuchos::Tuple;
3334 typedef Teuchos::ScalarTraits<scalar_type> STS;
3336 RCP<const Comm<int> > pComm = rowMap->getComm ();
3337 const int myRank = pComm->getRank ();
3338 const int rootRank = 0;
3339 const bool extraDebug =
false;
3344 TEUCHOS_TEST_FOR_EXCEPTION(
3345 rowMap.is_null (), std::invalid_argument,
3346 "Row Map must be nonnull.");
3347 TEUCHOS_TEST_FOR_EXCEPTION(
3348 rangeMap.is_null (), std::invalid_argument,
3349 "Range Map must be nonnull.");
3350 TEUCHOS_TEST_FOR_EXCEPTION(
3351 domainMap.is_null (), std::invalid_argument,
3352 "Domain Map must be nonnull.");
3353 TEUCHOS_TEST_FOR_EXCEPTION(
3354 rowMap->getComm().getRawPtr() != pComm.getRawPtr(),
3355 std::invalid_argument,
3356 "The specified row Map's communicator (rowMap->getComm())"
3357 "differs from the given separately supplied communicator pComm.");
3358 TEUCHOS_TEST_FOR_EXCEPTION(
3359 domainMap->getComm().getRawPtr() != pComm.getRawPtr(),
3360 std::invalid_argument,
3361 "The specified domain Map's communicator (domainMap->getComm())"
3362 "differs from the given separately supplied communicator pComm.");
3363 TEUCHOS_TEST_FOR_EXCEPTION(
3364 rangeMap->getComm().getRawPtr() != pComm.getRawPtr(),
3365 std::invalid_argument,
3366 "The specified range Map's communicator (rangeMap->getComm())"
3367 "differs from the given separately supplied communicator pComm.");
3372 size_t lineNumber = 1;
3374 if (debug && myRank == rootRank) {
3375 cerr <<
"Matrix Market reader: readSparse:" << endl
3376 <<
"-- Reading banner line" << endl;
3385 RCP<const Banner> pBanner;
3391 int bannerIsCorrect = 1;
3392 std::ostringstream errMsg;
3394 if (myRank == rootRank) {
3397 pBanner = readBanner (in, lineNumber, tolerant, debug);
3399 catch (std::exception& e) {
3400 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
3401 "threw an exception: " << e.what();
3402 bannerIsCorrect = 0;
3405 if (bannerIsCorrect) {
3410 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
3411 bannerIsCorrect = 0;
3412 errMsg <<
"The Matrix Market input file must contain a "
3413 "\"coordinate\"-format sparse matrix in order to create a "
3414 "Tpetra::CrsMatrix object from it, but the file's matrix "
3415 "type is \"" << pBanner->matrixType() <<
"\" instead.";
3420 if (tolerant && pBanner->matrixType() ==
"array") {
3421 bannerIsCorrect = 0;
3422 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
3423 "format sparse matrix in order to create a Tpetra::CrsMatrix "
3424 "object from it, but the file's matrix type is \"array\" "
3425 "instead. That probably means the file contains dense matrix "
3432 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
3439 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
3440 std::invalid_argument, errMsg.str ());
3442 if (debug && myRank == rootRank) {
3443 cerr <<
"-- Reading dimensions line" << endl;
3451 Tuple<global_ordinal_type, 3> dims =
3452 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
3454 if (debug && myRank == rootRank) {
3455 cerr <<
"-- Making Adder for collecting matrix data" << endl;
3462 RCP<adder_type> pAdder =
3463 makeAdder (pComm, pBanner, dims, tolerant, debug);
3465 if (debug && myRank == rootRank) {
3466 cerr <<
"-- Reading matrix data" << endl;
3476 int readSuccess = 1;
3477 std::ostringstream errMsg;
3478 if (myRank == rootRank) {
3481 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
3483 reader_type reader (pAdder);
3486 std::pair<bool, std::vector<size_t> > results =
3487 reader.read (in, lineNumber, tolerant, debug);
3488 readSuccess = results.first ? 1 : 0;
3490 catch (std::exception& e) {
3495 broadcast (*pComm, rootRank, ptr (&readSuccess));
3504 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
3505 "Failed to read the Matrix Market sparse matrix file: "
3509 if (debug && myRank == rootRank) {
3510 cerr <<
"-- Successfully read the Matrix Market data" << endl;
3523 if (debug && myRank == rootRank) {
3524 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
3526 <<
"----- Dimensions before: "
3527 << dims[0] <<
" x " << dims[1]
3531 Tuple<global_ordinal_type, 2> updatedDims;
3532 if (myRank == rootRank) {
3539 std::max (dims[0], pAdder->getAdder()->numRows());
3540 updatedDims[1] = pAdder->getAdder()->numCols();
3542 broadcast (*pComm, rootRank, updatedDims);
3543 dims[0] = updatedDims[0];
3544 dims[1] = updatedDims[1];
3545 if (debug && myRank == rootRank) {
3546 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
3560 if (myRank == rootRank) {
3567 if (dims[0] < pAdder->getAdder ()->numRows ()) {
3571 broadcast (*pComm, 0, ptr (&dimsMatch));
3572 if (dimsMatch == 0) {
3579 Tuple<global_ordinal_type, 2> addersDims;
3580 if (myRank == rootRank) {
3581 addersDims[0] = pAdder->getAdder()->numRows();
3582 addersDims[1] = pAdder->getAdder()->numCols();
3584 broadcast (*pComm, 0, addersDims);
3585 TEUCHOS_TEST_FOR_EXCEPTION(
3586 dimsMatch == 0, std::runtime_error,
3587 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
3588 << dims[1] <<
", but the actual data says that the matrix is "
3589 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
3590 "data includes more rows than reported in the metadata. This "
3591 "is not allowed when parsing in strict mode. Parse the matrix in "
3592 "tolerant mode to ignore the metadata when it disagrees with the "
3597 if (debug && myRank == rootRank) {
3598 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3610 ArrayRCP<size_t> numEntriesPerRow;
3611 ArrayRCP<size_t> rowPtr;
3612 ArrayRCP<global_ordinal_type> colInd;
3613 ArrayRCP<scalar_type> values;
3618 int mergeAndConvertSucceeded = 1;
3619 std::ostringstream errMsg;
3621 if (myRank == rootRank) {
3623 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3633 const size_type numRows = dims[0];
3636 pAdder->getAdder()->merge ();
3639 const std::vector<element_type>& entries =
3640 pAdder->getAdder()->getEntries();
3643 const size_t numEntries = (size_t)entries.size();
3646 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3647 <<
" rows and numEntries=" << numEntries
3648 <<
" entries." << endl;
3654 numEntriesPerRow = arcp<size_t> (numRows);
3655 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3656 rowPtr = arcp<size_t> (numRows+1);
3657 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3658 colInd = arcp<global_ordinal_type> (numEntries);
3659 values = arcp<scalar_type> (numEntries);
3666 for (curPos = 0; curPos < numEntries; ++curPos) {
3667 const element_type& curEntry = entries[curPos];
3669 TEUCHOS_TEST_FOR_EXCEPTION(
3670 curRow < prvRow, std::logic_error,
3671 "Row indices are out of order, even though they are supposed "
3672 "to be sorted. curRow = " << curRow <<
", prvRow = "
3673 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3674 "this bug to the Tpetra developers.");
3675 if (curRow > prvRow) {
3678 numEntriesPerRow[curRow]++;
3679 colInd[curPos] = curEntry.colIndex();
3680 values[curPos] = curEntry.value();
3685 rowPtr[row] = numEntriesPerRow[row-1] + rowPtr[row-1];
3688 catch (std::exception& e) {
3689 mergeAndConvertSucceeded = 0;
3690 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3691 "CSR format: " << e.what();
3694 if (debug && mergeAndConvertSucceeded) {
3696 const size_type numRows = dims[0];
3697 const size_type maxToDisplay = 100;
3699 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3700 << (numEntriesPerRow.size()-1) <<
"] ";
3701 if (numRows > maxToDisplay) {
3702 cerr <<
"(only showing first and last few entries) ";
3706 if (numRows > maxToDisplay) {
3707 for (size_type k = 0; k < 2; ++k) {
3708 cerr << numEntriesPerRow[k] <<
" ";
3711 for (size_type k = numRows-2; k < numRows-1; ++k) {
3712 cerr << numEntriesPerRow[k] <<
" ";
3716 for (size_type k = 0; k < numRows-1; ++k) {
3717 cerr << numEntriesPerRow[k] <<
" ";
3720 cerr << numEntriesPerRow[numRows-1];
3722 cerr <<
"]" << endl;
3724 cerr <<
"----- Proc 0: rowPtr ";
3725 if (numRows > maxToDisplay) {
3726 cerr <<
"(only showing first and last few entries) ";
3729 if (numRows > maxToDisplay) {
3730 for (size_type k = 0; k < 2; ++k) {
3731 cerr << rowPtr[k] <<
" ";
3734 for (size_type k = numRows-2; k < numRows; ++k) {
3735 cerr << rowPtr[k] <<
" ";
3739 for (size_type k = 0; k < numRows; ++k) {
3740 cerr << rowPtr[k] <<
" ";
3743 cerr << rowPtr[numRows] <<
"]" << endl;
3745 cerr <<
"----- Proc 0: colInd = [";
3746 for (
size_t k = 0; k < rowPtr[numRows]; ++k) {
3747 cerr << colInd[k] <<
" ";
3749 cerr <<
"]" << endl;
3763 if (debug && myRank == rootRank) {
3764 cerr <<
"-- Verifying Maps" << endl;
3766 TEUCHOS_TEST_FOR_EXCEPTION(
3767 as<global_size_t> (dims[0]) != rangeMap->getGlobalNumElements(),
3768 std::invalid_argument,
3769 "The range Map has " << rangeMap->getGlobalNumElements ()
3770 <<
" entries, but the matrix has a global number of rows " << dims[0]
3772 TEUCHOS_TEST_FOR_EXCEPTION(
3773 as<global_size_t> (dims[1]) != domainMap->getGlobalNumElements (),
3774 std::invalid_argument,
3775 "The domain Map has " << domainMap->getGlobalNumElements ()
3776 <<
" entries, but the matrix has a global number of columns "
3780 RCP<Teuchos::FancyOStream> err = debug ?
3781 Teuchos::getFancyOStream (Teuchos::rcpFromRef (cerr)) : null;
3783 RCP<const map_type> gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
3784 ArrayView<const global_ordinal_type> myRows =
3785 gatherRowMap->getLocalElementList ();
3786 const size_type myNumRows = myRows.size ();
3789 ArrayRCP<size_t> gatherNumEntriesPerRow = arcp<size_t>(myNumRows);
3790 for (size_type i_ = 0; i_ < myNumRows; i_++) {
3791 gatherNumEntriesPerRow[i_] = numEntriesPerRow[myRows[i_]-indexBase];
3797 RCP<sparse_matrix_type> A_proc0 =
3799 if (myRank == rootRank) {
3801 cerr <<
"-- Proc 0: Filling gather matrix" << endl;
3804 cerr <<
"---- Rows: " << Teuchos::toString (myRows) << endl;
3808 for (size_type i_ = 0; i_ < myNumRows; ++i_) {
3809 size_type i = myRows[i_] - indexBase;
3811 const size_type curPos = as<size_type> (rowPtr[i]);
3813 ArrayView<global_ordinal_type> curColInd =
3814 colInd.view (curPos, curNumEntries);
3815 ArrayView<scalar_type> curValues =
3816 values.view (curPos, curNumEntries);
3819 for (size_type k = 0; k < curNumEntries; ++k) {
3820 curColInd[k] += indexBase;
3823 cerr <<
"------ Columns: " << Teuchos::toString (curColInd) << endl;
3824 cerr <<
"------ Values: " << Teuchos::toString (curValues) << endl;
3827 if (curNumEntries > 0) {
3828 A_proc0->insertGlobalValues (myRows[i_], curColInd, curValues);
3834 numEntriesPerRow = null;
3840 RCP<sparse_matrix_type> A;
3842 export_type exp (gatherRowMap, rowMap);
3849 mv_type_go target_nnzPerRow(rowMap,1);
3850 mv_type_go source_nnzPerRow(gatherRowMap,1);
3851 Teuchos::ArrayRCP<GO> srcData = source_nnzPerRow.getDataNonConst(0);
3852 for (
int i=0; i<myNumRows; i++)
3853 srcData[i] = gatherNumEntriesPerRow[i];
3854 srcData = Teuchos::null;
3856 Teuchos::ArrayRCP<GO> targetData = target_nnzPerRow.getDataNonConst(0);
3857 ArrayRCP<size_t> targetData_size_t = arcp<size_t>(targetData.size());
3858 for (
int i=0; i<targetData.size(); i++)
3859 targetData_size_t[i] = targetData[i];
3861 if (colMap.is_null ()) {
3866 A->doExport (*A_proc0, exp,
INSERT);
3867 if (callFillComplete) {
3868 A->fillComplete (domainMap, rangeMap);
3880 if (callFillComplete) {
3881 const int numProcs = pComm->getSize ();
3883 if (extraDebug && debug) {
3884 const global_size_t globalNumRows = rangeMap->getGlobalNumElements ();
3885 const global_size_t globalNumCols = domainMap->getGlobalNumElements ();
3886 if (myRank == rootRank) {
3887 cerr <<
"-- Matrix is "
3888 << globalNumRows <<
" x " << globalNumCols
3889 <<
" with " << A->getGlobalNumEntries()
3890 <<
" entries, and index base "
3891 << A->getIndexBase() <<
"." << endl;
3894 for (
int p = 0; p < numProcs; ++p) {
3896 cerr <<
"-- Proc " << p <<
" owns "
3897 << A->getLocalNumCols() <<
" columns, and "
3898 << A->getLocalNumEntries() <<
" entries." << endl;
3905 if (debug && myRank == rootRank) {
3906 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3941 static Teuchos::RCP<multivector_type>
3943 const Teuchos::RCP<const comm_type>& comm,
3944 Teuchos::RCP<const map_type>& map,
3945 const bool tolerant=
false,
3946 const bool debug=
false,
3947 const bool binary=
false)
3949 using Teuchos::broadcast;
3950 using Teuchos::outArg;
3954 if (comm->getRank() == 0) {
3957 in.open (filename.c_str ());
3959 in.open (filename.c_str (), std::ios::binary);
3960 opened = in.is_open();
3966 broadcast<int, int> (*comm, 0, outArg (opened));
3967 TEUCHOS_TEST_FOR_EXCEPTION(
3968 opened == 0, std::runtime_error,
3969 "readDenseFile: Failed to open file \"" << filename <<
"\" on "
3971 return readDense (in, comm, map, tolerant, debug, binary);
4004 static Teuchos::RCP<vector_type>
4006 const Teuchos::RCP<const comm_type>& comm,
4007 Teuchos::RCP<const map_type>& map,
4008 const bool tolerant=
false,
4009 const bool debug=
false)
4011 using Teuchos::broadcast;
4012 using Teuchos::outArg;
4016 if (comm->getRank() == 0) {
4018 in.open (filename.c_str ());
4019 opened = in.is_open();
4025 broadcast<int, int> (*comm, 0, outArg (opened));
4026 TEUCHOS_TEST_FOR_EXCEPTION(
4027 opened == 0, std::runtime_error,
4028 "readVectorFile: Failed to open file \"" << filename <<
"\" on "
4030 return readVector (in, comm, map, tolerant, debug);
4102 static Teuchos::RCP<multivector_type>
4104 const Teuchos::RCP<const comm_type>& comm,
4105 Teuchos::RCP<const map_type>& map,
4106 const bool tolerant=
false,
4107 const bool debug=
false,
4108 const bool binary=
false)
4110 Teuchos::RCP<Teuchos::FancyOStream> err =
4111 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4112 return readDenseImpl<scalar_type> (in, comm, map, err, tolerant, debug, binary);
4117 static Teuchos::RCP<vector_type>
4119 const Teuchos::RCP<const comm_type>& comm,
4120 Teuchos::RCP<const map_type>& map,
4121 const bool tolerant=
false,
4122 const bool debug=
false)
4124 Teuchos::RCP<Teuchos::FancyOStream> err =
4125 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4126 return readVectorImpl<scalar_type> (in, comm, map, err, tolerant, debug);
4151 static Teuchos::RCP<const map_type>
4153 const Teuchos::RCP<const comm_type>& comm,
4154 const bool tolerant=
false,
4155 const bool debug=
false,
4156 const bool binary=
false)
4158 using Teuchos::inOutArg;
4159 using Teuchos::broadcast;
4163 if (comm->getRank () == 0) {
4165 in.open (filename.c_str (), std::ios::binary);
4167 in.open (filename.c_str ());
4172 broadcast<int, int> (*comm, 0, inOutArg (success));
4173 TEUCHOS_TEST_FOR_EXCEPTION(
4174 success == 0, std::runtime_error,
4175 "Tpetra::MatrixMarket::Reader::readMapFile: "
4176 "Failed to read file \"" << filename <<
"\" on Process 0.");
4177 return readMap (in, comm, tolerant, debug, binary);
4182 template<
class MultiVectorScalarType>
4187 readDenseImpl (std::istream& in,
4188 const Teuchos::RCP<const comm_type>& comm,
4189 Teuchos::RCP<const map_type>& map,
4190 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4191 const bool tolerant=
false,
4192 const bool debug=
false,
4193 const bool binary=
false)
4195 using Teuchos::MatrixMarket::Banner;
4196 using Teuchos::MatrixMarket::checkCommentLine;
4197 using Teuchos::ArrayRCP;
4199 using Teuchos::broadcast;
4200 using Teuchos::outArg;
4202 using Teuchos::Tuple;
4204 typedef MultiVectorScalarType ST;
4208 typedef Teuchos::ScalarTraits<ST> STS;
4209 typedef typename STS::magnitudeType MT;
4210 typedef Teuchos::ScalarTraits<MT> STM;
4215 const int myRank = comm->getRank ();
4217 if (! err.is_null ()) {
4221 *err << myRank <<
": readDenseImpl" << endl;
4223 if (! err.is_null ()) {
4258 size_t lineNumber = 1;
4261 std::ostringstream exMsg;
4262 int localBannerReadSuccess = 1;
4263 int localDimsReadSuccess = 1;
4269 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
4275 RCP<const Banner> pBanner;
4277 pBanner = readBanner (in, lineNumber, tolerant, debug);
4278 }
catch (std::exception& e) {
4280 localBannerReadSuccess = 0;
4283 if (localBannerReadSuccess) {
4284 if (pBanner->matrixType () !=
"array") {
4285 exMsg <<
"The Matrix Market file does not contain dense matrix "
4286 "data. Its banner (first) line says that its matrix type is \""
4287 << pBanner->matrixType () <<
"\", rather that the required "
4289 localBannerReadSuccess = 0;
4290 }
else if (pBanner->dataType() ==
"pattern") {
4291 exMsg <<
"The Matrix Market file's banner (first) "
4292 "line claims that the matrix's data type is \"pattern\". This does "
4293 "not make sense for a dense matrix, yet the file reports the matrix "
4294 "as dense. The only valid data types for a dense matrix are "
4295 "\"real\", \"complex\", and \"integer\".";
4296 localBannerReadSuccess = 0;
4300 dims[2] = encodeDataType (pBanner->dataType ());
4306 if (localBannerReadSuccess) {
4308 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
4317 bool commentLine =
true;
4319 while (commentLine) {
4322 if (in.eof () || in.fail ()) {
4323 exMsg <<
"Unable to get array dimensions line (at all) from line "
4324 << lineNumber <<
" of input stream. The input stream "
4325 <<
"claims that it is "
4326 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4327 localDimsReadSuccess = 0;
4330 if (getline (in, line)) {
4337 size_t start = 0, size = 0;
4338 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4345 std::istringstream istr (line);
4349 if (istr.eof () || istr.fail ()) {
4350 exMsg <<
"Unable to read any data from line " << lineNumber
4351 <<
" of input; the line should contain the matrix dimensions "
4352 <<
"\"<numRows> <numCols>\".";
4353 localDimsReadSuccess = 0;
4358 exMsg <<
"Failed to get number of rows from line "
4359 << lineNumber <<
" of input; the line should contains the "
4360 <<
"matrix dimensions \"<numRows> <numCols>\".";
4361 localDimsReadSuccess = 0;
4363 dims[0] = theNumRows;
4365 exMsg <<
"No more data after number of rows on line "
4366 << lineNumber <<
" of input; the line should contain the "
4367 <<
"matrix dimensions \"<numRows> <numCols>\".";
4368 localDimsReadSuccess = 0;
4373 exMsg <<
"Failed to get number of columns from line "
4374 << lineNumber <<
" of input; the line should contain "
4375 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4376 localDimsReadSuccess = 0;
4378 dims[1] = theNumCols;
4387 in.read(reinterpret_cast<char*>(&numRows),
sizeof(numRows));
4388 in.read(reinterpret_cast<char*>(&numCols),
sizeof(numCols));
4389 dims[0] = Teuchos::as<GO>(numRows);
4390 dims[1] = Teuchos::as<GO>(numCols);
4391 if ((
typeid(ST) ==
typeid(double)) || Teuchos::ScalarTraits<ST>::isOrdinal) {
4393 }
else if (Teuchos::ScalarTraits<ST>::isComplex) {
4396 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
4397 "Unrecognized Matrix Market data type. "
4398 "We should never get here. "
4399 "Please report this bug to the Tpetra developers.");
4401 localDimsReadSuccess =
true;
4402 localDimsReadSuccess =
true;
4409 Tuple<GO, 5> bannerDimsReadResult;
4411 bannerDimsReadResult[0] = dims[0];
4412 bannerDimsReadResult[1] = dims[1];
4413 bannerDimsReadResult[2] = dims[2];
4414 bannerDimsReadResult[3] = localBannerReadSuccess;
4415 bannerDimsReadResult[4] = localDimsReadSuccess;
4419 broadcast (*comm, 0, bannerDimsReadResult);
4421 TEUCHOS_TEST_FOR_EXCEPTION(
4422 bannerDimsReadResult[3] == 0, std::runtime_error,
4423 "Failed to read banner line: " << exMsg.str ());
4424 TEUCHOS_TEST_FOR_EXCEPTION(
4425 bannerDimsReadResult[4] == 0, std::runtime_error,
4426 "Failed to read matrix dimensions line: " << exMsg.str ());
4428 dims[0] = bannerDimsReadResult[0];
4429 dims[1] = bannerDimsReadResult[1];
4430 dims[2] = bannerDimsReadResult[2];
4435 const size_t numCols =
static_cast<size_t> (dims[1]);
4440 RCP<const map_type> proc0Map;
4441 if (map.is_null ()) {
4445 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
4446 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4448 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
4452 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
4456 RCP<MV> X = createMultiVector<ST, LO, GO, NT> (proc0Map, numCols);
4462 int localReadDataSuccess = 1;
4467 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4472 TEUCHOS_TEST_FOR_EXCEPTION(
4473 ! X->isConstantStride (), std::logic_error,
4474 "Can't get a 1-D view of the entries of the MultiVector X on "
4475 "Process 0, because the stride between the columns of X is not "
4476 "constant. This shouldn't happen because we just created X and "
4477 "haven't filled it in yet. Please report this bug to the Tpetra "
4484 ArrayRCP<ST> X_view = X->get1dViewNonConst ();
4485 TEUCHOS_TEST_FOR_EXCEPTION(
4486 as<global_size_t> (X_view.size ()) < numRows * numCols,
4488 "The view of X has size " << X_view.size() <<
" which is not enough to "
4489 "accommodate the expected number of entries numRows*numCols = "
4490 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
4491 "Please report this bug to the Tpetra developers.");
4492 const size_t stride = X->getStride ();
4499 const bool isComplex = (dims[2] == 1);
4500 size_type count = 0, curRow = 0, curCol = 0;
4503 while (getline (in, line)) {
4507 size_t start = 0, size = 0;
4508 const bool commentLine =
4509 checkCommentLine (line, start, size, lineNumber, tolerant);
4510 if (! commentLine) {
4516 if (count >= X_view.size()) {
4521 TEUCHOS_TEST_FOR_EXCEPTION(
4522 count >= X_view.size(),
4524 "The Matrix Market input stream has more data in it than "
4525 "its metadata reported. Current line number is "
4526 << lineNumber <<
".");
4535 const size_t pos = line.substr (start, size).find (
':');
4536 if (pos != std::string::npos) {
4540 std::istringstream istr (line.substr (start, size));
4544 if (istr.eof() || istr.fail()) {
4551 TEUCHOS_TEST_FOR_EXCEPTION(
4552 ! tolerant && (istr.eof() || istr.fail()),
4554 "Line " << lineNumber <<
" of the Matrix Market file is "
4555 "empty, or we cannot read from it for some other reason.");
4558 ST val = STS::zero();
4561 MT real = STM::zero(), imag = STM::zero();
4578 TEUCHOS_TEST_FOR_EXCEPTION(
4579 ! tolerant && istr.eof(), std::runtime_error,
4580 "Failed to get the real part of a complex-valued matrix "
4581 "entry from line " << lineNumber <<
" of the Matrix Market "
4587 }
else if (istr.eof()) {
4588 TEUCHOS_TEST_FOR_EXCEPTION(
4589 ! tolerant && istr.eof(), std::runtime_error,
4590 "Missing imaginary part of a complex-valued matrix entry "
4591 "on line " << lineNumber <<
" of the Matrix Market file.");
4597 TEUCHOS_TEST_FOR_EXCEPTION(
4598 ! tolerant && istr.fail(), std::runtime_error,
4599 "Failed to get the imaginary part of a complex-valued "
4600 "matrix entry from line " << lineNumber <<
" of the "
4601 "Matrix Market file.");
4608 TEUCHOS_TEST_FOR_EXCEPTION(
4609 ! tolerant && istr.fail(), std::runtime_error,
4610 "Failed to get a real-valued matrix entry from line "
4611 << lineNumber <<
" of the Matrix Market file.");
4614 if (istr.fail() && tolerant) {
4620 TEUCHOS_TEST_FOR_EXCEPTION(
4621 ! tolerant && istr.fail(), std::runtime_error,
4622 "Failed to read matrix data from line " << lineNumber
4623 <<
" of the Matrix Market file.");
4626 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
4628 curRow = count % numRows;
4629 curCol = count / numRows;
4630 X_view[curRow + curCol*stride] = val;
4635 TEUCHOS_TEST_FOR_EXCEPTION(
4636 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
4638 "The Matrix Market metadata reports that the dense matrix is "
4639 << numRows <<
" x " << numCols <<
", and thus has "
4640 << numRows*numCols <<
" total entries, but we only found " << count
4641 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4642 }
catch (std::exception& e) {
4644 localReadDataSuccess = 0;
4649 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4654 TEUCHOS_TEST_FOR_EXCEPTION(
4655 ! X->isConstantStride (), std::logic_error,
4656 "Can't get a 1-D view of the entries of the MultiVector X on "
4657 "Process 0, because the stride between the columns of X is not "
4658 "constant. This shouldn't happen because we just created X and "
4659 "haven't filled it in yet. Please report this bug to the Tpetra "
4666 auto X_view = X->getLocalViewHost (Access::OverwriteAll);
4668 TEUCHOS_TEST_FOR_EXCEPTION(
4669 as<global_size_t> (X_view.extent(0)) < numRows,
4671 "The view of X has " << X_view.extent(0) <<
" rows which is not enough to "
4672 "accommodate the expected number of entries numRows = "
4674 "Please report this bug to the Tpetra developers.");
4675 TEUCHOS_TEST_FOR_EXCEPTION(
4676 as<global_size_t> (X_view.extent(1)) < numCols,
4678 "The view of X has " << X_view.extent(1) <<
" colums which is not enough to "
4679 "accommodate the expected number of entries numRows = "
4681 "Please report this bug to the Tpetra developers.");
4683 for (
size_t curRow = 0; curRow < numRows; ++curRow) {
4684 for (
size_t curCol = 0; curCol < numCols; ++curCol) {
4685 if (Teuchos::ScalarTraits<ST>::isOrdinal){
4687 in.read(reinterpret_cast<char*>(&val),
sizeof(val));
4688 X_view(curRow, curCol) = val;
4691 in.read(reinterpret_cast<char*>(&val),
sizeof(val));
4692 X_view(curRow, curCol) = val;
4700 *err << myRank <<
": readDenseImpl: done reading data" << endl;
4704 int globalReadDataSuccess = localReadDataSuccess;
4705 broadcast (*comm, 0, outArg (globalReadDataSuccess));
4706 TEUCHOS_TEST_FOR_EXCEPTION(
4707 globalReadDataSuccess == 0, std::runtime_error,
4708 "Failed to read the multivector's data: " << exMsg.str ());
4713 if (comm->getSize () == 1 && map.is_null ()) {
4715 if (! err.is_null ()) {
4719 *err << myRank <<
": readDenseImpl: done" << endl;
4721 if (! err.is_null ()) {
4728 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
4732 RCP<MV> Y = createMultiVector<ST, LO, GO, NT> (map, numCols);
4735 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
4741 Export<LO, GO, NT> exporter (proc0Map, map, err);
4744 *err << myRank <<
": readDenseImpl: Exporting" << endl;
4747 Y->doExport (*X, exporter,
INSERT);
4749 if (! err.is_null ()) {
4753 *err << myRank <<
": readDenseImpl: done" << endl;
4755 if (! err.is_null ()) {
4764 template<
class VectorScalarType>
4769 readVectorImpl (std::istream& in,
4770 const Teuchos::RCP<const comm_type>& comm,
4771 Teuchos::RCP<const map_type>& map,
4772 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4773 const bool tolerant=
false,
4774 const bool debug=
false)
4776 using Teuchos::MatrixMarket::Banner;
4777 using Teuchos::MatrixMarket::checkCommentLine;
4779 using Teuchos::broadcast;
4780 using Teuchos::outArg;
4782 using Teuchos::Tuple;
4784 typedef VectorScalarType ST;
4788 typedef Teuchos::ScalarTraits<ST> STS;
4789 typedef typename STS::magnitudeType MT;
4790 typedef Teuchos::ScalarTraits<MT> STM;
4795 const int myRank = comm->getRank ();
4797 if (! err.is_null ()) {
4801 *err << myRank <<
": readVectorImpl" << endl;
4803 if (! err.is_null ()) {
4837 size_t lineNumber = 1;
4840 std::ostringstream exMsg;
4841 int localBannerReadSuccess = 1;
4842 int localDimsReadSuccess = 1;
4847 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
4853 RCP<const Banner> pBanner;
4855 pBanner = readBanner (in, lineNumber, tolerant, debug);
4856 }
catch (std::exception& e) {
4858 localBannerReadSuccess = 0;
4861 if (localBannerReadSuccess) {
4862 if (pBanner->matrixType () !=
"array") {
4863 exMsg <<
"The Matrix Market file does not contain dense matrix "
4864 "data. Its banner (first) line says that its matrix type is \""
4865 << pBanner->matrixType () <<
"\", rather that the required "
4867 localBannerReadSuccess = 0;
4868 }
else if (pBanner->dataType() ==
"pattern") {
4869 exMsg <<
"The Matrix Market file's banner (first) "
4870 "line claims that the matrix's data type is \"pattern\". This does "
4871 "not make sense for a dense matrix, yet the file reports the matrix "
4872 "as dense. The only valid data types for a dense matrix are "
4873 "\"real\", \"complex\", and \"integer\".";
4874 localBannerReadSuccess = 0;
4878 dims[2] = encodeDataType (pBanner->dataType ());
4884 if (localBannerReadSuccess) {
4886 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
4895 bool commentLine =
true;
4897 while (commentLine) {
4900 if (in.eof () || in.fail ()) {
4901 exMsg <<
"Unable to get array dimensions line (at all) from line "
4902 << lineNumber <<
" of input stream. The input stream "
4903 <<
"claims that it is "
4904 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4905 localDimsReadSuccess = 0;
4908 if (getline (in, line)) {
4915 size_t start = 0, size = 0;
4916 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4923 std::istringstream istr (line);
4927 if (istr.eof () || istr.fail ()) {
4928 exMsg <<
"Unable to read any data from line " << lineNumber
4929 <<
" of input; the line should contain the matrix dimensions "
4930 <<
"\"<numRows> <numCols>\".";
4931 localDimsReadSuccess = 0;
4936 exMsg <<
"Failed to get number of rows from line "
4937 << lineNumber <<
" of input; the line should contains the "
4938 <<
"matrix dimensions \"<numRows> <numCols>\".";
4939 localDimsReadSuccess = 0;
4941 dims[0] = theNumRows;
4943 exMsg <<
"No more data after number of rows on line "
4944 << lineNumber <<
" of input; the line should contain the "
4945 <<
"matrix dimensions \"<numRows> <numCols>\".";
4946 localDimsReadSuccess = 0;
4951 exMsg <<
"Failed to get number of columns from line "
4952 << lineNumber <<
" of input; the line should contain "
4953 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4954 localDimsReadSuccess = 0;
4956 dims[1] = theNumCols;
4966 exMsg <<
"File does not contain a 1D Vector";
4967 localDimsReadSuccess = 0;
4973 Tuple<GO, 5> bannerDimsReadResult;
4975 bannerDimsReadResult[0] = dims[0];
4976 bannerDimsReadResult[1] = dims[1];
4977 bannerDimsReadResult[2] = dims[2];
4978 bannerDimsReadResult[3] = localBannerReadSuccess;
4979 bannerDimsReadResult[4] = localDimsReadSuccess;
4984 broadcast (*comm, 0, bannerDimsReadResult);
4986 TEUCHOS_TEST_FOR_EXCEPTION(
4987 bannerDimsReadResult[3] == 0, std::runtime_error,
4988 "Failed to read banner line: " << exMsg.str ());
4989 TEUCHOS_TEST_FOR_EXCEPTION(
4990 bannerDimsReadResult[4] == 0, std::runtime_error,
4991 "Failed to read matrix dimensions line: " << exMsg.str ());
4993 dims[0] = bannerDimsReadResult[0];
4994 dims[1] = bannerDimsReadResult[1];
4995 dims[2] = bannerDimsReadResult[2];
5000 const size_t numCols =
static_cast<size_t> (dims[1]);
5005 RCP<const map_type> proc0Map;
5006 if (map.is_null ()) {
5010 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
5011 const size_t localNumRows = (myRank == 0) ? numRows : 0;
5013 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
5017 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
5021 RCP<MV> X = createVector<ST, LO, GO, NT> (proc0Map);
5027 int localReadDataSuccess = 1;
5031 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
5036 TEUCHOS_TEST_FOR_EXCEPTION(
5037 ! X->isConstantStride (), std::logic_error,
5038 "Can't get a 1-D view of the entries of the MultiVector X on "
5039 "Process 0, because the stride between the columns of X is not "
5040 "constant. This shouldn't happen because we just created X and "
5041 "haven't filled it in yet. Please report this bug to the Tpetra "
5048 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst ();
5049 TEUCHOS_TEST_FOR_EXCEPTION(
5050 as<global_size_t> (X_view.size ()) < numRows * numCols,
5052 "The view of X has size " << X_view <<
" which is not enough to "
5053 "accommodate the expected number of entries numRows*numCols = "
5054 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
5055 "Please report this bug to the Tpetra developers.");
5056 const size_t stride = X->getStride ();
5063 const bool isComplex = (dims[2] == 1);
5064 size_type count = 0, curRow = 0, curCol = 0;
5067 while (getline (in, line)) {
5071 size_t start = 0, size = 0;
5072 const bool commentLine =
5073 checkCommentLine (line, start, size, lineNumber, tolerant);
5074 if (! commentLine) {
5080 if (count >= X_view.size()) {
5085 TEUCHOS_TEST_FOR_EXCEPTION(
5086 count >= X_view.size(),
5088 "The Matrix Market input stream has more data in it than "
5089 "its metadata reported. Current line number is "
5090 << lineNumber <<
".");
5099 const size_t pos = line.substr (start, size).find (
':');
5100 if (pos != std::string::npos) {
5104 std::istringstream istr (line.substr (start, size));
5108 if (istr.eof() || istr.fail()) {
5115 TEUCHOS_TEST_FOR_EXCEPTION(
5116 ! tolerant && (istr.eof() || istr.fail()),
5118 "Line " << lineNumber <<
" of the Matrix Market file is "
5119 "empty, or we cannot read from it for some other reason.");
5122 ST val = STS::zero();
5125 MT real = STM::zero(), imag = STM::zero();
5142 TEUCHOS_TEST_FOR_EXCEPTION(
5143 ! tolerant && istr.eof(), std::runtime_error,
5144 "Failed to get the real part of a complex-valued matrix "
5145 "entry from line " << lineNumber <<
" of the Matrix Market "
5151 }
else if (istr.eof()) {
5152 TEUCHOS_TEST_FOR_EXCEPTION(
5153 ! tolerant && istr.eof(), std::runtime_error,
5154 "Missing imaginary part of a complex-valued matrix entry "
5155 "on line " << lineNumber <<
" of the Matrix Market file.");
5161 TEUCHOS_TEST_FOR_EXCEPTION(
5162 ! tolerant && istr.fail(), std::runtime_error,
5163 "Failed to get the imaginary part of a complex-valued "
5164 "matrix entry from line " << lineNumber <<
" of the "
5165 "Matrix Market file.");
5172 TEUCHOS_TEST_FOR_EXCEPTION(
5173 ! tolerant && istr.fail(), std::runtime_error,
5174 "Failed to get a real-valued matrix entry from line "
5175 << lineNumber <<
" of the Matrix Market file.");
5178 if (istr.fail() && tolerant) {
5184 TEUCHOS_TEST_FOR_EXCEPTION(
5185 ! tolerant && istr.fail(), std::runtime_error,
5186 "Failed to read matrix data from line " << lineNumber
5187 <<
" of the Matrix Market file.");
5190 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
5192 curRow = count % numRows;
5193 curCol = count / numRows;
5194 X_view[curRow + curCol*stride] = val;
5199 TEUCHOS_TEST_FOR_EXCEPTION(
5200 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
5202 "The Matrix Market metadata reports that the dense matrix is "
5203 << numRows <<
" x " << numCols <<
", and thus has "
5204 << numRows*numCols <<
" total entries, but we only found " << count
5205 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
5206 }
catch (std::exception& e) {
5208 localReadDataSuccess = 0;
5213 *err << myRank <<
": readVectorImpl: done reading data" << endl;
5217 int globalReadDataSuccess = localReadDataSuccess;
5218 broadcast (*comm, 0, outArg (globalReadDataSuccess));
5219 TEUCHOS_TEST_FOR_EXCEPTION(
5220 globalReadDataSuccess == 0, std::runtime_error,
5221 "Failed to read the multivector's data: " << exMsg.str ());
5226 if (comm->getSize () == 1 && map.is_null ()) {
5228 if (! err.is_null ()) {
5232 *err << myRank <<
": readVectorImpl: done" << endl;
5234 if (! err.is_null ()) {
5241 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
5245 RCP<MV> Y = createVector<ST, LO, GO, NT> (map);
5248 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
5254 Export<LO, GO, NT> exporter (proc0Map, map, err);
5257 *err << myRank <<
": readVectorImpl: Exporting" << endl;
5260 Y->doExport (*X, exporter,
INSERT);
5262 if (! err.is_null ()) {
5266 *err << myRank <<
": readVectorImpl: done" << endl;
5268 if (! err.is_null ()) {
5297 static Teuchos::RCP<const map_type>
5299 const Teuchos::RCP<const comm_type>& comm,
5300 const bool tolerant=
false,
5301 const bool debug=
false,
5302 const bool binary=
false)
5304 Teuchos::RCP<Teuchos::FancyOStream> err =
5305 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
5306 return readMap (in, comm, err, tolerant, debug, binary);
5336 static Teuchos::RCP<const map_type>
5338 const Teuchos::RCP<const comm_type>& comm,
5339 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5340 const bool tolerant=
false,
5341 const bool debug=
false,
5342 const bool binary=
false)
5344 using Teuchos::arcp;
5345 using Teuchos::Array;
5346 using Teuchos::ArrayRCP;
5348 using Teuchos::broadcast;
5349 using Teuchos::Comm;
5350 using Teuchos::CommRequest;
5351 using Teuchos::inOutArg;
5352 using Teuchos::ireceive;
5353 using Teuchos::outArg;
5355 using Teuchos::receive;
5356 using Teuchos::reduceAll;
5357 using Teuchos::REDUCE_MIN;
5358 using Teuchos::isend;
5359 using Teuchos::SerialComm;
5360 using Teuchos::toString;
5361 using Teuchos::wait;
5364 typedef ptrdiff_t int_type;
5370 const int numProcs = comm->getSize ();
5371 const int myRank = comm->getRank ();
5373 if (err.is_null ()) {
5377 std::ostringstream os;
5378 os << myRank <<
": readMap: " << endl;
5381 if (err.is_null ()) {
5387 const int sizeTag = 1339;
5389 const int dataTag = 1340;
5395 RCP<CommRequest<int> > sizeReq;
5396 RCP<CommRequest<int> > dataReq;
5401 ArrayRCP<int_type> numGidsToRecv (1);
5402 numGidsToRecv[0] = 0;
5404 sizeReq = ireceive<int, int_type> (numGidsToRecv, 0, sizeTag, *comm);
5407 int readSuccess = 1;
5408 std::ostringstream exMsg;
5417 RCP<const Comm<int> > proc0Comm (
new SerialComm<int> ());
5419 RCP<const map_type> dataMap;
5423 data = readDenseImpl<GO> (in, proc0Comm, dataMap, err, tolerant, debug, binary);
5425 if (data.is_null ()) {
5427 exMsg <<
"readDenseImpl() returned null." << endl;
5429 }
catch (std::exception& e) {
5431 exMsg << e.what () << endl;
5437 std::map<int, Array<GO> > pid2gids;
5442 int_type globalNumGIDs = 0;
5452 if (myRank == 0 && readSuccess == 1) {
5453 if (data->getNumVectors () == 2) {
5454 ArrayRCP<const GO> GIDs = data->getData (0);
5455 ArrayRCP<const GO> PIDs = data->getData (1);
5456 globalNumGIDs = GIDs.size ();
5460 if (globalNumGIDs > 0) {
5461 const int pid =
static_cast<int> (PIDs[0]);
5463 if (pid < 0 || pid >= numProcs) {
5465 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5466 <<
"Encountered invalid PID " << pid <<
"." << endl;
5469 const GO gid = GIDs[0];
5470 pid2gids[pid].push_back (gid);
5474 if (readSuccess == 1) {
5477 for (size_type k = 1; k < globalNumGIDs; ++k) {
5478 const int pid =
static_cast<int> (PIDs[k]);
5479 if (pid < 0 || pid >= numProcs) {
5481 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5482 <<
"Encountered invalid PID " << pid <<
"." << endl;
5485 const int_type gid = GIDs[k];
5486 pid2gids[pid].push_back (gid);
5487 if (gid < indexBase) {
5494 else if (data->getNumVectors () == 1) {
5495 if (data->getGlobalLength () % 2 !=
static_cast<GST
> (0)) {
5497 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
5498 "wrong format (for Map format 2.0). The global number of rows "
5499 "in the MultiVector must be even (divisible by 2)." << endl;
5502 ArrayRCP<const GO> theData = data->getData (0);
5503 globalNumGIDs =
static_cast<GO
> (data->getGlobalLength ()) /
5504 static_cast<GO> (2);
5508 if (globalNumGIDs > 0) {
5509 const int pid =
static_cast<int> (theData[1]);
5510 if (pid < 0 || pid >= numProcs) {
5512 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5513 <<
"Encountered invalid PID " << pid <<
"." << endl;
5516 const GO gid = theData[0];
5517 pid2gids[pid].push_back (gid);
5523 for (int_type k = 1; k < globalNumGIDs; ++k) {
5524 const int pid =
static_cast<int> (theData[2*k + 1]);
5525 if (pid < 0 || pid >= numProcs) {
5527 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5528 <<
"Encountered invalid PID " << pid <<
"." << endl;
5531 const GO gid = theData[2*k];
5532 pid2gids[pid].push_back (gid);
5533 if (gid < indexBase) {
5542 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
5543 "either 1 column (for the new Map format 2.0) or 2 columns (for "
5544 "the old Map format 1.0).";
5551 int_type readResults[3];
5552 readResults[0] =
static_cast<int_type
> (indexBase);
5553 readResults[1] =
static_cast<int_type
> (globalNumGIDs);
5554 readResults[2] =
static_cast<int_type
> (readSuccess);
5555 broadcast<int, int_type> (*comm, 0, 3, readResults);
5557 indexBase =
static_cast<GO
> (readResults[0]);
5558 globalNumGIDs =
static_cast<int_type
> (readResults[1]);
5559 readSuccess =
static_cast<int> (readResults[2]);
5565 TEUCHOS_TEST_FOR_EXCEPTION(
5566 readSuccess != 1, std::runtime_error,
5567 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
5568 "following exception message: " << exMsg.str ());
5572 for (
int p = 1; p < numProcs; ++p) {
5573 ArrayRCP<int_type> numGidsToSend (1);
5575 auto it = pid2gids.find (p);
5576 if (it == pid2gids.end ()) {
5577 numGidsToSend[0] = 0;
5579 numGidsToSend[0] = it->second.size ();
5581 sizeReq = isend<int, int_type> (numGidsToSend, p, sizeTag, *comm);
5582 wait<int> (*comm, outArg (sizeReq));
5587 wait<int> (*comm, outArg (sizeReq));
5592 ArrayRCP<GO> myGids;
5593 int_type myNumGids = 0;
5595 GO* myGidsRaw = NULL;
5597 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (0);
5598 if (it != pid2gids.end ()) {
5599 myGidsRaw = it->second.getRawPtr ();
5600 myNumGids = it->second.size ();
5602 myGids = arcp<GO> (myGidsRaw, 0, myNumGids,
false);
5606 myNumGids = numGidsToRecv[0];
5607 myGids = arcp<GO> (myNumGids);
5614 if (myNumGids > 0) {
5615 dataReq = ireceive<int, GO> (myGids, 0, dataTag, *comm);
5619 for (
int p = 1; p < numProcs; ++p) {
5621 ArrayRCP<GO> sendGids;
5622 GO* sendGidsRaw = NULL;
5623 int_type numSendGids = 0;
5625 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (p);
5626 if (it != pid2gids.end ()) {
5627 numSendGids = it->second.size ();
5628 sendGidsRaw = it->second.getRawPtr ();
5629 sendGids = arcp<GO> (sendGidsRaw, 0, numSendGids,
false);
5632 if (numSendGids > 0) {
5633 dataReq = isend<int, GO> (sendGids, p, dataTag, *comm);
5635 wait<int> (*comm, outArg (dataReq));
5637 else if (myRank == p) {
5639 wait<int> (*comm, outArg (dataReq));
5644 std::ostringstream os;
5645 os << myRank <<
": readMap: creating Map" << endl;
5648 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
5649 RCP<const map_type> newMap;
5656 std::ostringstream errStrm;
5658 newMap = rcp (
new map_type (INVALID, myGids (), indexBase, comm));
5660 catch (std::exception& e) {
5662 errStrm <<
"Process " << comm->getRank () <<
" threw an exception: "
5663 << e.what () << std::endl;
5667 errStrm <<
"Process " << comm->getRank () <<
" threw an exception "
5668 "not a subclass of std::exception" << std::endl;
5670 Teuchos::reduceAll<int, int> (*comm, Teuchos::REDUCE_MIN,
5671 lclSuccess, Teuchos::outArg (gblSuccess));
5672 if (gblSuccess != 1) {
5675 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
5677 if (err.is_null ()) {
5681 std::ostringstream os;
5682 os << myRank <<
": readMap: done" << endl;
5685 if (err.is_null ()) {
5705 encodeDataType (
const std::string& dataType)
5707 if (dataType ==
"real" || dataType ==
"integer") {
5709 }
else if (dataType ==
"complex") {
5711 }
else if (dataType ==
"pattern") {
5717 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
5718 "Unrecognized Matrix Market data type \"" << dataType
5719 <<
"\". We should never get here. "
5720 "Please report this bug to the Tpetra developers.");
5755 static Teuchos::RCP<sparse_matrix_type>
5757 const std::string& filename_suffix,
5758 const Teuchos::RCP<const map_type>& rowMap,
5759 Teuchos::RCP<const map_type>& colMap,
5760 const Teuchos::RCP<const map_type>& domainMap,
5761 const Teuchos::RCP<const map_type>& rangeMap,
5762 const bool callFillComplete=
true,
5763 const bool tolerant=
false,
5764 const int ranksToReadAtOnce=8,
5765 const bool debug=
false)
5770 using STS =
typename Teuchos::ScalarTraits<ST>;
5772 using Teuchos::ArrayRCP;
5773 using Teuchos::arcp;
5780 TEUCHOS_TEST_FOR_EXCEPTION(
5781 rowMap.is_null (), std::invalid_argument,
5782 "Row Map must be nonnull.");
5783 Teuchos::RCP<const Teuchos::Comm<int> > comm = rowMap->getComm();
5784 TEUCHOS_TEST_FOR_EXCEPTION
5785 (comm.is_null (), std::invalid_argument,
5786 "The input row map's communicator (Teuchos::Comm object) is null.");
5787 TEUCHOS_TEST_FOR_EXCEPTION(
5788 rangeMap.is_null (), std::invalid_argument,
5789 "Range Map must be nonnull.");
5790 TEUCHOS_TEST_FOR_EXCEPTION(
5791 domainMap.is_null (), std::invalid_argument,
5792 "Domain Map must be nonnull.");
5793 TEUCHOS_TEST_FOR_EXCEPTION(
5794 domainMap->getComm().getRawPtr() != comm.getRawPtr(),
5795 std::invalid_argument,
5796 "The specified domain Map's communicator (domainMap->getComm())"
5797 "differs from row Map's communicator");
5798 TEUCHOS_TEST_FOR_EXCEPTION(
5799 rangeMap->getComm().getRawPtr() != comm.getRawPtr(),
5800 std::invalid_argument,
5801 "The specified range Map's communicator (rangeMap->getComm())"
5802 "differs from row Map's communicator");
5805 const int myRank = comm->getRank();
5806 const int numProc = comm->getSize();
5807 std::string filename = filename_prefix + std::to_string(myRank) + filename_suffix;
5810 int rank_limit = std::min(std::max(ranksToReadAtOnce,1),numProc);
5813 ArrayRCP<size_t> numEntriesPerRow;
5814 ArrayRCP<size_t> rowPtr;
5815 ArrayRCP<global_ordinal_type> colInd;
5816 ArrayRCP<scalar_type> values;
5817 std::ostringstream errMsg;
5824 bool success =
true;
5825 int bannerIsCorrect = 1, readSuccess = 1;
5826 LO numRows, numCols, numNonzeros;
5827 for(
int base_rank = 0; base_rank < numProc; base_rank += rank_limit) {
5828 int stop = std::min(base_rank+rank_limit,numProc);
5831 if(base_rank <= myRank && myRank < stop) {
5833 std::ifstream in(filename);
5834 using Teuchos::MatrixMarket::Banner;
5835 size_t lineNumber = 1;
5836 RCP<const Banner> pBanner;
5838 pBanner = readBanner (in, lineNumber, tolerant, debug);
5840 catch (std::exception& e) {
5841 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
5842 "threw an exception: " << e.what();
5843 bannerIsCorrect = 0;
5845 if (bannerIsCorrect) {
5850 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
5851 bannerIsCorrect = 0;
5852 errMsg <<
"The Matrix Market input file must contain a "
5853 "\"coordinate\"-format sparse matrix in order to create a "
5854 "Tpetra::CrsMatrix object from it, but the file's matrix "
5855 "type is \"" << pBanner->matrixType() <<
"\" instead.";
5860 if (tolerant && pBanner->matrixType() ==
"array") {
5861 bannerIsCorrect = 0;
5862 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
5863 "format sparse matrix in order to create a Tpetra::CrsMatrix "
5864 "object from it, but the file's matrix type is \"array\" "
5865 "instead. That probably means the file contains dense matrix "
5871 using Teuchos::MatrixMarket::readCoordinateDimensions;
5872 success = readCoordinateDimensions (in, numRows, numCols,
5873 numNonzeros, lineNumber,
5877 TEUCHOS_TEST_FOR_EXCEPTION(numRows != (LO)rowMap->getLocalNumElements(), std::invalid_argument,
5878 "# rows in file does not match rowmap.");
5879 TEUCHOS_TEST_FOR_EXCEPTION(!colMap.is_null() && numCols != (LO)colMap->getLocalNumElements(), std::invalid_argument,
5880 "# rows in file does not match colmap.");
5884 typedef Teuchos::MatrixMarket::Raw::Adder<scalar_type,global_ordinal_type> raw_adder_type;
5885 bool tolerant_required =
true;
5886 Teuchos::RCP<raw_adder_type> pRaw =
5887 Teuchos::rcp (
new raw_adder_type (numRows,numCols,numNonzeros,tolerant_required,debug));
5888 RCP<adder_type> pAdder = Teuchos::rcp (
new adder_type (pRaw, pBanner->symmType ()));
5891 std::cerr <<
"-- Reading matrix data" << std::endl;
5896 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
5898 reader_type reader (pAdder);
5901 std::pair<bool, std::vector<size_t> > results = reader.read (in, lineNumber, tolerant_required, debug);
5904 readSuccess = results.first ? 1 : 0;
5906 catch (std::exception& e) {
5913 typedef Teuchos::MatrixMarket::Raw::Element<scalar_type,global_ordinal_type> element_type;
5916 pAdder->getAdder()->merge ();
5919 const std::vector<element_type>& entries = pAdder->getAdder()->getEntries();
5922 const size_t numEntries = (size_t)entries.size();
5925 std::cerr <<
"----- Proc "<<myRank<<
": Matrix has numRows=" << numRows
5926 <<
" rows and numEntries=" << numEntries
5927 <<
" entries." << std::endl;
5934 numEntriesPerRow = arcp<size_t> (numRows);
5935 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
5936 rowPtr = arcp<size_t> (numRows+1);
5937 std::fill (rowPtr.begin(), rowPtr.end(), 0);
5938 colInd = arcp<global_ordinal_type> (numEntries);
5939 values = arcp<scalar_type> (numEntries);
5945 LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
5947 LO indexBase = rowMap->getIndexBase();
5948 for (curPos = 0; curPos < numEntries; ++curPos) {
5949 const element_type& curEntry = entries[curPos];
5951 LO l_curRow = rowMap->getLocalElement(curRow);
5954 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow == INVALID,std::logic_error,
5955 "Current global row "<< curRow <<
" is invalid.");
5957 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow < l_prvRow, std::logic_error,
5958 "Row indices are out of order, even though they are supposed "
5959 "to be sorted. curRow = " << l_curRow <<
", prvRow = "
5960 << l_prvRow <<
", at curPos = " << curPos <<
". Please report "
5961 "this bug to the Tpetra developers.");
5962 if (l_curRow > l_prvRow) {
5963 for (LO r = l_prvRow+1; r <= l_curRow; ++r) {
5966 l_prvRow = l_curRow;
5968 numEntriesPerRow[l_curRow]++;
5969 colInd[curPos] = curEntry.colIndex() + indexBase;
5970 values[curPos] = curEntry.value();
5976 rowPtr[numRows] = numEntries;
5987 RCP<sparse_matrix_type> A;
5988 if(colMap.is_null()) {
5990 for(
size_t i=0; i<rowMap->getLocalNumElements(); i++) {
5991 GO g_row = rowMap->getGlobalElement(i);
5992 size_t start = rowPtr[i];
5993 size_t size = rowPtr[i+1] - rowPtr[i];
5995 A->insertGlobalValues(g_row,size,&values[start],&colInd[start]);
6000 throw std::runtime_error(
"Reading with a column map is not yet implemented");
6002 RCP<const map_type> myDomainMap = domainMap.is_null() ? rowMap : domainMap;
6003 RCP<const map_type> myRangeMap = rangeMap.is_null() ? rowMap : rangeMap;
6005 A->fillComplete(myDomainMap,myRangeMap);
6009 TEUCHOS_TEST_FOR_EXCEPTION(success ==
false, std::runtime_error,
6046 template<
class SparseMatrixType>
6051 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
6113 const std::string& matrixName,
6114 const std::string& matrixDescription,
6115 const bool debug=
false)
6117 Teuchos::RCP<const Teuchos::Comm<int> > comm = matrix.getComm ();
6118 TEUCHOS_TEST_FOR_EXCEPTION
6119 (comm.is_null (), std::invalid_argument,
6120 "The input matrix's communicator (Teuchos::Comm object) is null.");
6121 const int myRank = comm->getRank ();
6126 out.open (filename.c_str ());
6128 writeSparse (out, matrix, matrixName, matrixDescription, debug);
6137 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6138 const std::string& matrixName,
6139 const std::string& matrixDescription,
6140 const bool debug=
false)
6142 TEUCHOS_TEST_FOR_EXCEPTION
6143 (pMatrix.is_null (), std::invalid_argument,
6144 "The input matrix is null.");
6146 matrixDescription, debug);
6171 const bool debug=
false)
6179 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6180 const bool debug=
false)
6218 const std::string& matrixName,
6219 const std::string& matrixDescription,
6220 const bool debug=
false)
6222 using Teuchos::ArrayView;
6223 using Teuchos::Comm;
6224 using Teuchos::FancyOStream;
6225 using Teuchos::getFancyOStream;
6226 using Teuchos::null;
6228 using Teuchos::rcpFromRef;
6234 using STS =
typename Teuchos::ScalarTraits<ST>;
6240 Teuchos::SetScientific<ST> sci (out);
6243 RCP<const Comm<int> > comm = matrix.getComm ();
6244 TEUCHOS_TEST_FOR_EXCEPTION(
6245 comm.is_null (), std::invalid_argument,
6246 "The input matrix's communicator (Teuchos::Comm object) is null.");
6247 const int myRank = comm->getRank ();
6250 RCP<FancyOStream> err =
6251 debug ? getFancyOStream (rcpFromRef (std::cerr)) : null;
6253 std::ostringstream os;
6254 os << myRank <<
": writeSparse" << endl;
6257 os <<
"-- " << myRank <<
": past barrier" << endl;
6262 const bool debugPrint = debug && myRank == 0;
6264 RCP<const map_type> rowMap = matrix.getRowMap ();
6265 RCP<const map_type> colMap = matrix.getColMap ();
6266 RCP<const map_type> domainMap = matrix.getDomainMap ();
6267 RCP<const map_type> rangeMap = matrix.getRangeMap ();
6269 const global_size_t numRows = rangeMap->getGlobalNumElements ();
6270 const global_size_t numCols = domainMap->getGlobalNumElements ();
6272 if (debug && myRank == 0) {
6273 std::ostringstream os;
6274 os <<
"-- Input sparse matrix is:"
6275 <<
"---- " << numRows <<
" x " << numCols << endl
6277 << (matrix.isGloballyIndexed() ?
"Globally" :
"Locally")
6278 <<
" indexed." << endl
6279 <<
"---- Its row map has " << rowMap->getGlobalNumElements ()
6280 <<
" elements." << endl
6281 <<
"---- Its col map has " << colMap->getGlobalNumElements ()
6282 <<
" elements." << endl;
6287 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6289 std::ostringstream os;
6290 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6293 RCP<const map_type> gatherRowMap =
6294 Details::computeGatherMap (rowMap, err, debug);
6302 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6303 RCP<const map_type> gatherColMap =
6304 Details::computeGatherMap (colMap, err, debug);
6308 import_type importer (rowMap, gatherRowMap);
6313 RCP<sparse_matrix_type> newMatrix =
6315 static_cast<size_t> (0)));
6317 newMatrix->doImport (matrix, importer,
INSERT);
6322 RCP<const map_type> gatherDomainMap =
6323 rcp (
new map_type (numCols, localNumCols,
6324 domainMap->getIndexBase (),
6326 RCP<const map_type> gatherRangeMap =
6327 rcp (
new map_type (numRows, localNumRows,
6328 rangeMap->getIndexBase (),
6330 newMatrix->fillComplete (gatherDomainMap, gatherRangeMap);
6334 cerr <<
"-- Output sparse matrix is:"
6335 <<
"---- " << newMatrix->getRangeMap ()->getGlobalNumElements ()
6337 << newMatrix->getDomainMap ()->getGlobalNumElements ()
6339 << newMatrix->getGlobalNumEntries () <<
" entries;" << endl
6341 << (newMatrix->isGloballyIndexed () ?
"Globally" :
"Locally")
6342 <<
" indexed." << endl
6343 <<
"---- Its row map has "
6344 << newMatrix->getRowMap ()->getGlobalNumElements ()
6345 <<
" elements, with index base "
6346 << newMatrix->getRowMap ()->getIndexBase () <<
"." << endl
6347 <<
"---- Its col map has "
6348 << newMatrix->getColMap ()->getGlobalNumElements ()
6349 <<
" elements, with index base "
6350 << newMatrix->getColMap ()->getIndexBase () <<
"." << endl
6351 <<
"---- Element count of output matrix's column Map may differ "
6352 <<
"from that of the input matrix's column Map, if some columns "
6353 <<
"of the matrix contain no entries." << endl;
6366 out <<
"%%MatrixMarket matrix coordinate "
6367 << (STS::isComplex ?
"complex" :
"real")
6368 <<
" general" << endl;
6371 if (matrixName !=
"") {
6372 printAsComment (out, matrixName);
6374 if (matrixDescription !=
"") {
6375 printAsComment (out, matrixDescription);
6385 out << newMatrix->getRangeMap ()->getGlobalNumElements () <<
" "
6386 << newMatrix->getDomainMap ()->getGlobalNumElements () <<
" "
6387 << newMatrix->getGlobalNumEntries () << endl;
6392 const GO rowIndexBase = gatherRowMap->getIndexBase ();
6393 const GO colIndexBase = newMatrix->getColMap()->getIndexBase ();
6401 if (newMatrix->isGloballyIndexed()) {
6404 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
6405 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
6406 for (GO globalRowIndex = minAllGlobalIndex;
6407 globalRowIndex <= maxAllGlobalIndex;
6409 typename sparse_matrix_type::global_inds_host_view_type ind;
6410 typename sparse_matrix_type::values_host_view_type val;
6411 newMatrix->getGlobalRowView (globalRowIndex, ind, val);
6412 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6413 const GO globalColIndex = ind(ii);
6416 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6417 << (globalColIndex + 1 - colIndexBase) <<
" ";
6418 if (STS::isComplex) {
6419 out << STS::real (val(ii)) <<
" " << STS::imag (val(ii));
6428 using OTG = Teuchos::OrdinalTraits<GO>;
6429 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
6430 localRowIndex <= gatherRowMap->getMaxLocalIndex();
6433 const GO globalRowIndex =
6434 gatherRowMap->getGlobalElement (localRowIndex);
6435 TEUCHOS_TEST_FOR_EXCEPTION(
6436 globalRowIndex == OTG::invalid(), std::logic_error,
6437 "Failed to convert the supposed local row index "
6438 << localRowIndex <<
" into a global row index. "
6439 "Please report this bug to the Tpetra developers.");
6440 typename sparse_matrix_type::local_inds_host_view_type ind;
6441 typename sparse_matrix_type::values_host_view_type val;
6442 newMatrix->getLocalRowView (localRowIndex, ind, val);
6443 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6445 const GO globalColIndex =
6446 newMatrix->getColMap()->getGlobalElement (ind(ii));
6447 TEUCHOS_TEST_FOR_EXCEPTION(
6448 globalColIndex == OTG::invalid(), std::logic_error,
6449 "On local row " << localRowIndex <<
" of the sparse matrix: "
6450 "Failed to convert the supposed local column index "
6451 << ind(ii) <<
" into a global column index. Please report "
6452 "this bug to the Tpetra developers.");
6455 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6456 << (globalColIndex + 1 - colIndexBase) <<
" ";
6457 if (STS::isComplex) {
6458 out << STS::real (val(ii)) <<
" " << STS::imag (val(ii));
6472 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6473 const std::string& matrixName,
6474 const std::string& matrixDescription,
6475 const bool debug=
false)
6477 TEUCHOS_TEST_FOR_EXCEPTION
6478 (pMatrix.is_null (), std::invalid_argument,
6479 "The input matrix is null.");
6480 writeSparse (out, *pMatrix, matrixName, matrixDescription, debug);
6516 const std::string& graphName,
6517 const std::string& graphDescription,
6518 const bool debug=
false)
6520 using Teuchos::ArrayView;
6521 using Teuchos::Comm;
6522 using Teuchos::FancyOStream;
6523 using Teuchos::getFancyOStream;
6524 using Teuchos::null;
6526 using Teuchos::rcpFromRef;
6537 if (rowMap.is_null ()) {
6540 auto comm = rowMap->getComm ();
6541 if (comm.is_null ()) {
6544 const int myRank = comm->getRank ();
6547 RCP<FancyOStream> err =
6548 debug ? getFancyOStream (rcpFromRef (std::cerr)) : null;
6550 std::ostringstream os;
6551 os << myRank <<
": writeSparseGraph" << endl;
6554 os <<
"-- " << myRank <<
": past barrier" << endl;
6559 const bool debugPrint = debug && myRank == 0;
6566 const global_size_t numRows = rangeMap->getGlobalNumElements ();
6567 const global_size_t numCols = domainMap->getGlobalNumElements ();
6569 if (debug && myRank == 0) {
6570 std::ostringstream os;
6571 os <<
"-- Input sparse graph is:"
6572 <<
"---- " << numRows <<
" x " << numCols <<
" with "
6576 <<
" indexed." << endl
6577 <<
"---- Its row Map has " << rowMap->getGlobalNumElements ()
6578 <<
" elements." << endl
6579 <<
"---- Its col Map has " << colMap->getGlobalNumElements ()
6580 <<
" elements." << endl;
6585 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6587 std::ostringstream os;
6588 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6591 auto gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
6599 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6600 auto gatherColMap = Details::computeGatherMap (colMap, err, debug);
6609 static_cast<size_t> (0));
6616 RCP<const map_type> gatherDomainMap =
6617 rcp (
new map_type (numCols, localNumCols,
6618 domainMap->getIndexBase (),
6620 RCP<const map_type> gatherRangeMap =
6621 rcp (
new map_type (numRows, localNumRows,
6622 rangeMap->getIndexBase (),
6624 newGraph.
fillComplete (gatherDomainMap, gatherRangeMap);
6628 cerr <<
"-- Output sparse graph is:"
6629 <<
"---- " << newGraph.
getRangeMap ()->getGlobalNumElements ()
6636 <<
" indexed." << endl
6637 <<
"---- Its row map has "
6638 << newGraph.
getRowMap ()->getGlobalNumElements ()
6639 <<
" elements, with index base "
6640 << newGraph.
getRowMap ()->getIndexBase () <<
"." << endl
6641 <<
"---- Its col map has "
6642 << newGraph.
getColMap ()->getGlobalNumElements ()
6643 <<
" elements, with index base "
6644 << newGraph.
getColMap ()->getIndexBase () <<
"." << endl
6645 <<
"---- Element count of output graph's column Map may differ "
6646 <<
"from that of the input matrix's column Map, if some columns "
6647 <<
"of the matrix contain no entries." << endl;
6661 out <<
"%%MatrixMarket matrix coordinate pattern general" << endl;
6664 if (graphName !=
"") {
6665 printAsComment (out, graphName);
6667 if (graphDescription !=
"") {
6668 printAsComment (out, graphDescription);
6679 out << newGraph.
getRangeMap ()->getGlobalNumElements () <<
" "
6680 << newGraph.
getDomainMap ()->getGlobalNumElements () <<
" "
6686 const GO rowIndexBase = gatherRowMap->getIndexBase ();
6687 const GO colIndexBase = newGraph.
getColMap()->getIndexBase ();
6698 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
6699 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
6700 for (GO globalRowIndex = minAllGlobalIndex;
6701 globalRowIndex <= maxAllGlobalIndex;
6703 typename crs_graph_type::global_inds_host_view_type ind;
6705 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6706 const GO globalColIndex = ind(ii);
6709 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6710 << (globalColIndex + 1 - colIndexBase) <<
" ";
6716 typedef Teuchos::OrdinalTraits<GO> OTG;
6717 for (LO localRowIndex = gatherRowMap->getMinLocalIndex ();
6718 localRowIndex <= gatherRowMap->getMaxLocalIndex ();
6721 const GO globalRowIndex =
6722 gatherRowMap->getGlobalElement (localRowIndex);
6723 TEUCHOS_TEST_FOR_EXCEPTION
6724 (globalRowIndex == OTG::invalid (), std::logic_error,
"Failed "
6725 "to convert the supposed local row index " << localRowIndex <<
6726 " into a global row index. Please report this bug to the "
6727 "Tpetra developers.");
6728 typename crs_graph_type::local_inds_host_view_type ind;
6730 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
6732 const GO globalColIndex =
6733 newGraph.
getColMap ()->getGlobalElement (ind(ii));
6734 TEUCHOS_TEST_FOR_EXCEPTION(
6735 globalColIndex == OTG::invalid(), std::logic_error,
6736 "On local row " << localRowIndex <<
" of the sparse graph: "
6737 "Failed to convert the supposed local column index "
6738 << ind(ii) <<
" into a global column index. Please report "
6739 "this bug to the Tpetra developers.");
6742 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6743 << (globalColIndex + 1 - colIndexBase) <<
" ";
6759 const bool debug=
false)
6801 const std::string& graphName,
6802 const std::string& graphDescription,
6803 const bool debug=
false)
6806 if (comm.is_null ()) {
6814 const int myRank = comm->getRank ();
6819 out.open (filename.c_str ());
6834 const bool debug=
false)
6849 const Teuchos::RCP<const crs_graph_type>& pGraph,
6850 const std::string& graphName,
6851 const std::string& graphDescription,
6852 const bool debug=
false)
6868 const Teuchos::RCP<const crs_graph_type>& pGraph,
6869 const bool debug=
false)
6899 const bool debug=
false)
6907 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6908 const bool debug=
false)
6944 const std::string& matrixName,
6945 const std::string& matrixDescription,
6946 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6947 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6949 const int myRank = X.
getMap ().is_null () ? 0 :
6950 (X.
getMap ()->getComm ().is_null () ? 0 :
6951 X.
getMap ()->getComm ()->getRank ());
6955 out.open (filename.c_str());
6958 writeDense (out, X, matrixName, matrixDescription, err, dbg);
6971 const Teuchos::RCP<const multivector_type>& X,
6972 const std::string& matrixName,
6973 const std::string& matrixDescription,
6974 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6975 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6977 TEUCHOS_TEST_FOR_EXCEPTION(
6978 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
6979 "writeDenseFile: The input MultiVector X is null.");
6980 writeDenseFile (filename, *X, matrixName, matrixDescription, err, dbg);
6991 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6992 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7004 const Teuchos::RCP<const multivector_type>& X,
7005 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7006 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7008 TEUCHOS_TEST_FOR_EXCEPTION(
7009 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7010 "writeDenseFile: The input MultiVector X is null.");
7048 const std::string& matrixName,
7049 const std::string& matrixDescription,
7050 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7051 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7053 using Teuchos::Comm;
7054 using Teuchos::outArg;
7055 using Teuchos::REDUCE_MAX;
7056 using Teuchos::reduceAll;
7060 RCP<const Comm<int> > comm = X.
getMap ().is_null () ?
7061 Teuchos::null : X.
getMap ()->getComm ();
7062 const int myRank = comm.is_null () ? 0 : comm->getRank ();
7067 const bool debug = ! dbg.is_null ();
7070 std::ostringstream os;
7071 os << myRank <<
": writeDense" << endl;
7076 writeDenseHeader (out, X, matrixName, matrixDescription, err, dbg);
7081 for (
size_t j = 0; j < numVecs; ++j) {
7082 writeDenseColumn (out, * (X.
getVector (j)), err, dbg);
7087 std::ostringstream os;
7088 os << myRank <<
": writeDense: Done" << endl;
7122 writeDenseHeader (std::ostream& out,
7124 const std::string& matrixName,
7125 const std::string& matrixDescription,
7126 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7127 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7129 using Teuchos::Comm;
7130 using Teuchos::outArg;
7132 using Teuchos::REDUCE_MAX;
7133 using Teuchos::reduceAll;
7135 typedef Teuchos::ScalarTraits<scalar_type> STS;
7136 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
7138 RCP<const Comm<int> > comm = X.getMap ().is_null () ?
7139 Teuchos::null : X.getMap ()->getComm ();
7140 const int myRank = comm.is_null () ? 0 : comm->getRank ();
7147 const bool debug = ! dbg.is_null ();
7151 std::ostringstream os;
7152 os << myRank <<
": writeDenseHeader" << endl;
7171 std::ostringstream hdr;
7173 std::string dataType;
7174 if (STS::isComplex) {
7175 dataType =
"complex";
7176 }
else if (STS::isOrdinal) {
7177 dataType =
"integer";
7181 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
7186 if (matrixName !=
"") {
7187 printAsComment (hdr, matrixName);
7189 if (matrixDescription !=
"") {
7190 printAsComment (hdr, matrixDescription);
7193 hdr << X.getGlobalLength () <<
" " << X.getNumVectors () << endl;
7197 }
catch (std::exception& e) {
7198 if (! err.is_null ()) {
7199 *err << prefix <<
"While writing the Matrix Market header, "
7200 "Process 0 threw an exception: " << e.what () << endl;
7209 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
7210 TEUCHOS_TEST_FOR_EXCEPTION(
7211 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
7212 "which prevented this method from completing.");
7216 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
7239 writeDenseColumn (std::ostream& out,
7241 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7242 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7244 using Teuchos::arcp;
7245 using Teuchos::Array;
7246 using Teuchos::ArrayRCP;
7247 using Teuchos::ArrayView;
7248 using Teuchos::Comm;
7249 using Teuchos::CommRequest;
7250 using Teuchos::ireceive;
7251 using Teuchos::isend;
7252 using Teuchos::outArg;
7253 using Teuchos::REDUCE_MAX;
7254 using Teuchos::reduceAll;
7256 using Teuchos::TypeNameTraits;
7257 using Teuchos::wait;
7259 typedef Teuchos::ScalarTraits<scalar_type> STS;
7261 const Comm<int>& comm = * (X.getMap ()->getComm ());
7262 const int myRank = comm.getRank ();
7263 const int numProcs = comm.getSize ();
7270 const bool debug = ! dbg.is_null ();
7274 std::ostringstream os;
7275 os << myRank <<
": writeDenseColumn" << endl;
7284 Teuchos::SetScientific<scalar_type> sci (out);
7286 const size_t myNumRows = X.getLocalLength ();
7287 const size_t numCols = X.getNumVectors ();
7290 const int sizeTag = 1337;
7291 const int dataTag = 1338;
7352 RCP<CommRequest<int> > sendReqSize, sendReqData;
7358 Array<ArrayRCP<size_t> > recvSizeBufs (3);
7359 Array<ArrayRCP<scalar_type> > recvDataBufs (3);
7360 Array<RCP<CommRequest<int> > > recvSizeReqs (3);
7361 Array<RCP<CommRequest<int> > > recvDataReqs (3);
7364 ArrayRCP<size_t> sendDataSize (1);
7365 sendDataSize[0] = myNumRows;
7369 std::ostringstream os;
7370 os << myRank <<
": Post receive-size receives from "
7371 "Procs 1 and 2: tag = " << sizeTag << endl;
7375 recvSizeBufs[0].resize (1);
7379 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7380 recvSizeBufs[1].resize (1);
7381 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7382 recvSizeBufs[2].resize (1);
7383 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7386 ireceive<int, size_t> (recvSizeBufs[1], 1, sizeTag, comm);
7390 ireceive<int, size_t> (recvSizeBufs[2], 2, sizeTag, comm);
7393 else if (myRank == 1 || myRank == 2) {
7395 std::ostringstream os;
7396 os << myRank <<
": Post send-size send: size = "
7397 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7404 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
7408 std::ostringstream os;
7409 os << myRank <<
": Not posting my send-size send yet" << endl;
7418 std::ostringstream os;
7419 os << myRank <<
": Pack my entries" << endl;
7422 ArrayRCP<scalar_type> sendDataBuf;
7424 sendDataBuf = arcp<scalar_type> (myNumRows * numCols);
7425 X.get1dCopy (sendDataBuf (), myNumRows);
7427 catch (std::exception& e) {
7429 if (! err.is_null ()) {
7430 std::ostringstream os;
7431 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
7432 "entries threw an exception: " << e.what () << endl;
7437 std::ostringstream os;
7438 os << myRank <<
": Done packing my entries" << endl;
7447 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
7450 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7458 std::ostringstream os;
7459 os << myRank <<
": Write my entries" << endl;
7465 const size_t printNumRows = myNumRows;
7466 ArrayView<const scalar_type> printData = sendDataBuf ();
7467 const size_t printStride = printNumRows;
7468 if (static_cast<size_t> (printData.size ()) < printStride * numCols) {
7470 if (! err.is_null ()) {
7471 std::ostringstream os;
7472 os <<
"Process " << myRank <<
": My MultiVector data's size "
7473 << printData.size () <<
" does not match my local dimensions "
7474 << printStride <<
" x " << numCols <<
"." << endl;
7482 for (
size_t col = 0; col < numCols; ++col) {
7483 for (
size_t row = 0; row < printNumRows; ++row) {
7484 if (STS::isComplex) {
7485 out << STS::real (printData[row + col * printStride]) <<
" "
7486 << STS::imag (printData[row + col * printStride]) << endl;
7488 out << printData[row + col * printStride] << endl;
7497 const int recvRank = 1;
7498 const int circBufInd = recvRank % 3;
7500 std::ostringstream os;
7501 os << myRank <<
": Wait on receive-size receive from Process "
7502 << recvRank << endl;
7506 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7510 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7511 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7513 if (! err.is_null ()) {
7514 std::ostringstream os;
7515 os << myRank <<
": Result of receive-size receive from Process "
7516 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7517 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7518 "This should never happen, and suggests that the receive never "
7519 "got posted. Please report this bug to the Tpetra developers."
7534 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7536 std::ostringstream os;
7537 os << myRank <<
": Post receive-data receive from Process "
7538 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7539 << recvDataBufs[circBufInd].size () << endl;
7542 if (! recvSizeReqs[circBufInd].is_null ()) {
7544 if (! err.is_null ()) {
7545 std::ostringstream os;
7546 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7547 "null, before posting the receive-data receive from Process "
7548 << recvRank <<
". This should never happen. Please report "
7549 "this bug to the Tpetra developers." << endl;
7553 recvDataReqs[circBufInd] =
7554 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7555 recvRank, dataTag, comm);
7558 else if (myRank == 1) {
7561 std::ostringstream os;
7562 os << myRank <<
": Wait on my send-size send" << endl;
7565 wait<int> (comm, outArg (sendReqSize));
7571 for (
int p = 1; p < numProcs; ++p) {
7573 if (p + 2 < numProcs) {
7575 const int recvRank = p + 2;
7576 const int circBufInd = recvRank % 3;
7578 std::ostringstream os;
7579 os << myRank <<
": Post receive-size receive from Process "
7580 << recvRank <<
": tag = " << sizeTag << endl;
7583 if (! recvSizeReqs[circBufInd].is_null ()) {
7585 if (! err.is_null ()) {
7586 std::ostringstream os;
7587 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7588 <<
"null, for the receive-size receive from Process "
7589 << recvRank <<
"! This may mean that this process never "
7590 <<
"finished waiting for the receive from Process "
7591 << (recvRank - 3) <<
"." << endl;
7595 recvSizeReqs[circBufInd] =
7596 ireceive<int, size_t> (recvSizeBufs[circBufInd],
7597 recvRank, sizeTag, comm);
7600 if (p + 1 < numProcs) {
7601 const int recvRank = p + 1;
7602 const int circBufInd = recvRank % 3;
7606 std::ostringstream os;
7607 os << myRank <<
": Wait on receive-size receive from Process "
7608 << recvRank << endl;
7611 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7615 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7616 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7618 if (! err.is_null ()) {
7619 std::ostringstream os;
7620 os << myRank <<
": Result of receive-size receive from Process "
7621 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7622 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7623 "This should never happen, and suggests that the receive never "
7624 "got posted. Please report this bug to the Tpetra developers."
7638 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7640 std::ostringstream os;
7641 os << myRank <<
": Post receive-data receive from Process "
7642 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7643 << recvDataBufs[circBufInd].size () << endl;
7646 if (! recvDataReqs[circBufInd].is_null ()) {
7648 if (! err.is_null ()) {
7649 std::ostringstream os;
7650 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
7651 <<
"null, for the receive-data receive from Process "
7652 << recvRank <<
"! This may mean that this process never "
7653 <<
"finished waiting for the receive from Process "
7654 << (recvRank - 3) <<
"." << endl;
7658 recvDataReqs[circBufInd] =
7659 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7660 recvRank, dataTag, comm);
7664 const int recvRank = p;
7665 const int circBufInd = recvRank % 3;
7667 std::ostringstream os;
7668 os << myRank <<
": Wait on receive-data receive from Process "
7669 << recvRank << endl;
7672 wait<int> (comm, outArg (recvDataReqs[circBufInd]));
7679 std::ostringstream os;
7680 os << myRank <<
": Write entries from Process " << recvRank
7682 *dbg << os.str () << endl;
7684 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
7685 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7687 if (! err.is_null ()) {
7688 std::ostringstream os;
7689 os << myRank <<
": Result of receive-size receive from Process "
7690 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
7691 "invalid() = " << Teuchos::OrdinalTraits<size_t>::invalid ()
7692 <<
". This should never happen, and suggests that its "
7693 "receive-size receive was never posted. "
7694 "Please report this bug to the Tpetra developers." << endl;
7701 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null ()) {
7703 if (! err.is_null ()) {
7704 std::ostringstream os;
7705 os << myRank <<
": Result of receive-size receive from Proc "
7706 << recvRank <<
" was " << printNumRows <<
" > 0, but "
7707 "recvDataBufs[" << circBufInd <<
"] is null. This should "
7708 "never happen. Please report this bug to the Tpetra "
7709 "developers." << endl;
7719 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd]) ();
7720 const size_t printStride = printNumRows;
7724 for (
size_t col = 0; col < numCols; ++col) {
7725 for (
size_t row = 0; row < printNumRows; ++row) {
7726 if (STS::isComplex) {
7727 out << STS::real (printData[row + col * printStride]) <<
" "
7728 << STS::imag (printData[row + col * printStride]) << endl;
7730 out << printData[row + col * printStride] << endl;
7735 else if (myRank == p) {
7738 std::ostringstream os;
7739 os << myRank <<
": Wait on my send-data send" << endl;
7742 wait<int> (comm, outArg (sendReqData));
7744 else if (myRank == p + 1) {
7747 std::ostringstream os;
7748 os << myRank <<
": Post send-data send: tag = " << dataTag
7752 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7755 std::ostringstream os;
7756 os << myRank <<
": Wait on my send-size send" << endl;
7759 wait<int> (comm, outArg (sendReqSize));
7761 else if (myRank == p + 2) {
7764 std::ostringstream os;
7765 os << myRank <<
": Post send-size send: size = "
7766 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7769 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
7774 reduceAll<int, int> (comm, REDUCE_MAX, lclErr, outArg (gblErr));
7775 TEUCHOS_TEST_FOR_EXCEPTION(
7776 gblErr == 1, std::runtime_error,
"Tpetra::MatrixMarket::writeDense "
7777 "experienced some kind of error and was unable to complete.");
7781 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
7795 const Teuchos::RCP<const multivector_type>& X,
7796 const std::string& matrixName,
7797 const std::string& matrixDescription,
7798 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7799 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7801 TEUCHOS_TEST_FOR_EXCEPTION(
7802 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7803 "writeDense: The input MultiVector X is null.");
7804 writeDense (out, *X, matrixName, matrixDescription, err, dbg);
7815 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7816 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7828 const Teuchos::RCP<const multivector_type>& X,
7829 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7830 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7832 TEUCHOS_TEST_FOR_EXCEPTION(
7833 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7834 "writeDense: The input MultiVector X is null.");
7860 Teuchos::RCP<Teuchos::FancyOStream> err =
7861 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));