GLOBAL Int UMFPACK_report_symbolic ( void *SymbolicHandle, const double Control [UMFPACK_CONTROL] ) { Int n_row, n_col, nz, nchains, nfr, maxnrows, maxncols, prl, k, chain, frontid, frontid1, frontid2, kk, *Chain_start, *W, *Chain_maxrows, *Chain_maxcols, *Front_npivcol, *Front_1strow, *Front_leftmostdesc, *Front_parent, done, status1, status2 ; SymbolicType *Symbolic ; prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ; if (prl <= 2) { return (UMFPACK_OK) ; } PRINTF (("Symbolic object: ")) ; Symbolic = (SymbolicType *) SymbolicHandle ; if (!UMF_valid_symbolic (Symbolic)) { PRINTF (("ERROR: invalid\n")) ; return (UMFPACK_ERROR_invalid_Symbolic_object) ; } n_row = Symbolic->n_row ; n_col = Symbolic->n_col ; nz = Symbolic->nz ; nchains = Symbolic->nchains ; nfr = Symbolic->nfr ; maxnrows = Symbolic->maxnrows ; maxncols = Symbolic->maxncols ; Chain_start = Symbolic->Chain_start ; Chain_maxrows = Symbolic->Chain_maxrows ; Chain_maxcols = Symbolic->Chain_maxcols ; Front_npivcol = Symbolic->Front_npivcol ; Front_1strow = Symbolic->Front_1strow ; Front_leftmostdesc = Symbolic->Front_leftmostdesc ; Front_parent = Symbolic->Front_parent ; if (prl >= 4) { PRINTF (("\n matrix to be factorized:\n")) ; PRINTF (("\tn_row: "ID" n_col: "ID"\n", n_row, n_col)) ; PRINTF (("\tnumber of entries: "ID"\n", nz)) ; PRINTF ((" block size used for dense matrix kernels: "ID"\n", Symbolic->nb)) ; PRINTF ((" strategy used: ")) ; /* strategy cannot be auto */ if (Symbolic->strategy == UMFPACK_STRATEGY_SYMMETRIC) { PRINTF (("symmetric\n")) ; PRINTF ((" ordering used: ")) ; if (Symbolic->ordering == UMFPACK_ORDERING_AMD) { PRINTF (("amd on A\n")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_GIVEN) { PRINTF (("user permutation")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_USER) { PRINTF (("user function")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_METIS) { PRINTF (("metis on A")) ; } } else /* if (Symbolic->strategy == UMFPACK_STRATEGY_UNSYMMETRIC) */ { PRINTF (("unsymmetric\n")) ; PRINTF ((" ordering used: ")) ; if (Symbolic->ordering == UMFPACK_ORDERING_AMD) { PRINTF (("colamd on A\n")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_GIVEN) { PRINTF (("user permutation")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_USER) { PRINTF (("user function")) ; } else if (Symbolic->ordering == UMFPACK_ORDERING_METIS) { PRINTF (("metis on A'A")) ; } } PRINTF (("\n")) ; PRINTF ((" performn column etree postorder: ")) ; if (Symbolic->fixQ) { PRINTF (("no\n")) ; } else { PRINTF (("yes\n")) ; } PRINTF ((" prefer diagonal pivoting (attempt P=Q): ")) ; if (Symbolic->prefer_diagonal) { PRINTF (("yes\n")) ; } else { PRINTF (("no\n")) ; } PRINTF ((" variable-size part of Numeric object:\n")) ; PRINTF (("\tminimum initial size (Units): %.20g (MBytes): %.1f\n", Symbolic->dnum_mem_init_usage, MBYTES (Symbolic->dnum_mem_init_usage))) ; PRINTF (("\testimated peak size (Units): %.20g (MBytes): %.1f\n", Symbolic->num_mem_usage_est, MBYTES (Symbolic->num_mem_usage_est))) ; PRINTF (("\testimated final size (Units): %.20g (MBytes): %.1f\n", Symbolic->num_mem_size_est, MBYTES (Symbolic->num_mem_size_est))) ; PRINTF ((" symbolic factorization memory usage (Units):" " %.20g (MBytes): %.1f\n", Symbolic->peak_sym_usage, MBYTES (Symbolic->peak_sym_usage))) ; PRINTF ((" frontal matrices / supercolumns:\n")) ; PRINTF (("\tnumber of frontal chains: "ID"\n", nchains)) ; PRINTF (("\tnumber of frontal matrices: "ID"\n", nfr)) ; PRINTF (("\tlargest frontal matrix row dimension: "ID"\n", maxnrows)) ; PRINTF (("\tlargest frontal matrix column dimension: "ID"\n",maxncols)); } k = 0 ; done = FALSE ; for (chain = 0 ; chain < nchains ; chain++) { frontid1 = Chain_start [chain] ; frontid2 = Chain_start [chain+1] - 1 ; PRINTF4 (("\n Frontal chain: "ID". Frontal matrices "ID" to "ID"\n", INDEX (chain), INDEX (frontid1), INDEX (frontid2))) ; PRINTF4 (("\tLargest frontal matrix in Frontal chain: "ID"-by-"ID"\n", Chain_maxrows [chain], Chain_maxcols [chain])) ; for (frontid = frontid1 ; frontid <= frontid2 ; frontid++) { kk = Front_npivcol [frontid] ; PRINTF4 (("\tFront: "ID" pivot cols: "ID" (pivot columns "ID" to " ID")\n", INDEX (frontid), kk, INDEX (k), INDEX (k+kk-1))) ; PRINTF4 (("\t pivot row candidates: "ID" to "ID"\n", INDEX (Front_1strow [Front_leftmostdesc [frontid]]), INDEX (Front_1strow [frontid+1]-1))) ; PRINTF4 (("\t leftmost descendant: "ID"\n", INDEX (Front_leftmostdesc [frontid]))) ; PRINTF4 (("\t 1st new candidate row : "ID"\n", INDEX (Front_1strow [frontid]))) ; PRINTF4 (("\t parent:")) ; if (Front_parent [frontid] == EMPTY) { PRINTF4 ((" (none)\n")) ; } else { PRINTF4 ((" "ID"\n", INDEX (Front_parent [frontid]))) ; } done = (frontid == 20 && frontid < nfr-1 && prl == 4) ; if (done) { PRINTF4 (("\t...\n")) ; break ; } k += kk ; } if (Front_npivcol [nfr] != 0) { PRINTF4 (("\tFront: "ID" placeholder for "ID" empty columns\n", INDEX (nfr), Front_npivcol [nfr])) ; } if (done) { break ; } } W = (Int *) UMF_malloc (MAX (n_row, n_col), sizeof (Int)) ; if (!W) { PRINTF (("ERROR: out of memory to check Symbolic object\n\n")) ; return (UMFPACK_ERROR_out_of_memory) ; } PRINTF4 (("\nInitial column permutation, Q1: ")) ; status1 = UMF_report_perm (n_col, Symbolic->Cperm_init, W, prl, 0) ; PRINTF4 (("\nInitial row permutation, P1: ")) ; status2 = UMF_report_perm (n_row, Symbolic->Rperm_init, W, prl, 0) ; (void) UMF_free ((void *) W) ; if (status1 != UMFPACK_OK || status2 != UMFPACK_OK) { return (UMFPACK_ERROR_invalid_Symbolic_object) ; } PRINTF4 ((" Symbolic object: ")) ; PRINTF (("OK\n\n")) ; return (UMFPACK_OK) ; }
GLOBAL Int UMFPACK_report_numeric ( void *NumericHandle, const double Control [UMFPACK_CONTROL] ) { Int prl, *W, nn, n_row, n_col, n_inner, num_fixed_size, numeric_size, npiv ; NumericType *Numeric ; prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ; if (prl <= 2) { return (UMFPACK_OK) ; } PRINTF (("Numeric object: ")) ; Numeric = (NumericType *) NumericHandle ; if (!UMF_valid_numeric (Numeric)) { PRINTF (("ERROR: LU factors invalid\n\n")) ; return (UMFPACK_ERROR_invalid_Numeric_object) ; } n_row = Numeric->n_row ; n_col = Numeric->n_col ; nn = MAX (n_row, n_col) ; n_inner = MIN (n_row, n_col) ; npiv = Numeric->npiv ; DEBUG1 (("n_row "ID" n_col "ID" nn "ID" n_inner "ID" npiv "ID"\n", n_row, n_col, nn, n_inner, npiv)) ; /* size of Numeric object, except Numeric->Memory and Numeric->Upattern */ /* see also UMF_set_stats */ num_fixed_size = UNITS (NumericType, 1) /* Numeric structure */ + UNITS (Entry, n_inner+1) /* D */ + UNITS (Int, n_row+1) /* Rperm */ + UNITS (Int, n_col+1) /* Cperm */ + 6 * UNITS (Int, npiv+1) /* Lpos, Uilen, Uip, Upos, Lilen, Lip */ + ((Numeric->scale != UMFPACK_SCALE_NONE) ? UNITS (Entry, n_row) : 0) ; /* Rs */ DEBUG1 (("num fixed size: "ID"\n", num_fixed_size)) ; DEBUG1 (("Numeric->size "ID"\n", Numeric->size)) ; DEBUG1 (("ulen units "ID"\n", UNITS (Int, Numeric->ulen))) ; /* size of Numeric->Memory is Numeric->size */ /* size of Numeric->Upattern is Numeric->ulen */ numeric_size = num_fixed_size + Numeric->size + UNITS (Int, Numeric->ulen) ; DEBUG1 (("numeric total size "ID"\n", numeric_size)) ; if (prl >= 4) { PRINTF (("\n n_row: "ID" n_col: "ID"\n", n_row, n_col)) ; PRINTF ((" relative pivot tolerance used: %g\n", Numeric->relpt)) ; PRINTF ((" relative symmetric pivot tolerance used: %g\n", Numeric->relpt2)) ; PRINTF ((" matrix scaled: ")) ; if (Numeric->scale == UMFPACK_SCALE_NONE) { PRINTF (("no")) ; } else if (Numeric->scale == UMFPACK_SCALE_SUM) { PRINTF (("yes (divided each row by sum abs value in each row)\n")) ; PRINTF ((" minimum sum (abs (rows of A)): %.5e\n", Numeric->rsmin)) ; PRINTF ((" maximum sum (abs (rows of A)): %.5e", Numeric->rsmax)) ; } else if (Numeric->scale == UMFPACK_SCALE_MAX) { PRINTF (("yes (divided each row by max abs value in each row)\n")) ; PRINTF ((" minimum max (abs (rows of A)): %.5e\n", Numeric->rsmin)) ; PRINTF ((" maximum max (abs (rows of A)): %.5e", Numeric->rsmax)) ; } PRINTF (("\n")) ; PRINTF ((" initial allocation parameter used: %g\n", Numeric->alloc_init)) ; PRINTF ((" frontal matrix allocation parameter used: %g\n", Numeric->front_alloc_init)) ; PRINTF ((" final total size of Numeric object (Units): "ID"\n", numeric_size)) ; PRINTF ((" final total size of Numeric object (MBytes): %.1f\n", MBYTES (numeric_size))) ; PRINTF ((" peak size of variable-size part (Units): "ID"\n", Numeric->max_usage)) ; PRINTF ((" peak size of variable-size part (MBytes): %.1f\n", MBYTES (Numeric->max_usage))) ; PRINTF ((" largest actual frontal matrix size: "ID"\n", Numeric->maxfrsize)) ; PRINTF ((" memory defragmentations: "ID"\n", Numeric->ngarbage)) ; PRINTF ((" memory reallocations: "ID"\n", Numeric->nrealloc)) ; PRINTF ((" costly memory reallocations: "ID"\n", Numeric->ncostly)) ; PRINTF ((" entries in compressed pattern (L and U): "ID"\n", Numeric->isize)) ; PRINTF ((" number of nonzeros in L (excl diag): "ID"\n", Numeric->lnz)) ; PRINTF ((" number of entries stored in L (excl diag): "ID"\n", Numeric->nLentries)) ; PRINTF ((" number of nonzeros in U (excl diag): "ID"\n", Numeric->unz)) ; PRINTF ((" number of entries stored in U (excl diag): "ID"\n", Numeric->nUentries)) ; PRINTF ((" factorization floating-point operations: %g\n", Numeric->flops)) ; PRINTF ((" number of nonzeros on diagonal of U: "ID"\n", Numeric->nnzpiv)) ; PRINTF ((" min abs. value on diagonal of U: %.5e\n", Numeric->min_udiag)) ; PRINTF ((" max abs. value on diagonal of U: %.5e\n", Numeric->max_udiag)) ; PRINTF ((" reciprocal condition number estimate: %.2e\n", Numeric->rcond)) ; } W = (Int *) UMF_malloc (nn, sizeof (Int)) ; if (!W) { PRINTF ((" ERROR: out of memory to check Numeric object\n\n")) ; return (UMFPACK_ERROR_out_of_memory) ; } if (Numeric->Rs) { #ifndef NRECIPROCAL if (Numeric->do_recip) { PRINTF4 (("\nScale factors applied via multiplication\n")) ; } else #endif { PRINTF4 (("\nScale factors applied via division\n")) ; } PRINTF4 (("Scale factors, Rs: ")) ; (void) UMF_report_vector (n_row, Numeric->Rs, (double *) NULL, prl, FALSE, TRUE) ; } else { PRINTF4 (("Scale factors, Rs: (not present)\n")) ; } PRINTF4 (("\nP: row ")) ; if (UMF_report_perm (n_row, Numeric->Rperm, W, prl, 0) != UMFPACK_OK) { (void) UMF_free ((void *) W) ; return (UMFPACK_ERROR_invalid_Numeric_object) ; } PRINTF4 (("\nQ: column ")) ; if (UMF_report_perm (n_col, Numeric->Cperm, W, prl, 0) != UMFPACK_OK) { (void) UMF_free ((void *) W) ; return (UMFPACK_ERROR_invalid_Numeric_object) ; } if (!report_L (Numeric, W, prl)) { (void) UMF_free ((void *) W) ; PRINTF ((" ERROR: L factor invalid\n\n")) ; return (UMFPACK_ERROR_invalid_Numeric_object) ; } if (!report_U (Numeric, W, prl)) { (void) UMF_free ((void *) W) ; PRINTF ((" ERROR: U factor invalid\n\n")) ; return (UMFPACK_ERROR_invalid_Numeric_object) ; } /* The diagonal of U is in "merged" (Entry) form, not "split" form. */ PRINTF4 (("\ndiagonal of U: ")) ; (void) UMF_report_vector (n_inner, (double *) Numeric->D, (double *) NULL, prl, FALSE, FALSE) ; (void) UMF_free ((void *) W) ; PRINTF4 ((" Numeric object: ")) ; PRINTF (("OK\n\n")) ; return (UMFPACK_OK) ; }
GLOBAL void UMFPACK_report_info ( const double Control [UMFPACK_CONTROL], const double Info [UMFPACK_INFO] ) { double lnz_est, unz_est, lunz_est, lnz, unz, lunz, tsym, tnum, fnum, tsolve, fsolve, ftot, twsym, twnum, twsolve, twtot, n2 ; Int n_row, n_col, n_inner, prl, is_sym, strategy ; /* ---------------------------------------------------------------------- */ /* get control settings and status to determine what to print */ /* ---------------------------------------------------------------------- */ prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ; if (!Info || prl < 2) { /* no output generated if Info is (double *) NULL */ /* or if prl is less than 2 */ return ; } /* ---------------------------------------------------------------------- */ /* print umfpack version */ /* ---------------------------------------------------------------------- */ PRINTF (("UMFPACK V%d.%d.%d (%s), Info:\n", UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION, UMFPACK_DATE)) ; #ifndef NDEBUG PRINTF (( "**** Debugging enabled (UMFPACK will be exceedingly slow!) *****************\n" )) ; #endif /* ---------------------------------------------------------------------- */ /* print run-time options */ /* ---------------------------------------------------------------------- */ #ifdef DINT PRINTF ((" matrix entry defined as: double\n")) ; PRINTF ((" Int (generic integer) defined as: int\n")) ; #endif #ifdef DLONG PRINTF ((" matrix entry defined as: double\n")) ; PRINTF ((" Int (generic integer) defined as: SuiteSparse_long\n")) ; #endif #ifdef ZINT PRINTF ((" matrix entry defined as: double complex\n")) ; PRINTF ((" Int (generic integer) defined as: int\n")) ; #endif #ifdef ZLONG PRINTF ((" matrix entry defined as: double complex\n")) ; PRINTF ((" Int (generic integer) defined as: SuiteSparse_long\n")) ; #endif /* ---------------------------------------------------------------------- */ /* print compile-time options */ /* ---------------------------------------------------------------------- */ PRINTF ((" BLAS library used: ")) ; #ifdef NBLAS PRINTF (("none. UMFPACK will be slow.\n")) ; #else PRINTF (("Fortran BLAS. size of BLAS integer: "ID"\n", (Int) (sizeof (BLAS_INT)))) ; #endif PRINTF ((" MATLAB: ")) ; #ifdef MATLAB_MEX_FILE PRINTF (("yes.\n")) ; #else #ifdef MATHWORKS PRINTF (("yes.\n")) ; #else PRINTF (("no.\n")) ; #endif #endif PRINTF ((" CPU timer: ")) ; #ifdef SUITESPARSE_TIMER_ENABLED PRINTF (("POSIX C clock_getttime ( ) routine.\n")) ; #else PRINTF (("none.\n")) ; #endif /* ---------------------------------------------------------------------- */ /* print n and nz */ /* ---------------------------------------------------------------------- */ n_row = (Int) Info [UMFPACK_NROW] ; n_col = (Int) Info [UMFPACK_NCOL] ; n_inner = MIN (n_row, n_col) ; PRINT_INFO (" number of rows in matrix A: "ID"\n", n_row) ; PRINT_INFO (" number of columns in matrix A: "ID"\n", n_col) ; PRINT_INFO (" entries in matrix A: "ID"\n", (Int) Info [UMFPACK_NZ]) ; PRINT_INFO (" memory usage reported in: "ID"-byte Units\n", (Int) Info [UMFPACK_SIZE_OF_UNIT]) ; PRINT_INFO (" size of int: "ID" bytes\n", (Int) Info [UMFPACK_SIZE_OF_INT]) ; PRINT_INFO (" size of SuiteSparse_long: "ID" bytes\n", (Int) Info [UMFPACK_SIZE_OF_LONG]) ; PRINT_INFO (" size of pointer: "ID" bytes\n", (Int) Info [UMFPACK_SIZE_OF_POINTER]) ; PRINT_INFO (" size of numerical entry: "ID" bytes\n", (Int) Info [UMFPACK_SIZE_OF_ENTRY]) ; /* ---------------------------------------------------------------------- */ /* symbolic parameters */ /* ---------------------------------------------------------------------- */ strategy = Info [UMFPACK_STRATEGY_USED] ; if (strategy == UMFPACK_STRATEGY_SYMMETRIC) { PRINTF (("\n strategy used: symmetric\n")) ; if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_AMD) { PRINTF ((" ordering used: amd on A+A'\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_GIVEN) { PRINTF ((" ordering used: user perm.\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_USER) { PRINTF ((" ordering used: user function\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_NONE) { PRINTF ((" ordering used: none\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_METIS) { PRINTF ((" ordering used: metis on A+A'\n")) ; } else { PRINTF ((" ordering used: not computed\n")) ; } } else { PRINTF (("\n strategy used: unsymmetric\n")) ; if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_AMD) { PRINTF ((" ordering used: colamd on A\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_GIVEN) { PRINTF ((" ordering used: user perm.\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_USER) { PRINTF ((" ordering used: user function\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_NONE) { PRINTF ((" ordering used: none\n")) ; } else if (Info [UMFPACK_ORDERING_USED] == UMFPACK_ORDERING_METIS) { PRINTF ((" ordering used: metis on A'A\n")) ; } else { PRINTF ((" ordering used: not computed\n")) ; } } if (Info [UMFPACK_QFIXED] == 1) { PRINTF ((" modify Q during factorization: no\n")) ; } else if (Info [UMFPACK_QFIXED] == 0) { PRINTF ((" modify Q during factorization: yes\n")) ; } if (Info [UMFPACK_DIAG_PREFERRED] == 0) { PRINTF ((" prefer diagonal pivoting: no\n")) ; } else if (Info [UMFPACK_DIAG_PREFERRED] == 1) { PRINTF ((" prefer diagonal pivoting: yes\n")) ; } /* ---------------------------------------------------------------------- */ /* singleton statistics */ /* ---------------------------------------------------------------------- */ PRINT_INFO (" pivots with zero Markowitz cost: %0.f\n", Info [UMFPACK_COL_SINGLETONS] + Info [UMFPACK_ROW_SINGLETONS]) ; PRINT_INFO (" submatrix S after removing zero-cost pivots:\n" " number of \"dense\" rows: %.0f\n", Info [UMFPACK_NDENSE_ROW]) ; PRINT_INFO (" number of \"dense\" columns: %.0f\n", Info [UMFPACK_NDENSE_COL]) ; PRINT_INFO (" number of empty rows: %.0f\n", Info [UMFPACK_NEMPTY_ROW]) ; PRINT_INFO (" number of empty columns %.0f\n", Info [UMFPACK_NEMPTY_COL]) ; is_sym = Info [UMFPACK_S_SYMMETRIC] ; if (is_sym > 0) { PRINTF ((" submatrix S square and diagonal preserved\n")) ; } else if (is_sym == 0) { PRINTF ((" submatrix S not square or diagonal not preserved\n")); } /* ---------------------------------------------------------------------- */ /* statistics from amd_aat */ /* ---------------------------------------------------------------------- */ n2 = Info [UMFPACK_N2] ; if (n2 >= 0) { PRINTF ((" pattern of square submatrix S:\n")) ; } PRINT_INFO (" number rows and columns %.0f\n", n2) ; PRINT_INFO (" symmetry of nonzero pattern: %.6f\n", Info [UMFPACK_PATTERN_SYMMETRY]) ; PRINT_INFO (" nz in S+S' (excl. diagonal): %.0f\n", Info [UMFPACK_NZ_A_PLUS_AT]) ; PRINT_INFO (" nz on diagonal of matrix S: %.0f\n", Info [UMFPACK_NZDIAG]) ; if (Info [UMFPACK_NZDIAG] >= 0 && n2 > 0) { PRINTF ((" fraction of nz on diagonal: %.6f\n", Info [UMFPACK_NZDIAG] / n2)) ; } /* ---------------------------------------------------------------------- */ /* statistics from AMD */ /* ---------------------------------------------------------------------- */ if (strategy == UMFPACK_STRATEGY_SYMMETRIC && Info [UMFPACK_ORDERING_USED] != UMFPACK_ORDERING_GIVEN) { double dmax = Info [UMFPACK_SYMMETRIC_DMAX] ; PRINTF ((" AMD statistics, for strict diagonal pivoting:\n")) ; PRINT_INFO (" est. flops for LU factorization: %.5e\n", Info [UMFPACK_SYMMETRIC_FLOPS]) ; PRINT_INFO (" est. nz in L+U (incl. diagonal): %.0f\n", Info [UMFPACK_SYMMETRIC_LUNZ]) ; if (dmax > 0) { PRINT_INFO (" est. largest front (# entries): %.0f\n", dmax*dmax) ; } PRINT_INFO (" est. max nz in any column of L: %.0f\n", dmax) ; PRINT_INFO ( " number of \"dense\" rows/columns in S+S': %.0f\n", Info [UMFPACK_SYMMETRIC_NDENSE]) ; } /* ---------------------------------------------------------------------- */ /* symbolic factorization */ /* ---------------------------------------------------------------------- */ tsym = Info [UMFPACK_SYMBOLIC_TIME] ; twsym = Info [UMFPACK_SYMBOLIC_WALLTIME] ; PRINT_INFO (" symbolic factorization defragmentations: %.0f\n", Info [UMFPACK_SYMBOLIC_DEFRAG]) ; PRINT_INFO (" symbolic memory usage (Units): %.0f\n", Info [UMFPACK_SYMBOLIC_PEAK_MEMORY]) ; PRINT_INFO (" symbolic memory usage (MBytes): %.1f\n", MBYTES (Info [UMFPACK_SYMBOLIC_PEAK_MEMORY])) ; PRINT_INFO (" Symbolic size (Units): %.0f\n", Info [UMFPACK_SYMBOLIC_SIZE]) ; PRINT_INFO (" Symbolic size (MBytes): %.0f\n", MBYTES (Info [UMFPACK_SYMBOLIC_SIZE])) ; PRINT_INFO (" symbolic factorization wallclock time(sec): %.2f\n", twsym) ; /* ---------------------------------------------------------------------- */ /* scaling, from numerical factorization */ /* ---------------------------------------------------------------------- */ if (Info [UMFPACK_WAS_SCALED] == UMFPACK_SCALE_NONE) { PRINTF (("\n matrix scaled: no\n")) ; } else if (Info [UMFPACK_WAS_SCALED] == UMFPACK_SCALE_SUM) { PRINTF (("\n matrix scaled: yes ")) ; PRINTF (("(divided each row by sum of abs values in each row)\n")) ; PRINTF ((" minimum sum (abs (rows of A)): %.5e\n", Info [UMFPACK_RSMIN])) ; PRINTF ((" maximum sum (abs (rows of A)): %.5e\n", Info [UMFPACK_RSMAX])) ; } else if (Info [UMFPACK_WAS_SCALED] == UMFPACK_SCALE_MAX) { PRINTF (("\n matrix scaled: yes ")) ; PRINTF (("(divided each row by max abs value in each row)\n")) ; PRINTF ((" minimum max (abs (rows of A)): %.5e\n", Info [UMFPACK_RSMIN])) ; PRINTF ((" maximum max (abs (rows of A)): %.5e\n", Info [UMFPACK_RSMAX])) ; } /* ---------------------------------------------------------------------- */ /* estimate/actual in symbolic/numeric factorization */ /* ---------------------------------------------------------------------- */ /* double relop, but ignore NaN case: */ if (Info [UMFPACK_SYMBOLIC_DEFRAG] >= 0 /* UMFPACK_*symbolic called */ || Info [UMFPACK_NUMERIC_DEFRAG] >= 0) /* UMFPACK_numeric called */ { PRINTF (("\n symbolic/numeric factorization: upper bound")) ; PRINTF ((" actual %%\n")) ; PRINTF ((" variable-sized part of Numeric object:\n")) ; } print_ratio (" initial size (Units)", " %20.0f", Info [UMFPACK_VARIABLE_INIT_ESTIMATE], Info [UMFPACK_VARIABLE_INIT]) ; print_ratio (" peak size (Units)", " %20.0f", Info [UMFPACK_VARIABLE_PEAK_ESTIMATE], Info [UMFPACK_VARIABLE_PEAK]) ; print_ratio (" final size (Units)", " %20.0f", Info [UMFPACK_VARIABLE_FINAL_ESTIMATE], Info [UMFPACK_VARIABLE_FINAL]) ; print_ratio ("Numeric final size (Units)", " %20.0f", Info [UMFPACK_NUMERIC_SIZE_ESTIMATE], Info [UMFPACK_NUMERIC_SIZE]) ; print_ratio ("Numeric final size (MBytes)", " %20.1f", MBYTES (Info [UMFPACK_NUMERIC_SIZE_ESTIMATE]), MBYTES (Info [UMFPACK_NUMERIC_SIZE])) ; print_ratio ("peak memory usage (Units)", " %20.0f", Info [UMFPACK_PEAK_MEMORY_ESTIMATE], Info [UMFPACK_PEAK_MEMORY]) ; print_ratio ("peak memory usage (MBytes)", " %20.1f", MBYTES (Info [UMFPACK_PEAK_MEMORY_ESTIMATE]), MBYTES (Info [UMFPACK_PEAK_MEMORY])) ; print_ratio ("numeric factorization flops", " %20.5e", Info [UMFPACK_FLOPS_ESTIMATE], Info [UMFPACK_FLOPS]) ; lnz_est = Info [UMFPACK_LNZ_ESTIMATE] ; unz_est = Info [UMFPACK_UNZ_ESTIMATE] ; if (lnz_est >= 0 && unz_est >= 0) /* double relop, but ignore NaN case */ { lunz_est = lnz_est + unz_est - n_inner ; } else { lunz_est = EMPTY ; } lnz = Info [UMFPACK_LNZ] ; unz = Info [UMFPACK_UNZ] ; if (lnz >= 0 && unz >= 0) /* double relop, but ignore NaN case */ { lunz = lnz + unz - n_inner ; } else { lunz = EMPTY ; } print_ratio ("nz in L (incl diagonal)", " %20.0f", lnz_est, lnz) ; print_ratio ("nz in U (incl diagonal)", " %20.0f", unz_est, unz) ; print_ratio ("nz in L+U (incl diagonal)", " %20.0f", lunz_est, lunz) ; print_ratio ("largest front (# entries)", " %20.0f", Info [UMFPACK_MAX_FRONT_SIZE_ESTIMATE], Info [UMFPACK_MAX_FRONT_SIZE]) ; print_ratio ("largest # rows in front", " %20.0f", Info [UMFPACK_MAX_FRONT_NROWS_ESTIMATE], Info [UMFPACK_MAX_FRONT_NROWS]) ; print_ratio ("largest # columns in front", " %20.0f", Info [UMFPACK_MAX_FRONT_NCOLS_ESTIMATE], Info [UMFPACK_MAX_FRONT_NCOLS]) ; /* ---------------------------------------------------------------------- */ /* numeric factorization */ /* ---------------------------------------------------------------------- */ tnum = Info [UMFPACK_NUMERIC_TIME] ; twnum = Info [UMFPACK_NUMERIC_WALLTIME] ; fnum = Info [UMFPACK_FLOPS] ; PRINT_INFO ("\n initial allocation ratio used: %0.3g\n", Info [UMFPACK_ALLOC_INIT_USED]) ; PRINT_INFO (" # of forced updates due to frontal growth: %.0f\n", Info [UMFPACK_FORCED_UPDATES]) ; PRINT_INFO (" number of off-diagonal pivots: %.0f\n", Info [UMFPACK_NOFF_DIAG]) ; PRINT_INFO (" nz in L (incl diagonal), if none dropped %.0f\n", Info [UMFPACK_ALL_LNZ]) ; PRINT_INFO (" nz in U (incl diagonal), if none dropped %.0f\n", Info [UMFPACK_ALL_UNZ]) ; PRINT_INFO (" number of small entries dropped %.0f\n", Info [UMFPACK_NZDROPPED]) ; PRINT_INFO (" nonzeros on diagonal of U: %.0f\n", Info [UMFPACK_UDIAG_NZ]) ; PRINT_INFO (" min abs. value on diagonal of U: %.2e\n", Info [UMFPACK_UMIN]) ; PRINT_INFO (" max abs. value on diagonal of U: %.2e\n", Info [UMFPACK_UMAX]) ; PRINT_INFO (" estimate of reciprocal of condition number: %.2e\n", Info [UMFPACK_RCOND]) ; PRINT_INFO (" indices in compressed pattern: %.0f\n", Info [UMFPACK_COMPRESSED_PATTERN]) ; PRINT_INFO (" numerical values stored in Numeric object: %.0f\n", Info [UMFPACK_LU_ENTRIES]) ; PRINT_INFO (" numeric factorization defragmentations: %.0f\n", Info [UMFPACK_NUMERIC_DEFRAG]) ; PRINT_INFO (" numeric factorization reallocations: %.0f\n", Info [UMFPACK_NUMERIC_REALLOC]) ; PRINT_INFO (" costly numeric factorization reallocations: %.0f\n", Info [UMFPACK_NUMERIC_COSTLY_REALLOC]) ; PRINT_INFO (" numeric factorization wallclock time (sec): %.2f\n", twnum) ; #define TMIN 0.001 if (twnum > TMIN && fnum > 0) { PRINT_INFO ( " numeric factorization mflops (wallclock): %.2f\n", 1e-6 * fnum / twnum) ; } ftot = fnum ; twtot = EMPTY ; if (twsym >= TMIN && twnum >= TMIN) { twtot = twsym + twnum ; PRINT_INFO (" symbolic + numeric wall clock time (sec): %.2f\n", twtot) ; if (ftot > 0 && twtot > TMIN) { PRINT_INFO ( " symbolic + numeric mflops (wall clock): %.2f\n", 1e-6 * ftot / twtot) ; } } /* ---------------------------------------------------------------------- */ /* solve */ /* ---------------------------------------------------------------------- */ tsolve = Info [UMFPACK_SOLVE_TIME] ; twsolve = Info [UMFPACK_SOLVE_WALLTIME] ; fsolve = Info [UMFPACK_SOLVE_FLOPS] ; PRINT_INFO ("\n solve flops: %.5e\n", fsolve) ; PRINT_INFO (" iterative refinement steps taken: %.0f\n", Info [UMFPACK_IR_TAKEN]) ; PRINT_INFO (" iterative refinement steps attempted: %.0f\n", Info [UMFPACK_IR_ATTEMPTED]) ; PRINT_INFO (" sparse backward error omega1: %.2e\n", Info [UMFPACK_OMEGA1]) ; PRINT_INFO (" sparse backward error omega2: %.2e\n", Info [UMFPACK_OMEGA2]) ; PRINT_INFO (" solve wall clock time (sec): %.2f\n", twsolve) ; if (fsolve > 0 && twsolve > TMIN) { PRINT_INFO ( " solve mflops (wall clock time): %.2f\n", 1e-6 * fsolve / twsolve) ; } if (ftot >= 0 && fsolve >= 0) { ftot += fsolve ; PRINT_INFO ( "\n total symbolic + numeric + solve flops: %.5e\n", ftot) ; } if (twsolve >= TMIN) { if (twtot >= TMIN && ftot >= 0) { twtot += tsolve ; PRINT_INFO ( " total symbolic+numeric+solve wall clock time: %.2f\n", twtot) ; if (ftot > 0 && twtot > TMIN) { PRINT_INFO ( " total symbolic+numeric+solve mflops(wallclock) %.2f\n", 1e-6 * ftot / twtot) ; } } } PRINTF (("\n")) ; }