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");
339 if (std::sscanf(line,
"%3c", Type) != 1)
340 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid Type info, line 3 of Harwell-Boeing file.\n");
342 if (std::sscanf(line,
"%*3c%i", Nrow) != 1) *Nrow = 0;
343 if (std::sscanf(line,
"%*3c%*i%i", Ncol) != 1) *Ncol = 0;
344 if (std::sscanf(line,
"%*3c%*i%*i%i", Nnzero) != 1) *Nnzero = 0;
345 if (std::sscanf(line,
"%*3c%*i%*i%*i%i", &Neltvl) != 1) Neltvl = 0;
348 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
349 std::fprintf(stderr,
"Error: Failed to read from file.\n");
352 if (std::sscanf(line,
"%*s") < 0)
353 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fourth line of HB file.\n");
354 if (std::sscanf(line,
"%16c", Ptrfmt) != 1)
355 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
356 if (std::sscanf(line,
"%*16c%16c", Indfmt) != 1)
357 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
358 if (std::sscanf(line,
"%*16c%*16c%20c", Valfmt) != 1)
359 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid format info, line 4 of Harwell-Boeing file.\n");
360 std::sscanf(line,
"%*16c%*16c%*20c%20c", Rhsfmt);
361 *(Ptrfmt + 16) =
'\0';
362 *(Indfmt + 16) =
'\0';
363 *(Valfmt + 20) =
'\0';
364 *(Rhsfmt + 20) =
'\0';
368 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
369 std::fprintf(stderr,
"Error: Failed to read from file.\n");
372 if (std::sscanf(line,
"%*s") < 0)
373 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) fifth line of HB file.\n");
374 if (std::sscanf(line,
"%3c", Rhstype) != 1)
375 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Invalid RHS type information, line 5 of Harwell-Boeing file.\n");
376 if (std::sscanf(line,
"%*3c%i", Nrhs) != 1) *Nrhs = 0;
377 if (std::sscanf(line,
"%*3c%*i%i", &Nrhsix) != 1) Nrhsix = 0;
382int readHB_mat_double(
const char* filename,
int colptr[],
int rowind[],
403 int i, j, ind, col, offset, count, last, Nrhs;
404 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
405 int Nrow, Ncol, Nnzero, Nentries;
406 int Ptrperline, Ptrwidth, Indperline, Indwidth;
407 int Valperline, Valwidth, Valprec;
410 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
411 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
414 if ((in_file = std::fopen(filename,
"r")) == NULL) {
415 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
419 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
420 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
421 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
424 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
425 ParseIfmt(Indfmt, &Indperline, &Indwidth);
426 if (Type[0] !=
'P') {
427 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
432 offset = 1 - _SP_base;
435 ThisElement = (
char*)malloc(Ptrwidth + 1);
436 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
437 *(ThisElement + Ptrwidth) =
'\0';
439 for (i = 0; i < Ptrcrd; i++) {
440 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
441 std::fprintf(stderr,
"Error: Failed to read from file.\n");
444 if (std::sscanf(line,
"%*s") < 0)
445 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
447 for (ind = 0; ind < Ptrperline; ind++) {
448 if (count > Ncol)
break;
449 std::strncpy(ThisElement, line + col, Ptrwidth);
451 colptr[count] = std::atoi(ThisElement) - offset;
460 ThisElement = (
char*)malloc(Indwidth + 1);
461 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
462 *(ThisElement + Indwidth) =
'\0';
464 for (i = 0; i < Indcrd; i++) {
465 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
466 std::fprintf(stderr,
"Error: Failed to read from file.\n");
469 if (std::sscanf(line,
"%*s") < 0)
470 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
472 for (ind = 0; ind < Indperline; ind++) {
473 if (count == Nnzero)
break;
474 std::strncpy(ThisElement, line + col, Indwidth);
476 rowind[count] = std::atoi(ThisElement) - offset;
485 if (Type[0] !=
'P') {
488 Nentries = 2 * Nnzero;
492 ThisElement = (
char*)malloc(Valwidth + 2);
493 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
494 *(ThisElement + Valwidth) =
'\0';
495 *(ThisElement + Valwidth + 1) =
'\0';
497 for (i = 0; i < Valcrd; i++) {
498 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
499 std::fprintf(stderr,
"Error: Failed to read from file.\n");
502 if (std::sscanf(line,
"%*s") < 0)
503 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
504 if (Valflag ==
'D') {
505 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
509 for (ind = 0; ind < Valperline; ind++) {
510 if (count == Nentries)
break;
511 std::strncpy(ThisElement, line + col, Valwidth);
513 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
515 last = std::strlen(ThisElement);
516 for (j = last + 1; j >= 0; j--) {
517 ThisElement[j] = ThisElement[j - 1];
518 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
519 ThisElement[j - 1] = Valflag;
524 val[count] = std::atof(ThisElement);
527 *(ThisElement + Valwidth) =
'\0';
528 *(ThisElement + Valwidth + 1) =
'\0';
534 std::fclose(in_file);
538int readHB_newmat_double(
const char* filename,
int* M,
int* N,
int* nonzeros,
539 int** colptr,
int** rowind,
double** val) {
543 if (readHB_info(filename, M, N, nonzeros, &Type, &Nrhs) == 0) {
547 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
548 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
549 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
550 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
551 if (Type[0] ==
'C') {
557 *val = (
double*)malloc(*nonzeros *
sizeof(
double) * 2);
558 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
560 if (Type[0] !=
'P') {
562 *val = (
double*)malloc(*nonzeros *
sizeof(
double));
563 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
566 return readHB_mat_double(filename, *colptr, *rowind, *val);
569int readHB_aux_double(
const char* filename,
const char AuxType,
double b[]) {
592 int i, j, n, maxcol,
start, stride, col, last, linel;
593 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
594 int Nrow, Ncol, Nnzero, Nentries;
595 int Nrhs, nvecs, rhsi;
596 int Rhsperline, Rhswidth, Rhsprec;
599 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
600 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
603 if ((in_file = std::fopen(filename,
"r")) == NULL) {
604 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
608 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
609 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
610 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
613 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
616 if (Rhstype[0] !=
'F') {
617 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
618 std::fprintf(stderr,
" Rhs must be specified as full. \n");
623 if (Type[0] ==
'C') {
631 if (Rhstype[1] ==
'G') nvecs++;
632 if (Rhstype[2] ==
'X') nvecs++;
634 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
635 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
638 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
639 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
643 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
644 maxcol = Rhsperline * Rhswidth;
647 n = Ptrcrd + Indcrd + Valcrd;
649 for (i = 0; i < n; i++) {
650 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
651 std::fprintf(stderr,
"Error: Failed to read from file.\n");
662 else if (AuxType ==
'G')
665 start = (nvecs - 1) * Nentries;
666 stride = (nvecs - 1) * Nentries;
668 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
669 std::fprintf(stderr,
"Error: Failed to read from file.\n");
672 linel = std::strchr(line,
'\n') - line;
676 for (i = 0; i <
start; i++) {
677 if (col >= (maxcol < linel ? maxcol : linel)) {
678 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
679 std::fprintf(stderr,
"Error: Failed to read from file.\n");
682 linel = std::strchr(line,
'\n') - line;
687 if (Rhsflag ==
'D') {
688 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
694 ThisElement = (
char*)malloc(Rhswidth + 1);
695 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
696 *(ThisElement + Rhswidth) =
'\0';
697 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
698 for (i = 0; i < Nentries; i++) {
699 if (col >= (maxcol < linel ? maxcol : linel)) {
700 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
701 std::fprintf(stderr,
"Error: Failed to read from file.\n");
704 linel = std::strchr(line,
'\n') - line;
705 if (Rhsflag ==
'D') {
706 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
710 std::strncpy(ThisElement, line + col, Rhswidth);
712 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
714 last = std::strlen(ThisElement);
715 for (j = last + 1; j >= 0; j--) {
716 ThisElement[j] = ThisElement[j - 1];
717 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
718 ThisElement[j - 1] = Rhsflag;
723 b[i] = std::atof(ThisElement);
729 for (i = 0; i < stride; i++) {
730 if (col >= (maxcol < linel ? maxcol : linel)) {
731 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
732 std::fprintf(stderr,
"Error: Failed to read from file.\n");
735 linel = std::strchr(line,
'\n') - line;
743 std::fclose(in_file);
747int readHB_newaux_double(
const char* filename,
const char AuxType,
double** b) {
754 readHB_info(filename, &M, &N, &nonzeros, &Type, &Nrhs);
756 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
759 if (Type[0] ==
'C') {
760 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
761 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
762 *b = (
double*)malloc(M * Nrhs *
sizeof(
double) * 2);
763 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
764 return readHB_aux_double(filename, AuxType, *b);
766 *b = (
double*)malloc(M * Nrhs *
sizeof(
double));
767 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
768 return readHB_aux_double(filename, AuxType, *b);
773int writeHB_mat_double(
const char* filename,
int M,
int N,
774 int nz,
const int colptr[],
const int rowind[],
775 const double val[],
int Nrhs,
const double rhs[],
776 const double guess[],
const double exact[],
777 const char* Title,
const char* Key,
const char* Type,
778 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
779 const char* Rhstype) {
790 int i, j, entry, offset, acount, linemod;
791 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
792 int nvalentries, nrhsentries;
793 int Ptrperline, Ptrwidth, Indperline, Indwidth;
794 int Rhsperline, Rhswidth, Rhsprec;
796 int Valperline, Valwidth, Valprec;
798 char pformat[16], iformat[16], vformat[19], rformat[19];
800 if (Type[0] ==
'C') {
801 nvalentries = 2 * nz;
808 if (filename != NULL) {
809 if ((out_file = std::fopen(filename,
"w")) == NULL) {
810 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
816 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
817 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
818 std::sprintf(pformat,
"%%%dd", Ptrwidth);
819 ptrcrd = (N + 1) / Ptrperline;
820 if ((N + 1) % Ptrperline != 0) ptrcrd++;
822 if (Indfmt == NULL) Indfmt = Ptrfmt;
823 ParseIfmt(Indfmt, &Indperline, &Indwidth);
824 std::sprintf(iformat,
"%%%dd", Indwidth);
825 indcrd = nz / Indperline;
826 if (nz % Indperline != 0) indcrd++;
828 if (Type[0] !=
'P') {
829 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
830 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
831 if (Valflag ==
'D') *std::strchr(Valfmt,
'D') =
'E';
833 std::sprintf(vformat,
"%% %d.%df", Valwidth, Valprec);
835 std::sprintf(vformat,
"%% %d.%dE", Valwidth, Valprec);
836 valcrd = nvalentries / Valperline;
837 if (nvalentries % Valperline != 0) valcrd++;
842 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
843 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
845 std::sprintf(rformat,
"%% %d.%df", Rhswidth, Rhsprec);
847 std::sprintf(rformat,
"%% %d.%dE", Rhswidth, Rhsprec);
848 if (Rhsflag ==
'D') *std::strchr(Rhsfmt,
'D') =
'E';
849 rhscrd = nrhsentries / Rhsperline;
850 if (nrhsentries % Rhsperline != 0) rhscrd++;
851 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
852 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
857 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
861 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
862 ptrcrd, indcrd, valcrd, rhscrd);
863 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
864 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
868 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
870 std::fprintf(out_file,
"\n");
872 offset = 1 - _SP_base;
876 for (i = 0; i < N + 1; i++) {
877 entry = colptr[i] + offset;
878 std::fprintf(out_file, pformat, entry);
879 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
882 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
885 for (i = 0; i < nz; i++) {
886 entry = rowind[i] + offset;
887 std::fprintf(out_file, iformat, entry);
888 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
891 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
895 if (Type[0] !=
'P') {
897 for (i = 0; i < nvalentries; i++) {
898 std::fprintf(out_file, vformat, val[i]);
899 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
902 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
909 for (i = 0; i < Nrhs; i++) {
910 for (j = 0; j < nrhsentries; j++) {
911 std::fprintf(out_file, rformat, rhs[j]);
912 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
914 if ((acount - 1) % Rhsperline != linemod) {
915 std::fprintf(out_file,
"\n");
916 linemod = (acount - 1) % Rhsperline;
919 if (Rhstype[1] ==
'G') {
920 for (j = 0; j < nrhsentries; j++) {
921 std::fprintf(out_file, rformat, guess[j]);
922 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
924 if ((acount - 1) % Rhsperline != linemod) {
925 std::fprintf(out_file,
"\n");
926 linemod = (acount - 1) % Rhsperline;
928 guess += nrhsentries;
930 if (Rhstype[2] ==
'X') {
931 for (j = 0; j < nrhsentries; j++) {
932 std::fprintf(out_file, rformat, exact[j]);
933 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
935 if ((acount - 1) % Rhsperline != linemod) {
936 std::fprintf(out_file,
"\n");
937 linemod = (acount - 1) % Rhsperline;
939 exact += nrhsentries;
945 if (std::fclose(out_file) != 0) {
946 std::fprintf(stderr,
"Error closing file in writeHB_mat_double().\n");
952int readHB_mat_char(
const char* filename,
int colptr[],
int rowind[],
953 char val[],
char* Valfmt) {
973 int i, j, ind, col, offset, count, last;
974 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
975 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
976 int Ptrperline, Ptrwidth, Indperline, Indwidth;
977 int Valperline, Valwidth, Valprec;
981 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
982 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
984 if ((in_file = std::fopen(filename,
"r")) == NULL) {
985 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
989 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
990 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
991 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
994 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
995 ParseIfmt(Indfmt, &Indperline, &Indwidth);
996 if (Type[0] !=
'P') {
997 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
998 if (Valflag ==
'D') {
999 *std::strchr(Valfmt,
'D') =
'E';
1005 offset = 1 - _SP_base;
1008 ThisElement = (
char*)malloc(Ptrwidth + 1);
1009 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1010 *(ThisElement + Ptrwidth) =
'\0';
1012 for (i = 0; i < Ptrcrd; i++) {
1013 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1014 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1017 if (std::sscanf(line,
"%*s") < 0)
1018 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in pointer data region of HB file.\n");
1020 for (ind = 0; ind < Ptrperline; ind++) {
1021 if (count > Ncol)
break;
1022 std::strncpy(ThisElement, line + col, Ptrwidth);
1024 colptr[count] = std::atoi(ThisElement) - offset;
1033 ThisElement = (
char*)malloc(Indwidth + 1);
1034 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1035 *(ThisElement + Indwidth) =
'\0';
1037 for (i = 0; i < Indcrd; i++) {
1038 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1039 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1042 if (std::sscanf(line,
"%*s") < 0)
1043 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in index data region of HB file.\n");
1045 for (ind = 0; ind < Indperline; ind++) {
1046 if (count == Nnzero)
break;
1047 std::strncpy(ThisElement, line + col, Indwidth);
1049 rowind[count] = std::atoi(ThisElement) - offset;
1058 if (Type[0] !=
'P') {
1061 Nentries = 2 * Nnzero;
1065 ThisElement = (
char*)malloc(Valwidth + 1);
1066 if (ThisElement == NULL) IOHBTerminate(
"Insufficient memory for ThisElement.");
1067 *(ThisElement + Valwidth) =
'\0';
1069 for (i = 0; i < Valcrd; i++) {
1070 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1071 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1074 if (std::sscanf(line,
"%*s") < 0)
1075 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in value data region of HB file.\n");
1076 if (Valflag ==
'D') {
1077 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1080 for (ind = 0; ind < Valperline; ind++) {
1081 if (count == Nentries)
break;
1082 ThisElement = &val[count * Valwidth];
1083 std::strncpy(ThisElement, line + col, Valwidth);
1085 if (Valflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1087 last = std::strlen(ThisElement);
1088 for (j = last + 1; j >= 0; j--) {
1089 ThisElement[j] = ThisElement[j - 1];
1090 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1091 ThisElement[j - 1] = Valflag;
1105int readHB_newmat_char(
const char* filename,
int* M,
int* N,
int* nonzeros,
int** colptr,
1106 int** rowind,
char** val,
char** Valfmt) {
1109 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1110 int Valperline, Valwidth, Valprec;
1112 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1113 char Ptrfmt[17], Indfmt[17], Rhsfmt[21];
1115 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1116 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1120 *Valfmt = (
char*)malloc(21 *
sizeof(
char));
1121 if (*Valfmt == NULL) IOHBTerminate(
"Insufficient memory for Valfmt.");
1122 readHB_header(in_file, Title, Key, Type, M, N, nonzeros, &Nrhs,
1123 Ptrfmt, Indfmt, (*Valfmt), Rhsfmt,
1124 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1125 std::fclose(in_file);
1126 ParseRfmt(*Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1128 *colptr = (
int*)malloc((*N + 1) *
sizeof(int));
1129 if (*colptr == NULL) IOHBTerminate(
"Insufficient memory for colptr.\n");
1130 *rowind = (
int*)malloc(*nonzeros *
sizeof(
int));
1131 if (*rowind == NULL) IOHBTerminate(
"Insufficient memory for rowind.\n");
1132 if (Type[0] ==
'C') {
1138 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char) * 2);
1139 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1141 if (Type[0] !=
'P') {
1143 *val = (
char*)malloc(*nonzeros * Valwidth *
sizeof(
char));
1144 if (*val == NULL) IOHBTerminate(
"Insufficient memory for val.\n");
1147 return readHB_mat_char(filename, *colptr, *rowind, *val, *Valfmt);
1150int readHB_aux_char(
const char* filename,
const char AuxType,
char b[]) {
1173 int i, j, n, maxcol,
start, stride, col, last, linel, nvecs, rhsi;
1174 int Nrow, Ncol, Nnzero, Nentries, Nrhs;
1175 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1176 int Rhsperline, Rhswidth, Rhsprec;
1178 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1179 char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21];
1183 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1184 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1188 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1189 Ptrfmt, Indfmt, Valfmt, Rhsfmt,
1190 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1193 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) when none are present.\n");
1196 if (Rhstype[0] !=
'F') {
1197 std::fprintf(stderr,
"Warn: Attempt to read auxillary vector(s) which are not stored in Full form.\n");
1198 std::fprintf(stderr,
" Rhs must be specified as full. \n");
1203 if (Type[0] ==
'C') {
1204 Nentries = 2 * Nrow;
1211 if (Rhstype[1] ==
'G') nvecs++;
1212 if (Rhstype[2] ==
'X') nvecs++;
1214 if (AuxType ==
'G' && Rhstype[1] !=
'G') {
1215 std::fprintf(stderr,
"Warn: Attempt to read auxillary Guess vector(s) when none are present.\n");
1218 if (AuxType ==
'X' && Rhstype[2] !=
'X') {
1219 std::fprintf(stderr,
"Warn: Attempt to read auxillary eXact solution vector(s) when none are present.\n");
1223 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1224 maxcol = Rhsperline * Rhswidth;
1227 n = Ptrcrd + Indcrd + Valcrd;
1229 for (i = 0; i < n; i++) {
1230 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1231 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1242 else if (AuxType ==
'G')
1245 start = (nvecs - 1) * Nentries;
1246 stride = (nvecs - 1) * Nentries;
1248 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1249 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1252 linel = std::strchr(line,
'\n') - line;
1253 if (std::sscanf(line,
"%*s") < 0)
1254 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1258 for (i = 0; i <
start; i++) {
1260 if (col >= (maxcol < linel ? maxcol : linel)) {
1261 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1262 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1265 linel = std::strchr(line,
'\n') - line;
1266 if (std::sscanf(line,
"%*s") < 0)
1267 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1272 if (Rhsflag ==
'D') {
1273 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1278 for (rhsi = 0; rhsi < Nrhs; rhsi++) {
1279 for (i = 0; i < Nentries; i++) {
1280 if (col >= (maxcol < linel ? maxcol : linel)) {
1281 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1282 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1285 linel = std::strchr(line,
'\n') - line;
1286 if (std::sscanf(line,
"%*s") < 0)
1287 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1288 if (Rhsflag ==
'D') {
1289 while (std::strchr(line,
'D')) *std::strchr(line,
'D') =
'E';
1293 ThisElement = &b[i * Rhswidth];
1294 std::strncpy(ThisElement, line + col, Rhswidth);
1295 if (Rhsflag !=
'F' && std::strchr(ThisElement,
'E') == NULL) {
1297 last = std::strlen(ThisElement);
1298 for (j = last + 1; j >= 0; j--) {
1299 ThisElement[j] = ThisElement[j - 1];
1300 if (ThisElement[j] ==
'+' || ThisElement[j] ==
'-') {
1301 ThisElement[j - 1] = Rhsflag;
1308 b += Nentries * Rhswidth;
1312 for (i = 0; i < stride; i++) {
1314 if (col >= (maxcol < linel ? maxcol : linel)) {
1315 if (std::fgets(line, BUFSIZ, in_file) == NULL) {
1316 std::fprintf(stderr,
"Error: Failed to read from file.\n");
1319 linel = std::strchr(line,
'\n') - line;
1320 if (std::sscanf(line,
"%*s") < 0)
1321 IOHBTerminate(
"Trilinos_Util_iohb.cpp: Null (or blank) line in auxillary vector data region of HB file.\n");
1327 std::fclose(in_file);
1331int readHB_newaux_char(
const char* filename,
const char AuxType,
char** b,
char** Rhsfmt) {
1333 int Ptrcrd, Indcrd, Valcrd, Rhscrd;
1334 int Nrow, Ncol, Nnzero, Nrhs;
1335 int Rhsperline, Rhswidth, Rhsprec;
1337 char Title[73], Key[9], Type[4] =
"XXX", Rhstype[4];
1338 char Ptrfmt[17], Indfmt[17], Valfmt[21];
1340 if ((in_file = std::fopen(filename,
"r")) == NULL) {
1341 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1345 *Rhsfmt = (
char*)malloc(21 *
sizeof(
char));
1346 if (*Rhsfmt == NULL) IOHBTerminate(
"Insufficient memory for Rhsfmt.");
1347 readHB_header(in_file, Title, Key, Type, &Nrow, &Ncol, &Nnzero, &Nrhs,
1348 Ptrfmt, Indfmt, Valfmt, (*Rhsfmt),
1349 &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype);
1350 std::fclose(in_file);
1352 std::fprintf(stderr,
"Warn: Requested read of aux vector(s) when none are present.\n");
1355 ParseRfmt(*Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1356 if (Type[0] ==
'C') {
1357 std::fprintf(stderr,
"Warning: Reading complex aux vector(s) from HB file %s.", filename);
1358 std::fprintf(stderr,
" Real and imaginary parts will be interlaced in b[].");
1359 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char) * 2);
1360 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1361 return readHB_aux_char(filename, AuxType, *b);
1363 *b = (
char*)malloc(Nrow * Nrhs * Rhswidth *
sizeof(
char));
1364 if (*b == NULL) IOHBTerminate(
"Insufficient memory for rhs.\n");
1365 return readHB_aux_char(filename, AuxType, *b);
1370int writeHB_mat_char(
const char* filename,
int M,
int N,
1371 int nz,
const int colptr[],
const int rowind[],
1372 const char val[],
int Nrhs,
const char rhs[],
1373 const char guess[],
const char exact[],
1374 const char* Title,
const char* Key,
const char* Type,
1375 char* Ptrfmt,
char* Indfmt,
char* Valfmt,
char* Rhsfmt,
1376 const char* Rhstype) {
1386 std::FILE* out_file;
1387 int i, j, acount, linemod, entry, offset;
1388 int totcrd, ptrcrd, indcrd, valcrd, rhscrd;
1389 int nvalentries, nrhsentries;
1390 int Ptrperline, Ptrwidth, Indperline, Indwidth;
1391 int Rhsperline, Rhswidth, Rhsprec;
1393 int Valperline, Valwidth, Valprec;
1395 char pformat[16], iformat[16], vformat[19], rformat[19];
1397 if (Type[0] ==
'C') {
1398 nvalentries = 2 * nz;
1399 nrhsentries = 2 * M;
1405 if (filename != NULL) {
1406 if ((out_file = std::fopen(filename,
"w")) == NULL) {
1407 std::fprintf(stderr,
"Error: Cannot open file: %s\n", filename);
1413 if (Ptrfmt != NULL) strcpy(Ptrfmt,
"(8I10)");
1414 ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth);
1415 std::sprintf(pformat,
"%%%dd", Ptrwidth);
1417 if (Indfmt == NULL) Indfmt = Ptrfmt;
1418 ParseIfmt(Indfmt, &Indperline, &Indwidth);
1419 std::sprintf(iformat,
"%%%dd", Indwidth);
1421 if (Type[0] !=
'P') {
1422 if (Valfmt != NULL) strcpy(Valfmt,
"(4E20.13)");
1423 ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag);
1424 std::sprintf(vformat,
"%%%ds", Valwidth);
1427 ptrcrd = (N + 1) / Ptrperline;
1428 if ((N + 1) % Ptrperline != 0) ptrcrd++;
1430 indcrd = nz / Indperline;
1431 if (nz % Indperline != 0) indcrd++;
1433 valcrd = nvalentries / Valperline;
1434 if (nvalentries % Valperline != 0) valcrd++;
1437 if (Rhsfmt == NULL) Rhsfmt = Valfmt;
1438 ParseRfmt(Rhsfmt, &Rhsperline, &Rhswidth, &Rhsprec, &Rhsflag);
1439 std::sprintf(rformat,
"%%%ds", Rhswidth);
1440 rhscrd = nrhsentries / Rhsperline;
1441 if (nrhsentries % Rhsperline != 0) rhscrd++;
1442 if (Rhstype[1] ==
'G') rhscrd += rhscrd;
1443 if (Rhstype[2] ==
'X') rhscrd += rhscrd;
1448 totcrd = 4 + ptrcrd + indcrd + valcrd + rhscrd;
1452 std::fprintf(out_file,
"%-72s%-8s\n%14d%14d%14d%14d%14d\n", Title, Key, totcrd,
1453 ptrcrd, indcrd, valcrd, rhscrd);
1454 std::fprintf(out_file,
"%3s%11s%14d%14d%14d\n", Type,
" ", M, N, nz);
1455 std::fprintf(out_file,
"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt);
1459 std::fprintf(out_file,
"%-20s\n%-14s%d\n", Rhsfmt, Rhstype, Nrhs);
1461 std::fprintf(out_file,
"\n");
1463 offset = 1 - _SP_base;
1467 for (i = 0; i < N + 1; i++) {
1468 entry = colptr[i] + offset;
1469 std::fprintf(out_file, pformat, entry);
1470 if ((i + 1) % Ptrperline == 0) std::fprintf(out_file,
"\n");
1473 if ((N + 1) % Ptrperline != 0) std::fprintf(out_file,
"\n");
1476 for (i = 0; i < nz; i++) {
1477 entry = rowind[i] + offset;
1478 std::fprintf(out_file, iformat, entry);
1479 if ((i + 1) % Indperline == 0) std::fprintf(out_file,
"\n");
1482 if (nz % Indperline != 0) std::fprintf(out_file,
"\n");
1486 if (Type[0] !=
'P') {
1487 for (i = 0; i < nvalentries; i++) {
1488 std::fprintf(out_file, vformat, val + i * Valwidth);
1489 if ((i + 1) % Valperline == 0) std::fprintf(out_file,
"\n");
1492 if (nvalentries % Valperline != 0) std::fprintf(out_file,
"\n");
1498 for (j = 0; j < Nrhs; j++) {
1499 for (i = 0; i < nrhsentries; i++) {
1500 std::fprintf(out_file, rformat, rhs + i * Rhswidth);
1501 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1503 if (acount % Rhsperline != linemod) {
1504 std::fprintf(out_file,
"\n");
1505 linemod = (acount - 1) % Rhsperline;
1507 if (Rhstype[1] ==
'G') {
1508 for (i = 0; i < nrhsentries; i++) {
1509 std::fprintf(out_file, rformat, guess + i * Rhswidth);
1510 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1512 if (acount % Rhsperline != linemod) {
1513 std::fprintf(out_file,
"\n");
1514 linemod = (acount - 1) % Rhsperline;
1517 if (Rhstype[2] ==
'X') {
1518 for (i = 0; i < nrhsentries; i++) {
1519 std::fprintf(out_file, rformat, exact + i * Rhswidth);
1520 if (acount++ % Rhsperline == linemod) std::fprintf(out_file,
"\n");
1522 if (acount % Rhsperline != linemod) {
1523 std::fprintf(out_file,
"\n");
1524 linemod = (acount - 1) % Rhsperline;
1531 if (std::fclose(out_file) != 0) {
1532 std::fprintf(stderr,
"Error closing file in writeHB_mat_char().\n");
1538int ParseIfmt(
char* fmt,
int* perline,
int* width) {
1550 tmp = std::strchr(fmt,
'(');
1551 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'I') - tmp - 1);
1552 *perline = std::atoi(tmp);
1553 if (*perline == 0) *perline = 1;
1554 if (tmp != NULL) free((
void*)tmp);
1555 tmp = std::strchr(fmt,
'I');
1556 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1557 *width = std::atoi(tmp);
1558 if (tmp != NULL) free((
void*)tmp);
1562int ParseRfmt(
char* fmt,
int* perline,
int* width,
int* prec,
int* flag) {
1583 if (std::strchr(fmt,
'(') != NULL) fmt = std::strchr(fmt,
'(');
1584 if (std::strchr(fmt,
')') != NULL) {
1585 tmp2 = std::strchr(fmt,
')');
1586 while (std::strchr(tmp2 + 1,
')') != NULL) {
1587 tmp2 = std::strchr(tmp2 + 1,
')');
1591 if (std::strchr(fmt,
'P') != NULL)
1593 if (std::strchr(fmt,
'(') != NULL) {
1594 tmp = std::strchr(fmt,
'P');
1595 if (*(++tmp) ==
',') tmp++;
1596 tmp3 = std::strchr(fmt,
'(') + 1;
1599 while (*(tmp2 + len) !=
'\0') {
1600 *tmp2 = *(tmp2 + len);
1603 *(std::strchr(fmt,
')') + 1) =
'\0';
1606 if (std::strchr(fmt,
'E') != NULL) {
1608 }
else if (std::strchr(fmt,
'D') != NULL) {
1610 }
else if (std::strchr(fmt,
'F') != NULL) {
1613 std::fprintf(stderr,
"Real format %s in H/B file not supported.\n", fmt);
1616 tmp = std::strchr(fmt,
'(');
1617 tmp = substr(fmt, tmp - fmt + 1, std::strchr(fmt, *flag) - tmp - 1);
1618 *perline = std::atoi(tmp);
1619 if (*perline == 0) *perline = 1;
1620 if (tmp != NULL) free((
void*)tmp);
1621 tmp = std::strchr(fmt, *flag);
1622 if (std::strchr(fmt,
'.')) {
1623 tmp1 = substr(fmt, std::strchr(fmt,
'.') - fmt + 1, std::strchr(fmt,
')') - std::strchr(fmt,
'.') - 1);
1624 *prec = std::atoi(tmp1);
1625 if (tmp1 != NULL) free((
void*)tmp1);
1626 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
'.') - tmp - 1);
1628 tmp1 = substr(fmt, tmp - fmt + 1, std::strchr(fmt,
')') - tmp - 1);
1630 *width = std::atoi(tmp1);
1631 if (tmp1 != NULL) free((
void*)tmp1);
1635char* substr(
const char* S,
const int pos,
const int len) {
1638 if ((
size_t)pos + len <= std::strlen(S)) {
1639 SubS = (
char*)malloc(len + 1);
1640 if (SubS == NULL) IOHBTerminate(
"Insufficient memory for SubS.");
1641 for (i = 0; i < len; i++) SubS[i] = S[pos + i];
1649void upcase(
char* S) {
1652 len = ::std::strlen(S);
1653 for (i = 0; i < len; i++)
1654 S[i] = ::std::toupper(S[i]);
1657void IOHBTerminate(
const char* message) {
1658 ::std::fprintf(stderr,
"%s", message);
void start()
Start the deep_copy counter.