42 #ifndef __MatrixMarket_Tpetra_hpp
43 #define __MatrixMarket_Tpetra_hpp
56 #include "Tpetra_Details_gathervPrint.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"
164 template<
class SparseMatrixType>
169 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
184 typedef typename SparseMatrixType::global_ordinal_type
206 typedef Teuchos::Comm<int> comm_type;
210 typedef Teuchos::RCP<const comm_type> comm_ptr;
211 typedef Teuchos::RCP<const map_type> map_ptr;
212 typedef Teuchos::RCP<node_type> node_ptr;
220 typedef Teuchos::ArrayRCP<int>::size_type size_type;
233 static Teuchos::RCP<const map_type>
234 makeRangeMap (
const Teuchos::RCP<const comm_type>& pComm,
235 const Teuchos::RCP<node_type>& pNode,
239 if (pNode.is_null ()) {
240 return rcp (
new map_type (static_cast<global_size_t> (numRows),
241 static_cast<global_ordinal_type> (0),
242 pComm, GloballyDistributed));
245 return rcp (
new map_type (static_cast<global_size_t> (numRows),
246 static_cast<global_ordinal_type> (0),
247 pComm, GloballyDistributed, pNode));
279 static Teuchos::RCP<const map_type>
280 makeRowMap (
const Teuchos::RCP<const map_type>& pRowMap,
281 const Teuchos::RCP<const comm_type>& pComm,
282 const Teuchos::RCP<node_type>& pNode,
287 if (pRowMap.is_null ()) {
288 if (pNode.is_null ()) {
289 return rcp (
new map_type (static_cast<global_size_t> (numRows),
290 static_cast<global_ordinal_type> (0),
291 pComm, GloballyDistributed));
294 return rcp (
new map_type (static_cast<global_size_t> (numRows),
295 static_cast<global_ordinal_type> (0),
296 pComm, GloballyDistributed, pNode));
300 TEUCHOS_TEST_FOR_EXCEPTION
301 (! pRowMap->isDistributed () && pComm->getSize () > 1,
302 std::invalid_argument,
"The specified row map is not distributed, "
303 "but the given communicator includes more than one process (in "
304 "fact, there are " << pComm->getSize () <<
" processes).");
305 TEUCHOS_TEST_FOR_EXCEPTION
306 (pRowMap->getComm () != pComm, std::invalid_argument,
307 "The specified row Map's communicator (pRowMap->getComm()) "
308 "differs from the given separately supplied communicator pComm.");
327 static Teuchos::RCP<const map_type>
328 makeDomainMap (
const Teuchos::RCP<const map_type>& pRangeMap,
337 if (numRows == numCols) {
340 return createUniformContigMapWithNode<LO,GO,NT> (numCols,
341 pRangeMap->getComm (),
342 pRangeMap->getNode ());
419 distribute (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
420 Teuchos::ArrayRCP<size_t>& myRowPtr,
421 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
422 Teuchos::ArrayRCP<scalar_type>& myValues,
423 const Teuchos::RCP<const map_type>& pRowMap,
424 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
425 Teuchos::ArrayRCP<size_t>& rowPtr,
426 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
427 Teuchos::ArrayRCP<scalar_type>& values,
428 const bool debug=
false)
431 using Teuchos::ArrayRCP;
432 using Teuchos::ArrayView;
435 using Teuchos::CommRequest;
438 using Teuchos::receive;
443 const bool extraDebug =
false;
444 RCP<const comm_type> pComm = pRowMap->getComm ();
445 const int numProcs = pComm->getSize ();
446 const int myRank = pComm->getRank ();
447 const int rootRank = 0;
454 ArrayView<const GO> myRows = pRowMap->getNodeElementList();
455 const size_type myNumRows = myRows.size();
456 TEUCHOS_TEST_FOR_EXCEPTION(static_cast<size_t>(myNumRows) !=
457 pRowMap->getNodeNumElements(),
459 "pRowMap->getNodeElementList().size() = "
461 <<
" != pRowMap->getNodeNumElements() = "
462 << pRowMap->getNodeNumElements() <<
". "
463 "Please report this bug to the Tpetra developers.");
464 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
466 "On Proc 0: numEntriesPerRow.size() = "
467 << numEntriesPerRow.size()
468 <<
" != pRowMap->getNodeElementList().size() = "
469 << myNumRows <<
". Please report this bug to the "
470 "Tpetra developers.");
474 myNumEntriesPerRow = arcp<size_t> (myNumRows);
476 if (myRank != rootRank) {
480 send (*pComm, myNumRows, rootRank);
481 if (myNumRows != 0) {
485 send (*pComm, static_cast<int> (myNumRows),
486 myRows.getRawPtr(), rootRank);
496 receive (*pComm, rootRank,
497 static_cast<int> (myNumRows),
498 myNumEntriesPerRow.getRawPtr());
503 std::accumulate (myNumEntriesPerRow.begin(),
504 myNumEntriesPerRow.end(), 0);
510 myColInd = arcp<GO> (myNumEntries);
511 myValues = arcp<scalar_type> (myNumEntries);
512 if (myNumEntries > 0) {
515 receive (*pComm, rootRank,
516 static_cast<int> (myNumEntries),
517 myColInd.getRawPtr());
518 receive (*pComm, rootRank,
519 static_cast<int> (myNumEntries),
520 myValues.getRawPtr());
526 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
530 for (size_type k = 0; k < myNumRows; ++k) {
531 const GO myCurRow = myRows[k];
533 myNumEntriesPerRow[k] = numEntriesInThisRow;
535 if (extraDebug && debug) {
536 cerr <<
"Proc " << pRowMap->getComm ()->getRank ()
537 <<
": myNumEntriesPerRow[0.." << (myNumRows-1) <<
"] = [";
538 for (size_type k = 0; k < myNumRows; ++k) {
539 cerr << myNumEntriesPerRow[k];
540 if (k < myNumRows-1) {
548 std::accumulate (myNumEntriesPerRow.begin(),
549 myNumEntriesPerRow.end(), 0);
551 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
552 << myNumEntries <<
" entries" << endl;
554 myColInd = arcp<GO> (myNumEntries);
555 myValues = arcp<scalar_type> (myNumEntries);
563 for (size_type k = 0; k < myNumRows;
564 myCurPos += myNumEntriesPerRow[k], ++k) {
566 const GO myRow = myRows[k];
567 const size_t curPos = rowPtr[myRow];
570 if (curNumEntries > 0) {
571 ArrayView<GO> colIndView = colInd (curPos, curNumEntries);
572 ArrayView<GO> myColIndView = myColInd (myCurPos, curNumEntries);
573 std::copy (colIndView.begin(), colIndView.end(),
574 myColIndView.begin());
576 ArrayView<scalar_type> valuesView =
577 values (curPos, curNumEntries);
578 ArrayView<scalar_type> myValuesView =
579 myValues (myCurPos, curNumEntries);
580 std::copy (valuesView.begin(), valuesView.end(),
581 myValuesView.begin());
586 for (
int p = 1; p < numProcs; ++p) {
588 cerr <<
"-- Proc 0: Processing proc " << p << endl;
591 size_type theirNumRows = 0;
596 receive (*pComm, p, &theirNumRows);
598 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
599 << theirNumRows <<
" rows" << endl;
601 if (theirNumRows != 0) {
606 ArrayRCP<GO> theirRows = arcp<GO> (theirNumRows);
607 receive (*pComm, p, as<int> (theirNumRows),
608 theirRows.getRawPtr ());
617 const global_size_t numRows = pRowMap->getGlobalNumElements ();
618 const GO indexBase = pRowMap->getIndexBase ();
619 bool theirRowsValid =
true;
620 for (size_type k = 0; k < theirNumRows; ++k) {
621 if (theirRows[k] < indexBase ||
622 as<global_size_t> (theirRows[k] - indexBase) >= numRows) {
623 theirRowsValid =
false;
626 if (! theirRowsValid) {
627 TEUCHOS_TEST_FOR_EXCEPTION(
628 ! theirRowsValid, std::logic_error,
629 "Proc " << p <<
" has at least one invalid row index. "
630 "Here are all of them: " <<
631 Teuchos::toString (theirRows ()) <<
". Valid row index "
632 "range (zero-based): [0, " << (numRows - 1) <<
"].");
647 ArrayRCP<size_t> theirNumEntriesPerRow;
648 theirNumEntriesPerRow = arcp<size_t> (theirNumRows);
649 for (size_type k = 0; k < theirNumRows; ++k) {
650 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
657 send (*pComm, static_cast<int> (theirNumRows),
658 theirNumEntriesPerRow.getRawPtr(), p);
662 std::accumulate (theirNumEntriesPerRow.begin(),
663 theirNumEntriesPerRow.end(), 0);
666 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
667 << theirNumEntries <<
" entries" << endl;
672 if (theirNumEntries == 0) {
681 ArrayRCP<GO> theirColInd (theirNumEntries);
682 ArrayRCP<scalar_type> theirValues (theirNumEntries);
690 for (size_type k = 0; k < theirNumRows;
691 theirCurPos += theirNumEntriesPerRow[k], k++) {
693 const GO theirRow = theirRows[k];
699 if (curNumEntries > 0) {
700 ArrayView<GO> colIndView =
701 colInd (curPos, curNumEntries);
702 ArrayView<GO> theirColIndView =
703 theirColInd (theirCurPos, curNumEntries);
704 std::copy (colIndView.begin(), colIndView.end(),
705 theirColIndView.begin());
707 ArrayView<scalar_type> valuesView =
708 values (curPos, curNumEntries);
709 ArrayView<scalar_type> theirValuesView =
710 theirValues (theirCurPos, curNumEntries);
711 std::copy (valuesView.begin(), valuesView.end(),
712 theirValuesView.begin());
719 send (*pComm, static_cast<int> (theirNumEntries),
720 theirColInd.getRawPtr(), p);
721 send (*pComm, static_cast<int> (theirNumEntries),
722 theirValues.getRawPtr(), p);
725 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
733 numEntriesPerRow =
null;
738 if (debug && myRank == 0) {
739 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
747 myRowPtr = arcp<size_t> (myNumRows+1);
749 for (size_type k = 1; k < myNumRows+1; ++k) {
750 myRowPtr[k] = myRowPtr[k-1] + myNumEntriesPerRow[k-1];
752 if (extraDebug && debug) {
753 cerr <<
"Proc " << Teuchos::rank (*(pRowMap->getComm()))
754 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
755 for (size_type k = 0; k < myNumRows+1; ++k) {
761 cerr <<
"]" << endl << endl;
764 if (debug && myRank == 0) {
765 cerr <<
"-- Proc 0: Done with distribute" << endl;
782 static Teuchos::RCP<sparse_matrix_type>
783 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
784 Teuchos::ArrayRCP<size_t>& myRowPtr,
785 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
786 Teuchos::ArrayRCP<scalar_type>& myValues,
787 const Teuchos::RCP<const map_type>& pRowMap,
788 const Teuchos::RCP<const map_type>& pRangeMap,
789 const Teuchos::RCP<const map_type>& pDomainMap,
790 const bool callFillComplete =
true)
792 using Teuchos::ArrayView;
806 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
807 "makeMatrix: myRowPtr array is null. "
808 "Please report this bug to the Tpetra developers.");
809 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
810 "makeMatrix: domain map is null. "
811 "Please report this bug to the Tpetra developers.");
812 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
813 "makeMatrix: range map is null. "
814 "Please report this bug to the Tpetra developers.");
815 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
816 "makeMatrix: row map is null. "
817 "Please report this bug to the Tpetra developers.");
824 RCP<sparse_matrix_type> A =
830 ArrayView<const GO> myRows = pRowMap->getNodeElementList ();
831 const size_type myNumRows = myRows.size ();
834 const GO indexBase = pRowMap->getIndexBase ();
835 for (size_type i = 0; i < myNumRows; ++i) {
836 const size_type myCurPos = myRowPtr[i];
838 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
839 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
842 for (size_type k = 0; k < curNumEntries; ++k) {
843 curColInd[k] += indexBase;
846 if (curNumEntries > 0) {
847 A->insertGlobalValues (myRows[i], curColInd, curValues);
854 myNumEntriesPerRow =
null;
859 if (callFillComplete) {
860 A->fillComplete (pDomainMap, pRangeMap);
870 static Teuchos::RCP<sparse_matrix_type>
871 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
872 Teuchos::ArrayRCP<size_t>& myRowPtr,
873 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
874 Teuchos::ArrayRCP<scalar_type>& myValues,
875 const Teuchos::RCP<const map_type>& pRowMap,
876 const Teuchos::RCP<const map_type>& pRangeMap,
877 const Teuchos::RCP<const map_type>& pDomainMap,
878 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
879 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams)
881 using Teuchos::ArrayView;
895 TEUCHOS_TEST_FOR_EXCEPTION(
896 myRowPtr.is_null(), std::logic_error,
897 "makeMatrix: myRowPtr array is null. "
898 "Please report this bug to the Tpetra developers.");
899 TEUCHOS_TEST_FOR_EXCEPTION(
900 pDomainMap.is_null(), std::logic_error,
901 "makeMatrix: domain map is null. "
902 "Please report this bug to the Tpetra developers.");
903 TEUCHOS_TEST_FOR_EXCEPTION(
904 pRangeMap.is_null(), std::logic_error,
905 "makeMatrix: range map is null. "
906 "Please report this bug to the Tpetra developers.");
907 TEUCHOS_TEST_FOR_EXCEPTION(
908 pRowMap.is_null(), std::logic_error,
909 "makeMatrix: row map is null. "
910 "Please report this bug to the Tpetra developers.");
917 RCP<sparse_matrix_type> A =
923 ArrayView<const GO> myRows = pRowMap->getNodeElementList();
924 const size_type myNumRows = myRows.size();
927 const GO indexBase = pRowMap->getIndexBase ();
928 for (size_type i = 0; i < myNumRows; ++i) {
929 const size_type myCurPos = myRowPtr[i];
931 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
932 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
935 for (size_type k = 0; k < curNumEntries; ++k) {
936 curColInd[k] += indexBase;
938 if (curNumEntries > 0) {
939 A->insertGlobalValues (myRows[i], curColInd, curValues);
946 myNumEntriesPerRow =
null;
951 A->fillComplete (pDomainMap, pRangeMap, fillCompleteParams);
959 static Teuchos::RCP<sparse_matrix_type>
960 makeMatrix (Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
961 Teuchos::ArrayRCP<size_t>& myRowPtr,
962 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
963 Teuchos::ArrayRCP<scalar_type>& myValues,
964 const Teuchos::RCP<const map_type>& rowMap,
965 Teuchos::RCP<const map_type>& colMap,
966 const Teuchos::RCP<const map_type>& domainMap,
967 const Teuchos::RCP<const map_type>& rangeMap,
968 const bool callFillComplete =
true)
970 using Teuchos::ArrayView;
976 typedef typename ArrayView<const GO>::size_type size_type;
982 RCP<sparse_matrix_type> A;
983 if (colMap.is_null ()) {
991 ArrayView<const GO> myRows = rowMap->getNodeElementList ();
992 const size_type myNumRows = myRows.size ();
995 const GO indexBase = rowMap->getIndexBase ();
996 for (size_type i = 0; i < myNumRows; ++i) {
997 const size_type myCurPos = myRowPtr[i];
998 const size_type curNumEntries = as<size_type> (myNumEntriesPerRow[i]);
999 ArrayView<GO> curColInd = myColInd.view (myCurPos, curNumEntries);
1000 ArrayView<scalar_type> curValues = myValues.view (myCurPos, curNumEntries);
1003 for (size_type k = 0; k < curNumEntries; ++k) {
1004 curColInd[k] += indexBase;
1006 if (curNumEntries > 0) {
1007 A->insertGlobalValues (myRows[i], curColInd, curValues);
1014 myNumEntriesPerRow =
null;
1019 if (callFillComplete) {
1020 A->fillComplete (domainMap, rangeMap);
1021 if (colMap.is_null ()) {
1022 colMap = A->getColMap ();
1046 static Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
1047 readBanner (std::istream& in,
1049 const bool tolerant=
false,
1050 const bool debug=
false,
1051 const bool isGraph=
false)
1053 using Teuchos::MatrixMarket::Banner;
1058 typedef Teuchos::ScalarTraits<scalar_type> STS;
1060 RCP<Banner> pBanner;
1064 const bool readFailed = ! getline(in, line);
1065 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
1066 "Failed to get Matrix Market banner line from input.");
1073 pBanner = rcp (
new Banner (line, tolerant));
1074 }
catch (std::exception& e) {
1075 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1076 "Matrix Market banner line contains syntax error(s): "
1079 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
1080 std::invalid_argument,
"The Matrix Market file does not contain "
1081 "matrix data. Its Banner (first) line says that its object type is \""
1082 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
1086 TEUCHOS_TEST_FOR_EXCEPTION(
1087 ! STS::isComplex && pBanner->dataType() ==
"complex",
1088 std::invalid_argument,
1089 "The Matrix Market file contains complex-valued data, but you are "
1090 "trying to read it into a matrix containing entries of the real-"
1091 "valued Scalar type \""
1092 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
1093 TEUCHOS_TEST_FOR_EXCEPTION(
1095 pBanner->dataType() !=
"real" &&
1096 pBanner->dataType() !=
"complex" &&
1097 pBanner->dataType() !=
"integer",
1098 std::invalid_argument,
1099 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
1100 "Matrix Market file may not contain a \"pattern\" matrix. A "
1101 "pattern matrix is really just a graph with no weights. It "
1102 "should be stored in a CrsGraph, not a CrsMatrix.");
1104 TEUCHOS_TEST_FOR_EXCEPTION(
1106 pBanner->dataType() !=
"pattern",
1107 std::invalid_argument,
1108 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
1109 "Matrix Market file must contain a \"pattern\" matrix.");
1136 static Teuchos::Tuple<global_ordinal_type, 3>
1137 readCoordDims (std::istream& in,
1139 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1140 const Teuchos::RCP<const comm_type>& pComm,
1141 const bool tolerant =
false,
1142 const bool debug =
false)
1144 using Teuchos::MatrixMarket::readCoordinateDimensions;
1145 using Teuchos::Tuple;
1150 Tuple<global_ordinal_type, 3> dims;
1156 bool success =
false;
1157 if (pComm->getRank() == 0) {
1158 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
1159 std::invalid_argument,
"The Tpetra::CrsMatrix Matrix Market reader "
1160 "only accepts \"coordinate\" (sparse) matrix data.");
1164 success = readCoordinateDimensions (in, numRows, numCols,
1165 numNonzeros, lineNumber,
1171 dims[2] = numNonzeros;
1179 int the_success = success ? 1 : 0;
1180 Teuchos::broadcast (*pComm, 0, &the_success);
1181 success = (the_success == 1);
1186 Teuchos::broadcast (*pComm, 0, dims);
1194 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
1195 "Error reading Matrix Market sparse matrix: failed to read "
1196 "coordinate matrix dimensions.");
1211 typedef Teuchos::MatrixMarket::SymmetrizingAdder<Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type> > adder_type;
1213 typedef Teuchos::MatrixMarket::SymmetrizingGraphAdder<Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> > graph_adder_type;
1240 static Teuchos::RCP<adder_type>
1241 makeAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1242 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1243 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1244 const bool tolerant=
false,
1245 const bool debug=
false)
1247 if (pComm->getRank () == 0) {
1248 typedef Teuchos::MatrixMarket::Raw::Adder<
scalar_type,
1251 Teuchos::RCP<raw_adder_type> pRaw =
1252 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1254 return Teuchos::rcp (
new adder_type (pRaw, pBanner->symmType ()));
1257 return Teuchos::null;
1286 static Teuchos::RCP<graph_adder_type>
1287 makeGraphAdder (
const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1288 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
1289 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
1290 const bool tolerant=
false,
1291 const bool debug=
false)
1293 if (pComm->getRank () == 0) {
1294 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
1295 Teuchos::RCP<raw_adder_type> pRaw =
1296 Teuchos::rcp (
new raw_adder_type (dims[0], dims[1], dims[2],
1298 return Teuchos::rcp (
new graph_adder_type (pRaw, pBanner->symmType ()));
1301 return Teuchos::null;
1306 static Teuchos::RCP<sparse_graph_type>
1307 readSparseGraphHelper (std::istream& in,
1308 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1309 const Teuchos::RCP<node_type>& pNode,
1310 const Teuchos::RCP<const map_type>& rowMap,
1311 Teuchos::RCP<const map_type>& colMap,
1312 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1313 const bool tolerant,
1316 using Teuchos::MatrixMarket::Banner;
1319 using Teuchos::Tuple;
1323 const int myRank = pComm->getRank ();
1324 const int rootRank = 0;
1329 size_t lineNumber = 1;
1331 if (debug && myRank == rootRank) {
1332 cerr <<
"Matrix Market reader: readGraph:" << endl
1333 <<
"-- Reading banner line" << endl;
1342 RCP<const Banner> pBanner;
1348 int bannerIsCorrect = 1;
1349 std::ostringstream errMsg;
1351 if (myRank == rootRank) {
1354 pBanner = readBanner (in, lineNumber, tolerant, debug,
true);
1356 catch (std::exception& e) {
1357 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1358 "threw an exception: " << e.what();
1359 bannerIsCorrect = 0;
1362 if (bannerIsCorrect) {
1367 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
1368 bannerIsCorrect = 0;
1369 errMsg <<
"The Matrix Market input file must contain a "
1370 "\"coordinate\"-format sparse graph in order to create a "
1371 "Tpetra::CrsGraph object from it, but the file's matrix "
1372 "type is \"" << pBanner->matrixType() <<
"\" instead.";
1377 if (tolerant && pBanner->matrixType() ==
"array") {
1378 bannerIsCorrect = 0;
1379 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1380 "format sparse graph in order to create a Tpetra::CrsGraph "
1381 "object from it, but the file's matrix type is \"array\" "
1382 "instead. That probably means the file contains dense matrix "
1389 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
1396 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
1397 std::invalid_argument, errMsg.str ());
1399 if (debug && myRank == rootRank) {
1400 cerr <<
"-- Reading dimensions line" << endl;
1408 Tuple<global_ordinal_type, 3> dims =
1409 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
1411 if (debug && myRank == rootRank) {
1412 cerr <<
"-- Making Adder for collecting graph data" << endl;
1419 RCP<graph_adder_type> pAdder =
1420 makeGraphAdder (pComm, pBanner, dims, tolerant, debug);
1422 if (debug && myRank == rootRank) {
1423 cerr <<
"-- Reading graph data" << endl;
1433 int readSuccess = 1;
1434 std::ostringstream errMsg;
1435 if (myRank == rootRank) {
1438 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
1440 reader_type reader (pAdder);
1443 std::pair<bool, std::vector<size_t> > results =
1444 reader.read (in, lineNumber, tolerant, debug);
1445 readSuccess = results.first ? 1 : 0;
1447 catch (std::exception& e) {
1452 broadcast (*pComm, rootRank, ptr (&readSuccess));
1461 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1462 "Failed to read the Matrix Market sparse graph file: "
1466 if (debug && myRank == rootRank) {
1467 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1480 if (debug && myRank == rootRank) {
1481 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1483 <<
"----- Dimensions before: "
1484 << dims[0] <<
" x " << dims[1]
1488 Tuple<global_ordinal_type, 2> updatedDims;
1489 if (myRank == rootRank) {
1496 std::max (dims[0], pAdder->getAdder()->numRows());
1497 updatedDims[1] = pAdder->getAdder()->numCols();
1499 broadcast (*pComm, rootRank, updatedDims);
1500 dims[0] = updatedDims[0];
1501 dims[1] = updatedDims[1];
1502 if (debug && myRank == rootRank) {
1503 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1517 if (myRank == rootRank) {
1524 if (dims[0] < pAdder->getAdder ()->numRows ()) {
1528 broadcast (*pComm, 0, ptr (&dimsMatch));
1529 if (dimsMatch == 0) {
1536 Tuple<global_ordinal_type, 2> addersDims;
1537 if (myRank == rootRank) {
1538 addersDims[0] = pAdder->getAdder()->numRows();
1539 addersDims[1] = pAdder->getAdder()->numCols();
1541 broadcast (*pComm, 0, addersDims);
1542 TEUCHOS_TEST_FOR_EXCEPTION(
1543 dimsMatch == 0, std::runtime_error,
1544 "The graph metadata says that the graph is " << dims[0] <<
" x "
1545 << dims[1] <<
", but the actual data says that the graph is "
1546 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1547 "data includes more rows than reported in the metadata. This "
1548 "is not allowed when parsing in strict mode. Parse the graph in "
1549 "tolerant mode to ignore the metadata when it disagrees with the "
1555 RCP<map_type> proc0Map;
1557 if(Teuchos::is_null(rowMap)) {
1561 indexBase = rowMap->getIndexBase();
1563 if(myRank == rootRank) {
1564 proc0Map = rcp(
new map_type(dims[0],dims[0],indexBase,pComm,pNode));
1567 proc0Map = rcp(
new map_type(dims[0],0,indexBase,pComm,pNode));
1571 RCP<sparse_graph_type> proc0Graph =
1573 if(myRank == rootRank) {
1574 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1577 const std::vector<element_type>& entries =
1578 pAdder->getAdder()->getEntries();
1581 for(
size_t curPos=0; curPos<entries.size(); curPos++) {
1582 const element_type& curEntry = entries[curPos];
1585 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol,1);
1586 proc0Graph->insertGlobalIndices(curRow,colView);
1589 proc0Graph->fillComplete();
1591 RCP<sparse_graph_type> distGraph;
1592 if(Teuchos::is_null(rowMap))
1595 RCP<map_type> distMap =
1596 rcp(
new map_type(dims[0],0,pComm,GloballyDistributed,pNode));
1602 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1603 import_type importer (proc0Map, distMap);
1606 distGraph->doImport(*proc0Graph,importer,
INSERT);
1612 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1613 import_type importer (proc0Map, rowMap);
1616 distGraph->doImport(*proc0Graph,importer,
INSERT);
1646 static Teuchos::RCP<sparse_graph_type>
1648 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1649 const bool callFillComplete=
true,
1650 const bool tolerant=
false,
1651 const bool debug=
false)
1655 callFillComplete, tolerant, debug);
1664 static Teuchos::RCP<sparse_graph_type>
1666 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm,
1667 const Teuchos::RCP<node_type>& node,
1668 const bool callFillComplete=
true,
1669 const bool tolerant=
false,
1670 const bool debug=
false)
1672 using Teuchos::broadcast;
1673 using Teuchos::outArg;
1681 if (comm->getRank () == 0) {
1683 in.open (filename.c_str ());
1690 broadcast<int, int> (*comm, 0, outArg (opened));
1691 TEUCHOS_TEST_FOR_EXCEPTION
1692 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1693 "Failed to open file \"" << filename <<
"\" on Process 0.");
1729 static Teuchos::RCP<sparse_graph_type>
1731 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1732 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1733 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1734 const bool tolerant=
false,
1735 const bool debug=
false)
1739 constructorParams, fillCompleteParams,
1749 static Teuchos::RCP<sparse_graph_type>
1751 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1752 const Teuchos::RCP<node_type>& pNode,
1753 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1754 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1755 const bool tolerant=
false,
1756 const bool debug=
false)
1758 using Teuchos::broadcast;
1759 using Teuchos::outArg;
1767 if (pComm->getRank () == 0) {
1769 in.open (filename.c_str ());
1776 broadcast<int, int> (*pComm, 0, outArg (opened));
1777 TEUCHOS_TEST_FOR_EXCEPTION
1778 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1779 "Failed to open file \"" << filename <<
"\" on Process 0.");
1780 if (pComm->getRank () == 0) {
1781 in.open (filename.c_str ());
1784 fillCompleteParams, tolerant, debug);
1827 static Teuchos::RCP<sparse_graph_type>
1829 const Teuchos::RCP<const map_type>& rowMap,
1830 Teuchos::RCP<const map_type>& colMap,
1831 const Teuchos::RCP<const map_type>& domainMap,
1832 const Teuchos::RCP<const map_type>& rangeMap,
1833 const bool callFillComplete=
true,
1834 const bool tolerant=
false,
1835 const bool debug=
false)
1837 using Teuchos::broadcast;
1838 using Teuchos::Comm;
1839 using Teuchos::outArg;
1842 TEUCHOS_TEST_FOR_EXCEPTION
1843 (rowMap.is_null (), std::invalid_argument,
1844 "Input rowMap must be nonnull.");
1845 RCP<const Comm<int> > comm = rowMap->getComm ();
1846 if (comm.is_null ()) {
1849 return Teuchos::null;
1858 if (comm->getRank () == 0) {
1860 in.open (filename.c_str ());
1867 broadcast<int, int> (*comm, 0, outArg (opened));
1868 TEUCHOS_TEST_FOR_EXCEPTION
1869 (opened == 0, std::runtime_error,
"readSparseGraphFile: "
1870 "Failed to open file \"" << filename <<
"\" on Process 0.");
1872 callFillComplete, tolerant, debug);
1900 static Teuchos::RCP<sparse_graph_type>
1902 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1903 const bool callFillComplete=
true,
1904 const bool tolerant=
false,
1905 const bool debug=
false)
1913 static Teuchos::RCP<sparse_graph_type>
1915 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1916 const Teuchos::RCP<node_type>& pNode,
1917 const bool callFillComplete=
true,
1918 const bool tolerant=
false,
1919 const bool debug=
false)
1921 Teuchos::RCP<const map_type> fakeRowMap;
1922 Teuchos::RCP<const map_type> fakeColMap;
1923 Teuchos::RCP<Teuchos::ParameterList> fakeCtorParams;
1925 Teuchos::RCP<sparse_graph_type> graph =
1926 readSparseGraphHelper (in, pComm, pNode, fakeRowMap, fakeColMap,
1927 fakeCtorParams, tolerant, debug);
1928 if (callFillComplete) {
1929 graph->fillComplete ();
1963 static Teuchos::RCP<sparse_graph_type>
1965 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1966 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1967 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1968 const bool tolerant=
false,
1969 const bool debug=
false)
1973 fillCompleteParams, tolerant, debug);
1977 static Teuchos::RCP<sparse_graph_type>
1979 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
1980 const Teuchos::RCP<node_type>& pNode,
1981 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1982 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1983 const bool tolerant=
false,
1984 const bool debug=
false)
1986 Teuchos::RCP<const map_type> fakeRowMap;
1987 Teuchos::RCP<const map_type> fakeColMap;
1988 Teuchos::RCP<sparse_graph_type> graph =
1989 readSparseGraphHelper (in, pComm, pNode, fakeRowMap, fakeColMap,
1990 constructorParams, tolerant, debug);
1991 graph->fillComplete (fillCompleteParams);
2035 static Teuchos::RCP<sparse_graph_type>
2037 const Teuchos::RCP<const map_type>& rowMap,
2038 Teuchos::RCP<const map_type>& colMap,
2039 const Teuchos::RCP<const map_type>& domainMap,
2040 const Teuchos::RCP<const map_type>& rangeMap,
2041 const bool callFillComplete=
true,
2042 const bool tolerant=
false,
2043 const bool debug=
false)
2045 Teuchos::RCP<sparse_graph_type> graph =
2046 readSparseGraphHelper (in, rowMap->getComm (), rowMap->getNode (),
2047 rowMap, colMap, Teuchos::null, tolerant,
2049 if (callFillComplete) {
2050 graph->fillComplete (domainMap, rangeMap);
2078 static Teuchos::RCP<sparse_matrix_type>
2080 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2081 const bool callFillComplete=
true,
2082 const bool tolerant=
false,
2083 const bool debug=
false)
2085 return readSparseFile (filename, pComm, Teuchos::null, callFillComplete, tolerant, debug);
2089 static Teuchos::RCP<sparse_matrix_type>
2091 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2092 const Teuchos::RCP<node_type>& pNode,
2093 const bool callFillComplete=
true,
2094 const bool tolerant=
false,
2095 const bool debug=
false)
2097 const int myRank = pComm->getRank ();
2102 in.open (filename.c_str ());
2110 return readSparse (in, pComm, pNode, callFillComplete, tolerant, debug);
2144 static Teuchos::RCP<sparse_matrix_type>
2146 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2147 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2148 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2149 const bool tolerant=
false,
2150 const bool debug=
false)
2153 constructorParams, fillCompleteParams,
2158 static Teuchos::RCP<sparse_matrix_type>
2160 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2161 const Teuchos::RCP<node_type>& pNode,
2162 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2163 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2164 const bool tolerant=
false,
2165 const bool debug=
false)
2168 if (pComm->getRank () == 0) {
2169 in.open (filename.c_str ());
2171 return readSparse (in, pComm, pNode, constructorParams,
2172 fillCompleteParams, tolerant, debug);
2212 static Teuchos::RCP<sparse_matrix_type>
2214 const Teuchos::RCP<const map_type>& rowMap,
2215 Teuchos::RCP<const map_type>& colMap,
2216 const Teuchos::RCP<const map_type>& domainMap,
2217 const Teuchos::RCP<const map_type>& rangeMap,
2218 const bool callFillComplete=
true,
2219 const bool tolerant=
false,
2220 const bool debug=
false)
2222 using Teuchos::broadcast;
2223 using Teuchos::Comm;
2224 using Teuchos::outArg;
2227 TEUCHOS_TEST_FOR_EXCEPTION(
2228 rowMap.is_null (), std::invalid_argument,
2229 "Row Map must be nonnull.");
2231 RCP<const Comm<int> > comm = rowMap->getComm ();
2232 const int myRank = comm->getRank ();
2242 in.open (filename.c_str ());
2249 broadcast<int, int> (*comm, 0, outArg (opened));
2250 TEUCHOS_TEST_FOR_EXCEPTION(
2251 opened == 0, std::runtime_error,
2252 "readSparseFile: Failed to open file \"" << filename <<
"\" on "
2254 return readSparse (in, rowMap, colMap, domainMap, rangeMap,
2255 callFillComplete, tolerant, debug);
2283 static Teuchos::RCP<sparse_matrix_type>
2285 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2286 const bool callFillComplete=
true,
2287 const bool tolerant=
false,
2288 const bool debug=
false)
2290 return readSparse (in, pComm, Teuchos::null, callFillComplete, tolerant, debug);
2294 static Teuchos::RCP<sparse_matrix_type>
2296 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2297 const Teuchos::RCP<node_type>& pNode,
2298 const bool callFillComplete=
true,
2299 const bool tolerant=
false,
2300 const bool debug=
false)
2302 using Teuchos::MatrixMarket::Banner;
2303 using Teuchos::arcp;
2304 using Teuchos::ArrayRCP;
2305 using Teuchos::broadcast;
2306 using Teuchos::null;
2309 using Teuchos::REDUCE_MAX;
2310 using Teuchos::reduceAll;
2311 using Teuchos::Tuple;
2314 typedef Teuchos::ScalarTraits<scalar_type> STS;
2316 const bool extraDebug =
false;
2317 const int myRank = pComm->getRank ();
2318 const int rootRank = 0;
2323 size_t lineNumber = 1;
2325 if (debug && myRank == rootRank) {
2326 cerr <<
"Matrix Market reader: readSparse:" << endl
2327 <<
"-- Reading banner line" << endl;
2336 RCP<const Banner> pBanner;
2342 int bannerIsCorrect = 1;
2343 std::ostringstream errMsg;
2345 if (myRank == rootRank) {
2348 pBanner = readBanner (in, lineNumber, tolerant, debug);
2350 catch (std::exception& e) {
2351 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2352 "threw an exception: " << e.what();
2353 bannerIsCorrect = 0;
2356 if (bannerIsCorrect) {
2361 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2362 bannerIsCorrect = 0;
2363 errMsg <<
"The Matrix Market input file must contain a "
2364 "\"coordinate\"-format sparse matrix in order to create a "
2365 "Tpetra::CrsMatrix object from it, but the file's matrix "
2366 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2371 if (tolerant && pBanner->matrixType() ==
"array") {
2372 bannerIsCorrect = 0;
2373 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2374 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2375 "object from it, but the file's matrix type is \"array\" "
2376 "instead. That probably means the file contains dense matrix "
2383 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2390 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2391 std::invalid_argument, errMsg.str ());
2393 if (debug && myRank == rootRank) {
2394 cerr <<
"-- Reading dimensions line" << endl;
2402 Tuple<global_ordinal_type, 3> dims =
2403 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2405 if (debug && myRank == rootRank) {
2406 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2411 RCP<adder_type> pAdder =
2412 makeAdder (pComm, pBanner, dims, tolerant, debug);
2414 if (debug && myRank == rootRank) {
2415 cerr <<
"-- Reading matrix data" << endl;
2425 int readSuccess = 1;
2426 std::ostringstream errMsg;
2427 if (myRank == rootRank) {
2430 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2432 reader_type reader (pAdder);
2435 std::pair<bool, std::vector<size_t> > results =
2436 reader.read (in, lineNumber, tolerant, debug);
2437 readSuccess = results.first ? 1 : 0;
2439 catch (std::exception& e) {
2444 broadcast (*pComm, rootRank, ptr (&readSuccess));
2453 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2454 "Failed to read the Matrix Market sparse matrix file: "
2458 if (debug && myRank == rootRank) {
2459 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2472 if (debug && myRank == rootRank) {
2473 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2475 <<
"----- Dimensions before: "
2476 << dims[0] <<
" x " << dims[1]
2480 Tuple<global_ordinal_type, 2> updatedDims;
2481 if (myRank == rootRank) {
2488 std::max (dims[0], pAdder->getAdder()->numRows());
2489 updatedDims[1] = pAdder->getAdder()->numCols();
2491 broadcast (*pComm, rootRank, updatedDims);
2492 dims[0] = updatedDims[0];
2493 dims[1] = updatedDims[1];
2494 if (debug && myRank == rootRank) {
2495 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2509 if (myRank == rootRank) {
2516 if (dims[0] < pAdder->getAdder ()->numRows ()) {
2520 broadcast (*pComm, 0, ptr (&dimsMatch));
2521 if (dimsMatch == 0) {
2528 Tuple<global_ordinal_type, 2> addersDims;
2529 if (myRank == rootRank) {
2530 addersDims[0] = pAdder->getAdder()->numRows();
2531 addersDims[1] = pAdder->getAdder()->numCols();
2533 broadcast (*pComm, 0, addersDims);
2534 TEUCHOS_TEST_FOR_EXCEPTION(
2535 dimsMatch == 0, std::runtime_error,
2536 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2537 << dims[1] <<
", but the actual data says that the matrix is "
2538 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2539 "data includes more rows than reported in the metadata. This "
2540 "is not allowed when parsing in strict mode. Parse the matrix in "
2541 "tolerant mode to ignore the metadata when it disagrees with the "
2546 if (debug && myRank == rootRank) {
2547 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2559 ArrayRCP<size_t> numEntriesPerRow;
2560 ArrayRCP<size_t> rowPtr;
2561 ArrayRCP<global_ordinal_type> colInd;
2562 ArrayRCP<scalar_type> values;
2567 int mergeAndConvertSucceeded = 1;
2568 std::ostringstream errMsg;
2570 if (myRank == rootRank) {
2572 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2582 const size_type numRows = dims[0];
2585 pAdder->getAdder()->merge ();
2588 const std::vector<element_type>& entries =
2589 pAdder->getAdder()->getEntries();
2592 const size_t numEntries = (size_t)entries.size();
2595 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2596 <<
" rows and numEntries=" << numEntries
2597 <<
" entries." << endl;
2603 numEntriesPerRow = arcp<size_t> (numRows);
2604 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2605 rowPtr = arcp<size_t> (numRows+1);
2606 std::fill (rowPtr.begin(), rowPtr.end(), 0);
2607 colInd = arcp<global_ordinal_type> (numEntries);
2608 values = arcp<scalar_type> (numEntries);
2615 for (curPos = 0; curPos < numEntries; ++curPos) {
2616 const element_type& curEntry = entries[curPos];
2618 TEUCHOS_TEST_FOR_EXCEPTION(
2619 curRow < prvRow, std::logic_error,
2620 "Row indices are out of order, even though they are supposed "
2621 "to be sorted. curRow = " << curRow <<
", prvRow = "
2622 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2623 "this bug to the Tpetra developers.");
2624 if (curRow > prvRow) {
2630 numEntriesPerRow[curRow]++;
2631 colInd[curPos] = curEntry.colIndex();
2632 values[curPos] = curEntry.value();
2637 rowPtr[numRows] = numEntries;
2639 catch (std::exception& e) {
2640 mergeAndConvertSucceeded = 0;
2641 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2642 "CSR format: " << e.what();
2645 if (debug && mergeAndConvertSucceeded) {
2647 const size_type numRows = dims[0];
2648 const size_type maxToDisplay = 100;
2650 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2651 << (numEntriesPerRow.size()-1) <<
"] ";
2652 if (numRows > maxToDisplay) {
2653 cerr <<
"(only showing first and last few entries) ";
2657 if (numRows > maxToDisplay) {
2658 for (size_type k = 0; k < 2; ++k) {
2659 cerr << numEntriesPerRow[k] <<
" ";
2662 for (size_type k = numRows-2; k < numRows-1; ++k) {
2663 cerr << numEntriesPerRow[k] <<
" ";
2667 for (size_type k = 0; k < numRows-1; ++k) {
2668 cerr << numEntriesPerRow[k] <<
" ";
2671 cerr << numEntriesPerRow[numRows-1];
2673 cerr <<
"]" << endl;
2675 cerr <<
"----- Proc 0: rowPtr ";
2676 if (numRows > maxToDisplay) {
2677 cerr <<
"(only showing first and last few entries) ";
2680 if (numRows > maxToDisplay) {
2681 for (size_type k = 0; k < 2; ++k) {
2682 cerr << rowPtr[k] <<
" ";
2685 for (size_type k = numRows-2; k < numRows; ++k) {
2686 cerr << rowPtr[k] <<
" ";
2690 for (size_type k = 0; k < numRows; ++k) {
2691 cerr << rowPtr[k] <<
" ";
2694 cerr << rowPtr[numRows] <<
"]" << endl;
2705 if (debug && myRank == rootRank) {
2706 cerr <<
"-- Making range, domain, and row maps" << endl;
2713 RCP<const map_type> pRangeMap = makeRangeMap (pComm, pNode, dims[0]);
2714 RCP<const map_type> pDomainMap =
2715 makeDomainMap (pRangeMap, dims[0], dims[1]);
2716 RCP<const map_type> pRowMap = makeRowMap (
null, pComm, pNode, dims[0]);
2718 if (debug && myRank == rootRank) {
2719 cerr <<
"-- Distributing the matrix data" << endl;
2733 ArrayRCP<size_t> myNumEntriesPerRow;
2734 ArrayRCP<size_t> myRowPtr;
2735 ArrayRCP<global_ordinal_type> myColInd;
2736 ArrayRCP<scalar_type> myValues;
2738 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
2739 numEntriesPerRow, rowPtr, colInd, values, debug);
2741 if (debug && myRank == rootRank) {
2742 cerr <<
"-- Inserting matrix entries on each processor";
2743 if (callFillComplete) {
2744 cerr <<
" and calling fillComplete()";
2755 RCP<sparse_matrix_type> pMatrix =
2756 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
2757 pRowMap, pRangeMap, pDomainMap, callFillComplete);
2762 int localIsNull = pMatrix.is_null () ? 1 : 0;
2763 int globalIsNull = 0;
2764 reduceAll (*pComm, REDUCE_MAX, localIsNull, ptr (&globalIsNull));
2765 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
2766 "Reader::makeMatrix() returned a null pointer on at least one "
2767 "process. Please report this bug to the Tpetra developers.");
2770 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
2771 "Reader::makeMatrix() returned a null pointer. "
2772 "Please report this bug to the Tpetra developers.");
2784 if (callFillComplete) {
2785 const int numProcs = pComm->getSize ();
2787 if (extraDebug && debug) {
2789 pRangeMap->getGlobalNumElements ();
2791 pDomainMap->getGlobalNumElements ();
2792 if (myRank == rootRank) {
2793 cerr <<
"-- Matrix is "
2794 << globalNumRows <<
" x " << globalNumCols
2795 <<
" with " << pMatrix->getGlobalNumEntries()
2796 <<
" entries, and index base "
2797 << pMatrix->getIndexBase() <<
"." << endl;
2800 for (
int p = 0; p < numProcs; ++p) {
2802 cerr <<
"-- Proc " << p <<
" owns "
2803 << pMatrix->getNodeNumCols() <<
" columns, and "
2804 << pMatrix->getNodeNumEntries() <<
" entries." << endl;
2811 if (debug && myRank == rootRank) {
2812 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2847 static Teuchos::RCP<sparse_matrix_type>
2849 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2850 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2851 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2852 const bool tolerant=
false,
2853 const bool debug=
false)
2855 return readSparse (in, pComm, Teuchos::null, constructorParams,
2856 fillCompleteParams, tolerant, debug);
2860 static Teuchos::RCP<sparse_matrix_type>
2862 const Teuchos::RCP<
const Teuchos::Comm<int> >& pComm,
2863 const Teuchos::RCP<node_type>& pNode,
2864 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
2865 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
2866 const bool tolerant=
false,
2867 const bool debug=
false)
2869 using Teuchos::MatrixMarket::Banner;
2870 using Teuchos::arcp;
2871 using Teuchos::ArrayRCP;
2872 using Teuchos::broadcast;
2873 using Teuchos::null;
2876 using Teuchos::reduceAll;
2877 using Teuchos::Tuple;
2880 typedef Teuchos::ScalarTraits<scalar_type> STS;
2882 const bool extraDebug =
false;
2883 const int myRank = pComm->getRank ();
2884 const int rootRank = 0;
2889 size_t lineNumber = 1;
2891 if (debug && myRank == rootRank) {
2892 cerr <<
"Matrix Market reader: readSparse:" << endl
2893 <<
"-- Reading banner line" << endl;
2902 RCP<const Banner> pBanner;
2908 int bannerIsCorrect = 1;
2909 std::ostringstream errMsg;
2911 if (myRank == rootRank) {
2914 pBanner = readBanner (in, lineNumber, tolerant, debug);
2916 catch (std::exception& e) {
2917 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2918 "threw an exception: " << e.what();
2919 bannerIsCorrect = 0;
2922 if (bannerIsCorrect) {
2927 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
2928 bannerIsCorrect = 0;
2929 errMsg <<
"The Matrix Market input file must contain a "
2930 "\"coordinate\"-format sparse matrix in order to create a "
2931 "Tpetra::CrsMatrix object from it, but the file's matrix "
2932 "type is \"" << pBanner->matrixType() <<
"\" instead.";
2937 if (tolerant && pBanner->matrixType() ==
"array") {
2938 bannerIsCorrect = 0;
2939 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2940 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2941 "object from it, but the file's matrix type is \"array\" "
2942 "instead. That probably means the file contains dense matrix "
2949 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
2956 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2957 std::invalid_argument, errMsg.str ());
2959 if (debug && myRank == rootRank) {
2960 cerr <<
"-- Reading dimensions line" << endl;
2968 Tuple<global_ordinal_type, 3> dims =
2969 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
2971 if (debug && myRank == rootRank) {
2972 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2977 RCP<adder_type> pAdder =
2978 makeAdder (pComm, pBanner, dims, tolerant, debug);
2980 if (debug && myRank == rootRank) {
2981 cerr <<
"-- Reading matrix data" << endl;
2991 int readSuccess = 1;
2992 std::ostringstream errMsg;
2993 if (myRank == rootRank) {
2996 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2998 reader_type reader (pAdder);
3001 std::pair<bool, std::vector<size_t> > results =
3002 reader.read (in, lineNumber, tolerant, debug);
3003 readSuccess = results.first ? 1 : 0;
3005 catch (std::exception& e) {
3010 broadcast (*pComm, rootRank, ptr (&readSuccess));
3019 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
3020 "Failed to read the Matrix Market sparse matrix file: "
3024 if (debug && myRank == rootRank) {
3025 cerr <<
"-- Successfully read the Matrix Market data" << endl;
3038 if (debug && myRank == rootRank) {
3039 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
3041 <<
"----- Dimensions before: "
3042 << dims[0] <<
" x " << dims[1]
3046 Tuple<global_ordinal_type, 2> updatedDims;
3047 if (myRank == rootRank) {
3054 std::max (dims[0], pAdder->getAdder()->numRows());
3055 updatedDims[1] = pAdder->getAdder()->numCols();
3057 broadcast (*pComm, rootRank, updatedDims);
3058 dims[0] = updatedDims[0];
3059 dims[1] = updatedDims[1];
3060 if (debug && myRank == rootRank) {
3061 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
3075 if (myRank == rootRank) {
3082 if (dims[0] < pAdder->getAdder ()->numRows ()) {
3086 broadcast (*pComm, 0, ptr (&dimsMatch));
3087 if (dimsMatch == 0) {
3094 Tuple<global_ordinal_type, 2> addersDims;
3095 if (myRank == rootRank) {
3096 addersDims[0] = pAdder->getAdder()->numRows();
3097 addersDims[1] = pAdder->getAdder()->numCols();
3099 broadcast (*pComm, 0, addersDims);
3100 TEUCHOS_TEST_FOR_EXCEPTION(
3101 dimsMatch == 0, std::runtime_error,
3102 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
3103 << dims[1] <<
", but the actual data says that the matrix is "
3104 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
3105 "data includes more rows than reported in the metadata. This "
3106 "is not allowed when parsing in strict mode. Parse the matrix in "
3107 "tolerant mode to ignore the metadata when it disagrees with the "
3112 if (debug && myRank == rootRank) {
3113 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3125 ArrayRCP<size_t> numEntriesPerRow;
3126 ArrayRCP<size_t> rowPtr;
3127 ArrayRCP<global_ordinal_type> colInd;
3128 ArrayRCP<scalar_type> values;
3133 int mergeAndConvertSucceeded = 1;
3134 std::ostringstream errMsg;
3136 if (myRank == rootRank) {
3138 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3148 const size_type numRows = dims[0];
3151 pAdder->getAdder()->merge ();
3154 const std::vector<element_type>& entries =
3155 pAdder->getAdder()->getEntries();
3158 const size_t numEntries = (size_t)entries.size();
3161 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3162 <<
" rows and numEntries=" << numEntries
3163 <<
" entries." << endl;
3169 numEntriesPerRow = arcp<size_t> (numRows);
3170 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3171 rowPtr = arcp<size_t> (numRows+1);
3172 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3173 colInd = arcp<global_ordinal_type> (numEntries);
3174 values = arcp<scalar_type> (numEntries);
3181 for (curPos = 0; curPos < numEntries; ++curPos) {
3182 const element_type& curEntry = entries[curPos];
3184 TEUCHOS_TEST_FOR_EXCEPTION(
3185 curRow < prvRow, std::logic_error,
3186 "Row indices are out of order, even though they are supposed "
3187 "to be sorted. curRow = " << curRow <<
", prvRow = "
3188 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3189 "this bug to the Tpetra developers.");
3190 if (curRow > prvRow) {
3196 numEntriesPerRow[curRow]++;
3197 colInd[curPos] = curEntry.colIndex();
3198 values[curPos] = curEntry.value();
3203 rowPtr[numRows] = numEntries;
3205 catch (std::exception& e) {
3206 mergeAndConvertSucceeded = 0;
3207 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3208 "CSR format: " << e.what();
3211 if (debug && mergeAndConvertSucceeded) {
3213 const size_type numRows = dims[0];
3214 const size_type maxToDisplay = 100;
3216 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3217 << (numEntriesPerRow.size()-1) <<
"] ";
3218 if (numRows > maxToDisplay) {
3219 cerr <<
"(only showing first and last few entries) ";
3223 if (numRows > maxToDisplay) {
3224 for (size_type k = 0; k < 2; ++k) {
3225 cerr << numEntriesPerRow[k] <<
" ";
3228 for (size_type k = numRows-2; k < numRows-1; ++k) {
3229 cerr << numEntriesPerRow[k] <<
" ";
3233 for (size_type k = 0; k < numRows-1; ++k) {
3234 cerr << numEntriesPerRow[k] <<
" ";
3237 cerr << numEntriesPerRow[numRows-1];
3239 cerr <<
"]" << endl;
3241 cerr <<
"----- Proc 0: rowPtr ";
3242 if (numRows > maxToDisplay) {
3243 cerr <<
"(only showing first and last few entries) ";
3246 if (numRows > maxToDisplay) {
3247 for (size_type k = 0; k < 2; ++k) {
3248 cerr << rowPtr[k] <<
" ";
3251 for (size_type k = numRows-2; k < numRows; ++k) {
3252 cerr << rowPtr[k] <<
" ";
3256 for (size_type k = 0; k < numRows; ++k) {
3257 cerr << rowPtr[k] <<
" ";
3260 cerr << rowPtr[numRows] <<
"]" << endl;
3271 if (debug && myRank == rootRank) {
3272 cerr <<
"-- Making range, domain, and row maps" << endl;
3279 RCP<const map_type> pRangeMap = makeRangeMap (pComm, pNode, dims[0]);
3280 RCP<const map_type> pDomainMap =
3281 makeDomainMap (pRangeMap, dims[0], dims[1]);
3282 RCP<const map_type> pRowMap = makeRowMap (
null, pComm, pNode, dims[0]);
3284 if (debug && myRank == rootRank) {
3285 cerr <<
"-- Distributing the matrix data" << endl;
3299 ArrayRCP<size_t> myNumEntriesPerRow;
3300 ArrayRCP<size_t> myRowPtr;
3301 ArrayRCP<global_ordinal_type> myColInd;
3302 ArrayRCP<scalar_type> myValues;
3304 distribute (myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
3305 numEntriesPerRow, rowPtr, colInd, values, debug);
3307 if (debug && myRank == rootRank) {
3308 cerr <<
"-- Inserting matrix entries on each process "
3309 "and calling fillComplete()" << endl;
3318 Teuchos::RCP<sparse_matrix_type> pMatrix =
3319 makeMatrix (myNumEntriesPerRow, myRowPtr, myColInd, myValues,
3320 pRowMap, pRangeMap, pDomainMap, constructorParams,
3321 fillCompleteParams);
3326 int localIsNull = pMatrix.is_null () ? 1 : 0;
3327 int globalIsNull = 0;
3328 reduceAll (*pComm, Teuchos::REDUCE_MAX, localIsNull, ptr (&globalIsNull));
3329 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
3330 "Reader::makeMatrix() returned a null pointer on at least one "
3331 "process. Please report this bug to the Tpetra developers.");
3334 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
3335 "Reader::makeMatrix() returned a null pointer. "
3336 "Please report this bug to the Tpetra developers.");
3345 if (extraDebug && debug) {
3346 const int numProcs = pComm->getSize ();
3348 pRangeMap->getGlobalNumElements();
3350 pDomainMap->getGlobalNumElements();
3351 if (myRank == rootRank) {
3352 cerr <<
"-- Matrix is "
3353 << globalNumRows <<
" x " << globalNumCols
3354 <<
" with " << pMatrix->getGlobalNumEntries()
3355 <<
" entries, and index base "
3356 << pMatrix->getIndexBase() <<
"." << endl;
3359 for (
int p = 0; p < numProcs; ++p) {
3361 cerr <<
"-- Proc " << p <<
" owns "
3362 << pMatrix->getNodeNumCols() <<
" columns, and "
3363 << pMatrix->getNodeNumEntries() <<
" entries." << endl;
3369 if (debug && myRank == rootRank) {
3370 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3416 static Teuchos::RCP<sparse_matrix_type>
3418 const Teuchos::RCP<const map_type>& rowMap,
3419 Teuchos::RCP<const map_type>& colMap,
3420 const Teuchos::RCP<const map_type>& domainMap,
3421 const Teuchos::RCP<const map_type>& rangeMap,
3422 const bool callFillComplete=
true,
3423 const bool tolerant=
false,
3424 const bool debug=
false)
3426 using Teuchos::MatrixMarket::Banner;
3427 using Teuchos::arcp;
3428 using Teuchos::ArrayRCP;
3429 using Teuchos::ArrayView;
3431 using Teuchos::broadcast;
3432 using Teuchos::Comm;
3433 using Teuchos::null;
3436 using Teuchos::reduceAll;
3437 using Teuchos::Tuple;
3440 typedef Teuchos::ScalarTraits<scalar_type> STS;
3442 RCP<const Comm<int> > pComm = rowMap->getComm ();
3443 const int myRank = pComm->getRank ();
3444 const int rootRank = 0;
3445 const bool extraDebug =
false;
3450 TEUCHOS_TEST_FOR_EXCEPTION(
3451 rowMap.is_null (), std::invalid_argument,
3452 "Row Map must be nonnull.");
3453 TEUCHOS_TEST_FOR_EXCEPTION(
3454 rangeMap.is_null (), std::invalid_argument,
3455 "Range Map must be nonnull.");
3456 TEUCHOS_TEST_FOR_EXCEPTION(
3457 domainMap.is_null (), std::invalid_argument,
3458 "Domain Map must be nonnull.");
3459 TEUCHOS_TEST_FOR_EXCEPTION(
3460 rowMap->getComm().getRawPtr() != pComm.getRawPtr(),
3461 std::invalid_argument,
3462 "The specified row Map's communicator (rowMap->getComm())"
3463 "differs from the given separately supplied communicator pComm.");
3464 TEUCHOS_TEST_FOR_EXCEPTION(
3465 domainMap->getComm().getRawPtr() != pComm.getRawPtr(),
3466 std::invalid_argument,
3467 "The specified domain Map's communicator (domainMap->getComm())"
3468 "differs from the given separately supplied communicator pComm.");
3469 TEUCHOS_TEST_FOR_EXCEPTION(
3470 rangeMap->getComm().getRawPtr() != pComm.getRawPtr(),
3471 std::invalid_argument,
3472 "The specified range Map's communicator (rangeMap->getComm())"
3473 "differs from the given separately supplied communicator pComm.");
3478 size_t lineNumber = 1;
3480 if (debug && myRank == rootRank) {
3481 cerr <<
"Matrix Market reader: readSparse:" << endl
3482 <<
"-- Reading banner line" << endl;
3491 RCP<const Banner> pBanner;
3497 int bannerIsCorrect = 1;
3498 std::ostringstream errMsg;
3500 if (myRank == rootRank) {
3503 pBanner = readBanner (in, lineNumber, tolerant, debug);
3505 catch (std::exception& e) {
3506 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
3507 "threw an exception: " << e.what();
3508 bannerIsCorrect = 0;
3511 if (bannerIsCorrect) {
3516 if (! tolerant && pBanner->matrixType() !=
"coordinate") {
3517 bannerIsCorrect = 0;
3518 errMsg <<
"The Matrix Market input file must contain a "
3519 "\"coordinate\"-format sparse matrix in order to create a "
3520 "Tpetra::CrsMatrix object from it, but the file's matrix "
3521 "type is \"" << pBanner->matrixType() <<
"\" instead.";
3526 if (tolerant && pBanner->matrixType() ==
"array") {
3527 bannerIsCorrect = 0;
3528 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
3529 "format sparse matrix in order to create a Tpetra::CrsMatrix "
3530 "object from it, but the file's matrix type is \"array\" "
3531 "instead. That probably means the file contains dense matrix "
3538 broadcast (*pComm, rootRank, ptr (&bannerIsCorrect));
3545 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
3546 std::invalid_argument, errMsg.str ());
3548 if (debug && myRank == rootRank) {
3549 cerr <<
"-- Reading dimensions line" << endl;
3557 Tuple<global_ordinal_type, 3> dims =
3558 readCoordDims (in, lineNumber, pBanner, pComm, tolerant, debug);
3560 if (debug && myRank == rootRank) {
3561 cerr <<
"-- Making Adder for collecting matrix data" << endl;
3568 RCP<adder_type> pAdder =
3569 makeAdder (pComm, pBanner, dims, tolerant, debug);
3571 if (debug && myRank == rootRank) {
3572 cerr <<
"-- Reading matrix data" << endl;
3582 int readSuccess = 1;
3583 std::ostringstream errMsg;
3584 if (myRank == rootRank) {
3587 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
3589 reader_type reader (pAdder);
3592 std::pair<bool, std::vector<size_t> > results =
3593 reader.read (in, lineNumber, tolerant, debug);
3594 readSuccess = results.first ? 1 : 0;
3596 catch (std::exception& e) {
3601 broadcast (*pComm, rootRank, ptr (&readSuccess));
3610 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
3611 "Failed to read the Matrix Market sparse matrix file: "
3615 if (debug && myRank == rootRank) {
3616 cerr <<
"-- Successfully read the Matrix Market data" << endl;
3629 if (debug && myRank == rootRank) {
3630 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
3632 <<
"----- Dimensions before: "
3633 << dims[0] <<
" x " << dims[1]
3637 Tuple<global_ordinal_type, 2> updatedDims;
3638 if (myRank == rootRank) {
3645 std::max (dims[0], pAdder->getAdder()->numRows());
3646 updatedDims[1] = pAdder->getAdder()->numCols();
3648 broadcast (*pComm, rootRank, updatedDims);
3649 dims[0] = updatedDims[0];
3650 dims[1] = updatedDims[1];
3651 if (debug && myRank == rootRank) {
3652 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
3666 if (myRank == rootRank) {
3673 if (dims[0] < pAdder->getAdder ()->numRows ()) {
3677 broadcast (*pComm, 0, ptr (&dimsMatch));
3678 if (dimsMatch == 0) {
3685 Tuple<global_ordinal_type, 2> addersDims;
3686 if (myRank == rootRank) {
3687 addersDims[0] = pAdder->getAdder()->numRows();
3688 addersDims[1] = pAdder->getAdder()->numCols();
3690 broadcast (*pComm, 0, addersDims);
3691 TEUCHOS_TEST_FOR_EXCEPTION(
3692 dimsMatch == 0, std::runtime_error,
3693 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
3694 << dims[1] <<
", but the actual data says that the matrix is "
3695 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
3696 "data includes more rows than reported in the metadata. This "
3697 "is not allowed when parsing in strict mode. Parse the matrix in "
3698 "tolerant mode to ignore the metadata when it disagrees with the "
3703 if (debug && myRank == rootRank) {
3704 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
3716 ArrayRCP<size_t> numEntriesPerRow;
3717 ArrayRCP<size_t> rowPtr;
3718 ArrayRCP<global_ordinal_type> colInd;
3719 ArrayRCP<scalar_type> values;
3724 int mergeAndConvertSucceeded = 1;
3725 std::ostringstream errMsg;
3727 if (myRank == rootRank) {
3729 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
3739 const size_type numRows = dims[0];
3742 pAdder->getAdder()->merge ();
3745 const std::vector<element_type>& entries =
3746 pAdder->getAdder()->getEntries();
3749 const size_t numEntries = (size_t)entries.size();
3752 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
3753 <<
" rows and numEntries=" << numEntries
3754 <<
" entries." << endl;
3760 numEntriesPerRow = arcp<size_t> (numRows);
3761 std::fill (numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
3762 rowPtr = arcp<size_t> (numRows+1);
3763 std::fill (rowPtr.begin(), rowPtr.end(), 0);
3764 colInd = arcp<global_ordinal_type> (numEntries);
3765 values = arcp<scalar_type> (numEntries);
3772 for (curPos = 0; curPos < numEntries; ++curPos) {
3773 const element_type& curEntry = entries[curPos];
3775 TEUCHOS_TEST_FOR_EXCEPTION(
3776 curRow < prvRow, std::logic_error,
3777 "Row indices are out of order, even though they are supposed "
3778 "to be sorted. curRow = " << curRow <<
", prvRow = "
3779 << prvRow <<
", at curPos = " << curPos <<
". Please report "
3780 "this bug to the Tpetra developers.");
3781 if (curRow > prvRow) {
3787 numEntriesPerRow[curRow]++;
3788 colInd[curPos] = curEntry.colIndex();
3789 values[curPos] = curEntry.value();
3794 rowPtr[numRows] = numEntries;
3796 catch (std::exception& e) {
3797 mergeAndConvertSucceeded = 0;
3798 errMsg <<
"Failed to merge sparse matrix entries and convert to "
3799 "CSR format: " << e.what();
3802 if (debug && mergeAndConvertSucceeded) {
3804 const size_type numRows = dims[0];
3805 const size_type maxToDisplay = 100;
3807 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
3808 << (numEntriesPerRow.size()-1) <<
"] ";
3809 if (numRows > maxToDisplay) {
3810 cerr <<
"(only showing first and last few entries) ";
3814 if (numRows > maxToDisplay) {
3815 for (size_type k = 0; k < 2; ++k) {
3816 cerr << numEntriesPerRow[k] <<
" ";
3819 for (size_type k = numRows-2; k < numRows-1; ++k) {
3820 cerr << numEntriesPerRow[k] <<
" ";
3824 for (size_type k = 0; k < numRows-1; ++k) {
3825 cerr << numEntriesPerRow[k] <<
" ";
3828 cerr << numEntriesPerRow[numRows-1];
3830 cerr <<
"]" << endl;
3832 cerr <<
"----- Proc 0: rowPtr ";
3833 if (numRows > maxToDisplay) {
3834 cerr <<
"(only showing first and last few entries) ";
3837 if (numRows > maxToDisplay) {
3838 for (size_type k = 0; k < 2; ++k) {
3839 cerr << rowPtr[k] <<
" ";
3842 for (size_type k = numRows-2; k < numRows; ++k) {
3843 cerr << rowPtr[k] <<
" ";
3847 for (size_type k = 0; k < numRows; ++k) {
3848 cerr << rowPtr[k] <<
" ";
3851 cerr << rowPtr[numRows] <<
"]" << endl;
3853 cerr <<
"----- Proc 0: colInd = [";
3854 for (
size_t k = 0; k < rowPtr[numRows]; ++k) {
3855 cerr << colInd[k] <<
" ";
3857 cerr <<
"]" << endl;
3871 if (debug && myRank == rootRank) {
3872 cerr <<
"-- Verifying Maps" << endl;
3874 TEUCHOS_TEST_FOR_EXCEPTION(
3875 as<global_size_t> (dims[0]) != rangeMap->getGlobalNumElements(),
3876 std::invalid_argument,
3877 "The range Map has " << rangeMap->getGlobalNumElements ()
3878 <<
" entries, but the matrix has a global number of rows " << dims[0]
3880 TEUCHOS_TEST_FOR_EXCEPTION(
3881 as<global_size_t> (dims[1]) != domainMap->getGlobalNumElements (),
3882 std::invalid_argument,
3883 "The domain Map has " << domainMap->getGlobalNumElements ()
3884 <<
" entries, but the matrix has a global number of columns "
3888 RCP<Teuchos::FancyOStream> err = debug ?
3889 Teuchos::getFancyOStream (Teuchos::rcpFromRef (cerr)) :
null;
3891 RCP<const map_type> gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
3892 ArrayView<const global_ordinal_type> myRows =
3893 gatherRowMap->getNodeElementList ();
3894 const size_type myNumRows = myRows.size ();
3897 ArrayRCP<size_t> gatherNumEntriesPerRow = arcp<size_t>(myNumRows);
3898 for (size_type i_ = 0; i_ < myNumRows; i_++) {
3899 gatherNumEntriesPerRow[i_] = numEntriesPerRow[myRows[i_]-indexBase];
3905 RCP<sparse_matrix_type> A_proc0 =
3908 if (myRank == rootRank) {
3910 cerr <<
"-- Proc 0: Filling gather matrix" << endl;
3913 cerr <<
"---- Rows: " << Teuchos::toString (myRows) << endl;
3917 for (size_type i_ = 0; i_ < myNumRows; ++i_) {
3918 size_type i = myRows[i_] - indexBase;
3920 const size_type curPos = as<size_type> (rowPtr[i]);
3922 ArrayView<global_ordinal_type> curColInd =
3923 colInd.view (curPos, curNumEntries);
3924 ArrayView<scalar_type> curValues =
3925 values.view (curPos, curNumEntries);
3928 for (size_type k = 0; k < curNumEntries; ++k) {
3929 curColInd[k] += indexBase;
3932 cerr <<
"------ Columns: " << Teuchos::toString (curColInd) << endl;
3933 cerr <<
"------ Values: " << Teuchos::toString (curValues) << endl;
3936 if (curNumEntries > 0) {
3937 A_proc0->insertGlobalValues (myRows[i_], curColInd, curValues);
3943 numEntriesPerRow =
null;
3949 RCP<sparse_matrix_type> A;
3950 if (colMap.is_null ()) {
3956 export_type exp (gatherRowMap, rowMap);
3957 A->doExport (*A_proc0, exp,
INSERT);
3959 if (callFillComplete) {
3960 A->fillComplete (domainMap, rangeMap);
3972 if (callFillComplete) {
3973 const int numProcs = pComm->getSize ();
3975 if (extraDebug && debug) {
3976 const global_size_t globalNumRows = rangeMap->getGlobalNumElements ();
3977 const global_size_t globalNumCols = domainMap->getGlobalNumElements ();
3978 if (myRank == rootRank) {
3979 cerr <<
"-- Matrix is "
3980 << globalNumRows <<
" x " << globalNumCols
3981 <<
" with " << A->getGlobalNumEntries()
3982 <<
" entries, and index base "
3983 << A->getIndexBase() <<
"." << endl;
3986 for (
int p = 0; p < numProcs; ++p) {
3988 cerr <<
"-- Proc " << p <<
" owns "
3989 << A->getNodeNumCols() <<
" columns, and "
3990 << A->getNodeNumEntries() <<
" entries." << endl;
3997 if (debug && myRank == rootRank) {
3998 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
4033 static Teuchos::RCP<multivector_type>
4035 const Teuchos::RCP<const comm_type>& comm,
4036 Teuchos::RCP<const map_type>& map,
4037 const bool tolerant=
false,
4038 const bool debug=
false)
4041 if (comm->getRank () == 0) {
4042 in.open (filename.c_str ());
4044 return readDense (in, comm, map, tolerant, debug);
4048 static Teuchos::RCP<multivector_type>
4050 const Teuchos::RCP<const comm_type>& comm,
4051 const Teuchos::RCP<node_type>& node,
4052 Teuchos::RCP<const map_type>& map,
4053 const bool tolerant=
false,
4054 const bool debug=
false)
4057 if (comm->getRank () == 0) {
4058 in.open (filename.c_str ());
4060 return readDense (in, comm, node, map, tolerant, debug);
4092 static Teuchos::RCP<vector_type>
4094 const Teuchos::RCP<const comm_type>& comm,
4095 Teuchos::RCP<const map_type>& map,
4096 const bool tolerant=
false,
4097 const bool debug=
false)
4100 if (comm->getRank () == 0) {
4101 in.open (filename.c_str ());
4103 return readVector (in, comm, map, tolerant, debug);
4108 static Teuchos::RCP<vector_type>
4110 const Teuchos::RCP<const comm_type>& comm,
4111 const Teuchos::RCP<node_type>& node,
4112 Teuchos::RCP<const map_type>& map,
4113 const bool tolerant=
false,
4114 const bool debug=
false)
4117 if (comm->getRank () == 0) {
4118 in.open (filename.c_str ());
4120 return readVector (in, comm, node, map, tolerant, debug);
4190 static Teuchos::RCP<multivector_type>
4192 const Teuchos::RCP<const comm_type>& comm,
4193 Teuchos::RCP<const map_type>& map,
4194 const bool tolerant=
false,
4195 const bool debug=
false)
4197 return readDense (in, comm, Teuchos::null, map, tolerant, debug);
4201 static Teuchos::RCP<multivector_type>
4203 const Teuchos::RCP<const comm_type>& comm,
4204 const Teuchos::RCP<node_type>& node,
4205 Teuchos::RCP<const map_type>& map,
4206 const bool tolerant=
false,
4207 const bool debug=
false)
4209 Teuchos::RCP<Teuchos::FancyOStream> err =
4210 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4211 return readDenseImpl<scalar_type> (in, comm, node, map,
4212 err, tolerant, debug);
4216 static Teuchos::RCP<vector_type>
4218 const Teuchos::RCP<const comm_type>& comm,
4219 Teuchos::RCP<const map_type>& map,
4220 const bool tolerant=
false,
4221 const bool debug=
false)
4223 Teuchos::RCP<Teuchos::FancyOStream> err =
4224 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4225 return readVectorImpl<scalar_type> (in, comm, Teuchos::null, map,
4226 err, tolerant, debug);
4230 static Teuchos::RCP<vector_type>
4232 const Teuchos::RCP<const comm_type>& comm,
4233 const Teuchos::RCP<node_type>& node,
4234 Teuchos::RCP<const map_type>& map,
4235 const bool tolerant=
false,
4236 const bool debug=
false)
4238 Teuchos::RCP<Teuchos::FancyOStream> err =
4239 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
4240 return readVectorImpl<scalar_type> (in, comm, node, map,
4241 err, tolerant, debug);
4264 static Teuchos::RCP<const map_type>
4266 const Teuchos::RCP<const comm_type>& comm,
4267 const bool tolerant=
false,
4268 const bool debug=
false)
4270 return readMapFile (filename, comm, Teuchos::null, tolerant, debug);
4275 static Teuchos::RCP<const map_type>
4277 const Teuchos::RCP<const comm_type>& comm,
4278 const Teuchos::RCP<node_type>& node,
4279 const bool tolerant=
false,
4280 const bool debug=
false)
4282 using Teuchos::inOutArg;
4283 using Teuchos::broadcast;
4287 if (comm->getRank () == 0) {
4288 in.open (filename.c_str ());
4293 broadcast<int, int> (*comm, 0, inOutArg (success));
4294 TEUCHOS_TEST_FOR_EXCEPTION(
4295 success == 0, std::runtime_error,
4296 "Tpetra::MatrixMarket::Reader::readMapFile: "
4297 "Failed to read file \"" << filename <<
"\" on Process 0.");
4298 return readMap (in, comm, node, tolerant, debug);
4302 template<
class MultiVectorScalarType>
4307 readDenseImpl (std::istream& in,
4308 const Teuchos::RCP<const comm_type>& comm,
4309 const Teuchos::RCP<node_type>& node,
4310 Teuchos::RCP<const map_type>& map,
4311 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4312 const bool tolerant=
false,
4313 const bool debug=
false)
4315 using Teuchos::MatrixMarket::Banner;
4316 using Teuchos::MatrixMarket::checkCommentLine;
4317 using Teuchos::ArrayRCP;
4319 using Teuchos::broadcast;
4320 using Teuchos::outArg;
4322 using Teuchos::Tuple;
4324 typedef MultiVectorScalarType ST;
4328 typedef Teuchos::ScalarTraits<ST> STS;
4329 typedef typename STS::magnitudeType MT;
4330 typedef Teuchos::ScalarTraits<MT> STM;
4335 const int myRank = comm->getRank ();
4337 if (! err.is_null ()) {
4341 *err << myRank <<
": readDenseImpl" << endl;
4343 if (! err.is_null ()) {
4377 size_t lineNumber = 1;
4380 std::ostringstream exMsg;
4381 int localBannerReadSuccess = 1;
4382 int localDimsReadSuccess = 1;
4387 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
4393 RCP<const Banner> pBanner;
4395 pBanner = readBanner (in, lineNumber, tolerant, debug);
4396 }
catch (std::exception& e) {
4398 localBannerReadSuccess = 0;
4401 if (localBannerReadSuccess) {
4402 if (pBanner->matrixType () !=
"array") {
4403 exMsg <<
"The Matrix Market file does not contain dense matrix "
4404 "data. Its banner (first) line says that its matrix type is \""
4405 << pBanner->matrixType () <<
"\", rather that the required "
4407 localBannerReadSuccess = 0;
4408 }
else if (pBanner->dataType() ==
"pattern") {
4409 exMsg <<
"The Matrix Market file's banner (first) "
4410 "line claims that the matrix's data type is \"pattern\". This does "
4411 "not make sense for a dense matrix, yet the file reports the matrix "
4412 "as dense. The only valid data types for a dense matrix are "
4413 "\"real\", \"complex\", and \"integer\".";
4414 localBannerReadSuccess = 0;
4418 dims[2] = encodeDataType (pBanner->dataType ());
4424 if (localBannerReadSuccess) {
4426 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
4435 bool commentLine =
true;
4437 while (commentLine) {
4440 if (in.eof () || in.fail ()) {
4441 exMsg <<
"Unable to get array dimensions line (at all) from line "
4442 << lineNumber <<
" of input stream. The input stream "
4443 <<
"claims that it is "
4444 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4445 localDimsReadSuccess = 0;
4448 if (getline (in, line)) {
4455 size_t start = 0, size = 0;
4456 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4463 std::istringstream istr (line);
4467 if (istr.eof () || istr.fail ()) {
4468 exMsg <<
"Unable to read any data from line " << lineNumber
4469 <<
" of input; the line should contain the matrix dimensions "
4470 <<
"\"<numRows> <numCols>\".";
4471 localDimsReadSuccess = 0;
4476 exMsg <<
"Failed to get number of rows from line "
4477 << lineNumber <<
" of input; the line should contains the "
4478 <<
"matrix dimensions \"<numRows> <numCols>\".";
4479 localDimsReadSuccess = 0;
4481 dims[0] = theNumRows;
4483 exMsg <<
"No more data after number of rows on line "
4484 << lineNumber <<
" of input; the line should contain the "
4485 <<
"matrix dimensions \"<numRows> <numCols>\".";
4486 localDimsReadSuccess = 0;
4491 exMsg <<
"Failed to get number of columns from line "
4492 << lineNumber <<
" of input; the line should contain "
4493 <<
"the matrix dimensions \"<numRows> <numCols>\".";
4494 localDimsReadSuccess = 0;
4496 dims[1] = theNumCols;
4507 Tuple<GO, 5> bannerDimsReadResult;
4509 bannerDimsReadResult[0] = dims[0];
4510 bannerDimsReadResult[1] = dims[1];
4511 bannerDimsReadResult[2] = dims[2];
4512 bannerDimsReadResult[3] = localBannerReadSuccess;
4513 bannerDimsReadResult[4] = localDimsReadSuccess;
4517 broadcast (*comm, 0, bannerDimsReadResult);
4519 TEUCHOS_TEST_FOR_EXCEPTION(
4520 bannerDimsReadResult[3] == 0, std::runtime_error,
4521 "Failed to read banner line: " << exMsg.str ());
4522 TEUCHOS_TEST_FOR_EXCEPTION(
4523 bannerDimsReadResult[4] == 0, std::runtime_error,
4524 "Failed to read matrix dimensions line: " << exMsg.str ());
4526 dims[0] = bannerDimsReadResult[0];
4527 dims[1] = bannerDimsReadResult[1];
4528 dims[2] = bannerDimsReadResult[2];
4532 const global_size_t numRows = static_cast<global_size_t> (dims[0]);
4533 const size_t numCols = static_cast<size_t> (dims[1]);
4538 RCP<const map_type> proc0Map;
4539 if (map.is_null ()) {
4543 if (node.is_null ()) {
4544 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
4546 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm, node);
4548 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4550 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
4551 comm, map->getNode ());
4554 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
4558 RCP<MV> X = createMultiVector<ST, LO, GO, NT> (proc0Map, numCols);
4564 int localReadDataSuccess = 1;
4568 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
4573 TEUCHOS_TEST_FOR_EXCEPTION(
4574 ! X->isConstantStride (), std::logic_error,
4575 "Can't get a 1-D view of the entries of the MultiVector X on "
4576 "Process 0, because the stride between the columns of X is not "
4577 "constant. This shouldn't happen because we just created X and "
4578 "haven't filled it in yet. Please report this bug to the Tpetra "
4585 ArrayRCP<ST> X_view = X->get1dViewNonConst ();
4586 TEUCHOS_TEST_FOR_EXCEPTION(
4587 as<global_size_t> (X_view.size ()) < numRows * numCols,
4589 "The view of X has size " << X_view <<
" which is not enough to "
4590 "accommodate the expected number of entries numRows*numCols = "
4591 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
4592 "Please report this bug to the Tpetra developers.");
4593 const size_t stride = X->getStride ();
4600 const bool isComplex = (dims[2] == 1);
4601 size_type count = 0, curRow = 0, curCol = 0;
4604 while (getline (in, line)) {
4608 size_t start = 0, size = 0;
4609 const bool commentLine =
4610 checkCommentLine (line, start, size, lineNumber, tolerant);
4611 if (! commentLine) {
4617 if (count >= X_view.size()) {
4622 TEUCHOS_TEST_FOR_EXCEPTION(
4623 count >= X_view.size(),
4625 "The Matrix Market input stream has more data in it than "
4626 "its metadata reported. Current line number is "
4627 << lineNumber <<
".");
4636 const size_t pos = line.substr (start, size).find (
':');
4637 if (pos != std::string::npos) {
4641 std::istringstream istr (line.substr (start, size));
4645 if (istr.eof() || istr.fail()) {
4652 TEUCHOS_TEST_FOR_EXCEPTION(
4653 ! tolerant && (istr.eof() || istr.fail()),
4655 "Line " << lineNumber <<
" of the Matrix Market file is "
4656 "empty, or we cannot read from it for some other reason.");
4659 ST val = STS::zero();
4662 MT real = STM::zero(), imag = STM::zero();
4679 TEUCHOS_TEST_FOR_EXCEPTION(
4680 ! tolerant && istr.eof(), std::runtime_error,
4681 "Failed to get the real part of a complex-valued matrix "
4682 "entry from line " << lineNumber <<
" of the Matrix Market "
4688 }
else if (istr.eof()) {
4689 TEUCHOS_TEST_FOR_EXCEPTION(
4690 ! tolerant && istr.eof(), std::runtime_error,
4691 "Missing imaginary part of a complex-valued matrix entry "
4692 "on line " << lineNumber <<
" of the Matrix Market file.");
4698 TEUCHOS_TEST_FOR_EXCEPTION(
4699 ! tolerant && istr.fail(), std::runtime_error,
4700 "Failed to get the imaginary part of a complex-valued "
4701 "matrix entry from line " << lineNumber <<
" of the "
4702 "Matrix Market file.");
4709 TEUCHOS_TEST_FOR_EXCEPTION(
4710 ! tolerant && istr.fail(), std::runtime_error,
4711 "Failed to get a real-valued matrix entry from line "
4712 << lineNumber <<
" of the Matrix Market file.");
4715 if (istr.fail() && tolerant) {
4721 TEUCHOS_TEST_FOR_EXCEPTION(
4722 ! tolerant && istr.fail(), std::runtime_error,
4723 "Failed to read matrix data from line " << lineNumber
4724 <<
" of the Matrix Market file.");
4727 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
4729 curRow = count % numRows;
4730 curCol = count / numRows;
4731 X_view[curRow + curCol*stride] = val;
4736 TEUCHOS_TEST_FOR_EXCEPTION(
4737 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
4739 "The Matrix Market metadata reports that the dense matrix is "
4740 << numRows <<
" x " << numCols <<
", and thus has "
4741 << numRows*numCols <<
" total entries, but we only found " << count
4742 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4743 }
catch (std::exception& e) {
4745 localReadDataSuccess = 0;
4750 *err << myRank <<
": readDenseImpl: done reading data" << endl;
4754 int globalReadDataSuccess = localReadDataSuccess;
4755 broadcast (*comm, 0, outArg (globalReadDataSuccess));
4756 TEUCHOS_TEST_FOR_EXCEPTION(
4757 globalReadDataSuccess == 0, std::runtime_error,
4758 "Failed to read the multivector's data: " << exMsg.str ());
4763 if (comm->getSize () == 1 && map.is_null ()) {
4765 if (! err.is_null ()) {
4769 *err << myRank <<
": readDenseImpl: done" << endl;
4771 if (! err.is_null ()) {
4778 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
4782 RCP<MV> Y = createMultiVector<ST, LO, GO, NT> (map, numCols);
4785 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
4791 Export<LO, GO, NT> exporter (proc0Map, map, err);
4794 *err << myRank <<
": readDenseImpl: Exporting" << endl;
4797 Y->doExport (*X, exporter,
INSERT);
4799 if (! err.is_null ()) {
4803 *err << myRank <<
": readDenseImpl: done" << endl;
4805 if (! err.is_null ()) {
4814 template<
class VectorScalarType>
4819 readVectorImpl (std::istream& in,
4820 const Teuchos::RCP<const comm_type>& comm,
4821 const Teuchos::RCP<node_type>& node,
4822 Teuchos::RCP<const map_type>& map,
4823 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4824 const bool tolerant=
false,
4825 const bool debug=
false)
4827 using Teuchos::MatrixMarket::Banner;
4828 using Teuchos::MatrixMarket::checkCommentLine;
4830 using Teuchos::broadcast;
4831 using Teuchos::outArg;
4833 using Teuchos::Tuple;
4835 typedef VectorScalarType ST;
4839 typedef Teuchos::ScalarTraits<ST> STS;
4840 typedef typename STS::magnitudeType MT;
4841 typedef Teuchos::ScalarTraits<MT> STM;
4846 const int myRank = comm->getRank ();
4848 if (! err.is_null ()) {
4852 *err << myRank <<
": readVectorImpl" << endl;
4854 if (! err.is_null ()) {
4888 size_t lineNumber = 1;
4891 std::ostringstream exMsg;
4892 int localBannerReadSuccess = 1;
4893 int localDimsReadSuccess = 1;
4898 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
4904 RCP<const Banner> pBanner;
4906 pBanner = readBanner (in, lineNumber, tolerant, debug);
4907 }
catch (std::exception& e) {
4909 localBannerReadSuccess = 0;
4912 if (localBannerReadSuccess) {
4913 if (pBanner->matrixType () !=
"array") {
4914 exMsg <<
"The Matrix Market file does not contain dense matrix "
4915 "data. Its banner (first) line says that its matrix type is \""
4916 << pBanner->matrixType () <<
"\", rather that the required "
4918 localBannerReadSuccess = 0;
4919 }
else if (pBanner->dataType() ==
"pattern") {
4920 exMsg <<
"The Matrix Market file's banner (first) "
4921 "line claims that the matrix's data type is \"pattern\". This does "
4922 "not make sense for a dense matrix, yet the file reports the matrix "
4923 "as dense. The only valid data types for a dense matrix are "
4924 "\"real\", \"complex\", and \"integer\".";
4925 localBannerReadSuccess = 0;
4929 dims[2] = encodeDataType (pBanner->dataType ());
4935 if (localBannerReadSuccess) {
4937 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
4946 bool commentLine =
true;
4948 while (commentLine) {
4951 if (in.eof () || in.fail ()) {
4952 exMsg <<
"Unable to get array dimensions line (at all) from line "
4953 << lineNumber <<
" of input stream. The input stream "
4954 <<
"claims that it is "
4955 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
4956 localDimsReadSuccess = 0;
4959 if (getline (in, line)) {
4966 size_t start = 0, size = 0;
4967 commentLine = checkCommentLine (line, start, size, lineNumber, tolerant);
4974 std::istringstream istr (line);
4978 if (istr.eof () || istr.fail ()) {
4979 exMsg <<
"Unable to read any data from line " << lineNumber
4980 <<
" of input; the line should contain the matrix dimensions "
4981 <<
"\"<numRows> <numCols>\".";
4982 localDimsReadSuccess = 0;
4987 exMsg <<
"Failed to get number of rows from line "
4988 << lineNumber <<
" of input; the line should contains the "
4989 <<
"matrix dimensions \"<numRows> <numCols>\".";
4990 localDimsReadSuccess = 0;
4992 dims[0] = theNumRows;
4994 exMsg <<
"No more data after number of rows on line "
4995 << lineNumber <<
" of input; the line should contain the "
4996 <<
"matrix dimensions \"<numRows> <numCols>\".";
4997 localDimsReadSuccess = 0;
5002 exMsg <<
"Failed to get number of columns from line "
5003 << lineNumber <<
" of input; the line should contain "
5004 <<
"the matrix dimensions \"<numRows> <numCols>\".";
5005 localDimsReadSuccess = 0;
5007 dims[1] = theNumCols;
5017 exMsg <<
"File does not contain a 1D Vector";
5018 localDimsReadSuccess = 0;
5024 Tuple<GO, 5> bannerDimsReadResult;
5026 bannerDimsReadResult[0] = dims[0];
5027 bannerDimsReadResult[1] = dims[1];
5028 bannerDimsReadResult[2] = dims[2];
5029 bannerDimsReadResult[3] = localBannerReadSuccess;
5030 bannerDimsReadResult[4] = localDimsReadSuccess;
5035 broadcast (*comm, 0, bannerDimsReadResult);
5037 TEUCHOS_TEST_FOR_EXCEPTION(
5038 bannerDimsReadResult[3] == 0, std::runtime_error,
5039 "Failed to read banner line: " << exMsg.str ());
5040 TEUCHOS_TEST_FOR_EXCEPTION(
5041 bannerDimsReadResult[4] == 0, std::runtime_error,
5042 "Failed to read matrix dimensions line: " << exMsg.str ());
5044 dims[0] = bannerDimsReadResult[0];
5045 dims[1] = bannerDimsReadResult[1];
5046 dims[2] = bannerDimsReadResult[2];
5050 const global_size_t numRows = static_cast<global_size_t> (dims[0]);
5051 const size_t numCols = static_cast<size_t> (dims[1]);
5056 RCP<const map_type> proc0Map;
5057 if (map.is_null ()) {
5061 if (node.is_null ()) {
5062 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm);
5064 map = createUniformContigMapWithNode<LO, GO, NT> (numRows, comm, node);
5066 const size_t localNumRows = (myRank == 0) ? numRows : 0;
5068 proc0Map = createContigMapWithNode<LO, GO, NT> (numRows, localNumRows,
5069 comm, map->getNode ());
5072 proc0Map = Details::computeGatherMap<map_type> (map, err, debug);
5076 RCP<MV> X = createVector<ST, LO, GO, NT> (proc0Map);
5082 int localReadDataSuccess = 1;
5086 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
5091 TEUCHOS_TEST_FOR_EXCEPTION(
5092 ! X->isConstantStride (), std::logic_error,
5093 "Can't get a 1-D view of the entries of the MultiVector X on "
5094 "Process 0, because the stride between the columns of X is not "
5095 "constant. This shouldn't happen because we just created X and "
5096 "haven't filled it in yet. Please report this bug to the Tpetra "
5103 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst ();
5104 TEUCHOS_TEST_FOR_EXCEPTION(
5105 as<global_size_t> (X_view.size ()) < numRows * numCols,
5107 "The view of X has size " << X_view <<
" which is not enough to "
5108 "accommodate the expected number of entries numRows*numCols = "
5109 << numRows <<
"*" << numCols <<
" = " << numRows*numCols <<
". "
5110 "Please report this bug to the Tpetra developers.");
5111 const size_t stride = X->getStride ();
5118 const bool isComplex = (dims[2] == 1);
5119 size_type count = 0, curRow = 0, curCol = 0;
5122 while (getline (in, line)) {
5126 size_t start = 0, size = 0;
5127 const bool commentLine =
5128 checkCommentLine (line, start, size, lineNumber, tolerant);
5129 if (! commentLine) {
5135 if (count >= X_view.size()) {
5140 TEUCHOS_TEST_FOR_EXCEPTION(
5141 count >= X_view.size(),
5143 "The Matrix Market input stream has more data in it than "
5144 "its metadata reported. Current line number is "
5145 << lineNumber <<
".");
5154 const size_t pos = line.substr (start, size).find (
':');
5155 if (pos != std::string::npos) {
5159 std::istringstream istr (line.substr (start, size));
5163 if (istr.eof() || istr.fail()) {
5170 TEUCHOS_TEST_FOR_EXCEPTION(
5171 ! tolerant && (istr.eof() || istr.fail()),
5173 "Line " << lineNumber <<
" of the Matrix Market file is "
5174 "empty, or we cannot read from it for some other reason.");
5177 ST val = STS::zero();
5180 MT real = STM::zero(), imag = STM::zero();
5197 TEUCHOS_TEST_FOR_EXCEPTION(
5198 ! tolerant && istr.eof(), std::runtime_error,
5199 "Failed to get the real part of a complex-valued matrix "
5200 "entry from line " << lineNumber <<
" of the Matrix Market "
5206 }
else if (istr.eof()) {
5207 TEUCHOS_TEST_FOR_EXCEPTION(
5208 ! tolerant && istr.eof(), std::runtime_error,
5209 "Missing imaginary part of a complex-valued matrix entry "
5210 "on line " << lineNumber <<
" of the Matrix Market file.");
5216 TEUCHOS_TEST_FOR_EXCEPTION(
5217 ! tolerant && istr.fail(), std::runtime_error,
5218 "Failed to get the imaginary part of a complex-valued "
5219 "matrix entry from line " << lineNumber <<
" of the "
5220 "Matrix Market file.");
5227 TEUCHOS_TEST_FOR_EXCEPTION(
5228 ! tolerant && istr.fail(), std::runtime_error,
5229 "Failed to get a real-valued matrix entry from line "
5230 << lineNumber <<
" of the Matrix Market file.");
5233 if (istr.fail() && tolerant) {
5239 TEUCHOS_TEST_FOR_EXCEPTION(
5240 ! tolerant && istr.fail(), std::runtime_error,
5241 "Failed to read matrix data from line " << lineNumber
5242 <<
" of the Matrix Market file.");
5245 Teuchos::MatrixMarket::details::assignScalar<ST> (val, real, imag);
5247 curRow = count % numRows;
5248 curCol = count / numRows;
5249 X_view[curRow + curCol*stride] = val;
5254 TEUCHOS_TEST_FOR_EXCEPTION(
5255 ! tolerant && static_cast<global_size_t> (count) < numRows * numCols,
5257 "The Matrix Market metadata reports that the dense matrix is "
5258 << numRows <<
" x " << numCols <<
", and thus has "
5259 << numRows*numCols <<
" total entries, but we only found " << count
5260 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
5261 }
catch (std::exception& e) {
5263 localReadDataSuccess = 0;
5268 *err << myRank <<
": readVectorImpl: done reading data" << endl;
5272 int globalReadDataSuccess = localReadDataSuccess;
5273 broadcast (*comm, 0, outArg (globalReadDataSuccess));
5274 TEUCHOS_TEST_FOR_EXCEPTION(
5275 globalReadDataSuccess == 0, std::runtime_error,
5276 "Failed to read the multivector's data: " << exMsg.str ());
5281 if (comm->getSize () == 1 && map.is_null ()) {
5283 if (! err.is_null ()) {
5287 *err << myRank <<
": readVectorImpl: done" << endl;
5289 if (! err.is_null ()) {
5296 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
5300 RCP<MV> Y = createVector<ST, LO, GO, NT> (map);
5303 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
5309 Export<LO, GO, NT> exporter (proc0Map, map, err);
5312 *err << myRank <<
": readVectorImpl: Exporting" << endl;
5315 Y->doExport (*X, exporter,
INSERT);
5317 if (! err.is_null ()) {
5321 *err << myRank <<
": readVectorImpl: done" << endl;
5323 if (! err.is_null ()) {
5352 static Teuchos::RCP<const map_type>
5354 const Teuchos::RCP<const comm_type>& comm,
5355 const bool tolerant=
false,
5356 const bool debug=
false)
5358 Teuchos::RCP<Teuchos::FancyOStream> err =
5359 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
5360 return readMap (in, comm, err, tolerant, debug);
5365 static Teuchos::RCP<const map_type>
5367 const Teuchos::RCP<const comm_type>& comm,
5368 const Teuchos::RCP<node_type>& node,
5369 const bool tolerant=
false,
5370 const bool debug=
false)
5372 Teuchos::RCP<Teuchos::FancyOStream> err =
5373 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
5374 return readMap (in, comm, node, err, tolerant, debug);
5402 static Teuchos::RCP<const map_type>
5404 const Teuchos::RCP<const comm_type>& comm,
5405 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5406 const bool tolerant=
false,
5407 const bool debug=
false)
5409 return readMap (in, comm, Teuchos::null, err, tolerant, debug);
5414 static Teuchos::RCP<const map_type>
5416 const Teuchos::RCP<const comm_type>& comm,
5417 const Teuchos::RCP<node_type>& node,
5418 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5419 const bool tolerant=
false,
5420 const bool debug=
false)
5422 using Teuchos::arcp;
5423 using Teuchos::Array;
5424 using Teuchos::ArrayRCP;
5426 using Teuchos::broadcast;
5427 using Teuchos::Comm;
5428 using Teuchos::CommRequest;
5429 using Teuchos::inOutArg;
5430 using Teuchos::ireceive;
5431 using Teuchos::outArg;
5433 using Teuchos::receive;
5434 using Teuchos::reduceAll;
5435 using Teuchos::REDUCE_MIN;
5436 using Teuchos::isend;
5437 using Teuchos::SerialComm;
5438 using Teuchos::toString;
5439 using Teuchos::wait;
5442 typedef ptrdiff_t int_type;
5448 const int numProcs = comm->getSize ();
5449 const int myRank = comm->getRank ();
5451 if (err.is_null ()) {
5455 std::ostringstream os;
5456 os << myRank <<
": readMap: " << endl;
5459 if (err.is_null ()) {
5465 const int sizeTag = 1339;
5467 const int dataTag = 1340;
5473 RCP<CommRequest<int> > sizeReq;
5474 RCP<CommRequest<int> > dataReq;
5479 ArrayRCP<int_type> numGidsToRecv (1);
5480 numGidsToRecv[0] = 0;
5482 sizeReq = ireceive<int, int_type> (numGidsToRecv, 0, sizeTag, *comm);
5485 int readSuccess = 1;
5486 std::ostringstream exMsg;
5495 RCP<const Comm<int> > proc0Comm (
new SerialComm<int> ());
5497 RCP<const map_type> dataMap;
5501 data = readDenseImpl<GO> (in, proc0Comm, node, dataMap,
5502 err, tolerant, debug);
5504 if (data.is_null ()) {
5506 exMsg <<
"readDenseImpl() returned null." << endl;
5508 }
catch (std::exception& e) {
5510 exMsg << e.what () << endl;
5516 std::map<int, Array<GO> > pid2gids;
5521 int_type globalNumGIDs = 0;
5531 if (myRank == 0 && readSuccess == 1) {
5532 if (data->getNumVectors () == 2) {
5533 ArrayRCP<const GO> GIDs = data->getData (0);
5534 ArrayRCP<const GO> PIDs = data->getData (1);
5535 globalNumGIDs = GIDs.size ();
5539 if (globalNumGIDs > 0) {
5540 const int pid = static_cast<int> (PIDs[0]);
5542 if (pid < 0 || pid >= numProcs) {
5544 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5545 <<
"Encountered invalid PID " << pid <<
"." << endl;
5548 const GO gid = GIDs[0];
5549 pid2gids[pid].push_back (gid);
5553 if (readSuccess == 1) {
5556 for (size_type k = 1; k < globalNumGIDs; ++k) {
5557 const int pid = static_cast<int> (PIDs[k]);
5558 if (pid < 0 || pid >= numProcs) {
5560 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5561 <<
"Encountered invalid PID " << pid <<
"." << endl;
5564 const int_type gid = GIDs[k];
5565 pid2gids[pid].push_back (gid);
5566 if (gid < indexBase) {
5573 else if (data->getNumVectors () == 1) {
5574 if (data->getGlobalLength () % 2 != static_cast<GST> (0)) {
5576 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
5577 "wrong format (for Map format 2.0). The global number of rows "
5578 "in the MultiVector must be even (divisible by 2)." << endl;
5581 ArrayRCP<const GO> theData = data->getData (0);
5582 globalNumGIDs = static_cast<GO> (data->getGlobalLength ()) /
5583 static_cast<GO> (2);
5587 if (globalNumGIDs > 0) {
5588 const int pid = static_cast<int> (theData[1]);
5589 if (pid < 0 || pid >= numProcs) {
5591 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5592 <<
"Encountered invalid PID " << pid <<
"." << endl;
5595 const GO gid = theData[0];
5596 pid2gids[pid].push_back (gid);
5602 for (int_type k = 1; k < globalNumGIDs; ++k) {
5603 const int pid = static_cast<int> (theData[2*k + 1]);
5604 if (pid < 0 || pid >= numProcs) {
5606 exMsg <<
"Tpetra::MatrixMarket::readMap: "
5607 <<
"Encountered invalid PID " << pid <<
"." << endl;
5610 const GO gid = theData[2*k];
5611 pid2gids[pid].push_back (gid);
5612 if (gid < indexBase) {
5621 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
5622 "either 1 column (for the new Map format 2.0) or 2 columns (for "
5623 "the old Map format 1.0).";
5630 int_type readResults[3];
5631 readResults[0] = static_cast<int_type> (indexBase);
5632 readResults[1] = static_cast<int_type> (globalNumGIDs);
5633 readResults[2] = static_cast<int_type> (readSuccess);
5634 broadcast<int, int_type> (*comm, 0, 3, readResults);
5636 indexBase = static_cast<GO> (readResults[0]);
5637 globalNumGIDs = static_cast<int_type> (readResults[1]);
5638 readSuccess = static_cast<int> (readResults[2]);
5644 TEUCHOS_TEST_FOR_EXCEPTION(
5645 readSuccess != 1, std::runtime_error,
5646 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
5647 "following exception message: " << exMsg.str ());
5651 for (
int p = 1; p < numProcs; ++p) {
5652 ArrayRCP<int_type> numGidsToSend (1);
5654 typename std::map<int, Array<GO> >::const_iterator it = pid2gids.find (p);
5655 if (it == pid2gids.end ()) {
5656 numGidsToSend[0] = 0;
5658 numGidsToSend[0] = it->second.size ();
5660 sizeReq = isend<int, int_type> (numGidsToSend, p, sizeTag, *comm);
5661 wait<int> (*comm, outArg (sizeReq));
5666 wait<int> (*comm, outArg (sizeReq));
5671 ArrayRCP<GO> myGids;
5672 int_type myNumGids = 0;
5674 GO* myGidsRaw = NULL;
5676 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (0);
5677 if (it != pid2gids.end ()) {
5678 myGidsRaw = it->second.getRawPtr ();
5679 myNumGids = it->second.size ();
5681 myGids = arcp<GO> (myGidsRaw, 0, myNumGids,
false);
5685 myNumGids = numGidsToRecv[0];
5686 myGids = arcp<GO> (myNumGids);
5693 if (myNumGids > 0) {
5694 dataReq = ireceive<int, GO> (myGids, 0, dataTag, *comm);
5698 for (
int p = 1; p < numProcs; ++p) {
5700 ArrayRCP<GO> sendGids;
5701 GO* sendGidsRaw = NULL;
5702 int_type numSendGids = 0;
5704 typename std::map<int, Array<GO> >::iterator it = pid2gids.find (p);
5705 if (it != pid2gids.end ()) {
5706 numSendGids = it->second.size ();
5707 sendGidsRaw = it->second.getRawPtr ();
5708 sendGids = arcp<GO> (sendGidsRaw, 0, numSendGids,
false);
5711 if (numSendGids > 0) {
5712 dataReq = isend<int, GO> (sendGids, p, dataTag, *comm);
5714 wait<int> (*comm, outArg (dataReq));
5716 else if (myRank == p) {
5718 wait<int> (*comm, outArg (dataReq));
5723 std::ostringstream os;
5724 os << myRank <<
": readMap: creating Map" << endl;
5727 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
5728 RCP<const map_type> newMap;
5735 std::ostringstream errStrm;
5737 if (node.is_null ()) {
5738 newMap = rcp (
new map_type (INVALID, myGids (), indexBase, comm));
5741 newMap = rcp (
new map_type (INVALID, myGids (), indexBase, comm, node));
5744 catch (std::exception& e) {
5746 errStrm <<
"Process " << comm->getRank () <<
" threw an exception: "
5747 << e.what () << std::endl;
5751 errStrm <<
"Process " << comm->getRank () <<
" threw an exception "
5752 "not a subclass of std::exception" << std::endl;
5754 Teuchos::reduceAll<int, int> (*comm, Teuchos::REDUCE_MIN,
5755 lclSuccess, Teuchos::outArg (gblSuccess));
5756 if (gblSuccess != 1) {
5759 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
5761 if (err.is_null ()) {
5765 std::ostringstream os;
5766 os << myRank <<
": readMap: done" << endl;
5769 if (err.is_null ()) {
5788 encodeDataType (
const std::string& dataType)
5790 if (dataType ==
"real" || dataType ==
"integer") {
5792 }
else if (dataType ==
"complex") {
5794 }
else if (dataType ==
"pattern") {
5800 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
5801 "Unrecognized Matrix Market data type \"" << dataType
5802 <<
"\". We should never get here. "
5803 "Please report this bug to the Tpetra developers.");
5836 template<
class SparseMatrixType>
5841 typedef Teuchos::RCP<sparse_matrix_type> sparse_matrix_ptr;
5902 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5903 const std::string& matrixName,
5904 const std::string& matrixDescription,
5905 const bool debug=
false)
5907 TEUCHOS_TEST_FOR_EXCEPTION(
5908 pMatrix.is_null (), std::invalid_argument,
5909 "The input matrix is null.");
5910 Teuchos::RCP<const Teuchos::Comm<int> > comm = pMatrix->getComm ();
5911 TEUCHOS_TEST_FOR_EXCEPTION(
5912 comm.is_null (), std::invalid_argument,
5913 "The input matrix's communicator (Teuchos::Comm object) is null.");
5914 const int myRank = comm->getRank ();
5920 out.open (filename.c_str ());
5922 writeSparse (out, pMatrix, matrixName, matrixDescription, debug);
5950 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5951 const bool debug=
false)
5988 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5989 const std::string& matrixName,
5990 const std::string& matrixDescription,
5991 const bool debug=
false)
5993 using Teuchos::ArrayView;
5994 using Teuchos::Comm;
5995 using Teuchos::FancyOStream;
5996 using Teuchos::getFancyOStream;
5997 using Teuchos::null;
5999 using Teuchos::rcpFromRef;
6005 typedef typename Teuchos::ScalarTraits<ST> STS;
6006 typedef typename ArrayView<const LO>::const_iterator lo_iter;
6007 typedef typename ArrayView<const GO>::const_iterator go_iter;
6008 typedef typename ArrayView<const ST>::const_iterator st_iter;
6010 TEUCHOS_TEST_FOR_EXCEPTION(
6011 pMatrix.is_null (), std::invalid_argument,
6012 "The input matrix is null.");
6018 Teuchos::SetScientific<ST> sci (out);
6021 RCP<const Comm<int> > comm = pMatrix->getComm ();
6022 TEUCHOS_TEST_FOR_EXCEPTION(
6023 comm.is_null (), std::invalid_argument,
6024 "The input matrix's communicator (Teuchos::Comm object) is null.");
6025 const int myRank = comm->getRank ();
6028 RCP<FancyOStream> err =
6029 debug ? getFancyOStream (rcpFromRef (std::cerr)) :
null;
6031 std::ostringstream os;
6032 os << myRank <<
": writeSparse" << endl;
6035 os <<
"-- " << myRank <<
": past barrier" << endl;
6040 const bool debugPrint = debug && myRank == 0;
6042 RCP<const map_type> rowMap = pMatrix->getRowMap ();
6043 RCP<const map_type> colMap = pMatrix->getColMap ();
6044 RCP<const map_type> domainMap = pMatrix->getDomainMap ();
6045 RCP<const map_type> rangeMap = pMatrix->getRangeMap ();
6047 const global_size_t numRows = rangeMap->getGlobalNumElements ();
6048 const global_size_t numCols = domainMap->getGlobalNumElements ();
6050 if (debug && myRank == 0) {
6051 std::ostringstream os;
6052 os <<
"-- Input sparse matrix is:"
6053 <<
"---- " << numRows <<
" x " << numCols << endl
6055 << (pMatrix->isGloballyIndexed() ?
"Globally" :
"Locally")
6056 <<
" indexed." << endl
6057 <<
"---- Its row map has " << rowMap->getGlobalNumElements ()
6058 <<
" elements." << endl
6059 <<
"---- Its col map has " << colMap->getGlobalNumElements ()
6060 <<
" elements." << endl;
6065 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6067 std::ostringstream os;
6068 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6071 RCP<const map_type> gatherRowMap =
6072 Details::computeGatherMap (rowMap, err, debug);
6080 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6081 RCP<const map_type> gatherColMap =
6082 Details::computeGatherMap (colMap, err, debug);
6086 import_type importer (rowMap, gatherRowMap);
6091 RCP<sparse_matrix_type> newMatrix =
6093 static_cast<size_t> (0)));
6095 newMatrix->doImport (*pMatrix, importer,
INSERT);
6100 RCP<const map_type> gatherDomainMap =
6101 rcp (
new map_type (numCols, localNumCols,
6102 domainMap->getIndexBase (),
6104 RCP<const map_type> gatherRangeMap =
6105 rcp (
new map_type (numRows, localNumRows,
6106 rangeMap->getIndexBase (),
6108 newMatrix->fillComplete (gatherDomainMap, gatherRangeMap);
6112 cerr <<
"-- Output sparse matrix is:"
6113 <<
"---- " << newMatrix->getRangeMap ()->getGlobalNumElements ()
6115 << newMatrix->getDomainMap ()->getGlobalNumElements ()
6117 << newMatrix->getGlobalNumEntries () <<
" entries;" << endl
6119 << (newMatrix->isGloballyIndexed () ?
"Globally" :
"Locally")
6120 <<
" indexed." << endl
6121 <<
"---- Its row map has "
6122 << newMatrix->getRowMap ()->getGlobalNumElements ()
6123 <<
" elements, with index base "
6124 << newMatrix->getRowMap ()->getIndexBase () <<
"." << endl
6125 <<
"---- Its col map has "
6126 << newMatrix->getColMap ()->getGlobalNumElements ()
6127 <<
" elements, with index base "
6128 << newMatrix->getColMap ()->getIndexBase () <<
"." << endl
6129 <<
"---- Element count of output matrix's column Map may differ "
6130 <<
"from that of the input matrix's column Map, if some columns "
6131 <<
"of the matrix contain no entries." << endl;
6144 out <<
"%%MatrixMarket matrix coordinate "
6145 << (STS::isComplex ?
"complex" :
"real")
6146 <<
" general" << endl;
6149 if (matrixName !=
"") {
6150 printAsComment (out, matrixName);
6152 if (matrixDescription !=
"") {
6153 printAsComment (out, matrixDescription);
6163 out << newMatrix->getRangeMap ()->getGlobalNumElements () <<
" "
6164 << newMatrix->getDomainMap ()->getGlobalNumElements () <<
" "
6165 << newMatrix->getGlobalNumEntries () << endl;
6170 const GO rowIndexBase = gatherRowMap->getIndexBase ();
6171 const GO colIndexBase = newMatrix->getColMap()->getIndexBase ();
6179 if (newMatrix->isGloballyIndexed()) {
6182 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
6183 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
6184 for (GO globalRowIndex = minAllGlobalIndex;
6185 globalRowIndex <= maxAllGlobalIndex;
6187 ArrayView<const GO> ind;
6188 ArrayView<const ST> val;
6189 newMatrix->getGlobalRowView (globalRowIndex, ind, val);
6190 go_iter indIter = ind.begin ();
6191 st_iter valIter = val.begin ();
6192 for (; indIter != ind.end() && valIter != val.end();
6193 ++indIter, ++valIter) {
6194 const GO globalColIndex = *indIter;
6197 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6198 << (globalColIndex + 1 - colIndexBase) <<
" ";
6199 if (STS::isComplex) {
6200 out << STS::real (*valIter) <<
" " << STS::imag (*valIter);
6208 typedef Teuchos::OrdinalTraits<GO> OTG;
6209 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
6210 localRowIndex <= gatherRowMap->getMaxLocalIndex();
6213 const GO globalRowIndex =
6214 gatherRowMap->getGlobalElement (localRowIndex);
6215 TEUCHOS_TEST_FOR_EXCEPTION(
6216 globalRowIndex == OTG::invalid(), std::logic_error,
6217 "Failed to convert the supposed local row index "
6218 << localRowIndex <<
" into a global row index. "
6219 "Please report this bug to the Tpetra developers.");
6220 ArrayView<const LO> ind;
6221 ArrayView<const ST> val;
6222 newMatrix->getLocalRowView (localRowIndex, ind, val);
6223 lo_iter indIter = ind.begin ();
6224 st_iter valIter = val.begin ();
6225 for (; indIter != ind.end() && valIter != val.end();
6226 ++indIter, ++valIter) {
6228 const GO globalColIndex =
6229 newMatrix->getColMap()->getGlobalElement (*indIter);
6230 TEUCHOS_TEST_FOR_EXCEPTION(
6231 globalColIndex == OTG::invalid(), std::logic_error,
6232 "On local row " << localRowIndex <<
" of the sparse matrix: "
6233 "Failed to convert the supposed local column index "
6234 << *indIter <<
" into a global column index. Please report "
6235 "this bug to the Tpetra developers.");
6238 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6239 << (globalColIndex + 1 - colIndexBase) <<
" ";
6240 if (STS::isComplex) {
6241 out << STS::real (*valIter) <<
" " << STS::imag (*valIter);
6286 const std::string& graphName,
6287 const std::string& graphDescription,
6288 const bool debug=
false)
6290 using Teuchos::ArrayView;
6291 using Teuchos::Comm;
6292 using Teuchos::FancyOStream;
6293 using Teuchos::getFancyOStream;
6294 using Teuchos::null;
6296 using Teuchos::rcpFromRef;
6307 if (rowMap.is_null ()) {
6310 auto comm = rowMap->getComm ();
6311 if (comm.is_null ()) {
6314 const int myRank = comm->getRank ();
6317 RCP<FancyOStream> err =
6318 debug ? getFancyOStream (rcpFromRef (std::cerr)) :
null;
6320 std::ostringstream os;
6321 os << myRank <<
": writeSparseGraph" << endl;
6324 os <<
"-- " << myRank <<
": past barrier" << endl;
6329 const bool debugPrint = debug && myRank == 0;
6336 const global_size_t numRows = rangeMap->getGlobalNumElements ();
6337 const global_size_t numCols = domainMap->getGlobalNumElements ();
6339 if (debug && myRank == 0) {
6340 std::ostringstream os;
6341 os <<
"-- Input sparse graph is:"
6342 <<
"---- " << numRows <<
" x " << numCols <<
" with "
6346 <<
" indexed." << endl
6347 <<
"---- Its row Map has " << rowMap->getGlobalNumElements ()
6348 <<
" elements." << endl
6349 <<
"---- Its col Map has " << colMap->getGlobalNumElements ()
6350 <<
" elements." << endl;
6355 const size_t localNumRows = (myRank == 0) ? numRows : 0;
6357 std::ostringstream os;
6358 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
6361 auto gatherRowMap = Details::computeGatherMap (rowMap, err, debug);
6369 const size_t localNumCols = (myRank == 0) ? numCols : 0;
6370 auto gatherColMap = Details::computeGatherMap (colMap, err, debug);
6379 static_cast<size_t> (0));
6386 RCP<const map_type> gatherDomainMap =
6387 rcp (
new map_type (numCols, localNumCols,
6388 domainMap->getIndexBase (),
6390 RCP<const map_type> gatherRangeMap =
6391 rcp (
new map_type (numRows, localNumRows,
6392 rangeMap->getIndexBase (),
6394 newGraph.
fillComplete (gatherDomainMap, gatherRangeMap);
6398 cerr <<
"-- Output sparse graph is:"
6399 <<
"---- " << newGraph.
getRangeMap ()->getGlobalNumElements ()
6406 <<
" indexed." << endl
6407 <<
"---- Its row map has "
6408 << newGraph.
getRowMap ()->getGlobalNumElements ()
6409 <<
" elements, with index base "
6410 << newGraph.
getRowMap ()->getIndexBase () <<
"." << endl
6411 <<
"---- Its col map has "
6412 << newGraph.
getColMap ()->getGlobalNumElements ()
6413 <<
" elements, with index base "
6414 << newGraph.
getColMap ()->getIndexBase () <<
"." << endl
6415 <<
"---- Element count of output graph's column Map may differ "
6416 <<
"from that of the input matrix's column Map, if some columns "
6417 <<
"of the matrix contain no entries." << endl;
6431 out <<
"%%MatrixMarket matrix coordinate pattern general" << endl;
6434 if (graphName !=
"") {
6435 printAsComment (out, graphName);
6437 if (graphDescription !=
"") {
6438 printAsComment (out, graphDescription);
6449 out << newGraph.
getRangeMap ()->getGlobalNumElements () <<
" "
6450 << newGraph.
getDomainMap ()->getGlobalNumElements () <<
" "
6456 const GO rowIndexBase = gatherRowMap->getIndexBase ();
6457 const GO colIndexBase = newGraph.
getColMap()->getIndexBase ();
6468 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex ();
6469 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex ();
6470 for (GO globalRowIndex = minAllGlobalIndex;
6471 globalRowIndex <= maxAllGlobalIndex;
6473 ArrayView<const GO> ind;
6475 for (
auto indIter = ind.begin (); indIter != ind.end (); ++indIter) {
6476 const GO globalColIndex = *indIter;
6479 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6480 << (globalColIndex + 1 - colIndexBase) <<
" ";
6486 typedef Teuchos::OrdinalTraits<GO> OTG;
6487 for (LO localRowIndex = gatherRowMap->getMinLocalIndex ();
6488 localRowIndex <= gatherRowMap->getMaxLocalIndex ();
6491 const GO globalRowIndex =
6492 gatherRowMap->getGlobalElement (localRowIndex);
6493 TEUCHOS_TEST_FOR_EXCEPTION
6494 (globalRowIndex == OTG::invalid (), std::logic_error,
"Failed "
6495 "to convert the supposed local row index " << localRowIndex <<
6496 " into a global row index. Please report this bug to the "
6497 "Tpetra developers.");
6498 ArrayView<const LO> ind;
6500 for (
auto indIter = ind.begin (); indIter != ind.end (); ++indIter) {
6502 const GO globalColIndex =
6503 newGraph.
getColMap ()->getGlobalElement (*indIter);
6504 TEUCHOS_TEST_FOR_EXCEPTION(
6505 globalColIndex == OTG::invalid(), std::logic_error,
6506 "On local row " << localRowIndex <<
" of the sparse graph: "
6507 "Failed to convert the supposed local column index "
6508 << *indIter <<
" into a global column index. Please report "
6509 "this bug to the Tpetra developers.");
6512 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
6513 << (globalColIndex + 1 - colIndexBase) <<
" ";
6529 const bool debug=
false)
6571 const std::string& graphName,
6572 const std::string& graphDescription,
6573 const bool debug=
false)
6576 if (comm.is_null ()) {
6584 const int myRank = comm->getRank ();
6589 out.open (filename.c_str ());
6604 const bool debug=
false)
6619 const Teuchos::RCP<const crs_graph_type>& pGraph,
6620 const std::string& graphName,
6621 const std::string& graphDescription,
6622 const bool debug=
false)
6638 const Teuchos::RCP<const crs_graph_type>& pGraph,
6639 const bool debug=
false)
6668 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
6669 const bool debug=
false)
6705 const std::string& matrixName,
6706 const std::string& matrixDescription,
6707 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6708 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6710 const int myRank = X.
getMap ().is_null () ? 0 :
6711 (X.
getMap ()->getComm ().is_null () ? 0 :
6712 X.
getMap ()->getComm ()->getRank ());
6716 out.open (filename.c_str());
6719 writeDense (out, X, matrixName, matrixDescription, err, dbg);
6732 const Teuchos::RCP<const multivector_type>& X,
6733 const std::string& matrixName,
6734 const std::string& matrixDescription,
6735 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6736 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6738 TEUCHOS_TEST_FOR_EXCEPTION(
6739 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
6740 "writeDenseFile: The input MultiVector X is null.");
6741 writeDenseFile (filename, *X, matrixName, matrixDescription, err, dbg);
6752 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6753 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6765 const Teuchos::RCP<const multivector_type>& X,
6766 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6767 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6769 TEUCHOS_TEST_FOR_EXCEPTION(
6770 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
6771 "writeDenseFile: The input MultiVector X is null.");
6809 const std::string& matrixName,
6810 const std::string& matrixDescription,
6811 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6812 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6814 using Teuchos::Comm;
6815 using Teuchos::outArg;
6816 using Teuchos::REDUCE_MAX;
6817 using Teuchos::reduceAll;
6821 RCP<const Comm<int> > comm = X.
getMap ().is_null () ?
6822 Teuchos::null : X.
getMap ()->getComm ();
6823 const int myRank = comm.is_null () ? 0 : comm->getRank ();
6828 const bool debug = ! dbg.is_null ();
6831 std::ostringstream os;
6832 os << myRank <<
": writeDense" << endl;
6837 writeDenseHeader (out, X, matrixName, matrixDescription, err, dbg);
6842 for (
size_t j = 0; j < numVecs; ++j) {
6843 writeDenseColumn (out, * (X.
getVector (j)), err, dbg);
6848 std::ostringstream os;
6849 os << myRank <<
": writeDense: Done" << endl;
6883 writeDenseHeader (std::ostream& out,
6885 const std::string& matrixName,
6886 const std::string& matrixDescription,
6887 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
6888 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
6890 using Teuchos::Comm;
6891 using Teuchos::outArg;
6893 using Teuchos::REDUCE_MAX;
6894 using Teuchos::reduceAll;
6897 typedef Teuchos::ScalarTraits<scalar_type> STS;
6898 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
6900 RCP<const Comm<int> > comm = X.getMap ().is_null () ?
6901 Teuchos::null : X.getMap ()->getComm ();
6902 const int myRank = comm.is_null () ? 0 : comm->getRank ();
6909 const bool debug = ! dbg.is_null ();
6913 std::ostringstream os;
6914 os << myRank <<
": writeDenseHeader" << endl;
6933 std::ostringstream hdr;
6935 std::string dataType;
6936 if (STS::isComplex) {
6937 dataType =
"complex";
6938 }
else if (STS::isOrdinal) {
6939 dataType =
"integer";
6943 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
6948 if (matrixName !=
"") {
6949 printAsComment (hdr, matrixName);
6951 if (matrixDescription !=
"") {
6952 printAsComment (hdr, matrixDescription);
6955 hdr << X.getGlobalLength () <<
" " << X.getNumVectors () << endl;
6959 }
catch (std::exception& e) {
6960 if (! err.is_null ()) {
6961 *err << prefix <<
"While writing the Matrix Market header, "
6962 "Process 0 threw an exception: " << e.what () << endl;
6971 reduceAll<int, int> (*comm, REDUCE_MAX, lclErr, outArg (gblErr));
6972 TEUCHOS_TEST_FOR_EXCEPTION(
6973 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
6974 "which prevented this method from completing.");
6978 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
7001 writeDenseColumn (std::ostream& out,
7003 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7004 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7006 using Teuchos::arcp;
7007 using Teuchos::Array;
7008 using Teuchos::ArrayRCP;
7009 using Teuchos::ArrayView;
7010 using Teuchos::Comm;
7011 using Teuchos::CommRequest;
7012 using Teuchos::ireceive;
7013 using Teuchos::isend;
7014 using Teuchos::outArg;
7015 using Teuchos::REDUCE_MAX;
7016 using Teuchos::reduceAll;
7018 using Teuchos::TypeNameTraits;
7019 using Teuchos::wait;
7022 typedef Teuchos::ScalarTraits<scalar_type> STS;
7024 const Comm<int>& comm = * (X.getMap ()->getComm ());
7025 const int myRank = comm.getRank ();
7026 const int numProcs = comm.getSize ();
7033 const bool debug = ! dbg.is_null ();
7037 std::ostringstream os;
7038 os << myRank <<
": writeDenseColumn" << endl;
7047 Teuchos::SetScientific<scalar_type> sci (out);
7049 const size_t myNumRows = X.getLocalLength ();
7050 const size_t numCols = X.getNumVectors ();
7053 const int sizeTag = 1337;
7054 const int dataTag = 1338;
7115 RCP<CommRequest<int> > sendReqSize, sendReqData;
7121 Array<ArrayRCP<size_t> > recvSizeBufs (3);
7122 Array<ArrayRCP<scalar_type> > recvDataBufs (3);
7123 Array<RCP<CommRequest<int> > > recvSizeReqs (3);
7124 Array<RCP<CommRequest<int> > > recvDataReqs (3);
7127 ArrayRCP<size_t> sendDataSize (1);
7128 sendDataSize[0] = myNumRows;
7132 std::ostringstream os;
7133 os << myRank <<
": Post receive-size receives from "
7134 "Procs 1 and 2: tag = " << sizeTag << endl;
7138 recvSizeBufs[0].resize (1);
7142 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7143 recvSizeBufs[1].resize (1);
7144 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7145 recvSizeBufs[2].resize (1);
7146 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid ();
7149 ireceive<int, size_t> (recvSizeBufs[1], 1, sizeTag, comm);
7153 ireceive<int, size_t> (recvSizeBufs[2], 2, sizeTag, comm);
7156 else if (myRank == 1 || myRank == 2) {
7158 std::ostringstream os;
7159 os << myRank <<
": Post send-size send: size = "
7160 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7167 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
7171 std::ostringstream os;
7172 os << myRank <<
": Not posting my send-size send yet" << endl;
7181 std::ostringstream os;
7182 os << myRank <<
": Pack my entries" << endl;
7185 ArrayRCP<scalar_type> sendDataBuf;
7187 sendDataBuf = arcp<scalar_type> (myNumRows * numCols);
7188 X.get1dCopy (sendDataBuf (), myNumRows);
7190 catch (std::exception& e) {
7192 if (! err.is_null ()) {
7193 std::ostringstream os;
7194 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
7195 "entries threw an exception: " << e.what () << endl;
7200 std::ostringstream os;
7201 os << myRank <<
": Done packing my entries" << endl;
7210 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
7213 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7221 std::ostringstream os;
7222 os << myRank <<
": Write my entries" << endl;
7228 const size_t printNumRows = myNumRows;
7229 ArrayView<const scalar_type> printData = sendDataBuf ();
7230 const size_t printStride = printNumRows;
7231 if (static_cast<size_t> (printData.size ()) < printStride * numCols) {
7233 if (! err.is_null ()) {
7234 std::ostringstream os;
7235 os <<
"Process " << myRank <<
": My MultiVector data's size "
7236 << printData.size () <<
" does not match my local dimensions "
7237 << printStride <<
" x " << numCols <<
"." << endl;
7245 for (
size_t col = 0; col < numCols; ++col) {
7246 for (
size_t row = 0; row < printNumRows; ++row) {
7247 if (STS::isComplex) {
7248 out << STS::real (printData[row + col * printStride]) <<
" "
7249 << STS::imag (printData[row + col * printStride]) << endl;
7251 out << printData[row + col * printStride] << endl;
7260 const int recvRank = 1;
7261 const int circBufInd = recvRank % 3;
7263 std::ostringstream os;
7264 os << myRank <<
": Wait on receive-size receive from Process "
7265 << recvRank << endl;
7269 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7273 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7274 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7276 if (! err.is_null ()) {
7277 std::ostringstream os;
7278 os << myRank <<
": Result of receive-size receive from Process "
7279 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7280 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7281 "This should never happen, and suggests that the receive never "
7282 "got posted. Please report this bug to the Tpetra developers."
7297 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7299 std::ostringstream os;
7300 os << myRank <<
": Post receive-data receive from Process "
7301 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7302 << recvDataBufs[circBufInd].size () << endl;
7305 if (! recvSizeReqs[circBufInd].is_null ()) {
7307 if (! err.is_null ()) {
7308 std::ostringstream os;
7309 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7310 "null, before posting the receive-data receive from Process "
7311 << recvRank <<
". This should never happen. Please report "
7312 "this bug to the Tpetra developers." << endl;
7316 recvDataReqs[circBufInd] =
7317 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7318 recvRank, dataTag, comm);
7321 else if (myRank == 1) {
7324 std::ostringstream os;
7325 os << myRank <<
": Wait on my send-size send" << endl;
7328 wait<int> (comm, outArg (sendReqSize));
7334 for (
int p = 1; p < numProcs; ++p) {
7336 if (p + 2 < numProcs) {
7338 const int recvRank = p + 2;
7339 const int circBufInd = recvRank % 3;
7341 std::ostringstream os;
7342 os << myRank <<
": Post receive-size receive from Process "
7343 << recvRank <<
": tag = " << sizeTag << endl;
7346 if (! recvSizeReqs[circBufInd].is_null ()) {
7348 if (! err.is_null ()) {
7349 std::ostringstream os;
7350 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7351 <<
"null, for the receive-size receive from Process "
7352 << recvRank <<
"! This may mean that this process never "
7353 <<
"finished waiting for the receive from Process "
7354 << (recvRank - 3) <<
"." << endl;
7358 recvSizeReqs[circBufInd] =
7359 ireceive<int, size_t> (recvSizeBufs[circBufInd],
7360 recvRank, sizeTag, comm);
7363 if (p + 1 < numProcs) {
7364 const int recvRank = p + 1;
7365 const int circBufInd = recvRank % 3;
7369 std::ostringstream os;
7370 os << myRank <<
": Wait on receive-size receive from Process "
7371 << recvRank << endl;
7374 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7378 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
7379 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7381 if (! err.is_null ()) {
7382 std::ostringstream os;
7383 os << myRank <<
": Result of receive-size receive from Process "
7384 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
7385 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid () <<
". "
7386 "This should never happen, and suggests that the receive never "
7387 "got posted. Please report this bug to the Tpetra developers."
7401 recvDataBufs[circBufInd].resize (recvNumRows * numCols);
7403 std::ostringstream os;
7404 os << myRank <<
": Post receive-data receive from Process "
7405 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7406 << recvDataBufs[circBufInd].size () << endl;
7409 if (! recvDataReqs[circBufInd].is_null ()) {
7411 if (! err.is_null ()) {
7412 std::ostringstream os;
7413 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
7414 <<
"null, for the receive-data receive from Process "
7415 << recvRank <<
"! This may mean that this process never "
7416 <<
"finished waiting for the receive from Process "
7417 << (recvRank - 3) <<
"." << endl;
7421 recvDataReqs[circBufInd] =
7422 ireceive<int, scalar_type> (recvDataBufs[circBufInd],
7423 recvRank, dataTag, comm);
7427 const int recvRank = p;
7428 const int circBufInd = recvRank % 3;
7430 std::ostringstream os;
7431 os << myRank <<
": Wait on receive-data receive from Process "
7432 << recvRank << endl;
7435 wait<int> (comm, outArg (recvDataReqs[circBufInd]));
7442 std::ostringstream os;
7443 os << myRank <<
": Write entries from Process " << recvRank
7445 *dbg << os.str () << endl;
7447 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
7448 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid ()) {
7450 if (! err.is_null ()) {
7451 std::ostringstream os;
7452 os << myRank <<
": Result of receive-size receive from Process "
7453 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
7454 "invalid() = " << Teuchos::OrdinalTraits<size_t>::invalid ()
7455 <<
". This should never happen, and suggests that its "
7456 "receive-size receive was never posted. "
7457 "Please report this bug to the Tpetra developers." << endl;
7464 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null ()) {
7466 if (! err.is_null ()) {
7467 std::ostringstream os;
7468 os << myRank <<
": Result of receive-size receive from Proc "
7469 << recvRank <<
" was " << printNumRows <<
" > 0, but "
7470 "recvDataBufs[" << circBufInd <<
"] is null. This should "
7471 "never happen. Please report this bug to the Tpetra "
7472 "developers." << endl;
7482 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd]) ();
7483 const size_t printStride = printNumRows;
7487 for (
size_t col = 0; col < numCols; ++col) {
7488 for (
size_t row = 0; row < printNumRows; ++row) {
7489 if (STS::isComplex) {
7490 out << STS::real (printData[row + col * printStride]) <<
" "
7491 << STS::imag (printData[row + col * printStride]) << endl;
7493 out << printData[row + col * printStride] << endl;
7498 else if (myRank == p) {
7501 std::ostringstream os;
7502 os << myRank <<
": Wait on my send-data send" << endl;
7505 wait<int> (comm, outArg (sendReqData));
7507 else if (myRank == p + 1) {
7510 std::ostringstream os;
7511 os << myRank <<
": Post send-data send: tag = " << dataTag
7515 sendReqData = isend<int, scalar_type> (sendDataBuf, 0, dataTag, comm);
7518 std::ostringstream os;
7519 os << myRank <<
": Wait on my send-size send" << endl;
7522 wait<int> (comm, outArg (sendReqSize));
7524 else if (myRank == p + 2) {
7527 std::ostringstream os;
7528 os << myRank <<
": Post send-size send: size = "
7529 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7532 sendReqSize = isend<int, size_t> (sendDataSize, 0, sizeTag, comm);
7537 reduceAll<int, int> (comm, REDUCE_MAX, lclErr, outArg (gblErr));
7538 TEUCHOS_TEST_FOR_EXCEPTION(
7539 gblErr == 1, std::runtime_error,
"Tpetra::MatrixMarket::writeDense "
7540 "experienced some kind of error and was unable to complete.");
7544 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
7558 const Teuchos::RCP<const multivector_type>& X,
7559 const std::string& matrixName,
7560 const std::string& matrixDescription,
7561 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7562 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7564 TEUCHOS_TEST_FOR_EXCEPTION(
7565 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7566 "writeDense: The input MultiVector X is null.");
7567 writeDense (out, *X, matrixName, matrixDescription, err, dbg);
7578 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7579 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7591 const Teuchos::RCP<const multivector_type>& X,
7592 const Teuchos::RCP<Teuchos::FancyOStream>& err = Teuchos::null,
7593 const Teuchos::RCP<Teuchos::FancyOStream>& dbg = Teuchos::null)
7595 TEUCHOS_TEST_FOR_EXCEPTION(
7596 X.is_null (), std::invalid_argument,
"Tpetra::MatrixMarket::"
7597 "writeDense: The input MultiVector X is null.");
7623 Teuchos::RCP<Teuchos::FancyOStream> err =
7624 Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr));
7639 const Teuchos::RCP<Teuchos::FancyOStream>& err,
7640 const bool debug=
false)
7642 using Teuchos::Array;
7643 using Teuchos::ArrayRCP;
7644 using Teuchos::ArrayView;
7645 using Teuchos::Comm;
7646 using Teuchos::CommRequest;
7647 using Teuchos::ireceive;
7648 using Teuchos::isend;
7650 using Teuchos::TypeNameTraits;
7651 using Teuchos::wait;
7654 typedef int pid_type;
7669 typedef ptrdiff_t int_type;
7670 TEUCHOS_TEST_FOR_EXCEPTION(
7671 sizeof (GO) >
sizeof (int_type), std::logic_error,
7672 "The global ordinal type GO=" << TypeNameTraits<GO>::name ()
7673 <<
" is too big for ptrdiff_t. sizeof(GO) = " <<
sizeof (GO)
7674 <<
" > sizeof(ptrdiff_t) = " <<
sizeof (ptrdiff_t) <<
".");
7675 TEUCHOS_TEST_FOR_EXCEPTION(
7676 sizeof (pid_type) >
sizeof (int_type), std::logic_error,
7677 "The (MPI) process rank type pid_type=" <<
7678 TypeNameTraits<pid_type>::name () <<
" is too big for ptrdiff_t. "
7679 "sizeof(pid_type) = " <<
sizeof (pid_type) <<
" > sizeof(ptrdiff_t)"
7680 " = " <<
sizeof (ptrdiff_t) <<
".");
7682 const Comm<int>& comm = * (map.
getComm ());
7683 const int myRank = comm.getRank ();
7684 const int numProcs = comm.getSize ();
7686 if (! err.is_null ()) {
7690 std::ostringstream os;
7691 os << myRank <<
": writeMap" << endl;
7694 if (! err.is_null ()) {
7701 const int sizeTag = 1337;
7702 const int dataTag = 1338;
7761 RCP<CommRequest<int> > sendReqSize, sendReqData;
7767 Array<ArrayRCP<int_type> > recvSizeBufs (3);
7768 Array<ArrayRCP<int_type> > recvDataBufs (3);
7769 Array<RCP<CommRequest<int> > > recvSizeReqs (3);
7770 Array<RCP<CommRequest<int> > > recvDataReqs (3);
7773 ArrayRCP<int_type> sendDataSize (1);
7774 sendDataSize[0] = myNumRows;
7778 std::ostringstream os;
7779 os << myRank <<
": Post receive-size receives from "
7780 "Procs 1 and 2: tag = " << sizeTag << endl;
7784 recvSizeBufs[0].resize (1);
7785 (recvSizeBufs[0])[0] = -1;
7786 recvSizeBufs[1].resize (1);
7787 (recvSizeBufs[1])[0] = -1;
7788 recvSizeBufs[2].resize (1);
7789 (recvSizeBufs[2])[0] = -1;
7792 ireceive<int, int_type> (recvSizeBufs[1], 1, sizeTag, comm);
7796 ireceive<int, int_type> (recvSizeBufs[2], 2, sizeTag, comm);
7799 else if (myRank == 1 || myRank == 2) {
7801 std::ostringstream os;
7802 os << myRank <<
": Post send-size send: size = "
7803 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
7810 sendReqSize = isend<int, int_type> (sendDataSize, 0, sizeTag, comm);
7814 std::ostringstream os;
7815 os << myRank <<
": Not posting my send-size send yet" << endl;
7826 std::ostringstream os;
7827 os << myRank <<
": Pack my GIDs and PIDs" << endl;
7831 ArrayRCP<int_type> sendDataBuf (myNumRows * 2);
7834 const int_type myMinGblIdx =
7836 for (
size_t k = 0; k < myNumRows; ++k) {
7837 const int_type gid = myMinGblIdx + static_cast<int_type> (k);
7838 const int_type pid = static_cast<int_type> (myRank);
7839 sendDataBuf[2*k] = gid;
7840 sendDataBuf[2*k+1] = pid;
7845 for (
size_t k = 0; k < myNumRows; ++k) {
7846 const int_type gid = static_cast<int_type> (myGblInds[k]);
7847 const int_type pid = static_cast<int_type> (myRank);
7848 sendDataBuf[2*k] = gid;
7849 sendDataBuf[2*k+1] = pid;
7854 std::ostringstream os;
7855 os << myRank <<
": Done packing my GIDs and PIDs" << endl;
7862 *err << myRank <<
": Post send-data send: tag = " << dataTag
7865 sendReqData = isend<int, int_type> (sendDataBuf, 0, dataTag, comm);
7870 *err << myRank <<
": Write MatrixMarket header" << endl;
7875 std::ostringstream hdr;
7879 hdr <<
"%%MatrixMarket matrix array integer general" << endl
7880 <<
"% Format: Version 2.0" << endl
7882 <<
"% This file encodes a Tpetra::Map." << endl
7883 <<
"% It is stored as a dense vector, with twice as many " << endl
7884 <<
"% entries as the global number of GIDs (global indices)." << endl
7885 <<
"% (GID, PID) pairs are stored contiguously, where the PID " << endl
7886 <<
"% is the rank of the process owning that GID." << endl
7891 std::ostringstream os;
7892 os << myRank <<
": Write my GIDs and PIDs" << endl;
7898 const int_type printNumRows = myNumRows;
7899 ArrayView<const int_type> printData = sendDataBuf ();
7900 for (int_type k = 0; k < printNumRows; ++k) {
7901 const int_type gid = printData[2*k];
7902 const int_type pid = printData[2*k+1];
7903 out << gid << endl << pid << endl;
7909 const int recvRank = 1;
7910 const int circBufInd = recvRank % 3;
7912 std::ostringstream os;
7913 os << myRank <<
": Wait on receive-size receive from Process "
7914 << recvRank << endl;
7918 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
7922 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
7923 if (debug && recvNumRows == -1) {
7924 std::ostringstream os;
7925 os << myRank <<
": Result of receive-size receive from Process "
7926 << recvRank <<
" is -1. This should never happen, and "
7927 "suggests that the receive never got posted. Please report "
7928 "this bug to the Tpetra developers." << endl;
7933 recvDataBufs[circBufInd].resize (recvNumRows * 2);
7935 std::ostringstream os;
7936 os << myRank <<
": Post receive-data receive from Process "
7937 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
7938 << recvDataBufs[circBufInd].size () << endl;
7941 if (! recvSizeReqs[circBufInd].is_null ()) {
7942 std::ostringstream os;
7943 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7944 "null, before posting the receive-data receive from Process "
7945 << recvRank <<
". This should never happen. Please report "
7946 "this bug to the Tpetra developers." << endl;
7949 recvDataReqs[circBufInd] =
7950 ireceive<int, int_type> (recvDataBufs[circBufInd],
7951 recvRank, dataTag, comm);
7954 else if (myRank == 1) {
7957 std::ostringstream os;
7958 os << myRank <<
": Wait on my send-size send" << endl;
7961 wait<int> (comm, outArg (sendReqSize));
7967 for (
int p = 1; p < numProcs; ++p) {
7969 if (p + 2 < numProcs) {
7971 const int recvRank = p + 2;
7972 const int circBufInd = recvRank % 3;
7974 std::ostringstream os;
7975 os << myRank <<
": Post receive-size receive from Process "
7976 << recvRank <<
": tag = " << sizeTag << endl;
7979 if (! recvSizeReqs[circBufInd].is_null ()) {
7980 std::ostringstream os;
7981 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
7982 <<
"null, for the receive-size receive from Process "
7983 << recvRank <<
"! This may mean that this process never "
7984 <<
"finished waiting for the receive from Process "
7985 << (recvRank - 3) <<
"." << endl;
7988 recvSizeReqs[circBufInd] =
7989 ireceive<int, int_type> (recvSizeBufs[circBufInd],
7990 recvRank, sizeTag, comm);
7993 if (p + 1 < numProcs) {
7994 const int recvRank = p + 1;
7995 const int circBufInd = recvRank % 3;
7999 std::ostringstream os;
8000 os << myRank <<
": Wait on receive-size receive from Process "
8001 << recvRank << endl;
8004 wait<int> (comm, outArg (recvSizeReqs[circBufInd]));
8008 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
8009 if (debug && recvNumRows == -1) {
8010 std::ostringstream os;
8011 os << myRank <<
": Result of receive-size receive from Process "
8012 << recvRank <<
" is -1. This should never happen, and "
8013 "suggests that the receive never got posted. Please report "
8014 "this bug to the Tpetra developers." << endl;
8019 recvDataBufs[circBufInd].resize (recvNumRows * 2);
8021 std::ostringstream os;
8022 os << myRank <<
": Post receive-data receive from Process "
8023 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
8024 << recvDataBufs[circBufInd].size () << endl;
8027 if (! recvDataReqs[circBufInd].is_null ()) {
8028 std::ostringstream os;
8029 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
8030 <<
"null, for the receive-data receive from Process "
8031 << recvRank <<
"! This may mean that this process never "
8032 <<
"finished waiting for the receive from Process "
8033 << (recvRank - 3) <<
"." << endl;
8036 recvDataReqs[circBufInd] =
8037 ireceive<int, int_type> (recvDataBufs[circBufInd],
8038 recvRank, dataTag, comm);
8042 const int recvRank = p;
8043 const int circBufInd = recvRank % 3;
8045 std::ostringstream os;
8046 os << myRank <<
": Wait on receive-data receive from Process "
8047 << recvRank << endl;
8050 wait<int> (comm, outArg (recvDataReqs[circBufInd]));
8057 std::ostringstream os;
8058 os << myRank <<
": Write GIDs and PIDs from Process "
8059 << recvRank << endl;
8060 *err << os.str () << endl;
8062 const int_type printNumRows = (recvSizeBufs[circBufInd])[0];
8063 if (debug && printNumRows == -1) {
8064 std::ostringstream os;
8065 os << myRank <<
": Result of receive-size receive from Process "
8066 << recvRank <<
" was -1. This should never happen, and "
8067 "suggests that its receive-size receive was never posted. "
8068 "Please report this bug to the Tpetra developers." << endl;
8071 if (debug && printNumRows > 0 && recvDataBufs[circBufInd].is_null ()) {
8072 std::ostringstream os;
8073 os << myRank <<
": Result of receive-size receive from Proc "
8074 << recvRank <<
" was " << printNumRows <<
" > 0, but "
8075 "recvDataBufs[" << circBufInd <<
"] is null. This should "
8076 "never happen. Please report this bug to the Tpetra "
8077 "developers." << endl;
8080 ArrayView<const int_type> printData = (recvDataBufs[circBufInd]) ();
8081 for (int_type k = 0; k < printNumRows; ++k) {
8082 const int_type gid = printData[2*k];
8083 const int_type pid = printData[2*k+1];
8084 out << gid << endl << pid << endl;
8087 else if (myRank == p) {
8090 std::ostringstream os;
8091 os << myRank <<
": Wait on my send-data send" << endl;
8094 wait<int> (comm, outArg (sendReqData));
8096 else if (myRank == p + 1) {
8099 std::ostringstream os;
8100 os << myRank <<
": Post send-data send: tag = " << dataTag
8104 sendReqData = isend<int, int_type> (sendDataBuf, 0, dataTag, comm);
8107 std::ostringstream os;
8108 os << myRank <<
": Wait on my send-size send" << endl;
8111 wait<int> (comm, outArg (sendReqSize));
8113 else if (myRank == p + 2) {
8116 std::ostringstream os;
8117 os << myRank <<
": Post send-size send: size = "
8118 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
8121 sendReqSize = isend<int, int_type> (sendDataSize, 0, sizeTag, comm);
8125 if (! err.is_null ()) {
8129 *err << myRank <<
": writeMap: Done" << endl;
8131 if (! err.is_null ()) {
8141 const int myRank = map.
getComm ()->getRank ();
8144 out.open (filename.c_str());
8177 printAsComment (std::ostream& out,
const std::string& str)
8180 std::istringstream inpstream (str);
8183 while (getline (inpstream, line)) {
8184 if (! line.empty()) {
8187 if (line[0] ==
'%') {
8188 out << line << endl;
8191 out <<
"%% " << line << endl;
8219 Teuchos::ParameterList pl;
8245 Teuchos::ParameterList pl;
8288 const Teuchos::ParameterList& params)
8291 std::string tmpFile =
"__TMP__" + fileName;
8292 const int myRank = A.
getDomainMap()->getComm()->getRank();
8293 bool precisionChanged=
false;
8303 if (std::ifstream(tmpFile))
8304 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
8305 "writeOperator: temporary file " << tmpFile <<
" already exists");
8306 out.open(tmpFile.c_str());
8307 if (params.isParameter(
"precision")) {
8308 oldPrecision = out.precision(params.get<
int>(
"precision"));
8309 precisionChanged=
true;
8313 const std::string header = writeOperatorImpl(out, A, params);
8316 if (precisionChanged)
8317 out.precision(oldPrecision);
8319 out.open(fileName.c_str(), std::ios::binary);
8320 bool printMatrixMarketHeader =
true;
8321 if (params.isParameter(
"print MatrixMarket header"))
8322 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
8323 if (printMatrixMarketHeader && myRank == 0) {
8328 std::ifstream src(tmpFile, std::ios_base::binary);
8332 remove(tmpFile.c_str());
8377 const Teuchos::ParameterList& params)
8379 const int myRank = A.
getDomainMap ()->getComm ()->getRank ();
8396 std::ostringstream tmpOut;
8398 if (params.isParameter (
"precision") && params.isType<
int> (
"precision")) {
8399 (void) tmpOut.precision (params.get<
int> (
"precision"));
8403 const std::string header = writeOperatorImpl (tmpOut, A, params);
8406 bool printMatrixMarketHeader =
true;
8407 if (params.isParameter (
"print MatrixMarket header") &&
8408 params.isType<
bool> (
"print MatrixMarket header")) {
8409 printMatrixMarketHeader = params.get<
bool> (
"print MatrixMarket header");
8411 if (printMatrixMarketHeader && myRank == 0) {
8427 out << tmpOut.str ();
8441 writeOperatorImpl (std::ostream& os,
8442 const operator_type& A,
8443 const Teuchos::ParameterList& params)
8447 using Teuchos::ArrayRCP;
8448 using Teuchos::Array;
8453 typedef Teuchos::OrdinalTraits<LO> TLOT;
8454 typedef Teuchos::OrdinalTraits<GO> TGOT;
8458 const map_type& domainMap = *(A.getDomainMap());
8459 RCP<const map_type> rangeMap = A.getRangeMap();
8460 RCP<const Teuchos::Comm<int> > comm = rangeMap->getComm();
8461 const int myRank = comm->getRank();
8462 const size_t numProcs = comm->getSize();
8465 if (params.isParameter(
"probing size"))
8466 numMVs = params.get<
int>(
"probing size");
8469 GO minColGid = domainMap.getMinAllGlobalIndex();
8470 GO maxColGid = domainMap.getMaxAllGlobalIndex();
8475 GO numGlobElts = maxColGid - minColGid + TGOT::one();
8476 GO numChunks = numGlobElts / numMVs;
8477 GO rem = numGlobElts % numMVs;
8478 GO indexBase = rangeMap->getIndexBase();
8480 int offsetToUseInPrinting = 1 - indexBase;
8481 if (params.isParameter(
"zero-based indexing")) {
8482 if (params.get<
bool>(
"zero-based indexing") ==
true)
8483 offsetToUseInPrinting = -indexBase;
8487 size_t numLocalRangeEntries = rangeMap->getNodeNumElements();
8490 RCP<const map_type> allGidsMap = rcp(
new map_type(TGOT::invalid(), numLocalRangeEntries,
8493 mv_type_go allGids(allGidsMap,1);
8494 Teuchos::ArrayRCP<GO> allGidsData = allGids.getDataNonConst(0);
8496 for (
size_t i=0; i<numLocalRangeEntries; i++)
8497 allGidsData[i] = rangeMap->getGlobalElement(i);
8498 allGidsData = Teuchos::null;
8501 GO numTargetMapEntries=TGOT::zero();
8502 Teuchos::Array<GO> importGidList;
8504 numTargetMapEntries = rangeMap->getGlobalNumElements();
8505 importGidList.reserve(numTargetMapEntries);
8506 for (GO j=0; j<numTargetMapEntries; ++j) importGidList.push_back(j + indexBase);
8508 importGidList.reserve(numTargetMapEntries);
8510 RCP<map_type> importGidMap = rcp(
new map_type(TGOT::invalid(), importGidList(), indexBase, comm));
8513 import_type gidImporter(allGidsMap, importGidMap);
8514 mv_type_go importedGids(importGidMap, 1);
8515 importedGids.doImport(allGids, gidImporter,
INSERT);
8518 ArrayRCP<const GO> importedGidsData = importedGids.getData(0);
8519 RCP<const map_type> importMap = rcp(
new map_type(TGOT::invalid(), importedGidsData(), indexBase, comm) );
8522 import_type importer(rangeMap, importMap);
8524 RCP<mv_type> colsOnPid0 = rcp(
new mv_type(importMap,numMVs));
8526 RCP<mv_type> ei = rcp(
new mv_type(A.getDomainMap(),numMVs));
8527 RCP<mv_type> colsA = rcp(
new mv_type(A.getRangeMap(),numMVs));
8529 Array<GO> globalColsArray, localColsArray;
8530 globalColsArray.reserve(numMVs);
8531 localColsArray.reserve(numMVs);
8533 ArrayRCP<ArrayRCP<Scalar> > eiData(numMVs);
8534 for (
size_t i=0; i<numMVs; ++i)
8535 eiData[i] = ei->getDataNonConst(i);
8540 for (GO k=0; k<numChunks; ++k) {
8541 for (
size_t j=0; j<numMVs; ++j ) {
8543 GO curGlobalCol = minColGid + k*numMVs + j;
8544 globalColsArray.push_back(curGlobalCol);
8546 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8547 if (curLocalCol != TLOT::invalid()) {
8548 eiData[j][curLocalCol] = TGOT::one();
8549 localColsArray.push_back(curLocalCol);
8555 A.apply(*ei,*colsA);
8557 colsOnPid0->doImport(*colsA,importer,
INSERT);
8560 globalNnz += writeColumns(os,*colsOnPid0, numMVs, importedGidsData(),
8561 globalColsArray, offsetToUseInPrinting);
8564 for (
size_t j=0; j<numMVs; ++j ) {
8565 for (
int i=0; i<localColsArray.size(); ++i)
8566 eiData[j][localColsArray[i]] = TGOT::zero();
8568 globalColsArray.clear();
8569 localColsArray.clear();
8577 for (
int j=0; j<rem; ++j ) {
8578 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
8579 globalColsArray.push_back(curGlobalCol);
8581 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
8582 if (curLocalCol != TLOT::invalid()) {
8583 eiData[j][curLocalCol] = TGOT::one();
8584 localColsArray.push_back(curLocalCol);
8590 A.apply(*ei,*colsA);
8592 colsOnPid0->doImport(*colsA,importer,
INSERT);
8594 globalNnz += writeColumns(os,*colsOnPid0, rem, importedGidsData(),
8595 globalColsArray, offsetToUseInPrinting);
8598 for (
int j=0; j<rem; ++j ) {
8599 for (
int i=0; i<localColsArray.size(); ++i)
8600 eiData[j][localColsArray[i]] = TGOT::zero();
8602 globalColsArray.clear();
8603 localColsArray.clear();
8612 std::ostringstream oss;
8614 oss <<
"%%MatrixMarket matrix coordinate ";
8615 if (Teuchos::ScalarTraits<typename operator_type::scalar_type>::isComplex) {
8620 oss <<
" general" << std::endl;
8621 oss <<
"% Tpetra::Operator" << std::endl;
8622 std::time_t now = std::time(NULL);
8623 oss <<
"% time stamp: " << ctime(&now);
8624 oss <<
"% written from " << numProcs <<
" processes" << std::endl;
8625 size_t numRows = rangeMap->getGlobalNumElements();
8626 size_t numCols = domainMap.getGlobalNumElements();
8627 oss << numRows <<
" " << numCols <<
" " << globalNnz << std::endl;
8634 writeColumns(std::ostream& os, mv_type
const &colsA,
size_t const &numCols,
8635 Teuchos::ArrayView<const global_ordinal_type>
const &rowGids,
8636 Teuchos::Array<global_ordinal_type>
const &colsArray,
8641 typedef Teuchos::ScalarTraits<Scalar> STS;
8644 const Scalar zero = STS::zero();
8645 const size_t numRows = colsA.getGlobalLength();
8646 for (
size_t j=0; j<numCols; ++j) {
8647 Teuchos::ArrayRCP<const Scalar>
const curCol = colsA.getData(j);
8648 const GO J = colsArray[j];
8649 for (
size_t i=0; i<numRows; ++i) {
8650 const Scalar val = curCol[i];
8652 os << rowGids[i]+indexBase <<
" " << J+indexBase <<
" " << val << std::endl;
8669 #endif // __MatrixMarket_Tpetra_hpp