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