42 #ifndef TPETRA_DETAILS_READTRIPLES_HPP
43 #define TPETRA_DETAILS_READTRIPLES_HPP
54 #include "TpetraCore_config.h"
55 #include "Tpetra_Details_PackTriples.hpp"
56 #include "Kokkos_ArithTraits.hpp"
57 #include "Teuchos_MatrixMarket_generic.hpp"
58 #include "Teuchos_CommHelpers.hpp"
110 template<
class OrdinalType,
class RealType>
112 readComplexData (std::istream& istr,
113 OrdinalType& rowIndex,
114 OrdinalType& colIndex,
117 const std::size_t lineNumber,
120 using ::Teuchos::MatrixMarket::readRealData;
122 RealType the_realPart, the_imagPart;
123 if (! readRealData (istr, rowIndex, colIndex, the_realPart, lineNumber, tolerant)) {
128 std::ostringstream os;
129 os <<
"Failed to read pattern data and/or real value from line "
130 << lineNumber <<
" of input";
131 throw std::invalid_argument(os.str());
139 std::ostringstream os;
140 os <<
"No more data after real value on line "
141 << lineNumber <<
" of input";
142 throw std::invalid_argument (os.str ());
145 istr >> the_imagPart;
151 std::ostringstream os;
152 os <<
"Failed to get imaginary value from line "
153 << lineNumber <<
" of input";
154 throw std::invalid_argument (os.str ());
157 realPart = the_realPart;
158 imagPart = the_imagPart;
174 const bool isComplex = ::Kokkos::Details::ArithTraits<SC>::is_complex>
197 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
198 const std::string& line,
199 const std::size_t lineNumber,
200 const bool tolerant =
false,
201 std::ostream* errStrm = NULL,
202 const bool debug =
false);
212 template<
class SC,
class GO>
235 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
236 const std::string& line,
237 const std::size_t lineNumber,
238 const bool tolerant =
false,
239 std::ostream* errStrm = NULL,
240 const bool debug =
false)
242 using ::Teuchos::MatrixMarket::checkCommentLine;
243 typedef typename ::Kokkos::Details::ArithTraits<SC>::mag_type real_type;
247 real_type realPart, imagPart;
248 std::istringstream istr (line);
254 success = readComplexData (istr, rowInd, colInd, realPart, imagPart,
255 lineNumber, tolerant);
257 catch (std::exception& e) {
259 if (errStrm != NULL) {
260 std::ostringstream os;
261 os <<
"readLine: readComplexData threw an exception: " << e.what ()
263 *errStrm << os.str ();
277 processTriple (rowInd, colInd, SC (realPart, imagPart));
278 if (errCode != 0 && errStrm != NULL) {
279 std::ostringstream os;
280 os <<
"readLine: processTriple returned " << errCode <<
" != 0."
282 *errStrm << os.str ();
299 template<
class SC,
class GO>
322 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
323 const std::string& line,
324 const std::size_t lineNumber,
325 const bool tolerant =
false,
326 std::ostream* errStrm = NULL,
327 const bool debug =
false)
329 using ::Teuchos::MatrixMarket::checkCommentLine;
330 using ::Teuchos::MatrixMarket::readRealData;
335 std::istringstream istr (line);
338 success = readRealData (istr, rowInd, colInd, val,
339 lineNumber, tolerant);
341 catch (std::exception& e) {
343 if (errStrm != NULL) {
344 std::ostringstream os;
345 os <<
"readLine: readRealData threw an exception: " << e.what ()
347 *errStrm << os.str ();
352 if (debug && errStrm != NULL) {
353 std::ostringstream os;
354 os <<
"readLine: Got entry: row=" << rowInd <<
", col=" << colInd
355 <<
", val=" << val << std::endl;
356 *errStrm << os.str ();
359 const int errCode = processTriple (rowInd, colInd, val);
360 if (errCode != 0 && errStrm != NULL) {
361 std::ostringstream os;
362 os <<
"readLine: processTriple returned " << errCode <<
" != 0."
364 *errStrm << os.str ();
399 template<
class SC,
class GO>
401 readLine (std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
402 const std::string& line,
403 const std::size_t lineNumber,
404 const bool tolerant =
false,
405 std::ostream* errStrm = NULL,
406 const bool debug =
false)
409 tolerant, errStrm, debug);
442 template<
class SC,
class GO>
444 readTriples (std::istream& inputStream,
445 std::size_t& curLineNum,
446 std::size_t& numTriplesRead,
447 std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
448 const std::size_t maxNumTriplesToRead,
449 const bool tolerant =
false,
450 std::ostream* errStrm = NULL,
451 const bool debug =
false)
453 using Teuchos::MatrixMarket::checkCommentLine;
458 if (inputStream.eof ()) {
461 else if (inputStream.fail ()) {
462 if (errStrm != NULL) {
463 *errStrm <<
"Input stream reports a failure (not the same as "
464 "end-of-file)." << endl;
470 std::vector<size_t> badLineNumbers;
473 bool inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
475 while (inputStreamCanStillBeRead && numTriplesRead < maxNumTriplesToRead) {
483 const bool isCommentLine =
484 checkCommentLine (line, start, size, curLineNum, tolerant);
487 inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
492 const std::string theLine = line.substr (start, size);
495 const int curErrCode =
496 readLine (processTriple, theLine, curLineNum, tolerant, errStrm, debug);
497 if (curErrCode != 0) {
498 errCode = curErrCode;
499 badLineNumbers.push_back (curLineNum);
504 if (numTriplesRead < maxNumTriplesToRead) {
505 inputStreamCanStillBeRead = std::getline (inputStream, line).good ();
510 if (errCode != 0 && errStrm != NULL) {
511 const size_t numBadLines = badLineNumbers.size ();
512 *errStrm <<
"Encountered " << numBadLines <<
" bad line"
513 << (numBadLines != size_t (1) ?
"s" :
"")
515 for (
size_t k = 0; k < numBadLines; ++k) {
516 *errStrm << badLineNumbers[k];
517 if (k + 1 < numBadLines) {
521 *errStrm <<
"]" << endl;
523 if (! inputStream.eof () && inputStream.fail ()) {
527 if (errStrm != NULL) {
528 *errStrm <<
"The input stream is not at end-of-file, "
529 "but is in a bad state." << endl;
560 template<
class SC,
class GO>
562 readAndSendOneBatchOfTriples (std::istream& inputStream,
563 std::size_t& curLineNum,
564 std::size_t& numEntRead,
565 ::Teuchos::ArrayRCP<int>& sizeBuf,
566 ::Teuchos::ArrayRCP<char>& msgBuf,
567 std::vector<GO>& rowInds,
568 std::vector<GO>& colInds,
569 std::vector<SC>& vals,
570 const std::size_t maxNumEntPerMsg,
572 const ::Teuchos::Comm<int>& comm,
573 const bool tolerant =
false,
574 std::ostream* errStrm = NULL,
575 const bool debug =
false)
577 using ::Tpetra::Details::countPackTriplesCount;
578 using ::Tpetra::Details::countPackTriples;
579 using ::Tpetra::Details::packTriplesCount;
580 using ::Tpetra::Details::packTriples;
581 using ::Teuchos::isend;
584 using ::Kokkos::ArithTraits;
587 constexpr
int sizeTag = 42;
588 constexpr
int msgTag = 43;
598 auto processTriple = [&rowInds, &colInds, &vals]
599 (
const GO rowInd,
const GO colInd,
const SC& val) {
601 rowInds.push_back (rowInd);
602 colInds.push_back (colInd);
603 vals.push_back (val);
611 errCode = readTriples<SC, GO> (inputStream, curLineNum, numEntRead,
612 processTriple, maxNumEntPerMsg, tolerant,
614 if (debug && errStrm != NULL) {
615 std::ostringstream os;
616 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
617 <<
", GO=" <<
typeid (GO).name () <<
": "
618 <<
"readAndSendOneBatchOfTriples: readTriples read "
619 << numEntRead <<
" matrix entries, and returned errCode="
620 << errCode <<
"." << std::endl;
621 *errStrm << os.str ();
623 if (numEntRead != rowInds.size () ||
624 numEntRead != colInds.size () ||
625 numEntRead != vals.size ()) {
626 if (errStrm != NULL) {
627 *errStrm <<
"readTriples size results are not consistent. "
628 <<
"numEntRead = " << numEntRead
629 <<
", rowInds.size() = " << rowInds.size ()
630 <<
", colInds.size() = " << colInds.size ()
631 <<
", and vals.size() = " << vals.size () <<
"."
645 if (numEntRead == 0 || errCode != 0) {
651 if (debug && errStrm != NULL) {
652 std::ostringstream os;
653 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
654 <<
", GO=" <<
typeid (GO).name () <<
": "
655 <<
"Post send (size=0, errCode=" << errCode <<
") "
656 <<
"to " << destRank <<
" with tag " << sizeTag << endl;
657 *errStrm << os.str ();
659 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
663 const int numEnt =
static_cast<int> (numEntRead);
670 if (countSize <= 0 && errCode == 0) {
677 if (debug && errStrm != NULL) {
678 std::ostringstream os;
679 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
680 <<
", GO=" <<
typeid (GO).name () <<
": "
681 <<
"Post send (size=0, error case) to " << destRank
682 <<
" with tag " << sizeTag << endl;
683 *errStrm << os.str ();
685 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
689 errCode = countPackTriples<SC, GO> (numEnt, comm, triplesSize, errStrm);
694 if (debug && errStrm != NULL) {
695 std::ostringstream os;
696 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
697 <<
", GO=" <<
typeid (GO).name () <<
": "
698 <<
"Post send (size=0, error case) to " << destRank
699 <<
" with tag " << sizeTag << endl;
700 *errStrm << os.str ();
702 send (sizeBuf.getRawPtr (), 1, destRank, sizeTag, comm);
708 const int outBufSize = countSize + triplesSize;
709 sizeBuf[0] = outBufSize;
710 if (debug && errStrm != NULL) {
711 std::ostringstream os;
712 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
713 <<
", GO=" <<
typeid (GO).name () <<
": "
714 <<
"Post isend (size=" << sizeBuf[0] <<
") to " << destRank
715 <<
" with tag " << sizeTag << endl;
716 *errStrm << os.str ();
718 auto sizeReq = isend<int, int> (sizeBuf, destRank, sizeTag, comm);
720 msgBuf.resize (outBufSize);
721 char* outBuf = msgBuf.getRawPtr ();
725 int outBufCurPos = 0;
727 outBufCurPos, comm, errStrm);
729 errCode = packTriples<SC, GO> (rowInds.data (), colInds.data (),
730 vals.data (), numEnt, outBuf,
731 outBufSize, outBufCurPos, comm,
734 if (debug && errStrm != NULL) {
735 std::ostringstream os;
736 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
737 <<
", GO=" <<
typeid (GO).name () <<
": "
738 <<
"Post isend (packed data) to " << destRank
739 <<
" with tag " << msgTag << endl;
740 *errStrm << os.str ();
742 auto msgReq = isend<int, char> (msgBuf, destRank, msgTag, comm);
748 if (debug && errStrm != NULL) {
749 std::ostringstream os;
750 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
751 <<
", GO=" <<
typeid (GO).name () <<
": "
752 <<
"Wait on isend (size)" << endl;
753 *errStrm << os.str ();
756 if (debug && errStrm != NULL) {
757 std::ostringstream os;
758 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
759 <<
", GO=" <<
typeid (GO).name () <<
": "
760 <<
"Wait on isend (packed data)" << endl;
761 *errStrm << os.str ();
810 template<
class SC,
class GO,
class CommRequestPtr>
812 recvOneBatchOfTriples (std::vector<GO>& rowInds,
813 std::vector<GO>& colInds,
814 std::vector<SC>& vals,
816 ::Teuchos::ArrayRCP<int>& sizeBuf,
817 ::Teuchos::ArrayRCP<char>& msgBuf,
818 CommRequestPtr& sizeReq,
820 const ::Teuchos::Comm<int>& comm,
821 const bool tolerant =
false,
822 std::ostream* errStrm = NULL,
823 const bool debug =
false)
825 using ::Tpetra::Details::unpackTriplesCount;
826 using ::Tpetra::Details::unpackTriples;
827 using ::Kokkos::ArithTraits;
832 constexpr
int msgTag = 43;
837 if (debug && errStrm != NULL) {
838 std::ostringstream os;
839 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
840 <<
", GO=" <<
typeid (GO).name () <<
": "
841 <<
"Wait on irecv (size)" << std::endl;
842 *errStrm << os.str ();
845 sizeReq = CommRequestPtr (NULL);
846 const int inBufSize = sizeBuf[0];
847 if (debug && errStrm != NULL) {
848 std::ostringstream os;
849 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
850 <<
", GO=" <<
typeid (GO).name () <<
": "
851 <<
"Received size: sizeBuf[0]=" << sizeBuf[0] << std::endl;
852 *errStrm << os.str ();
855 if (inBufSize == 0) {
862 msgBuf.resize (inBufSize);
863 char* inBuf = msgBuf.getRawPtr ();
865 if (debug && errStrm != NULL) {
866 std::ostringstream os;
867 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
868 <<
", GO=" <<
typeid (GO).name () <<
": "
869 <<
"Post irecv (packed data) " <<
"from " << srcRank
870 <<
" with tag " << msgTag << std::endl;
871 *errStrm << os.str ();
873 auto msgReq = ::Teuchos::ireceive (msgBuf, srcRank, msgTag, comm);
874 if (debug && errStrm != NULL) {
875 std::ostringstream os;
876 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
877 <<
", GO=" <<
typeid (GO).name () <<
": "
878 <<
"Wait on irecv (packed data)" << std::endl;
879 *errStrm << os.str ();
885 numEnt, comm, errStrm);
887 rowInds.resize (numEnt);
888 colInds.resize (numEnt);
889 vals.resize (numEnt);
890 errCode = unpackTriples<SC, GO> (inBuf, inBufSize, inBufCurPos,
891 rowInds.data (), colInds.data (),
892 vals.data (), numEnt, comm, errStrm);
937 template<
class SC,
class GO>
940 std::size_t& curLineNum,
941 std::size_t& totalNumEntRead,
942 std::function<
int (
const GO,
const GO,
const SC&)> processTriple,
943 const std::size_t maxNumEntPerMsg,
944 const ::Teuchos::Comm<int>& comm,
945 const bool tolerant =
false,
946 std::ostream* errStrm = NULL,
947 const bool debug =
false)
949 using Kokkos::ArithTraits;
953 constexpr
int srcRank = 0;
956 constexpr
int sizeTag = 42;
958 const int myRank = comm.getRank ();
959 const int numProcs = comm.getSize ();
962 ::Teuchos::ArrayRCP<int> sizeBuf (1);
963 ::Teuchos::ArrayRCP<char> msgBuf;
967 std::vector<GO> rowInds;
968 std::vector<GO> colInds;
969 std::vector<SC> vals;
970 rowInds.reserve (maxNumEntPerMsg);
971 colInds.reserve (maxNumEntPerMsg);
972 vals.reserve (maxNumEntPerMsg);
975 if (myRank == srcRank) {
979 bool lastMessageWasLegitZero =
false;
981 ! inputStream.eof () && errCode == 0;
982 destRank = (destRank + 1) % numProcs) {
984 size_t curNumEntRead = 0;
985 if (destRank == srcRank) {
989 const int readErrCode =
990 Impl::readTriples<SC, GO> (inputStream, curLineNum, curNumEntRead,
991 processTriple, maxNumEntPerMsg, tolerant,
993 if (debug && errStrm != NULL) {
994 std::ostringstream os;
995 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
996 <<
", GO=" <<
typeid (GO).name () <<
": "
997 <<
"(dest=src) readTriples returned curNumEntRead="
998 << curNumEntRead <<
", errCode=" << readErrCode << endl;
999 *errStrm << os.str ();
1001 errCode = (readErrCode != 0) ? readErrCode : errCode;
1004 if (
false && debug && errStrm != NULL) {
1005 std::ostringstream os;
1006 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1007 <<
", GO=" <<
typeid (GO).name () <<
": "
1008 <<
"Calling readAndSend... with destRank=" << destRank << endl;
1009 *errStrm << os.str ();
1012 const int readAndSendErrCode =
1013 Impl::readAndSendOneBatchOfTriples<SC, GO> (inputStream, curLineNum,
1016 rowInds, colInds, vals,
1017 maxNumEntPerMsg, destRank,
1018 comm, tolerant, errStrm,
1020 totalNumEntRead += curNumEntRead;
1021 if (debug && errStrm != NULL) {
1022 std::ostringstream os;
1023 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1024 <<
", GO=" <<
typeid (GO).name () <<
": "
1025 <<
"readAndSend... with destRank=" << destRank
1026 <<
" returned curNumEntRead=" << curNumEntRead
1027 <<
", errCode=" << readAndSendErrCode << endl;
1028 *errStrm << os.str ();
1030 errCode = (readAndSendErrCode != 0) ? readAndSendErrCode : errCode;
1031 if (readAndSendErrCode == 0 && curNumEntRead == 0) {
1032 lastMessageWasLegitZero =
true;
1033 if (debug && errStrm != NULL) {
1034 std::ostringstream os;
1035 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1036 <<
", GO=" <<
typeid (GO).name () <<
": "
1037 <<
"Last send to " << destRank <<
" with tag " << sizeTag
1038 <<
" was legit zero, counts as termination" << endl;
1039 *errStrm << os.str ();
1051 destRank = (destRank - 1) % numProcs;
1053 destRank = destRank + numProcs;
1056 const int startRank = lastMessageWasLegitZero ? (destRank+1) : destRank;
1057 for (
int outRank = startRank; outRank < numProcs; ++outRank) {
1058 if (outRank != srcRank) {
1059 if (debug && errStrm != NULL) {
1060 std::ostringstream os;
1061 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1062 <<
", GO=" <<
typeid (GO).name () <<
": "
1063 <<
"Post send (size, termination msg) to " << outRank
1064 <<
" with tag " << sizeTag <<
"(was last message legit zero? "
1065 << (lastMessageWasLegitZero ?
"true" :
"false") <<
")" << endl;
1066 *errStrm << os.str ();
1069 ::Teuchos::send (sizeBuf.getRawPtr (), 1, outRank, sizeTag, comm);
1078 if (debug && errStrm != NULL) {
1079 std::ostringstream os;
1080 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1081 <<
", GO=" <<
typeid (GO).name () <<
": "
1082 <<
"Post irecv (size) from " << srcRank
1083 <<
" with tag " << sizeTag << std::endl;
1084 *errStrm << os.str ();
1086 auto sizeReq = ::Teuchos::ireceive (sizeBuf, srcRank, sizeTag, comm);
1089 const int recvErrCode =
1090 Impl::recvOneBatchOfTriples (rowInds, colInds, vals, numEnt, sizeBuf,
1091 msgBuf, sizeReq, srcRank, comm, tolerant,
1093 if (debug && errStrm != NULL) {
1094 std::ostringstream os;
1095 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1096 <<
", GO=" <<
typeid (GO).name () <<
": "
1097 <<
"recvOneBatchOfTriples returned numEnt=" << numEnt
1098 <<
", errCode=" << recvErrCode << endl;
1099 *errStrm << os.str ();
1101 errCode = (recvErrCode != 0) ? recvErrCode : errCode;
1103 if (numEnt != static_cast<int> (rowInds.size ()) ||
1104 numEnt != static_cast<int> (colInds.size ()) ||
1105 numEnt != static_cast<int> (vals.size ())) {
1106 errCode = (errCode == 0) ? -1 : errCode;
1107 if (errStrm != NULL) {
1108 *errStrm <<
"recvOneBatchOfTriples produced inconsistent data sizes. "
1109 <<
"numEnt = " << numEnt
1110 <<
", rowInds.size() = " << rowInds.size ()
1111 <<
", colInds.size() = " << colInds.size ()
1112 <<
", vals.size() = " << vals.size () <<
"."
1123 for (
int k = 0; k < numEnt && errCode == 0; ++k) {
1124 const int curErrCode = processTriple (rowInds[k], colInds[k], vals[k]);
1125 errCode = (curErrCode == 0) ? errCode : curErrCode;
1130 if (debug && errStrm != NULL) {
1131 std::ostringstream os;
1132 os <<
"Proc " << comm.getRank () <<
", SC=" <<
typeid (SC).name ()
1133 <<
", GO=" <<
typeid (GO).name () <<
": "
1134 <<
"Done with send/recv loop" << endl;
1135 *errStrm << os.str ();
1139 using ::Teuchos::outArg;
1140 using ::Teuchos::REDUCE_BOR;
1141 using ::Teuchos::reduceAll;
1142 const int lclErrCode = errCode;
1143 reduceAll<int, int> (comm, REDUCE_BOR, lclErrCode, outArg (errCode));
1150 #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")...
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 ...