44 #include "Tpetra_MatrixIO.hpp" 
   56 bool Tpetra::Utils::parseIfmt(Teuchos::ArrayRCP<char> fmt, 
int &perline, 
int &width) {
 
   57   TEUCHOS_TEST_FOR_EXCEPT(fmt.size() != 0 && fmt[fmt.size()-1] != 
'\0');
 
   60   std::transform(fmt.begin(), fmt.end(), fmt, static_cast < int(*)(int) > (std::toupper));
 
   61   if (std::sscanf(fmt.getRawPtr(),
"(%dI%d)",&perline,&width) == 2) {
 
   67 bool Tpetra::Utils::parseRfmt(Teuchos::ArrayRCP<char> fmt, 
int &perline, 
int &width, 
int &prec, 
char &valformat) {
 
   68   TEUCHOS_TEST_FOR_EXCEPT(fmt.size() != 0 && fmt[fmt.size()-1] != 
'\0');
 
   69   std::transform(fmt.begin(), fmt.end(), fmt, static_cast < int(*)(int) > (std::toupper));
 
   71   Teuchos::ArrayRCP<char>::iterator firstLeftParen = std::find( fmt.begin(),  fmt.end(), 
'(');
 
   72   Teuchos::ArrayRCP<char>::iterator lastRightParen = std::find(std::reverse_iterator<Teuchos::ArrayRCP<char>::iterator>(fmt.end()), 
 
   73                                                                std::reverse_iterator<Teuchos::ArrayRCP<char>::iterator>(fmt.begin()), 
 
   77   if (firstLeftParen == fmt.end() || lastRightParen == fmt.begin()) {
 
   82     fmt += (firstLeftParen - fmt.begin());
 
   83     size_t newLen = lastRightParen - firstLeftParen + 1;
 
   84     fmt.resize(newLen + 1);
 
   87   if (std::find(fmt.begin(),fmt.end(),
'P') != fmt.end()) {
 
   92   if (std::sscanf(fmt.getRawPtr(),
"(%d%c%d.%d)",&perline,&valformat,&width,&prec) == 4) {
 
   93     if (valformat == 
'E' || valformat == 
'D' || valformat == 
'F') {
 
  101 void Tpetra::Utils::readHBHeader(std::ifstream &fin, Teuchos::ArrayRCP<char> &Title, Teuchos::ArrayRCP<char> &Key, Teuchos::ArrayRCP<char> &Type, 
 
  102                            int &Nrow, 
int &Ncol, 
int &Nnzero, 
int &Nrhs,
 
  103                            Teuchos::ArrayRCP<char> &Ptrfmt, Teuchos::ArrayRCP<char> &Indfmt, Teuchos::ArrayRCP<char> &Valfmt, Teuchos::ArrayRCP<char> &Rhsfmt, 
 
  104                            int &Ptrcrd, 
int &Indcrd, 
int &Valcrd, 
int &Rhscrd, Teuchos::ArrayRCP<char> &Rhstype) {
 
  105   int Totcrd, Neltvl, Nrhsix;
 
  106   const int MAXLINE = 81;
 
  109   Title.resize(72 + 1);  std::fill(Title.begin(),  Title.end(),  
'\0');
 
  110   Key.resize(8 + 1);     std::fill(Key.begin(),    Key.end(),    
'\0');
 
  111   Type.resize(3 + 1);    std::fill(Type.begin(),   Type.end(),   
'\0');
 
  112   Ptrfmt.resize(16 + 1); std::fill(Ptrfmt.begin(), Ptrfmt.end(), 
'\0');
 
  113   Indfmt.resize(16 + 1); std::fill(Indfmt.begin(), Indfmt.end(), 
'\0');
 
  114   Valfmt.resize(20 + 1); std::fill(Valfmt.begin(), Valfmt.end(), 
'\0');
 
  115   Rhsfmt.resize(20 + 1); std::fill(Rhsfmt.begin(), Rhsfmt.end(), 
'\0');
 
  117   const std::string errStr(
"Tpetra::Utils::readHBHeader(): Improperly formatted H/B file: ");
 
  119   fin.getline(line,MAXLINE);
 
  120   TEUCHOS_TEST_FOR_EXCEPTION( std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr << 
"error buffering line.");
 
  121   (void)std::sscanf(line, 
"%72c%8[^\n]", Title.getRawPtr(), Key.getRawPtr());
 
  123   fin.getline(line,MAXLINE);
 
  124   TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr << 
"error buffering line.");
 
  125   if ( std::sscanf(line,
"%14d%14d%14d%14d%14d",&Totcrd,&Ptrcrd,&Indcrd,&Valcrd,&Rhscrd) != 5 ) {
 
  127     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)");
 
  130   fin.getline(line,MAXLINE);
 
  131   TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr << 
"error buffering line.");
 
  132   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)");
 
  133   std::transform(Type.begin(), Type.end(), Type.begin(), static_cast < int(*)(int) > (std::toupper));
 
  135   fin.getline(line,MAXLINE);
 
  136   TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr << 
"error buffering line.");
 
  138     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)");
 
  141     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)");
 
  145     Rhstype.resize(3 + 1,
'\0');
 
  146     fin.getline(line,MAXLINE);
 
  147     TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(line,
"%*s") < 0, std::runtime_error, errStr << 
"error buffering line.");
 
  148     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)");
 
  153 void Tpetra::Utils::readHBInfo(
const std::string &filename, 
int &M, 
int &N, 
int &nz, Teuchos::ArrayRCP<char> &Type, 
int &Nrhs) {
 
  155   int Ptrcrd, Indcrd, Valcrd, Rhscrd; 
 
  156   Teuchos::ArrayRCP<char> Title, Key, Rhstype, Ptrfmt, Indfmt, Valfmt, Rhsfmt;
 
  158     fin.open(filename.c_str(),std::ifstream::in);
 
  159     Tpetra::Utils::readHBHeader(fin, Title, Key, Type, M, N, nz, Nrhs,
 
  160                                 Ptrfmt, Indfmt, Valfmt, Rhsfmt, 
 
  161                                 Ptrcrd, Indcrd, Valcrd, Rhscrd, Rhstype);
 
  164   catch (std::exception &e) {
 
  165     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, 
 
  166         "Tpetra::Utils::readHBInfo() of filename \"" << filename << 
"\" caught exception: " << std::endl
 
  167         << e.what() << std::endl);
 
  172 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) {
 
  177     int ptrCrd, indCrd, valCrd;
 
  178     Teuchos::ArrayRCP<char> Title, Key, Ptrfmt, Indfmt, Valfmt;
 
  179     const int MAXSIZE = 81;
 
  180     char lineBuf[MAXSIZE];
 
  182     int ptrsPerLine, ptrWidth, indsPerLine, indWidth, valsPerLine, valWidth, valPrec;
 
  185     fin.open(filename.c_str(),std::ifstream::in);
 
  189       Teuchos::ArrayRCP<char> Rhstype, Rhsfmt;
 
  190       Teuchos::ArrayRCP<char> TypeArray;
 
  191       Tpetra::Utils::readHBHeader(fin, Title, Key, TypeArray, numRows, numCols, numNZ, Nrhs,
 
  192                                   Ptrfmt, Indfmt, Valfmt, Rhsfmt, 
 
  193                                   ptrCrd, indCrd, valCrd, rhsCrd, Rhstype);
 
  194       if (TypeArray.size() > 0) {
 
  195         type.resize(TypeArray.size()-1);
 
  196         std::copy(TypeArray.begin(), TypeArray.end(), type.begin());
 
  199     const std::string errStr(
"Tpetra::Utils::readHBHeader(): Improperly formatted H/B file.");
 
  200     const bool readPatternOnly = (type[0] == 
'P' || type[0] == 
'p');
 
  201     const bool readComplex     = (type[0] == 
'C' || type[0] == 
'c');
 
  203     TEUCHOS_TEST_FOR_EXCEPTION( Tpetra::Utils::parseIfmt(Ptrfmt,ptrsPerLine,ptrWidth) == 
true, std::runtime_error,
 
  204         "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
 
  205     TEUCHOS_TEST_FOR_EXCEPTION( Tpetra::Utils::parseIfmt(Indfmt,indsPerLine,indWidth) == 
true, std::runtime_error,
 
  206         "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
 
  207     if (readPatternOnly == 
false) {
 
  208       TEUCHOS_TEST_FOR_EXCEPTION( Tpetra::Utils::parseRfmt(Valfmt,valsPerLine,valWidth,valPrec,valFlag) == 
true, std::runtime_error,
 
  209           "Tpetra::Utils::readHBMatDouble(): error parsing. Invalid/unsupported file format.");
 
  213     if (numCols == 0) 
return;
 
  216     colPtrs = Teuchos::arcp<int>(numCols+1);
 
  218       rowInds = Teuchos::arcp<int>(numNZ);  
 
  219       if (readPatternOnly == 
false) {
 
  221           vals = Teuchos::arcp<double>(2*numNZ); 
 
  224           vals = Teuchos::arcp<double>(numNZ); 
 
  234       for (
int lno=0; lno < ptrCrd; ++lno) {
 
  235         fin.getline(lineBuf, MAXSIZE);
 
  236         TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
 
  237         char *linePtr = lineBuf;
 
  238         for (
int ptr=0; ptr < ptrsPerLine; ++ptr) {
 
  239           if (colPtrsRead == numCols + 1) 
break;
 
  242           std::swap(NullSub,linePtr[ptrWidth]);
 
  244           std::sscanf(linePtr, 
"%d", &cptr);
 
  246           std::swap(NullSub,linePtr[ptrWidth]);
 
  248           colPtrs[colPtrsRead++] = cptr;
 
  251       TEUCHOS_TEST_FOR_EXCEPT(colPtrsRead != numCols + 1);
 
  259       for (
int lno=0; lno < indCrd; ++lno) {
 
  260         fin.getline(lineBuf, MAXSIZE);
 
  261         TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
 
  262         char *linePtr = lineBuf;
 
  263         for (
int indcntr=0; indcntr < indsPerLine; ++indcntr) {
 
  264           if (indicesRead == numNZ) 
break;
 
  267           std::swap(NullSub,linePtr[indWidth]);
 
  269           std::sscanf(linePtr, 
"%d", &ind);
 
  271           std::swap(NullSub,linePtr[indWidth]);
 
  273           rowInds[indicesRead++] = ind;
 
  276       TEUCHOS_TEST_FOR_EXCEPT(indicesRead != numNZ);
 
  282     if (readPatternOnly == 
false) {
 
  285         totalNumVals = 2*numNZ;
 
  288         totalNumVals = numNZ;
 
  292       for (
int lno=0; lno < valCrd; ++lno) {
 
  293         fin.getline(lineBuf, MAXSIZE);
 
  294         TEUCHOS_TEST_FOR_EXCEPTION(std::sscanf(lineBuf,
"%*s") < 0, std::runtime_error, errStr);
 
  296         if (valFlag == 
'D') std::replace_if(lineBuf, lineBuf+MAXSIZE, [] (
const char c) { 
return c == 
'D'; }, 
'E');
 
  297         char *linePtr = lineBuf;
 
  298         for (
int valcntr=0; valcntr < valsPerLine; ++valcntr) {
 
  299           if (valsRead == totalNumVals) 
break;
 
  302           std::swap(NullSub,linePtr[valWidth]);
 
  304           std::sscanf(linePtr, 
"%le", &val);
 
  306           std::swap(NullSub,linePtr[valWidth]);
 
  308           vals[valsRead++] = val;
 
  311       TEUCHOS_TEST_FOR_EXCEPT(valsRead != totalNumVals);
 
  315   catch (std::exception &e) {
 
  316     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error, 
 
  317         "Tpetra::Utils::readHBInfo() of filename \"" << filename << 
"\" caught exception: " << std::endl
 
  318         << e.what() << std::endl);
 
  322 #ifdef HAVE_TPETRA_EXPLICIT_INSTANTIATION 
  324 #include "TpetraCore_ETIHelperMacros.h" 
  325 #include "Tpetra_MatrixIO_def.hpp" 
  330     TPETRA_ETI_MANGLING_TYPEDEFS()
 
  332     TPETRA_INSTANTIATE_SLGN(TPETRA_MATRIXIO_INSTANT)
 
  337 #endif // HAVE_TPETRA_EXPLICIT_INSTANTIATION