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,
char** 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 mat_type = (
char*)malloc(4);
261 if (mat_type == NULL) IOHBTerminate(
"Insufficient memory for mat_type\n");
263 if ((in_file = std::fopen(filename,
"r")) == NULL) {
264 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
268 readHB_header(in_file, Title, Key, mat_type, &Nrow, &Ncol, &Nnzero, Nrhs,
269 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
270 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
271 std::fclose(in_file);
297int readHB_header(std::FILE* in_file,
char* Title,
char* Key,
char* Type,
298 int* Nrow,
int* Ncol,
int* Nnzero,
int* Nrhs,
299 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
300 int* Ptrcrd,
int* Indcrd,
int* Valcrd,
int* Rhscrd,
305 int Totcrd, Neltvl, Nrhsix;
309 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
310 std::fprintf(stderr,
"Error: Failed to read from file.\n");
313 if (std::sscanf(line,
"%*s") < 0)
314 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) first line of HB file.\n");
315 (void)std::sscanf(line,
"%72c%8[^\n]", Title, Key);
317 *(Title + 72) =
'\0';
320 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
321 std::fprintf(stderr,
"Error: Failed to read from file.\n");
324 if (std::sscanf(line,
"%*s") < 0)
325 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) second line of HB file.\n");
326 if (std::sscanf(line,
"%i", &Totcrd) != 1) Totcrd = 0;
327 if (std::sscanf(line,
"%*i%i", Ptrcrd) != 1) *Ptrcrd = 0;
328 if (std::sscanf(line,
"%*i%*i%i", Indcrd) != 1) *Indcrd = 0;
329 if (std::sscanf(line,
"%*i%*i%*i%i", Valcrd) != 1) *Valcrd = 0;
330 if (std::sscanf(line,
"%*i%*i%*i%*i%i", Rhscrd) != 1) *Rhscrd = 0;
333 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
334 std::fprintf(stderr,
"Error: Failed to read from file.\n");
337 if (std::sscanf(line,
"%*s") < 0)
338 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) third line of HB file.\n");
340 if (std::sscanf(line,
"%3c", Type) != 1)
341 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid Type info, line 3 of Harwell-Boeing file.\n");
343 if (std::sscanf(line,
"%*3c%i", Nrow) != 1) *Nrow = 0;
344 if (std::sscanf(line,
"%*3c%*i%i", Ncol) != 1) *Ncol = 0;
345 if (std::sscanf(line,
"%*3c%*i%*i%i", Nnzero) != 1) *Nnzero = 0;
346 if (std::sscanf(line,
"%*3c%*i%*i%*i%i", &Neltvl) != 1) Neltvl = 0;
349 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
350 std::fprintf(stderr,
"Error: Failed to read from file.\n");
353 if (std::sscanf(line,
"%*s") < 0)
354 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fourth line of HB file.\n");
355 if (std::sscanf(line,
"%16c", Ptrfmt) != 1)
356 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
357 if (std::sscanf(line,
"%*16c%16c", Indfmt) != 1)
358 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
359 if (std::sscanf(line,
"%*16c%*16c%20c", Valfmt) != 1)
360 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
361 std::sscanf(line,
"%*16c%*16c%*20c%20c", Rhsfmt);
362 *(Ptrfmt + 16) =
'\0';
363 *(Indfmt + 16) =
'\0';
364 *(Valfmt + 20) =
'\0';
365 *(Rhsfmt + 20) =
'\0';
369 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
370 std::fprintf(stderr,
"Error: Failed to read from file.\n");
373 if (std::sscanf(line,
"%*s") < 0)
374 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fifth line of HB file.\n");
375 if (std::sscanf(line,
"%3c", Rhstype) != 1)
376 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid RHS type information, line 5 of Harwell-Boeing file.\n");
377 if (std::sscanf(line,
"%*3c%i", Nrhs) != 1) *Nrhs = 0;
378 if (std::sscanf(line,
"%*3c%*i%i", &Nrhsix) != 1) Nrhsix = 0;
383int readHB_mat_double(
const char* filename,
int colptr[],
int rowind[],
404 int i, j, ind, col, offset, count, last, Nrhs;
405 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
406 int Nrow, Ncol, Nnzero, Nentries;
407 int Ptrperline, Ptrwidth, Indperline, Indwidth;
408 int Valperline, Valwidth, Valprec;
411 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
412 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
415 if ((in_file = std::fopen(filename,
"r")) == NULL) {
416 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
420 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
421 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
422 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
425 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
426 ParseIfmt(Indfmt, &Indperline, &Indwidth);
427 if (Type[0] !=
'P') {
428 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
433 offset = 1 - _SP_base;
436 ThisElement = (
char*)malloc(Ptrwidth + 1);
437 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
438 *(ThisElement + Ptrwidth) =
'\0';
440 for (i = 0; i < Ptrcrd; i++) {
441 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
442 std::fprintf(stderr,
"Error: Failed to read from file.\n");
445 if (std::sscanf(line,
"%*s") < 0)
446 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
448 for (ind = 0; ind < Ptrperline; ind++) {
449 if (count > Ncol)
break;
450 std::strncpy(ThisElement, line + col, Ptrwidth);
452 colptr[count] = std::atoi(ThisElement) - offset;
461 ThisElement = (
char*)malloc(Indwidth + 1);
462 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
463 *(ThisElement + Indwidth) =
'\0';
465 for (i = 0; i < Indcrd; i++) {
466 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
467 std::fprintf(stderr,
"Error: Failed to read from file.\n");
470 if (std::sscanf(line,
"%*s") < 0)
471 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
473 for (ind = 0; ind < Indperline; ind++) {
474 if (count == Nnzero)
break;
475 std::strncpy(ThisElement, line + col, Indwidth);
477 rowind[count] = std::atoi(ThisElement) - offset;
486 if (Type[0] !=
'P') {
489 Nentries = 2 * Nnzero;
493 ThisElement = (
char*)malloc(Valwidth + 2);
494 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
495 *(ThisElement + Valwidth) =
'\0';
496 *(ThisElement + Valwidth + 1) =
'\0';
498 for (i = 0; i < Valcrd; i++) {
499 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
500 std::fprintf(stderr,
"Error: Failed to read from file.\n");
503 if (std::sscanf(line,
"%*s") < 0)
504 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
505 if (Valflag ==
'D') {
506 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
510 for (ind = 0; ind < Valperline; ind++) {
511 if (count == Nentries)
break;
512 std::strncpy(ThisElement, line + col, Valwidth);
514 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
516 last = std::strlen(ThisElement);
517 for (j = last + 1; j >= 0; j--) {
518 ThisElement[j] = ThisElement[j - 1];
519 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
520 ThisElement[j - 1] = Valflag;
525 val[count] = std::atof(ThisElement);
528 *(ThisElement + Valwidth) =
'\0';
529 *(ThisElement + Valwidth + 1) =
'\0';
535 std::fclose(in_file);
539int readHB_newmat_double(
const char* filename,
int* M,
int* N,
int* nonzeros,
540 int** colptr,
int** rowind,
double** val) {
544 if (readHB_info(filename, M, N, nonzeros, &Type, &Nrhs) == 0) {
548 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
549 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
550 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
551 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
552 if (Type[0] ==
'C') {
558 *val = (
double*)malloc(*nonzeros *
sizeof(
double) * 2);
559 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
561 if (Type[0] !=
'P') {
563 *val = (
double*)malloc(*nonzeros *
sizeof(
double));
564 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
567 return readHB_mat_double(filename, *colptr, *rowind, *val);
570int readHB_aux_double(
const char* filename,
const char AuxType,
double b[]) {
593 int i, j, n, maxcol,
start, stride, col, last, linel;
594 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
595 int Nrow, Ncol, Nnzero, Nentries;
596 int Nrhs, nvecs, rhsi;
597 int Rhsperline, Rhswidth, Rhsprec;
600 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
601 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
604 if ((in_file = std::fopen(filename,
"r")) == NULL) {
605 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
609 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
610 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
611 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
614 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
617 if (Rhstype[0] !=
'F') {
618 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
619 std::fprintf(stderr,
" Rhs must be specified as full. \n");
624 if (Type[0] ==
'C') {
632 if (Rhstype[1] ==
'G') nvecs++;
633 if (Rhstype[2] ==
'X') nvecs++;
635 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
636 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
639 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
640 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
644 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
645 maxcol = Rhsperline * Rhswidth;
648 n = Ptrcrd + Indcrd + Valcrd;
650 for (i = 0; i < n; i++) {
651 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
652 std::fprintf(stderr,
"Error: Failed to read from file.\n");
663 else if (AuxType ==
'G')
666 start = (nvecs - 1) * Nentries;
667 stride = (nvecs - 1) * Nentries;
669 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
670 std::fprintf(stderr,
"Error: Failed to read from file.\n");
673 linel = std::strchr(line,
'\n') - line;
677 for (i = 0; i <
start; i++) {
678 if (col >= (maxcol < linel ? maxcol : linel)) {
679 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
680 std::fprintf(stderr,
"Error: Failed to read from file.\n");
683 linel = std::strchr(line,
'\n') - line;
688 if (Rhsflag ==
'D') {
689 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
695 ThisElement = (
char*)malloc(Rhswidth + 1);
696 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
697 *(ThisElement + Rhswidth) =
'\0';
698 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
699 for (i = 0; i < Nentries; i++) {
700 if (col >= (maxcol < linel ? maxcol : linel)) {
701 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
702 std::fprintf(stderr,
"Error: Failed to read from file.\n");
705 linel = std::strchr(line,
'\n') - line;
706 if (Rhsflag ==
'D') {
707 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
711 std::strncpy(ThisElement, line + col, Rhswidth);
713 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
715 last = std::strlen(ThisElement);
716 for (j = last + 1; j >= 0; j--) {
717 ThisElement[j] = ThisElement[j - 1];
718 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
719 ThisElement[j - 1] = Rhsflag;
724 b[i] = std::atof(ThisElement);
730 for (i = 0; i < stride; i++) {
731 if (col >= (maxcol < linel ? maxcol : linel)) {
732 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
733 std::fprintf(stderr,
"Error: Failed to read from file.\n");
736 linel = std::strchr(line,
'\n') - line;
744 std::fclose(in_file);
748int readHB_newaux_double(
const char* filename,
const char AuxType,
double** b) {
755 readHB_info(filename, &M, &N, &nonzeros, &Type, &Nrhs);
757 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
760 if (Type[0] ==
'C') {
761 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
762 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
763 *b = (
double*)malloc(M * Nrhs *
sizeof(
double) * 2);
764 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
765 return readHB_aux_double(filename, AuxType, *b);
767 *b = (
double*)malloc(M * Nrhs *
sizeof(
double));
768 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
769 return readHB_aux_double(filename, AuxType, *b);
774int writeHB_mat_double(
const char* filename,
int M,
int N,
775 int nz,
const int colptr[],
const int rowind[],
776 const double val[],
int Nrhs,
const double rhs[],
777 const double guess[],
const double exact[],
778 const char* Title,
const char* Key,
const char* Type,
779 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
780 const char* Rhstype) {
791 int i, j, entry, offset, acount, linemod;
792 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
793 int nvalentries, nrhsentries;
794 int Ptrperline, Ptrwidth, Indperline, Indwidth;
795 int Rhsperline, Rhswidth, Rhsprec;
797 int Valperline, Valwidth, Valprec;
799 char pformat[16], iformat[16], vformat[19], rformat[19];
801 if (Type[0] ==
'C') {
802 nvalentries = 2 * nz;
809 if (filename != NULL) {
810 if ((out_file = std::fopen(filename,
"w")) == NULL) {
811 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
817 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
818 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
819 std::sprintf(pformat,
"%%%dd", Ptrwidth);
820 ptrcrd = (N + 1) / Ptrperline;
821 if ((N + 1) % Ptrperline != 0) ptrcrd++;
823 if (Indfmt == NULL) Indfmt = Ptrfmt;
824 ParseIfmt(Indfmt, &Indperline, &Indwidth);
825 std::sprintf(iformat,
"%%%dd", Indwidth);
826 indcrd = nz / Indperline;
827 if (nz % Indperline != 0) indcrd++;
829 if (Type[0] !=
'P') {
830 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
831 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
832 if (Valflag ==
'D') *std::strchr(Valfmt,
'D') =
'E';
834 std::sprintf(vformat,
"%% %d.%df", Valwidth, Valprec);
836 std::sprintf(vformat,
"%% %d.%dE", Valwidth, Valprec);
837 valcrd = nvalentries / Valperline;
838 if (nvalentries % Valperline != 0) valcrd++;
843 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
844 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
846 std::sprintf(rformat,
"%% %d.%df", Rhswidth, Rhsprec);
848 std::sprintf(rformat,
"%% %d.%dE", Rhswidth, Rhsprec);
849 if (Rhsflag ==
'D') *std::strchr(Rhsfmt,
'D') =
'E';
850 rhscrd = nrhsentries / Rhsperline;
851 if (nrhsentries % Rhsperline != 0) rhscrd++;
852 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
853 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
858 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
862 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
863 ptrcrd, indcrd, valcrd, rhscrd);
864 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
865 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
869 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
871 std::fprintf(out_file,
"\n");
873 offset = 1 - _SP_base;
877 for (i = 0; i < N + 1; i++) {
878 entry = colptr[i] + offset;
879 std::fprintf(out_file, pformat, entry);
880 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
883 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
886 for (i = 0; i < nz; i++) {
887 entry = rowind[i] + offset;
888 std::fprintf(out_file, iformat, entry);
889 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
892 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
896 if (Type[0] !=
'P') {
898 for (i = 0; i < nvalentries; i++) {
899 std::fprintf(out_file, vformat, val[i]);
900 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
903 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
910 for (i = 0; i < Nrhs; i++) {
911 for (j = 0; j < nrhsentries; j++) {
912 std::fprintf(out_file, rformat, rhs[j]);
913 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
915 if ((acount - 1) % Rhsperline != linemod) {
916 std::fprintf(out_file,
"\n");
917 linemod = (acount - 1) % Rhsperline;
920 if (Rhstype[1] ==
'G') {
921 for (j = 0; j < nrhsentries; j++) {
922 std::fprintf(out_file, rformat, guess[j]);
923 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
925 if ((acount - 1) % Rhsperline != linemod) {
926 std::fprintf(out_file,
"\n");
927 linemod = (acount - 1) % Rhsperline;
929 guess += nrhsentries;
931 if (Rhstype[2] ==
'X') {
932 for (j = 0; j < nrhsentries; j++) {
933 std::fprintf(out_file, rformat, exact[j]);
934 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
936 if ((acount - 1) % Rhsperline != linemod) {
937 std::fprintf(out_file,
"\n");
938 linemod = (acount - 1) % Rhsperline;
940 exact += nrhsentries;
946 if (std::fclose(out_file) != 0) {
947 std::fprintf(stderr,
"Error closing file in writeHB_mat_double().\n");
953int readHB_mat_char(
const char* filename,
int colptr[],
int rowind[],
954 char val[],
char* Valfmt) {
974 int i, j, ind, col, offset, count, last;
975 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
976 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
977 int Ptrperline, Ptrwidth, Indperline, Indwidth;
978 int Valperline, Valwidth, Valprec;
982 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
983 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
985 if ((in_file = std::fopen(filename,
"r")) == NULL) {
986 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
990 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
991 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
992 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
995 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
996 ParseIfmt(Indfmt, &Indperline, &Indwidth);
997 if (Type[0] !=
'P') {
998 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
999 if (Valflag ==
'D') {
1000 *std::strchr(Valfmt,
'D') =
'E';
1006 offset = 1 - _SP_base;
1009 ThisElement = (
char*)malloc(Ptrwidth + 1);
1010 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1011 *(ThisElement + Ptrwidth) =
'\0';
1013 for (i = 0; i < Ptrcrd; i++) {
1014 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1015 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1018 if (std::sscanf(line,
"%*s") < 0)
1019 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
1021 for (ind = 0; ind < Ptrperline; ind++) {
1022 if (count > Ncol)
break;
1023 std::strncpy(ThisElement, line + col, Ptrwidth);
1025 colptr[count] = std::atoi(ThisElement) - offset;
1034 ThisElement = (
char*)malloc(Indwidth + 1);
1035 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1036 *(ThisElement + Indwidth) =
'\0';
1038 for (i = 0; i < Indcrd; i++) {
1039 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1040 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1043 if (std::sscanf(line,
"%*s") < 0)
1044 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
1046 for (ind = 0; ind < Indperline; ind++) {
1047 if (count == Nnzero)
break;
1048 std::strncpy(ThisElement, line + col, Indwidth);
1050 rowind[count] = std::atoi(ThisElement) - offset;
1059 if (Type[0] !=
'P') {
1062 Nentries = 2 * Nnzero;
1066 ThisElement = (
char*)malloc(Valwidth + 1);
1067 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1068 *(ThisElement + Valwidth) =
'\0';
1070 for (i = 0; i < Valcrd; i++) {
1071 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1072 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1075 if (std::sscanf(line,
"%*s") < 0)
1076 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
1077 if (Valflag ==
'D') {
1078 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1081 for (ind = 0; ind < Valperline; ind++) {
1082 if (count == Nentries)
break;
1083 ThisElement = &val[count * Valwidth];
1084 std::strncpy(ThisElement, line + col, Valwidth);
1086 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1088 last = std::strlen(ThisElement);
1089 for (j = last + 1; j >= 0; j--) {
1090 ThisElement[j] = ThisElement[j - 1];
1091 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1092 ThisElement[j - 1] = Valflag;
1106int readHB_newmat_char(
const char* filename,
int* M,
int* N,
int* nonzeros,
int** colptr,
1107 int** rowind,
char** val,
char** Valfmt) {
1110 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1111 int Valperline, Valwidth, Valprec;
1113 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1114 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
1116 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1117 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1121 *Valfmt = (
char*)malloc(21 *
sizeof(
char));
1122 if (*Valfmt == NULL) IOHBTerminate(
"Insufficient memory for Valfmt.");
1123 readHB_header(in_file, Title, Key, Type, M, N, nonzeros, &Nrhs,
1124 Ptrfmt, Indfmt, (*Valfmt), Rhsfmt,
1125 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1126 std::fclose(in_file);
1127 ParseRfmt(*Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1129 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
1130 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
1131 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
1132 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
1133 if (Type[0] ==
'C') {
1139 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char) * 2);
1140 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1142 if (Type[0] !=
'P') {
1144 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char));
1145 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1148 return readHB_mat_char(filename, *colptr, *rowind, *val, *Valfmt);
1151int readHB_aux_char(
const char* filename,
const char AuxType,
char b[]) {
1174 int i, j, n, maxcol,
start, stride, col, last, linel, nvecs, rhsi;
1175 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
1176 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1177 int Rhsperline, Rhswidth, Rhsprec;
1179 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1180 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
1184 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1185 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1189 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1190 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
1191 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1194 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
1197 if (Rhstype[0] !=
'F') {
1198 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
1199 std::fprintf(stderr,
" Rhs must be specified as full. \n");
1204 if (Type[0] ==
'C') {
1205 Nentries = 2 * Nrow;
1212 if (Rhstype[1] ==
'G') nvecs++;
1213 if (Rhstype[2] ==
'X') nvecs++;
1215 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
1216 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
1219 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
1220 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
1224 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1225 maxcol = Rhsperline * Rhswidth;
1228 n = Ptrcrd + Indcrd + Valcrd;
1230 for (i = 0; i < n; i++) {
1231 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1232 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1243 else if (AuxType ==
'G')
1246 start = (nvecs - 1) * Nentries;
1247 stride = (nvecs - 1) * Nentries;
1249 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1250 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1253 linel = std::strchr(line,
'\n') - line;
1254 if (std::sscanf(line,
"%*s") < 0)
1255 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1259 for (i = 0; i <
start; i++) {
1261 if (col >= (maxcol < linel ? maxcol : linel)) {
1262 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1263 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1266 linel = std::strchr(line,
'\n') - line;
1267 if (std::sscanf(line,
"%*s") < 0)
1268 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1273 if (Rhsflag ==
'D') {
1274 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1279 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
1280 for (i = 0; i < Nentries; i++) {
1281 if (col >= (maxcol < linel ? maxcol : linel)) {
1282 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1283 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1286 linel = std::strchr(line,
'\n') - line;
1287 if (std::sscanf(line,
"%*s") < 0)
1288 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1289 if (Rhsflag ==
'D') {
1290 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1294 ThisElement = &b[i * Rhswidth];
1295 std::strncpy(ThisElement, line + col, Rhswidth);
1296 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1298 last = std::strlen(ThisElement);
1299 for (j = last + 1; j >= 0; j--) {
1300 ThisElement[j] = ThisElement[j - 1];
1301 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1302 ThisElement[j - 1] = Rhsflag;
1309 b += Nentries * Rhswidth;
1313 for (i = 0; i < stride; i++) {
1315 if (col >= (maxcol < linel ? maxcol : linel)) {
1316 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1317 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1320 linel = std::strchr(line,
'\n') - line;
1321 if (std::sscanf(line,
"%*s") < 0)
1322 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1328 std::fclose(in_file);
1332int readHB_newaux_char(
const char* filename,
const char AuxType,
char** b,
char** Rhsfmt) {
1334 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1335 int Nrow, Ncol, Nnzero, Nrhs;
1336 int Rhsperline, Rhswidth, Rhsprec;
1338 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1339 char Ptrfmt[17], Indfmt[17], Valfmt[21];
1341 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1342 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1346 *Rhsfmt = (
char*)malloc(21 *
sizeof(
char));
1347 if (*Rhsfmt == NULL) IOHBTerminate(
"Insufficient memory for Rhsfmt.");
1348 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1349 Ptrfmt, Indfmt, Valfmt, (*Rhsfmt),
1350 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1351 std::fclose(in_file);
1353 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
1356 ParseRfmt(*Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1357 if (Type[0] ==
'C') {
1358 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
1359 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
1360 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char) * 2);
1361 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1362 return readHB_aux_char(filename, AuxType, *b);
1364 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char));
1365 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1366 return readHB_aux_char(filename, AuxType, *b);
1371int writeHB_mat_char(
const char* filename,
int M,
int N,
1372 int nz,
const int colptr[],
const int rowind[],
1373 const char val[],
int Nrhs,
const char rhs[],
1374 const char guess[],
const char exact[],
1375 const char* Title,
const char* Key,
const char* Type,
1376 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
1377 const char* Rhstype) {
1387 std::FILE* out_file;
1388 int i, j, acount, linemod, entry, offset;
1389 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
1390 int nvalentries, nrhsentries;
1391 int Ptrperline, Ptrwidth, Indperline, Indwidth;
1392 int Rhsperline, Rhswidth, Rhsprec;
1394 int Valperline, Valwidth, Valprec;
1396 char pformat[16], iformat[16], vformat[19], rformat[19];
1398 if (Type[0] ==
'C') {
1399 nvalentries = 2 * nz;
1400 nrhsentries = 2 * M;
1406 if (filename != NULL) {
1407 if ((out_file = std::fopen(filename,
"w")) == NULL) {
1408 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1414 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
1415 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
1416 std::sprintf(pformat,
"%%%dd", Ptrwidth);
1418 if (Indfmt == NULL) Indfmt = Ptrfmt;
1419 ParseIfmt(Indfmt, &Indperline, &Indwidth);
1420 std::sprintf(iformat,
"%%%dd", Indwidth);
1422 if (Type[0] !=
'P') {
1423 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
1424 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1425 std::sprintf(vformat,
"%%%ds", Valwidth);
1428 ptrcrd = (N + 1) / Ptrperline;
1429 if ((N + 1) % Ptrperline != 0) ptrcrd++;
1431 indcrd = nz / Indperline;
1432 if (nz % Indperline != 0) indcrd++;
1434 valcrd = nvalentries / Valperline;
1435 if (nvalentries % Valperline != 0) valcrd++;
1438 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
1439 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1440 std::sprintf(rformat,
"%%%ds", Rhswidth);
1441 rhscrd = nrhsentries / Rhsperline;
1442 if (nrhsentries % Rhsperline != 0) rhscrd++;
1443 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
1444 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
1449 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
1453 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
1454 ptrcrd, indcrd, valcrd, rhscrd);
1455 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
1456 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
1460 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
1462 std::fprintf(out_file,
"\n");
1464 offset = 1 - _SP_base;
1468 for (i = 0; i < N + 1; i++) {
1469 entry = colptr[i] + offset;
1470 std::fprintf(out_file, pformat, entry);
1471 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
1474 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
1477 for (i = 0; i < nz; i++) {
1478 entry = rowind[i] + offset;
1479 std::fprintf(out_file, iformat, entry);
1480 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
1483 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
1487 if (Type[0] !=
'P') {
1488 for (i = 0; i < nvalentries; i++) {
1489 std::fprintf(out_file, vformat, val + i * Valwidth);
1490 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
1493 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
1499 for (j = 0; j < Nrhs; j++) {
1500 for (i = 0; i < nrhsentries; i++) {
1501 std::fprintf(out_file, rformat, rhs + i * Rhswidth);
1502 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1504 if (acount % Rhsperline != linemod) {
1505 std::fprintf(out_file,
"\n");
1506 linemod = (acount - 1) % Rhsperline;
1508 if (Rhstype[1] ==
'G') {
1509 for (i = 0; i < nrhsentries; i++) {
1510 std::fprintf(out_file, rformat, guess + i * Rhswidth);
1511 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1513 if (acount % Rhsperline != linemod) {
1514 std::fprintf(out_file,
"\n");
1515 linemod = (acount - 1) % Rhsperline;
1518 if (Rhstype[2] ==
'X') {
1519 for (i = 0; i < nrhsentries; i++) {
1520 std::fprintf(out_file, rformat, exact + i * Rhswidth);
1521 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1523 if (acount % Rhsperline != linemod) {
1524 std::fprintf(out_file,
"\n");
1525 linemod = (acount - 1) % Rhsperline;
1532 if (std::fclose(out_file) != 0) {
1533 std::fprintf(stderr,
"Error closing file in writeHB_mat_char().\n");
1539int ParseIfmt(
char* fmt,
int* perline,
int* width) {
1551 tmp = std::strchr(fmt,
'(');
1552 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'I') - tmp - 1);
1553 *perline = std::atoi(tmp);
1554 if (*perline == 0) *perline = 1;
1555 if (tmp != NULL) free((
void*)tmp);
1556 tmp = std::strchr(fmt,
'I');
1557 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1558 *width = std::atoi(tmp);
1559 if (tmp != NULL) free((
void*)tmp);
1563int ParseRfmt(
char* fmt,
int* perline,
int* width,
int* prec,
int* flag) {
1584 if (std::strchr(fmt,
'(') != NULL) fmt = std::strchr(fmt,
'(');
1585 if (std::strchr(fmt,
')') != NULL) {
1586 tmp2 = std::strchr(fmt,
')');
1587 while (std::strchr(tmp2 + 1,
')') != NULL) {
1588 tmp2 = std::strchr(tmp2 + 1,
')');
1592 if (std::strchr(fmt,
'P') != NULL)
1594 if (std::strchr(fmt,
'(') != NULL) {
1595 tmp = std::strchr(fmt,
'P');
1596 if (*(++tmp) ==
',') tmp++;
1597 tmp3 = std::strchr(fmt,
'(') + 1;
1600 while (*(tmp2 + len) !=
'\0') {
1601 *tmp2 = *(tmp2 + len);
1604 *(std::strchr(fmt,
')') + 1) =
'\0';
1607 if (std::strchr(fmt,
'E') != NULL) {
1609 }
else if (std::strchr(fmt,
'D') != NULL) {
1611 }
else if (std::strchr(fmt,
'F') != NULL) {
1614 std::fprintf(stderr,
"Real format %s in H/B file not supported.\n", fmt);
1617 tmp = std::strchr(fmt,
'(');
1618 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt, *flag) - tmp - 1);
1619 *perline = std::atoi(tmp);
1620 if (*perline == 0) *perline = 1;
1621 if (tmp != NULL) free((
void*)tmp);
1622 tmp = std::strchr(fmt, *flag);
1623 if (std::strchr(fmt,
'.')) {
1624 tmp1 = substr(fmt, std::strchr(fmt,
'.') - fmt + 1, std::strchr(fmt,
')') - std::strchr(fmt,
'.') - 1);
1625 *prec = std::atoi(tmp1);
1626 if (tmp1 != NULL) free((
void*)tmp1);
1627 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'.') - tmp - 1);
1629 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1631 *width = std::atoi(tmp1);
1632 if (tmp1 != NULL) free((
void*)tmp1);
1636char* substr(
const char* S,
const int pos,
const int len) {
1639 if ((
size_t)pos + len <= std::strlen(S)) {
1640 SubS = (
char*)malloc(len + 1);
1641 if (SubS == NULL) IOHBTerminate(
"Insufficient memory for SubS.");
1642 for (i = 0; i < len; i++) SubS[i] = S[pos + i];
1650void upcase(
char* S) {
1653 len = ::std::strlen(S);
1654 for (i = 0; i < len; i++)
1655 S[i] = ::std::toupper(S[i]);
1658void IOHBTerminate(
const char* message) {
1659 ::std::fprintf(stderr,
"%s", message);
void start()
Start the deep_copy counter.