10#ifndef MATRIXMARKET_TPETRA_DEF_HPP
11#define MATRIXMARKET_TPETRA_DEF_HPP
13#include "MatrixMarket_Tpetra_decl.hpp"
14#include "Teuchos_OrdinalTraits.hpp"
16#include "Tpetra_CrsMatrix.hpp"
17#include "Tpetra_Operator.hpp"
18#include "Tpetra_Vector.hpp"
20#include "Teuchos_MatrixMarket_Raw_Adder.hpp"
21#include "Teuchos_MatrixMarket_Raw_Graph_Adder.hpp"
22#include "Teuchos_MatrixMarket_SymmetrizingAdder.hpp"
23#include "Teuchos_MatrixMarket_SymmetrizingGraphAdder.hpp"
24#include "Teuchos_MatrixMarket_assignScalar.hpp"
25#include "Teuchos_MatrixMarket_Banner.hpp"
26#include "Teuchos_MatrixMarket_CoordDataReader.hpp"
27#include "Teuchos_SetScientific.hpp"
28#include "Teuchos_TimeMonitor.hpp"
31#include "mmio_Tpetra.h"
33#include "Tpetra_Distribution.hpp"
45template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
46Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
47MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeRangeMap(
const trcp_tcomm_t& pComm,
52 pComm, GloballyDistributed));
55template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
56Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
57MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeRowMap(
const Teuchos::RCP<const map_type>& pRowMap,
58 const trcp_tcomm_t& pComm,
62 if (pRowMap.is_null()) {
65 pComm, GloballyDistributed));
67 TEUCHOS_TEST_FOR_EXCEPTION(!pRowMap->isDistributed() && pComm->getSize() > 1,
68 std::invalid_argument,
69 "The specified row map is not distributed, "
70 "but the given communicator includes more than one process (in "
72 << pComm->getSize() <<
" processes).");
73 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap->getComm() != pComm, std::invalid_argument,
74 "The specified row Map's communicator (pRowMap->getComm()) "
75 "differs from the given separately supplied communicator pComm.");
80template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
81Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
82MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeDomainMap(
const Teuchos::RCP<const map_type>& pRangeMap,
90 if (numRows == numCols) {
94 pRangeMap->getComm());
98template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
99void MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::distribute(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
100 Teuchos::ArrayRCP<size_t>& myRowPtr,
101 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
102 Teuchos::ArrayRCP<scalar_type>& myValues,
103 const Teuchos::RCP<const map_type>& pRowMap,
104 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
105 Teuchos::ArrayRCP<size_t>& rowPtr,
106 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
107 Teuchos::ArrayRCP<scalar_type>& values,
112 using Teuchos::ArrayRCP;
113 using Teuchos::ArrayView;
116 using Teuchos::CommRequest;
119 using Teuchos::receive;
122 const bool extraDebug =
false;
123 trcp_tcomm_t pComm = pRowMap->
getComm();
124 const int numProcs = pComm->getSize();
125 const int myRank = pComm->getRank();
126 const int rootRank = 0;
133 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
134 const size_type myNumRows = myRows.size();
135 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<size_t>(myNumRows) !=
136 pRowMap->getLocalNumElements(),
138 "pRowMap->getLocalElementList().size() = "
140 <<
" != pRowMap->getLocalNumElements() = "
141 << pRowMap->getLocalNumElements() <<
". "
142 "Please report this bug to the Tpetra developers.");
143 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
145 "On Proc 0: numEntriesPerRow.size() = "
146 << numEntriesPerRow.size()
147 <<
" != pRowMap->getLocalElementList().size() = "
148 << myNumRows <<
". Please report this bug to the "
149 "Tpetra developers.");
153 myNumEntriesPerRow = arcp<size_t>(myNumRows);
155 if (myRank != rootRank) {
159 send(*pComm, myNumRows, rootRank);
160 if (myNumRows != 0) {
164 send(*pComm,
static_cast<int>(myNumRows),
165 myRows.getRawPtr(), rootRank);
175 receive(*pComm, rootRank,
176 static_cast<int>(myNumRows),
177 myNumEntriesPerRow.getRawPtr());
181 const size_t myNumEntries =
182 std::accumulate(myNumEntriesPerRow.begin(),
183 myNumEntriesPerRow.end(),
size_t(0));
184 TEUCHOS_TEST_FOR_EXCEPTION(
185 myNumEntries >
static_cast<size_t>(std::numeric_limits<int>::max()),
187 "MatrixMarketReader::distribute: myNumEntries exceeds int range");
193 myColInd = arcp<GO>(myNumEntries);
194 myValues = arcp<scalar_type>(myNumEntries);
195 if (myNumEntries > 0) {
198 receive(*pComm, rootRank,
199 static_cast<int>(myNumEntries),
200 myColInd.getRawPtr());
201 receive(*pComm, rootRank,
202 static_cast<int>(myNumEntries),
203 myValues.getRawPtr());
209 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
213 for (size_type k = 0; k < myNumRows; ++k) {
214 const GO myCurRow = myRows[k];
216 myNumEntriesPerRow[k] = numEntriesInThisRow;
218 if (extraDebug && debug) {
219 cerr <<
"Proc " << pRowMap->getComm()->getRank()
220 <<
": myNumEntriesPerRow[0.." << (myNumRows - 1) <<
"] = [";
221 for (size_type k = 0; k < myNumRows; ++k) {
222 cerr << myNumEntriesPerRow[k];
223 if (k < myNumRows - 1) {
230 const size_t myNumEntries =
231 std::accumulate(myNumEntriesPerRow.begin(),
232 myNumEntriesPerRow.end(),
size_t(0));
233 TEUCHOS_TEST_FOR_EXCEPTION(
234 myNumEntries >
static_cast<size_t>(std::numeric_limits<int>::max()),
236 "MatrixMarketReader::distribute: myNumEntries exceeds int range");
238 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
239 << myNumEntries <<
" entries" << endl;
241 myColInd = arcp<GO>(myNumEntries);
242 myValues = arcp<scalar_type>(myNumEntries);
250 for (size_type k = 0; k < myNumRows;
251 myCurPos += myNumEntriesPerRow[k], ++k) {
253 const GO myRow = myRows[k];
254 const size_t curPos = rowPtr[myRow];
257 if (curNumEntries > 0) {
258 ArrayView<GO> colIndView = colInd(curPos, curNumEntries);
259 ArrayView<GO> myColIndView = myColInd(myCurPos, curNumEntries);
260 std::copy(colIndView.begin(), colIndView.end(),
261 myColIndView.begin());
263 ArrayView<scalar_type> valuesView =
264 values(curPos, curNumEntries);
265 ArrayView<scalar_type> myValuesView =
266 myValues(myCurPos, curNumEntries);
267 std::copy(valuesView.begin(), valuesView.end(),
268 myValuesView.begin());
273 for (
int p = 1; p < numProcs; ++p) {
275 cerr <<
"-- Proc 0: Processing proc " << p << endl;
278 size_type theirNumRows = 0;
283 receive(*pComm, p, &theirNumRows);
285 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
286 << theirNumRows <<
" rows" << endl;
288 if (theirNumRows != 0) {
293 ArrayRCP<GO> theirRows = arcp<GO>(theirNumRows);
294 receive(*pComm, p, as<int>(theirNumRows),
295 theirRows.getRawPtr());
304 const global_size_t numRows = pRowMap->getGlobalNumElements();
305 const GO indexBase = pRowMap->getIndexBase();
306 bool theirRowsValid =
true;
307 for (size_type k = 0; k < theirNumRows; ++k) {
308 if (theirRows[k] < indexBase ||
309 as<global_size_t>(theirRows[k] - indexBase) >= numRows) {
310 theirRowsValid =
false;
313 if (!theirRowsValid) {
314 TEUCHOS_TEST_FOR_EXCEPTION(
315 !theirRowsValid, std::logic_error,
316 "Proc " << p <<
" has at least one invalid row index. "
317 "Here are all of them: "
318 << Teuchos::toString(theirRows()) <<
". Valid row index "
319 "range (zero-based): [0, "
320 << (numRows - 1) <<
"].");
335 ArrayRCP<size_t> theirNumEntriesPerRow;
336 theirNumEntriesPerRow = arcp<size_t>(theirNumRows);
337 for (size_type k = 0; k < theirNumRows; ++k) {
338 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
345 send(*pComm,
static_cast<int>(theirNumRows),
346 theirNumEntriesPerRow.getRawPtr(), p);
349 const size_t theirNumEntries =
350 std::accumulate(theirNumEntriesPerRow.begin(),
351 theirNumEntriesPerRow.end(),
size_t(0));
352 TEUCHOS_TEST_FOR_EXCEPTION(
353 theirNumEntries >
static_cast<size_t>(std::numeric_limits<int>::max()),
355 "MatrixMarketReader::distribute: theirNumEntries exceeds int range");
358 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
359 << theirNumEntries <<
" entries" << endl;
364 if (theirNumEntries == 0) {
373 ArrayRCP<GO> theirColInd(theirNumEntries);
374 ArrayRCP<scalar_type> theirValues(theirNumEntries);
382 for (size_type k = 0; k < theirNumRows;
383 theirCurPos += theirNumEntriesPerRow[k], k++) {
385 const GO theirRow = theirRows[k];
391 if (curNumEntries > 0) {
392 ArrayView<GO> colIndView =
393 colInd(curPos, curNumEntries);
394 ArrayView<GO> theirColIndView =
395 theirColInd(theirCurPos, curNumEntries);
396 std::copy(colIndView.begin(), colIndView.end(),
397 theirColIndView.begin());
399 ArrayView<scalar_type> valuesView =
400 values(curPos, curNumEntries);
401 ArrayView<scalar_type> theirValuesView =
402 theirValues(theirCurPos, curNumEntries);
403 std::copy(valuesView.begin(), valuesView.end(),
404 theirValuesView.begin());
411 send(*pComm,
static_cast<int>(theirNumEntries),
412 theirColInd.getRawPtr(), p);
413 send(*pComm,
static_cast<int>(theirNumEntries),
414 theirValues.getRawPtr(), p);
417 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
425 numEntriesPerRow = null;
430 if (debug && myRank == 0) {
431 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
439 myRowPtr = arcp<size_t>(myNumRows + 1);
441 for (size_type k = 1; k < myNumRows + 1; ++k) {
442 myRowPtr[k] = myRowPtr[k - 1] + myNumEntriesPerRow[k - 1];
444 if (extraDebug && debug) {
445 cerr <<
"Proc " << Teuchos::rank(*(pRowMap->getComm()))
446 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
447 for (size_type k = 0; k < myNumRows + 1; ++k) {
457 if (debug && myRank == 0) {
458 cerr <<
"-- Proc 0: Done with distribute" << endl;
462template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
463Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
464MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
465 Teuchos::ArrayRCP<size_t>& myRowPtr,
466 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
467 Teuchos::ArrayRCP<scalar_type>& myValues,
468 const Teuchos::RCP<const map_type>& pRowMap,
469 const Teuchos::RCP<const map_type>& pRangeMap,
470 const Teuchos::RCP<const map_type>& pDomainMap,
471 const bool callFillComplete) {
474 using Teuchos::ArrayView;
486 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
487 "makeMatrix: myRowPtr array is null. "
488 "Please report this bug to the Tpetra developers.");
489 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
490 "makeMatrix: domain map is null. "
491 "Please report this bug to the Tpetra developers.");
492 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
493 "makeMatrix: range map is null. "
494 "Please report this bug to the Tpetra developers.");
495 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
496 "makeMatrix: row map is null. "
497 "Please report this bug to the Tpetra developers.");
501 RCP<sparse_matrix_type> A =
502 rcp(
new sparse_matrix_type(pRowMap, myNumEntriesPerRow()));
506 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
507 const size_type myNumRows = myRows.size();
510 const GO indexBase = pRowMap->getIndexBase();
511 for (size_type i = 0; i < myNumRows; ++i) {
512 const size_type myCurPos = myRowPtr[i];
514 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
515 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
518 for (size_type k = 0; k < curNumEntries; ++k) {
519 curColInd[k] += indexBase;
522 if (curNumEntries > 0) {
523 A->insertGlobalValues(myRows[i], curColInd, curValues);
530 myNumEntriesPerRow = null;
535 if (callFillComplete) {
536 A->fillComplete(pDomainMap, pRangeMap);
541template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
542Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
543MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
544 Teuchos::ArrayRCP<size_t>& myRowPtr,
547 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pRowMap,
548 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pRangeMap,
549 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pDomainMap,
550 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
551 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams) {
554 using Teuchos::ArrayView;
560 using size_type =
typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::size_type;
567 TEUCHOS_TEST_FOR_EXCEPTION(
568 myRowPtr.is_null(), std::logic_error,
569 "makeMatrix: myRowPtr array is null. "
570 "Please report this bug to the Tpetra developers.");
571 TEUCHOS_TEST_FOR_EXCEPTION(
572 pDomainMap.is_null(), std::logic_error,
573 "makeMatrix: domain map is null. "
574 "Please report this bug to the Tpetra developers.");
575 TEUCHOS_TEST_FOR_EXCEPTION(
576 pRangeMap.is_null(), std::logic_error,
577 "makeMatrix: range map is null. "
578 "Please report this bug to the Tpetra developers.");
579 TEUCHOS_TEST_FOR_EXCEPTION(
580 pRowMap.is_null(), std::logic_error,
581 "makeMatrix: row map is null. "
582 "Please report this bug to the Tpetra developers.");
586 RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type> A =
587 rcp(
new typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type(pRowMap, myNumEntriesPerRow(),
592 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
593 const size_type myNumRows = myRows.size();
596 const GO indexBase = pRowMap->getIndexBase();
597 for (size_type i = 0; i < myNumRows; ++i) {
598 const size_type myCurPos = myRowPtr[i];
600 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
601 ArrayView<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
604 for (size_type k = 0; k < curNumEntries; ++k) {
605 curColInd[k] += indexBase;
607 if (curNumEntries > 0) {
608 A->insertGlobalValues(myRows[i], curColInd, curValues);
615 myNumEntriesPerRow = null;
620 A->fillComplete(pDomainMap, pRangeMap, fillCompleteParams);
624template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
625Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
626MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
627 Teuchos::ArrayRCP<size_t>& myRowPtr,
628 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
629 Teuchos::ArrayRCP<scalar_type>& myValues,
630 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rowMap,
631 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& colMap,
632 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& domainMap,
633 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rangeMap,
634 const bool callFillComplete) {
635 using Teuchos::ArrayView;
644 RCP<sparse_matrix_type> A;
645 if (colMap.is_null()) {
646 A = rcp(
new sparse_matrix_type(rowMap, myNumEntriesPerRow()));
648 A = rcp(
new sparse_matrix_type(rowMap, colMap, myNumEntriesPerRow()));
653 ArrayView<const GO> myRows = rowMap->getLocalElementList();
654 const size_type myNumRows = myRows.size();
658 for (size_type i = 0; i < myNumRows; ++i) {
659 const size_type myCurPos = myRowPtr[i];
660 const size_type curNumEntries = as<size_type>(myNumEntriesPerRow[i]);
661 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
662 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
665 for (size_type k = 0; k < curNumEntries; ++k) {
666 curColInd[k] += indexBase;
668 if (curNumEntries > 0) {
669 A->insertGlobalValues(myRows[i], curColInd, curValues);
676 myNumEntriesPerRow = null;
681 if (callFillComplete) {
682 A->fillComplete(domainMap, rangeMap);
683 if (colMap.is_null()) {
684 colMap = A->getColMap();
690template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
691Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
692MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readBanner(std::istream& in,
696 const bool isGraph) {
701 using Teuchos::MatrixMarket::Banner;
702 typedef Teuchos::ScalarTraits<scalar_type> STS;
708 const bool readFailed = !getline(in, line);
709 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
710 "Failed to get Matrix Market banner line from input.");
717 pBanner = rcp(
new Banner(line, tolerant));
718 }
catch (std::exception& e) {
719 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
720 "Matrix Market banner line contains syntax error(s): "
724 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
725 std::invalid_argument,
726 "The Matrix Market file does not contain "
727 "matrix data. Its Banner (first) line says that its object type is \""
728 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
732 TEUCHOS_TEST_FOR_EXCEPTION(
733 !STS::isComplex && pBanner->dataType() ==
"complex",
734 std::invalid_argument,
735 "The Matrix Market file contains complex-valued data, but you are "
736 "trying to read it into a matrix containing entries of the real-"
737 "valued Scalar type \""
738 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
739 TEUCHOS_TEST_FOR_EXCEPTION(
741 pBanner->dataType() !=
"real" &&
742 pBanner->dataType() !=
"complex" &&
743 pBanner->dataType() !=
"integer",
744 std::invalid_argument,
745 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
746 "Matrix Market file may not contain a \"pattern\" matrix. A "
747 "pattern matrix is really just a graph with no weights. It "
748 "should be stored in a CrsGraph, not a CrsMatrix.");
750 TEUCHOS_TEST_FOR_EXCEPTION(
752 pBanner->dataType() !=
"pattern",
753 std::invalid_argument,
754 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
755 "Matrix Market file must contain a \"pattern\" matrix.");
760template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
761Teuchos::Tuple<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::global_ordinal_type, 3>
762MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readCoordDims(std::istream& in,
764 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
768 using Teuchos::Tuple;
769 using Teuchos::MatrixMarket::readCoordinateDimensions;
774 Tuple<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::global_ordinal_type, 3> dims;
780 bool success =
false;
781 if (pComm->getRank() == 0) {
782 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
783 std::invalid_argument,
784 "The Tpetra::CrsMatrix Matrix Market reader "
785 "only accepts \"coordinate\" (sparse) matrix data.");
789 success = readCoordinateDimensions(in, numRows, numCols,
790 numNonzeros, lineNumber,
796 dims[2] = numNonzeros;
804 int the_success = success ? 1 : 0;
805 Teuchos::broadcast(*pComm, 0, &the_success);
806 success = (the_success == 1);
811 Teuchos::broadcast(*pComm, 0, dims);
818 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
819 "Error reading Matrix Market sparse matrix: failed to read "
820 "coordinate matrix dimensions.");
825template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
826Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::adder_type>
827MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
828 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
829 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
832 if (pComm->getRank() == 0) {
833 typedef Teuchos::MatrixMarket::Raw::Adder<
scalar_type,
836 Teuchos::RCP<raw_adder_type> pRaw =
837 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
839 return Teuchos::rcp(
new adder_type(pRaw, pBanner->symmType()));
841 return Teuchos::null;
845template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
846Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::graph_adder_type>
847MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeGraphAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
848 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
849 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
852 if (pComm->getRank() == 0) {
853 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
854 Teuchos::RCP<raw_adder_type> pRaw =
855 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
857 return Teuchos::rcp(
new graph_adder_type(pRaw, pBanner->symmType()));
859 return Teuchos::null;
863template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
864Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
865MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readSparseGraphHelper(std::istream& in,
866 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
867 const Teuchos::RCP<const map_type>& rowMap,
868 Teuchos::RCP<const map_type>& colMap,
869 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
876 using Teuchos::Tuple;
877 using Teuchos::MatrixMarket::Banner;
879 const int myRank = pComm->getRank();
880 const int rootRank = 0;
885 size_t lineNumber = 1;
887 if (debug && myRank == rootRank) {
888 cerr <<
"Matrix Market reader: readGraph:" << endl
889 <<
"-- Reading banner line" << endl;
898 RCP<const Banner> pBanner;
904 int bannerIsCorrect = 1;
905 std::ostringstream errMsg;
907 if (myRank == rootRank) {
910 pBanner = readBanner(in, lineNumber, tolerant, debug,
true);
911 }
catch (std::exception& e) {
912 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
913 "threw an exception: "
918 if (bannerIsCorrect) {
923 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
925 errMsg <<
"The Matrix Market input file must contain a "
926 "\"coordinate\"-format sparse graph in order to create a "
927 "Tpetra::CrsGraph object from it, but the file's matrix "
929 << pBanner->matrixType() <<
"\" instead.";
934 if (tolerant && pBanner->matrixType() ==
"array") {
936 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
937 "format sparse graph in order to create a Tpetra::CrsGraph "
938 "object from it, but the file's matrix type is \"array\" "
939 "instead. That probably means the file contains dense matrix "
946 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
953 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
954 std::invalid_argument, errMsg.str());
956 if (debug && myRank == rootRank) {
957 cerr <<
"-- Reading dimensions line" << endl;
965 Tuple<global_ordinal_type, 3> dims =
966 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
968 if (debug && myRank == rootRank) {
969 cerr <<
"-- Making Adder for collecting graph data" << endl;
976 RCP<graph_adder_type> pAdder =
977 makeGraphAdder(pComm, pBanner, dims, tolerant, debug);
979 if (debug && myRank == rootRank) {
980 cerr <<
"-- Reading graph data" << endl;
991 std::ostringstream errMsg;
992 if (myRank == rootRank) {
995 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
998 reader_type reader(pAdder);
1001 std::pair<bool, std::vector<size_t>> results =
1002 reader.read(in, lineNumber, tolerant, debug);
1003 readSuccess = results.first ? 1 : 0;
1004 }
catch (std::exception& e) {
1009 broadcast(*pComm, rootRank, ptr(&readSuccess));
1018 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1019 "Failed to read the Matrix Market sparse graph file: "
1023 if (debug && myRank == rootRank) {
1024 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1037 if (debug && myRank == rootRank) {
1038 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1040 <<
"----- Dimensions before: "
1041 << dims[0] <<
" x " << dims[1]
1045 Tuple<global_ordinal_type, 2> updatedDims;
1046 if (myRank == rootRank) {
1053 std::max(dims[0], pAdder->getAdder()->numRows());
1054 updatedDims[1] = pAdder->getAdder()->numCols();
1056 broadcast(*pComm, rootRank, updatedDims);
1057 dims[0] = updatedDims[0];
1058 dims[1] = updatedDims[1];
1059 if (debug && myRank == rootRank) {
1060 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1073 if (myRank == rootRank) {
1080 if (dims[0] < pAdder->getAdder()->numRows()) {
1084 broadcast(*pComm, 0, ptr(&dimsMatch));
1085 if (dimsMatch == 0) {
1092 Tuple<global_ordinal_type, 2> addersDims;
1093 if (myRank == rootRank) {
1094 addersDims[0] = pAdder->getAdder()->numRows();
1095 addersDims[1] = pAdder->getAdder()->numCols();
1097 broadcast(*pComm, 0, addersDims);
1098 TEUCHOS_TEST_FOR_EXCEPTION(
1099 dimsMatch == 0, std::runtime_error,
1100 "The graph metadata says that the graph is " << dims[0] <<
" x "
1101 << dims[1] <<
", but the actual data says that the graph is "
1102 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1103 "data includes more rows than reported in the metadata. This "
1104 "is not allowed when parsing in strict mode. Parse the graph in "
1105 "tolerant mode to ignore the metadata when it disagrees with the "
1111 RCP<map_type> proc0Map;
1113 if (Teuchos::is_null(rowMap)) {
1116 indexBase = rowMap->getIndexBase();
1118 if (myRank == rootRank) {
1119 proc0Map = rcp(
new map_type(dims[0], dims[0], indexBase, pComm));
1121 proc0Map = rcp(
new map_type(dims[0], 0, indexBase, pComm));
1125 std::map<global_ordinal_type, size_t> numEntriesPerRow_map;
1126 if (myRank == rootRank) {
1127 const auto& entries = pAdder()->getAdder()->getEntries();
1132 for (
const auto& entry : entries) {
1134 ++numEntriesPerRow_map[gblRow];
1138 Teuchos::Array<size_t> numEntriesPerRow(proc0Map->getLocalNumElements());
1139 for (
const auto& ent : numEntriesPerRow_map) {
1141 TEUCHOS_TEST_FOR_EXCEPTION(
1142 lclRow == Teuchos::OrdinalTraits<local_ordinal_type>::invalid(),
1144 "MatrixMarketReader::readSparseGraphHelper: global row "
1145 << ent.first <<
" is not owned by proc0Map. This should not happen.");
1146 numEntriesPerRow[lclRow] = ent.second;
1153 std::map<global_ordinal_type, size_t> empty_map;
1154 std::swap(numEntriesPerRow_map, empty_map);
1157 RCP<sparse_graph_type> proc0Graph =
1158 rcp(
new sparse_graph_type(proc0Map, numEntriesPerRow(),
1159 constructorParams));
1160 if (myRank == rootRank) {
1161 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1164 const std::vector<element_type>& entries =
1165 pAdder->getAdder()->getEntries();
1168 for (
size_t curPos = 0; curPos < entries.size(); curPos++) {
1169 const element_type& curEntry = entries[curPos];
1172 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol, 1);
1173 proc0Graph->insertGlobalIndices(curRow, colView);
1176 proc0Graph->fillComplete();
1178 RCP<sparse_graph_type> distGraph;
1179 if (Teuchos::is_null(rowMap)) {
1181 RCP<map_type> distMap =
1182 rcp(
new map_type(dims[0], 0, pComm, GloballyDistributed));
1185 distGraph = rcp(
new sparse_graph_type(distMap, colMap, 0, constructorParams));
1192 distGraph->doImport(*proc0Graph, importer,
INSERT);
1194 distGraph = rcp(
new sparse_graph_type(rowMap, colMap, 0, constructorParams));
1201 distGraph->doImport(*proc0Graph, importer,
INSERT);
1207template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1208Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1211 const bool callFillComplete,
1212 const bool tolerant,
1224template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1225Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1228 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1229 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1230 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1231 const bool tolerant,
1237 fillCompleteParams, tolerant, debug);
1243template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1244Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1246 const Teuchos::RCP<const map_type>& rowMap,
1247 Teuchos::RCP<const map_type>& colMap,
1248 const Teuchos::RCP<const map_type>& domainMap,
1249 const Teuchos::RCP<const map_type>& rangeMap,
1250 const bool callFillComplete,
1251 const bool tolerant,
1253 TEUCHOS_TEST_FOR_EXCEPTION(rowMap.is_null(), std::invalid_argument,
1254 "Input rowMap must be nonnull.");
1256 if (comm.is_null()) {
1259 return Teuchos::null;
1265 callFillComplete, tolerant, debug);
1268template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1269Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1271 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1272 const bool callFillComplete,
1273 const bool tolerant,
1275 Teuchos::RCP<const map_type> fakeRowMap;
1276 Teuchos::RCP<const map_type> fakeColMap;
1277 Teuchos::RCP<Teuchos::ParameterList> fakeCtorParams;
1279 Teuchos::RCP<sparse_graph_type> graph =
1280 readSparseGraphHelper(in, pComm,
1281 fakeRowMap, fakeColMap,
1282 fakeCtorParams, tolerant, debug);
1283 if (callFillComplete) {
1284 graph->fillComplete();
1289template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1290Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1292 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1293 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1294 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1295 const bool tolerant,
1297 Teuchos::RCP<const map_type> fakeRowMap;
1298 Teuchos::RCP<const map_type> fakeColMap;
1299 Teuchos::RCP<sparse_graph_type> graph =
1300 readSparseGraphHelper(in, pComm,
1301 fakeRowMap, fakeColMap,
1302 constructorParams, tolerant, debug);
1303 graph->fillComplete(fillCompleteParams);
1307template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1308Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1310 const Teuchos::RCP<const map_type>& rowMap,
1311 Teuchos::RCP<const map_type>& colMap,
1312 const Teuchos::RCP<const map_type>& domainMap,
1313 const Teuchos::RCP<const map_type>& rangeMap,
1314 const bool callFillComplete,
1315 const bool tolerant,
1317 Teuchos::RCP<sparse_graph_type> graph =
1318 readSparseGraphHelper(in, rowMap->getComm(),
1319 rowMap, colMap, Teuchos::null, tolerant,
1321 if (callFillComplete) {
1322 graph->fillComplete(domainMap, rangeMap);
1327#include "MatrixMarket_TpetraNew.hpp"
1329template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1330Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1331MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readSparseFile(
const std::string& filename,
1333 const bool callFillComplete,
1334 const bool tolerant,
1338 return readSparse(in, comm, callFillComplete, tolerant, debug);
1344template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1345Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1346MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readSparseFile(
const std::string& filename,
1348 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1349 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1350 const bool tolerant,
1354 return readSparse(in, comm, constructorParams,
1355 fillCompleteParams, tolerant, debug);
1358template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1359Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1360MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readSparseFile(
const std::string& filename,
1361 const Teuchos::RCP<const map_type>& rowMap,
1362 Teuchos::RCP<const map_type>& colMap,
1363 const Teuchos::RCP<const map_type>& domainMap,
1364 const Teuchos::RCP<const map_type>& rangeMap,
1365 const bool callFillComplete,
1366 const bool tolerant,
1368 TEUCHOS_TEST_FOR_EXCEPTION(
1369 rowMap.is_null(), std::invalid_argument,
1370 "Row Map must be nonnull.");
1376 return readSparse(in, rowMap, colMap, domainMap, rangeMap,
1377 callFillComplete, tolerant, debug);
1380template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1381Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1383 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1384 const bool callFillComplete,
1385 const bool tolerant,
1389 using Teuchos::arcp;
1390 using Teuchos::ArrayRCP;
1391 using Teuchos::broadcast;
1392 using Teuchos::null;
1395 using Teuchos::REDUCE_MAX;
1396 using Teuchos::reduceAll;
1397 using Teuchos::Tuple;
1398 using Teuchos::MatrixMarket::Banner;
1399 typedef Teuchos::ScalarTraits<scalar_type> STS;
1401 const bool extraDebug =
false;
1402 const int myRank = pComm->getRank();
1403 const int rootRank = 0;
1408 size_t lineNumber = 1;
1410 if (debug && myRank == rootRank) {
1411 cerr <<
"Matrix Market reader: readSparse:" << endl
1412 <<
"-- Reading banner line" << endl;
1421 RCP<const Banner> pBanner;
1427 int bannerIsCorrect = 1;
1428 std::ostringstream errMsg;
1430 if (myRank == rootRank) {
1433 pBanner = readBanner(in, lineNumber, tolerant, debug);
1434 }
catch (std::exception& e) {
1435 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1436 "threw an exception: "
1438 bannerIsCorrect = 0;
1441 if (bannerIsCorrect) {
1446 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
1447 bannerIsCorrect = 0;
1448 errMsg <<
"The Matrix Market input file must contain a "
1449 "\"coordinate\"-format sparse matrix in order to create a "
1450 "Tpetra::CrsMatrix object from it, but the file's matrix "
1452 << pBanner->matrixType() <<
"\" instead.";
1457 if (tolerant && pBanner->matrixType() ==
"array") {
1458 bannerIsCorrect = 0;
1459 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1460 "format sparse matrix in order to create a Tpetra::CrsMatrix "
1461 "object from it, but the file's matrix type is \"array\" "
1462 "instead. That probably means the file contains dense matrix "
1469 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
1476 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
1477 std::invalid_argument, errMsg.str());
1479 if (debug && myRank == rootRank) {
1480 cerr <<
"-- Reading dimensions line" << endl;
1488 Tuple<global_ordinal_type, 3> dims =
1489 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
1491 if (debug && myRank == rootRank) {
1492 cerr <<
"-- Making Adder for collecting matrix data" << endl;
1497 RCP<adder_type> pAdder =
1498 makeAdder(pComm, pBanner, dims, tolerant, debug);
1500 if (debug && myRank == rootRank) {
1501 cerr <<
"-- Reading matrix data" << endl;
1511 int readSuccess = 1;
1512 std::ostringstream errMsg;
1513 if (myRank == rootRank) {
1516 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
1519 reader_type reader(pAdder);
1522 std::pair<bool, std::vector<size_t>> results =
1523 reader.read(in, lineNumber, tolerant, debug);
1524 readSuccess = results.first ? 1 : 0;
1525 }
catch (std::exception& e) {
1530 broadcast(*pComm, rootRank, ptr(&readSuccess));
1539 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1540 "Failed to read the Matrix Market sparse matrix file: "
1544 if (debug && myRank == rootRank) {
1545 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1558 if (debug && myRank == rootRank) {
1559 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
1561 <<
"----- Dimensions before: "
1562 << dims[0] <<
" x " << dims[1]
1566 Tuple<global_ordinal_type, 2> updatedDims;
1567 if (myRank == rootRank) {
1574 std::max(dims[0], pAdder->getAdder()->numRows());
1575 updatedDims[1] = pAdder->getAdder()->numCols();
1577 broadcast(*pComm, rootRank, updatedDims);
1578 dims[0] = updatedDims[0];
1579 dims[1] = updatedDims[1];
1580 if (debug && myRank == rootRank) {
1581 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1594 if (myRank == rootRank) {
1601 if (dims[0] < pAdder->getAdder()->numRows()) {
1605 broadcast(*pComm, 0, ptr(&dimsMatch));
1606 if (dimsMatch == 0) {
1613 Tuple<global_ordinal_type, 2> addersDims;
1614 if (myRank == rootRank) {
1615 addersDims[0] = pAdder->getAdder()->numRows();
1616 addersDims[1] = pAdder->getAdder()->numCols();
1618 broadcast(*pComm, 0, addersDims);
1619 TEUCHOS_TEST_FOR_EXCEPTION(
1620 dimsMatch == 0, std::runtime_error,
1621 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
1622 << dims[1] <<
", but the actual data says that the matrix is "
1623 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1624 "data includes more rows than reported in the metadata. This "
1625 "is not allowed when parsing in strict mode. Parse the matrix in "
1626 "tolerant mode to ignore the metadata when it disagrees with the "
1631 if (debug && myRank == rootRank) {
1632 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
1644 ArrayRCP<size_t> numEntriesPerRow;
1645 ArrayRCP<size_t> rowPtr;
1646 ArrayRCP<global_ordinal_type> colInd;
1647 ArrayRCP<scalar_type> values;
1652 int mergeAndConvertSucceeded = 1;
1653 std::ostringstream errMsg;
1655 if (myRank == rootRank) {
1657 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
1668 const size_type numRows = dims[0];
1671 pAdder->getAdder()->merge();
1674 const std::vector<element_type>& entries =
1675 pAdder->getAdder()->getEntries();
1678 const size_t numEntries = (size_t)entries.size();
1681 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
1682 <<
" rows and numEntries=" << numEntries
1683 <<
" entries." << endl;
1689 numEntriesPerRow = arcp<size_t>(numRows);
1690 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
1691 rowPtr = arcp<size_t>(numRows + 1);
1692 std::fill(rowPtr.begin(), rowPtr.end(), 0);
1693 colInd = arcp<global_ordinal_type>(numEntries);
1694 values = arcp<scalar_type>(numEntries);
1701 for (curPos = 0; curPos < numEntries; ++curPos) {
1702 const element_type& curEntry = entries[curPos];
1704 TEUCHOS_TEST_FOR_EXCEPTION(
1705 curRow < prvRow, std::logic_error,
1706 "Row indices are out of order, even though they are supposed "
1707 "to be sorted. curRow = "
1708 << curRow <<
", prvRow = "
1709 << prvRow <<
", at curPos = " << curPos <<
". Please report "
1710 "this bug to the Tpetra developers.");
1711 if (curRow > prvRow) {
1717 numEntriesPerRow[curRow]++;
1718 colInd[curPos] = curEntry.colIndex();
1719 values[curPos] = curEntry.value();
1724 rowPtr[numRows] = numEntries;
1726 catch (std::exception& e) {
1727 mergeAndConvertSucceeded = 0;
1728 errMsg <<
"Failed to merge sparse matrix entries and convert to "
1733 if (debug && mergeAndConvertSucceeded) {
1735 const size_type numRows = dims[0];
1736 const size_type maxToDisplay = 100;
1738 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
1739 << (numEntriesPerRow.size() - 1) <<
"] ";
1740 if (numRows > maxToDisplay) {
1741 cerr <<
"(only showing first and last few entries) ";
1745 if (numRows > maxToDisplay) {
1746 for (size_type k = 0; k < 2; ++k) {
1747 cerr << numEntriesPerRow[k] <<
" ";
1750 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
1751 cerr << numEntriesPerRow[k] <<
" ";
1754 for (size_type k = 0; k < numRows - 1; ++k) {
1755 cerr << numEntriesPerRow[k] <<
" ";
1758 cerr << numEntriesPerRow[numRows - 1];
1760 cerr <<
"]" << endl;
1762 cerr <<
"----- Proc 0: rowPtr ";
1763 if (numRows > maxToDisplay) {
1764 cerr <<
"(only showing first and last few entries) ";
1767 if (numRows > maxToDisplay) {
1768 for (size_type k = 0; k < 2; ++k) {
1769 cerr << rowPtr[k] <<
" ";
1772 for (size_type k = numRows - 2; k < numRows; ++k) {
1773 cerr << rowPtr[k] <<
" ";
1776 for (size_type k = 0; k < numRows; ++k) {
1777 cerr << rowPtr[k] <<
" ";
1780 cerr << rowPtr[numRows] <<
"]" << endl;
1786 int mergeAndConvertSucceededAll = mergeAndConvertSucceeded;
1787 broadcast(*pComm, rootRank, ptr(&mergeAndConvertSucceededAll));
1788 if (mergeAndConvertSucceededAll == 0) {
1789 TEUCHOS_TEST_FOR_EXCEPTION(
1790 true, std::runtime_error,
1791 "Failed to merge sparse matrix entries and convert to CSR format: "
1802 if (debug && myRank == rootRank) {
1803 cerr <<
"-- Making range, domain, and row maps" << endl;
1810 RCP<const map_type> pRangeMap = makeRangeMap(pComm, dims[0]);
1811 RCP<const map_type> pDomainMap =
1812 makeDomainMap(pRangeMap, dims[0], dims[1]);
1813 RCP<const map_type> pRowMap = makeRowMap(null, pComm, dims[0]);
1815 if (debug && myRank == rootRank) {
1816 cerr <<
"-- Distributing the matrix data" << endl;
1830 ArrayRCP<size_t> myNumEntriesPerRow;
1831 ArrayRCP<size_t> myRowPtr;
1832 ArrayRCP<global_ordinal_type> myColInd;
1833 ArrayRCP<scalar_type> myValues;
1835 distribute(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
1836 numEntriesPerRow, rowPtr, colInd, values, debug);
1838 if (debug && myRank == rootRank) {
1839 cerr <<
"-- Inserting matrix entries on each processor";
1840 if (callFillComplete) {
1841 cerr <<
" and calling fillComplete()";
1852 RCP<sparse_matrix_type> pMatrix =
1853 makeMatrix(myNumEntriesPerRow, myRowPtr, myColInd, myValues,
1854 pRowMap, pRangeMap, pDomainMap, callFillComplete);
1859 int localIsNull = pMatrix.is_null() ? 1 : 0;
1860 int globalIsNull = 0;
1861 reduceAll(*pComm, REDUCE_MAX, localIsNull, ptr(&globalIsNull));
1862 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
1863 "MatrixMarketReader::makeMatrix() returned a null pointer on at least one "
1864 "process. Please report this bug to the Tpetra developers.");
1866 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
1867 "MatrixMarketReader::makeMatrix() returned a null pointer. "
1868 "Please report this bug to the Tpetra developers.");
1880 if (callFillComplete) {
1881 const int numProcs = pComm->getSize();
1883 if (extraDebug && debug) {
1885 pRangeMap->getGlobalNumElements();
1887 pDomainMap->getGlobalNumElements();
1888 if (myRank == rootRank) {
1889 cerr <<
"-- Matrix is "
1890 << globalNumRows <<
" x " << globalNumCols
1891 <<
" with " << pMatrix->getGlobalNumEntries()
1892 <<
" entries, and index base "
1893 << pMatrix->getIndexBase() <<
"." << endl;
1896 for (
int p = 0; p < numProcs; ++p) {
1898 cerr <<
"-- Proc " << p <<
" owns "
1899 << pMatrix->getLocalNumCols() <<
" columns, and "
1900 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
1907 if (debug && myRank == rootRank) {
1908 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
1914template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1915Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1917 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
1918 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
1919 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams,
1920 const bool tolerant,
1924 using Teuchos::arcp;
1925 using Teuchos::ArrayRCP;
1926 using Teuchos::broadcast;
1927 using Teuchos::null;
1930 using Teuchos::reduceAll;
1931 using Teuchos::Tuple;
1932 using Teuchos::MatrixMarket::Banner;
1933 typedef Teuchos::ScalarTraits<scalar_type> STS;
1935 const bool extraDebug =
false;
1936 const int myRank = pComm->getRank();
1937 const int rootRank = 0;
1942 size_t lineNumber = 1;
1944 if (debug && myRank == rootRank) {
1945 cerr <<
"Matrix Market reader: readSparse:" << endl
1946 <<
"-- Reading banner line" << endl;
1955 RCP<const Banner> pBanner;
1961 int bannerIsCorrect = 1;
1962 std::ostringstream errMsg;
1964 if (myRank == rootRank) {
1967 pBanner = readBanner(in, lineNumber, tolerant, debug);
1968 }
catch (std::exception& e) {
1969 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1970 "threw an exception: "
1972 bannerIsCorrect = 0;
1975 if (bannerIsCorrect) {
1980 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
1981 bannerIsCorrect = 0;
1982 errMsg <<
"The Matrix Market input file must contain a "
1983 "\"coordinate\"-format sparse matrix in order to create a "
1984 "Tpetra::CrsMatrix object from it, but the file's matrix "
1986 << pBanner->matrixType() <<
"\" instead.";
1991 if (tolerant && pBanner->matrixType() ==
"array") {
1992 bannerIsCorrect = 0;
1993 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1994 "format sparse matrix in order to create a Tpetra::CrsMatrix "
1995 "object from it, but the file's matrix type is \"array\" "
1996 "instead. That probably means the file contains dense matrix "
2003 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
2010 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2011 std::invalid_argument, errMsg.str());
2013 if (debug && myRank == rootRank) {
2014 cerr <<
"-- Reading dimensions line" << endl;
2022 Tuple<global_ordinal_type, 3> dims =
2023 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
2025 if (debug && myRank == rootRank) {
2026 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2031 RCP<adder_type> pAdder =
2032 makeAdder(pComm, pBanner, dims, tolerant, debug);
2034 if (debug && myRank == rootRank) {
2035 cerr <<
"-- Reading matrix data" << endl;
2045 int readSuccess = 1;
2046 std::ostringstream errMsg;
2047 if (myRank == rootRank) {
2050 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2053 reader_type reader(pAdder);
2056 std::pair<bool, std::vector<size_t>> results =
2057 reader.read(in, lineNumber, tolerant, debug);
2058 readSuccess = results.first ? 1 : 0;
2059 }
catch (std::exception& e) {
2064 broadcast(*pComm, rootRank, ptr(&readSuccess));
2073 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2074 "Failed to read the Matrix Market sparse matrix file: "
2078 if (debug && myRank == rootRank) {
2079 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2092 if (debug && myRank == rootRank) {
2093 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2095 <<
"----- Dimensions before: "
2096 << dims[0] <<
" x " << dims[1]
2100 Tuple<global_ordinal_type, 2> updatedDims;
2101 if (myRank == rootRank) {
2108 std::max(dims[0], pAdder->getAdder()->numRows());
2109 updatedDims[1] = pAdder->getAdder()->numCols();
2111 broadcast(*pComm, rootRank, updatedDims);
2112 dims[0] = updatedDims[0];
2113 dims[1] = updatedDims[1];
2114 if (debug && myRank == rootRank) {
2115 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2128 if (myRank == rootRank) {
2135 if (dims[0] < pAdder->getAdder()->numRows()) {
2139 broadcast(*pComm, 0, ptr(&dimsMatch));
2140 if (dimsMatch == 0) {
2147 Tuple<global_ordinal_type, 2> addersDims;
2148 if (myRank == rootRank) {
2149 addersDims[0] = pAdder->getAdder()->numRows();
2150 addersDims[1] = pAdder->getAdder()->numCols();
2152 broadcast(*pComm, 0, addersDims);
2153 TEUCHOS_TEST_FOR_EXCEPTION(
2154 dimsMatch == 0, std::runtime_error,
2155 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2156 << dims[1] <<
", but the actual data says that the matrix is "
2157 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2158 "data includes more rows than reported in the metadata. This "
2159 "is not allowed when parsing in strict mode. Parse the matrix in "
2160 "tolerant mode to ignore the metadata when it disagrees with the "
2165 if (debug && myRank == rootRank) {
2166 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2178 ArrayRCP<size_t> numEntriesPerRow;
2179 ArrayRCP<size_t> rowPtr;
2180 ArrayRCP<global_ordinal_type> colInd;
2181 ArrayRCP<scalar_type> values;
2186 int mergeAndConvertSucceeded = 1;
2187 std::ostringstream errMsg;
2189 if (myRank == rootRank) {
2191 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2202 const size_type numRows = dims[0];
2205 pAdder->getAdder()->merge();
2208 const std::vector<element_type>& entries =
2209 pAdder->getAdder()->getEntries();
2212 const size_t numEntries = (size_t)entries.size();
2215 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2216 <<
" rows and numEntries=" << numEntries
2217 <<
" entries." << endl;
2223 numEntriesPerRow = arcp<size_t>(numRows);
2224 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2225 rowPtr = arcp<size_t>(numRows + 1);
2226 std::fill(rowPtr.begin(), rowPtr.end(), 0);
2227 colInd = arcp<global_ordinal_type>(numEntries);
2228 values = arcp<scalar_type>(numEntries);
2235 for (curPos = 0; curPos < numEntries; ++curPos) {
2236 const element_type& curEntry = entries[curPos];
2238 TEUCHOS_TEST_FOR_EXCEPTION(
2239 curRow < prvRow, std::logic_error,
2240 "Row indices are out of order, even though they are supposed "
2241 "to be sorted. curRow = "
2242 << curRow <<
", prvRow = "
2243 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2244 "this bug to the Tpetra developers.");
2245 if (curRow > prvRow) {
2251 numEntriesPerRow[curRow]++;
2252 colInd[curPos] = curEntry.colIndex();
2253 values[curPos] = curEntry.value();
2258 rowPtr[numRows] = numEntries;
2260 catch (std::exception& e) {
2261 mergeAndConvertSucceeded = 0;
2262 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2267 if (debug && mergeAndConvertSucceeded) {
2269 const size_type numRows = dims[0];
2270 const size_type maxToDisplay = 100;
2272 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2273 << (numEntriesPerRow.size() - 1) <<
"] ";
2274 if (numRows > maxToDisplay) {
2275 cerr <<
"(only showing first and last few entries) ";
2279 if (numRows > maxToDisplay) {
2280 for (size_type k = 0; k < 2; ++k) {
2281 cerr << numEntriesPerRow[k] <<
" ";
2284 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
2285 cerr << numEntriesPerRow[k] <<
" ";
2288 for (size_type k = 0; k < numRows - 1; ++k) {
2289 cerr << numEntriesPerRow[k] <<
" ";
2292 cerr << numEntriesPerRow[numRows - 1];
2294 cerr <<
"]" << endl;
2296 cerr <<
"----- Proc 0: rowPtr ";
2297 if (numRows > maxToDisplay) {
2298 cerr <<
"(only showing first and last few entries) ";
2301 if (numRows > maxToDisplay) {
2302 for (size_type k = 0; k < 2; ++k) {
2303 cerr << rowPtr[k] <<
" ";
2306 for (size_type k = numRows - 2; k < numRows; ++k) {
2307 cerr << rowPtr[k] <<
" ";
2310 for (size_type k = 0; k < numRows; ++k) {
2311 cerr << rowPtr[k] <<
" ";
2314 cerr << rowPtr[numRows] <<
"]" << endl;
2319 int mergeAndConvertSucceededAll = mergeAndConvertSucceeded;
2320 broadcast(*pComm, rootRank, ptr(&mergeAndConvertSucceededAll));
2321 if (mergeAndConvertSucceededAll == 0) {
2322 TEUCHOS_TEST_FOR_EXCEPTION(
2323 true, std::runtime_error,
2324 "Failed to merge sparse matrix entries and convert to CSR format: "
2335 if (debug && myRank == rootRank) {
2336 cerr <<
"-- Making range, domain, and row maps" << endl;
2343 RCP<const map_type> pRangeMap = makeRangeMap(pComm, dims[0]);
2344 RCP<const map_type> pDomainMap =
2345 makeDomainMap(pRangeMap, dims[0], dims[1]);
2346 RCP<const map_type> pRowMap = makeRowMap(null, pComm, dims[0]);
2348 if (debug && myRank == rootRank) {
2349 cerr <<
"-- Distributing the matrix data" << endl;
2363 ArrayRCP<size_t> myNumEntriesPerRow;
2364 ArrayRCP<size_t> myRowPtr;
2365 ArrayRCP<global_ordinal_type> myColInd;
2366 ArrayRCP<scalar_type> myValues;
2368 distribute(myNumEntriesPerRow, myRowPtr, myColInd, myValues, pRowMap,
2369 numEntriesPerRow, rowPtr, colInd, values, debug);
2371 if (debug && myRank == rootRank) {
2372 cerr <<
"-- Inserting matrix entries on each process "
2373 "and calling fillComplete()"
2383 Teuchos::RCP<sparse_matrix_type> pMatrix =
2384 makeMatrix(myNumEntriesPerRow, myRowPtr, myColInd, myValues,
2385 pRowMap, pRangeMap, pDomainMap, constructorParams,
2386 fillCompleteParams);
2391 int localIsNull = pMatrix.is_null() ? 1 : 0;
2392 int globalIsNull = 0;
2393 reduceAll(*pComm, Teuchos::REDUCE_MAX, localIsNull, ptr(&globalIsNull));
2394 TEUCHOS_TEST_FOR_EXCEPTION(globalIsNull != 0, std::logic_error,
2395 "MatrixMarketReader::makeMatrix() returned a null pointer on at least one "
2396 "process. Please report this bug to the Tpetra developers.");
2398 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::logic_error,
2399 "MatrixMarketReader::makeMatrix() returned a null pointer. "
2400 "Please report this bug to the Tpetra developers.");
2409 if (extraDebug && debug) {
2410 const int numProcs = pComm->getSize();
2412 pRangeMap->getGlobalNumElements();
2414 pDomainMap->getGlobalNumElements();
2415 if (myRank == rootRank) {
2416 cerr <<
"-- Matrix is "
2417 << globalNumRows <<
" x " << globalNumCols
2418 <<
" with " << pMatrix->getGlobalNumEntries()
2419 <<
" entries, and index base "
2420 << pMatrix->getIndexBase() <<
"." << endl;
2423 for (
int p = 0; p < numProcs; ++p) {
2425 cerr <<
"-- Proc " << p <<
" owns "
2426 << pMatrix->getLocalNumCols() <<
" columns, and "
2427 << pMatrix->getLocalNumEntries() <<
" entries." << endl;
2433 if (debug && myRank == rootRank) {
2434 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2440template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2441Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
2443 const Teuchos::RCP<const map_type>& rowMap,
2444 Teuchos::RCP<const map_type>& colMap,
2445 const Teuchos::RCP<const map_type>& domainMap,
2446 const Teuchos::RCP<const map_type>& rangeMap,
2447 const bool callFillComplete,
2448 const bool tolerant,
2452 using Teuchos::arcp;
2453 using Teuchos::ArrayRCP;
2454 using Teuchos::ArrayView;
2456 using Teuchos::broadcast;
2457 using Teuchos::Comm;
2458 using Teuchos::null;
2461 using Teuchos::reduceAll;
2462 using Teuchos::Tuple;
2463 using Teuchos::MatrixMarket::Banner;
2464 typedef Teuchos::ScalarTraits<scalar_type> STS;
2466 RCP<const Comm<int>> pComm = rowMap->getComm();
2467 const int myRank = pComm->getRank();
2468 const int rootRank = 0;
2469 const bool extraDebug =
false;
2474 TEUCHOS_TEST_FOR_EXCEPTION(
2475 rowMap.is_null(), std::invalid_argument,
2476 "Row Map must be nonnull.");
2477 TEUCHOS_TEST_FOR_EXCEPTION(
2478 rangeMap.is_null(), std::invalid_argument,
2479 "Range Map must be nonnull.");
2480 TEUCHOS_TEST_FOR_EXCEPTION(
2481 domainMap.is_null(), std::invalid_argument,
2482 "Domain Map must be nonnull.");
2483 TEUCHOS_TEST_FOR_EXCEPTION(
2484 rowMap->getComm().getRawPtr() != pComm.getRawPtr(),
2485 std::invalid_argument,
2486 "The specified row Map's communicator (rowMap->getComm())"
2487 "differs from the given separately supplied communicator pComm.");
2488 TEUCHOS_TEST_FOR_EXCEPTION(
2489 domainMap->getComm().getRawPtr() != pComm.getRawPtr(),
2490 std::invalid_argument,
2491 "The specified domain Map's communicator (domainMap->getComm())"
2492 "differs from the given separately supplied communicator pComm.");
2493 TEUCHOS_TEST_FOR_EXCEPTION(
2494 rangeMap->getComm().getRawPtr() != pComm.getRawPtr(),
2495 std::invalid_argument,
2496 "The specified range Map's communicator (rangeMap->getComm())"
2497 "differs from the given separately supplied communicator pComm.");
2502 size_t lineNumber = 1;
2504 if (debug && myRank == rootRank) {
2505 cerr <<
"Matrix Market reader: readSparse:" << endl
2506 <<
"-- Reading banner line" << endl;
2515 RCP<const Banner> pBanner;
2521 int bannerIsCorrect = 1;
2522 std::ostringstream errMsg;
2524 if (myRank == rootRank) {
2527 pBanner = readBanner(in, lineNumber, tolerant, debug);
2528 }
catch (std::exception& e) {
2529 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2530 "threw an exception: "
2532 bannerIsCorrect = 0;
2535 if (bannerIsCorrect) {
2540 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
2541 bannerIsCorrect = 0;
2542 errMsg <<
"The Matrix Market input file must contain a "
2543 "\"coordinate\"-format sparse matrix in order to create a "
2544 "Tpetra::CrsMatrix object from it, but the file's matrix "
2546 << pBanner->matrixType() <<
"\" instead.";
2551 if (tolerant && pBanner->matrixType() ==
"array") {
2552 bannerIsCorrect = 0;
2553 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2554 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2555 "object from it, but the file's matrix type is \"array\" "
2556 "instead. That probably means the file contains dense matrix "
2563 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
2570 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
2571 std::invalid_argument, errMsg.str());
2573 if (debug && myRank == rootRank) {
2574 cerr <<
"-- Reading dimensions line" << endl;
2582 Tuple<global_ordinal_type, 3> dims =
2583 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
2585 if (debug && myRank == rootRank) {
2586 cerr <<
"-- Making Adder for collecting matrix data" << endl;
2593 RCP<adder_type> pAdder =
2594 makeAdder(pComm, pBanner, dims, tolerant, debug);
2596 if (debug && myRank == rootRank) {
2597 cerr <<
"-- Reading matrix data" << endl;
2607 int readSuccess = 1;
2608 std::ostringstream errMsg;
2609 if (myRank == rootRank) {
2612 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2615 reader_type reader(pAdder);
2618 std::pair<bool, std::vector<size_t>> results =
2619 reader.read(in, lineNumber, tolerant, debug);
2620 readSuccess = results.first ? 1 : 0;
2621 }
catch (std::exception& e) {
2626 broadcast(*pComm, rootRank, ptr(&readSuccess));
2635 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
2636 "Failed to read the Matrix Market sparse matrix file: "
2640 if (debug && myRank == rootRank) {
2641 cerr <<
"-- Successfully read the Matrix Market data" << endl;
2654 if (debug && myRank == rootRank) {
2655 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2657 <<
"----- Dimensions before: "
2658 << dims[0] <<
" x " << dims[1]
2662 Tuple<global_ordinal_type, 2> updatedDims;
2663 if (myRank == rootRank) {
2670 std::max(dims[0], pAdder->getAdder()->numRows());
2671 updatedDims[1] = pAdder->getAdder()->numCols();
2673 broadcast(*pComm, rootRank, updatedDims);
2674 dims[0] = updatedDims[0];
2675 dims[1] = updatedDims[1];
2676 if (debug && myRank == rootRank) {
2677 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
2690 if (myRank == rootRank) {
2697 if (dims[0] < pAdder->getAdder()->numRows()) {
2701 broadcast(*pComm, 0, ptr(&dimsMatch));
2702 if (dimsMatch == 0) {
2709 Tuple<global_ordinal_type, 2> addersDims;
2710 if (myRank == rootRank) {
2711 addersDims[0] = pAdder->getAdder()->numRows();
2712 addersDims[1] = pAdder->getAdder()->numCols();
2714 broadcast(*pComm, 0, addersDims);
2715 TEUCHOS_TEST_FOR_EXCEPTION(
2716 dimsMatch == 0, std::runtime_error,
2717 "The matrix metadata says that the matrix is " << dims[0] <<
" x "
2718 << dims[1] <<
", but the actual data says that the matrix is "
2719 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
2720 "data includes more rows than reported in the metadata. This "
2721 "is not allowed when parsing in strict mode. Parse the matrix in "
2722 "tolerant mode to ignore the metadata when it disagrees with the "
2727 if (debug && myRank == rootRank) {
2728 cerr <<
"-- Converting matrix data into CSR format on Proc 0" << endl;
2740 ArrayRCP<size_t> numEntriesPerRow;
2741 ArrayRCP<size_t> rowPtr;
2742 ArrayRCP<global_ordinal_type> colInd;
2743 ArrayRCP<scalar_type> values;
2748 int mergeAndConvertSucceeded = 1;
2749 std::ostringstream errMsg;
2751 if (myRank == rootRank) {
2753 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2764 const size_type numRows = dims[0];
2767 pAdder->getAdder()->merge();
2770 const std::vector<element_type>& entries =
2771 pAdder->getAdder()->getEntries();
2774 const size_t numEntries = (size_t)entries.size();
2777 cerr <<
"----- Proc 0: Matrix has numRows=" << numRows
2778 <<
" rows and numEntries=" << numEntries
2779 <<
" entries." << endl;
2785 numEntriesPerRow = arcp<size_t>(numRows);
2786 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
2787 rowPtr = arcp<size_t>(numRows + 1);
2788 std::fill(rowPtr.begin(), rowPtr.end(), 0);
2789 colInd = arcp<global_ordinal_type>(numEntries);
2790 values = arcp<scalar_type>(numEntries);
2797 for (curPos = 0; curPos < numEntries; ++curPos) {
2798 const element_type& curEntry = entries[curPos];
2800 TEUCHOS_TEST_FOR_EXCEPTION(
2801 curRow < prvRow, std::logic_error,
2802 "Row indices are out of order, even though they are supposed "
2803 "to be sorted. curRow = "
2804 << curRow <<
", prvRow = "
2805 << prvRow <<
", at curPos = " << curPos <<
". Please report "
2806 "this bug to the Tpetra developers.");
2807 if (curRow > prvRow) {
2810 numEntriesPerRow[curRow]++;
2811 colInd[curPos] = curEntry.colIndex();
2812 values[curPos] = curEntry.value();
2817 rowPtr[row] = numEntriesPerRow[row - 1] + rowPtr[row - 1];
2820 catch (std::exception& e) {
2821 mergeAndConvertSucceeded = 0;
2822 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2827 if (debug && mergeAndConvertSucceeded) {
2829 const size_type numRows = dims[0];
2830 const size_type maxToDisplay = 100;
2832 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2833 << (numEntriesPerRow.size() - 1) <<
"] ";
2834 if (numRows > maxToDisplay) {
2835 cerr <<
"(only showing first and last few entries) ";
2839 if (numRows > maxToDisplay) {
2840 for (size_type k = 0; k < 2; ++k) {
2841 cerr << numEntriesPerRow[k] <<
" ";
2844 for (size_type k = numRows - 2; k < numRows - 1; ++k) {
2845 cerr << numEntriesPerRow[k] <<
" ";
2848 for (size_type k = 0; k < numRows - 1; ++k) {
2849 cerr << numEntriesPerRow[k] <<
" ";
2852 cerr << numEntriesPerRow[numRows - 1];
2854 cerr <<
"]" << endl;
2856 cerr <<
"----- Proc 0: rowPtr ";
2857 if (numRows > maxToDisplay) {
2858 cerr <<
"(only showing first and last few entries) ";
2861 if (numRows > maxToDisplay) {
2862 for (size_type k = 0; k < 2; ++k) {
2863 cerr << rowPtr[k] <<
" ";
2866 for (size_type k = numRows - 2; k < numRows; ++k) {
2867 cerr << rowPtr[k] <<
" ";
2870 for (size_type k = 0; k < numRows; ++k) {
2871 cerr << rowPtr[k] <<
" ";
2874 cerr << rowPtr[numRows] <<
"]" << endl;
2876 cerr <<
"----- Proc 0: colInd = [";
2877 for (
size_t k = 0; k < rowPtr[numRows]; ++k) {
2878 cerr << colInd[k] <<
" ";
2880 cerr <<
"]" << endl;
2894 if (debug && myRank == rootRank) {
2895 cerr <<
"-- Verifying Maps" << endl;
2897 TEUCHOS_TEST_FOR_EXCEPTION(
2898 as<global_ordinal_type>(dims[0]) != rangeMap->getMaxAllGlobalIndex() + 1 - rangeMap->getIndexBase(),
2899 std::invalid_argument,
2900 "The range Map has " << rangeMap->getMaxAllGlobalIndex()
2901 <<
" max entry, but the matrix has a global number of rows " << dims[0]
2903 TEUCHOS_TEST_FOR_EXCEPTION(
2904 as<global_ordinal_type>(dims[1]) != domainMap->getMaxAllGlobalIndex() + 1 - domainMap->getIndexBase(),
2905 std::invalid_argument,
2906 "The domain Map has " << domainMap->getMaxAllGlobalIndex()
2907 <<
" max entry, but the matrix has a global number of columns "
2911 RCP<Teuchos::FancyOStream> err = debug ? Teuchos::getFancyOStream(Teuchos::rcpFromRef(cerr)) : null;
2913 RCP<const map_type> gatherRowMap = Details::computeGatherMap(rowMap, err, debug);
2914 ArrayView<const global_ordinal_type> myRows =
2915 gatherRowMap->getLocalElementList();
2916 const size_type myNumRows = myRows.size();
2919 ArrayRCP<size_t> gatherNumEntriesPerRow = arcp<size_t>(myNumRows);
2920 for (size_type i_ = 0; i_ < myNumRows; i_++) {
2921 gatherNumEntriesPerRow[i_] = numEntriesPerRow[myRows[i_] - indexBase];
2927 RCP<sparse_matrix_type> A_proc0 =
2928 rcp(
new sparse_matrix_type(gatherRowMap, gatherNumEntriesPerRow()));
2929 if (myRank == rootRank) {
2931 cerr <<
"-- Proc 0: Filling gather matrix" << endl;
2934 cerr <<
"---- Rows: " << Teuchos::toString(myRows) << endl;
2938 for (size_type i_ = 0; i_ < myNumRows; ++i_) {
2939 size_type i = myRows[i_] - indexBase;
2941 const size_type curPos = as<size_type>(rowPtr[i]);
2943 ArrayView<global_ordinal_type> curColInd =
2944 colInd.view(curPos, curNumEntries);
2945 ArrayView<scalar_type> curValues =
2946 values.view(curPos, curNumEntries);
2949 for (size_type k = 0; k < curNumEntries; ++k) {
2950 curColInd[k] += indexBase;
2953 cerr <<
"------ Columns: " << Teuchos::toString(curColInd) << endl;
2954 cerr <<
"------ Values: " << Teuchos::toString(curValues) << endl;
2957 if (curNumEntries > 0) {
2958 A_proc0->insertGlobalValues(myRows[i_], curColInd, curValues);
2964 numEntriesPerRow = null;
2970 RCP<sparse_matrix_type> A;
2979 mv_type_go target_nnzPerRow(rowMap, 1);
2980 mv_type_go source_nnzPerRow(gatherRowMap, 1);
2981 Teuchos::ArrayRCP<GO> srcData = source_nnzPerRow.getDataNonConst(0);
2982 for (
int i = 0; i < myNumRows; i++)
2983 srcData[i] = gatherNumEntriesPerRow[i];
2984 srcData = Teuchos::null;
2985 target_nnzPerRow.doExport(source_nnzPerRow, exp,
Tpetra::INSERT);
2986 Teuchos::ArrayRCP<GO> targetData = target_nnzPerRow.getDataNonConst(0);
2987 ArrayRCP<size_t> targetData_size_t = arcp<size_t>(targetData.size());
2988 for (
int i = 0; i < targetData.size(); i++)
2989 targetData_size_t[i] = targetData[i];
2991 if (colMap.is_null()) {
2992 A = rcp(
new sparse_matrix_type(rowMap, targetData_size_t()));
2994 A = rcp(
new sparse_matrix_type(rowMap, colMap, targetData_size_t()));
2996 A->doExport(*A_proc0, exp,
INSERT);
2997 if (callFillComplete) {
2998 A->fillComplete(domainMap, rangeMap);
3010 if (callFillComplete) {
3011 const int numProcs = pComm->getSize();
3013 if (extraDebug && debug) {
3014 const global_size_t globalNumRows = rangeMap->getGlobalNumElements();
3015 const global_size_t globalNumCols = domainMap->getGlobalNumElements();
3016 if (myRank == rootRank) {
3017 cerr <<
"-- Matrix is "
3018 << globalNumRows <<
" x " << globalNumCols
3019 <<
" with " << A->getGlobalNumEntries()
3020 <<
" entries, and index base "
3021 << A->getIndexBase() <<
"." << endl;
3024 for (
int p = 0; p < numProcs; ++p) {
3026 cerr <<
"-- Proc " << p <<
" owns "
3027 << A->getLocalNumCols() <<
" columns, and "
3028 << A->getLocalNumEntries() <<
" entries." << endl;
3035 if (debug && myRank == rootRank) {
3036 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3042template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3043Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::multivector_type>
3046 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3047 const bool tolerant,
3049 const bool binary) {
3052 return readDense(in, comm, map, tolerant, debug, binary);
3055template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3058 const std::string& filename,
const bool safe,
3059 std::ios_base::openmode mode) {
3064 int all_should_stop =
false;
3067 if (comm->getRank() == 0) {
3068 in.open(filename, mode);
3069 all_should_stop = !in && safe;
3073 if (comm) Teuchos::broadcast(*comm, 0, &all_should_stop);
3075 TEUCHOS_TEST_FOR_EXCEPTION(
3078 "Could not open input file '" + filename +
"' on root rank 0.");
3083template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3084Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::vector_type>
3087 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3088 const bool tolerant,
3092 return readVector(in, comm, map, tolerant, debug);
3095template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3096Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::multivector_type>
3099 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3100 const bool tolerant,
3102 const bool binary) {
3103 Teuchos::RCP<Teuchos::FancyOStream> err =
3104 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3105 return readDenseImpl<scalar_type>(in, comm, map, err, tolerant, debug, binary);
3108template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3109Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::vector_type>
3112 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3113 const bool tolerant,
3115 Teuchos::RCP<Teuchos::FancyOStream> err =
3116 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3117 return readVectorImpl<scalar_type>(in, comm, map, err, tolerant, debug);
3120template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3121Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
3124 const bool tolerant,
3126 const bool binary) {
3129 return readMap(in, comm, tolerant, debug, binary);
3132template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3133template <
class MultiVectorScalarType>
3138MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readDenseImpl(std::istream& in,
3140 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3141 const Teuchos::RCP<Teuchos::FancyOStream>& err,
3142 const bool tolerant,
3144 const bool binary) {
3146 using Teuchos::ArrayRCP;
3148 using Teuchos::broadcast;
3149 using Teuchos::outArg;
3151 using Teuchos::Tuple;
3152 using Teuchos::MatrixMarket::Banner;
3153 using Teuchos::MatrixMarket::checkCommentLine;
3154 typedef MultiVectorScalarType ST;
3158 typedef Teuchos::ScalarTraits<ST> STS;
3159 typedef typename STS::magnitudeType MT;
3160 typedef Teuchos::ScalarTraits<MT> STM;
3165 const int myRank = comm->getRank();
3167 if (!err.is_null()) {
3171 *err << myRank <<
": readDenseImpl" << endl;
3173 if (!err.is_null()) {
3208 size_t lineNumber = 1;
3211 std::ostringstream exMsg;
3212 int localBannerReadSuccess = 1;
3213 int localDimsReadSuccess = 1;
3219 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
3225 RCP<const Banner> pBanner;
3227 pBanner = readBanner(in, lineNumber, tolerant, debug);
3228 }
catch (std::exception& e) {
3230 localBannerReadSuccess = 0;
3233 if (localBannerReadSuccess) {
3234 if (pBanner->matrixType() !=
"array") {
3235 exMsg <<
"The Matrix Market file does not contain dense matrix "
3236 "data. Its banner (first) line says that its matrix type is \""
3237 << pBanner->matrixType() <<
"\", rather that the required "
3239 localBannerReadSuccess = 0;
3240 }
else if (pBanner->dataType() ==
"pattern") {
3241 exMsg <<
"The Matrix Market file's banner (first) "
3242 "line claims that the matrix's data type is \"pattern\". This does "
3243 "not make sense for a dense matrix, yet the file reports the matrix "
3244 "as dense. The only valid data types for a dense matrix are "
3245 "\"real\", \"complex\", and \"integer\".";
3246 localBannerReadSuccess = 0;
3250 dims[2] = encodeDataType(pBanner->dataType());
3256 if (localBannerReadSuccess) {
3258 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
3267 bool commentLine =
true;
3269 while (commentLine) {
3272 if (in.eof() || in.fail()) {
3273 exMsg <<
"Unable to get array dimensions line (at all) from line "
3274 << lineNumber <<
" of input stream. The input stream "
3275 <<
"claims that it is "
3276 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
3277 localDimsReadSuccess = 0;
3280 if (getline(in, line)) {
3287 size_t start = 0, size = 0;
3288 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
3295 std::istringstream istr(line);
3299 if (istr.eof() || istr.fail()) {
3300 exMsg <<
"Unable to read any data from line " << lineNumber
3301 <<
" of input; the line should contain the matrix dimensions "
3302 <<
"\"<numRows> <numCols>\".";
3303 localDimsReadSuccess = 0;
3308 exMsg <<
"Failed to get number of rows from line "
3309 << lineNumber <<
" of input; the line should contains the "
3310 <<
"matrix dimensions \"<numRows> <numCols>\".";
3311 localDimsReadSuccess = 0;
3313 dims[0] = theNumRows;
3315 exMsg <<
"No more data after number of rows on line "
3316 << lineNumber <<
" of input; the line should contain the "
3317 <<
"matrix dimensions \"<numRows> <numCols>\".";
3318 localDimsReadSuccess = 0;
3323 exMsg <<
"Failed to get number of columns from line "
3324 << lineNumber <<
" of input; the line should contain "
3325 <<
"the matrix dimensions \"<numRows> <numCols>\".";
3326 localDimsReadSuccess = 0;
3328 dims[1] = theNumCols;
3337 in.read(
reinterpret_cast<char*
>(&numRows),
sizeof(numRows));
3338 in.read(
reinterpret_cast<char*
>(&numCols),
sizeof(numCols));
3339 TEUCHOS_TEST_FOR_EXCEPTION(
3340 numRows == 0 || numCols == 0,
3342 "Matrix Market dense binary header has non-positive dimensions: "
3344 << numRows <<
", numCols=" << numCols);
3345 dims[0] = Teuchos::as<GO>(numRows);
3346 dims[1] = Teuchos::as<GO>(numCols);
3347 if ((
typeid(ST) ==
typeid(
double)) || Teuchos::ScalarTraits<ST>::isOrdinal) {
3349 }
else if (Teuchos::ScalarTraits<ST>::isComplex) {
3352 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
3353 "Unrecognized Matrix Market data type. "
3354 "We should never get here. "
3355 "Please report this bug to the Tpetra developers.");
3357 localDimsReadSuccess =
true;
3358 localDimsReadSuccess =
true;
3365 Tuple<GO, 5> bannerDimsReadResult;
3367 bannerDimsReadResult[0] = dims[0];
3368 bannerDimsReadResult[1] = dims[1];
3369 bannerDimsReadResult[2] = dims[2];
3370 bannerDimsReadResult[3] = localBannerReadSuccess;
3371 bannerDimsReadResult[4] = localDimsReadSuccess;
3375 broadcast(*comm, 0, bannerDimsReadResult);
3377 TEUCHOS_TEST_FOR_EXCEPTION(
3378 bannerDimsReadResult[3] == 0, std::runtime_error,
3379 "Failed to read banner line: " << exMsg.str());
3380 TEUCHOS_TEST_FOR_EXCEPTION(
3381 bannerDimsReadResult[4] == 0, std::runtime_error,
3382 "Failed to read matrix dimensions line: " << exMsg.str());
3384 dims[0] = bannerDimsReadResult[0];
3385 dims[1] = bannerDimsReadResult[1];
3386 dims[2] = bannerDimsReadResult[2];
3391 const size_t numCols =
static_cast<size_t>(dims[1]);
3396 RCP<const map_type> proc0Map;
3397 if (map.is_null()) {
3402 const size_t localNumRows = (myRank == 0) ? numRows : 0;
3407 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
3417 int localReadDataSuccess = 1;
3422 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
3427 TEUCHOS_TEST_FOR_EXCEPTION(
3428 !X->isConstantStride(), std::logic_error,
3429 "Can't get a 1-D view of the entries of the MultiVector X on "
3430 "Process 0, because the stride between the columns of X is not "
3431 "constant. This shouldn't happen because we just created X and "
3432 "haven't filled it in yet. Please report this bug to the Tpetra "
3439 ArrayRCP<ST> X_view = X->get1dViewNonConst();
3440 TEUCHOS_TEST_FOR_EXCEPTION(
3441 as<global_size_t>(X_view.size()) < numRows * numCols,
3443 "The view of X has size " << X_view.size() <<
" which is not enough to "
3444 "accommodate the expected number of entries numRows*numCols = "
3445 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
3446 "Please report this bug to the Tpetra developers.");
3447 const size_t stride = X->getStride();
3454 const bool isComplex = (dims[2] == 1);
3455 size_type count = 0, curRow = 0, curCol = 0;
3458 while (getline(in, line)) {
3462 size_t start = 0, size = 0;
3463 const bool commentLine =
3464 checkCommentLine(line, start, size, lineNumber, tolerant);
3471 if (count >= X_view.size()) {
3475 TEUCHOS_TEST_FOR_EXCEPTION(
3476 count >= X_view.size(),
3478 "The Matrix Market input stream has more data in it than "
3479 "its metadata reported. Current line number is "
3480 << lineNumber <<
".");
3489 const size_t pos = line.substr(start, size).find(
':');
3490 if (pos != std::string::npos) {
3494 std::istringstream istr(line.substr(start, size));
3498 if (istr.eof() || istr.fail()) {
3505 TEUCHOS_TEST_FOR_EXCEPTION(
3506 !tolerant && (istr.eof() || istr.fail()),
3508 "Line " << lineNumber <<
" of the Matrix Market file is "
3509 "empty, or we cannot read from it for some other reason.");
3512 ST val = STS::zero();
3515 MT real = STM::zero(), imag = STM::zero();
3532 TEUCHOS_TEST_FOR_EXCEPTION(
3533 !tolerant && istr.eof(), std::runtime_error,
3534 "Failed to get the real part of a complex-valued matrix "
3536 << lineNumber <<
" of the Matrix Market "
3542 }
else if (istr.eof()) {
3543 TEUCHOS_TEST_FOR_EXCEPTION(
3544 !tolerant && istr.eof(), std::runtime_error,
3545 "Missing imaginary part of a complex-valued matrix entry "
3547 << lineNumber <<
" of the Matrix Market file.");
3553 TEUCHOS_TEST_FOR_EXCEPTION(
3554 !tolerant && istr.fail(), std::runtime_error,
3555 "Failed to get the imaginary part of a complex-valued "
3556 "matrix entry from line "
3557 << lineNumber <<
" of the "
3558 "Matrix Market file.");
3565 TEUCHOS_TEST_FOR_EXCEPTION(
3566 !tolerant && istr.fail(), std::runtime_error,
3567 "Failed to get a real-valued matrix entry from line "
3568 << lineNumber <<
" of the Matrix Market file.");
3571 if (istr.fail() && tolerant) {
3577 TEUCHOS_TEST_FOR_EXCEPTION(
3578 !tolerant && istr.fail(), std::runtime_error,
3579 "Failed to read matrix data from line " << lineNumber
3580 <<
" of the Matrix Market file.");
3583 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
3585 curRow = count % numRows;
3586 curCol = count / numRows;
3587 X_view[curRow + curCol * stride] = val;
3592 TEUCHOS_TEST_FOR_EXCEPTION(
3593 !tolerant &&
static_cast<global_size_t>(count) < numRows * numCols,
3595 "The Matrix Market metadata reports that the dense matrix is "
3596 << numRows <<
" x " << numCols <<
", and thus has "
3597 << numRows * numCols <<
" total entries, but we only found " << count
3598 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
3599 }
catch (std::exception& e) {
3601 localReadDataSuccess = 0;
3606 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
3611 TEUCHOS_TEST_FOR_EXCEPTION(
3612 !X->isConstantStride(), std::logic_error,
3613 "Can't get a 1-D view of the entries of the MultiVector X on "
3614 "Process 0, because the stride between the columns of X is not "
3615 "constant. This shouldn't happen because we just created X and "
3616 "haven't filled it in yet. Please report this bug to the Tpetra "
3623 auto X_view = X->getLocalViewHost(Access::OverwriteAll);
3625 TEUCHOS_TEST_FOR_EXCEPTION(
3626 as<global_size_t>(X_view.extent(0)) < numRows,
3628 "The view of X has " << X_view.extent(0) <<
" rows which is not enough to "
3629 "accommodate the expected number of entries numRows = "
3631 "Please report this bug to the Tpetra developers.");
3632 TEUCHOS_TEST_FOR_EXCEPTION(
3633 as<global_size_t>(X_view.extent(1)) < numCols,
3635 "The view of X has " << X_view.extent(1) <<
" colums which is not enough to "
3636 "accommodate the expected number of entries numRows = "
3638 "Please report this bug to the Tpetra developers.");
3640 for (
size_t curRow = 0; curRow < numRows; ++curRow) {
3641 for (
size_t curCol = 0; curCol < numCols; ++curCol) {
3642 if (Teuchos::ScalarTraits<ST>::isOrdinal) {
3644 in.read(
reinterpret_cast<char*
>(&val),
sizeof(val));
3645 X_view(curRow, curCol) = val;
3648 in.read(
reinterpret_cast<char*
>(&val),
sizeof(val));
3649 X_view(curRow, curCol) = val;
3657 *err << myRank <<
": readDenseImpl: done reading data" << endl;
3661 int globalReadDataSuccess = localReadDataSuccess;
3662 broadcast(*comm, 0, outArg(globalReadDataSuccess));
3663 TEUCHOS_TEST_FOR_EXCEPTION(
3664 globalReadDataSuccess == 0, std::runtime_error,
3665 "Failed to read the multivector's data: " << exMsg.str());
3670 if (comm->getSize() == 1 && map.is_null()) {
3672 if (!err.is_null()) {
3676 *err << myRank <<
": readDenseImpl: done" << endl;
3678 if (!err.is_null()) {
3685 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
3692 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
3701 *err << myRank <<
": readDenseImpl: Exporting" << endl;
3704 Y->doExport(*X, exporter,
INSERT);
3706 if (!err.is_null()) {
3710 *err << myRank <<
": readDenseImpl: done" << endl;
3712 if (!err.is_null()) {
3720template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3721template <
class VectorScalarType>
3722Teuchos::RCP<Tpetra::Vector<VectorScalarType,
3726MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readVectorImpl(std::istream& in,
3728 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3729 const Teuchos::RCP<Teuchos::FancyOStream>& err,
3730 const bool tolerant,
3734 using Teuchos::broadcast;
3735 using Teuchos::outArg;
3737 using Teuchos::Tuple;
3738 using Teuchos::MatrixMarket::Banner;
3739 using Teuchos::MatrixMarket::checkCommentLine;
3740 typedef VectorScalarType ST;
3744 typedef Teuchos::ScalarTraits<ST> STS;
3745 typedef typename STS::magnitudeType MT;
3746 typedef Teuchos::ScalarTraits<MT> STM;
3747 typedef Tpetra::Vector<ST, LO, GO, NT> MV;
3751 const int myRank = comm->getRank();
3753 if (!err.is_null()) {
3757 *err << myRank <<
": readVectorImpl" << endl;
3759 if (!err.is_null()) {
3793 size_t lineNumber = 1;
3796 std::ostringstream exMsg;
3797 int localBannerReadSuccess = 1;
3798 int localDimsReadSuccess = 1;
3803 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
3809 RCP<const Banner> pBanner;
3811 pBanner = readBanner(in, lineNumber, tolerant, debug);
3812 }
catch (std::exception& e) {
3814 localBannerReadSuccess = 0;
3817 if (localBannerReadSuccess) {
3818 if (pBanner->matrixType() !=
"array") {
3819 exMsg <<
"The Matrix Market file does not contain dense matrix "
3820 "data. Its banner (first) line says that its matrix type is \""
3821 << pBanner->matrixType() <<
"\", rather that the required "
3823 localBannerReadSuccess = 0;
3824 }
else if (pBanner->dataType() ==
"pattern") {
3825 exMsg <<
"The Matrix Market file's banner (first) "
3826 "line claims that the matrix's data type is \"pattern\". This does "
3827 "not make sense for a dense matrix, yet the file reports the matrix "
3828 "as dense. The only valid data types for a dense matrix are "
3829 "\"real\", \"complex\", and \"integer\".";
3830 localBannerReadSuccess = 0;
3834 dims[2] = encodeDataType(pBanner->dataType());
3840 if (localBannerReadSuccess) {
3842 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
3851 bool commentLine =
true;
3853 while (commentLine) {
3856 if (in.eof() || in.fail()) {
3857 exMsg <<
"Unable to get array dimensions line (at all) from line "
3858 << lineNumber <<
" of input stream. The input stream "
3859 <<
"claims that it is "
3860 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
3861 localDimsReadSuccess = 0;
3864 if (getline(in, line)) {
3871 size_t start = 0, size = 0;
3872 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
3879 std::istringstream istr(line);
3883 if (istr.eof() || istr.fail()) {
3884 exMsg <<
"Unable to read any data from line " << lineNumber
3885 <<
" of input; the line should contain the matrix dimensions "
3886 <<
"\"<numRows> <numCols>\".";
3887 localDimsReadSuccess = 0;
3892 exMsg <<
"Failed to get number of rows from line "
3893 << lineNumber <<
" of input; the line should contains the "
3894 <<
"matrix dimensions \"<numRows> <numCols>\".";
3895 localDimsReadSuccess = 0;
3897 dims[0] = theNumRows;
3899 exMsg <<
"No more data after number of rows on line "
3900 << lineNumber <<
" of input; the line should contain the "
3901 <<
"matrix dimensions \"<numRows> <numCols>\".";
3902 localDimsReadSuccess = 0;
3907 exMsg <<
"Failed to get number of columns from line "
3908 << lineNumber <<
" of input; the line should contain "
3909 <<
"the matrix dimensions \"<numRows> <numCols>\".";
3910 localDimsReadSuccess = 0;
3912 dims[1] = theNumCols;
3922 exMsg <<
"File does not contain a 1D Vector";
3923 localDimsReadSuccess = 0;
3929 Tuple<GO, 5> bannerDimsReadResult;
3931 bannerDimsReadResult[0] = dims[0];
3932 bannerDimsReadResult[1] = dims[1];
3933 bannerDimsReadResult[2] = dims[2];
3934 bannerDimsReadResult[3] = localBannerReadSuccess;
3935 bannerDimsReadResult[4] = localDimsReadSuccess;
3940 broadcast(*comm, 0, bannerDimsReadResult);
3942 TEUCHOS_TEST_FOR_EXCEPTION(
3943 bannerDimsReadResult[3] == 0, std::runtime_error,
3944 "Failed to read banner line: " << exMsg.str());
3945 TEUCHOS_TEST_FOR_EXCEPTION(
3946 bannerDimsReadResult[4] == 0, std::runtime_error,
3947 "Failed to read matrix dimensions line: " << exMsg.str());
3949 dims[0] = bannerDimsReadResult[0];
3950 dims[1] = bannerDimsReadResult[1];
3951 dims[2] = bannerDimsReadResult[2];
3956 const size_t numCols =
static_cast<size_t>(dims[1]);
3961 RCP<const map_type> proc0Map;
3962 if (map.is_null()) {
3967 const size_t localNumRows = (myRank == 0) ? numRows : 0;
3972 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
3982 int localReadDataSuccess = 1;
3986 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
3991 TEUCHOS_TEST_FOR_EXCEPTION(
3992 !X->isConstantStride(), std::logic_error,
3993 "Can't get a 1-D view of the entries of the MultiVector X on "
3994 "Process 0, because the stride between the columns of X is not "
3995 "constant. This shouldn't happen because we just created X and "
3996 "haven't filled it in yet. Please report this bug to the Tpetra "
4003 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst();
4004 TEUCHOS_TEST_FOR_EXCEPTION(
4005 as<global_size_t>(X_view.size()) < numRows * numCols,
4007 "The view of X has size " << X_view <<
" which is not enough to "
4008 "accommodate the expected number of entries numRows*numCols = "
4009 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
4010 "Please report this bug to the Tpetra developers.");
4011 const size_t stride = X->getStride();
4018 const bool isComplex = (dims[2] == 1);
4019 size_type count = 0, curRow = 0, curCol = 0;
4022 while (getline(in, line)) {
4026 size_t start = 0, size = 0;
4027 const bool commentLine =
4028 checkCommentLine(line, start, size, lineNumber, tolerant);
4035 if (count >= X_view.size()) {
4039 TEUCHOS_TEST_FOR_EXCEPTION(
4040 count >= X_view.size(),
4042 "The Matrix Market input stream has more data in it than "
4043 "its metadata reported. Current line number is "
4044 << lineNumber <<
".");
4053 const size_t pos = line.substr(start, size).find(
':');
4054 if (pos != std::string::npos) {
4058 std::istringstream istr(line.substr(start, size));
4062 if (istr.eof() || istr.fail()) {
4069 TEUCHOS_TEST_FOR_EXCEPTION(
4070 !tolerant && (istr.eof() || istr.fail()),
4072 "Line " << lineNumber <<
" of the Matrix Market file is "
4073 "empty, or we cannot read from it for some other reason.");
4076 ST val = STS::zero();
4079 MT real = STM::zero(), imag = STM::zero();
4096 TEUCHOS_TEST_FOR_EXCEPTION(
4097 !tolerant && istr.eof(), std::runtime_error,
4098 "Failed to get the real part of a complex-valued matrix "
4100 << lineNumber <<
" of the Matrix Market "
4106 }
else if (istr.eof()) {
4107 TEUCHOS_TEST_FOR_EXCEPTION(
4108 !tolerant && istr.eof(), std::runtime_error,
4109 "Missing imaginary part of a complex-valued matrix entry "
4111 << lineNumber <<
" of the Matrix Market file.");
4117 TEUCHOS_TEST_FOR_EXCEPTION(
4118 !tolerant && istr.fail(), std::runtime_error,
4119 "Failed to get the imaginary part of a complex-valued "
4120 "matrix entry from line "
4121 << lineNumber <<
" of the "
4122 "Matrix Market file.");
4129 TEUCHOS_TEST_FOR_EXCEPTION(
4130 !tolerant && istr.fail(), std::runtime_error,
4131 "Failed to get a real-valued matrix entry from line "
4132 << lineNumber <<
" of the Matrix Market file.");
4135 if (istr.fail() && tolerant) {
4141 TEUCHOS_TEST_FOR_EXCEPTION(
4142 !tolerant && istr.fail(), std::runtime_error,
4143 "Failed to read matrix data from line " << lineNumber
4144 <<
" of the Matrix Market file.");
4147 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
4149 curRow = count % numRows;
4150 curCol = count / numRows;
4151 X_view[curRow + curCol * stride] = val;
4156 TEUCHOS_TEST_FOR_EXCEPTION(
4157 !tolerant &&
static_cast<global_size_t>(count) < numRows * numCols,
4159 "The Matrix Market metadata reports that the dense matrix is "
4160 << numRows <<
" x " << numCols <<
", and thus has "
4161 << numRows * numCols <<
" total entries, but we only found " << count
4162 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4163 }
catch (std::exception& e) {
4165 localReadDataSuccess = 0;
4170 *err << myRank <<
": readVectorImpl: done reading data" << endl;
4174 int globalReadDataSuccess = localReadDataSuccess;
4175 broadcast(*comm, 0, outArg(globalReadDataSuccess));
4176 TEUCHOS_TEST_FOR_EXCEPTION(
4177 globalReadDataSuccess == 0, std::runtime_error,
4178 "Failed to read the multivector's data: " << exMsg.str());
4183 if (comm->getSize() == 1 && map.is_null()) {
4185 if (!err.is_null()) {
4189 *err << myRank <<
": readVectorImpl: done" << endl;
4191 if (!err.is_null()) {
4198 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
4205 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
4214 *err << myRank <<
": readVectorImpl: Exporting" << endl;
4217 Y->doExport(*X, exporter,
INSERT);
4219 if (!err.is_null()) {
4223 *err << myRank <<
": readVectorImpl: done" << endl;
4225 if (!err.is_null()) {
4233template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4234Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
4237 const bool tolerant,
4239 const bool binary) {
4240 Teuchos::RCP<Teuchos::FancyOStream> err =
4241 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
4242 return readMap(in, comm, err, tolerant, debug, binary);
4245template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4246Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
4249 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4250 const bool tolerant,
4252 const bool binary) {
4254 using Teuchos::arcp;
4255 using Teuchos::Array;
4256 using Teuchos::ArrayRCP;
4258 using Teuchos::broadcast;
4259 using Teuchos::Comm;
4260 using Teuchos::CommRequest;
4261 using Teuchos::inOutArg;
4262 using Teuchos::ireceive;
4263 using Teuchos::isend;
4264 using Teuchos::outArg;
4266 using Teuchos::receive;
4267 using Teuchos::REDUCE_MIN;
4268 using Teuchos::reduceAll;
4269 using Teuchos::SerialComm;
4270 using Teuchos::toString;
4271 using Teuchos::wait;
4273 typedef ptrdiff_t int_type;
4277 typedef Tpetra::MultiVector<GO, LO, GO, NT> MV;
4279 const int numProcs = comm->getSize();
4280 const int myRank = comm->getRank();
4282 if (!err.is_null()) {
4286 std::ostringstream os;
4287 os << myRank <<
": readMap: " << endl;
4290 if (!err.is_null()) {
4296 const int sizeTag = 1339;
4298 const int dataTag = 1340;
4304 RCP<CommRequest<int>> sizeReq;
4305 RCP<CommRequest<int>> dataReq;
4310 ArrayRCP<int_type> numGidsToRecv(1);
4311 numGidsToRecv[0] = 0;
4313 sizeReq = ireceive<int, int_type>(numGidsToRecv, 0, sizeTag, *comm);
4316 int readSuccess = 1;
4317 std::ostringstream exMsg;
4326 RCP<const Comm<int>> proc0Comm(
new SerialComm<int>());
4328 RCP<const map_type> dataMap;
4332 data = readDenseImpl<GO>(in, proc0Comm, dataMap, err, tolerant, debug, binary);
4334 if (data.is_null()) {
4336 exMsg <<
"readDenseImpl() returned null." << endl;
4338 }
catch (std::exception& e) {
4340 exMsg << e.what() << endl;
4346 std::map<int, Array<GO>> pid2gids;
4351 int_type globalNumGIDs = 0;
4361 if (myRank == 0 && readSuccess == 1) {
4362 if (data->getNumVectors() == 2) {
4363 ArrayRCP<const GO> GIDs = data->getData(0);
4364 ArrayRCP<const GO> PIDs = data->getData(1);
4365 globalNumGIDs = GIDs.size();
4369 if (globalNumGIDs > 0) {
4370 const int pid =
static_cast<int>(PIDs[0]);
4372 if (pid < 0 || pid >= numProcs) {
4374 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4375 <<
"Encountered invalid PID " << pid <<
"." << endl;
4377 const GO gid = GIDs[0];
4378 pid2gids[pid].push_back(gid);
4382 if (readSuccess == 1) {
4385 for (size_type k = 1; k < globalNumGIDs; ++k) {
4386 const int pid =
static_cast<int>(PIDs[k]);
4387 if (pid < 0 || pid >= numProcs) {
4389 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4390 <<
"Encountered invalid PID " << pid <<
"." << endl;
4392 const int_type gid = GIDs[k];
4393 pid2gids[pid].push_back(gid);
4394 if (gid < indexBase) {
4400 }
else if (data->getNumVectors() == 1) {
4401 if (data->getGlobalLength() % 2 !=
static_cast<GST
>(0)) {
4403 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
4404 "wrong format (for Map format 2.0). The global number of rows "
4405 "in the MultiVector must be even (divisible by 2)."
4408 ArrayRCP<const GO> theData = data->getData(0);
4409 globalNumGIDs =
static_cast<GO
>(data->getGlobalLength()) /
4414 if (globalNumGIDs > 0) {
4415 const int pid =
static_cast<int>(theData[1]);
4416 if (pid < 0 || pid >= numProcs) {
4418 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4419 <<
"Encountered invalid PID " << pid <<
"." << endl;
4421 const GO gid = theData[0];
4422 pid2gids[pid].push_back(gid);
4428 for (int_type k = 1; k < globalNumGIDs; ++k) {
4429 const int pid =
static_cast<int>(theData[2 * k + 1]);
4430 if (pid < 0 || pid >= numProcs) {
4432 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4433 <<
"Encountered invalid PID " << pid <<
"." << endl;
4435 const GO gid = theData[2 * k];
4436 pid2gids[pid].push_back(gid);
4437 if (gid < indexBase) {
4445 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
4446 "either 1 column (for the new Map format 2.0) or 2 columns (for "
4447 "the old Map format 1.0).";
4454 int_type readResults[3];
4455 readResults[0] =
static_cast<int_type
>(indexBase);
4456 readResults[1] =
static_cast<int_type
>(globalNumGIDs);
4457 readResults[2] =
static_cast<int_type
>(readSuccess);
4458 broadcast<int, int_type>(*comm, 0, 3, readResults);
4460 indexBase =
static_cast<GO
>(readResults[0]);
4461 globalNumGIDs =
static_cast<int_type
>(readResults[1]);
4462 readSuccess =
static_cast<int>(readResults[2]);
4468 TEUCHOS_TEST_FOR_EXCEPTION(
4469 readSuccess != 1, std::runtime_error,
4470 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
4471 "following exception message: "
4476 for (
int p = 1; p < numProcs; ++p) {
4477 ArrayRCP<int_type> numGidsToSend(1);
4479 auto it = pid2gids.find(p);
4480 if (it == pid2gids.end()) {
4481 numGidsToSend[0] = 0;
4483 numGidsToSend[0] = it->second.size();
4485 sizeReq = isend<int, int_type>(numGidsToSend, p, sizeTag, *comm);
4486 wait<int>(*comm, outArg(sizeReq));
4490 wait<int>(*comm, outArg(sizeReq));
4495 ArrayRCP<GO> myGids;
4496 int_type myNumGids = 0;
4498 GO* myGidsRaw = NULL;
4500 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(0);
4501 if (it != pid2gids.end()) {
4502 myGidsRaw = it->second.getRawPtr();
4503 myNumGids = it->second.size();
4505 myGids = arcp<GO>(myGidsRaw, 0, myNumGids,
false);
4508 myNumGids = numGidsToRecv[0];
4509 myGids = arcp<GO>(myNumGids);
4516 if (myNumGids > 0) {
4517 dataReq = ireceive<int, GO>(myGids, 0, dataTag, *comm);
4521 for (
int p = 1; p < numProcs; ++p) {
4523 ArrayRCP<GO> sendGids;
4524 GO* sendGidsRaw = NULL;
4525 int_type numSendGids = 0;
4527 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(p);
4528 if (it != pid2gids.end()) {
4529 numSendGids = it->second.size();
4530 sendGidsRaw = it->second.getRawPtr();
4531 sendGids = arcp<GO>(sendGidsRaw, 0, numSendGids,
false);
4534 if (numSendGids > 0) {
4535 dataReq = isend<int, GO>(sendGids, p, dataTag, *comm);
4537 wait<int>(*comm, outArg(dataReq));
4538 }
else if (myRank == p) {
4540 wait<int>(*comm, outArg(dataReq));
4545 std::ostringstream os;
4546 os << myRank <<
": readMap: creating Map" << endl;
4549 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid();
4550 RCP<const map_type> newMap;
4557 std::ostringstream errStrm;
4559 newMap = rcp(
new map_type(INVALID, myGids(), indexBase, comm));
4560 }
catch (std::exception& e) {
4562 errStrm <<
"Process " << comm->getRank() <<
" threw an exception: "
4563 << e.what() << std::endl;
4566 errStrm <<
"Process " << comm->getRank() <<
" threw an exception "
4567 "not a subclass of std::exception"
4570 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MIN,
4571 lclSuccess, Teuchos::outArg(gblSuccess));
4572 if (gblSuccess != 1) {
4575 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
4577 if (!err.is_null()) {
4581 std::ostringstream os;
4582 os << myRank <<
": readMap: done" << endl;
4585 if (!err.is_null()) {
4591template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4592int MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::encodeDataType(
const std::string& dataType) {
4593 if (dataType ==
"real" || dataType ==
"integer") {
4595 }
else if (dataType ==
"complex") {
4597 }
else if (dataType ==
"pattern") {
4603 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
4604 "Unrecognized Matrix Market data type \"" << dataType
4605 <<
"\". We should never get here. "
4606 "Please report this bug to the Tpetra developers.");
4610template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4611Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
4613 const std::string& filename_suffix,
4614 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rowMap,
4615 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& colMap,
4616 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& domainMap,
4617 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rangeMap,
4618 const bool callFillComplete,
4619 const bool tolerant,
4620 const int ranksToReadAtOnce,
4625 using STS =
typename Teuchos::ScalarTraits<ST>;
4626 using Teuchos::arcp;
4627 using Teuchos::ArrayRCP;
4635 TEUCHOS_TEST_FOR_EXCEPTION(
4636 rowMap.is_null(), std::invalid_argument,
4637 "Row Map must be nonnull.");
4638 Teuchos::RCP<const Teuchos::Comm<int>> comm = rowMap->getComm();
4639 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
4640 "The input row map's communicator (Teuchos::Comm object) is null.");
4641 TEUCHOS_TEST_FOR_EXCEPTION(
4642 rangeMap.is_null(), std::invalid_argument,
4643 "Range Map must be nonnull.");
4644 TEUCHOS_TEST_FOR_EXCEPTION(
4645 domainMap.is_null(), std::invalid_argument,
4646 "Domain Map must be nonnull.");
4647 TEUCHOS_TEST_FOR_EXCEPTION(
4648 domainMap->getComm().getRawPtr() != comm.getRawPtr(),
4649 std::invalid_argument,
4650 "The specified domain Map's communicator (domainMap->getComm())"
4651 "differs from row Map's communicator");
4652 TEUCHOS_TEST_FOR_EXCEPTION(
4653 rangeMap->getComm().getRawPtr() != comm.getRawPtr(),
4654 std::invalid_argument,
4655 "The specified range Map's communicator (rangeMap->getComm())"
4656 "differs from row Map's communicator");
4659 const int myRank = comm->getRank();
4660 const int numProc = comm->getSize();
4661 std::string filename = filename_prefix + std::to_string(myRank) + filename_suffix;
4664 int rank_limit = std::min(std::max(ranksToReadAtOnce, 1), numProc);
4667 ArrayRCP<size_t> numEntriesPerRow;
4668 ArrayRCP<size_t> rowPtr;
4669 ArrayRCP<global_ordinal_type> colInd;
4670 ArrayRCP<scalar_type> values;
4671 std::ostringstream errMsg;
4678 bool success =
true;
4679 int bannerIsCorrect = 1, readSuccess = 1;
4680 LO numRows, numCols, numNonzeros;
4681 for (
int base_rank = 0; base_rank < numProc; base_rank += rank_limit) {
4682 int stop = std::min(base_rank + rank_limit, numProc);
4685 if (base_rank <= myRank && myRank < stop) {
4687 std::ifstream in(filename);
4688 using Teuchos::MatrixMarket::Banner;
4689 size_t lineNumber = 1;
4690 RCP<const Banner> pBanner;
4692 pBanner = readBanner(in, lineNumber, tolerant, debug);
4693 }
catch (std::exception& e) {
4694 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
4695 "threw an exception: "
4697 bannerIsCorrect = 0;
4699 if (bannerIsCorrect) {
4704 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
4705 bannerIsCorrect = 0;
4706 errMsg <<
"The Matrix Market input file must contain a "
4707 "\"coordinate\"-format sparse matrix in order to create a "
4708 "Tpetra::CrsMatrix object from it, but the file's matrix "
4710 << pBanner->matrixType() <<
"\" instead.";
4715 if (tolerant && pBanner->matrixType() ==
"array") {
4716 bannerIsCorrect = 0;
4717 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
4718 "format sparse matrix in order to create a Tpetra::CrsMatrix "
4719 "object from it, but the file's matrix type is \"array\" "
4720 "instead. That probably means the file contains dense matrix "
4726 using Teuchos::MatrixMarket::readCoordinateDimensions;
4727 success = readCoordinateDimensions(in, numRows, numCols,
4728 numNonzeros, lineNumber,
4732 TEUCHOS_TEST_FOR_EXCEPTION(numRows != (LO)rowMap->getLocalNumElements(), std::invalid_argument,
4733 "# rows in file does not match rowmap.");
4734 TEUCHOS_TEST_FOR_EXCEPTION(!colMap.is_null() && numCols != (LO)colMap->getLocalNumElements(), std::invalid_argument,
4735 "# rows in file does not match colmap.");
4738 typedef Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type> raw_adder_type;
4739 bool tolerant_required =
true;
4740 Teuchos::RCP<raw_adder_type> pRaw =
4741 Teuchos::rcp(
new raw_adder_type(numRows, numCols, numNonzeros, tolerant_required, debug));
4742 RCP<adder_type> pAdder = Teuchos::rcp(
new adder_type(pRaw, pBanner->symmType()));
4745 std::cerr <<
"-- Reading matrix data" << std::endl;
4750 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
4753 reader_type reader(pAdder);
4756 std::pair<bool, std::vector<size_t>> results = reader.read(in, lineNumber, tolerant_required, debug);
4758 readSuccess = results.first ? 1 : 0;
4759 }
catch (std::exception& e) {
4766 typedef Teuchos::MatrixMarket::Raw::Element<scalar_type, global_ordinal_type> element_type;
4769 pAdder->getAdder()->merge();
4772 const std::vector<element_type>& entries = pAdder->getAdder()->getEntries();
4775 const size_t numEntries = (size_t)entries.size();
4778 std::cerr <<
"----- Proc " << myRank <<
": Matrix has numRows=" << numRows
4779 <<
" rows and numEntries=" << numEntries
4780 <<
" entries." << std::endl;
4786 numEntriesPerRow = arcp<size_t>(numRows);
4787 std::fill(numEntriesPerRow.begin(), numEntriesPerRow.end(), 0);
4788 rowPtr = arcp<size_t>(numRows + 1);
4789 std::fill(rowPtr.begin(), rowPtr.end(), 0);
4790 colInd = arcp<global_ordinal_type>(numEntries);
4791 values = arcp<scalar_type>(numEntries);
4797 LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
4799 LO indexBase = rowMap->getIndexBase();
4800 for (curPos = 0; curPos < numEntries; ++curPos) {
4801 const element_type& curEntry = entries[curPos];
4803 LO l_curRow = rowMap->getLocalElement(curRow);
4805 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow == INVALID, std::logic_error,
4806 "Current global row " << curRow <<
" is invalid.");
4808 TEUCHOS_TEST_FOR_EXCEPTION(l_curRow < l_prvRow, std::logic_error,
4809 "Row indices are out of order, even though they are supposed "
4810 "to be sorted. curRow = "
4811 << l_curRow <<
", prvRow = "
4812 << l_prvRow <<
", at curPos = " << curPos <<
". Please report "
4813 "this bug to the Tpetra developers.");
4814 if (l_curRow > l_prvRow) {
4815 for (LO r = l_prvRow + 1; r <= l_curRow; ++r) {
4818 l_prvRow = l_curRow;
4820 numEntriesPerRow[l_curRow]++;
4821 colInd[curPos] = curEntry.colIndex() + indexBase;
4822 values[curPos] = curEntry.value();
4827 rowPtr[numRows] = numEntries;
4837 RCP<sparse_matrix_type> A;
4838 if (colMap.is_null()) {
4839 A = rcp(
new sparse_matrix_type(rowMap, numEntriesPerRow()));
4840 for (
size_t i = 0; i < rowMap->getLocalNumElements(); i++) {
4841 GO g_row = rowMap->getGlobalElement(i);
4842 size_t start = rowPtr[i];
4843 size_t size = rowPtr[i + 1] - rowPtr[i];
4845 A->insertGlobalValues(g_row, size, &values[start], &colInd[start]);
4849 throw std::runtime_error(
"Reading with a column map is not yet implemented");
4851 RCP<const map_type> myDomainMap = domainMap.is_null() ? rowMap : domainMap;
4852 RCP<const map_type> myRangeMap = rangeMap.is_null() ? rowMap : rangeMap;
4854 A->fillComplete(myDomainMap, myRangeMap);
4858 TEUCHOS_TEST_FOR_EXCEPTION(success ==
false, std::runtime_error,
4864template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4866 const sparse_matrix_type& matrix,
4867 const std::string& matrixName,
4868 const std::string& matrixDescription,
4871 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
4872 "The input matrix's communicator (Teuchos::Comm object) is null.");
4873 const int myRank = comm->getRank();
4875 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm, filename, myRank,
true);
4877 writeSparse(out, matrix, matrixName, matrixDescription, debug);
4883template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4885 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
4886 const std::string& matrixName,
4887 const std::string& matrixDescription,
4889 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::invalid_argument,
4890 "The input matrix is null.");
4892 matrixDescription, debug);
4895template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4897 const sparse_matrix_type& matrix,
4902template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4904 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
4909template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4911 const sparse_matrix_type& matrix,
4912 const std::string& matrixName,
4913 const std::string& matrixDescription,
4917 using Teuchos::ArrayView;
4918 using Teuchos::Comm;
4919 using Teuchos::FancyOStream;
4920 using Teuchos::getFancyOStream;
4921 using Teuchos::null;
4923 using Teuchos::rcpFromRef;
4927 using STS =
typename Teuchos::ScalarTraits<ST>;
4933 Teuchos::SetScientific<ST> sci(out);
4937 TEUCHOS_TEST_FOR_EXCEPTION(
4938 comm.is_null(), std::invalid_argument,
4939 "The input matrix's communicator (Teuchos::Comm object) is null.");
4940 const int myRank = comm->getRank();
4943 RCP<FancyOStream> err =
4944 debug ? getFancyOStream(rcpFromRef(std::cerr)) : null;
4946 std::ostringstream os;
4947 os << myRank <<
": writeSparse" << endl;
4950 os <<
"-- " << myRank <<
": past barrier" << endl;
4955 const bool debugPrint = debug && myRank == 0;
4957 RCP<const map_type> rowMap = matrix.
getRowMap();
4958 RCP<const map_type> colMap = matrix.
getColMap();
4960 RCP<const map_type> rangeMap = matrix.
getRangeMap();
4962 if (!rowMap->haveGlobalConstants())
4963 Teuchos::rcp_const_cast<map_type>(rowMap)->computeGlobalConstants();
4964 if (!colMap->haveGlobalConstants())
4965 Teuchos::rcp_const_cast<map_type>(colMap)->computeGlobalConstants();
4966 if (!domainMap->haveGlobalConstants())
4967 Teuchos::rcp_const_cast<map_type>(domainMap)->computeGlobalConstants();
4968 if (!rangeMap->haveGlobalConstants())
4969 Teuchos::rcp_const_cast<map_type>(rangeMap)->computeGlobalConstants();
4971 const global_size_t numRows = rangeMap->getMaxAllGlobalIndex() + 1 - rangeMap->getIndexBase();
4972 const global_size_t numCols = domainMap->getMaxAllGlobalIndex() + 1 - domainMap->getIndexBase();
4974 if (debug && myRank == 0) {
4975 std::ostringstream os;
4976 os <<
"-- Input sparse matrix is:"
4977 <<
"---- " << numRows <<
" x " << numCols << endl
4980 <<
" indexed." << endl
4981 <<
"---- Its row map has " << rowMap->getGlobalNumElements()
4982 <<
" elements." << endl
4983 <<
"---- Its col map has " << colMap->getGlobalNumElements()
4984 <<
" elements." << endl;
4989 const size_t localNumRows = (myRank == 0) ? numRows : 0;
4991 std::ostringstream os;
4992 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
4995 RCP<const map_type> gatherRowMap =
4996 Details::computeGatherMap(rowMap, err, debug);
5004 const size_t localNumCols = (myRank == 0) ? numCols : 0;
5005 RCP<const map_type> gatherColMap =
5006 Details::computeGatherMap(colMap, err, debug);
5015 RCP<sparse_matrix_type> newMatrix =
5016 rcp(
new sparse_matrix_type(gatherRowMap, gatherColMap,
5017 static_cast<size_t>(0)));
5019 newMatrix->doImport(matrix, importer,
INSERT);
5024 RCP<const map_type> gatherDomainMap =
5025 rcp(
new map_type(numCols, localNumCols,
5026 domainMap->getIndexBase(),
5028 RCP<const map_type> gatherRangeMap =
5029 rcp(
new map_type(numRows, localNumRows,
5030 rangeMap->getIndexBase(),
5032 newMatrix->fillComplete(gatherDomainMap, gatherRangeMap);
5036 cerr <<
"-- Output sparse matrix is:"
5037 <<
"---- " << newMatrix->getRangeMap()->getGlobalNumElements()
5039 << newMatrix->getDomainMap()->getGlobalNumElements()
5041 << newMatrix->getGlobalNumEntries() <<
" entries;" << endl
5043 << (newMatrix->isGloballyIndexed() ?
"Globally" :
"Locally")
5044 <<
" indexed." << endl
5045 <<
"---- Its row map has "
5046 << newMatrix->getRowMap()->getGlobalNumElements()
5047 <<
" elements, with index base "
5048 << newMatrix->getRowMap()->getIndexBase() <<
"." << endl
5049 <<
"---- Its col map has "
5050 << newMatrix->getColMap()->getGlobalNumElements()
5051 <<
" elements, with index base "
5052 << newMatrix->getColMap()->getIndexBase() <<
"." << endl
5053 <<
"---- Element count of output matrix's column Map may differ "
5054 <<
"from that of the input matrix's column Map, if some columns "
5055 <<
"of the matrix contain no entries." << endl;
5068 out <<
"%%MatrixMarket matrix coordinate "
5069 << (STS::isComplex ?
"complex" :
"real")
5070 <<
" general" << endl;
5073 if (matrixName !=
"") {
5074 printAsComment(out, matrixName);
5076 if (matrixDescription !=
"") {
5077 printAsComment(out, matrixDescription);
5087 out << newMatrix->getRangeMap()->getMaxAllGlobalIndex() + 1 - newMatrix->getRangeMap()->getIndexBase() <<
" "
5088 << newMatrix->getDomainMap()->getMaxAllGlobalIndex() + 1 - newMatrix->getDomainMap()->getIndexBase() <<
" "
5089 << newMatrix->getGlobalNumEntries() << endl;
5094 const GO rowIndexBase = gatherRowMap->getIndexBase();
5095 const GO colIndexBase = newMatrix->getColMap()->getIndexBase();
5103 if (newMatrix->isGloballyIndexed()) {
5106 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex();
5107 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex();
5108 for (GO globalRowIndex = minAllGlobalIndex;
5109 globalRowIndex <= maxAllGlobalIndex;
5111 typename sparse_matrix_type::global_inds_host_view_type ind;
5112 typename sparse_matrix_type::values_host_view_type val;
5113 newMatrix->getGlobalRowView(globalRowIndex, ind, val);
5114 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
5115 const GO globalColIndex = ind(ii);
5118 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
5119 << (globalColIndex + 1 - colIndexBase) <<
" ";
5120 if (STS::isComplex) {
5121 out << STS::real(val(ii)) <<
" " << STS::imag(val(ii));
5129 using OTG = Teuchos::OrdinalTraits<GO>;
5130 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
5131 localRowIndex <= gatherRowMap->getMaxLocalIndex();
5134 const GO globalRowIndex =
5135 gatherRowMap->getGlobalElement(localRowIndex);
5136 TEUCHOS_TEST_FOR_EXCEPTION(
5137 globalRowIndex == OTG::invalid(), std::logic_error,
5138 "Failed to convert the supposed local row index "
5139 << localRowIndex <<
" into a global row index. "
5140 "Please report this bug to the Tpetra developers.");
5141 typename sparse_matrix_type::local_inds_host_view_type ind;
5142 typename sparse_matrix_type::values_host_view_type val;
5143 newMatrix->getLocalRowView(localRowIndex, ind, val);
5144 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
5146 const GO globalColIndex =
5147 newMatrix->getColMap()->getGlobalElement(ind(ii));
5148 TEUCHOS_TEST_FOR_EXCEPTION(
5149 globalColIndex == OTG::invalid(), std::logic_error,
5150 "On local row " << localRowIndex <<
" of the sparse matrix: "
5151 "Failed to convert the supposed local column index "
5152 << ind(ii) <<
" into a global column index. Please report "
5153 "this bug to the Tpetra developers.");
5156 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
5157 << (globalColIndex + 1 - colIndexBase) <<
" ";
5158 if (STS::isComplex) {
5159 out << STS::real(val(ii)) <<
" " << STS::imag(val(ii));
5170template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5172 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5173 const std::string& matrixName,
5174 const std::string& matrixDescription,
5176 TEUCHOS_TEST_FOR_EXCEPTION(pMatrix.is_null(), std::invalid_argument,
5177 "The input matrix is null.");
5178 writeSparse(out, *pMatrix, matrixName, matrixDescription, debug);
5181template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5184 const std::string& graphName,
5185 const std::string& graphDescription,
5189 using Teuchos::ArrayView;
5190 using Teuchos::Comm;
5191 using Teuchos::FancyOStream;
5192 using Teuchos::getFancyOStream;
5193 using Teuchos::null;
5195 using Teuchos::rcpFromRef;
5204 if (rowMap.is_null()) {
5207 auto comm = rowMap->getComm();
5208 if (comm.is_null()) {
5211 const int myRank = comm->getRank();
5214 RCP<FancyOStream> err =
5215 debug ? getFancyOStream(rcpFromRef(std::cerr)) : null;
5217 std::ostringstream os;
5218 os << myRank <<
": writeSparseGraph" << endl;
5221 os <<
"-- " << myRank <<
": past barrier" << endl;
5226 const bool debugPrint = debug && myRank == 0;
5233 if (!rowMap->haveGlobalConstants())
5234 Teuchos::rcp_const_cast<map_type>(rowMap)->computeGlobalConstants();
5235 if (!colMap->haveGlobalConstants())
5236 Teuchos::rcp_const_cast<map_type>(colMap)->computeGlobalConstants();
5237 if (!domainMap->haveGlobalConstants())
5238 Teuchos::rcp_const_cast<map_type>(domainMap)->computeGlobalConstants();
5239 if (!rangeMap->haveGlobalConstants())
5240 Teuchos::rcp_const_cast<map_type>(rangeMap)->computeGlobalConstants();
5242 const global_size_t numRows = rangeMap->getGlobalNumElements();
5243 const global_size_t numCols = domainMap->getGlobalNumElements();
5245 if (debug && myRank == 0) {
5246 std::ostringstream os;
5247 os <<
"-- Input sparse graph is:"
5248 <<
"---- " << numRows <<
" x " << numCols <<
" with "
5252 <<
" indexed." << endl
5253 <<
"---- Its row Map has " << rowMap->getGlobalNumElements()
5254 <<
" elements." << endl
5255 <<
"---- Its col Map has " << colMap->getGlobalNumElements()
5256 <<
" elements." << endl;
5261 const size_t localNumRows = (myRank == 0) ? numRows : 0;
5263 std::ostringstream os;
5264 os <<
"-- " << myRank <<
": making gatherRowMap" << endl;
5267 auto gatherRowMap = Details::computeGatherMap(rowMap, err, debug);
5275 const size_t localNumCols = (myRank == 0) ? numCols : 0;
5276 auto gatherColMap = Details::computeGatherMap(colMap, err, debug);
5285 static_cast<size_t>(0));
5292 RCP<const map_type> gatherDomainMap =
5293 rcp(
new map_type(numCols, localNumCols,
5294 domainMap->getIndexBase(),
5296 RCP<const map_type> gatherRangeMap =
5297 rcp(
new map_type(numRows, localNumRows,
5298 rangeMap->getIndexBase(),
5300 newGraph.
fillComplete(gatherDomainMap, gatherRangeMap);
5304 cerr <<
"-- Output sparse graph is:"
5305 <<
"---- " << newGraph.
getRangeMap()->getGlobalNumElements()
5312 <<
" indexed." << endl
5313 <<
"---- Its row map has "
5314 << newGraph.
getRowMap()->getGlobalNumElements()
5315 <<
" elements, with index base "
5316 << newGraph.
getRowMap()->getIndexBase() <<
"." << endl
5317 <<
"---- Its col map has "
5318 << newGraph.
getColMap()->getGlobalNumElements()
5319 <<
" elements, with index base "
5320 << newGraph.
getColMap()->getIndexBase() <<
"." << endl
5321 <<
"---- Element count of output graph's column Map may differ "
5322 <<
"from that of the input matrix's column Map, if some columns "
5323 <<
"of the matrix contain no entries." << endl;
5337 out <<
"%%MatrixMarket matrix coordinate pattern general" << endl;
5340 if (graphName !=
"") {
5341 printAsComment(out, graphName);
5343 if (graphDescription !=
"") {
5344 printAsComment(out, graphDescription);
5355 out << newGraph.
getRangeMap()->getMaxAllGlobalIndex() + 1 - newGraph.
getRangeMap()->getIndexBase() <<
" "
5362 const GO rowIndexBase = gatherRowMap->getIndexBase();
5363 const GO colIndexBase = newGraph.
getColMap()->getIndexBase();
5374 const GO minAllGlobalIndex = gatherRowMap->getMinAllGlobalIndex();
5375 const GO maxAllGlobalIndex = gatherRowMap->getMaxAllGlobalIndex();
5376 for (GO globalRowIndex = minAllGlobalIndex;
5377 globalRowIndex <= maxAllGlobalIndex;
5379 typename crs_graph_type::global_inds_host_view_type ind;
5381 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
5382 const GO globalColIndex = ind(ii);
5385 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
5386 << (globalColIndex + 1 - colIndexBase) <<
" ";
5391 typedef Teuchos::OrdinalTraits<GO> OTG;
5392 for (LO localRowIndex = gatherRowMap->getMinLocalIndex();
5393 localRowIndex <= gatherRowMap->getMaxLocalIndex();
5396 const GO globalRowIndex =
5397 gatherRowMap->getGlobalElement(localRowIndex);
5398 TEUCHOS_TEST_FOR_EXCEPTION(globalRowIndex == OTG::invalid(), std::logic_error,
5400 "to convert the supposed local row index "
5401 << localRowIndex <<
" into a global row index. Please report this bug to the "
5402 "Tpetra developers.");
5403 typename crs_graph_type::local_inds_host_view_type ind;
5405 for (
size_t ii = 0; ii < ind.extent(0); ii++) {
5407 const GO globalColIndex =
5408 newGraph.
getColMap()->getGlobalElement(ind(ii));
5409 TEUCHOS_TEST_FOR_EXCEPTION(
5410 globalColIndex == OTG::invalid(), std::logic_error,
5411 "On local row " << localRowIndex <<
" of the sparse graph: "
5412 "Failed to convert the supposed local column index "
5413 << ind(ii) <<
" into a global column index. Please report "
5414 "this bug to the Tpetra developers.");
5417 out << (globalRowIndex + 1 - rowIndexBase) <<
" "
5418 << (globalColIndex + 1 - colIndexBase) <<
" ";
5426template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5433template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5436 const std::string& graphName,
5437 const std::string& graphDescription,
5440 if (comm.is_null()) {
5448 const int myRank = comm->getRank();
5450 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm, filename, myRank,
true);
5458template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5465template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5467 const Teuchos::RCP<const crs_graph_type>& pGraph,
5468 const std::string& graphName,
5469 const std::string& graphDescription,
5474template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5476 const Teuchos::RCP<const crs_graph_type>& pGraph,
5481template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5483 const sparse_matrix_type& matrix,
5488template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5490 const Teuchos::RCP<const sparse_matrix_type>& pMatrix,
5495template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5498 const std::string& matrixName,
5499 const std::string& matrixDescription,
5500 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5501 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5505 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm, filename, myRank,
true);
5507 writeDense(out, X, matrixName, matrixDescription, err, dbg);
5513template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5516 const std::string& matrixName,
5517 const std::string& matrixDescription,
5518 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5519 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5520 TEUCHOS_TEST_FOR_EXCEPTION(
5521 X.is_null(), std::invalid_argument,
5522 "Tpetra::MatrixMarket::"
5523 "writeDenseFile: The input MultiVector X is null.");
5524 writeDenseFile(filename, *X, matrixName, matrixDescription, err, dbg);
5527template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5530 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5531 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5532 writeDenseFile(filename, X,
"",
"", err, dbg);
5535template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5538 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5539 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5540 TEUCHOS_TEST_FOR_EXCEPTION(
5541 X.is_null(), std::invalid_argument,
5542 "Tpetra::MatrixMarket::"
5543 "writeDenseFile: The input MultiVector X is null.");
5544 writeDenseFile(filename, *X, err, dbg);
5547template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5550 const std::string& matrixName,
5551 const std::string& matrixDescription,
5552 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5553 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5555 using Teuchos::Comm;
5556 using Teuchos::outArg;
5557 using Teuchos::REDUCE_MAX;
5558 using Teuchos::reduceAll;
5566 const bool debug = !dbg.is_null();
5569 std::ostringstream os;
5570 os << myRank <<
": writeDense" << endl;
5575 writeDenseHeader(out, X, matrixName, matrixDescription, err, dbg);
5580 for (
size_t j = 0; j < numVecs; ++j) {
5581 writeDenseColumn(out, *(X.
getVector(j)), err, dbg);
5586 std::ostringstream os;
5587 os << myRank <<
": writeDense: Done" << endl;
5593template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5594std::ofstream MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::openOutFileOnRankZero(
5595 const trcp_tcomm_t& comm,
5596 const std::string& filename,
const int rank,
const bool safe,
5597 const std::ios_base::openmode mode) {
5602 int all_should_stop = 0;
5606 out.open(filename, mode);
5607 all_should_stop = !out && safe;
5611 if (comm) Teuchos::broadcast(*comm, 0, &all_should_stop);
5613 TEUCHOS_TEST_FOR_EXCEPTION(
5616 "Could not open output file '" + filename +
"' on root rank 0.");
5621template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5622void MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeDenseHeader(std::ostream& out,
5624 const std::string& matrixName,
5625 const std::string& matrixDescription,
5626 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5627 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5629 using Teuchos::Comm;
5630 using Teuchos::outArg;
5632 using Teuchos::REDUCE_MAX;
5633 using Teuchos::reduceAll;
5634 typedef Teuchos::ScalarTraits<scalar_type> STS;
5635 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
5645 const bool debug = !dbg.is_null();
5649 std::ostringstream os;
5650 os << myRank <<
": writeDenseHeader" << endl;
5669 std::ostringstream hdr;
5671 std::string dataType;
5672 if (STS::isComplex) {
5673 dataType =
"complex";
5674 }
else if (STS::isOrdinal) {
5675 dataType =
"integer";
5679 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
5684 if (matrixName !=
"") {
5685 printAsComment(hdr, matrixName);
5687 if (matrixDescription !=
"") {
5688 printAsComment(hdr, matrixDescription);
5691 hdr << X.getGlobalLength() <<
" " << X.getNumVectors() << endl;
5695 }
catch (std::exception& e) {
5696 if (!err.is_null()) {
5697 *err << prefix <<
"While writing the Matrix Market header, "
5698 "Process 0 threw an exception: "
5699 << e.what() << endl;
5708 reduceAll<int, int>(*comm, REDUCE_MAX, lclErr, outArg(gblErr));
5709 TEUCHOS_TEST_FOR_EXCEPTION(
5710 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
5711 "which prevented this method from completing.");
5715 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
5720template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5721void MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeDenseColumn(std::ostream& out,
5723 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5724 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5726 using Teuchos::arcp;
5727 using Teuchos::Array;
5728 using Teuchos::ArrayRCP;
5729 using Teuchos::ArrayView;
5730 using Teuchos::Comm;
5731 using Teuchos::CommRequest;
5732 using Teuchos::ireceive;
5733 using Teuchos::isend;
5734 using Teuchos::outArg;
5736 using Teuchos::REDUCE_MAX;
5737 using Teuchos::reduceAll;
5738 using Teuchos::TypeNameTraits;
5739 using Teuchos::wait;
5740 typedef Teuchos::ScalarTraits<scalar_type> STS;
5742 const Comm<int>& comm = *(X.getMap()->getComm());
5743 const int myRank = comm.getRank();
5744 const int numProcs = comm.getSize();
5751 const bool debug = !dbg.is_null();
5755 std::ostringstream os;
5756 os << myRank <<
": writeDenseColumn" << endl;
5765 Teuchos::SetScientific<scalar_type> sci(out);
5767 const size_t myNumRows = X.getLocalLength();
5768 const size_t numCols = X.getNumVectors();
5771 const int sizeTag = 1337;
5772 const int dataTag = 1338;
5833 RCP<CommRequest<int>> sendReqSize, sendReqData;
5839 Array<ArrayRCP<size_t>> recvSizeBufs(3);
5840 Array<ArrayRCP<scalar_type>> recvDataBufs(3);
5841 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
5842 Array<RCP<CommRequest<int>>> recvDataReqs(3);
5845 ArrayRCP<size_t> sendDataSize(1);
5846 sendDataSize[0] = myNumRows;
5850 std::ostringstream os;
5851 os << myRank <<
": Post receive-size receives from "
5852 "Procs 1 and 2: tag = "
5857 recvSizeBufs[0].resize(1);
5861 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5862 recvSizeBufs[1].resize(1);
5863 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5864 recvSizeBufs[2].resize(1);
5865 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5868 ireceive<int, size_t>(recvSizeBufs[1], 1, sizeTag, comm);
5872 ireceive<int, size_t>(recvSizeBufs[2], 2, sizeTag, comm);
5874 }
else if (myRank == 1 || myRank == 2) {
5876 std::ostringstream os;
5877 os << myRank <<
": Post send-size send: size = "
5878 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
5885 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
5888 std::ostringstream os;
5889 os << myRank <<
": Not posting my send-size send yet" << endl;
5898 std::ostringstream os;
5899 os << myRank <<
": Pack my entries" << endl;
5902 ArrayRCP<scalar_type> sendDataBuf;
5904 sendDataBuf = arcp<scalar_type>(myNumRows * numCols);
5905 X.get1dCopy(sendDataBuf(), myNumRows);
5906 }
catch (std::exception& e) {
5908 if (!err.is_null()) {
5909 std::ostringstream os;
5910 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
5911 "entries threw an exception: "
5912 << e.what() << endl;
5917 std::ostringstream os;
5918 os << myRank <<
": Done packing my entries" << endl;
5927 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
5930 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
5938 std::ostringstream os;
5939 os << myRank <<
": Write my entries" << endl;
5945 const size_t printNumRows = myNumRows;
5946 ArrayView<const scalar_type> printData = sendDataBuf();
5947 const size_t printStride = printNumRows;
5948 if (
static_cast<size_t>(printData.size()) < printStride * numCols) {
5950 if (!err.is_null()) {
5951 std::ostringstream os;
5952 os <<
"Process " << myRank <<
": My MultiVector data's size "
5953 << printData.size() <<
" does not match my local dimensions "
5954 << printStride <<
" x " << numCols <<
"." << endl;
5961 for (
size_t col = 0; col < numCols; ++col) {
5962 for (
size_t row = 0; row < printNumRows; ++row) {
5963 if (STS::isComplex) {
5964 out << STS::real(printData[row + col * printStride]) <<
" "
5965 << STS::imag(printData[row + col * printStride]) << endl;
5967 out << printData[row + col * printStride] << endl;
5976 const int recvRank = 1;
5977 const int circBufInd = recvRank % 3;
5979 std::ostringstream os;
5980 os << myRank <<
": Wait on receive-size receive from Process "
5981 << recvRank << endl;
5985 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
5989 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
5990 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
5992 if (!err.is_null()) {
5993 std::ostringstream os;
5994 os << myRank <<
": Result of receive-size receive from Process "
5995 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
5996 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
5997 "This should never happen, and suggests that the receive never "
5998 "got posted. Please report this bug to the Tpetra developers."
6013 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
6015 std::ostringstream os;
6016 os << myRank <<
": Post receive-data receive from Process "
6017 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6018 << recvDataBufs[circBufInd].size() << endl;
6021 if (!recvSizeReqs[circBufInd].is_null()) {
6023 if (!err.is_null()) {
6024 std::ostringstream os;
6025 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6026 "null, before posting the receive-data receive from Process "
6027 << recvRank <<
". This should never happen. Please report "
6028 "this bug to the Tpetra developers."
6033 recvDataReqs[circBufInd] =
6034 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
6035 recvRank, dataTag, comm);
6037 }
else if (myRank == 1) {
6040 std::ostringstream os;
6041 os << myRank <<
": Wait on my send-size send" << endl;
6044 wait<int>(comm, outArg(sendReqSize));
6050 for (
int p = 1; p < numProcs; ++p) {
6052 if (p + 2 < numProcs) {
6054 const int recvRank = p + 2;
6055 const int circBufInd = recvRank % 3;
6057 std::ostringstream os;
6058 os << myRank <<
": Post receive-size receive from Process "
6059 << recvRank <<
": tag = " << sizeTag << endl;
6062 if (!recvSizeReqs[circBufInd].is_null()) {
6064 if (!err.is_null()) {
6065 std::ostringstream os;
6066 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6067 <<
"null, for the receive-size receive from Process "
6068 << recvRank <<
"! This may mean that this process never "
6069 <<
"finished waiting for the receive from Process "
6070 << (recvRank - 3) <<
"." << endl;
6074 recvSizeReqs[circBufInd] =
6075 ireceive<int, size_t>(recvSizeBufs[circBufInd],
6076 recvRank, sizeTag, comm);
6079 if (p + 1 < numProcs) {
6080 const int recvRank = p + 1;
6081 const int circBufInd = recvRank % 3;
6085 std::ostringstream os;
6086 os << myRank <<
": Wait on receive-size receive from Process "
6087 << recvRank << endl;
6090 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6094 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
6095 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
6097 if (!err.is_null()) {
6098 std::ostringstream os;
6099 os << myRank <<
": Result of receive-size receive from Process "
6100 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
6101 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
6102 "This should never happen, and suggests that the receive never "
6103 "got posted. Please report this bug to the Tpetra developers."
6117 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
6119 std::ostringstream os;
6120 os << myRank <<
": Post receive-data receive from Process "
6121 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6122 << recvDataBufs[circBufInd].size() << endl;
6125 if (!recvDataReqs[circBufInd].is_null()) {
6127 if (!err.is_null()) {
6128 std::ostringstream os;
6129 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
6130 <<
"null, for the receive-data receive from Process "
6131 << recvRank <<
"! This may mean that this process never "
6132 <<
"finished waiting for the receive from Process "
6133 << (recvRank - 3) <<
"." << endl;
6137 recvDataReqs[circBufInd] =
6138 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
6139 recvRank, dataTag, comm);
6143 const int recvRank = p;
6144 const int circBufInd = recvRank % 3;
6146 std::ostringstream os;
6147 os << myRank <<
": Wait on receive-data receive from Process "
6148 << recvRank << endl;
6151 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
6158 std::ostringstream os;
6159 os << myRank <<
": Write entries from Process " << recvRank
6161 *dbg << os.str() << endl;
6163 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
6164 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
6166 if (!err.is_null()) {
6167 std::ostringstream os;
6168 os << myRank <<
": Result of receive-size receive from Process "
6169 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
6171 << Teuchos::OrdinalTraits<size_t>::invalid()
6172 <<
". This should never happen, and suggests that its "
6173 "receive-size receive was never posted. "
6174 "Please report this bug to the Tpetra developers."
6182 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
6184 if (!err.is_null()) {
6185 std::ostringstream os;
6186 os << myRank <<
": Result of receive-size receive from Proc "
6187 << recvRank <<
" was " << printNumRows <<
" > 0, but "
6189 << circBufInd <<
"] is null. This should "
6190 "never happen. Please report this bug to the Tpetra "
6202 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd])();
6203 const size_t printStride = printNumRows;
6207 for (
size_t col = 0; col < numCols; ++col) {
6208 for (
size_t row = 0; row < printNumRows; ++row) {
6209 if (STS::isComplex) {
6210 out << STS::real(printData[row + col * printStride]) <<
" "
6211 << STS::imag(printData[row + col * printStride]) << endl;
6213 out << printData[row + col * printStride] << endl;
6217 }
else if (myRank == p) {
6220 std::ostringstream os;
6221 os << myRank <<
": Wait on my send-data send" << endl;
6224 wait<int>(comm, outArg(sendReqData));
6225 }
else if (myRank == p + 1) {
6228 std::ostringstream os;
6229 os << myRank <<
": Post send-data send: tag = " << dataTag
6233 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
6236 std::ostringstream os;
6237 os << myRank <<
": Wait on my send-size send" << endl;
6240 wait<int>(comm, outArg(sendReqSize));
6241 }
else if (myRank == p + 2) {
6244 std::ostringstream os;
6245 os << myRank <<
": Post send-size send: size = "
6246 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6249 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
6254 reduceAll<int, int>(comm, REDUCE_MAX, lclErr, outArg(gblErr));
6255 TEUCHOS_TEST_FOR_EXCEPTION(
6256 gblErr == 1, std::runtime_error,
6257 "Tpetra::MatrixMarket::writeDense "
6258 "experienced some kind of error and was unable to complete.");
6262 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
6267template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6270 const std::string& matrixName,
6271 const std::string& matrixDescription,
6272 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6273 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6274 TEUCHOS_TEST_FOR_EXCEPTION(
6275 X.is_null(), std::invalid_argument,
6276 "Tpetra::MatrixMarket::"
6277 "writeDense: The input MultiVector X is null.");
6278 writeDense(out, *X, matrixName, matrixDescription, err, dbg);
6281template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6284 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6285 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6286 writeDense(out, X,
"",
"", err, dbg);
6289template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6292 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6293 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6294 TEUCHOS_TEST_FOR_EXCEPTION(
6295 X.is_null(), std::invalid_argument,
6296 "Tpetra::MatrixMarket::"
6297 "writeDense: The input MultiVector X is null.");
6298 writeDense(out, *X,
"",
"", err, dbg);
6301template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6303 Teuchos::RCP<Teuchos::FancyOStream> err =
6304 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
6305 writeMap(out, map, err, debug);
6308template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6311 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6314 using Teuchos::Array;
6315 using Teuchos::ArrayRCP;
6316 using Teuchos::ArrayView;
6317 using Teuchos::Comm;
6318 using Teuchos::CommRequest;
6319 using Teuchos::ireceive;
6320 using Teuchos::isend;
6322 using Teuchos::TypeNameTraits;
6323 using Teuchos::wait;
6325 typedef int pid_type;
6340 typedef ptrdiff_t int_type;
6341 TEUCHOS_TEST_FOR_EXCEPTION(
6342 sizeof(GO) >
sizeof(int_type), std::logic_error,
6343 "The global ordinal type GO=" << TypeNameTraits<GO>::name()
6344 <<
" is too big for ptrdiff_t. sizeof(GO) = " <<
sizeof(GO)
6345 <<
" > sizeof(ptrdiff_t) = " <<
sizeof(ptrdiff_t) <<
".");
6346 TEUCHOS_TEST_FOR_EXCEPTION(
6347 sizeof(pid_type) >
sizeof(int_type), std::logic_error,
6348 "The (MPI) process rank type pid_type=" << TypeNameTraits<pid_type>::name() <<
" is too big for ptrdiff_t. "
6349 "sizeof(pid_type) = "
6350 <<
sizeof(pid_type) <<
" > sizeof(ptrdiff_t)"
6352 <<
sizeof(ptrdiff_t) <<
".");
6354 const Comm<int>& comm = *(map.getComm());
6355 const int myRank = comm.getRank();
6356 const int numProcs = comm.getSize();
6358 if (!err.is_null()) {
6362 std::ostringstream os;
6363 os << myRank <<
": writeMap" << endl;
6366 if (!err.is_null()) {
6370 const size_t myNumRows = map.getLocalNumElements();
6373 const int sizeTag = 1337;
6374 const int dataTag = 1338;
6433 RCP<CommRequest<int>> sendReqSize, sendReqData;
6439 Array<ArrayRCP<int_type>> recvSizeBufs(3);
6440 Array<ArrayRCP<int_type>> recvDataBufs(3);
6441 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
6442 Array<RCP<CommRequest<int>>> recvDataReqs(3);
6445 ArrayRCP<int_type> sendDataSize(1);
6446 sendDataSize[0] = myNumRows;
6450 std::ostringstream os;
6451 os << myRank <<
": Post receive-size receives from "
6452 "Procs 1 and 2: tag = "
6457 recvSizeBufs[0].resize(1);
6458 (recvSizeBufs[0])[0] = -1;
6459 recvSizeBufs[1].resize(1);
6460 (recvSizeBufs[1])[0] = -1;
6461 recvSizeBufs[2].resize(1);
6462 (recvSizeBufs[2])[0] = -1;
6465 ireceive<int, int_type>(recvSizeBufs[1], 1, sizeTag, comm);
6469 ireceive<int, int_type>(recvSizeBufs[2], 2, sizeTag, comm);
6471 }
else if (myRank == 1 || myRank == 2) {
6473 std::ostringstream os;
6474 os << myRank <<
": Post send-size send: size = "
6475 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6482 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
6485 std::ostringstream os;
6486 os << myRank <<
": Not posting my send-size send yet" << endl;
6497 std::ostringstream os;
6498 os << myRank <<
": Pack my GIDs and PIDs" << endl;
6502 ArrayRCP<int_type> sendDataBuf(myNumRows * 2);
6504 if (map.isContiguous()) {
6505 const int_type myMinGblIdx =
6506 static_cast<int_type
>(map.getMinGlobalIndex());
6507 for (
size_t k = 0; k < myNumRows; ++k) {
6508 const int_type gid = myMinGblIdx +
static_cast<int_type
>(k);
6509 const int_type pid =
static_cast<int_type
>(myRank);
6510 sendDataBuf[2 * k] = gid;
6511 sendDataBuf[2 * k + 1] = pid;
6514 ArrayView<const GO> myGblInds = map.getLocalElementList();
6515 for (
size_t k = 0; k < myNumRows; ++k) {
6516 const int_type gid =
static_cast<int_type
>(myGblInds[k]);
6517 const int_type pid =
static_cast<int_type
>(myRank);
6518 sendDataBuf[2 * k] = gid;
6519 sendDataBuf[2 * k + 1] = pid;
6524 std::ostringstream os;
6525 os << myRank <<
": Done packing my GIDs and PIDs" << endl;
6532 *err << myRank <<
": Post send-data send: tag = " << dataTag
6535 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
6540 *err << myRank <<
": Write MatrixMarket header" << endl;
6545 std::ostringstream hdr;
6549 hdr <<
"%%MatrixMarket matrix array integer general" << endl
6550 <<
"% Format: Version 2.0" << endl
6552 <<
"% This file encodes a Tpetra::Map." << endl
6553 <<
"% It is stored as a dense vector, with twice as many " << endl
6554 <<
"% entries as the global number of GIDs (global indices)." << endl
6555 <<
"% (GID, PID) pairs are stored contiguously, where the PID " << endl
6556 <<
"% is the rank of the process owning that GID." << endl
6557 << (2 * map.getGlobalNumElements()) <<
" " << 1 << endl;
6561 std::ostringstream os;
6562 os << myRank <<
": Write my GIDs and PIDs" << endl;
6568 const int_type printNumRows = myNumRows;
6569 ArrayView<const int_type> printData = sendDataBuf();
6570 for (int_type k = 0; k < printNumRows; ++k) {
6571 const int_type gid = printData[2 * k];
6572 const int_type pid = printData[2 * k + 1];
6580 const int recvRank = 1;
6581 const int circBufInd = recvRank % 3;
6583 std::ostringstream os;
6584 os << myRank <<
": Wait on receive-size receive from Process "
6585 << recvRank << endl;
6589 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6593 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
6594 if (debug && recvNumRows == -1) {
6595 std::ostringstream os;
6596 os << myRank <<
": Result of receive-size receive from Process "
6597 << recvRank <<
" is -1. This should never happen, and "
6598 "suggests that the receive never got posted. Please report "
6599 "this bug to the Tpetra developers."
6605 recvDataBufs[circBufInd].resize(recvNumRows * 2);
6607 std::ostringstream os;
6608 os << myRank <<
": Post receive-data receive from Process "
6609 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6610 << recvDataBufs[circBufInd].size() << endl;
6613 if (!recvSizeReqs[circBufInd].is_null()) {
6614 std::ostringstream os;
6615 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6616 "null, before posting the receive-data receive from Process "
6617 << recvRank <<
". This should never happen. Please report "
6618 "this bug to the Tpetra developers."
6622 recvDataReqs[circBufInd] =
6623 ireceive<int, int_type>(recvDataBufs[circBufInd],
6624 recvRank, dataTag, comm);
6626 }
else if (myRank == 1) {
6629 std::ostringstream os;
6630 os << myRank <<
": Wait on my send-size send" << endl;
6633 wait<int>(comm, outArg(sendReqSize));
6639 for (
int p = 1; p < numProcs; ++p) {
6641 if (p + 2 < numProcs) {
6643 const int recvRank = p + 2;
6644 const int circBufInd = recvRank % 3;
6646 std::ostringstream os;
6647 os << myRank <<
": Post receive-size receive from Process "
6648 << recvRank <<
": tag = " << sizeTag << endl;
6651 if (!recvSizeReqs[circBufInd].is_null()) {
6652 std::ostringstream os;
6653 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6654 <<
"null, for the receive-size receive from Process "
6655 << recvRank <<
"! This may mean that this process never "
6656 <<
"finished waiting for the receive from Process "
6657 << (recvRank - 3) <<
"." << endl;
6660 recvSizeReqs[circBufInd] =
6661 ireceive<int, int_type>(recvSizeBufs[circBufInd],
6662 recvRank, sizeTag, comm);
6665 if (p + 1 < numProcs) {
6666 const int recvRank = p + 1;
6667 const int circBufInd = recvRank % 3;
6671 std::ostringstream os;
6672 os << myRank <<
": Wait on receive-size receive from Process "
6673 << recvRank << endl;
6676 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6680 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
6681 if (debug && recvNumRows == -1) {
6682 std::ostringstream os;
6683 os << myRank <<
": Result of receive-size receive from Process "
6684 << recvRank <<
" is -1. This should never happen, and "
6685 "suggests that the receive never got posted. Please report "
6686 "this bug to the Tpetra developers."
6692 recvDataBufs[circBufInd].resize(recvNumRows * 2);
6694 std::ostringstream os;
6695 os << myRank <<
": Post receive-data receive from Process "
6696 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6697 << recvDataBufs[circBufInd].size() << endl;
6700 if (!recvDataReqs[circBufInd].is_null()) {
6701 std::ostringstream os;
6702 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
6703 <<
"null, for the receive-data receive from Process "
6704 << recvRank <<
"! This may mean that this process never "
6705 <<
"finished waiting for the receive from Process "
6706 << (recvRank - 3) <<
"." << endl;
6709 recvDataReqs[circBufInd] =
6710 ireceive<int, int_type>(recvDataBufs[circBufInd],
6711 recvRank, dataTag, comm);
6715 const int recvRank = p;
6716 const int circBufInd = recvRank % 3;
6718 std::ostringstream os;
6719 os << myRank <<
": Wait on receive-data receive from Process "
6720 << recvRank << endl;
6723 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
6730 std::ostringstream os;
6731 os << myRank <<
": Write GIDs and PIDs from Process "
6732 << recvRank << endl;
6733 *err << os.str() << endl;
6735 const int_type printNumRows = (recvSizeBufs[circBufInd])[0];
6736 if (debug && printNumRows == -1) {
6737 std::ostringstream os;
6738 os << myRank <<
": Result of receive-size receive from Process "
6739 << recvRank <<
" was -1. This should never happen, and "
6740 "suggests that its receive-size receive was never posted. "
6741 "Please report this bug to the Tpetra developers."
6745 if (debug && printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
6746 std::ostringstream os;
6747 os << myRank <<
": Result of receive-size receive from Proc "
6748 << recvRank <<
" was " << printNumRows <<
" > 0, but "
6750 << circBufInd <<
"] is null. This should "
6751 "never happen. Please report this bug to the Tpetra "
6756 ArrayView<const int_type> printData = (recvDataBufs[circBufInd])();
6757 for (int_type k = 0; k < printNumRows; ++k) {
6758 const int_type gid = printData[2 * k];
6759 const int_type pid = printData[2 * k + 1];
6763 }
else if (myRank == p) {
6766 std::ostringstream os;
6767 os << myRank <<
": Wait on my send-data send" << endl;
6770 wait<int>(comm, outArg(sendReqData));
6771 }
else if (myRank == p + 1) {
6774 std::ostringstream os;
6775 os << myRank <<
": Post send-data send: tag = " << dataTag
6779 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
6782 std::ostringstream os;
6783 os << myRank <<
": Wait on my send-size send" << endl;
6786 wait<int>(comm, outArg(sendReqSize));
6787 }
else if (myRank == p + 2) {
6790 std::ostringstream os;
6791 os << myRank <<
": Post send-size send: size = "
6792 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6795 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
6799 if (!err.is_null()) {
6803 *err << myRank <<
": writeMap: Done" << endl;
6805 if (!err.is_null()) {
6810template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6813 const int myRank = map.
getComm()->getRank();
6815 auto out = MatrixMarketWriter::openOutFileOnRankZero(map.
getComm(), filename, myRank,
true);
6823template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6824void MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::printAsComment(std::ostream& out,
const std::string& str) {
6826 std::istringstream inpstream(str);
6829 while (getline(inpstream, line)) {
6830 if (!line.empty()) {
6833 if (line[0] ==
'%') {
6834 out << line << endl;
6836 out <<
"%% " << line << endl;
6842template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6844 Teuchos::ParameterList pl;
6845 writeOperator(fileName, A, pl);
6848template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6850 Teuchos::ParameterList pl;
6851 writeOperator(out, A, pl);
6854template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6856 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6857 const Teuchos::ParameterList& params) {
6859 std::string tmpFile =
"__TMP__" + fileName;
6860 const int myRank = A.getDomainMap()->getComm()->getRank();
6861 bool precisionChanged =
false;
6862 int oldPrecision = 0;
6871 if (std::ifstream(tmpFile))
6872 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
6873 "writeOperator: temporary file " << tmpFile <<
" already exists");
6874 out.open(tmpFile.c_str());
6875 if (params.isParameter(
"precision")) {
6876 oldPrecision = out.precision(params.get<
int>(
"precision"));
6877 precisionChanged =
true;
6881 const std::string header = writeOperatorImpl(out, A, params);
6884 if (precisionChanged)
6885 out.precision(oldPrecision);
6887 out.open(fileName.c_str(), std::ios::binary);
6888 bool printMatrixMarketHeader =
true;
6889 if (params.isParameter(
"print MatrixMarket header"))
6890 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
6891 if (printMatrixMarketHeader && myRank == 0) {
6896 std::ifstream src(tmpFile, std::ios_base::binary);
6900 remove(tmpFile.c_str());
6904template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6906 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6907 const Teuchos::ParameterList& params) {
6908 const int myRank = A.getDomainMap()->getComm()->getRank();
6925 std::ostringstream tmpOut;
6927 if (params.isParameter(
"precision") && params.isType<
int>(
"precision")) {
6928 (void)tmpOut.precision(params.get<
int>(
"precision"));
6932 const std::string header = writeOperatorImpl(tmpOut, A, params);
6935 bool printMatrixMarketHeader =
true;
6936 if (params.isParameter(
"print MatrixMarket header") &&
6937 params.isType<
bool>(
"print MatrixMarket header")) {
6938 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
6940 if (printMatrixMarketHeader && myRank == 0) {
6956 out << tmpOut.str();
6960template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6962MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeOperatorImpl(std::ostream& os,
6963 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6964 const Teuchos::ParameterList& params) {
6965 using Teuchos::Array;
6966 using Teuchos::ArrayRCP;
6972 typedef Teuchos::OrdinalTraits<LO> TLOT;
6973 typedef Teuchos::OrdinalTraits<GO> TGOT;
6974 typedef Tpetra::Import<LO, GO, node_type>
import_type;
6975 typedef Tpetra::MultiVector<GO, LO, GO, node_type> mv_type_go;
6977 const map_type& domainMap = *(A.getDomainMap());
6979 trcp_tcomm_t comm = rangeMap->getComm();
6980 const int myRank = comm->getRank();
6981 const size_t numProcs = comm->getSize();
6984 if (params.isParameter(
"probing size"))
6985 numMVs = params.get<
int>(
"probing size");
6988 GO minColGid = domainMap.getMinAllGlobalIndex();
6989 GO maxColGid = domainMap.getMaxAllGlobalIndex();
6994 GO numGlobElts = maxColGid - minColGid + TGOT::one();
6995 GO numChunks = numGlobElts / numMVs;
6996 GO rem = numGlobElts % numMVs;
6997 GO indexBase = rangeMap->getIndexBase();
6999 int offsetToUseInPrinting = 1 - indexBase;
7000 if (params.isParameter(
"zero-based indexing")) {
7001 if (params.get<
bool>(
"zero-based indexing") ==
true)
7002 offsetToUseInPrinting = -indexBase;
7006 size_t numLocalRangeEntries = rangeMap->getLocalNumElements();
7009 RCP<const map_type> allGidsMap = rcp(
new map_type(TGOT::invalid(), numLocalRangeEntries,
7012 mv_type_go allGids(allGidsMap, 1);
7013 Teuchos::ArrayRCP<GO> allGidsData = allGids.getDataNonConst(0);
7015 for (
size_t i = 0; i < numLocalRangeEntries; i++)
7016 allGidsData[i] = rangeMap->getGlobalElement(i);
7017 allGidsData = Teuchos::null;
7020 GO numTargetMapEntries = TGOT::zero();
7021 Teuchos::Array<GO> importGidList;
7023 numTargetMapEntries = rangeMap->getGlobalNumElements();
7024 importGidList.reserve(numTargetMapEntries);
7025 for (GO j = 0; j < numTargetMapEntries; ++j) importGidList.push_back(j + indexBase);
7027 importGidList.reserve(numTargetMapEntries);
7029 RCP<map_type> importGidMap = rcp(
new map_type(TGOT::invalid(), importGidList(), indexBase, comm));
7032 import_type gidImporter(allGidsMap, importGidMap);
7033 mv_type_go importedGids(importGidMap, 1);
7034 importedGids.doImport(allGids, gidImporter,
INSERT);
7037 ArrayRCP<const GO> importedGidsData = importedGids.getData(0);
7038 RCP<const map_type> importMap = rcp(
new map_type(TGOT::invalid(), importedGidsData(), indexBase, comm));
7043 RCP<mv_type> colsOnPid0 = rcp(
new mv_type(importMap, numMVs));
7045 RCP<mv_type> ei = rcp(
new mv_type(A.getDomainMap(), numMVs));
7046 RCP<mv_type> colsA = rcp(
new mv_type(A.getRangeMap(), numMVs));
7048 Array<GO> globalColsArray, localColsArray;
7049 globalColsArray.reserve(numMVs);
7050 localColsArray.reserve(numMVs);
7052 ArrayRCP<ArrayRCP<Scalar>> eiData(numMVs);
7053 for (
size_t i = 0; i < numMVs; ++i)
7054 eiData[i] = ei->getDataNonConst(i);
7059 for (GO k = 0; k < numChunks; ++k) {
7060 for (
size_t j = 0; j < numMVs; ++j) {
7062 GO curGlobalCol = minColGid + k * numMVs + j;
7063 globalColsArray.push_back(curGlobalCol);
7065 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
7066 if (curLocalCol != TLOT::invalid()) {
7067 eiData[j][curLocalCol] = TGOT::one();
7068 localColsArray.push_back(curLocalCol);
7073 for (
size_t i = 0; i < numMVs; ++i)
7074 eiData[i] = Teuchos::null;
7076 A.apply(*ei, *colsA);
7078 colsOnPid0->doImport(*colsA, importer,
INSERT);
7081 globalNnz += writeColumns(os, *colsOnPid0, numMVs, importedGidsData(),
7082 globalColsArray, offsetToUseInPrinting);
7085 for (
size_t i = 0; i < numMVs; ++i)
7086 eiData[i] = ei->getDataNonConst(i);
7087 for (
size_t j = 0; j < numMVs; ++j) {
7088 GO curGlobalCol = minColGid + k * numMVs + j;
7090 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
7091 if (curLocalCol != TLOT::invalid()) {
7092 eiData[j][curLocalCol] = TGOT::one();
7097 for (
size_t j = 0; j < numMVs; ++j) {
7098 for (
int i = 0; i < localColsArray.size(); ++i)
7099 eiData[j][localColsArray[i]] = TGOT::zero();
7101 globalColsArray.clear();
7102 localColsArray.clear();
7109 for (
int j = 0; j < rem; ++j) {
7110 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
7111 globalColsArray.push_back(curGlobalCol);
7113 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
7114 if (curLocalCol != TLOT::invalid()) {
7115 eiData[j][curLocalCol] = TGOT::one();
7116 localColsArray.push_back(curLocalCol);
7121 for (
size_t i = 0; i < numMVs; ++i)
7122 eiData[i] = Teuchos::null;
7124 A.apply(*ei, *colsA);
7126 colsOnPid0->doImport(*colsA, importer,
INSERT);
7128 globalNnz += writeColumns(os, *colsOnPid0, rem, importedGidsData(),
7129 globalColsArray, offsetToUseInPrinting);
7132 for (
size_t i = 0; i < numMVs; ++i)
7133 eiData[i] = ei->getDataNonConst(i);
7134 for (
int j = 0; j < rem; ++j) {
7135 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
7137 LO curLocalCol = domainMap.getLocalElement(curGlobalCol);
7138 if (curLocalCol != TLOT::invalid()) {
7139 eiData[j][curLocalCol] = TGOT::one();
7144 for (
int j = 0; j < rem; ++j) {
7145 for (
int i = 0; i < localColsArray.size(); ++i)
7146 eiData[j][localColsArray[i]] = TGOT::zero();
7148 globalColsArray.clear();
7149 localColsArray.clear();
7157 std::ostringstream oss;
7159 oss <<
"%%MatrixMarket matrix coordinate ";
7160 if (Teuchos::ScalarTraits<typename operator_type::scalar_type>::isComplex) {
7165 oss <<
" general" << std::endl;
7166 oss <<
"% Tpetra::Operator" << std::endl;
7167 std::time_t now = std::time(NULL);
7168 oss <<
"% time stamp: " << ctime(&now);
7169 oss <<
"% written from " << numProcs <<
" processes" << std::endl;
7170 size_t numRows = rangeMap->getGlobalNumElements();
7171 size_t numCols = domainMap.getGlobalNumElements();
7172 oss << numRows <<
" " << numCols <<
" " << globalNnz << std::endl;
7178template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7180MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeColumns(std::ostream& os, mv_type
const& colsA,
size_t const& numCols,
7182 Teuchos::Array<global_ordinal_type>
const& colsArray,
7185 typedef Teuchos::ScalarTraits<Scalar> STS;
7188 const Scalar zero = STS::zero();
7189 const size_t numRows = colsA.getGlobalLength();
7190 for (
size_t j = 0; j < numCols; ++j) {
7191 Teuchos::ArrayRCP<const Scalar>
const curCol = colsA.getData(j);
7192 const GO J = colsArray[j];
7193 for (
size_t i = 0; i < numRows; ++i) {
7194 const Scalar val = curCol[i];
7196 os << rowGids[i] + indexBase <<
" " << J + indexBase <<
" " << val << std::endl;
7205template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7207 const std::string& filename_suffix,
7208 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type& matrix,
7209 const std::string& matrixName,
7210 const std::string& matrixDescription,
7211 const int ranksToWriteAtOnce,
7216 using STS =
typename Teuchos::ScalarTraits<ST>;
7221 TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), std::invalid_argument,
7222 "The input matrix's communicator (Teuchos::Comm object) is null.");
7224 "The input matrix must not be GloballyIndexed and must be fillComplete.");
7227 const int myRank = comm->getRank();
7228 const int numProc = comm->getSize();
7229 std::string filename = filename_prefix + std::to_string(myRank) + filename_suffix;
7230 RCP<const map_type> rowMap = matrix.
getRowMap();
7231 RCP<const map_type> colMap = matrix.
getColMap();
7233 size_t local_num_rows = rowMap->getLocalNumElements();
7234 size_t local_num_cols = colMap->getLocalNumElements();
7235 const GO rowIndexBase = rowMap->getIndexBase();
7236 const GO colIndexBase = colMap->getIndexBase();
7239 int rank_limit = std::min(std::max(ranksToWriteAtOnce, 1), numProc);
7242 for (
int base_rank = 0; base_rank < numProc; base_rank += rank_limit) {
7243 int stop = std::min(base_rank + rank_limit, numProc);
7245 if (base_rank <= myRank && myRank < stop) {
7247 std::ofstream out(filename);
7250 out <<
"%%MatrixMarket matrix coordinate "
7251 << (STS::isComplex ?
"complex" :
"real")
7252 <<
" general" << std::endl;
7255 if (matrixName !=
"") {
7256 printAsComment(out, matrixName);
7258 if (matrixDescription !=
"") {
7259 printAsComment(out, matrixDescription);
7265 out << local_num_rows <<
" " << local_num_cols <<
" " << local_nnz << std::endl;
7272 Teuchos::SetScientific<ST> sci(out);
7274 for (
size_t l_row = 0; l_row < local_num_rows; l_row++) {
7275 GO g_row = rowMap->getGlobalElement(l_row);
7277 typename sparse_matrix_type::local_inds_host_view_type indices;
7278 typename sparse_matrix_type::values_host_view_type values;
7280 for (
size_t ii = 0; ii < indices.extent(0); ii++) {
7281 const GO g_col = colMap->getGlobalElement(indices(ii));
7284 out << (g_row + 1 - rowIndexBase) <<
" "
7285 << (g_col + 1 - colIndexBase) <<
" ";
7286 if (STS::isComplex) {
7287 out << STS::real(values(ii)) <<
" " << STS::imag(values(ii));
7307template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7308template <
typename T>
7310 return obj.is_null() ? Teuchos::null : obj->getComm();
7313template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7315 return comm.is_null() ? 0 : comm->getRank();
7321#define TPETRA_MATRIXMARKET_INSTANT(SCALAR, LO, GO, NODE) \
7322 template class MatrixMarketReader<SCALAR, LO, GO, NODE>; \
7323 template class MatrixMarketWriter<SCALAR, LO, GO, NODE>;
From a distributed map build a map with all GIDs on the root node.
Declaration of a function that prints strings from each process.
Teuchos::RCP< const map_type > getColMap() const override
Returns the Map that describes the column distribution in this graph.
global_size_t getGlobalNumEntries() const override
Returns the global number of entries in the graph.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
Returns the communicator.
void fillComplete(const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const Teuchos::RCP< Teuchos::ParameterList > ¶ms=Teuchos::null)
Tell the graph that you are done changing its structure.
Teuchos::RCP< const map_type > getDomainMap() const override
Returns the Map associated with the domain of this graph.
void getGlobalRowView(const global_ordinal_type gblRow, global_inds_host_view_type &gblColInds) const override
Get a const view of the given global row's global column indices.
Teuchos::RCP< const map_type > getRangeMap() const override
Returns the Map associated with the domain of this graph.
Teuchos::RCP< const map_type > getRowMap() const override
Returns the Map that describes the row distribution in this graph.
void getLocalRowView(const LocalOrdinal lclRow, local_inds_host_view_type &lclColInds) const override
Get a const view of the given local row's local column indices.
bool isGloballyIndexed() const override
Whether the graph's column indices are stored as global indices.
bool isGloballyIndexed() const override
Whether the matrix is globally indexed on the calling process.
Teuchos::RCP< const map_type > getDomainMap() const override
The domain Map of this matrix.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const override
The communicator over which the matrix is distributed.
Teuchos::RCP< const map_type > getRangeMap() const override
The range Map of this matrix.
size_t getLocalNumEntries() const override
The local number of entries in this matrix.
GlobalOrdinal getIndexBase() const override
The index base for global indices for this matrix.
void getLocalRowView(LocalOrdinal LocalRow, local_inds_host_view_type &indices, values_host_view_type &values) const override
Get a constant view of a row of this matrix, using local row and column indices.
Teuchos::RCP< const map_type > getColMap() const override
The Map that describes the column distribution in this matrix.
bool isFillComplete() const override
Whether the matrix is fill complete.
Teuchos::RCP< const map_type > getRowMap() const override
The Map that describes the row distribution in this matrix.
void doImport(const SrcDistObject &source, const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, const CombineMode CM, const bool restrictedMode=false)
virtual Teuchos::RCP< const map_type > getMap() const
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
SparseMatrixType::local_ordinal_type local_ordinal_type
static Teuchos::RCP< sparse_matrix_type > readSparsePerRank(const std::string &filename_prefix, const std::string &filename_suffix, const Teuchos::RCP< const map_type > &rowMap, Teuchos::RCP< const map_type > &colMap, const Teuchos::RCP< const map_type > &domainMap, const Teuchos::RCP< const map_type > &rangeMap, const bool callFillComplete=true, const bool tolerant=false, const int ranksToReadAtOnce=8, const bool debug=false)
Read a Tpetra::CrsMatrix from a file per rank setup.
SparseMatrixType::scalar_type scalar_type
static Teuchos::RCP< multivector_type > readDense(std::istream &in, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read dense matrix (as a MultiVector) from the given Matrix Market input stream.
static Teuchos::RCP< multivector_type > readDenseFile(const std::string &filename, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read dense matrix (as a MultiVector) from the given Matrix Market file.
static std::ifstream openInFileOnRankZero(const trcp_tcomm_t &comm, const std::string &filename, const bool safe=true, std::ios_base::openmode mode=std::ios_base::in)
Open an input file stream safely on rank zero.
static Teuchos::RCP< sparse_graph_type > readSparseGraphFile(const std::string &filename, const trcp_tcomm_t &comm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market file.
static Teuchos::RCP< sparse_matrix_type > readSparse(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int > > &pComm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market input stream.
static Teuchos::RCP< const map_type > readMapFile(const std::string &filename, const trcp_tcomm_t &comm, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read Map (as a MultiVector) from the given Matrix Market file.
static Teuchos::RCP< vector_type > readVector(std::istream &in, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read Vector from the given Matrix Market input stream.
Teuchos::RCP< const Teuchos::Comm< int > > trcp_tcomm_t
Type of the MPI communicator.
static Teuchos::RCP< sparse_graph_type > readSparseGraph(std::istream &in, const Teuchos::RCP< const Teuchos::Comm< int > > &pComm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse graph from the given Matrix Market input stream.
static Teuchos::RCP< const map_type > readMap(std::istream &in, const trcp_tcomm_t &comm, const bool tolerant=false, const bool debug=false, const bool binary=false)
Read Map (as a MultiVector) from the given input stream.
SparseMatrixType::node_type node_type
The fourth template parameter of CrsMatrix and MultiVector.
static Teuchos::RCP< vector_type > readVectorFile(const std::string &filename, const trcp_tcomm_t &comm, Teuchos::RCP< const map_type > &map, const bool tolerant=false, const bool debug=false)
Read a Vector from the given Matrix Market file.
SparseMatrixType::global_ordinal_type global_ordinal_type
static trcp_tcomm_t getComm(const Teuchos::RCP< T > &obj)
Return obj MPI communicator or Teuchos::null.
static void writeSparsePerRank(const std::string &filename_prefix, const std::string &filename_suffix, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const int ranksToWriteAtOnce=8, const bool debug=false)
Write a Tpetra::CrsMatrix to a file per rank.
static void writeSparseGraph(std::ostream &out, const crs_graph_type &graph, const std::string &graphName, const std::string &graphDescription, const bool debug=false)
Print the sparse graph in Matrix Market format to the given output stream.
static void writeOperator(const std::string &fileName, operator_type const &A)
Write a Tpetra::Operator to a file.
Map< local_ordinal_type, global_ordinal_type, node_type > map_type
Specialization of Tpetra::Map that matches SparseMatrixType.
static void writeSparseGraphFile(const std::string &filename, const crs_graph_type &graph, const std::string &graphName, const std::string &graphDescription, const bool debug=false)
Print the sparse graph in Matrix Market format to the given file (by filename).
MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > multivector_type
Specialization of Tpetra::MultiVector that matches SparseMatrixType.
static void writeSparseFile(const std::string &filename, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Print the sparse matrix in Matrix Market format, with comments.
static int getRank(const trcp_tcomm_t &comm)
Return MPI rank or 0.
static void writeMap(std::ostream &out, const map_type &map, const bool debug=false)
Print the Map to the given output stream.
SparseMatrixType::global_ordinal_type global_ordinal_type
Type of indices as read from the Matrix Market file.
static void writeDense(std::ostream &out, const multivector_type &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
Teuchos::RCP< const Teuchos::Comm< int > > trcp_tcomm_t
Type of the MPI communicator.
static void writeMapFile(const std::string &filename, const map_type &map)
Write the Map to the given file.
SparseMatrixType::local_ordinal_type local_ordinal_type
Type of the local indices of the sparse matrix.
static void writeDenseFile(const std::string &filename, const multivector_type &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
CrsGraph< local_ordinal_type, global_ordinal_type, node_type > crs_graph_type
Specialization of Tpetra::CrsGraph that matches SparseMatrixType.
SparseMatrixType::scalar_type scalar_type
Type of the entries of the sparse matrix.
static void writeSparse(std::ostream &out, const sparse_matrix_type &matrix, const std::string &matrixName, const std::string &matrixDescription, const bool debug=false)
Print the sparse matrix in Matrix Market format, with comments.
One or more distributed dense vectors.
Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(const size_t j) const
Return a Vector which is a const view of column j.
size_t getNumVectors() const
Number of columns in the multivector.
void start()
Start the deep_copy counter.
void gathervPrint(std::ostream &out, const std::string &s, const Teuchos::Comm< int > &comm)
On Process 0 in the given communicator, print strings from each process in that communicator,...
Namespace Tpetra contains the class and methods constituting the Tpetra library.
Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > createMultiVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, const size_t numVectors)
Nonmember MultiVector "constructor": Create a MultiVector from a given Map.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createUniformContigMapWithNode(const global_size_t numElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Non-member constructor for a uniformly distributed, contiguous Map with a user-specified Kokkos Node.
Teuchos::RCP< Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > createVector(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map)
Nonmember Vector "constructor": Create a Vector from a given Map.
size_t global_size_t
Global size_t object.
@ INSERT
Insert new values that don't currently exist.
Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > createContigMapWithNode(const global_size_t numElements, const size_t localNumElements, const Teuchos::RCP< const Teuchos::Comm< int > > &comm)
Nonmember constructor for a (potentially) nonuniformly distributed, contiguous Map for a user-specifi...