10 #include "Tpetra_MatrixIO.hpp"
23 bool Tpetra::Utils::parseIfmt(Teuchos::ArrayRCP<char> fmt,
int &perline,
int &width) {
24 TEUCHOS_TEST_FOR_EXCEPT(fmt.size() != 0 && fmt[fmt.size() - 1] !=
'\0');
27 std::transform(fmt.begin(), fmt.end(), fmt,
static_cast<int (*)(
int)
>(std::toupper));
28 if (std::sscanf(fmt.getRawPtr(),
"(%dI%d)", &perline, &width) == 2) {
34 bool Tpetra::Utils::parseRfmt(Teuchos::ArrayRCP<char> fmt,
int &perline,
int &width,
int &prec,
char &valformat) {
35 TEUCHOS_TEST_FOR_EXCEPT(fmt.size() != 0 && fmt[fmt.size() - 1] !=
'\0');
36 std::transform(fmt.begin(), fmt.end(), fmt,
static_cast<int (*)(
int)
>(std::toupper));
38 Teuchos::ArrayRCP<char>::iterator firstLeftParen = std::find(fmt.begin(), fmt.end(),
'(');
39 Teuchos::ArrayRCP<char>::iterator lastRightParen = std::find(std::reverse_iterator<Teuchos::ArrayRCP<char>::iterator>(fmt.end()),
40 std::reverse_iterator<Teuchos::ArrayRCP<char>::iterator>(fmt.begin()),
46 if (firstLeftParen == fmt.end() || lastRightParen == fmt.begin()) {
50 fmt += (firstLeftParen - fmt.begin());
51 size_t newLen = lastRightParen - firstLeftParen + 1;
52 fmt.resize(newLen + 1);
55 if (std::find(fmt.begin(), fmt.end(),
'P') != fmt.end()) {
60 if (std::sscanf(fmt.getRawPtr(),
"(%d%c%d.%d)", &perline, &valformat, &width, &prec) == 4) {
61 if (valformat ==
'E' || valformat ==
'D' || valformat ==
'F') {
68 void Tpetra::Utils::readHBHeader(std::ifstream &fin, Teuchos::ArrayRCP<char> &Title, Teuchos::ArrayRCP<char> &Key, Teuchos::ArrayRCP<char> &Type,
69 int &Nrow,
int &Ncol,
int &Nnzero,
int &Nrhs,
70 Teuchos::ArrayRCP<char> &Ptrfmt, Teuchos::ArrayRCP<char> &Indfmt, Teuchos::ArrayRCP<char> &Valfmt, Teuchos::ArrayRCP<char> &Rhsfmt,
71 int &Ptrcrd,
int &Indcrd,
int &Valcrd,
int &Rhscrd, Teuchos::ArrayRCP<char> &Rhstype) {
72 int Totcrd, Neltvl, Nrhsix;
73 const int MAXLINE = 81;
77 std::fill(Title.begin(), Title.end(),
'\0');
79 std::fill(Key.begin(), Key.end(),
'\0');
81 std::fill(Type.begin(), Type.end(),
'\0');
82 Ptrfmt.resize(16 + 1);
83 std::fill(Ptrfmt.begin(), Ptrfmt.end(),
'\0');
84 Indfmt.resize(16 + 1);
85 std::fill(Indfmt.begin(), Indfmt.end(),
'\0');
86 Valfmt.resize(20 + 1);
87 std::fill(Valfmt.begin(), Valfmt.end(),
'\0');
88 Rhsfmt.resize(20 + 1);
89 std::fill(Rhsfmt.begin(), Rhsfmt.end(),
'\0');
91 const std::string errStr(
"Tpetra::Utils::readHBHeader(): Improperly formatted H/B file: ");
93 fin.getline(line, MAXLINE);
94 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr <<
"error buffering first line.");
95 (void)std::sscanf(line,
"%72c%8[^\n]", Title.getRawPtr(), Key.getRawPtr());
97 fin.getline(line, MAXLINE);
98 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr <<
"error buffering second line.");
99 if (std::sscanf(line,
"%14d%14d%14d%14d%14d", &Totcrd, &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd) != 5) {
101 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%14d%14d%14d%14d", &Totcrd, &Ptrcrd, &Indcrd, &Valcrd) != 4, std::runtime_error, errStr <<
"error reading pointers (line 2)");
104 fin.getline(line, MAXLINE);
105 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr <<
"error buffering third line.");
106 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%3c%14i%14i%14i%14i", Type.getRawPtr(), &Nrow, &Ncol, &Nnzero, &Neltvl) != 5, std::runtime_error, errStr <<
"error reading matrix meta-data (line 3)");
107 std::transform(Type.begin(), Type.end(), Type.begin(),
static_cast<int (*)(
int)
>(std::toupper));
109 fin.getline(line, MAXLINE);
110 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr <<
"error buffering fourth line.");
112 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%16c%16c%20c%20c", Ptrfmt.getRawPtr(), Indfmt.getRawPtr(), Valfmt.getRawPtr(), Rhsfmt.getRawPtr()) != 4, std::runtime_error, errStr <<
"error reading formats (line 4)");
114 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%16c%16c%20c", Ptrfmt.getRawPtr(), Indfmt.getRawPtr(), Valfmt.getRawPtr()) != 3, std::runtime_error, errStr <<
"error reading formats (line 4)");
118 Rhstype.resize(3 + 1,
'\0');
119 fin.getline(line, MAXLINE);
120 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr <<
"error buffering fifth line.");
121 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%3c%14d%14d", Rhstype.getRawPtr(), &Nrhs, &Nrhsix) != 3, std::runtime_error, errStr <<
"error reading right-hand-side meta-data (line 5)");
125 void Tpetra::Utils::readHBInfo(
const std::string &filename,
int &M,
int &N,
int &nz, Teuchos::ArrayRCP<char> &Type,
int &Nrhs) {
127 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
128 Teuchos::ArrayRCP<char> Title, Key, Rhstype, Ptrfmt, Indfmt, Valfmt, Rhsfmt;
130 fin.open(filename.c_str(), std::ifstream::in);
131 TEUCHOS_TEST_FOR_EXCEPTION(!fin, std::runtime_error,
"Tpetra::Utils::readHBInfo(): H/B file does not exist or cannot be opened");
132 Tpetra::Utils::readHBHeader(fin, Title, Key, Type, M, N, nz, Nrhs,
133 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
134 Ptrcrd, Indcrd, Valcrd, Rhscrd, Rhstype);
136 }
catch (std::exception &e) {
137 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
138 "Tpetra::Utils::readHBInfo() of filename \"" << filename <<
"\" caught exception: " << std::endl
139 << e.what() << std::endl);
143 void Tpetra::Utils::readHBMatDouble(
const std::string &filename,
int &numRows,
int &numCols,
int &numNZ, std::string &type, Teuchos::ArrayRCP<int> &colPtrs, Teuchos::ArrayRCP<int> &rowInds, Teuchos::ArrayRCP<double> &vals) {
148 int ptrCrd, indCrd, valCrd;
149 Teuchos::ArrayRCP<char> Title, Key, Ptrfmt, Indfmt, Valfmt;
150 const int MAXSIZE = 81;
151 char lineBuf[MAXSIZE];
153 int ptrsPerLine, ptrWidth, indsPerLine, indWidth, valsPerLine, valWidth, valPrec;
156 fin.open(filename.c_str(), std::ifstream::in);
157 TEUCHOS_TEST_FOR_EXCEPTION(!fin, std::runtime_error,
"Tpetra::Utils::readHBMatDouble(): H/B file does not exist or cannot be opened");
161 Teuchos::ArrayRCP<char> Rhstype, Rhsfmt;
162 Teuchos::ArrayRCP<char> TypeArray;
163 Tpetra::Utils::readHBHeader(fin, Title, Key, TypeArray, numRows, numCols, numNZ, Nrhs,
164 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
165 ptrCrd, indCrd, valCrd, rhsCrd, Rhstype);
166 if (TypeArray.size() > 0) {
167 type.resize(TypeArray.size() - 1);
168 std::copy(TypeArray.begin(), TypeArray.end(), type.begin());
171 const std::string errStr(
"Tpetra::Utils::readHBHeader(): Improperly formatted H/B file.");
172 const bool readPatternOnly = (type[0] ==
'P' || type[0] ==
'p');
173 const bool readComplex = (type[0] ==
'C' || type[0] ==
'c');
175 TEUCHOS_TEST_FOR_EXCEPTION(Tpetra::Utils::parseIfmt(Ptrfmt, ptrsPerLine, ptrWidth) ==
true, std::runtime_error,
176 "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
177 TEUCHOS_TEST_FOR_EXCEPTION(Tpetra::Utils::parseIfmt(Indfmt, indsPerLine, indWidth) ==
true, std::runtime_error,
178 "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
179 if (readPatternOnly ==
false) {
180 TEUCHOS_TEST_FOR_EXCEPTION(Tpetra::Utils::parseRfmt(Valfmt, valsPerLine, valWidth, valPrec, valFlag) ==
true, std::runtime_error,
181 "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
185 if (numCols == 0)
return;
188 colPtrs = Teuchos::arcp<int>(numCols + 1);
190 rowInds = Teuchos::arcp<int>(numNZ);
191 if (readPatternOnly ==
false) {
193 vals = Teuchos::arcp<double>(2 * numNZ);
195 vals = Teuchos::arcp<double>(numNZ);
205 for (
int lno = 0; lno < ptrCrd; ++lno) {
206 fin.getline(lineBuf, MAXSIZE);
207 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
208 char *linePtr = lineBuf;
209 for (
int ptr = 0; ptr < ptrsPerLine; ++ptr) {
210 if (colPtrsRead == numCols + 1)
break;
213 std::swap(NullSub, linePtr[ptrWidth]);
215 std::sscanf(linePtr,
"%d", &cptr);
217 std::swap(NullSub, linePtr[ptrWidth]);
219 colPtrs[colPtrsRead++] = cptr;
222 TEUCHOS_TEST_FOR_EXCEPT(colPtrsRead != numCols + 1);
230 for (
int lno = 0; lno < indCrd; ++lno) {
231 fin.getline(lineBuf, MAXSIZE);
232 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
233 char *linePtr = lineBuf;
234 for (
int indcntr = 0; indcntr < indsPerLine; ++indcntr) {
235 if (indicesRead == numNZ)
break;
238 std::swap(NullSub, linePtr[indWidth]);
240 std::sscanf(linePtr,
"%d", &ind);
242 std::swap(NullSub, linePtr[indWidth]);
244 rowInds[indicesRead++] = ind;
247 TEUCHOS_TEST_FOR_EXCEPT(indicesRead != numNZ);
253 if (readPatternOnly ==
false) {
256 totalNumVals = 2 * numNZ;
258 totalNumVals = numNZ;
262 for (
int lno = 0; lno < valCrd; ++lno) {
263 fin.getline(lineBuf, MAXSIZE);
264 TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
266 if (valFlag ==
'D') std::replace_if(
267 lineBuf, lineBuf + MAXSIZE, [](
const char c) {
return c ==
'D'; },
'E');
268 char *linePtr = lineBuf;
269 for (
int valcntr = 0; valcntr < valsPerLine; ++valcntr) {
270 if (valsRead == totalNumVals)
break;
273 std::swap(NullSub, linePtr[valWidth]);
275 std::sscanf(linePtr,
"%le", &val);
277 std::swap(NullSub, linePtr[valWidth]);
279 vals[valsRead++] = val;
282 TEUCHOS_TEST_FOR_EXCEPT(valsRead != totalNumVals);
285 }
catch (std::exception &e) {
286 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
287 "Tpetra::Utils::readHBInfo() of filename \"" << filename <<
"\" caught exception: " << std::endl
288 << e.what() << std::endl);
292 #ifdef HAVE_TPETRA_EXPLICIT_INSTANTIATION
294 #include "TpetraCore_ETIHelperMacros.h"
295 #include "Tpetra_MatrixIO_def.hpp"
300 TPETRA_ETI_MANGLING_TYPEDEFS()
302 TPETRA_INSTANTIATE_SLGN(TPETRA_MATRIXIO_INSTANT)
307 #endif // HAVE_TPETRA_EXPLICIT_INSTANTIATION