10 #ifndef TPETRA_DETAILS_READTRIPLES_HPP
11 #define TPETRA_DETAILS_READTRIPLES_HPP
22 #include "TpetraCore_config.h"
23 #include "Tpetra_Details_PackTriples.hpp"
24 #include "Kokkos_ArithTraits.hpp"
25 #include "Teuchos_MatrixMarket_generic.hpp"
26 #include "Teuchos_CommHelpers.hpp"
78 template<
class OrdinalType,
class RealType>
80 readComplexData (std::istream& istr,
81 OrdinalType& rowIndex,
82 OrdinalType& colIndex,
85 const std::size_t lineNumber,
88 using ::Teuchos::MatrixMarket::readRealData;
90 RealType the_realPart, the_imagPart;
91 if (! readRealData (istr, rowIndex, colIndex, the_realPart, lineNumber, tolerant)) {
96 std::ostringstream os;
97 os <<
"Failed to read pattern data and/or real value from line "
98 << lineNumber <<
" of input";
99 throw std::invalid_argument(os.str());
107 std::ostringstream os;
108 os <<
"No more data after real value on line "
109 << lineNumber <<
" of input";
110 throw std::invalid_argument (os.str ());
113 istr >> the_imagPart;
119 std::ostringstream os;
120 os <<
"Failed to get imaginary value from line "
121 << lineNumber <<
" of input";
122 throw std::invalid_argument (os.str ());
125 realPart = the_realPart;
126 imagPart = the_imagPart;
142 const bool isComplex = ::Kokkos::ArithTraits<SC>::is_complex>
165 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
166 const std::string& line,
167 const std::size_t lineNumber,
168 const bool tolerant =
false,
169 std::ostream* errStrm = NULL,
170 const bool debug =
false);
180 template<
class SC,
class GO>
203 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
204 const std::string& line,
205 const std::size_t lineNumber,
206 const bool tolerant =
false,
207 std::ostream* errStrm = NULL,
208 const bool debug =
false)
210 using ::Teuchos::MatrixMarket::checkCommentLine;
211 typedef typename ::Kokkos::ArithTraits<SC>::mag_type real_type;
215 real_type realPart, imagPart;
216 std::istringstream istr (line);
222 success = readComplexData (istr, rowInd, colInd, realPart, imagPart,
223 lineNumber, tolerant);
225 catch (std::exception& e) {
227 if (errStrm != NULL) {
228 std::ostringstream os;
229 os <<
"readLine: readComplexData threw an exception: " << e.what ()
231 *errStrm << os.str ();
245 processTriple (rowInd, colInd, SC (realPart, imagPart));
246 if (errCode != 0 && errStrm != NULL) {
247 std::ostringstream os;
248 os <<
"readLine: processTriple returned " << errCode <<
" != 0."
250 *errStrm << os.str ();
267 template<
class SC,
class GO>
290 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
291 const std::string& line,
292 const std::size_t lineNumber,
293 const bool tolerant =
false,
294 std::ostream* errStrm = NULL,
295 const bool debug =
false)
297 using ::Teuchos::MatrixMarket::checkCommentLine;
298 using ::Teuchos::MatrixMarket::readRealData;
303 std::istringstream istr (line);
306 success = readRealData (istr, rowInd, colInd, val,
307 lineNumber, tolerant);
309 catch (std::exception& e) {
311 if (errStrm != NULL) {
312 std::ostringstream os;
313 os <<
"readLine: readRealData threw an exception: " << e.what ()
315 *errStrm << os.str ();
320 if (debug && errStrm != NULL) {
321 std::ostringstream os;
322 os <<
"readLine: Got entry: row=" << rowInd <<
", col=" << colInd
323 <<
", val=" << val << std::endl;
324 *errStrm << os.str ();
327 const int errCode = processTriple (rowInd, colInd, val);
328 if (errCode != 0 && errStrm != NULL) {
329 std::ostringstream os;
330 os <<
"readLine: processTriple returned " << errCode <<
" != 0."
332 *errStrm << os.str ();
367 template<
class SC,
class GO>
369 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
370 const std::string& line,
371 const std::size_t lineNumber,
372 const bool tolerant =
false,
373 std::ostream* errStrm = NULL,
374 const bool debug =
false)
377 tolerant, errStrm, debug);
410 template<
class SC,
class GO>
412 readTriples (std::istream& inputStream,
413 std::size_t& curLineNum,
414 std::size_t& numTriplesRead,
415 std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
416 const std::size_t maxNumTriplesToRead,
417 const bool tolerant =
false,
418 std::ostream* errStrm = NULL,
419 const bool debug =
false)
421 using Teuchos::MatrixMarket::checkCommentLine;
426 if (inputStream.eof ()) {
429 else if (inputStream.fail ()) {
430 if (errStrm != NULL) {
431 *errStrm <<
"Input stream reports a failure (not the same as "
432 "end-of-file)." << endl;
438 std::vector<size_t> badLineNumbers;
441 bool inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
443 while (inputStreamCanStillBeRead && numTriplesRead < maxNumTriplesToRead) {
451 const bool isCommentLine =
452 checkCommentLine (line, start, size, curLineNum, tolerant);
455 inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
460 const std::string theLine = line.substr (start, size);
463 const int curErrCode =
464 readLine (processTriple, theLine, curLineNum, tolerant, errStrm, debug);
465 if (curErrCode != 0) {
466 errCode = curErrCode;
467 badLineNumbers.push_back (curLineNum);
472 if (numTriplesRead < maxNumTriplesToRead) {
473 inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
478 if (errCode != 0 && errStrm != NULL) {
479 const size_t numBadLines = badLineNumbers.size ();
480 *errStrm <<
"Encountered " << numBadLines <<
" bad line"
481 << (numBadLines != size_t (1) ?
"s" :
"")
483 for (
size_t k = 0; k < numBadLines; ++k) {
484 *errStrm << badLineNumbers[k];
485 if (k + 1 < numBadLines) {
489 *errStrm <<
"]" << endl;
491 if (! inputStream.eof () && inputStream.fail ()) {
495 if (errStrm != NULL) {
496 *errStrm <<
"The input stream is not at end-of-file, "
497 "but is in a bad state." << endl;
528 template<
class SC,
class GO>
530 readAndSendOneBatchOfTriples (std::istream& inputStream,
531 std::size_t& curLineNum,
532 std::size_t& numEntRead,
533 ::Teuchos::ArrayRCP<int>& sizeBuf,
534 ::Teuchos::ArrayRCP<char>& msgBuf,
535 std::vector<GO>& rowInds,
536 std::vector<GO>& colInds,
537 std::vector<SC>& vals,
538 const std::size_t maxNumEntPerMsg,
540 const ::Teuchos::Comm<int>& comm,
541 const bool tolerant =
false,
542 std::ostream* errStrm = NULL,
543 const bool debug =
false)
545 using ::Tpetra::Details::countPackTriplesCount;
546 using ::Tpetra::Details::countPackTriples;
547 using ::Tpetra::Details::packTriplesCount;
548 using ::Tpetra::Details::packTriples;
549 using ::Teuchos::isend;
552 using ::Kokkos::ArithTraits;
555 constexpr
int sizeTag = 42;
556 constexpr
int msgTag = 43;
566 auto processTriple = [&rowInds, &colInds, &vals]
567 (
const GO rowInd,
const GO colInd,
const SC& val) {
569 rowInds.push_back (rowInd);
570 colInds.push_back (colInd);
571 vals.push_back (val);
579 errCode = readTriples<SC, GO> (inputStream, curLineNum, numEntRead,
580 processTriple, maxNumEntPerMsg, tolerant,
582 if (debug && errStrm != NULL) {
583 std::ostringstream os;
584 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
585 <<
", GO=" <<
typeid (GO).name () <<
": "
586 <<
"readAndSendOneBatchOfTriples: readTriples read "
587 << numEntRead <<
" matrix entries, and returned errCode="
588 << errCode <<
"." << std::endl;
589 *errStrm << os.str ();
591 if (numEntRead != rowInds.size () ||
592 numEntRead != colInds.size () ||
593 numEntRead != vals.size ()) {
594 if (errStrm != NULL) {
595 *errStrm <<
"readTriples size results are not consistent. "
596 <<
"numEntRead = " << numEntRead
597 <<
", rowInds.size() = " << rowInds.size ()
598 <<
", colInds.size() = " << colInds.size ()
599 <<
", and vals.size() = " << vals.size () <<
"."
613 if (numEntRead == 0 || errCode != 0) {
619 if (debug && errStrm != NULL) {
620 std::ostringstream os;
621 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
622 <<
", GO=" <<
typeid (GO).name () <<
": "
623 <<
"Post send (size=0, errCode=" << errCode <<
") "
624 <<
"to " << destRank <<
" with tag " << sizeTag << endl;
625 *errStrm << os.str ();
627 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
631 const int numEnt =
static_cast<int> (numEntRead);
638 if (countSize <= 0 && errCode == 0) {
645 if (debug && errStrm != NULL) {
646 std::ostringstream os;
647 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
648 <<
", GO=" <<
typeid (GO).name () <<
": "
649 <<
"Post send (size=0, error case) to " << destRank
650 <<
" with tag " << sizeTag << endl;
651 *errStrm << os.str ();
653 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
657 errCode = countPackTriples<SC, GO> (numEnt, comm, triplesSize, errStrm);
662 if (debug && errStrm != NULL) {
663 std::ostringstream os;
664 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
665 <<
", GO=" <<
typeid (GO).name () <<
": "
666 <<
"Post send (size=0, error case) to " << destRank
667 <<
" with tag " << sizeTag << endl;
668 *errStrm << os.str ();
670 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
676 const int outBufSize = countSize + triplesSize;
677 sizeBuf[0] = outBufSize;
678 if (debug && errStrm != NULL) {
679 std::ostringstream os;
680 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
681 <<
", GO=" <<
typeid (GO).name () <<
": "
682 <<
"Post isend (size=" << sizeBuf[0] <<
") to " << destRank
683 <<
" with tag " << sizeTag << endl;
684 *errStrm << os.str ();
686 auto sizeReq = isend<int, int> (sizeBuf, destRank, sizeTag, comm);
688 msgBuf.resize (outBufSize);
689 char* outBuf = msgBuf.getRawPtr ();
693 int outBufCurPos = 0;
695 outBufCurPos, comm, errStrm);
697 errCode = packTriples<SC, GO> (rowInds.data (), colInds.data (),
698 vals.data (), numEnt, outBuf,
699 outBufSize, outBufCurPos, comm,
702 if (debug && errStrm != NULL) {
703 std::ostringstream os;
704 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
705 <<
", GO=" <<
typeid (GO).name () <<
": "
706 <<
"Post isend (packed data) to " << destRank
707 <<
" with tag " << msgTag << endl;
708 *errStrm << os.str ();
710 auto msgReq = isend<int, char> (msgBuf, destRank, msgTag, comm);
716 if (debug && errStrm != NULL) {
717 std::ostringstream os;
718 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
719 <<
", GO=" <<
typeid (GO).name () <<
": "
720 <<
"Wait on isend (size)" << endl;
721 *errStrm << os.str ();
724 if (debug && errStrm != NULL) {
725 std::ostringstream os;
726 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
727 <<
", GO=" <<
typeid (GO).name () <<
": "
728 <<
"Wait on isend (packed data)" << endl;
729 *errStrm << os.str ();
778 template<
class SC,
class GO,
class CommRequestPtr>
780 recvOneBatchOfTriples (std::vector<GO>& rowInds,
781 std::vector<GO>& colInds,
782 std::vector<SC>& vals,
784 ::Teuchos::ArrayRCP<int>& sizeBuf,
785 ::Teuchos::ArrayRCP<char>& msgBuf,
786 CommRequestPtr& sizeReq,
788 const ::Teuchos::Comm<int>& comm,
789 const bool tolerant =
false,
790 std::ostream* errStrm = NULL,
791 const bool debug =
false)
793 using ::Tpetra::Details::unpackTriplesCount;
794 using ::Tpetra::Details::unpackTriples;
795 using ::Kokkos::ArithTraits;
800 constexpr
int msgTag = 43;
805 if (debug && errStrm != NULL) {
806 std::ostringstream os;
807 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
808 <<
", GO=" <<
typeid (GO).name () <<
": "
809 <<
"Wait on irecv (size)" << std::endl;
810 *errStrm << os.str ();
813 sizeReq = CommRequestPtr (NULL);
814 const int inBufSize = sizeBuf[0];
815 if (debug && errStrm != NULL) {
816 std::ostringstream os;
817 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
818 <<
", GO=" <<
typeid (GO).name () <<
": "
819 <<
"Received size: sizeBuf[0]=" << sizeBuf[0] << std::endl;
820 *errStrm << os.str ();
823 if (inBufSize == 0) {
830 msgBuf.resize (inBufSize);
831 char* inBuf = msgBuf.getRawPtr ();
833 if (debug && errStrm != NULL) {
834 std::ostringstream os;
835 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
836 <<
", GO=" <<
typeid (GO).name () <<
": "
837 <<
"Post irecv (packed data) " <<
"from " << srcRank
838 <<
" with tag " << msgTag << std::endl;
839 *errStrm << os.str ();
841 auto msgReq = ::Teuchos::ireceive (msgBuf, srcRank, msgTag, comm);
842 if (debug && errStrm != NULL) {
843 std::ostringstream os;
844 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
845 <<
", GO=" <<
typeid (GO).name () <<
": "
846 <<
"Wait on irecv (packed data)" << std::endl;
847 *errStrm << os.str ();
853 numEnt, comm, errStrm);
855 rowInds.resize (numEnt);
856 colInds.resize (numEnt);
857 vals.resize (numEnt);
858 errCode = unpackTriples<SC, GO> (inBuf, inBufSize, inBufCurPos,
859 rowInds.data (), colInds.data (),
860 vals.data (), numEnt, comm, errStrm);
905 template<
class SC,
class GO>
908 std::size_t& curLineNum,
909 std::size_t& totalNumEntRead,
910 std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
911 const std::size_t maxNumEntPerMsg,
912 const ::Teuchos::Comm<int>& comm,
913 const bool tolerant =
false,
914 std::ostream* errStrm = NULL,
915 const bool debug =
false)
917 using Kokkos::ArithTraits;
921 constexpr
int srcRank = 0;
924 constexpr
int sizeTag = 42;
926 const int myRank = comm.getRank ();
927 const int numProcs = comm.getSize ();
930 ::Teuchos::ArrayRCP<int> sizeBuf (1);
931 ::Teuchos::ArrayRCP<char> msgBuf;
935 std::vector<GO> rowInds;
936 std::vector<GO> colInds;
937 std::vector<SC> vals;
938 rowInds.reserve (maxNumEntPerMsg);
939 colInds.reserve (maxNumEntPerMsg);
940 vals.reserve (maxNumEntPerMsg);
943 if (myRank == srcRank) {
947 bool lastMessageWasLegitZero =
false;
949 ! inputStream.eof () && errCode == 0;
950 destRank = (destRank + 1) % numProcs) {
952 size_t curNumEntRead = 0;
953 if (destRank == srcRank) {
957 const int readErrCode =
958 Impl::readTriples<SC, GO> (inputStream, curLineNum, curNumEntRead,
959 processTriple, maxNumEntPerMsg, tolerant,
961 if (debug && errStrm != NULL) {
962 std::ostringstream os;
963 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
964 <<
", GO=" <<
typeid (GO).name () <<
": "
965 <<
"(dest=src) readTriples returned curNumEntRead="
966 << curNumEntRead <<
", errCode=" << readErrCode << endl;
967 *errStrm << os.str ();
969 errCode = (readErrCode != 0) ? readErrCode : errCode;
972 if (
false && debug && errStrm != NULL) {
973 std::ostringstream os;
974 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
975 <<
", GO=" <<
typeid (GO).name () <<
": "
976 <<
"Calling readAndSend... with destRank=" << destRank << endl;
977 *errStrm << os.str ();
980 const int readAndSendErrCode =
981 Impl::readAndSendOneBatchOfTriples<SC, GO> (inputStream, curLineNum,
984 rowInds, colInds, vals,
985 maxNumEntPerMsg, destRank,
986 comm, tolerant, errStrm,
988 totalNumEntRead += curNumEntRead;
989 if (debug && errStrm != NULL) {
990 std::ostringstream os;
991 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
992 <<
", GO=" <<
typeid (GO).name () <<
": "
993 <<
"readAndSend... with destRank=" << destRank
994 <<
" returned curNumEntRead=" << curNumEntRead
995 <<
", errCode=" << readAndSendErrCode << endl;
996 *errStrm << os.str ();
998 errCode = (readAndSendErrCode != 0) ? readAndSendErrCode : errCode;
999 if (readAndSendErrCode == 0 && curNumEntRead == 0) {
1000 lastMessageWasLegitZero =
true;
1001 if (debug && errStrm != NULL) {
1002 std::ostringstream os;
1003 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1004 <<
", GO=" <<
typeid (GO).name () <<
": "
1005 <<
"Last send to " << destRank <<
" with tag " << sizeTag
1006 <<
" was legit zero, counts as termination" << endl;
1007 *errStrm << os.str ();
1019 destRank = (destRank - 1) % numProcs;
1021 destRank = destRank + numProcs;
1024 const int startRank = lastMessageWasLegitZero ? (destRank+1) : destRank;
1025 for (
int outRank = startRank; outRank < numProcs; ++outRank) {
1026 if (outRank != srcRank) {
1027 if (debug && errStrm != NULL) {
1028 std::ostringstream os;
1029 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1030 <<
", GO=" <<
typeid (GO).name () <<
": "
1031 <<
"Post send (size, termination msg) to " << outRank
1032 <<
" with tag " << sizeTag <<
"(was last message legit zero? "
1033 << (lastMessageWasLegitZero ?
"true" :
"false") <<
")" << endl;
1034 *errStrm << os.str ();
1037 ::Teuchos::send (sizeBuf.getRawPtr (), 1, outRank, sizeTag, comm);
1046 if (debug && errStrm != NULL) {
1047 std::ostringstream os;
1048 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1049 <<
", GO=" <<
typeid (GO).name () <<
": "
1050 <<
"Post irecv (size) from " << srcRank
1051 <<
" with tag " << sizeTag << std::endl;
1052 *errStrm << os.str ();
1054 auto sizeReq = ::Teuchos::ireceive (sizeBuf, srcRank, sizeTag, comm);
1057 const int recvErrCode =
1058 Impl::recvOneBatchOfTriples (rowInds, colInds, vals, numEnt, sizeBuf,
1059 msgBuf, sizeReq, srcRank, comm, tolerant,
1061 if (debug && errStrm != NULL) {
1062 std::ostringstream os;
1063 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1064 <<
", GO=" <<
typeid (GO).name () <<
": "
1065 <<
"recvOneBatchOfTriples returned numEnt=" << numEnt
1066 <<
", errCode=" << recvErrCode << endl;
1067 *errStrm << os.str ();
1069 errCode = (recvErrCode != 0) ? recvErrCode : errCode;
1071 if (numEnt != static_cast<int> (rowInds.size ()) ||
1072 numEnt != static_cast<int> (colInds.size ()) ||
1073 numEnt != static_cast<int> (vals.size ())) {
1074 errCode = (errCode == 0) ? -1 : errCode;
1075 if (errStrm != NULL) {
1076 *errStrm <<
"recvOneBatchOfTriples produced inconsistent data sizes. "
1077 <<
"numEnt = " << numEnt
1078 <<
", rowInds.size() = " << rowInds.size ()
1079 <<
", colInds.size() = " << colInds.size ()
1080 <<
", vals.size() = " << vals.size () <<
"."
1091 for (
int k = 0; k < numEnt && errCode == 0; ++k) {
1092 const int curErrCode = processTriple (rowInds[k], colInds[k], vals[k]);
1093 errCode = (curErrCode == 0) ? errCode : curErrCode;
1098 if (debug && errStrm != NULL) {
1099 std::ostringstream os;
1100 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1101 <<
", GO=" <<
typeid (GO).name () <<
": "
1102 <<
"Done with send/recv loop" << endl;
1103 *errStrm << os.str ();
1107 using ::Teuchos::outArg;
1108 using ::Teuchos::REDUCE_BOR;
1109 using ::Teuchos::reduceAll;
1110 const int lclErrCode = errCode;
1111 reduceAll<int, int> (comm, REDUCE_BOR, lclErrCode, outArg (errCode));
1118 #endif // TPETRA_DETAILS_READTRIPLES_HPP
int packTriplesCount(const int, char[], const int, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm)
Pack the count (number) of matrix triples.
static int readLine(std::function< int(const GO, const GO, const SC &)> processTriple, const std::string &line, const std::size_t lineNumber, const bool tolerant=false, std::ostream *errStrm=NULL, const bool debug=false)
Take a line from the Matrix Market file or input stream, and process the sparse matrix entry in that ...
int readAndDealOutTriples(std::istream &inputStream, std::size_t &curLineNum, std::size_t &totalNumEntRead, std::function< int(const GO, const GO, const SC &)> processTriple, const std::size_t maxNumEntPerMsg, const ::Teuchos::Comm< int > &comm, const bool tolerant=false, std::ostream *errStrm=NULL, const bool debug=false)
On Process 0 in the given communicator, read sparse matrix entries (in chunks of at most maxNumEntPer...
Implementation of the readLine stand-alone function in this namespace (see below).
int unpackTriplesCount(const char[], const int, int &, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm)
Unpack just the count of triples from the given input buffer.
static int readLine(std::function< int(const GO, const GO, const SC &)> processTriple, const std::string &line, const std::size_t lineNumber, const bool tolerant=false, std::ostream *errStrm=NULL, const bool debug=false)
Take a line from the Matrix Market file or input stream, and process the sparse matrix entry in that ...
int countPackTriplesCount(const ::Teuchos::Comm< int > &, int &size, std::ostream *errStrm)
Compute the buffer size required by packTriples for packing the number of matrix entries ("triples")...
void start()
Start the deep_copy counter.
static int readLine(std::function< int(const GO, const GO, const SC &)> processTriple, const std::string &line, const std::size_t lineNumber, const bool tolerant=false, std::ostream *errStrm=NULL, const bool debug=false)
Take a line from the Matrix Market file or input stream, and process the sparse matrix entry in that ...