217#include "Tpetra_Util_iohb.h"
224namespace Tpetra::HB {
230char* substr(
const char* S,
const int pos,
const int len);
232void IOHBTerminate(
const char* message);
234int readHB_info(
const char* filename,
int* M,
int* N,
int* nz, std::string& Type,
254 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
255 int Nrow, Ncol, Nnzero;
257 char Title[73], Key[9], Rhstype[4];
258 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
260 if ((in_file = std::fopen(filename,
"r")) == NULL) {
261 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
265 readHB_header(in_file, Title, Key, mat_type, &Nrow, &Ncol, &Nnzero, Nrhs,
266 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
267 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
268 std::fclose(in_file);
269 Type = std::string(mat_type, 3);
293int readHB_header(std::FILE* in_file,
char* Title,
char* Key,
char* Type,
294 int* Nrow,
int* Ncol,
int* Nnzero,
int* Nrhs,
295 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
296 int* Ptrcrd,
int* Indcrd,
int* Valcrd,
int* Rhscrd,
301 int Totcrd, Neltvl, Nrhsix;
305 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
306 std::fprintf(stderr,
"Error: Failed to read from file.\n");
309 if (std::sscanf(line,
"%*s") < 0)
310 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) first line of HB file.\n");
311 (void)std::sscanf(line,
"%72c%8[^\n]", Title, Key);
313 *(Title + 72) =
'\0';
316 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
317 std::fprintf(stderr,
"Error: Failed to read from file.\n");
320 if (std::sscanf(line,
"%*s") < 0)
321 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) second line of HB file.\n");
322 if (std::sscanf(line,
"%i", &Totcrd) != 1) Totcrd = 0;
323 if (std::sscanf(line,
"%*i%i", Ptrcrd) != 1) *Ptrcrd = 0;
324 if (std::sscanf(line,
"%*i%*i%i", Indcrd) != 1) *Indcrd = 0;
325 if (std::sscanf(line,
"%*i%*i%*i%i", Valcrd) != 1) *Valcrd = 0;
326 if (std::sscanf(line,
"%*i%*i%*i%*i%i", Rhscrd) != 1) *Rhscrd = 0;
329 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
330 std::fprintf(stderr,
"Error: Failed to read from file.\n");
333 if (std::sscanf(line,
"%*s") < 0)
334 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) third line of HB file.\n");
336 if (std::sscanf(line,
"%3c", Type) != 1)
337 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid Type info, line 3 of Harwell-Boeing file.\n");
339 if (std::sscanf(line,
"%*3c%i", Nrow) != 1) *Nrow = 0;
340 if (std::sscanf(line,
"%*3c%*i%i", Ncol) != 1) *Ncol = 0;
341 if (std::sscanf(line,
"%*3c%*i%*i%i", Nnzero) != 1) *Nnzero = 0;
342 if (std::sscanf(line,
"%*3c%*i%*i%*i%i", &Neltvl) != 1) Neltvl = 0;
345 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
346 std::fprintf(stderr,
"Error: Failed to read from file.\n");
349 if (std::sscanf(line,
"%*s") < 0)
350 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fourth line of HB file.\n");
351 if (std::sscanf(line,
"%16c", Ptrfmt) != 1)
352 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
353 if (std::sscanf(line,
"%*16c%16c", Indfmt) != 1)
354 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
355 if (std::sscanf(line,
"%*16c%*16c%20c", Valfmt) != 1)
356 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
357 std::sscanf(line,
"%*16c%*16c%*20c%20c", Rhsfmt);
358 *(Ptrfmt + 16) =
'\0';
359 *(Indfmt + 16) =
'\0';
360 *(Valfmt + 20) =
'\0';
361 *(Rhsfmt + 20) =
'\0';
365 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
366 std::fprintf(stderr,
"Error: Failed to read from file.\n");
369 if (std::sscanf(line,
"%*s") < 0)
370 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fifth line of HB file.\n");
371 if (std::sscanf(line,
"%3c", Rhstype) != 1)
372 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid RHS type information, line 5 of Harwell-Boeing file.\n");
373 if (std::sscanf(line,
"%*3c%i", Nrhs) != 1) *Nrhs = 0;
374 if (std::sscanf(line,
"%*3c%*i%i", &Nrhsix) != 1) Nrhsix = 0;
379int readHB_mat_double(
const char* filename,
int colptr[],
int rowind[],
400 int i, j, ind, col, offset, count, last, Nrhs;
401 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
402 int Nrow, Ncol, Nnzero, Nentries;
403 int Ptrperline, Ptrwidth, Indperline, Indwidth;
404 int Valperline, Valwidth, Valprec;
407 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
408 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
411 if ((in_file = std::fopen(filename,
"r")) == NULL) {
412 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
416 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
417 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
418 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
421 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
422 ParseIfmt(Indfmt, &Indperline, &Indwidth);
423 if (Type[0] !=
'P') {
424 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
429 offset = 1 - _SP_base;
432 ThisElement = (
char*)malloc(Ptrwidth + 1);
433 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
434 *(ThisElement + Ptrwidth) =
'\0';
436 for (i = 0; i < Ptrcrd; i++) {
437 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
438 std::fprintf(stderr,
"Error: Failed to read from file.\n");
441 if (std::sscanf(line,
"%*s") < 0)
442 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
444 for (ind = 0; ind < Ptrperline; ind++) {
445 if (count > Ncol)
break;
446 std::strncpy(ThisElement, line + col, Ptrwidth);
448 colptr[count] = std::atoi(ThisElement) - offset;
457 ThisElement = (
char*)malloc(Indwidth + 1);
458 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
459 *(ThisElement + Indwidth) =
'\0';
461 for (i = 0; i < Indcrd; i++) {
462 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
463 std::fprintf(stderr,
"Error: Failed to read from file.\n");
466 if (std::sscanf(line,
"%*s") < 0)
467 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
469 for (ind = 0; ind < Indperline; ind++) {
470 if (count == Nnzero)
break;
471 std::strncpy(ThisElement, line + col, Indwidth);
473 rowind[count] = std::atoi(ThisElement) - offset;
482 if (Type[0] !=
'P') {
485 Nentries = 2 * Nnzero;
489 ThisElement = (
char*)malloc(Valwidth + 2);
490 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
491 *(ThisElement + Valwidth) =
'\0';
492 *(ThisElement + Valwidth + 1) =
'\0';
494 for (i = 0; i < Valcrd; i++) {
495 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
496 std::fprintf(stderr,
"Error: Failed to read from file.\n");
499 if (std::sscanf(line,
"%*s") < 0)
500 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
501 if (Valflag ==
'D') {
502 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
506 for (ind = 0; ind < Valperline; ind++) {
507 if (count == Nentries)
break;
508 std::strncpy(ThisElement, line + col, Valwidth);
510 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
512 last = std::strlen(ThisElement);
513 for (j = last + 1; j >= 0; j--) {
514 ThisElement[j] = ThisElement[j - 1];
515 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
516 ThisElement[j - 1] = Valflag;
521 val[count] = std::atof(ThisElement);
524 *(ThisElement + Valwidth) =
'\0';
525 *(ThisElement + Valwidth + 1) =
'\0';
531 std::fclose(in_file);
535int readHB_newmat_double(
const char* filename,
int* M,
int* N,
int* nonzeros,
536 int** colptr,
int** rowind,
double** val) {
540 if (readHB_info(filename, M, N, nonzeros, Type, &Nrhs) == 0) {
544 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
545 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
546 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
547 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
548 if (Type[0] ==
'C') {
550 *val = (
double*)malloc(*nonzeros *
sizeof(
double) * 2);
551 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
553 if (Type[0] !=
'P') {
555 *val = (
double*)malloc(*nonzeros *
sizeof(
double));
556 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
559 return readHB_mat_double(filename, *colptr, *rowind, *val);
562int readHB_aux_double(
const char* filename,
const char AuxType,
double b[]) {
585 int i, j, n, maxcol,
start, stride, col, last, linel;
586 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
587 int Nrow, Ncol, Nnzero, Nentries;
588 int Nrhs, nvecs, rhsi;
589 int Rhsperline, Rhswidth, Rhsprec;
592 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
593 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
596 if ((in_file = std::fopen(filename,
"r")) == NULL) {
597 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
601 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
602 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
603 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
606 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
609 if (Rhstype[0] !=
'F') {
610 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
611 std::fprintf(stderr,
" Rhs must be specified as full. \n");
616 if (Type[0] ==
'C') {
624 if (Rhstype[1] ==
'G') nvecs++;
625 if (Rhstype[2] ==
'X') nvecs++;
627 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
628 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
631 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
632 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
636 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
637 maxcol = Rhsperline * Rhswidth;
640 n = Ptrcrd + Indcrd + Valcrd;
642 for (i = 0; i < n; i++) {
643 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
644 std::fprintf(stderr,
"Error: Failed to read from file.\n");
655 else if (AuxType ==
'G')
658 start = (nvecs - 1) * Nentries;
659 stride = (nvecs - 1) * Nentries;
661 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
662 std::fprintf(stderr,
"Error: Failed to read from file.\n");
665 linel = std::strchr(line,
'\n') - line;
669 for (i = 0; i <
start; i++) {
670 if (col >= (maxcol < linel ? maxcol : linel)) {
671 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
672 std::fprintf(stderr,
"Error: Failed to read from file.\n");
675 linel = std::strchr(line,
'\n') - line;
680 if (Rhsflag ==
'D') {
681 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
687 ThisElement = (
char*)malloc(Rhswidth + 1);
688 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
689 *(ThisElement + Rhswidth) =
'\0';
690 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
691 for (i = 0; i < Nentries; i++) {
692 if (col >= (maxcol < linel ? maxcol : linel)) {
693 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
694 std::fprintf(stderr,
"Error: Failed to read from file.\n");
697 linel = std::strchr(line,
'\n') - line;
698 if (Rhsflag ==
'D') {
699 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
703 std::strncpy(ThisElement, line + col, Rhswidth);
705 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
707 last = std::strlen(ThisElement);
708 for (j = last + 1; j >= 0; j--) {
709 ThisElement[j] = ThisElement[j - 1];
710 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
711 ThisElement[j - 1] = Rhsflag;
716 b[i] = std::atof(ThisElement);
722 for (i = 0; i < stride; i++) {
723 if (col >= (maxcol < linel ? maxcol : linel)) {
724 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
725 std::fprintf(stderr,
"Error: Failed to read from file.\n");
728 linel = std::strchr(line,
'\n') - line;
736 std::fclose(in_file);
740int readHB_newaux_double(
const char* filename,
const char AuxType,
double** b) {
747 readHB_info(filename, &M, &N, &nonzeros, Type, &Nrhs);
749 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
752 if (Type[0] ==
'C') {
753 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
754 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
755 *b = (
double*)malloc(M * Nrhs *
sizeof(
double) * 2);
756 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
757 return readHB_aux_double(filename, AuxType, *b);
759 *b = (
double*)malloc(M * Nrhs *
sizeof(
double));
760 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
761 return readHB_aux_double(filename, AuxType, *b);
766int writeHB_mat_double(
const char* filename,
int M,
int N,
767 int nz,
const int colptr[],
const int rowind[],
768 const double val[],
int Nrhs,
const double rhs[],
769 const double guess[],
const double exact[],
770 const char* Title,
const char* Key,
const char* Type,
771 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
772 const char* Rhstype) {
783 int i, j, entry, offset, acount, linemod;
784 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
785 int nvalentries, nrhsentries;
786 int Ptrperline, Ptrwidth, Indperline, Indwidth;
787 int Rhsperline, Rhswidth, Rhsprec;
789 int Valperline, Valwidth, Valprec;
791 char pformat[16], iformat[16], vformat[19], rformat[19];
793 if (Type[0] ==
'C') {
794 nvalentries = 2 * nz;
801 if (filename != NULL) {
802 if ((out_file = std::fopen(filename,
"w")) == NULL) {
803 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
809 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
810 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
811 std::sprintf(pformat,
"%%%dd", Ptrwidth);
812 ptrcrd = (N + 1) / Ptrperline;
813 if ((N + 1) % Ptrperline != 0) ptrcrd++;
815 if (Indfmt == NULL) Indfmt = Ptrfmt;
816 ParseIfmt(Indfmt, &Indperline, &Indwidth);
817 std::sprintf(iformat,
"%%%dd", Indwidth);
818 indcrd = nz / Indperline;
819 if (nz % Indperline != 0) indcrd++;
821 if (Type[0] !=
'P') {
822 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
823 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
824 if (Valflag ==
'D') *std::strchr(Valfmt,
'D') =
'E';
826 std::sprintf(vformat,
"%% %d.%df", Valwidth, Valprec);
828 std::sprintf(vformat,
"%% %d.%dE", Valwidth, Valprec);
829 valcrd = nvalentries / Valperline;
830 if (nvalentries % Valperline != 0) valcrd++;
835 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
836 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
838 std::sprintf(rformat,
"%% %d.%df", Rhswidth, Rhsprec);
840 std::sprintf(rformat,
"%% %d.%dE", Rhswidth, Rhsprec);
841 if (Rhsflag ==
'D') *std::strchr(Rhsfmt,
'D') =
'E';
842 rhscrd = nrhsentries / Rhsperline;
843 if (nrhsentries % Rhsperline != 0) rhscrd++;
844 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
845 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
850 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
854 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
855 ptrcrd, indcrd, valcrd, rhscrd);
856 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
857 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
861 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
863 std::fprintf(out_file,
"\n");
865 offset = 1 - _SP_base;
869 for (i = 0; i < N + 1; i++) {
870 entry = colptr[i] + offset;
871 std::fprintf(out_file, pformat, entry);
872 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
875 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
878 for (i = 0; i < nz; i++) {
879 entry = rowind[i] + offset;
880 std::fprintf(out_file, iformat, entry);
881 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
884 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
888 if (Type[0] !=
'P') {
890 for (i = 0; i < nvalentries; i++) {
891 std::fprintf(out_file, vformat, val[i]);
892 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
895 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
902 for (i = 0; i < Nrhs; i++) {
903 for (j = 0; j < nrhsentries; j++) {
904 std::fprintf(out_file, rformat, rhs[j]);
905 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
907 if ((acount - 1) % Rhsperline != linemod) {
908 std::fprintf(out_file,
"\n");
909 linemod = (acount - 1) % Rhsperline;
912 if (Rhstype[1] ==
'G') {
913 for (j = 0; j < nrhsentries; j++) {
914 std::fprintf(out_file, rformat, guess[j]);
915 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
917 if ((acount - 1) % Rhsperline != linemod) {
918 std::fprintf(out_file,
"\n");
919 linemod = (acount - 1) % Rhsperline;
921 guess += nrhsentries;
923 if (Rhstype[2] ==
'X') {
924 for (j = 0; j < nrhsentries; j++) {
925 std::fprintf(out_file, rformat, exact[j]);
926 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
928 if ((acount - 1) % Rhsperline != linemod) {
929 std::fprintf(out_file,
"\n");
930 linemod = (acount - 1) % Rhsperline;
932 exact += nrhsentries;
938 if (std::fclose(out_file) != 0) {
939 std::fprintf(stderr,
"Error closing file in writeHB_mat_double().\n");
945int readHB_mat_char(
const char* filename,
int colptr[],
int rowind[],
946 char val[],
char* Valfmt) {
966 int i, j, ind, col, offset, count, last;
967 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
968 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
969 int Ptrperline, Ptrwidth, Indperline, Indwidth;
970 int Valperline, Valwidth, Valprec;
974 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
975 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
977 if ((in_file = std::fopen(filename,
"r")) == NULL) {
978 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
982 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
983 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
984 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
987 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
988 ParseIfmt(Indfmt, &Indperline, &Indwidth);
989 if (Type[0] !=
'P') {
990 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
991 if (Valflag ==
'D') {
992 *std::strchr(Valfmt,
'D') =
'E';
998 offset = 1 - _SP_base;
1001 ThisElement = (
char*)malloc(Ptrwidth + 1);
1002 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1003 *(ThisElement + Ptrwidth) =
'\0';
1005 for (i = 0; i < Ptrcrd; i++) {
1006 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1007 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1010 if (std::sscanf(line,
"%*s") < 0)
1011 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
1013 for (ind = 0; ind < Ptrperline; ind++) {
1014 if (count > Ncol)
break;
1015 std::strncpy(ThisElement, line + col, Ptrwidth);
1017 colptr[count] = std::atoi(ThisElement) - offset;
1026 ThisElement = (
char*)malloc(Indwidth + 1);
1027 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1028 *(ThisElement + Indwidth) =
'\0';
1030 for (i = 0; i < Indcrd; i++) {
1031 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1032 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1035 if (std::sscanf(line,
"%*s") < 0)
1036 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
1038 for (ind = 0; ind < Indperline; ind++) {
1039 if (count == Nnzero)
break;
1040 std::strncpy(ThisElement, line + col, Indwidth);
1042 rowind[count] = std::atoi(ThisElement) - offset;
1051 if (Type[0] !=
'P') {
1054 Nentries = 2 * Nnzero;
1058 ThisElement = (
char*)malloc(Valwidth + 1);
1059 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1060 *(ThisElement + Valwidth) =
'\0';
1062 for (i = 0; i < Valcrd; i++) {
1063 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1064 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1067 if (std::sscanf(line,
"%*s") < 0)
1068 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
1069 if (Valflag ==
'D') {
1070 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1073 for (ind = 0; ind < Valperline; ind++) {
1074 if (count == Nentries)
break;
1075 ThisElement = &val[count * Valwidth];
1076 std::strncpy(ThisElement, line + col, Valwidth);
1078 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1080 last = std::strlen(ThisElement);
1081 for (j = last + 1; j >= 0; j--) {
1082 ThisElement[j] = ThisElement[j - 1];
1083 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1084 ThisElement[j - 1] = Valflag;
1098int readHB_newmat_char(
const char* filename,
int* M,
int* N,
int* nonzeros,
int** colptr,
1099 int** rowind,
char** val,
char** Valfmt) {
1102 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1103 int Valperline, Valwidth, Valprec;
1105 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1106 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
1108 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1109 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1113 *Valfmt = (
char*)malloc(21 *
sizeof(
char));
1114 if (*Valfmt == NULL) IOHBTerminate(
"Insufficient memory for Valfmt.");
1115 readHB_header(in_file, Title, Key, Type, M, N, nonzeros, &Nrhs,
1116 Ptrfmt, Indfmt, (*Valfmt), Rhsfmt,
1117 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1118 std::fclose(in_file);
1119 ParseRfmt(*Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1121 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
1122 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
1123 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
1124 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
1125 if (Type[0] ==
'C') {
1131 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char) * 2);
1132 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1134 if (Type[0] !=
'P') {
1136 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char));
1137 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1140 return readHB_mat_char(filename, *colptr, *rowind, *val, *Valfmt);
1143int readHB_aux_char(
const char* filename,
const char AuxType,
char b[]) {
1166 int i, j, n, maxcol,
start, stride, col, last, linel, nvecs, rhsi;
1167 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
1168 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1169 int Rhsperline, Rhswidth, Rhsprec;
1171 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1172 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
1176 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1177 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1181 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1182 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
1183 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1186 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
1189 if (Rhstype[0] !=
'F') {
1190 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
1191 std::fprintf(stderr,
" Rhs must be specified as full. \n");
1196 if (Type[0] ==
'C') {
1197 Nentries = 2 * Nrow;
1204 if (Rhstype[1] ==
'G') nvecs++;
1205 if (Rhstype[2] ==
'X') nvecs++;
1207 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
1208 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
1211 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
1212 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
1216 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1217 maxcol = Rhsperline * Rhswidth;
1220 n = Ptrcrd + Indcrd + Valcrd;
1222 for (i = 0; i < n; i++) {
1223 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1224 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1235 else if (AuxType ==
'G')
1238 start = (nvecs - 1) * Nentries;
1239 stride = (nvecs - 1) * Nentries;
1241 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1242 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1245 linel = std::strchr(line,
'\n') - line;
1246 if (std::sscanf(line,
"%*s") < 0)
1247 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1251 for (i = 0; i <
start; i++) {
1253 if (col >= (maxcol < linel ? maxcol : linel)) {
1254 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1255 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1258 linel = std::strchr(line,
'\n') - line;
1259 if (std::sscanf(line,
"%*s") < 0)
1260 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1265 if (Rhsflag ==
'D') {
1266 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1271 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
1272 for (i = 0; i < Nentries; i++) {
1273 if (col >= (maxcol < linel ? maxcol : linel)) {
1274 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1275 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1278 linel = std::strchr(line,
'\n') - line;
1279 if (std::sscanf(line,
"%*s") < 0)
1280 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1281 if (Rhsflag ==
'D') {
1282 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1286 ThisElement = &b[i * Rhswidth];
1287 std::strncpy(ThisElement, line + col, Rhswidth);
1288 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1290 last = std::strlen(ThisElement);
1291 for (j = last + 1; j >= 0; j--) {
1292 ThisElement[j] = ThisElement[j - 1];
1293 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1294 ThisElement[j - 1] = Rhsflag;
1301 b += Nentries * Rhswidth;
1305 for (i = 0; i < stride; i++) {
1307 if (col >= (maxcol < linel ? maxcol : linel)) {
1308 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1309 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1312 linel = std::strchr(line,
'\n') - line;
1313 if (std::sscanf(line,
"%*s") < 0)
1314 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1320 std::fclose(in_file);
1324int readHB_newaux_char(
const char* filename,
const char AuxType,
char** b,
char** Rhsfmt) {
1326 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1327 int Nrow, Ncol, Nnzero, Nrhs;
1328 int Rhsperline, Rhswidth, Rhsprec;
1330 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1331 char Ptrfmt[17], Indfmt[17], Valfmt[21];
1333 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1334 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1338 *Rhsfmt = (
char*)malloc(21 *
sizeof(
char));
1339 if (*Rhsfmt == NULL) IOHBTerminate(
"Insufficient memory for Rhsfmt.");
1340 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1341 Ptrfmt, Indfmt, Valfmt, (*Rhsfmt),
1342 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1343 std::fclose(in_file);
1345 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
1348 ParseRfmt(*Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1349 if (Type[0] ==
'C') {
1350 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
1351 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
1352 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char) * 2);
1353 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1354 return readHB_aux_char(filename, AuxType, *b);
1356 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char));
1357 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1358 return readHB_aux_char(filename, AuxType, *b);
1363int writeHB_mat_char(
const char* filename,
int M,
int N,
1364 int nz,
const int colptr[],
const int rowind[],
1365 const char val[],
int Nrhs,
const char rhs[],
1366 const char guess[],
const char exact[],
1367 const char* Title,
const char* Key,
const char* Type,
1368 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
1369 const char* Rhstype) {
1379 std::FILE* out_file;
1380 int i, j, acount, linemod, entry, offset;
1381 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
1382 int nvalentries, nrhsentries;
1383 int Ptrperline, Ptrwidth, Indperline, Indwidth;
1384 int Rhsperline, Rhswidth, Rhsprec;
1386 int Valperline, Valwidth, Valprec;
1388 char pformat[16], iformat[16], vformat[19], rformat[19];
1390 if (Type[0] ==
'C') {
1391 nvalentries = 2 * nz;
1392 nrhsentries = 2 * M;
1398 if (filename != NULL) {
1399 if ((out_file = std::fopen(filename,
"w")) == NULL) {
1400 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1406 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
1407 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
1408 std::sprintf(pformat,
"%%%dd", Ptrwidth);
1410 if (Indfmt == NULL) Indfmt = Ptrfmt;
1411 ParseIfmt(Indfmt, &Indperline, &Indwidth);
1412 std::sprintf(iformat,
"%%%dd", Indwidth);
1414 if (Type[0] !=
'P') {
1415 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
1416 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1417 std::sprintf(vformat,
"%%%ds", Valwidth);
1420 ptrcrd = (N + 1) / Ptrperline;
1421 if ((N + 1) % Ptrperline != 0) ptrcrd++;
1423 indcrd = nz / Indperline;
1424 if (nz % Indperline != 0) indcrd++;
1426 valcrd = nvalentries / Valperline;
1427 if (nvalentries % Valperline != 0) valcrd++;
1430 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
1431 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1432 std::sprintf(rformat,
"%%%ds", Rhswidth);
1433 rhscrd = nrhsentries / Rhsperline;
1434 if (nrhsentries % Rhsperline != 0) rhscrd++;
1435 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
1436 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
1441 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
1445 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
1446 ptrcrd, indcrd, valcrd, rhscrd);
1447 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
1448 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
1452 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
1454 std::fprintf(out_file,
"\n");
1456 offset = 1 - _SP_base;
1460 for (i = 0; i < N + 1; i++) {
1461 entry = colptr[i] + offset;
1462 std::fprintf(out_file, pformat, entry);
1463 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
1466 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
1469 for (i = 0; i < nz; i++) {
1470 entry = rowind[i] + offset;
1471 std::fprintf(out_file, iformat, entry);
1472 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
1475 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
1479 if (Type[0] !=
'P') {
1480 for (i = 0; i < nvalentries; i++) {
1481 std::fprintf(out_file, vformat, val + i * Valwidth);
1482 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
1485 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
1491 for (j = 0; j < Nrhs; j++) {
1492 for (i = 0; i < nrhsentries; i++) {
1493 std::fprintf(out_file, rformat, rhs + i * Rhswidth);
1494 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1496 if (acount % Rhsperline != linemod) {
1497 std::fprintf(out_file,
"\n");
1498 linemod = (acount - 1) % Rhsperline;
1500 if (Rhstype[1] ==
'G') {
1501 for (i = 0; i < nrhsentries; i++) {
1502 std::fprintf(out_file, rformat, guess + i * Rhswidth);
1503 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1505 if (acount % Rhsperline != linemod) {
1506 std::fprintf(out_file,
"\n");
1507 linemod = (acount - 1) % Rhsperline;
1510 if (Rhstype[2] ==
'X') {
1511 for (i = 0; i < nrhsentries; i++) {
1512 std::fprintf(out_file, rformat, exact + i * Rhswidth);
1513 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1515 if (acount % Rhsperline != linemod) {
1516 std::fprintf(out_file,
"\n");
1517 linemod = (acount - 1) % Rhsperline;
1524 if (std::fclose(out_file) != 0) {
1525 std::fprintf(stderr,
"Error closing file in writeHB_mat_char().\n");
1531int ParseIfmt(
char* fmt,
int* perline,
int* width) {
1543 tmp = std::strchr(fmt,
'(');
1544 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'I') - tmp - 1);
1545 *perline = std::atoi(tmp);
1546 if (*perline == 0) *perline = 1;
1547 if (tmp != NULL) free((
void*)tmp);
1548 tmp = std::strchr(fmt,
'I');
1549 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1550 *width = std::atoi(tmp);
1551 if (tmp != NULL) free((
void*)tmp);
1555int ParseRfmt(
char* fmt,
int* perline,
int* width,
int* prec,
int* flag) {
1576 if (std::strchr(fmt,
'(') != NULL) fmt = std::strchr(fmt,
'(');
1577 if (std::strchr(fmt,
')') != NULL) {
1578 tmp2 = std::strchr(fmt,
')');
1579 while (std::strchr(tmp2 + 1,
')') != NULL) {
1580 tmp2 = std::strchr(tmp2 + 1,
')');
1584 if (std::strchr(fmt,
'P') != NULL)
1586 if (std::strchr(fmt,
'(') != NULL) {
1587 tmp = std::strchr(fmt,
'P');
1588 if (*(++tmp) ==
',') tmp++;
1589 tmp3 = std::strchr(fmt,
'(') + 1;
1592 while (*(tmp2 + len) !=
'\0') {
1593 *tmp2 = *(tmp2 + len);
1596 *(std::strchr(fmt,
')') + 1) =
'\0';
1599 if (std::strchr(fmt,
'E') != NULL) {
1601 }
else if (std::strchr(fmt,
'D') != NULL) {
1603 }
else if (std::strchr(fmt,
'F') != NULL) {
1606 std::fprintf(stderr,
"Real format %s in H/B file not supported.\n", fmt);
1609 tmp = std::strchr(fmt,
'(');
1610 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt, *flag) - tmp - 1);
1611 *perline = std::atoi(tmp);
1612 if (*perline == 0) *perline = 1;
1613 if (tmp != NULL) free((
void*)tmp);
1614 tmp = std::strchr(fmt, *flag);
1615 if (std::strchr(fmt,
'.')) {
1616 tmp1 = substr(fmt, std::strchr(fmt,
'.') - fmt + 1, std::strchr(fmt,
')') - std::strchr(fmt,
'.') - 1);
1617 *prec = std::atoi(tmp1);
1618 if (tmp1 != NULL) free((
void*)tmp1);
1619 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'.') - tmp - 1);
1621 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1623 *width = std::atoi(tmp1);
1624 if (tmp1 != NULL) free((
void*)tmp1);
1628char* substr(
const char* S,
const int pos,
const int len) {
1631 if ((
size_t)pos + len <= std::strlen(S)) {
1632 SubS = (
char*)malloc(len + 1);
1633 if (SubS == NULL) IOHBTerminate(
"Insufficient memory for SubS.");
1634 for (i = 0; i < len; i++) SubS[i] = S[pos + i];
1642void upcase(
char* S) {
1645 len = ::std::strlen(S);
1646 for (i = 0; i < len; i++)
1647 S[i] = ::std::toupper(S[i]);
1650void IOHBTerminate(
const char* message) {
1651 ::std::fprintf(stderr,
"%s", message);
void start()
Start the deep_copy counter.