10#ifndef MATRIXMARKET_TPETRA_DEF_HPP
11#define MATRIXMARKET_TPETRA_DEF_HPP
13#include "MatrixMarket_Tpetra_decl.hpp"
15#include "Tpetra_CrsMatrix.hpp"
16#include "Tpetra_Operator.hpp"
17#include "Tpetra_Vector.hpp"
19#include "Teuchos_MatrixMarket_Raw_Adder.hpp"
20#include "Teuchos_MatrixMarket_Raw_Graph_Adder.hpp"
21#include "Teuchos_MatrixMarket_SymmetrizingAdder.hpp"
22#include "Teuchos_MatrixMarket_SymmetrizingGraphAdder.hpp"
23#include "Teuchos_MatrixMarket_assignScalar.hpp"
24#include "Teuchos_MatrixMarket_Banner.hpp"
25#include "Teuchos_MatrixMarket_CoordDataReader.hpp"
26#include "Teuchos_SetScientific.hpp"
27#include "Teuchos_TimeMonitor.hpp"
30#include "mmio_Tpetra.h"
32#include "Tpetra_Distribution.hpp"
44template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
45Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
46MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeRangeMap(
const trcp_tcomm_t& pComm,
47 const global_ordinal_type numRows) {
50 static_cast<global_ordinal_type
>(0),
51 pComm, GloballyDistributed));
54template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
55Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
56MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeRowMap(
const Teuchos::RCP<const map_type>& pRowMap,
57 const trcp_tcomm_t& pComm,
58 const global_ordinal_type numRows) {
61 if (pRowMap.is_null()) {
63 static_cast<global_ordinal_type
>(0),
64 pComm, GloballyDistributed));
66 TEUCHOS_TEST_FOR_EXCEPTION(!pRowMap->isDistributed() && pComm->getSize() > 1,
67 std::invalid_argument,
68 "The specified row map is not distributed, "
69 "but the given communicator includes more than one process (in "
71 << pComm->getSize() <<
" processes).");
72 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap->getComm() != pComm, std::invalid_argument,
73 "The specified row Map's communicator (pRowMap->getComm()) "
74 "differs from the given separately supplied communicator pComm.");
79template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
81MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeDomainMap(
const Teuchos::RCP<const map_type>& pRangeMap,
82 const global_ordinal_type numRows,
83 const global_ordinal_type numCols) {
86 typedef global_ordinal_type GO;
89 if (numRows == numCols) {
92 return createUniformContigMapWithNode<LO, GO, NT>(numCols,
93 pRangeMap->getComm());
97template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98void MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::distribute(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
99 Teuchos::ArrayRCP<size_t>& myRowPtr,
100 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
101 Teuchos::ArrayRCP<scalar_type>& myValues,
102 const Teuchos::RCP<const map_type>& pRowMap,
103 Teuchos::ArrayRCP<size_t>& numEntriesPerRow,
104 Teuchos::ArrayRCP<size_t>& rowPtr,
105 Teuchos::ArrayRCP<global_ordinal_type>& colInd,
106 Teuchos::ArrayRCP<scalar_type>& values,
111 using Teuchos::ArrayRCP;
112 using Teuchos::ArrayView;
115 using Teuchos::CommRequest;
118 using Teuchos::receive;
121 const bool extraDebug =
false;
122 trcp_tcomm_t pComm = pRowMap->getComm();
123 const int numProcs = pComm->getSize();
124 const int myRank = pComm->getRank();
125 const int rootRank = 0;
128 typedef global_ordinal_type GO;
132 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
133 const size_type myNumRows = myRows.size();
134 TEUCHOS_TEST_FOR_EXCEPTION(
static_cast<size_t>(myNumRows) !=
135 pRowMap->getLocalNumElements(),
137 "pRowMap->getLocalElementList().size() = "
139 <<
" != pRowMap->getLocalNumElements() = "
140 << pRowMap->getLocalNumElements() <<
". "
141 "Please report this bug to the Tpetra developers.");
142 TEUCHOS_TEST_FOR_EXCEPTION(myRank == 0 && numEntriesPerRow.size() < myNumRows,
144 "On Proc 0: numEntriesPerRow.size() = "
145 << numEntriesPerRow.size()
146 <<
" != pRowMap->getLocalElementList().size() = "
147 << myNumRows <<
". Please report this bug to the "
148 "Tpetra developers.");
152 myNumEntriesPerRow = arcp<size_t>(myNumRows);
154 if (myRank != rootRank) {
158 send(*pComm, myNumRows, rootRank);
159 if (myNumRows != 0) {
163 send(*pComm,
static_cast<int>(myNumRows),
164 myRows.getRawPtr(), rootRank);
174 receive(*pComm, rootRank,
175 static_cast<int>(myNumRows),
176 myNumEntriesPerRow.getRawPtr());
181 std::accumulate(myNumEntriesPerRow.begin(),
182 myNumEntriesPerRow.end(), 0);
188 myColInd = arcp<GO>(myNumEntries);
189 myValues = arcp<scalar_type>(myNumEntries);
190 if (myNumEntries > 0) {
193 receive(*pComm, rootRank,
194 static_cast<int>(myNumEntries),
195 myColInd.getRawPtr());
196 receive(*pComm, rootRank,
197 static_cast<int>(myNumEntries),
198 myValues.getRawPtr());
204 cerr <<
"-- Proc 0: Copying my data from global arrays" << endl;
208 for (size_type k = 0; k < myNumRows; ++k) {
209 const GO myCurRow = myRows[k];
211 myNumEntriesPerRow[k] = numEntriesInThisRow;
213 if (extraDebug && debug) {
214 cerr <<
"Proc " << pRowMap->getComm()->getRank()
215 <<
": myNumEntriesPerRow[0.." << (myNumRows - 1) <<
"] = [";
216 for (size_type k = 0; k < myNumRows; ++k) {
217 cerr << myNumEntriesPerRow[k];
218 if (k < myNumRows - 1) {
226 std::accumulate(myNumEntriesPerRow.begin(),
227 myNumEntriesPerRow.end(), 0);
229 cerr <<
"-- Proc 0: I own " << myNumRows <<
" rows and "
230 << myNumEntries <<
" entries" << endl;
232 myColInd = arcp<GO>(myNumEntries);
233 myValues = arcp<scalar_type>(myNumEntries);
241 for (size_type k = 0; k < myNumRows;
242 myCurPos += myNumEntriesPerRow[k], ++k) {
244 const GO myRow = myRows[k];
245 const size_t curPos = rowPtr[myRow];
248 if (curNumEntries > 0) {
249 ArrayView<GO> colIndView = colInd(curPos, curNumEntries);
250 ArrayView<GO> myColIndView = myColInd(myCurPos, curNumEntries);
251 std::copy(colIndView.begin(), colIndView.end(),
252 myColIndView.begin());
254 ArrayView<scalar_type> valuesView =
255 values(curPos, curNumEntries);
256 ArrayView<scalar_type> myValuesView =
257 myValues(myCurPos, curNumEntries);
258 std::copy(valuesView.begin(), valuesView.end(),
259 myValuesView.begin());
264 for (
int p = 1; p < numProcs; ++p) {
266 cerr <<
"-- Proc 0: Processing proc " << p << endl;
269 size_type theirNumRows = 0;
274 receive(*pComm, p, &theirNumRows);
276 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
277 << theirNumRows <<
" rows" << endl;
279 if (theirNumRows != 0) {
284 ArrayRCP<GO> theirRows = arcp<GO>(theirNumRows);
285 receive(*pComm, p, as<int>(theirNumRows),
286 theirRows.getRawPtr());
295 const global_size_t numRows = pRowMap->getGlobalNumElements();
296 const GO indexBase = pRowMap->getIndexBase();
297 bool theirRowsValid =
true;
298 for (size_type k = 0; k < theirNumRows; ++k) {
299 if (theirRows[k] < indexBase ||
300 as<global_size_t>(theirRows[k] - indexBase) >= numRows) {
301 theirRowsValid =
false;
304 if (!theirRowsValid) {
305 TEUCHOS_TEST_FOR_EXCEPTION(
306 !theirRowsValid, std::logic_error,
307 "Proc " << p <<
" has at least one invalid row index. "
308 "Here are all of them: "
309 << Teuchos::toString(theirRows()) <<
". Valid row index "
310 "range (zero-based): [0, "
311 << (numRows - 1) <<
"].");
326 ArrayRCP<size_t> theirNumEntriesPerRow;
327 theirNumEntriesPerRow = arcp<size_t>(theirNumRows);
328 for (size_type k = 0; k < theirNumRows; ++k) {
329 theirNumEntriesPerRow[k] = numEntriesPerRow[theirRows[k]];
336 send(*pComm,
static_cast<int>(theirNumRows),
337 theirNumEntriesPerRow.getRawPtr(), p);
341 std::accumulate(theirNumEntriesPerRow.begin(),
342 theirNumEntriesPerRow.end(), 0);
345 cerr <<
"-- Proc 0: Proc " << p <<
" owns "
346 << theirNumEntries <<
" entries" << endl;
351 if (theirNumEntries == 0) {
360 ArrayRCP<GO> theirColInd(theirNumEntries);
361 ArrayRCP<scalar_type> theirValues(theirNumEntries);
369 for (size_type k = 0; k < theirNumRows;
370 theirCurPos += theirNumEntriesPerRow[k], k++) {
372 const GO theirRow = theirRows[k];
378 if (curNumEntries > 0) {
379 ArrayView<GO> colIndView =
380 colInd(curPos, curNumEntries);
381 ArrayView<GO> theirColIndView =
382 theirColInd(theirCurPos, curNumEntries);
383 std::copy(colIndView.begin(), colIndView.end(),
384 theirColIndView.begin());
386 ArrayView<scalar_type> valuesView =
387 values(curPos, curNumEntries);
388 ArrayView<scalar_type> theirValuesView =
389 theirValues(theirCurPos, curNumEntries);
390 std::copy(valuesView.begin(), valuesView.end(),
391 theirValuesView.begin());
398 send(*pComm,
static_cast<int>(theirNumEntries),
399 theirColInd.getRawPtr(), p);
400 send(*pComm,
static_cast<int>(theirNumEntries),
401 theirValues.getRawPtr(), p);
404 cerr <<
"-- Proc 0: Finished with proc " << p << endl;
412 numEntriesPerRow = null;
417 if (debug && myRank == 0) {
418 cerr <<
"-- Proc 0: About to fill in myRowPtr" << endl;
426 myRowPtr = arcp<size_t>(myNumRows + 1);
428 for (size_type k = 1; k < myNumRows + 1; ++k) {
429 myRowPtr[k] = myRowPtr[k - 1] + myNumEntriesPerRow[k - 1];
431 if (extraDebug && debug) {
432 cerr <<
"Proc " << Teuchos::rank(*(pRowMap->getComm()))
433 <<
": myRowPtr[0.." << myNumRows <<
"] = [";
434 for (size_type k = 0; k < myNumRows + 1; ++k) {
444 if (debug && myRank == 0) {
445 cerr <<
"-- Proc 0: Done with distribute" << endl;
449template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
450Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
451MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
452 Teuchos::ArrayRCP<size_t>& myRowPtr,
453 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
454 Teuchos::ArrayRCP<scalar_type>& myValues,
455 const Teuchos::RCP<const map_type>& pRowMap,
456 const Teuchos::RCP<const map_type>& pRangeMap,
457 const Teuchos::RCP<const map_type>& pDomainMap,
458 const bool callFillComplete) {
461 using Teuchos::ArrayView;
466 typedef global_ordinal_type GO;
473 TEUCHOS_TEST_FOR_EXCEPTION(myRowPtr.is_null(), std::logic_error,
474 "makeMatrix: myRowPtr array is null. "
475 "Please report this bug to the Tpetra developers.");
476 TEUCHOS_TEST_FOR_EXCEPTION(pDomainMap.is_null(), std::logic_error,
477 "makeMatrix: domain map is null. "
478 "Please report this bug to the Tpetra developers.");
479 TEUCHOS_TEST_FOR_EXCEPTION(pRangeMap.is_null(), std::logic_error,
480 "makeMatrix: range map is null. "
481 "Please report this bug to the Tpetra developers.");
482 TEUCHOS_TEST_FOR_EXCEPTION(pRowMap.is_null(), std::logic_error,
483 "makeMatrix: row map is null. "
484 "Please report this bug to the Tpetra developers.");
488 RCP<sparse_matrix_type> A =
489 rcp(
new sparse_matrix_type(pRowMap, myNumEntriesPerRow()));
493 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
494 const size_type myNumRows = myRows.size();
497 const GO indexBase = pRowMap->getIndexBase();
498 for (size_type i = 0; i < myNumRows; ++i) {
499 const size_type myCurPos = myRowPtr[i];
501 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
502 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
505 for (size_type k = 0; k < curNumEntries; ++k) {
506 curColInd[k] += indexBase;
509 if (curNumEntries > 0) {
510 A->insertGlobalValues(myRows[i], curColInd, curValues);
517 myNumEntriesPerRow = null;
522 if (callFillComplete) {
523 A->fillComplete(pDomainMap, pRangeMap);
528template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
529Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
530MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
531 Teuchos::ArrayRCP<size_t>& myRowPtr,
534 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pRowMap,
535 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pRangeMap,
536 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& pDomainMap,
537 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
538 const Teuchos::RCP<Teuchos::ParameterList>& fillCompleteParams) {
541 using Teuchos::ArrayView;
547 using size_type =
typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::size_type;
554 TEUCHOS_TEST_FOR_EXCEPTION(
555 myRowPtr.is_null(), std::logic_error,
556 "makeMatrix: myRowPtr array is null. "
557 "Please report this bug to the Tpetra developers.");
558 TEUCHOS_TEST_FOR_EXCEPTION(
559 pDomainMap.is_null(), std::logic_error,
560 "makeMatrix: domain map is null. "
561 "Please report this bug to the Tpetra developers.");
562 TEUCHOS_TEST_FOR_EXCEPTION(
563 pRangeMap.is_null(), std::logic_error,
564 "makeMatrix: range map is null. "
565 "Please report this bug to the Tpetra developers.");
566 TEUCHOS_TEST_FOR_EXCEPTION(
567 pRowMap.is_null(), std::logic_error,
568 "makeMatrix: row map is null. "
569 "Please report this bug to the Tpetra developers.");
573 RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type> A =
574 rcp(
new typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type(pRowMap, myNumEntriesPerRow(),
579 ArrayView<const GO> myRows = pRowMap->getLocalElementList();
580 const size_type myNumRows = myRows.size();
583 const GO indexBase = pRowMap->getIndexBase();
584 for (size_type i = 0; i < myNumRows; ++i) {
585 const size_type myCurPos = myRowPtr[i];
587 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
588 ArrayView<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
591 for (size_type k = 0; k < curNumEntries; ++k) {
592 curColInd[k] += indexBase;
594 if (curNumEntries > 0) {
595 A->insertGlobalValues(myRows[i], curColInd, curValues);
602 myNumEntriesPerRow = null;
607 A->fillComplete(pDomainMap, pRangeMap, fillCompleteParams);
611template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
612Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
613MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeMatrix(Teuchos::ArrayRCP<size_t>& myNumEntriesPerRow,
614 Teuchos::ArrayRCP<size_t>& myRowPtr,
615 Teuchos::ArrayRCP<global_ordinal_type>& myColInd,
616 Teuchos::ArrayRCP<scalar_type>& myValues,
617 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rowMap,
618 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& colMap,
619 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& domainMap,
620 const Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& rangeMap,
621 const bool callFillComplete) {
622 using Teuchos::ArrayView;
627 typedef global_ordinal_type GO;
631 RCP<sparse_matrix_type> A;
633 A = rcp(
new sparse_matrix_type(
rowMap, myNumEntriesPerRow()));
635 A = rcp(
new sparse_matrix_type(
rowMap,
colMap, myNumEntriesPerRow()));
640 ArrayView<const GO> myRows =
rowMap->getLocalElementList();
641 const size_type myNumRows = myRows.size();
644 const GO indexBase =
rowMap->getIndexBase();
645 for (size_type i = 0; i < myNumRows; ++i) {
646 const size_type myCurPos = myRowPtr[i];
647 const size_type curNumEntries = as<size_type>(myNumEntriesPerRow[i]);
648 ArrayView<GO> curColInd = myColInd.view(myCurPos, curNumEntries);
649 ArrayView<scalar_type> curValues = myValues.view(myCurPos, curNumEntries);
652 for (size_type k = 0; k < curNumEntries; ++k) {
653 curColInd[k] += indexBase;
655 if (curNumEntries > 0) {
656 A->insertGlobalValues(myRows[i], curColInd, curValues);
663 myNumEntriesPerRow = null;
668 if (callFillComplete) {
677template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
678Teuchos::RCP<const Teuchos::MatrixMarket::Banner>
679MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readBanner(std::istream& in,
683 const bool isGraph) {
688 using Teuchos::MatrixMarket::Banner;
689 typedef Teuchos::ScalarTraits<scalar_type> STS;
695 const bool readFailed = !getline(in, line);
696 TEUCHOS_TEST_FOR_EXCEPTION(readFailed, std::invalid_argument,
697 "Failed to get Matrix Market banner line from input.");
704 pBanner = rcp(
new Banner(line, tolerant));
705 }
catch (std::exception& e) {
706 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
707 "Matrix Market banner line contains syntax error(s): "
711 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->objectType() !=
"matrix",
712 std::invalid_argument,
713 "The Matrix Market file does not contain "
714 "matrix data. Its Banner (first) line says that its object type is \""
715 << pBanner->matrixType() <<
"\", rather than the required \"matrix\".");
719 TEUCHOS_TEST_FOR_EXCEPTION(
720 !STS::isComplex && pBanner->dataType() ==
"complex",
721 std::invalid_argument,
722 "The Matrix Market file contains complex-valued data, but you are "
723 "trying to read it into a matrix containing entries of the real-"
724 "valued Scalar type \""
725 << Teuchos::TypeNameTraits<scalar_type>::name() <<
"\".");
726 TEUCHOS_TEST_FOR_EXCEPTION(
728 pBanner->dataType() !=
"real" &&
729 pBanner->dataType() !=
"complex" &&
730 pBanner->dataType() !=
"integer",
731 std::invalid_argument,
732 "When reading Matrix Market data into a Tpetra::CrsMatrix, the "
733 "Matrix Market file may not contain a \"pattern\" matrix. A "
734 "pattern matrix is really just a graph with no weights. It "
735 "should be stored in a CrsGraph, not a CrsMatrix.");
737 TEUCHOS_TEST_FOR_EXCEPTION(
739 pBanner->dataType() !=
"pattern",
740 std::invalid_argument,
741 "When reading Matrix Market data into a Tpetra::CrsGraph, the "
742 "Matrix Market file must contain a \"pattern\" matrix.");
747template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
748Teuchos::Tuple<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::global_ordinal_type, 3>
749MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readCoordDims(std::istream& in,
751 const Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
755 using Teuchos::Tuple;
756 using Teuchos::MatrixMarket::readCoordinateDimensions;
761 Tuple<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::global_ordinal_type, 3> dims;
767 bool success =
false;
768 if (pComm->getRank() == 0) {
769 TEUCHOS_TEST_FOR_EXCEPTION(pBanner->matrixType() !=
"coordinate",
770 std::invalid_argument,
771 "The Tpetra::CrsMatrix Matrix Market reader "
772 "only accepts \"coordinate\" (sparse) matrix data.");
776 success = readCoordinateDimensions(in, numRows, numCols,
777 numNonzeros, lineNumber,
783 dims[2] = numNonzeros;
791 int the_success = success ? 1 : 0;
792 Teuchos::broadcast(*pComm, 0, &the_success);
793 success = (the_success == 1);
798 Teuchos::broadcast(*pComm, 0, dims);
805 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
806 "Error reading Matrix Market sparse matrix: failed to read "
807 "coordinate matrix dimensions.");
812template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
813Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::adder_type>
814MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
815 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
816 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
819 if (pComm->getRank() == 0) {
820 typedef Teuchos::MatrixMarket::Raw::Adder<scalar_type,
823 Teuchos::RCP<raw_adder_type> pRaw =
824 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
826 return Teuchos::rcp(
new adder_type(pRaw, pBanner->symmType()));
828 return Teuchos::null;
832template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
833Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::graph_adder_type>
834MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::makeGraphAdder(
const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
835 Teuchos::RCP<const Teuchos::MatrixMarket::Banner>& pBanner,
836 const Teuchos::Tuple<global_ordinal_type, 3>& dims,
839 if (pComm->getRank() == 0) {
840 typedef Teuchos::MatrixMarket::Raw::GraphAdder<global_ordinal_type> raw_adder_type;
841 Teuchos::RCP<raw_adder_type> pRaw =
842 Teuchos::rcp(
new raw_adder_type(dims[0], dims[1], dims[2],
844 return Teuchos::rcp(
new graph_adder_type(pRaw, pBanner->symmType()));
846 return Teuchos::null;
850template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
851Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
852MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readSparseGraphHelper(std::istream& in,
853 const Teuchos::RCP<
const Teuchos::Comm<int>>& pComm,
854 const Teuchos::RCP<const map_type>& rowMap,
855 Teuchos::RCP<const map_type>& colMap,
856 const Teuchos::RCP<Teuchos::ParameterList>& constructorParams,
863 using Teuchos::Tuple;
864 using Teuchos::MatrixMarket::Banner;
866 const int myRank = pComm->getRank();
867 const int rootRank = 0;
872 size_t lineNumber = 1;
874 if (debug && myRank == rootRank) {
875 cerr <<
"Matrix Market reader: readGraph:" << endl
876 <<
"-- Reading banner line" << endl;
885 RCP<const Banner> pBanner;
891 int bannerIsCorrect = 1;
892 std::ostringstream errMsg;
894 if (myRank == rootRank) {
897 pBanner = readBanner(in, lineNumber, tolerant, debug,
true);
898 }
catch (std::exception& e) {
899 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
900 "threw an exception: "
905 if (bannerIsCorrect) {
910 if (!tolerant && pBanner->matrixType() !=
"coordinate") {
912 errMsg <<
"The Matrix Market input file must contain a "
913 "\"coordinate\"-format sparse graph in order to create a "
914 "Tpetra::CrsGraph object from it, but the file's matrix "
916 << pBanner->matrixType() <<
"\" instead.";
921 if (tolerant && pBanner->matrixType() ==
"array") {
923 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
924 "format sparse graph in order to create a Tpetra::CrsGraph "
925 "object from it, but the file's matrix type is \"array\" "
926 "instead. That probably means the file contains dense matrix "
933 broadcast(*pComm, rootRank, ptr(&bannerIsCorrect));
940 TEUCHOS_TEST_FOR_EXCEPTION(bannerIsCorrect == 0,
941 std::invalid_argument, errMsg.str());
943 if (debug && myRank == rootRank) {
944 cerr <<
"-- Reading dimensions line" << endl;
952 Tuple<global_ordinal_type, 3> dims =
953 readCoordDims(in, lineNumber, pBanner, pComm, tolerant, debug);
955 if (debug && myRank == rootRank) {
956 cerr <<
"-- Making Adder for collecting graph data" << endl;
963 RCP<graph_adder_type> pAdder =
964 makeGraphAdder(pComm, pBanner, dims, tolerant, debug);
966 if (debug && myRank == rootRank) {
967 cerr <<
"-- Reading graph data" << endl;
978 std::ostringstream errMsg;
979 if (myRank == rootRank) {
982 typedef Teuchos::MatrixMarket::CoordPatternReader<graph_adder_type,
985 reader_type reader(pAdder);
988 std::pair<bool, std::vector<size_t>> results =
989 reader.read(in, lineNumber, tolerant, debug);
990 readSuccess = results.first ? 1 : 0;
991 }
catch (std::exception& e) {
996 broadcast(*pComm, rootRank, ptr(&readSuccess));
1005 TEUCHOS_TEST_FOR_EXCEPTION(readSuccess == 0, std::runtime_error,
1006 "Failed to read the Matrix Market sparse graph file: "
1010 if (debug && myRank == rootRank) {
1011 cerr <<
"-- Successfully read the Matrix Market data" << endl;
1024 if (debug && myRank == rootRank) {
1025 cerr <<
"-- Tolerant mode: rebroadcasting graph dimensions"
1027 <<
"----- Dimensions before: "
1028 << dims[0] <<
" x " << dims[1]
1032 Tuple<global_ordinal_type, 2> updatedDims;
1033 if (myRank == rootRank) {
1040 std::max(dims[0], pAdder->getAdder()->numRows());
1041 updatedDims[1] = pAdder->getAdder()->numCols();
1043 broadcast(*pComm, rootRank, updatedDims);
1044 dims[0] = updatedDims[0];
1045 dims[1] = updatedDims[1];
1046 if (debug && myRank == rootRank) {
1047 cerr <<
"----- Dimensions after: " << dims[0] <<
" x "
1060 if (myRank == rootRank) {
1067 if (dims[0] < pAdder->getAdder()->numRows()) {
1071 broadcast(*pComm, 0, ptr(&dimsMatch));
1072 if (dimsMatch == 0) {
1079 Tuple<global_ordinal_type, 2> addersDims;
1080 if (myRank == rootRank) {
1081 addersDims[0] = pAdder->getAdder()->numRows();
1082 addersDims[1] = pAdder->getAdder()->numCols();
1084 broadcast(*pComm, 0, addersDims);
1085 TEUCHOS_TEST_FOR_EXCEPTION(
1086 dimsMatch == 0, std::runtime_error,
1087 "The graph metadata says that the graph is " << dims[0] <<
" x "
1088 << dims[1] <<
", but the actual data says that the graph is "
1089 << addersDims[0] <<
" x " << addersDims[1] <<
". That means the "
1090 "data includes more rows than reported in the metadata. This "
1091 "is not allowed when parsing in strict mode. Parse the graph in "
1092 "tolerant mode to ignore the metadata when it disagrees with the "
1098 RCP<map_type> proc0Map;
1099 global_ordinal_type indexBase;
1100 if (Teuchos::is_null(
rowMap)) {
1103 indexBase =
rowMap->getIndexBase();
1105 if (myRank == rootRank) {
1106 proc0Map = rcp(
new map_type(dims[0], dims[0], indexBase, pComm));
1108 proc0Map = rcp(
new map_type(dims[0], 0, indexBase, pComm));
1112 std::map<global_ordinal_type, size_t> numEntriesPerRow_map;
1113 if (myRank == rootRank) {
1114 const auto& entries = pAdder()->getAdder()->getEntries();
1119 for (
const auto& entry : entries) {
1120 const global_ordinal_type gblRow = entry.rowIndex() + indexBase;
1121 ++numEntriesPerRow_map[gblRow];
1125 Teuchos::Array<size_t> numEntriesPerRow(proc0Map->getLocalNumElements());
1126 for (
const auto& ent : numEntriesPerRow_map) {
1128 numEntriesPerRow[lclRow] = ent.second;
1135 std::map<global_ordinal_type, size_t> empty_map;
1136 std::swap(numEntriesPerRow_map, empty_map);
1139 RCP<sparse_graph_type> proc0Graph =
1140 rcp(
new sparse_graph_type(proc0Map, numEntriesPerRow(),
1141 constructorParams));
1142 if (myRank == rootRank) {
1143 typedef Teuchos::MatrixMarket::Raw::GraphElement<global_ordinal_type> element_type;
1146 const std::vector<element_type>& entries =
1147 pAdder->getAdder()->getEntries();
1150 for (
size_t curPos = 0; curPos < entries.size(); curPos++) {
1151 const element_type& curEntry = entries[curPos];
1152 const global_ordinal_type curRow = curEntry.rowIndex() + indexBase;
1153 const global_ordinal_type curCol = curEntry.colIndex() + indexBase;
1154 Teuchos::ArrayView<const global_ordinal_type> colView(&curCol, 1);
1155 proc0Graph->insertGlobalIndices(curRow, colView);
1158 proc0Graph->fillComplete();
1160 RCP<sparse_graph_type> distGraph;
1161 if (Teuchos::is_null(
rowMap)) {
1163 RCP<map_type> distMap =
1164 rcp(
new map_type(dims[0], 0, pComm, GloballyDistributed));
1167 distGraph = rcp(
new sparse_graph_type(distMap,
colMap, 0, constructorParams));
1170 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1171 import_type importer(proc0Map, distMap);
1174 distGraph->doImport(*proc0Graph, importer,
INSERT);
1176 distGraph = rcp(
new sparse_graph_type(
rowMap,
colMap, 0, constructorParams));
1179 typedef Import<local_ordinal_type, global_ordinal_type, node_type> import_type;
1180 import_type importer(proc0Map,
rowMap);
1183 distGraph->doImport(*proc0Graph, importer,
INSERT);
1189template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1190Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1198 return readSparseGraph(
in, comm,
1206template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1207Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::
1210 const Teuchos::RCP<
const Teuchos::Comm<int>>&
pComm,
1217 return readSparseGraph(
in,
pComm,
1225template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1226Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1228 const Teuchos::RCP<const map_type>& rowMap,
1229 Teuchos::RCP<const map_type>& colMap,
1230 const Teuchos::RCP<const map_type>& domainMap,
1231 const Teuchos::RCP<const map_type>&
rangeMap,
1236 "Input rowMap must be nonnull.");
1238 if (comm.is_null()) {
1241 return Teuchos::null;
1250template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1251Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1253 const Teuchos::RCP<
const Teuchos::Comm<int>>&
pComm,
1261 Teuchos::RCP<sparse_graph_type>
graph =
1262 readSparseGraphHelper(
in,
pComm,
1266 graph->fillComplete();
1271template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1272Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_graph_type>
1274 const Teuchos::RCP<
const Teuchos::Comm<int>>&
pComm,
1281 Teuchos::RCP<sparse_graph_type>
graph =
1282 readSparseGraphHelper(
in,
pComm,
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 map_type>& rowMap,
1293 Teuchos::RCP<const map_type>& colMap,
1294 const Teuchos::RCP<const map_type>& domainMap,
1295 const Teuchos::RCP<const map_type>&
rangeMap,
1299 Teuchos::RCP<sparse_graph_type>
graph =
1300 readSparseGraphHelper(
in,
rowMap->getComm(),
1309#include "MatrixMarket_TpetraNew.hpp"
1311template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1312Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1326template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1327Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1340template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1341Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1343 const Teuchos::RCP<const map_type>& rowMap,
1344 Teuchos::RCP<const map_type>& colMap,
1345 const Teuchos::RCP<const map_type>& domainMap,
1346 const Teuchos::RCP<const map_type>&
rangeMap,
1351 rowMap.is_null(), std::invalid_argument,
1352 "Row Map must be nonnull.");
1362template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1363Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1365 const Teuchos::RCP<
const Teuchos::Comm<int>>&
pComm,
1371 using Teuchos::arcp;
1372 using Teuchos::ArrayRCP;
1373 using Teuchos::broadcast;
1374 using Teuchos::null;
1377 using Teuchos::REDUCE_MAX;
1378 using Teuchos::reduceAll;
1379 using Teuchos::Tuple;
1380 using Teuchos::MatrixMarket::Banner;
1381 typedef Teuchos::ScalarTraits<scalar_type> STS;
1384 const int myRank =
pComm->getRank();
1393 cerr <<
"Matrix Market reader: readSparse:" <<
endl
1394 <<
"-- Reading banner line" <<
endl;
1410 std::ostringstream
errMsg;
1416 }
catch (std::exception&
e) {
1417 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1418 "threw an exception: "
1430 errMsg <<
"The Matrix Market input file must contain a "
1431 "\"coordinate\"-format sparse matrix in order to create a "
1432 "Tpetra::CrsMatrix object from it, but the file's matrix "
1434 <<
pBanner->matrixType() <<
"\" instead.";
1441 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1442 "format sparse matrix in order to create a Tpetra::CrsMatrix "
1443 "object from it, but the file's matrix type is \"array\" "
1444 "instead. That probably means the file contains dense matrix "
1459 std::invalid_argument,
errMsg.str());
1462 cerr <<
"-- Reading dimensions line" <<
endl;
1474 cerr <<
"-- Making Adder for collecting matrix data" <<
endl;
1483 cerr <<
"-- Reading matrix data" <<
endl;
1494 std::ostringstream
errMsg;
1498 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
1504 std::pair<bool, std::vector<size_t>>
results =
1507 }
catch (std::exception&
e) {
1522 "Failed to read the Matrix Market sparse matrix file: "
1527 cerr <<
"-- Successfully read the Matrix Market data" <<
endl;
1541 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
1543 <<
"----- Dimensions before: "
1556 std::max(
dims[0],
pAdder->getAdder()->numRows());
1563 cerr <<
"----- Dimensions after: " <<
dims[0] <<
" x "
1583 if (
dims[0] <
pAdder->getAdder()->numRows()) {
1603 "The matrix metadata says that the matrix is " <<
dims[0] <<
" x "
1604 <<
dims[1] <<
", but the actual data says that the matrix is "
1606 "data includes more rows than reported in the metadata. This "
1607 "is not allowed when parsing in strict mode. Parse the matrix in "
1608 "tolerant mode to ignore the metadata when it disagrees with the "
1614 cerr <<
"-- Converting matrix data into CSR format on Proc 0" <<
endl;
1635 std::ostringstream
errMsg;
1639 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
1653 pAdder->getAdder()->merge();
1656 const std::vector<element_type>& entries =
1657 pAdder->getAdder()->getEntries();
1660 const size_t numEntries = (
size_t)entries.size();
1663 cerr <<
"----- Proc 0: Matrix has numRows=" <<
numRows
1664 <<
" rows and numEntries=" << numEntries
1665 <<
" entries." <<
endl;
1688 "Row indices are out of order, even though they are supposed "
1689 "to be sorted. curRow = "
1690 <<
curRow <<
", prvRow = "
1691 <<
prvRow <<
", at curPos = " <<
curPos <<
". Please report "
1692 "this bug to the Tpetra developers.");
1708 catch (std::exception&
e) {
1710 errMsg <<
"Failed to merge sparse matrix entries and convert to "
1720 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
1723 cerr <<
"(only showing first and last few entries) ";
1728 for (size_type
k = 0;
k < 2; ++
k) {
1736 for (size_type
k = 0;
k <
numRows - 1; ++
k) {
1744 cerr <<
"----- Proc 0: rowPtr ";
1746 cerr <<
"(only showing first and last few entries) ";
1750 for (size_type
k = 0;
k < 2; ++
k) {
1774 cerr <<
"-- Making range, domain, and row maps" <<
endl;
1787 cerr <<
"-- Distributing the matrix data" <<
endl;
1810 cerr <<
"-- Inserting matrix entries on each processor";
1812 cerr <<
" and calling fillComplete()";
1834 "MatrixMarketReader::makeMatrix() returned a null pointer on at least one "
1835 "process. Please report this bug to the Tpetra developers.");
1838 "MatrixMarketReader::makeMatrix() returned a null pointer. "
1839 "Please report this bug to the Tpetra developers.");
1860 cerr <<
"-- Matrix is "
1862 <<
" with " <<
pMatrix->getGlobalNumEntries()
1863 <<
" entries, and index base "
1869 cerr <<
"-- Proc " <<
p <<
" owns "
1870 <<
pMatrix->getLocalNumCols() <<
" columns, and "
1871 <<
pMatrix->getLocalNumEntries() <<
" entries." <<
endl;
1879 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
1885template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1886Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
1888 const Teuchos::RCP<
const Teuchos::Comm<int>>&
pComm,
1895 using Teuchos::arcp;
1896 using Teuchos::ArrayRCP;
1897 using Teuchos::broadcast;
1898 using Teuchos::null;
1901 using Teuchos::reduceAll;
1902 using Teuchos::Tuple;
1903 using Teuchos::MatrixMarket::Banner;
1904 typedef Teuchos::ScalarTraits<scalar_type> STS;
1907 const int myRank =
pComm->getRank();
1916 cerr <<
"Matrix Market reader: readSparse:" <<
endl
1917 <<
"-- Reading banner line" <<
endl;
1933 std::ostringstream
errMsg;
1939 }
catch (std::exception&
e) {
1940 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
1941 "threw an exception: "
1953 errMsg <<
"The Matrix Market input file must contain a "
1954 "\"coordinate\"-format sparse matrix in order to create a "
1955 "Tpetra::CrsMatrix object from it, but the file's matrix "
1957 <<
pBanner->matrixType() <<
"\" instead.";
1964 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
1965 "format sparse matrix in order to create a Tpetra::CrsMatrix "
1966 "object from it, but the file's matrix type is \"array\" "
1967 "instead. That probably means the file contains dense matrix "
1982 std::invalid_argument,
errMsg.str());
1985 cerr <<
"-- Reading dimensions line" <<
endl;
1997 cerr <<
"-- Making Adder for collecting matrix data" <<
endl;
2006 cerr <<
"-- Reading matrix data" <<
endl;
2017 std::ostringstream
errMsg;
2021 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2027 std::pair<bool, std::vector<size_t>>
results =
2030 }
catch (std::exception&
e) {
2045 "Failed to read the Matrix Market sparse matrix file: "
2050 cerr <<
"-- Successfully read the Matrix Market data" <<
endl;
2064 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2066 <<
"----- Dimensions before: "
2079 std::max(
dims[0],
pAdder->getAdder()->numRows());
2086 cerr <<
"----- Dimensions after: " <<
dims[0] <<
" x "
2106 if (
dims[0] <
pAdder->getAdder()->numRows()) {
2126 "The matrix metadata says that the matrix is " <<
dims[0] <<
" x "
2127 <<
dims[1] <<
", but the actual data says that the matrix is "
2129 "data includes more rows than reported in the metadata. This "
2130 "is not allowed when parsing in strict mode. Parse the matrix in "
2131 "tolerant mode to ignore the metadata when it disagrees with the "
2137 cerr <<
"-- Converting matrix data into CSR format on Proc 0" <<
endl;
2158 std::ostringstream
errMsg;
2162 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2176 pAdder->getAdder()->merge();
2179 const std::vector<element_type>& entries =
2180 pAdder->getAdder()->getEntries();
2183 const size_t numEntries = (
size_t)entries.size();
2186 cerr <<
"----- Proc 0: Matrix has numRows=" <<
numRows
2187 <<
" rows and numEntries=" << numEntries
2188 <<
" entries." <<
endl;
2211 "Row indices are out of order, even though they are supposed "
2212 "to be sorted. curRow = "
2213 <<
curRow <<
", prvRow = "
2214 <<
prvRow <<
", at curPos = " <<
curPos <<
". Please report "
2215 "this bug to the Tpetra developers.");
2231 catch (std::exception&
e) {
2233 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2243 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2246 cerr <<
"(only showing first and last few entries) ";
2251 for (size_type
k = 0;
k < 2; ++
k) {
2259 for (size_type
k = 0;
k <
numRows - 1; ++
k) {
2267 cerr <<
"----- Proc 0: rowPtr ";
2269 cerr <<
"(only showing first and last few entries) ";
2273 for (size_type
k = 0;
k < 2; ++
k) {
2297 cerr <<
"-- Making range, domain, and row maps" <<
endl;
2310 cerr <<
"-- Distributing the matrix data" <<
endl;
2333 cerr <<
"-- Inserting matrix entries on each process "
2334 "and calling fillComplete()"
2344 Teuchos::RCP<sparse_matrix_type>
pMatrix =
2356 "MatrixMarketReader::makeMatrix() returned a null pointer on at least one "
2357 "process. Please report this bug to the Tpetra developers.");
2360 "MatrixMarketReader::makeMatrix() returned a null pointer. "
2361 "Please report this bug to the Tpetra developers.");
2377 cerr <<
"-- Matrix is "
2379 <<
" with " <<
pMatrix->getGlobalNumEntries()
2380 <<
" entries, and index base "
2386 cerr <<
"-- Proc " <<
p <<
" owns "
2387 <<
pMatrix->getLocalNumCols() <<
" columns, and "
2388 <<
pMatrix->getLocalNumEntries() <<
" entries." <<
endl;
2395 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
2401template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
2402Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
2404 const Teuchos::RCP<const map_type>& rowMap,
2405 Teuchos::RCP<const map_type>& colMap,
2406 const Teuchos::RCP<const map_type>& domainMap,
2407 const Teuchos::RCP<const map_type>&
rangeMap,
2413 using Teuchos::arcp;
2414 using Teuchos::ArrayRCP;
2415 using Teuchos::ArrayView;
2417 using Teuchos::broadcast;
2418 using Teuchos::Comm;
2419 using Teuchos::null;
2422 using Teuchos::reduceAll;
2423 using Teuchos::Tuple;
2424 using Teuchos::MatrixMarket::Banner;
2425 typedef Teuchos::ScalarTraits<scalar_type> STS;
2428 const int myRank =
pComm->getRank();
2436 rowMap.is_null(), std::invalid_argument,
2437 "Row Map must be nonnull.");
2439 rangeMap.is_null(), std::invalid_argument,
2440 "Range Map must be nonnull.");
2442 domainMap.is_null(), std::invalid_argument,
2443 "Domain Map must be nonnull.");
2445 rowMap->getComm().getRawPtr() !=
pComm.getRawPtr(),
2446 std::invalid_argument,
2447 "The specified row Map's communicator (rowMap->getComm())"
2448 "differs from the given separately supplied communicator pComm.");
2451 std::invalid_argument,
2452 "The specified domain Map's communicator (domainMap->getComm())"
2453 "differs from the given separately supplied communicator pComm.");
2456 std::invalid_argument,
2457 "The specified range Map's communicator (rangeMap->getComm())"
2458 "differs from the given separately supplied communicator pComm.");
2466 cerr <<
"Matrix Market reader: readSparse:" <<
endl
2467 <<
"-- Reading banner line" <<
endl;
2483 std::ostringstream
errMsg;
2489 }
catch (std::exception&
e) {
2490 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
2491 "threw an exception: "
2503 errMsg <<
"The Matrix Market input file must contain a "
2504 "\"coordinate\"-format sparse matrix in order to create a "
2505 "Tpetra::CrsMatrix object from it, but the file's matrix "
2507 <<
pBanner->matrixType() <<
"\" instead.";
2514 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
2515 "format sparse matrix in order to create a Tpetra::CrsMatrix "
2516 "object from it, but the file's matrix type is \"array\" "
2517 "instead. That probably means the file contains dense matrix "
2532 std::invalid_argument,
errMsg.str());
2535 cerr <<
"-- Reading dimensions line" <<
endl;
2547 cerr <<
"-- Making Adder for collecting matrix data" <<
endl;
2558 cerr <<
"-- Reading matrix data" <<
endl;
2569 std::ostringstream
errMsg;
2573 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
2579 std::pair<bool, std::vector<size_t>>
results =
2582 }
catch (std::exception&
e) {
2597 "Failed to read the Matrix Market sparse matrix file: "
2602 cerr <<
"-- Successfully read the Matrix Market data" <<
endl;
2616 cerr <<
"-- Tolerant mode: rebroadcasting matrix dimensions"
2618 <<
"----- Dimensions before: "
2631 std::max(
dims[0],
pAdder->getAdder()->numRows());
2638 cerr <<
"----- Dimensions after: " <<
dims[0] <<
" x "
2658 if (
dims[0] <
pAdder->getAdder()->numRows()) {
2678 "The matrix metadata says that the matrix is " <<
dims[0] <<
" x "
2679 <<
dims[1] <<
", but the actual data says that the matrix is "
2681 "data includes more rows than reported in the metadata. This "
2682 "is not allowed when parsing in strict mode. Parse the matrix in "
2683 "tolerant mode to ignore the metadata when it disagrees with the "
2689 cerr <<
"-- Converting matrix data into CSR format on Proc 0" <<
endl;
2710 std::ostringstream
errMsg;
2714 typedef Teuchos::MatrixMarket::Raw::Element<
scalar_type,
2728 pAdder->getAdder()->merge();
2731 const std::vector<element_type>& entries =
2732 pAdder->getAdder()->getEntries();
2735 const size_t numEntries = (
size_t)entries.size();
2738 cerr <<
"----- Proc 0: Matrix has numRows=" <<
numRows
2739 <<
" rows and numEntries=" << numEntries
2740 <<
" entries." <<
endl;
2763 "Row indices are out of order, even though they are supposed "
2764 "to be sorted. curRow = "
2765 <<
curRow <<
", prvRow = "
2766 <<
prvRow <<
", at curPos = " <<
curPos <<
". Please report "
2767 "this bug to the Tpetra developers.");
2781 catch (std::exception&
e) {
2783 errMsg <<
"Failed to merge sparse matrix entries and convert to "
2793 cerr <<
"----- Proc 0: numEntriesPerRow[0.."
2796 cerr <<
"(only showing first and last few entries) ";
2801 for (size_type
k = 0;
k < 2; ++
k) {
2809 for (size_type
k = 0;
k <
numRows - 1; ++
k) {
2817 cerr <<
"----- Proc 0: rowPtr ";
2819 cerr <<
"(only showing first and last few entries) ";
2823 for (size_type
k = 0;
k < 2; ++
k) {
2837 cerr <<
"----- Proc 0: colInd = [";
2856 cerr <<
"-- Verifying Maps" <<
endl;
2860 std::invalid_argument,
2861 "The range Map has " <<
rangeMap->getMaxAllGlobalIndex()
2862 <<
" max entry, but the matrix has a global number of rows " <<
dims[0]
2866 std::invalid_argument,
2867 "The domain Map has " <<
domainMap->getMaxAllGlobalIndex()
2868 <<
" max entry, but the matrix has a global number of columns "
2892 cerr <<
"-- Proc 0: Filling gather matrix" <<
endl;
2978 cerr <<
"-- Matrix is "
2980 <<
" with " <<
A->getGlobalNumEntries()
2981 <<
" entries, and index base "
2982 <<
A->getIndexBase() <<
"." <<
endl;
2987 cerr <<
"-- Proc " <<
p <<
" owns "
2988 <<
A->getLocalNumCols() <<
" columns, and "
2989 <<
A->getLocalNumEntries() <<
" entries." <<
endl;
2997 cerr <<
"-- Done creating the CrsMatrix from the Matrix Market data"
3003template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3004Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::multivector_type>
3016template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3020 std::ios_base::openmode
mode) {
3028 if (comm->getRank() == 0) {
3039 "Could not open input file '" +
filename +
"' on root rank 0.");
3044template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3045Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::vector_type>
3056template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3057Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::multivector_type>
3064 Teuchos::RCP<Teuchos::FancyOStream>
err =
3065 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3069template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3070Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::vector_type>
3076 Teuchos::RCP<Teuchos::FancyOStream>
err =
3077 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
3081template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3082Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
3093template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3094template <
class MultiVectorScalarType>
3102 const Teuchos::RCP<Teuchos::FancyOStream>&
err,
3107 using Teuchos::ArrayRCP;
3109 using Teuchos::broadcast;
3110 using Teuchos::outArg;
3112 using Teuchos::Tuple;
3113 using Teuchos::MatrixMarket::Banner;
3114 using Teuchos::MatrixMarket::checkCommentLine;
3116 typedef local_ordinal_type LO;
3117 typedef global_ordinal_type GO;
3118 typedef node_type
NT;
3119 typedef Teuchos::ScalarTraits<ST> STS;
3120 typedef typename STS::magnitudeType
MT;
3121 typedef Teuchos::ScalarTraits<MT> STM;
3126 const int myRank = comm->getRank();
3128 if (!
err.is_null()) {
3132 *err << myRank <<
": readDenseImpl" << endl;
3134 if (!err.is_null()) {
3169 size_t lineNumber = 1;
3172 std::ostringstream exMsg;
3173 int localBannerReadSuccess = 1;
3174 int localDimsReadSuccess = 1;
3180 *err << myRank <<
": readDenseImpl: Reading banner line (dense)" << endl;
3186 RCP<const Banner> pBanner;
3188 pBanner = readBanner(in, lineNumber, tolerant, debug);
3189 }
catch (std::exception& e) {
3191 localBannerReadSuccess = 0;
3194 if (localBannerReadSuccess) {
3195 if (pBanner->matrixType() !=
"array") {
3196 exMsg <<
"The Matrix Market file does not contain dense matrix "
3197 "data. Its banner (first) line says that its matrix type is \""
3198 << pBanner->matrixType() <<
"\", rather that the required "
3200 localBannerReadSuccess = 0;
3201 }
else if (pBanner->dataType() ==
"pattern") {
3202 exMsg <<
"The Matrix Market file's banner (first) "
3203 "line claims that the matrix's data type is \"pattern\". This does "
3204 "not make sense for a dense matrix, yet the file reports the matrix "
3205 "as dense. The only valid data types for a dense matrix are "
3206 "\"real\", \"complex\", and \"integer\".";
3207 localBannerReadSuccess = 0;
3211 dims[2] = encodeDataType(pBanner->dataType());
3217 if (localBannerReadSuccess) {
3219 *err << myRank <<
": readDenseImpl: Reading dimensions line (dense)" << endl;
3228 bool commentLine =
true;
3230 while (commentLine) {
3233 if (in.eof() || in.fail()) {
3234 exMsg <<
"Unable to get array dimensions line (at all) from line "
3235 << lineNumber <<
" of input stream. The input stream "
3236 <<
"claims that it is "
3237 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
3238 localDimsReadSuccess = 0;
3241 if (getline(in, line)) {
3248 size_t start = 0, size = 0;
3249 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
3256 std::istringstream istr(line);
3260 if (istr.eof() || istr.fail()) {
3261 exMsg <<
"Unable to read any data from line " << lineNumber
3262 <<
" of input; the line should contain the matrix dimensions "
3263 <<
"\"<numRows> <numCols>\".";
3264 localDimsReadSuccess = 0;
3269 exMsg <<
"Failed to get number of rows from line "
3270 << lineNumber <<
" of input; the line should contains the "
3271 <<
"matrix dimensions \"<numRows> <numCols>\".";
3272 localDimsReadSuccess = 0;
3274 dims[0] = theNumRows;
3276 exMsg <<
"No more data after number of rows on line "
3277 << lineNumber <<
" of input; the line should contain the "
3278 <<
"matrix dimensions \"<numRows> <numCols>\".";
3279 localDimsReadSuccess = 0;
3284 exMsg <<
"Failed to get number of columns from line "
3285 << lineNumber <<
" of input; the line should contain "
3286 <<
"the matrix dimensions \"<numRows> <numCols>\".";
3287 localDimsReadSuccess = 0;
3289 dims[1] = theNumCols;
3298 in.read(
reinterpret_cast<char*
>(&numRows),
sizeof(numRows));
3299 in.read(
reinterpret_cast<char*
>(&numCols),
sizeof(numCols));
3300 dims[0] = Teuchos::as<GO>(numRows);
3301 dims[1] = Teuchos::as<GO>(numCols);
3302 if ((
typeid(ST) ==
typeid(
double)) || Teuchos::ScalarTraits<ST>::isOrdinal) {
3304 }
else if (Teuchos::ScalarTraits<ST>::isComplex) {
3307 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
3308 "Unrecognized Matrix Market data type. "
3309 "We should never get here. "
3310 "Please report this bug to the Tpetra developers.");
3312 localDimsReadSuccess =
true;
3313 localDimsReadSuccess =
true;
3320 Tuple<GO, 5> bannerDimsReadResult;
3322 bannerDimsReadResult[0] = dims[0];
3323 bannerDimsReadResult[1] = dims[1];
3324 bannerDimsReadResult[2] = dims[2];
3325 bannerDimsReadResult[3] = localBannerReadSuccess;
3326 bannerDimsReadResult[4] = localDimsReadSuccess;
3330 broadcast(*comm, 0, bannerDimsReadResult);
3332 TEUCHOS_TEST_FOR_EXCEPTION(
3333 bannerDimsReadResult[3] == 0, std::runtime_error,
3334 "Failed to read banner line: " << exMsg.str());
3335 TEUCHOS_TEST_FOR_EXCEPTION(
3336 bannerDimsReadResult[4] == 0, std::runtime_error,
3337 "Failed to read matrix dimensions line: " << exMsg.str());
3339 dims[0] = bannerDimsReadResult[0];
3340 dims[1] = bannerDimsReadResult[1];
3341 dims[2] = bannerDimsReadResult[2];
3346 const size_t numCols =
static_cast<size_t>(dims[1]);
3351 RCP<const map_type> proc0Map;
3352 if (map.is_null()) {
3356 map = createUniformContigMapWithNode<LO, GO, NT>(numRows, comm);
3357 const size_t localNumRows = (myRank == 0) ? numRows : 0;
3359 proc0Map = createContigMapWithNode<LO, GO, NT>(numRows, localNumRows,
3362 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
3366 RCP<MV> X = createMultiVector<ST, LO, GO, NT>(proc0Map, numCols);
3372 int localReadDataSuccess = 1;
3377 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
3382 TEUCHOS_TEST_FOR_EXCEPTION(
3383 !X->isConstantStride(), std::logic_error,
3384 "Can't get a 1-D view of the entries of the MultiVector X on "
3385 "Process 0, because the stride between the columns of X is not "
3386 "constant. This shouldn't happen because we just created X and "
3387 "haven't filled it in yet. Please report this bug to the Tpetra "
3394 ArrayRCP<ST> X_view = X->get1dViewNonConst();
3395 TEUCHOS_TEST_FOR_EXCEPTION(
3396 as<global_size_t>(X_view.size()) < numRows * numCols,
3398 "The view of X has size " << X_view.size() <<
" which is not enough to "
3399 "accommodate the expected number of entries numRows*numCols = "
3400 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
3401 "Please report this bug to the Tpetra developers.");
3402 const size_t stride = X->getStride();
3409 const bool isComplex = (dims[2] == 1);
3410 size_type count = 0, curRow = 0, curCol = 0;
3413 while (getline(in, line)) {
3417 size_t start = 0, size = 0;
3418 const bool commentLine =
3419 checkCommentLine(line, start, size, lineNumber, tolerant);
3426 if (count >= X_view.size()) {
3430 TEUCHOS_TEST_FOR_EXCEPTION(
3431 count >= X_view.size(),
3433 "The Matrix Market input stream has more data in it than "
3434 "its metadata reported. Current line number is "
3435 << lineNumber <<
".");
3444 const size_t pos = line.substr(start, size).find(
':');
3445 if (pos != std::string::npos) {
3449 std::istringstream istr(line.substr(start, size));
3453 if (istr.eof() || istr.fail()) {
3460 TEUCHOS_TEST_FOR_EXCEPTION(
3461 !tolerant && (istr.eof() || istr.fail()),
3463 "Line " << lineNumber <<
" of the Matrix Market file is "
3464 "empty, or we cannot read from it for some other reason.");
3467 ST val = STS::zero();
3470 MT real = STM::zero(), imag = STM::zero();
3487 TEUCHOS_TEST_FOR_EXCEPTION(
3488 !tolerant && istr.eof(), std::runtime_error,
3489 "Failed to get the real part of a complex-valued matrix "
3491 << lineNumber <<
" of the Matrix Market "
3497 }
else if (istr.eof()) {
3498 TEUCHOS_TEST_FOR_EXCEPTION(
3499 !tolerant && istr.eof(), std::runtime_error,
3500 "Missing imaginary part of a complex-valued matrix entry "
3502 << lineNumber <<
" of the Matrix Market file.");
3508 TEUCHOS_TEST_FOR_EXCEPTION(
3509 !tolerant && istr.fail(), std::runtime_error,
3510 "Failed to get the imaginary part of a complex-valued "
3511 "matrix entry from line "
3512 << lineNumber <<
" of the "
3513 "Matrix Market file.");
3520 TEUCHOS_TEST_FOR_EXCEPTION(
3521 !tolerant && istr.fail(), std::runtime_error,
3522 "Failed to get a real-valued matrix entry from line "
3523 << lineNumber <<
" of the Matrix Market file.");
3526 if (istr.fail() && tolerant) {
3532 TEUCHOS_TEST_FOR_EXCEPTION(
3533 !tolerant && istr.fail(), std::runtime_error,
3534 "Failed to read matrix data from line " << lineNumber
3535 <<
" of the Matrix Market file.");
3538 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
3540 curRow = count % numRows;
3541 curCol = count / numRows;
3542 X_view[curRow + curCol * stride] = val;
3547 TEUCHOS_TEST_FOR_EXCEPTION(
3548 !tolerant &&
static_cast<global_size_t>(count) < numRows * numCols,
3550 "The Matrix Market metadata reports that the dense matrix is "
3551 << numRows <<
" x " << numCols <<
", and thus has "
3552 << numRows * numCols <<
" total entries, but we only found " << count
3553 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
3554 }
catch (std::exception& e) {
3556 localReadDataSuccess = 0;
3561 *err << myRank <<
": readDenseImpl: Reading matrix data (dense)"
3566 TEUCHOS_TEST_FOR_EXCEPTION(
3567 !X->isConstantStride(), std::logic_error,
3568 "Can't get a 1-D view of the entries of the MultiVector X on "
3569 "Process 0, because the stride between the columns of X is not "
3570 "constant. This shouldn't happen because we just created X and "
3571 "haven't filled it in yet. Please report this bug to the Tpetra "
3578 auto X_view = X->getLocalViewHost(Access::OverwriteAll);
3580 TEUCHOS_TEST_FOR_EXCEPTION(
3581 as<global_size_t>(X_view.extent(0)) < numRows,
3583 "The view of X has " << X_view.extent(0) <<
" rows which is not enough to "
3584 "accommodate the expected number of entries numRows = "
3586 "Please report this bug to the Tpetra developers.");
3587 TEUCHOS_TEST_FOR_EXCEPTION(
3588 as<global_size_t>(X_view.extent(1)) < numCols,
3590 "The view of X has " << X_view.extent(1) <<
" colums which is not enough to "
3591 "accommodate the expected number of entries numRows = "
3593 "Please report this bug to the Tpetra developers.");
3595 for (
size_t curRow = 0; curRow < numRows; ++curRow) {
3596 for (
size_t curCol = 0; curCol < numCols; ++curCol) {
3597 if (Teuchos::ScalarTraits<ST>::isOrdinal) {
3599 in.read(
reinterpret_cast<char*
>(&val),
sizeof(val));
3600 X_view(curRow, curCol) = val;
3603 in.read(
reinterpret_cast<char*
>(&val),
sizeof(val));
3604 X_view(curRow, curCol) = val;
3612 *err << myRank <<
": readDenseImpl: done reading data" << endl;
3616 int globalReadDataSuccess = localReadDataSuccess;
3617 broadcast(*comm, 0, outArg(globalReadDataSuccess));
3618 TEUCHOS_TEST_FOR_EXCEPTION(
3619 globalReadDataSuccess == 0, std::runtime_error,
3620 "Failed to read the multivector's data: " << exMsg.str());
3625 if (comm->getSize() == 1 && map.is_null()) {
3627 if (!err.is_null()) {
3631 *err << myRank <<
": readDenseImpl: done" << endl;
3633 if (!err.is_null()) {
3640 *err << myRank <<
": readDenseImpl: Creating target MV" << endl;
3644 RCP<MV> Y = createMultiVector<ST, LO, GO, NT>(map, numCols);
3647 *err << myRank <<
": readDenseImpl: Creating Export" << endl;
3653 Export<LO, GO, NT> exporter(proc0Map, map, err);
3656 *err << myRank <<
": readDenseImpl: Exporting" << endl;
3659 Y->doExport(*X, exporter,
INSERT);
3661 if (!err.is_null()) {
3665 *err << myRank <<
": readDenseImpl: done" << endl;
3667 if (!err.is_null()) {
3675template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
3676template <
class VectorScalarType>
3681MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::readVectorImpl(std::istream& in,
3683 Teuchos::RCP<
const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>& map,
3684 const Teuchos::RCP<Teuchos::FancyOStream>& err,
3685 const bool tolerant,
3689 using Teuchos::broadcast;
3690 using Teuchos::outArg;
3692 using Teuchos::Tuple;
3693 using Teuchos::MatrixMarket::Banner;
3694 using Teuchos::MatrixMarket::checkCommentLine;
3695 typedef VectorScalarType ST;
3697 typedef global_ordinal_type GO;
3698 typedef node_type NT;
3699 typedef Teuchos::ScalarTraits<ST> STS;
3700 typedef typename STS::magnitudeType MT;
3701 typedef Teuchos::ScalarTraits<MT> STM;
3706 const int myRank = comm->getRank();
3708 if (!err.is_null()) {
3712 *err << myRank <<
": readVectorImpl" << endl;
3714 if (!err.is_null()) {
3748 size_t lineNumber = 1;
3751 std::ostringstream exMsg;
3752 int localBannerReadSuccess = 1;
3753 int localDimsReadSuccess = 1;
3758 *err << myRank <<
": readVectorImpl: Reading banner line (dense)" << endl;
3764 RCP<const Banner> pBanner;
3766 pBanner = readBanner(in, lineNumber, tolerant, debug);
3767 }
catch (std::exception& e) {
3769 localBannerReadSuccess = 0;
3772 if (localBannerReadSuccess) {
3773 if (pBanner->matrixType() !=
"array") {
3774 exMsg <<
"The Matrix Market file does not contain dense matrix "
3775 "data. Its banner (first) line says that its matrix type is \""
3776 << pBanner->matrixType() <<
"\", rather that the required "
3778 localBannerReadSuccess = 0;
3779 }
else if (pBanner->dataType() ==
"pattern") {
3780 exMsg <<
"The Matrix Market file's banner (first) "
3781 "line claims that the matrix's data type is \"pattern\". This does "
3782 "not make sense for a dense matrix, yet the file reports the matrix "
3783 "as dense. The only valid data types for a dense matrix are "
3784 "\"real\", \"complex\", and \"integer\".";
3785 localBannerReadSuccess = 0;
3789 dims[2] = encodeDataType(pBanner->dataType());
3795 if (localBannerReadSuccess) {
3797 *err << myRank <<
": readVectorImpl: Reading dimensions line (dense)" << endl;
3806 bool commentLine =
true;
3808 while (commentLine) {
3811 if (in.eof() || in.fail()) {
3812 exMsg <<
"Unable to get array dimensions line (at all) from line "
3813 << lineNumber <<
" of input stream. The input stream "
3814 <<
"claims that it is "
3815 << (in.eof() ?
"at end-of-file." :
"in a failed state.");
3816 localDimsReadSuccess = 0;
3819 if (getline(in, line)) {
3826 size_t start = 0, size = 0;
3827 commentLine = checkCommentLine(line, start, size, lineNumber, tolerant);
3834 std::istringstream istr(line);
3838 if (istr.eof() || istr.fail()) {
3839 exMsg <<
"Unable to read any data from line " << lineNumber
3840 <<
" of input; the line should contain the matrix dimensions "
3841 <<
"\"<numRows> <numCols>\".";
3842 localDimsReadSuccess = 0;
3847 exMsg <<
"Failed to get number of rows from line "
3848 << lineNumber <<
" of input; the line should contains the "
3849 <<
"matrix dimensions \"<numRows> <numCols>\".";
3850 localDimsReadSuccess = 0;
3852 dims[0] = theNumRows;
3854 exMsg <<
"No more data after number of rows on line "
3855 << lineNumber <<
" of input; the line should contain the "
3856 <<
"matrix dimensions \"<numRows> <numCols>\".";
3857 localDimsReadSuccess = 0;
3862 exMsg <<
"Failed to get number of columns from line "
3863 << lineNumber <<
" of input; the line should contain "
3864 <<
"the matrix dimensions \"<numRows> <numCols>\".";
3865 localDimsReadSuccess = 0;
3867 dims[1] = theNumCols;
3877 exMsg <<
"File does not contain a 1D Vector";
3878 localDimsReadSuccess = 0;
3884 Tuple<GO, 5> bannerDimsReadResult;
3886 bannerDimsReadResult[0] = dims[0];
3887 bannerDimsReadResult[1] = dims[1];
3888 bannerDimsReadResult[2] = dims[2];
3889 bannerDimsReadResult[3] = localBannerReadSuccess;
3890 bannerDimsReadResult[4] = localDimsReadSuccess;
3895 broadcast(*comm, 0, bannerDimsReadResult);
3897 TEUCHOS_TEST_FOR_EXCEPTION(
3898 bannerDimsReadResult[3] == 0, std::runtime_error,
3899 "Failed to read banner line: " << exMsg.str());
3900 TEUCHOS_TEST_FOR_EXCEPTION(
3901 bannerDimsReadResult[4] == 0, std::runtime_error,
3902 "Failed to read matrix dimensions line: " << exMsg.str());
3904 dims[0] = bannerDimsReadResult[0];
3905 dims[1] = bannerDimsReadResult[1];
3906 dims[2] = bannerDimsReadResult[2];
3911 const size_t numCols =
static_cast<size_t>(dims[1]);
3916 RCP<const map_type> proc0Map;
3917 if (map.is_null()) {
3921 map = createUniformContigMapWithNode<LO, GO, NT>(numRows, comm);
3922 const size_t localNumRows = (myRank == 0) ? numRows : 0;
3924 proc0Map = createContigMapWithNode<LO, GO, NT>(numRows, localNumRows,
3927 proc0Map = Details::computeGatherMap<map_type>(map, err, debug);
3931 RCP<MV> X = createVector<ST, LO, GO, NT>(proc0Map);
3937 int localReadDataSuccess = 1;
3941 *err << myRank <<
": readVectorImpl: Reading matrix data (dense)"
3946 TEUCHOS_TEST_FOR_EXCEPTION(
3947 !X->isConstantStride(), std::logic_error,
3948 "Can't get a 1-D view of the entries of the MultiVector X on "
3949 "Process 0, because the stride between the columns of X is not "
3950 "constant. This shouldn't happen because we just created X and "
3951 "haven't filled it in yet. Please report this bug to the Tpetra "
3958 Teuchos::ArrayRCP<ST> X_view = X->get1dViewNonConst();
3959 TEUCHOS_TEST_FOR_EXCEPTION(
3960 as<global_size_t>(X_view.size()) < numRows * numCols,
3962 "The view of X has size " << X_view <<
" which is not enough to "
3963 "accommodate the expected number of entries numRows*numCols = "
3964 << numRows <<
"*" << numCols <<
" = " << numRows * numCols <<
". "
3965 "Please report this bug to the Tpetra developers.");
3966 const size_t stride = X->getStride();
3973 const bool isComplex = (dims[2] == 1);
3974 size_type count = 0, curRow = 0, curCol = 0;
3977 while (getline(in, line)) {
3981 size_t start = 0, size = 0;
3982 const bool commentLine =
3983 checkCommentLine(line, start, size, lineNumber, tolerant);
3990 if (count >= X_view.size()) {
3994 TEUCHOS_TEST_FOR_EXCEPTION(
3995 count >= X_view.size(),
3997 "The Matrix Market input stream has more data in it than "
3998 "its metadata reported. Current line number is "
3999 << lineNumber <<
".");
4008 const size_t pos = line.substr(start, size).find(
':');
4009 if (pos != std::string::npos) {
4013 std::istringstream istr(line.substr(start, size));
4017 if (istr.eof() || istr.fail()) {
4024 TEUCHOS_TEST_FOR_EXCEPTION(
4025 !tolerant && (istr.eof() || istr.fail()),
4027 "Line " << lineNumber <<
" of the Matrix Market file is "
4028 "empty, or we cannot read from it for some other reason.");
4031 ST val = STS::zero();
4034 MT real = STM::zero(), imag = STM::zero();
4051 TEUCHOS_TEST_FOR_EXCEPTION(
4052 !tolerant && istr.eof(), std::runtime_error,
4053 "Failed to get the real part of a complex-valued matrix "
4055 << lineNumber <<
" of the Matrix Market "
4061 }
else if (istr.eof()) {
4062 TEUCHOS_TEST_FOR_EXCEPTION(
4063 !tolerant && istr.eof(), std::runtime_error,
4064 "Missing imaginary part of a complex-valued matrix entry "
4066 << lineNumber <<
" of the Matrix Market file.");
4072 TEUCHOS_TEST_FOR_EXCEPTION(
4073 !tolerant && istr.fail(), std::runtime_error,
4074 "Failed to get the imaginary part of a complex-valued "
4075 "matrix entry from line "
4076 << lineNumber <<
" of the "
4077 "Matrix Market file.");
4084 TEUCHOS_TEST_FOR_EXCEPTION(
4085 !tolerant && istr.fail(), std::runtime_error,
4086 "Failed to get a real-valued matrix entry from line "
4087 << lineNumber <<
" of the Matrix Market file.");
4090 if (istr.fail() && tolerant) {
4096 TEUCHOS_TEST_FOR_EXCEPTION(
4097 !tolerant && istr.fail(), std::runtime_error,
4098 "Failed to read matrix data from line " << lineNumber
4099 <<
" of the Matrix Market file.");
4102 Teuchos::MatrixMarket::details::assignScalar<ST>(val, real, imag);
4104 curRow = count % numRows;
4105 curCol = count / numRows;
4106 X_view[curRow + curCol * stride] = val;
4111 TEUCHOS_TEST_FOR_EXCEPTION(
4112 !tolerant &&
static_cast<global_size_t>(count) < numRows * numCols,
4114 "The Matrix Market metadata reports that the dense matrix is "
4115 << numRows <<
" x " << numCols <<
", and thus has "
4116 << numRows * numCols <<
" total entries, but we only found " << count
4117 <<
" entr" << (count == 1 ?
"y" :
"ies") <<
" in the file.");
4118 }
catch (std::exception& e) {
4120 localReadDataSuccess = 0;
4125 *err << myRank <<
": readVectorImpl: done reading data" << endl;
4129 int globalReadDataSuccess = localReadDataSuccess;
4130 broadcast(*comm, 0, outArg(globalReadDataSuccess));
4131 TEUCHOS_TEST_FOR_EXCEPTION(
4132 globalReadDataSuccess == 0, std::runtime_error,
4133 "Failed to read the multivector's data: " << exMsg.str());
4138 if (comm->getSize() == 1 && map.is_null()) {
4140 if (!err.is_null()) {
4144 *err << myRank <<
": readVectorImpl: done" << endl;
4146 if (!err.is_null()) {
4153 *err << myRank <<
": readVectorImpl: Creating target MV" << endl;
4157 RCP<MV> Y = createVector<ST, LO, GO, NT>(map);
4160 *err << myRank <<
": readVectorImpl: Creating Export" << endl;
4166 Export<LO, GO, NT> exporter(proc0Map, map, err);
4169 *err << myRank <<
": readVectorImpl: Exporting" << endl;
4172 Y->doExport(*X, exporter,
INSERT);
4174 if (!err.is_null()) {
4178 *err << myRank <<
": readVectorImpl: done" << endl;
4180 if (!err.is_null()) {
4188template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4189Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
4192 const bool tolerant,
4194 const bool binary) {
4195 Teuchos::RCP<Teuchos::FancyOStream> err =
4196 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
4197 return readMap(in, comm, err, tolerant, debug, binary);
4200template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4201Teuchos::RCP<const typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::map_type>
4204 const Teuchos::RCP<Teuchos::FancyOStream>& err,
4205 const bool tolerant,
4207 const bool binary) {
4209 using Teuchos::arcp;
4210 using Teuchos::Array;
4211 using Teuchos::ArrayRCP;
4213 using Teuchos::broadcast;
4214 using Teuchos::Comm;
4215 using Teuchos::CommRequest;
4216 using Teuchos::inOutArg;
4217 using Teuchos::ireceive;
4218 using Teuchos::isend;
4219 using Teuchos::outArg;
4221 using Teuchos::receive;
4222 using Teuchos::REDUCE_MIN;
4223 using Teuchos::reduceAll;
4224 using Teuchos::SerialComm;
4225 using Teuchos::toString;
4226 using Teuchos::wait;
4228 typedef ptrdiff_t int_type;
4230 typedef global_ordinal_type GO;
4231 typedef node_type NT;
4234 const int numProcs = comm->getSize();
4235 const int myRank = comm->getRank();
4237 if (!err.is_null()) {
4241 std::ostringstream os;
4242 os << myRank <<
": readMap: " << endl;
4245 if (!err.is_null()) {
4251 const int sizeTag = 1339;
4253 const int dataTag = 1340;
4259 RCP<CommRequest<int>> sizeReq;
4260 RCP<CommRequest<int>> dataReq;
4265 ArrayRCP<int_type> numGidsToRecv(1);
4266 numGidsToRecv[0] = 0;
4268 sizeReq = ireceive<int, int_type>(numGidsToRecv, 0, sizeTag, *comm);
4271 int readSuccess = 1;
4272 std::ostringstream exMsg;
4281 RCP<const Comm<int>> proc0Comm(
new SerialComm<int>());
4283 RCP<const map_type> dataMap;
4287 data = readDenseImpl<GO>(in, proc0Comm, dataMap, err, tolerant, debug, binary);
4289 if (data.is_null()) {
4291 exMsg <<
"readDenseImpl() returned null." << endl;
4293 }
catch (std::exception& e) {
4295 exMsg << e.what() << endl;
4301 std::map<int, Array<GO>> pid2gids;
4306 int_type globalNumGIDs = 0;
4316 if (myRank == 0 && readSuccess == 1) {
4317 if (data->getNumVectors() == 2) {
4318 ArrayRCP<const GO> GIDs = data->getData(0);
4319 ArrayRCP<const GO> PIDs = data->getData(1);
4320 globalNumGIDs = GIDs.size();
4324 if (globalNumGIDs > 0) {
4325 const int pid =
static_cast<int>(PIDs[0]);
4327 if (pid < 0 || pid >= numProcs) {
4329 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4330 <<
"Encountered invalid PID " << pid <<
"." << endl;
4332 const GO gid = GIDs[0];
4333 pid2gids[pid].push_back(gid);
4337 if (readSuccess == 1) {
4340 for (size_type k = 1; k < globalNumGIDs; ++k) {
4341 const int pid =
static_cast<int>(PIDs[k]);
4342 if (pid < 0 || pid >= numProcs) {
4344 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4345 <<
"Encountered invalid PID " << pid <<
"." << endl;
4347 const int_type gid = GIDs[k];
4348 pid2gids[pid].push_back(gid);
4349 if (gid < indexBase) {
4355 }
else if (data->getNumVectors() == 1) {
4356 if (data->getGlobalLength() % 2 !=
static_cast<GST
>(0)) {
4358 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data has the "
4359 "wrong format (for Map format 2.0). The global number of rows "
4360 "in the MultiVector must be even (divisible by 2)."
4363 ArrayRCP<const GO> theData = data->getData(0);
4364 globalNumGIDs =
static_cast<GO
>(data->getGlobalLength()) /
4369 if (globalNumGIDs > 0) {
4370 const int pid =
static_cast<int>(theData[1]);
4371 if (pid < 0 || pid >= numProcs) {
4373 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4374 <<
"Encountered invalid PID " << pid <<
"." << endl;
4376 const GO gid = theData[0];
4377 pid2gids[pid].push_back(gid);
4383 for (int_type k = 1; k < globalNumGIDs; ++k) {
4384 const int pid =
static_cast<int>(theData[2 * k + 1]);
4385 if (pid < 0 || pid >= numProcs) {
4387 exMsg <<
"Tpetra::MatrixMarket::readMap: "
4388 <<
"Encountered invalid PID " << pid <<
"." << endl;
4390 const GO gid = theData[2 * k];
4391 pid2gids[pid].push_back(gid);
4392 if (gid < indexBase) {
4400 exMsg <<
"Tpetra::MatrixMarket::readMap: Input data must have "
4401 "either 1 column (for the new Map format 2.0) or 2 columns (for "
4402 "the old Map format 1.0).";
4409 int_type readResults[3];
4410 readResults[0] =
static_cast<int_type
>(indexBase);
4411 readResults[1] =
static_cast<int_type
>(globalNumGIDs);
4412 readResults[2] =
static_cast<int_type
>(readSuccess);
4413 broadcast<int, int_type>(*comm, 0, 3, readResults);
4415 indexBase =
static_cast<GO
>(readResults[0]);
4416 globalNumGIDs =
static_cast<int_type
>(readResults[1]);
4417 readSuccess =
static_cast<int>(readResults[2]);
4423 TEUCHOS_TEST_FOR_EXCEPTION(
4424 readSuccess != 1, std::runtime_error,
4425 "Tpetra::MatrixMarket::readMap: Reading the Map failed with the "
4426 "following exception message: "
4431 for (
int p = 1; p < numProcs; ++p) {
4432 ArrayRCP<int_type> numGidsToSend(1);
4434 auto it = pid2gids.find(p);
4435 if (it == pid2gids.end()) {
4436 numGidsToSend[0] = 0;
4438 numGidsToSend[0] = it->second.size();
4440 sizeReq = isend<int, int_type>(numGidsToSend, p, sizeTag, *comm);
4441 wait<int>(*comm, outArg(sizeReq));
4445 wait<int>(*comm, outArg(sizeReq));
4450 ArrayRCP<GO> myGids;
4451 int_type myNumGids = 0;
4453 GO* myGidsRaw = NULL;
4455 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(0);
4456 if (it != pid2gids.end()) {
4457 myGidsRaw = it->second.getRawPtr();
4458 myNumGids = it->second.size();
4460 myGids = arcp<GO>(myGidsRaw, 0, myNumGids,
false);
4463 myNumGids = numGidsToRecv[0];
4464 myGids = arcp<GO>(myNumGids);
4471 if (myNumGids > 0) {
4472 dataReq = ireceive<int, GO>(myGids, 0, dataTag, *comm);
4476 for (
int p = 1; p < numProcs; ++p) {
4478 ArrayRCP<GO> sendGids;
4479 GO* sendGidsRaw = NULL;
4480 int_type numSendGids = 0;
4482 typename std::map<int, Array<GO>>::iterator it = pid2gids.find(p);
4483 if (it != pid2gids.end()) {
4484 numSendGids = it->second.size();
4485 sendGidsRaw = it->second.getRawPtr();
4486 sendGids = arcp<GO>(sendGidsRaw, 0, numSendGids,
false);
4489 if (numSendGids > 0) {
4490 dataReq = isend<int, GO>(sendGids, p, dataTag, *comm);
4492 wait<int>(*comm, outArg(dataReq));
4493 }
else if (myRank == p) {
4495 wait<int>(*comm, outArg(dataReq));
4500 std::ostringstream os;
4501 os << myRank <<
": readMap: creating Map" << endl;
4504 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid();
4505 RCP<const map_type> newMap;
4512 std::ostringstream errStrm;
4514 newMap = rcp(
new map_type(INVALID, myGids(), indexBase, comm));
4515 }
catch (std::exception& e) {
4517 errStrm <<
"Process " << comm->getRank() <<
" threw an exception: "
4518 << e.what() << std::endl;
4521 errStrm <<
"Process " << comm->getRank() <<
" threw an exception "
4522 "not a subclass of std::exception"
4525 Teuchos::reduceAll<int, int>(*comm, Teuchos::REDUCE_MIN,
4526 lclSuccess, Teuchos::outArg(gblSuccess));
4527 if (gblSuccess != 1) {
4530 TEUCHOS_TEST_FOR_EXCEPTION(gblSuccess != 1, std::runtime_error,
"Map constructor failed!");
4532 if (!err.is_null()) {
4536 std::ostringstream os;
4537 os << myRank <<
": readMap: done" << endl;
4540 if (!err.is_null()) {
4546template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4547int MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::encodeDataType(
const std::string& dataType) {
4548 if (dataType ==
"real" || dataType ==
"integer") {
4550 }
else if (dataType ==
"complex") {
4552 }
else if (dataType ==
"pattern") {
4558 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
4559 "Unrecognized Matrix Market data type \"" << dataType
4560 <<
"\". We should never get here. "
4561 "Please report this bug to the Tpetra developers.");
4565template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4566Teuchos::RCP<typename MatrixMarketReader<Scalar, LocalOrdinal, GlobalOrdinal, Node>::sparse_matrix_type>
4580 using STS =
typename Teuchos::ScalarTraits<ST>;
4581 using Teuchos::arcp;
4582 using Teuchos::ArrayRCP;
4591 rowMap.is_null(), std::invalid_argument,
4592 "Row Map must be nonnull.");
4593 Teuchos::RCP<const Teuchos::Comm<int>> comm =
rowMap->getComm();
4595 "The input row map's communicator (Teuchos::Comm object) is null.");
4597 rangeMap.is_null(), std::invalid_argument,
4598 "Range Map must be nonnull.");
4600 domainMap.is_null(), std::invalid_argument,
4601 "Domain Map must be nonnull.");
4603 domainMap->getComm().getRawPtr() != comm.getRawPtr(),
4604 std::invalid_argument,
4605 "The specified domain Map's communicator (domainMap->getComm())"
4606 "differs from row Map's communicator");
4608 rangeMap->getComm().getRawPtr() != comm.getRawPtr(),
4609 std::invalid_argument,
4610 "The specified range Map's communicator (rangeMap->getComm())"
4611 "differs from row Map's communicator");
4614 const int myRank = comm->getRank();
4615 const int numProc = comm->getSize();
4626 std::ostringstream
errMsg;
4640 if (
base_rank <= myRank && myRank < stop) {
4643 using Teuchos::MatrixMarket::Banner;
4648 }
catch (std::exception&
e) {
4649 errMsg <<
"Attempt to read the Matrix Market file's Banner line "
4650 "threw an exception: "
4661 errMsg <<
"The Matrix Market input file must contain a "
4662 "\"coordinate\"-format sparse matrix in order to create a "
4663 "Tpetra::CrsMatrix object from it, but the file's matrix "
4665 <<
pBanner->matrixType() <<
"\" instead.";
4672 errMsg <<
"Matrix Market file must contain a \"coordinate\"-"
4673 "format sparse matrix in order to create a Tpetra::CrsMatrix "
4674 "object from it, but the file's matrix type is \"array\" "
4675 "instead. That probably means the file contains dense matrix "
4681 using Teuchos::MatrixMarket::readCoordinateDimensions;
4688 "# rows in file does not match rowmap.");
4690 "# rows in file does not match colmap.");
4693 typedef Teuchos::MatrixMarket::Raw::Adder<scalar_type, global_ordinal_type>
raw_adder_type;
4695 Teuchos::RCP<raw_adder_type>
pRaw =
4700 std::cerr <<
"-- Reading matrix data" << std::endl;
4705 typedef Teuchos::MatrixMarket::CoordDataReader<adder_type,
4714 }
catch (std::exception&
e) {
4721 typedef Teuchos::MatrixMarket::Raw::Element<scalar_type, global_ordinal_type>
element_type;
4724 pAdder->getAdder()->merge();
4727 const std::vector<element_type>& entries =
pAdder->getAdder()->getEntries();
4730 const size_t numEntries = (
size_t)entries.size();
4733 std::cerr <<
"----- Proc " << myRank <<
": Matrix has numRows=" <<
numRows
4734 <<
" rows and numEntries=" << numEntries
4735 <<
" entries." << std::endl;
4752 LO
INVALID = Teuchos::OrdinalTraits<LO>::invalid();
4761 "Current global row " <<
curRow <<
" is invalid.");
4764 "Row indices are out of order, even though they are supposed "
4765 "to be sorted. curRow = "
4768 "this bug to the Tpetra developers.");
4795 for (
size_t i = 0;
i <
rowMap->getLocalNumElements();
i++) {
4804 throw std::runtime_error(
"Reading with a column map is not yet implemented");
4819template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4827 "The input matrix's communicator (Teuchos::Comm object) is null.");
4828 const int myRank = comm->getRank();
4830 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm,
filename, myRank,
true);
4838template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4840 const Teuchos::RCP<const sparse_matrix_type>&
pMatrix,
4845 "The input matrix is null.");
4850template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4857template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4859 const Teuchos::RCP<const sparse_matrix_type>&
pMatrix,
4864template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
4872 using Teuchos::ArrayView;
4873 using Teuchos::Comm;
4874 using Teuchos::FancyOStream;
4875 using Teuchos::getFancyOStream;
4876 using Teuchos::null;
4878 using Teuchos::rcpFromRef;
4882 using STS =
typename Teuchos::ScalarTraits<ST>;
4888 Teuchos::SetScientific<ST>
sci(
out);
4893 comm.is_null(), std::invalid_argument,
4894 "The input matrix's communicator (Teuchos::Comm object) is null.");
4895 const int myRank = comm->getRank();
4901 std::ostringstream
os;
4902 os << myRank <<
": writeSparse" <<
endl;
4905 os <<
"-- " << myRank <<
": past barrier" <<
endl;
4910 const bool debugPrint = debug && myRank == 0;
4917 if (!
rowMap->haveGlobalConstants())
4918 Teuchos::rcp_const_cast<map_type>(
rowMap)->computeGlobalConstants();
4919 if (!
colMap->haveGlobalConstants())
4920 Teuchos::rcp_const_cast<map_type>(
colMap)->computeGlobalConstants();
4922 Teuchos::rcp_const_cast<map_type>(
domainMap)->computeGlobalConstants();
4923 if (!
rangeMap->haveGlobalConstants())
4924 Teuchos::rcp_const_cast<map_type>(
rangeMap)->computeGlobalConstants();
4929 if (debug && myRank == 0) {
4930 std::ostringstream
os;
4931 os <<
"-- Input sparse matrix is:"
4934 << (
matrix.isGloballyIndexed() ?
"Globally" :
"Locally")
4935 <<
" indexed." <<
endl
4936 <<
"---- Its row map has " <<
rowMap->getGlobalNumElements()
4937 <<
" elements." <<
endl
4938 <<
"---- Its col map has " <<
colMap->getGlobalNumElements()
4939 <<
" elements." <<
endl;
4946 std::ostringstream
os;
4947 os <<
"-- " << myRank <<
": making gatherRowMap" <<
endl;
4951 Details::computeGatherMap(
rowMap,
err, debug);
4959 const size_t localNumCols = (myRank == 0) ? numCols : 0;
4961 Details::computeGatherMap(
colMap,
err, debug);
4972 static_cast<size_t>(0)));
4991 cerr <<
"-- Output sparse matrix is:"
4992 <<
"---- " <<
newMatrix->getRangeMap()->getGlobalNumElements()
4994 <<
newMatrix->getDomainMap()->getGlobalNumElements()
4998 << (
newMatrix->isGloballyIndexed() ?
"Globally" :
"Locally")
4999 <<
" indexed." <<
endl
5000 <<
"---- Its row map has "
5001 <<
newMatrix->getRowMap()->getGlobalNumElements()
5002 <<
" elements, with index base "
5004 <<
"---- Its col map has "
5005 <<
newMatrix->getColMap()->getGlobalNumElements()
5006 <<
" elements, with index base "
5008 <<
"---- Element count of output matrix's column Map may differ "
5009 <<
"from that of the input matrix's column Map, if some columns "
5010 <<
"of the matrix contain no entries." <<
endl;
5023 out <<
"%%MatrixMarket matrix coordinate "
5024 << (STS::isComplex ?
"complex" :
"real")
5025 <<
" general" <<
endl;
5042 out <<
newMatrix->getRangeMap()->getMaxAllGlobalIndex() + 1 -
newMatrix->getRangeMap()->getIndexBase() <<
" "
5043 <<
newMatrix->getDomainMap()->getMaxAllGlobalIndex() + 1 -
newMatrix->getDomainMap()->getIndexBase() <<
" "
5066 typename sparse_matrix_type::global_inds_host_view_type
ind;
5067 typename sparse_matrix_type::values_host_view_type
val;
5069 for (
size_t ii = 0;
ii <
ind.extent(0);
ii++) {
5075 if (STS::isComplex) {
5084 using OTG = Teuchos::OrdinalTraits<GO>;
5093 "Failed to convert the supposed local row index "
5095 "Please report this bug to the Tpetra developers.");
5096 typename sparse_matrix_type::local_inds_host_view_type
ind;
5097 typename sparse_matrix_type::values_host_view_type
val;
5099 for (
size_t ii = 0;
ii <
ind.extent(0);
ii++) {
5105 "On local row " <<
localRowIndex <<
" of the sparse matrix: "
5106 "Failed to convert the supposed local column index "
5107 <<
ind(
ii) <<
" into a global column index. Please report "
5108 "this bug to the Tpetra developers.");
5113 if (STS::isComplex) {
5125template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5127 const Teuchos::RCP<const sparse_matrix_type>&
pMatrix,
5132 "The input matrix is null.");
5136template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5144 using Teuchos::ArrayView;
5145 using Teuchos::Comm;
5146 using Teuchos::FancyOStream;
5147 using Teuchos::getFancyOStream;
5148 using Teuchos::null;
5150 using Teuchos::rcpFromRef;
5162 auto comm =
rowMap->getComm();
5163 if (comm.is_null()) {
5166 const int myRank = comm->getRank();
5172 std::ostringstream
os;
5173 os << myRank <<
": writeSparseGraph" <<
endl;
5176 os <<
"-- " << myRank <<
": past barrier" <<
endl;
5181 const bool debugPrint = debug && myRank == 0;
5188 if (!
rowMap->haveGlobalConstants())
5189 Teuchos::rcp_const_cast<map_type>(
rowMap)->computeGlobalConstants();
5190 if (!
colMap->haveGlobalConstants())
5191 Teuchos::rcp_const_cast<map_type>(
colMap)->computeGlobalConstants();
5193 Teuchos::rcp_const_cast<map_type>(
domainMap)->computeGlobalConstants();
5194 if (!
rangeMap->haveGlobalConstants())
5195 Teuchos::rcp_const_cast<map_type>(
rangeMap)->computeGlobalConstants();
5200 if (debug && myRank == 0) {
5201 std::ostringstream
os;
5202 os <<
"-- Input sparse graph is:"
5203 <<
"---- " <<
numRows <<
" x " << numCols <<
" with "
5204 <<
graph.getGlobalNumEntries() <<
" entries;" <<
endl
5206 << (
graph.isGloballyIndexed() ?
"Globally" :
"Locally")
5207 <<
" indexed." <<
endl
5208 <<
"---- Its row Map has " <<
rowMap->getGlobalNumElements()
5209 <<
" elements." <<
endl
5210 <<
"---- Its col Map has " <<
colMap->getGlobalNumElements()
5211 <<
" elements." <<
endl;
5218 std::ostringstream
os;
5219 os <<
"-- " << myRank <<
": making gatherRowMap" <<
endl;
5230 const size_t localNumCols = (myRank == 0) ? numCols : 0;
5240 static_cast<size_t>(0));
5259 cerr <<
"-- Output sparse graph is:"
5260 <<
"---- " <<
newGraph.getRangeMap()->getGlobalNumElements()
5262 <<
newGraph.getDomainMap()->getGlobalNumElements()
5264 <<
newGraph.getGlobalNumEntries() <<
" entries;" <<
endl
5266 << (
newGraph.isGloballyIndexed() ?
"Globally" :
"Locally")
5267 <<
" indexed." <<
endl
5268 <<
"---- Its row map has "
5269 <<
newGraph.getRowMap()->getGlobalNumElements()
5270 <<
" elements, with index base "
5272 <<
"---- Its col map has "
5273 <<
newGraph.getColMap()->getGlobalNumElements()
5274 <<
" elements, with index base "
5276 <<
"---- Element count of output graph's column Map may differ "
5277 <<
"from that of the input matrix's column Map, if some columns "
5278 <<
"of the matrix contain no entries." <<
endl;
5292 out <<
"%%MatrixMarket matrix coordinate pattern general" <<
endl;
5310 out <<
newGraph.getRangeMap()->getMaxAllGlobalIndex() + 1 -
newGraph.getRangeMap()->getIndexBase() <<
" "
5311 <<
newGraph.getDomainMap()->getMaxAllGlobalIndex() + 1 -
newGraph.getDomainMap()->getIndexBase() <<
" "
5326 if (
newGraph.isGloballyIndexed()) {
5334 typename crs_graph_type::global_inds_host_view_type
ind;
5336 for (
size_t ii = 0;
ii <
ind.extent(0);
ii++) {
5346 typedef Teuchos::OrdinalTraits<GO>
OTG;
5355 "to convert the supposed local row index "
5356 <<
localRowIndex <<
" into a global row index. Please report this bug to the "
5357 "Tpetra developers.");
5358 typename crs_graph_type::local_inds_host_view_type
ind;
5360 for (
size_t ii = 0;
ii <
ind.extent(0);
ii++) {
5366 "On local row " <<
localRowIndex <<
" of the sparse graph: "
5367 "Failed to convert the supposed local column index "
5368 <<
ind(
ii) <<
" into a global column index. Please report "
5369 "this bug to the Tpetra developers.");
5381template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5385 writeSparseGraph(
out,
graph,
"",
"", debug);
5388template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5394 auto comm =
graph.getComm();
5395 if (comm.is_null()) {
5403 const int myRank = comm->getRank();
5405 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm,
filename, myRank,
true);
5413template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5420template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5422 const Teuchos::RCP<const crs_graph_type>&
pGraph,
5429template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5431 const Teuchos::RCP<const crs_graph_type>&
pGraph,
5436template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5440 writeSparse(
out,
matrix,
"",
"", debug);
5443template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5445 const Teuchos::RCP<const sparse_matrix_type>&
pMatrix,
5450template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5455 const Teuchos::RCP<Teuchos::FancyOStream>&
err,
5456 const Teuchos::RCP<Teuchos::FancyOStream>&
dbg) {
5460 auto out = MatrixMarketWriter::openOutFileOnRankZero(comm,
filename, myRank,
true);
5468template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5471 const std::string& matrixName,
5472 const std::string& matrixDescription,
5473 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5474 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5475 TEUCHOS_TEST_FOR_EXCEPTION(
5476 X.is_null(), std::invalid_argument,
5477 "Tpetra::MatrixMarket::"
5478 "writeDenseFile: The input MultiVector X is null.");
5479 writeDenseFile(filename, *X, matrixName, matrixDescription, err, dbg);
5482template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5485 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5486 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5487 writeDenseFile(filename, X,
"",
"", err, dbg);
5490template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5493 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5494 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5495 TEUCHOS_TEST_FOR_EXCEPTION(
5496 X.is_null(), std::invalid_argument,
5497 "Tpetra::MatrixMarket::"
5498 "writeDenseFile: The input MultiVector X is null.");
5499 writeDenseFile(filename, *X, err, dbg);
5502template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5507 const Teuchos::RCP<Teuchos::FancyOStream>&
err,
5508 const Teuchos::RCP<Teuchos::FancyOStream>&
dbg) {
5510 using Teuchos::Comm;
5511 using Teuchos::outArg;
5512 using Teuchos::REDUCE_MAX;
5513 using Teuchos::reduceAll;
5521 const bool debug = !
dbg.is_null();
5524 std::ostringstream
os;
5525 os << myRank <<
": writeDense" <<
endl;
5534 const size_t numVecs =
X.getNumVectors();
5536 writeDenseColumn(
out, *(
X.getVector(
j)),
err,
dbg);
5541 std::ostringstream
os;
5542 os << myRank <<
": writeDense: Done" <<
endl;
5548template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5550 const trcp_tcomm_t& comm,
5552 const std::ios_base::openmode
mode) {
5566 if (comm) Teuchos::broadcast(*comm, 0, &all_should_stop);
5568 TEUCHOS_TEST_FOR_EXCEPTION(
5571 "Could not open output file '" + filename +
"' on root rank 0.");
5576template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5577void MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeDenseHeader(std::ostream& out,
5579 const std::string& matrixName,
5580 const std::string& matrixDescription,
5581 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5582 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5584 using Teuchos::Comm;
5585 using Teuchos::outArg;
5587 using Teuchos::REDUCE_MAX;
5588 using Teuchos::reduceAll;
5589 typedef Teuchos::ScalarTraits<scalar_type> STS;
5590 const char prefix[] =
"Tpetra::MatrixMarket::writeDenseHeader: ";
5600 const bool debug = !dbg.is_null();
5604 std::ostringstream os;
5605 os << myRank <<
": writeDenseHeader" << endl;
5624 std::ostringstream hdr;
5626 std::string dataType;
5627 if (STS::isComplex) {
5628 dataType =
"complex";
5629 }
else if (STS::isOrdinal) {
5630 dataType =
"integer";
5634 hdr <<
"%%MatrixMarket matrix array " << dataType <<
" general"
5639 if (matrixName !=
"") {
5640 printAsComment(hdr, matrixName);
5642 if (matrixDescription !=
"") {
5643 printAsComment(hdr, matrixDescription);
5646 hdr << X.getGlobalLength() <<
" " << X.getNumVectors() << endl;
5650 }
catch (std::exception& e) {
5651 if (!err.is_null()) {
5652 *err << prefix <<
"While writing the Matrix Market header, "
5653 "Process 0 threw an exception: "
5654 << e.what() << endl;
5663 reduceAll<int, int>(*comm, REDUCE_MAX, lclErr, outArg(gblErr));
5664 TEUCHOS_TEST_FOR_EXCEPTION(
5665 gblErr == 1, std::runtime_error, prefix <<
"Some error occurred "
5666 "which prevented this method from completing.");
5670 *dbg << myRank <<
": writeDenseHeader: Done" << endl;
5675template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
5676void MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeDenseColumn(std::ostream& out,
5678 const Teuchos::RCP<Teuchos::FancyOStream>& err,
5679 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
5681 using Teuchos::arcp;
5682 using Teuchos::Array;
5683 using Teuchos::ArrayRCP;
5684 using Teuchos::ArrayView;
5685 using Teuchos::Comm;
5686 using Teuchos::CommRequest;
5687 using Teuchos::ireceive;
5688 using Teuchos::isend;
5689 using Teuchos::outArg;
5691 using Teuchos::REDUCE_MAX;
5692 using Teuchos::reduceAll;
5693 using Teuchos::TypeNameTraits;
5694 using Teuchos::wait;
5695 typedef Teuchos::ScalarTraits<scalar_type> STS;
5697 const Comm<int>& comm = *(X.getMap()->getComm());
5698 const int myRank = comm.getRank();
5699 const int numProcs = comm.getSize();
5706 const bool debug = !dbg.is_null();
5710 std::ostringstream os;
5711 os << myRank <<
": writeDenseColumn" << endl;
5720 Teuchos::SetScientific<scalar_type> sci(out);
5722 const size_t myNumRows = X.getLocalLength();
5723 const size_t numCols = X.getNumVectors();
5726 const int sizeTag = 1337;
5727 const int dataTag = 1338;
5788 RCP<CommRequest<int>> sendReqSize, sendReqData;
5794 Array<ArrayRCP<size_t>> recvSizeBufs(3);
5795 Array<ArrayRCP<scalar_type>> recvDataBufs(3);
5796 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
5797 Array<RCP<CommRequest<int>>> recvDataReqs(3);
5800 ArrayRCP<size_t> sendDataSize(1);
5801 sendDataSize[0] = myNumRows;
5805 std::ostringstream os;
5806 os << myRank <<
": Post receive-size receives from "
5807 "Procs 1 and 2: tag = "
5812 recvSizeBufs[0].resize(1);
5816 (recvSizeBufs[0])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5817 recvSizeBufs[1].resize(1);
5818 (recvSizeBufs[1])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5819 recvSizeBufs[2].resize(1);
5820 (recvSizeBufs[2])[0] = Teuchos::OrdinalTraits<size_t>::invalid();
5823 ireceive<int, size_t>(recvSizeBufs[1], 1, sizeTag, comm);
5827 ireceive<int, size_t>(recvSizeBufs[2], 2, sizeTag, comm);
5829 }
else if (myRank == 1 || myRank == 2) {
5831 std::ostringstream os;
5832 os << myRank <<
": Post send-size send: size = "
5833 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
5840 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
5843 std::ostringstream os;
5844 os << myRank <<
": Not posting my send-size send yet" << endl;
5853 std::ostringstream os;
5854 os << myRank <<
": Pack my entries" << endl;
5857 ArrayRCP<scalar_type> sendDataBuf;
5859 sendDataBuf = arcp<scalar_type>(myNumRows * numCols);
5860 X.get1dCopy(sendDataBuf(), myNumRows);
5861 }
catch (std::exception& e) {
5863 if (!err.is_null()) {
5864 std::ostringstream os;
5865 os <<
"Process " << myRank <<
": Attempt to pack my MultiVector "
5866 "entries threw an exception: "
5867 << e.what() << endl;
5872 std::ostringstream os;
5873 os << myRank <<
": Done packing my entries" << endl;
5882 *dbg << myRank <<
": Post send-data send: tag = " << dataTag
5885 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
5893 std::ostringstream os;
5894 os << myRank <<
": Write my entries" << endl;
5900 const size_t printNumRows = myNumRows;
5901 ArrayView<const scalar_type> printData = sendDataBuf();
5902 const size_t printStride = printNumRows;
5903 if (
static_cast<size_t>(printData.size()) < printStride * numCols) {
5905 if (!err.is_null()) {
5906 std::ostringstream os;
5907 os <<
"Process " << myRank <<
": My MultiVector data's size "
5908 << printData.size() <<
" does not match my local dimensions "
5909 << printStride <<
" x " << numCols <<
"." << endl;
5916 for (
size_t col = 0; col < numCols; ++col) {
5917 for (
size_t row = 0; row < printNumRows; ++row) {
5918 if (STS::isComplex) {
5919 out << STS::real(printData[row + col * printStride]) <<
" "
5920 << STS::imag(printData[row + col * printStride]) << endl;
5922 out << printData[row + col * printStride] << endl;
5931 const int recvRank = 1;
5932 const int circBufInd = recvRank % 3;
5934 std::ostringstream os;
5935 os << myRank <<
": Wait on receive-size receive from Process "
5936 << recvRank << endl;
5940 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
5944 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
5945 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
5947 if (!err.is_null()) {
5948 std::ostringstream os;
5949 os << myRank <<
": Result of receive-size receive from Process "
5950 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
5951 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
5952 "This should never happen, and suggests that the receive never "
5953 "got posted. Please report this bug to the Tpetra developers."
5968 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
5970 std::ostringstream os;
5971 os << myRank <<
": Post receive-data receive from Process "
5972 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
5973 << recvDataBufs[circBufInd].size() << endl;
5976 if (!recvSizeReqs[circBufInd].is_null()) {
5978 if (!err.is_null()) {
5979 std::ostringstream os;
5980 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
5981 "null, before posting the receive-data receive from Process "
5982 << recvRank <<
". This should never happen. Please report "
5983 "this bug to the Tpetra developers."
5988 recvDataReqs[circBufInd] =
5989 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
5990 recvRank, dataTag, comm);
5992 }
else if (myRank == 1) {
5995 std::ostringstream os;
5996 os << myRank <<
": Wait on my send-size send" << endl;
5999 wait<int>(comm, outArg(sendReqSize));
6005 for (
int p = 1; p < numProcs; ++p) {
6007 if (p + 2 < numProcs) {
6009 const int recvRank = p + 2;
6010 const int circBufInd = recvRank % 3;
6012 std::ostringstream os;
6013 os << myRank <<
": Post receive-size receive from Process "
6014 << recvRank <<
": tag = " << sizeTag << endl;
6017 if (!recvSizeReqs[circBufInd].is_null()) {
6019 if (!err.is_null()) {
6020 std::ostringstream os;
6021 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6022 <<
"null, for the receive-size receive from Process "
6023 << recvRank <<
"! This may mean that this process never "
6024 <<
"finished waiting for the receive from Process "
6025 << (recvRank - 3) <<
"." << endl;
6029 recvSizeReqs[circBufInd] =
6030 ireceive<int, size_t>(recvSizeBufs[circBufInd],
6031 recvRank, sizeTag, comm);
6034 if (p + 1 < numProcs) {
6035 const int recvRank = p + 1;
6036 const int circBufInd = recvRank % 3;
6040 std::ostringstream os;
6041 os << myRank <<
": Wait on receive-size receive from Process "
6042 << recvRank << endl;
6045 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6049 size_t recvNumRows = (recvSizeBufs[circBufInd])[0];
6050 if (recvNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
6052 if (!err.is_null()) {
6053 std::ostringstream os;
6054 os << myRank <<
": Result of receive-size receive from Process "
6055 << recvRank <<
" is Teuchos::OrdinalTraits<size_t>::invalid() "
6056 <<
"= " << Teuchos::OrdinalTraits<size_t>::invalid() <<
". "
6057 "This should never happen, and suggests that the receive never "
6058 "got posted. Please report this bug to the Tpetra developers."
6072 recvDataBufs[circBufInd].resize(recvNumRows * numCols);
6074 std::ostringstream os;
6075 os << myRank <<
": Post receive-data receive from Process "
6076 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6077 << recvDataBufs[circBufInd].size() << endl;
6080 if (!recvDataReqs[circBufInd].is_null()) {
6082 if (!err.is_null()) {
6083 std::ostringstream os;
6084 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
6085 <<
"null, for the receive-data receive from Process "
6086 << recvRank <<
"! This may mean that this process never "
6087 <<
"finished waiting for the receive from Process "
6088 << (recvRank - 3) <<
"." << endl;
6092 recvDataReqs[circBufInd] =
6093 ireceive<int, scalar_type>(recvDataBufs[circBufInd],
6094 recvRank, dataTag, comm);
6098 const int recvRank = p;
6099 const int circBufInd = recvRank % 3;
6101 std::ostringstream os;
6102 os << myRank <<
": Wait on receive-data receive from Process "
6103 << recvRank << endl;
6106 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
6113 std::ostringstream os;
6114 os << myRank <<
": Write entries from Process " << recvRank
6116 *dbg << os.str() << endl;
6118 size_t printNumRows = (recvSizeBufs[circBufInd])[0];
6119 if (printNumRows == Teuchos::OrdinalTraits<size_t>::invalid()) {
6121 if (!err.is_null()) {
6122 std::ostringstream os;
6123 os << myRank <<
": Result of receive-size receive from Process "
6124 << recvRank <<
" was Teuchos::OrdinalTraits<size_t>::"
6126 << Teuchos::OrdinalTraits<size_t>::invalid()
6127 <<
". This should never happen, and suggests that its "
6128 "receive-size receive was never posted. "
6129 "Please report this bug to the Tpetra developers."
6137 if (printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
6139 if (!err.is_null()) {
6140 std::ostringstream os;
6141 os << myRank <<
": Result of receive-size receive from Proc "
6142 << recvRank <<
" was " << printNumRows <<
" > 0, but "
6144 << circBufInd <<
"] is null. This should "
6145 "never happen. Please report this bug to the Tpetra "
6157 ArrayView<const scalar_type> printData = (recvDataBufs[circBufInd])();
6158 const size_t printStride = printNumRows;
6162 for (
size_t col = 0; col < numCols; ++col) {
6163 for (
size_t row = 0; row < printNumRows; ++row) {
6164 if (STS::isComplex) {
6165 out << STS::real(printData[row + col * printStride]) <<
" "
6166 << STS::imag(printData[row + col * printStride]) << endl;
6168 out << printData[row + col * printStride] << endl;
6172 }
else if (myRank == p) {
6175 std::ostringstream os;
6176 os << myRank <<
": Wait on my send-data send" << endl;
6179 wait<int>(comm, outArg(sendReqData));
6180 }
else if (myRank == p + 1) {
6183 std::ostringstream os;
6184 os << myRank <<
": Post send-data send: tag = " << dataTag
6188 sendReqData = isend<int, scalar_type>(sendDataBuf, 0, dataTag, comm);
6191 std::ostringstream os;
6192 os << myRank <<
": Wait on my send-size send" << endl;
6195 wait<int>(comm, outArg(sendReqSize));
6196 }
else if (myRank == p + 2) {
6199 std::ostringstream os;
6200 os << myRank <<
": Post send-size send: size = "
6201 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6204 sendReqSize = isend<int, size_t>(sendDataSize, 0, sizeTag, comm);
6209 reduceAll<int, int>(comm, REDUCE_MAX, lclErr, outArg(gblErr));
6210 TEUCHOS_TEST_FOR_EXCEPTION(
6211 gblErr == 1, std::runtime_error,
6212 "Tpetra::MatrixMarket::writeDense "
6213 "experienced some kind of error and was unable to complete.");
6217 *dbg << myRank <<
": writeDenseColumn: Done" << endl;
6222template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6225 const std::string& matrixName,
6226 const std::string& matrixDescription,
6227 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6228 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6229 TEUCHOS_TEST_FOR_EXCEPTION(
6230 X.is_null(), std::invalid_argument,
6231 "Tpetra::MatrixMarket::"
6232 "writeDense: The input MultiVector X is null.");
6233 writeDense(out, *X, matrixName, matrixDescription, err, dbg);
6236template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6239 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6240 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6241 writeDense(out, X,
"",
"", err, dbg);
6244template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6247 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6248 const Teuchos::RCP<Teuchos::FancyOStream>& dbg) {
6249 TEUCHOS_TEST_FOR_EXCEPTION(
6250 X.is_null(), std::invalid_argument,
6251 "Tpetra::MatrixMarket::"
6252 "writeDense: The input MultiVector X is null.");
6253 writeDense(out, *X,
"",
"", err, dbg);
6256template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6258 Teuchos::RCP<Teuchos::FancyOStream> err =
6259 Teuchos::getFancyOStream(Teuchos::rcpFromRef(std::cerr));
6260 writeMap(out, map, err, debug);
6263template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6266 const Teuchos::RCP<Teuchos::FancyOStream>& err,
6269 using Teuchos::Array;
6270 using Teuchos::ArrayRCP;
6271 using Teuchos::ArrayView;
6272 using Teuchos::Comm;
6273 using Teuchos::CommRequest;
6274 using Teuchos::ireceive;
6275 using Teuchos::isend;
6277 using Teuchos::TypeNameTraits;
6278 using Teuchos::wait;
6279 typedef global_ordinal_type GO;
6280 typedef int pid_type;
6295 typedef ptrdiff_t int_type;
6296 TEUCHOS_TEST_FOR_EXCEPTION(
6297 sizeof(GO) >
sizeof(int_type), std::logic_error,
6298 "The global ordinal type GO=" << TypeNameTraits<GO>::name()
6299 <<
" is too big for ptrdiff_t. sizeof(GO) = " <<
sizeof(GO)
6300 <<
" > sizeof(ptrdiff_t) = " <<
sizeof(ptrdiff_t) <<
".");
6301 TEUCHOS_TEST_FOR_EXCEPTION(
6302 sizeof(pid_type) >
sizeof(int_type), std::logic_error,
6303 "The (MPI) process rank type pid_type=" << TypeNameTraits<pid_type>::name() <<
" is too big for ptrdiff_t. "
6304 "sizeof(pid_type) = "
6305 <<
sizeof(pid_type) <<
" > sizeof(ptrdiff_t)"
6307 <<
sizeof(ptrdiff_t) <<
".");
6309 const Comm<int>& comm = *(map.getComm());
6310 const int myRank = comm.getRank();
6311 const int numProcs = comm.getSize();
6313 if (!err.is_null()) {
6317 std::ostringstream os;
6318 os << myRank <<
": writeMap" << endl;
6321 if (!err.is_null()) {
6325 const size_t myNumRows = map.getLocalNumElements();
6328 const int sizeTag = 1337;
6329 const int dataTag = 1338;
6388 RCP<CommRequest<int>> sendReqSize, sendReqData;
6394 Array<ArrayRCP<int_type>> recvSizeBufs(3);
6395 Array<ArrayRCP<int_type>> recvDataBufs(3);
6396 Array<RCP<CommRequest<int>>> recvSizeReqs(3);
6397 Array<RCP<CommRequest<int>>> recvDataReqs(3);
6400 ArrayRCP<int_type> sendDataSize(1);
6401 sendDataSize[0] = myNumRows;
6405 std::ostringstream os;
6406 os << myRank <<
": Post receive-size receives from "
6407 "Procs 1 and 2: tag = "
6412 recvSizeBufs[0].resize(1);
6413 (recvSizeBufs[0])[0] = -1;
6414 recvSizeBufs[1].resize(1);
6415 (recvSizeBufs[1])[0] = -1;
6416 recvSizeBufs[2].resize(1);
6417 (recvSizeBufs[2])[0] = -1;
6420 ireceive<int, int_type>(recvSizeBufs[1], 1, sizeTag, comm);
6424 ireceive<int, int_type>(recvSizeBufs[2], 2, sizeTag, comm);
6426 }
else if (myRank == 1 || myRank == 2) {
6428 std::ostringstream os;
6429 os << myRank <<
": Post send-size send: size = "
6430 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6437 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
6440 std::ostringstream os;
6441 os << myRank <<
": Not posting my send-size send yet" << endl;
6452 std::ostringstream os;
6453 os << myRank <<
": Pack my GIDs and PIDs" << endl;
6457 ArrayRCP<int_type> sendDataBuf(myNumRows * 2);
6459 if (map.isContiguous()) {
6460 const int_type myMinGblIdx =
6461 static_cast<int_type
>(map.getMinGlobalIndex());
6462 for (
size_t k = 0; k < myNumRows; ++k) {
6463 const int_type gid = myMinGblIdx +
static_cast<int_type
>(k);
6464 const int_type pid =
static_cast<int_type
>(myRank);
6465 sendDataBuf[2 * k] = gid;
6466 sendDataBuf[2 * k + 1] = pid;
6469 ArrayView<const GO> myGblInds = map.getLocalElementList();
6470 for (
size_t k = 0; k < myNumRows; ++k) {
6471 const int_type gid =
static_cast<int_type
>(myGblInds[k]);
6472 const int_type pid =
static_cast<int_type
>(myRank);
6473 sendDataBuf[2 * k] = gid;
6474 sendDataBuf[2 * k + 1] = pid;
6479 std::ostringstream os;
6480 os << myRank <<
": Done packing my GIDs and PIDs" << endl;
6487 *err << myRank <<
": Post send-data send: tag = " << dataTag
6490 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
6495 *err << myRank <<
": Write MatrixMarket header" << endl;
6500 std::ostringstream hdr;
6504 hdr <<
"%%MatrixMarket matrix array integer general" << endl
6505 <<
"% Format: Version 2.0" << endl
6507 <<
"% This file encodes a Tpetra::Map." << endl
6508 <<
"% It is stored as a dense vector, with twice as many " << endl
6509 <<
"% entries as the global number of GIDs (global indices)." << endl
6510 <<
"% (GID, PID) pairs are stored contiguously, where the PID " << endl
6511 <<
"% is the rank of the process owning that GID." << endl
6512 << (2 * map.getGlobalNumElements()) <<
" " << 1 << endl;
6516 std::ostringstream os;
6517 os << myRank <<
": Write my GIDs and PIDs" << endl;
6523 const int_type printNumRows = myNumRows;
6524 ArrayView<const int_type> printData = sendDataBuf();
6525 for (int_type k = 0; k < printNumRows; ++k) {
6526 const int_type gid = printData[2 * k];
6527 const int_type pid = printData[2 * k + 1];
6535 const int recvRank = 1;
6536 const int circBufInd = recvRank % 3;
6538 std::ostringstream os;
6539 os << myRank <<
": Wait on receive-size receive from Process "
6540 << recvRank << endl;
6544 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6548 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
6549 if (debug && recvNumRows == -1) {
6550 std::ostringstream os;
6551 os << myRank <<
": Result of receive-size receive from Process "
6552 << recvRank <<
" is -1. This should never happen, and "
6553 "suggests that the receive never got posted. Please report "
6554 "this bug to the Tpetra developers."
6560 recvDataBufs[circBufInd].resize(recvNumRows * 2);
6562 std::ostringstream os;
6563 os << myRank <<
": Post receive-data receive from Process "
6564 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6565 << recvDataBufs[circBufInd].size() << endl;
6568 if (!recvSizeReqs[circBufInd].is_null()) {
6569 std::ostringstream os;
6570 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6571 "null, before posting the receive-data receive from Process "
6572 << recvRank <<
". This should never happen. Please report "
6573 "this bug to the Tpetra developers."
6577 recvDataReqs[circBufInd] =
6578 ireceive<int, int_type>(recvDataBufs[circBufInd],
6579 recvRank, dataTag, comm);
6581 }
else if (myRank == 1) {
6584 std::ostringstream os;
6585 os << myRank <<
": Wait on my send-size send" << endl;
6588 wait<int>(comm, outArg(sendReqSize));
6594 for (
int p = 1; p < numProcs; ++p) {
6596 if (p + 2 < numProcs) {
6598 const int recvRank = p + 2;
6599 const int circBufInd = recvRank % 3;
6601 std::ostringstream os;
6602 os << myRank <<
": Post receive-size receive from Process "
6603 << recvRank <<
": tag = " << sizeTag << endl;
6606 if (!recvSizeReqs[circBufInd].is_null()) {
6607 std::ostringstream os;
6608 os << myRank <<
": recvSizeReqs[" << circBufInd <<
"] is not "
6609 <<
"null, for the receive-size receive from Process "
6610 << recvRank <<
"! This may mean that this process never "
6611 <<
"finished waiting for the receive from Process "
6612 << (recvRank - 3) <<
"." << endl;
6615 recvSizeReqs[circBufInd] =
6616 ireceive<int, int_type>(recvSizeBufs[circBufInd],
6617 recvRank, sizeTag, comm);
6620 if (p + 1 < numProcs) {
6621 const int recvRank = p + 1;
6622 const int circBufInd = recvRank % 3;
6626 std::ostringstream os;
6627 os << myRank <<
": Wait on receive-size receive from Process "
6628 << recvRank << endl;
6631 wait<int>(comm, outArg(recvSizeReqs[circBufInd]));
6635 const int_type recvNumRows = (recvSizeBufs[circBufInd])[0];
6636 if (debug && recvNumRows == -1) {
6637 std::ostringstream os;
6638 os << myRank <<
": Result of receive-size receive from Process "
6639 << recvRank <<
" is -1. This should never happen, and "
6640 "suggests that the receive never got posted. Please report "
6641 "this bug to the Tpetra developers."
6647 recvDataBufs[circBufInd].resize(recvNumRows * 2);
6649 std::ostringstream os;
6650 os << myRank <<
": Post receive-data receive from Process "
6651 << recvRank <<
": tag = " << dataTag <<
", buffer size = "
6652 << recvDataBufs[circBufInd].size() << endl;
6655 if (!recvDataReqs[circBufInd].is_null()) {
6656 std::ostringstream os;
6657 os << myRank <<
": recvDataReqs[" << circBufInd <<
"] is not "
6658 <<
"null, for the receive-data receive from Process "
6659 << recvRank <<
"! This may mean that this process never "
6660 <<
"finished waiting for the receive from Process "
6661 << (recvRank - 3) <<
"." << endl;
6664 recvDataReqs[circBufInd] =
6665 ireceive<int, int_type>(recvDataBufs[circBufInd],
6666 recvRank, dataTag, comm);
6670 const int recvRank = p;
6671 const int circBufInd = recvRank % 3;
6673 std::ostringstream os;
6674 os << myRank <<
": Wait on receive-data receive from Process "
6675 << recvRank << endl;
6678 wait<int>(comm, outArg(recvDataReqs[circBufInd]));
6685 std::ostringstream os;
6686 os << myRank <<
": Write GIDs and PIDs from Process "
6687 << recvRank << endl;
6688 *err << os.str() << endl;
6690 const int_type printNumRows = (recvSizeBufs[circBufInd])[0];
6691 if (debug && printNumRows == -1) {
6692 std::ostringstream os;
6693 os << myRank <<
": Result of receive-size receive from Process "
6694 << recvRank <<
" was -1. This should never happen, and "
6695 "suggests that its receive-size receive was never posted. "
6696 "Please report this bug to the Tpetra developers."
6700 if (debug && printNumRows > 0 && recvDataBufs[circBufInd].is_null()) {
6701 std::ostringstream os;
6702 os << myRank <<
": Result of receive-size receive from Proc "
6703 << recvRank <<
" was " << printNumRows <<
" > 0, but "
6705 << circBufInd <<
"] is null. This should "
6706 "never happen. Please report this bug to the Tpetra "
6711 ArrayView<const int_type> printData = (recvDataBufs[circBufInd])();
6712 for (int_type k = 0; k < printNumRows; ++k) {
6713 const int_type gid = printData[2 * k];
6714 const int_type pid = printData[2 * k + 1];
6718 }
else if (myRank == p) {
6721 std::ostringstream os;
6722 os << myRank <<
": Wait on my send-data send" << endl;
6725 wait<int>(comm, outArg(sendReqData));
6726 }
else if (myRank == p + 1) {
6729 std::ostringstream os;
6730 os << myRank <<
": Post send-data send: tag = " << dataTag
6734 sendReqData = isend<int, int_type>(sendDataBuf, 0, dataTag, comm);
6737 std::ostringstream os;
6738 os << myRank <<
": Wait on my send-size send" << endl;
6741 wait<int>(comm, outArg(sendReqSize));
6742 }
else if (myRank == p + 2) {
6745 std::ostringstream os;
6746 os << myRank <<
": Post send-size send: size = "
6747 << sendDataSize[0] <<
", tag = " << sizeTag << endl;
6750 sendReqSize = isend<int, int_type>(sendDataSize, 0, sizeTag, comm);
6754 if (!err.is_null()) {
6758 *err << myRank <<
": writeMap: Done" << endl;
6760 if (!err.is_null()) {
6765template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6768 const int myRank =
map.getComm()->getRank();
6770 auto out = MatrixMarketWriter::openOutFileOnRankZero(
map.getComm(),
filename, myRank,
true);
6778template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6785 if (!
line.empty()) {
6788 if (
line[0] ==
'%') {
6791 out <<
"%% " << line << endl;
6797template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6799 Teuchos::ParameterList pl;
6800 writeOperator(fileName, A, pl);
6803template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6805 Teuchos::ParameterList pl;
6806 writeOperator(out, A, pl);
6809template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6811 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6812 const Teuchos::ParameterList& params) {
6814 std::string tmpFile =
"__TMP__" + fileName;
6815 const int myRank = A.getDomainMap()->getComm()->getRank();
6816 bool precisionChanged =
false;
6817 int oldPrecision = 0;
6826 if (std::ifstream(tmpFile))
6827 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
6828 "writeOperator: temporary file " << tmpFile <<
" already exists");
6829 out.open(tmpFile.c_str());
6830 if (params.isParameter(
"precision")) {
6831 oldPrecision = out.precision(params.get<
int>(
"precision"));
6832 precisionChanged =
true;
6836 const std::string header = writeOperatorImpl(out, A, params);
6839 if (precisionChanged)
6840 out.precision(oldPrecision);
6842 out.open(fileName.c_str(), std::ios::binary);
6843 bool printMatrixMarketHeader =
true;
6844 if (params.isParameter(
"print MatrixMarket header"))
6845 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
6846 if (printMatrixMarketHeader && myRank == 0) {
6851 std::ifstream src(tmpFile, std::ios_base::binary);
6855 remove(tmpFile.c_str());
6859template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6861 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6862 const Teuchos::ParameterList& params) {
6863 const int myRank = A.getDomainMap()->getComm()->getRank();
6880 std::ostringstream tmpOut;
6882 if (params.isParameter(
"precision") && params.isType<
int>(
"precision")) {
6883 (void)tmpOut.precision(params.get<
int>(
"precision"));
6887 const std::string header = writeOperatorImpl(tmpOut, A, params);
6890 bool printMatrixMarketHeader =
true;
6891 if (params.isParameter(
"print MatrixMarket header") &&
6892 params.isType<
bool>(
"print MatrixMarket header")) {
6893 printMatrixMarketHeader = params.get<
bool>(
"print MatrixMarket header");
6895 if (printMatrixMarketHeader && myRank == 0) {
6911 out << tmpOut.str();
6915template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
6917MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeOperatorImpl(std::ostream& os,
6918 const typename MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::operator_type& A,
6919 const Teuchos::ParameterList& params) {
6920 using Teuchos::Array;
6921 using Teuchos::ArrayRCP;
6926 typedef global_ordinal_type GO;
6927 typedef Teuchos::OrdinalTraits<LO> TLOT;
6928 typedef Teuchos::OrdinalTraits<GO> TGOT;
6932 const map_type&
domainMap = *(A.getDomainMap());
6933 RCP<const map_type> rangeMap = A.getRangeMap();
6934 trcp_tcomm_t comm = rangeMap->getComm();
6935 const int myRank = comm->getRank();
6936 const size_t numProcs = comm->getSize();
6939 if (params.isParameter(
"probing size"))
6940 numMVs = params.get<
int>(
"probing size");
6943 GO minColGid =
domainMap.getMinAllGlobalIndex();
6944 GO maxColGid =
domainMap.getMaxAllGlobalIndex();
6949 GO numGlobElts = maxColGid - minColGid + TGOT::one();
6950 GO numChunks = numGlobElts / numMVs;
6951 GO rem = numGlobElts % numMVs;
6952 GO indexBase = rangeMap->getIndexBase();
6954 int offsetToUseInPrinting = 1 - indexBase;
6955 if (params.isParameter(
"zero-based indexing")) {
6956 if (params.get<
bool>(
"zero-based indexing") ==
true)
6957 offsetToUseInPrinting = -indexBase;
6961 size_t numLocalRangeEntries = rangeMap->getLocalNumElements();
6964 RCP<const map_type> allGidsMap = rcp(
new map_type(TGOT::invalid(), numLocalRangeEntries,
6967 mv_type_go allGids(allGidsMap, 1);
6968 Teuchos::ArrayRCP<GO> allGidsData = allGids.getDataNonConst(0);
6970 for (
size_t i = 0; i < numLocalRangeEntries; i++)
6971 allGidsData[i] = rangeMap->getGlobalElement(i);
6972 allGidsData = Teuchos::null;
6975 GO numTargetMapEntries = TGOT::zero();
6976 Teuchos::Array<GO> importGidList;
6978 numTargetMapEntries = rangeMap->getGlobalNumElements();
6979 importGidList.reserve(numTargetMapEntries);
6980 for (GO j = 0; j < numTargetMapEntries; ++j) importGidList.push_back(j + indexBase);
6982 importGidList.reserve(numTargetMapEntries);
6984 RCP<map_type> importGidMap = rcp(
new map_type(TGOT::invalid(), importGidList(), indexBase, comm));
6987 import_type gidImporter(allGidsMap, importGidMap);
6988 mv_type_go importedGids(importGidMap, 1);
6989 importedGids.doImport(allGids, gidImporter,
INSERT);
6992 ArrayRCP<const GO> importedGidsData = importedGids.getData(0);
6993 RCP<const map_type> importMap = rcp(
new map_type(TGOT::invalid(), importedGidsData(), indexBase, comm));
6996 import_type importer(rangeMap, importMap);
6998 RCP<mv_type> colsOnPid0 = rcp(
new mv_type(importMap, numMVs));
7000 RCP<mv_type> ei = rcp(
new mv_type(A.getDomainMap(), numMVs));
7001 RCP<mv_type> colsA = rcp(
new mv_type(A.getRangeMap(), numMVs));
7003 Array<GO> globalColsArray, localColsArray;
7004 globalColsArray.reserve(numMVs);
7005 localColsArray.reserve(numMVs);
7007 ArrayRCP<ArrayRCP<Scalar>> eiData(numMVs);
7008 for (
size_t i = 0; i < numMVs; ++i)
7009 eiData[i] = ei->getDataNonConst(i);
7014 for (GO k = 0; k < numChunks; ++k) {
7015 for (
size_t j = 0; j < numMVs; ++j) {
7017 GO curGlobalCol = minColGid + k * numMVs + j;
7018 globalColsArray.push_back(curGlobalCol);
7020 LO curLocalCol =
domainMap.getLocalElement(curGlobalCol);
7021 if (curLocalCol != TLOT::invalid()) {
7022 eiData[j][curLocalCol] = TGOT::one();
7023 localColsArray.push_back(curLocalCol);
7028 for (
size_t i = 0; i < numMVs; ++i)
7029 eiData[i] = Teuchos::null;
7031 A.apply(*ei, *colsA);
7033 colsOnPid0->doImport(*colsA, importer,
INSERT);
7036 globalNnz += writeColumns(os, *colsOnPid0, numMVs, importedGidsData(),
7037 globalColsArray, offsetToUseInPrinting);
7040 for (
size_t i = 0; i < numMVs; ++i)
7041 eiData[i] = ei->getDataNonConst(i);
7042 for (
size_t j = 0; j < numMVs; ++j) {
7043 GO curGlobalCol = minColGid + k * numMVs + j;
7045 LO curLocalCol =
domainMap.getLocalElement(curGlobalCol);
7046 if (curLocalCol != TLOT::invalid()) {
7047 eiData[j][curLocalCol] = TGOT::one();
7052 for (
size_t j = 0; j < numMVs; ++j) {
7053 for (
int i = 0; i < localColsArray.size(); ++i)
7054 eiData[j][localColsArray[i]] = TGOT::zero();
7056 globalColsArray.clear();
7057 localColsArray.clear();
7064 for (
int j = 0; j < rem; ++j) {
7065 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
7066 globalColsArray.push_back(curGlobalCol);
7068 LO curLocalCol =
domainMap.getLocalElement(curGlobalCol);
7069 if (curLocalCol != TLOT::invalid()) {
7070 eiData[j][curLocalCol] = TGOT::one();
7071 localColsArray.push_back(curLocalCol);
7076 for (
size_t i = 0; i < numMVs; ++i)
7077 eiData[i] = Teuchos::null;
7079 A.apply(*ei, *colsA);
7081 colsOnPid0->doImport(*colsA, importer,
INSERT);
7083 globalNnz += writeColumns(os, *colsOnPid0, rem, importedGidsData(),
7084 globalColsArray, offsetToUseInPrinting);
7087 for (
size_t i = 0; i < numMVs; ++i)
7088 eiData[i] = ei->getDataNonConst(i);
7089 for (
int j = 0; j < rem; ++j) {
7090 GO curGlobalCol = maxColGid - rem + j + TGOT::one();
7092 LO curLocalCol =
domainMap.getLocalElement(curGlobalCol);
7093 if (curLocalCol != TLOT::invalid()) {
7094 eiData[j][curLocalCol] = TGOT::one();
7099 for (
int j = 0; j < rem; ++j) {
7100 for (
int i = 0; i < localColsArray.size(); ++i)
7101 eiData[j][localColsArray[i]] = TGOT::zero();
7103 globalColsArray.clear();
7104 localColsArray.clear();
7112 std::ostringstream oss;
7114 oss <<
"%%MatrixMarket matrix coordinate ";
7115 if (Teuchos::ScalarTraits<typename operator_type::scalar_type>::isComplex) {
7120 oss <<
" general" << std::endl;
7121 oss <<
"% Tpetra::Operator" << std::endl;
7122 std::time_t now = std::time(NULL);
7123 oss <<
"% time stamp: " << ctime(&now);
7124 oss <<
"% written from " << numProcs <<
" processes" << std::endl;
7125 size_t numRows = rangeMap->getGlobalNumElements();
7126 size_t numCols =
domainMap.getGlobalNumElements();
7127 oss << numRows <<
" " << numCols <<
" " << globalNnz << std::endl;
7133template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7135MatrixMarketWriter<Scalar, LocalOrdinal, GlobalOrdinal, Node>::writeColumns(std::ostream& os, mv_type
const& colsA,
size_t const& numCols,
7137 Teuchos::Array<global_ordinal_type>
const& colsArray,
7139 typedef global_ordinal_type GO;
7140 typedef Teuchos::ScalarTraits<Scalar> STS;
7143 const Scalar zero = STS::zero();
7144 const size_t numRows = colsA.getGlobalLength();
7145 for (
size_t j = 0; j < numCols; ++j) {
7146 Teuchos::ArrayRCP<const Scalar>
const curCol = colsA.getData(j);
7147 const GO J = colsArray[j];
7148 for (
size_t i = 0; i < numRows; ++i) {
7149 const Scalar val = curCol[i];
7151 os << rowGids[i] + indexBase <<
" " << J + indexBase <<
" " << val << std::endl;
7160template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7171 using STS =
typename Teuchos::ScalarTraits<ST>;
7177 "The input matrix's communicator (Teuchos::Comm object) is null.");
7179 "The input matrix must not be GloballyIndexed and must be fillComplete.");
7182 const int myRank = comm->getRank();
7183 const int numProc = comm->getSize();
7200 if (
base_rank <= myRank && myRank < stop) {
7205 out <<
"%%MatrixMarket matrix coordinate "
7206 << (STS::isComplex ?
"complex" :
"real")
7207 <<
" general" << std::endl;
7227 Teuchos::SetScientific<ST>
sci(
out);
7232 typename sparse_matrix_type::local_inds_host_view_type indices;
7233 typename sparse_matrix_type::values_host_view_type
values;
7235 for (
size_t ii = 0;
ii < indices.extent(0);
ii++) {
7241 if (STS::isComplex) {
7262template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7263template <
typename T>
7265 return obj.is_null() ? Teuchos::null :
obj->getComm();
7268template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
7270 return comm.is_null() ? 0 : comm->getRank();
7276#define TPETRA_MATRIXMARKET_INSTANT(SCALAR, LO, GO, NODE) \
7277 template class MatrixMarketReader<SCALAR, LO, GO, NODE>; \
7278 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.
A distributed graph accessed by rows (adjacency lists) and stored sparsely.
Sparse matrix that presents a row-oriented interface that lets users read or modify entries.
Struct that holds views of the contents of a CrsMatrix.
Teuchos::RCP< const map_type > colMap
Col map for the original version of the matrix.
Teuchos::RCP< const map_type > domainMap
Domain map for original matrix.
Teuchos::RCP< const map_type > rowMap
Desired row map for "imported" version of the matrix.
A parallel distribution of indices over processes.
Matrix Market file reader for CrsMatrix and MultiVector.
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.
static Teuchos::RCP< sparse_matrix_type > readSparseFile(const std::string &filename, const trcp_tcomm_t &comm, const bool callFillComplete=true, const bool tolerant=false, const bool debug=false)
Read sparse matrix from the given Matrix Market file.
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
Matrix Market file writer for CrsMatrix and MultiVector.
Teuchos::RCP< const Teuchos::Comm< int > > trcp_tcomm_t
Type of the MPI communicator.
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.
static void writeMapFile(const std::string &filename, const map_type &map)
Write the Map to the given file.
static void writeDenseFile(const std::string &filename, const multivector_type &X, const std::string &matrixName, const std::string &matrixDescription, const Teuchos::RCP< Teuchos::FancyOStream > &err=Teuchos::null, const Teuchos::RCP< Teuchos::FancyOStream > &dbg=Teuchos::null)
Print the multivector in Matrix Market format, with matrix name and description.
static void 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.
A distributed dense vector.
void start()
Start the deep_copy counter.
int local_ordinal_type
Default value of Scalar template parameter.
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.
size_t global_size_t
Global size_t object.
@ INSERT
Insert new values that don't currently exist.