예제 #1
0
GLOBAL Int UMFPACK_report_vector
(
    Int n,
    const double Xx [ ],
#ifdef COMPLEX
    const double Xz [ ],
#endif
    const double Control [UMFPACK_CONTROL]
)
{
    Int prl ;

#ifndef COMPLEX
    double *Xz = (double *) NULL ;
#endif

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    return (UMF_report_vector (n, Xx, Xz, prl, TRUE, FALSE)) ;
}
예제 #2
0
void handler ( void )
{
    unsigned int ra;


    hexstring(GET_APSR());
    hexstring(GET_IPSR());
    hexstring(GET_EPSR());
    hexstring(GET_CONTROL());
    hexstring(SP_PROCESS());
    hexstring(SP_MAIN());
    hexstring(GET_SP());
    ra=GET_SP();
    for(;ra<0x20001000;ra+=4)
    {
        hexstrings(ra);
        hexstring(GET32(ra));
    }
    ra=SP_PROCESS();
    for(;ra<0x20000D00;ra+=4)
    {
        hexstrings(ra);
        hexstring(GET32(ra));
    }

    iwait();
}
예제 #3
0
//------------------------------------------------------------------------
int notmain ( void )
{
    unsigned int ra;

    PUT16(WDTCTL,0x5A84); //stop WDT

    uart_init(); //see readme
    for(ra=0;ra<1000;ra++) dummy(ra);
    hexstring(0x12345678);

    hexstring(GET_APSR());
    hexstring(GET_IPSR());
    hexstring(GET_EPSR());
    hexstring(SP_PROCESS());
    SETPSP(0x20000D00);
    hexstring(SP_PROCESS());
    hexstring(GET_CONTROL());
    ra=GET_CONTROL();
    //SETCONTROL(ra|(1<<1));
    hexstring(GET_CONTROL());
    hexstring(SP_MAIN());
    hexstring(GET_SP());
    ra=GET_SP();
    for(;ra<0x20000D00;ra+=4)
    {
        hexstrings(ra);
        hexstring(GET32(ra));
    }

    PUT32(SYST_CSR,4);
    PUT32(SYST_RVR,6000000-1);
    PUT32(SYST_CVR,6000000-1);
    PUT32(SYST_CSR,7);
    iwait();

    return(0);
}
GLOBAL Int UMFPACK_report_perm
(
    Int np,
    const Int Perm [ ],
    const double Control [UMFPACK_CONTROL]
)
{
    Int prl, *W, status ;

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    W = (Int *) UMF_malloc (MAX (np,1), sizeof (Int)) ;
    status = UMF_report_perm (np, Perm, W, prl, 1) ;
    (void) UMF_free ((void *) W) ;
    return (status) ;
}
예제 #5
0
GLOBAL Int UMFPACK_report_matrix
(
    Int n_row,
    Int n_col,
    const Int Ap [ ],
    const Int Ai [ ],
    const double Ax [ ],
#ifdef COMPLEX
    const double Az [ ],
#endif
    Int col_form,		/* 1: column form, 0: row form */
    const double Control [UMFPACK_CONTROL]
)
{
    Entry a ;
    Int prl, i, k, length, ilast, p, nz, prl1, p1, p2, n, n_i, do_values ;
    char *vector_kind, *index_kind ;
#ifdef COMPLEX
    Int split = SPLIT (Az) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* determine the form, and check if inputs exist */
    /* ---------------------------------------------------------------------- */

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    if (col_form)
    {
	vector_kind = "column" ;	/* column vectors */
	index_kind = "row" ;		/* with row indices */
	n = n_col ;
	n_i = n_row ;
    }
    else
    {
	vector_kind = "row" ;	/* row vectors */
	index_kind = "column" ;	/* with column indices */
	n = n_row ;
	n_i = n_col ;
    }

    PRINTF (("%s-form matrix, n_row "ID" n_col "ID", ",
        vector_kind, n_row, n_col)) ;

    if (n_row <= 0 || n_col <= 0)
    {
	PRINTF (("ERROR: n_row <= 0 or n_col <= 0\n\n")) ;
	return (UMFPACK_ERROR_n_nonpositive) ;
    }

    if (!Ap)
    {
	PRINTF (("ERROR: Ap missing\n\n")) ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    nz = Ap [n] ;
    PRINTF (("nz = "ID". ", nz)) ;
    if (nz < 0)
    {
	PRINTF (("ERROR: number of entries < 0\n\n")) ;
	return (UMFPACK_ERROR_invalid_matrix) ;
    }

    if (Ap [0] != 0)
    {
	PRINTF (("ERROR: Ap ["ID"] = "ID" must be "ID"\n\n",
	    (Int) INDEX (0), INDEX (Ap [0]), (Int) INDEX (0))) ;
	return (UMFPACK_ERROR_invalid_matrix) ;
    }

    if (!Ai)
    {
	PRINTF (("ERROR: Ai missing\n\n")) ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    do_values = Ax != (double *) NULL ;

    PRINTF4 (("\n")) ;

    /* ---------------------------------------------------------------------- */
    /* check the row/column pointers, Ap */
    /* ---------------------------------------------------------------------- */

    for (k = 0 ; k < n ; k++)
    {
	if (Ap [k] < 0)
	{
	    PRINTF (("ERROR: Ap ["ID"] < 0\n\n", INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
	if (Ap [k] > nz)
	{
	    PRINTF (("ERROR: Ap ["ID"] > size of Ai\n\n", INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

    for (k = 0 ; k < n ; k++)
    {
	length = Ap [k+1] - Ap [k] ;
	if (length < 0)
	{
	    PRINTF (("ERROR: # entries in %s "ID" is < 0\n\n",
		vector_kind, INDEX (k))) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* print each vector */
    /* ---------------------------------------------------------------------- */

    prl1 = prl ;

    for (k = 0 ; k < n ; k++)
    {
	/* if prl is 4, print the first 10 entries of the first 10 vectors */
	if (k < 10)
	{
	    prl = prl1 ;
	}
	/* get the vector pointers */
	p1 = Ap [k] ;
	p2 = Ap [k+1] ;
	length = p2 - p1 ;
	PRINTF4 (("\n    %s "ID": start: "ID" end: "ID" entries: "ID"\n",
	    vector_kind, INDEX (k), p1, p2-1, length)) ;
	ilast = EMPTY ;
	for (p = p1 ; p < p2 ; p++)
	{
	    i = Ai [p] ;
	    PRINTF4 (("\t%s "ID" ", index_kind, INDEX (i))) ;
	    if (do_values && prl >= 4)
	    {
		PRINTF ((":")) ;
		ASSIGN (a, Ax, Az, p, split) ;
		PRINT_ENTRY (a) ;
	    }
	    if (i < 0 || i >= n_i)
	    {
		PRINTF ((" ERROR: %s index "ID" out of range in %s "ID"\n\n",
		    index_kind, INDEX (i), vector_kind, INDEX (k))) ;
		return (UMFPACK_ERROR_invalid_matrix) ;
	    }
	    if (i <= ilast)
	    {
		PRINTF ((" ERROR: %s index "ID" out of order (or duplicate) in "
		    "%s "ID"\n\n", index_kind, INDEX (i),
                    vector_kind, INDEX (k))) ;
		return (UMFPACK_ERROR_invalid_matrix) ;
	    }
	    PRINTF4 (("\n")) ;
	    /* truncate printout, but continue to check matrix */
	    if (prl == 4 && (p - p1) == 9 && length > 10)
	    {
		PRINTF4 (("\t...\n")) ;
		prl-- ;
	    }
	    ilast = i ;
	}
	/* truncate printout, but continue to check matrix */
	if (prl == 4 && k == 9 && n > 10)
	{
	    PRINTF4 (("\n    ...\n")) ;
	    prl-- ;
	}
    }
    prl = prl1 ;

    /* ---------------------------------------------------------------------- */
    /* return the status of the matrix */
    /* ---------------------------------------------------------------------- */

    PRINTF4 (("    %s-form matrix ", vector_kind)) ;
    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) ;
}
예제 #7
0
GLOBAL void UMFPACK_report_status
(
    const double Control [UMFPACK_CONTROL],
    Int status
)
{
    Int prl ;

    /* ---------------------------------------------------------------------- */
    /* get control settings and status to determine what to print */
    /* ---------------------------------------------------------------------- */

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl < 1)
    {
	/* no output generated if prl is less than 1 */
	return ;
    }

    if (status == UMFPACK_OK && prl <= 1)
    {
	/* no output generated if prl is 1 or less and no error occurred. */
	/* note that the default printing level is 1. */
	return ;
    }

    /* ---------------------------------------------------------------------- */
    /* print umfpack license, copyright, version, and status condition */
    /* ---------------------------------------------------------------------- */

    PRINTF  (("\n")) ;
    PRINTF4 (("%s\n", UMFPACK_COPYRIGHT)) ;
    PRINTF6 (("%s", UMFPACK_LICENSE_PART1)) ;
    PRINTF6 (("%s", UMFPACK_LICENSE_PART2)) ;
    PRINTF6 (("%s", UMFPACK_LICENSE_PART3)) ;
    PRINTF  (("%s: ", UMFPACK_VERSION)) ;

    switch (status)
    {
	case UMFPACK_OK:
	    PRINTF (("OK\n")) ;
	    break ;

	case UMFPACK_WARNING_singular_matrix:
	    PRINTF (("WARNING: matrix is singular\n")) ;
	    break ;

	case UMFPACK_ERROR_out_of_memory:
	    PRINTF (("ERROR: out of memory\n")) ;
	    break ;

	case UMFPACK_ERROR_invalid_Numeric_object:
	    PRINTF (("ERROR: Numeric object is invalid\n")) ;
	    break ;

	case UMFPACK_ERROR_invalid_Symbolic_object:
	    PRINTF (("ERROR: Symbolic object is invalid\n")) ;
	    break ;

	case UMFPACK_ERROR_argument_missing:
	    PRINTF (("ERROR: required argument(s) missing\n")) ;
	    break ;

	case UMFPACK_ERROR_n_nonpositive:
	    PRINTF (("ERROR: dimension (n_row or n_col) must be > 0\n")) ;
	    break ;

	case UMFPACK_ERROR_invalid_matrix:
	    PRINTF (("ERROR: input matrix is invalid\n")) ;
	    break ;

	case UMFPACK_ERROR_invalid_system:
	    PRINTF (("ERROR: system argument invalid\n")) ;
	    break ;

	case UMFPACK_ERROR_invalid_permutation:
	    PRINTF (("ERROR: invalid permutation\n")) ;
	    break ;

	case UMFPACK_ERROR_different_pattern:
	    PRINTF (("ERROR: pattern of matrix (Ap and/or Ai) has changed\n")) ;
	    break ;

	case UMFPACK_ERROR_internal_error:
	    PRINTF (("INTERNAL ERROR!\n"
	    "Input arguments might be corrupted or aliased, or an internal\n"
	    "error has occurred.  Check your input arguments with the\n"
	    "umfpack_*_report_* routines before calling the umfpack_*\n"
	    "computational routines.  Recompile UMFPACK with debugging\n"
	    "enabled, and look for failed assertions.  If all else fails\n"
	    "please report this error to Tim Davis ([email protected]).\n"
	    )) ;
	    break ;

	default:
	    PRINTF (("ERROR: Unrecognized error code: "ID"\n", status)) ;

    }
    PRINTF  (("\n")) ;
}
GLOBAL Int UMFPACK_numeric
(
    const Int Ap [ ],
    const Int Ai [ ],
    const double Ax [ ],
#ifdef COMPLEX
    const double Az [ ],
#endif
    void *SymbolicHandle,
    void **NumericHandle,
    const double Control [UMFPACK_CONTROL],
    double User_Info [UMFPACK_INFO]
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    double Info2 [UMFPACK_INFO], alloc_init, relpt, relpt2, droptol,
	front_alloc_init, stats [2] ;
    double *Info ;
    WorkType WorkSpace, *Work ;
    NumericType *Numeric ;
    SymbolicType *Symbolic ;
    Int n_row, n_col, n_inner, newsize, i, status, *inew, npiv, ulen, scale ;
    Unit *mnew ;

    /* ---------------------------------------------------------------------- */
    /* get the amount of time used by the process so far */
    /* ---------------------------------------------------------------------- */

    umfpack_tic (stats) ;

    /* ---------------------------------------------------------------------- */
    /* initialize and check inputs */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    UMF_dump_start ( ) ;
    init_count = UMF_malloc_count ;
    DEBUGm4 (("\nUMFPACK numeric: U transpose version\n")) ;
#endif

    /* If front_alloc_init negative then allocate that size of front in
     * UMF_start_front.  If alloc_init negative, then allocate that initial
     * size of Numeric->Memory. */

    relpt = GET_CONTROL (UMFPACK_PIVOT_TOLERANCE,
	UMFPACK_DEFAULT_PIVOT_TOLERANCE) ;
    relpt2 = GET_CONTROL (UMFPACK_SYM_PIVOT_TOLERANCE,
	UMFPACK_DEFAULT_SYM_PIVOT_TOLERANCE) ;
    alloc_init = GET_CONTROL (UMFPACK_ALLOC_INIT, UMFPACK_DEFAULT_ALLOC_INIT) ;
    front_alloc_init = GET_CONTROL (UMFPACK_FRONT_ALLOC_INIT,
	UMFPACK_DEFAULT_FRONT_ALLOC_INIT) ;
    scale = GET_CONTROL (UMFPACK_SCALE, UMFPACK_DEFAULT_SCALE) ;
    droptol = GET_CONTROL (UMFPACK_DROPTOL, UMFPACK_DEFAULT_DROPTOL) ;

    relpt   = MAX (0.0, MIN (relpt,  1.0)) ;
    relpt2  = MAX (0.0, MIN (relpt2, 1.0)) ;
    droptol = MAX (0.0, droptol) ;
    front_alloc_init = MIN (1.0, front_alloc_init) ;

    if (scale != UMFPACK_SCALE_NONE && scale != UMFPACK_SCALE_MAX)
    {
	scale = UMFPACK_DEFAULT_SCALE ;
    }

    if (User_Info != (double *) NULL)
    {
	/* return Info in user's array */
	Info = User_Info ;
	/* clear the parts of Info that are set by UMFPACK_numeric */
	for (i = UMFPACK_NUMERIC_SIZE ; i <= UMFPACK_MAX_FRONT_NCOLS ; i++)
	{
	    Info [i] = EMPTY ;
	}
	for (i = UMFPACK_NUMERIC_DEFRAG ; i < UMFPACK_IR_TAKEN ; i++)
	{
	    Info [i] = EMPTY ;
	}
    }
    else
    {
	/* no Info array passed - use local one instead */
	Info = Info2 ;
	for (i = 0 ; i < UMFPACK_INFO ; i++)
	{
	    Info [i] = EMPTY ;
	}
    }

    Symbolic = (SymbolicType *) SymbolicHandle ;
    Numeric = (NumericType *) NULL ;
    if (!UMF_valid_symbolic (Symbolic))
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_invalid_Symbolic_object ;
	return (UMFPACK_ERROR_invalid_Symbolic_object) ;
    }

    /* compute alloc_init automatically for AMD or other symmetric ordering */
    if (/* Symbolic->ordering == UMFPACK_ORDERING_AMD */ alloc_init >= 0
        && Symbolic->amd_lunz > 0)
    {
	alloc_init = (Symbolic->nz + Symbolic->amd_lunz) / Symbolic->lunz_bound;
	alloc_init = MIN (1.0, alloc_init) ;
	alloc_init *= UMF_REALLOC_INCREASE ;
    }

    n_row = Symbolic->n_row ;
    n_col = Symbolic->n_col ;
    n_inner = MIN (n_row, n_col) ;

    /* check for integer overflow in Numeric->Memory minimum size */
    if (INT_OVERFLOW (Symbolic->dnum_mem_init_usage * sizeof (Unit)))
    {
	/* :: int overflow, initial Numeric->Memory size :: */
	/* There's no hope to allocate a Numeric object big enough simply to
	 * hold the initial matrix, so return an out-of-memory condition */
	DEBUGm4 (("out of memory: numeric int overflow\n")) ;
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }

    Info [UMFPACK_STATUS] = UMFPACK_OK ;
    Info [UMFPACK_NROW] = n_row ;
    Info [UMFPACK_NCOL] = n_col ;
    Info [UMFPACK_SIZE_OF_UNIT] = (double) (sizeof (Unit)) ;

    if (!Ap || !Ai || !Ax || !NumericHandle)
    {
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_argument_missing ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    Info [UMFPACK_NZ] = Ap [n_col] ;
    *NumericHandle = (void *) NULL ;

    /* ---------------------------------------------------------------------- */
    /* allocate the Work object */
    /* ---------------------------------------------------------------------- */

    /* (1) calls UMF_malloc 15 or 17 times, to obtain temporary workspace of
     * size c+1 Entry's and 2*(n_row+1) + 3*(n_col+1) + (n_col+n_inner+1) +
     * (nn+1) + * 3*(c+1) + 2*(r+1) + max(r,c) + (nfr+1) integers plus 2*nn
     * more integers if diagonal pivoting is to be done.  r is the maximum
     * number of rows in any frontal matrix, c is the maximum number of columns
     * in any frontal matrix, n_inner is min (n_row,n_col), nn is
     * max (n_row,n_col), and nfr is the number of frontal matrices.  For a
     * square matrix, this is c+1 Entry's and about 8n + 3c + 2r + max(r,c) +
     * nfr integers, plus 2n more for diagonal pivoting.
     */

    Work = &WorkSpace ;
    Work->n_row = n_row ;
    Work->n_col = n_col ;
    Work->nfr = Symbolic->nfr ;
    Work->nb = Symbolic->nb ;
    Work->n1 = Symbolic->n1 ;

    if (!work_alloc (Work, Symbolic))
    {
	DEBUGm4 (("out of memory: numeric work\n")) ;
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
	error (&Numeric, Work) ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }
    ASSERT (UMF_malloc_count == init_count + 16 + 2*Symbolic->prefer_diagonal) ;

    /* ---------------------------------------------------------------------- */
    /* allocate Numeric object */
    /* ---------------------------------------------------------------------- */

    /* (2) calls UMF_malloc 10 or 11 times, for a total space of
     * sizeof (NumericType) bytes, 4*(n_row+1) + 4*(n_row+1) integers, and
     * (n_inner+1) Entry's, plus n_row Entry's if row scaling is to be done.
     * sizeof (NumericType) is a small constant.  Next, it calls UMF_malloc
     * once, for the variable-sized part of the Numeric object
     * (Numeric->Memory).  The size of this object is the larger of
     * (Control [UMFPACK_ALLOC_INIT]) *  (the approximate upper bound computed
     * by UMFPACK_symbolic), and the minimum required to start the numerical
     * factorization.  * This request is reduced if it fails.
     */

    if (!numeric_alloc (&Numeric, Symbolic, alloc_init, scale))
    {
	DEBUGm4 (("out of memory: initial numeric\n")) ;
	Info [UMFPACK_STATUS] = UMFPACK_ERROR_out_of_memory ;
	error (&Numeric, Work) ;
	return (UMFPACK_ERROR_out_of_memory) ;
    }
    DEBUG0 (("malloc: init_count "ID" UMF_malloc_count "ID"\n",
	init_count, UMF_malloc_count)) ;
    ASSERT (UMF_malloc_count == init_count
	+ (16 + 2*Symbolic->prefer_diagonal)
	+ (11 + (scale != UMFPACK_SCALE_NONE))) ;

    /* set control parameters */
    Numeric->relpt = relpt ;
    Numeric->relpt2 = relpt2 ;
    Numeric->droptol = droptol ;
    Numeric->alloc_init = alloc_init ;
    Numeric->front_alloc_init = front_alloc_init ;
    Numeric->scale = scale ;

    DEBUG0 (("umf relpt %g %g init %g %g inc %g red %g\n",
	relpt, relpt2, alloc_init, front_alloc_init,
	UMF_REALLOC_INCREASE, UMF_REALLOC_REDUCTION)) ;

    /* ---------------------------------------------------------------------- */
    /* scale and factorize */
    /* ---------------------------------------------------------------------- */

    /* (3) During numerical factorization (inside UMF_kernel), the variable-size
     * block of memory is increased in size via a call to UMF_realloc if it is
     * found to be too small.  During factorization, this block holds the
     * pattern and values of L and U at the top end, and the elements
     * (contibution blocks) and the current frontal matrix (Work->F*) at the
     * bottom end.  The peak size of the variable-sized object is estimated in
     * UMFPACK_*symbolic (Info [UMFPACK_VARIABLE_PEAK_ESTIMATE]), although this
     * upper bound can be very loose.  The size of the Symbolic object
     * (which is currently allocated) is in Info [UMFPACK_SYMBOLIC_SIZE], and
     * is between 2*n and 13*n integers.
     */

    DEBUG0 (("Calling umf_kernel\n")) ;
    status = UMF_kernel (Ap, Ai, Ax,
#ifdef COMPLEX
	Az,
#endif
	Numeric, Work, Symbolic) ;

    Info [UMFPACK_STATUS] = status ;
    if (status < UMFPACK_OK)
    {
	/* out of memory, or pattern has changed */
	error (&Numeric, Work) ;
	return (status) ;
    }

    Info [UMFPACK_FORCED_UPDATES] = Work->nforced ;
    Info [UMFPACK_VARIABLE_INIT] = Numeric->init_usage ;
    if (Symbolic->prefer_diagonal)
    {
	Info [UMFPACK_NOFF_DIAG] = Work->noff_diagonal ;
    }

    DEBUG0 (("malloc: init_count "ID" UMF_malloc_count "ID"\n",
	init_count, UMF_malloc_count)) ;

    npiv = Numeric->npiv ;	/* = n_inner for nonsingular matrices */
    ulen = Numeric->ulen ;	/* = 0 for square nonsingular matrices */

    /* ---------------------------------------------------------------------- */
    /* free Work object */
    /* ---------------------------------------------------------------------- */

    /* (4) After numerical factorization all of the objects allocated in step
     * (1) are freed via UMF_free, except that one object of size n_col+1 is
     * kept if there are off-diagonal nonzeros in the last pivot row (can only
     * occur for singular or rectangular matrices).  This is Work->Upattern,
     * which is transfered to Numeric->Upattern if ulen > 0.
     */

    DEBUG0 (("malloc: init_count "ID" UMF_malloc_count "ID"\n",
	init_count, UMF_malloc_count)) ;

    free_work (Work) ;

    DEBUG0 (("malloc: init_count "ID" UMF_malloc_count "ID"\n",
	init_count, UMF_malloc_count)) ;
    DEBUG0 (("Numeric->ulen: "ID" scale: "ID"\n", ulen, scale)) ;
    ASSERT (UMF_malloc_count == init_count + (ulen > 0) +
	(11 + (scale != UMFPACK_SCALE_NONE))) ;

    /* ---------------------------------------------------------------------- */
    /* reduce Lpos, Lilen, Lip, Upos, Uilen and Uip to size npiv+1 */
    /* ---------------------------------------------------------------------- */

    /* (5) Six components of the Numeric object are reduced in size if the
     * matrix is singular or rectangular.   The original size is 3*(n_row+1) +
     * 3*(n_col+1) integers.  The new size is 6*(npiv+1) integers.  For
     * square non-singular matrices, these two sizes are the same.
     */

    if (npiv < n_row)
    {
	/* reduce Lpos, Uilen, and Uip from size n_row+1 to size npiv */
	inew = (Int *) UMF_realloc (Numeric->Lpos, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Lpos = inew ;
	}
	inew = (Int *) UMF_realloc (Numeric->Uilen, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Uilen = inew ;
	}
	inew = (Int *) UMF_realloc (Numeric->Uip, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Uip = inew ;
	}
    }

    if (npiv < n_col)
    {
	/* reduce Upos, Lilen, and Lip from size n_col+1 to size npiv */
	inew = (Int *) UMF_realloc (Numeric->Upos, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Upos = inew ;
	}
	inew = (Int *) UMF_realloc (Numeric->Lilen, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Lilen = inew ;
	}
	inew = (Int *) UMF_realloc (Numeric->Lip, npiv+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Lip = inew ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* reduce Numeric->Upattern from size n_col+1 to size ulen+1 */
    /* ---------------------------------------------------------------------- */

    /* (6) The size of Numeric->Upattern (formerly Work->Upattern) is reduced
     * from size n_col+1 to size ulen + 1.  If ulen is zero, the object does
     * not exist. */

    DEBUG4 (("ulen: "ID" Upattern "ID"\n", ulen, (Int) Numeric->Upattern)) ;
    ASSERT (IMPLIES (ulen == 0, Numeric->Upattern == (Int *) NULL)) ;
    if (ulen > 0 && ulen < n_col)
    {
	inew = (Int *) UMF_realloc (Numeric->Upattern, ulen+1, sizeof (Int)) ;
	if (inew)
	{
	    Numeric->Upattern = inew ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* reduce Numeric->Memory to hold just the LU factors at the head */
    /* ---------------------------------------------------------------------- */

    /* (7) The variable-sized block (Numeric->Memory) is reduced to hold just L
     * and U, via a call to UMF_realloc, since the frontal matrices are no
     * longer needed.
     */

    newsize = Numeric->ihead ;
    if (newsize < Numeric->size)
    {
	mnew = (Unit *) UMF_realloc (Numeric->Memory, newsize, sizeof (Unit)) ;
	if (mnew)
	{
	    /* realloc succeeded (how can it fail since the size is reduced?) */
	    Numeric->Memory = mnew ;
	    Numeric->size = newsize ;
	}
    }
    Numeric->ihead = Numeric->size ;
    Numeric->itail = Numeric->ihead ;
    Numeric->tail_usage = 0 ;
    Numeric->ibig = EMPTY ;
    /* UMF_mem_alloc_tail_block can no longer be called (no tail marker) */

    /* ---------------------------------------------------------------------- */
    /* report the results and return the Numeric object */
    /* ---------------------------------------------------------------------- */

    UMF_set_stats (
	Info,
	Symbolic,
	(double) Numeric->max_usage,	/* actual peak Numeric->Memory */
	(double) Numeric->size,		/* actual final Numeric->Memory */
	Numeric->flops,			/* actual "true flops" */
	(double) Numeric->lnz + n_inner,		/* actual nz in L */
	(double) Numeric->unz + Numeric->nnzpiv,	/* actual nz in U */
	(double) Numeric->maxfrsize,	/* actual largest front size */
	(double) ulen,			/* actual Numeric->Upattern size */
	(double) npiv,			/* actual # pivots found */
	(double) Numeric->maxnrows,	/* actual largest #rows in front */
	(double) Numeric->maxncols,	/* actual largest #cols in front */
	scale != UMFPACK_SCALE_NONE,
	Symbolic->prefer_diagonal,
	ACTUAL) ;

    Info [UMFPACK_ALLOC_INIT_USED] = Numeric->alloc_init ;
    Info [UMFPACK_NUMERIC_DEFRAG] = Numeric->ngarbage ;
    Info [UMFPACK_NUMERIC_REALLOC] = Numeric->nrealloc ;
    Info [UMFPACK_NUMERIC_COSTLY_REALLOC] = Numeric->ncostly ;
    Info [UMFPACK_COMPRESSED_PATTERN] = Numeric->isize ;
    Info [UMFPACK_LU_ENTRIES] = Numeric->nLentries + Numeric->nUentries +
	    Numeric->npiv ;
    Info [UMFPACK_UDIAG_NZ] = Numeric->nnzpiv ;
    Info [UMFPACK_RSMIN] = Numeric->rsmin ;
    Info [UMFPACK_RSMAX] = Numeric->rsmax ;
    Info [UMFPACK_WAS_SCALED] = Numeric->scale ;

    /* nz in L and U with no dropping of small entries */
    Info [UMFPACK_ALL_LNZ] = Numeric->all_lnz + n_inner ;
    Info [UMFPACK_ALL_UNZ] = Numeric->all_unz + Numeric->nnzpiv ;
    Info [UMFPACK_NZDROPPED] =
	  (Numeric->all_lnz - Numeric->lnz)
	+ (Numeric->all_unz - Numeric->unz) ;

    /* estimate of the reciprocal of the condition number. */
    if (SCALAR_IS_ZERO (Numeric->min_udiag)
     || SCALAR_IS_ZERO (Numeric->max_udiag)
     ||	SCALAR_IS_NAN (Numeric->min_udiag)
     ||	SCALAR_IS_NAN (Numeric->max_udiag))
    {
	/* rcond is zero if there is any zero or NaN on the diagonal */
	Numeric->rcond = 0.0 ;
    }
    else
    {
	/* estimate of the recipricol of the condition number. */
	/* This is NaN if diagonal is zero-free, but has one or more NaN's. */
	Numeric->rcond = Numeric->min_udiag / Numeric->max_udiag ;
    }
    Info [UMFPACK_UMIN]  = Numeric->min_udiag ;
    Info [UMFPACK_UMAX]  = Numeric->max_udiag ;
    Info [UMFPACK_RCOND] = Numeric->rcond ;

    if (Numeric->nnzpiv < n_inner
    || SCALAR_IS_ZERO (Numeric->rcond) || SCALAR_IS_NAN (Numeric->rcond))
    {
	/* there are zeros and/or NaN's on the diagonal of U */
	DEBUG0 (("Warning, matrix is singular in umfpack_numeric\n")) ;
	DEBUG0 (("nnzpiv "ID" n_inner "ID" rcond %g\n", Numeric->nnzpiv,
	    n_inner, Numeric->rcond)) ;
	status = UMFPACK_WARNING_singular_matrix ;
	Info [UMFPACK_STATUS] = status ;
    }

    Numeric->valid = NUMERIC_VALID ;
    *NumericHandle = (void *) Numeric ;

    /* Numeric has 11 to 13 objects */
    ASSERT (UMF_malloc_count == init_count + 11 +
	+ (ulen > 0)			    /* Numeric->Upattern */
	+ (scale != UMFPACK_SCALE_NONE)) ;  /* Numeric->Rs */

    /* ---------------------------------------------------------------------- */
    /* get the time used by UMFPACK_numeric */
    /* ---------------------------------------------------------------------- */

    umfpack_toc (stats) ;
    Info [UMFPACK_NUMERIC_WALLTIME] = stats [0] ;
    Info [UMFPACK_NUMERIC_TIME] = stats [1] ;

    /* return UMFPACK_OK or UMFPACK_WARNING_singular_matrix */
    return (status) ;

}
예제 #9
0
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 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")) ;
}
예제 #11
0
GLOBAL void UMFPACK_report_control
(
    const double Control [UMFPACK_CONTROL]
)
{
    double drow, dcol, relpt, relpt2, alloc_init, front_alloc_init, amd_alpha,
           tol, force_fixQ, droptol, aggr ;
    Int prl, nb, irstep, strategy, scale, s ;

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl < 2)
    {
        /* default is to print nothing */
        return ;
    }

    PRINTF  (("UMFPACK V%d.%d.%d (%s), Control:\n", UMFPACK_MAIN_VERSION,
              UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION, UMFPACK_DATE)) ;

    /* ---------------------------------------------------------------------- */
    /* run-time options */
    /* ---------------------------------------------------------------------- */

    /* This is a "run-time" option because all four umfpack_* versions */
    /* compiled into the UMFPACK library. */

#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: UF_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: UF_long\n")) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* printing level */
    /* ---------------------------------------------------------------------- */

    PRINTF (("\n    "ID": print level: "ID"\n",
             (Int) INDEX (UMFPACK_PRL), prl)) ;

    /* ---------------------------------------------------------------------- */
    /* dense row/col parameters */
    /* ---------------------------------------------------------------------- */

    drow = GET_CONTROL (UMFPACK_DENSE_ROW, UMFPACK_DEFAULT_DENSE_ROW) ;
    dcol = GET_CONTROL (UMFPACK_DENSE_COL, UMFPACK_DEFAULT_DENSE_COL) ;

    PRINTF (("    "ID": dense row parameter:    %g\n",
             (Int) INDEX (UMFPACK_DENSE_ROW), drow)) ;
    PRINTF (("        \"dense\" rows have    > max (16, (%g)*16*sqrt(n_col)"
             " entries)\n", drow)) ;
    PRINTF (("    "ID": dense column parameter: %g\n",
             (Int) INDEX (UMFPACK_DENSE_COL), dcol)) ;
    PRINTF (("        \"dense\" columns have > max (16, (%g)*16*sqrt(n_row)"
             " entries)\n", dcol)) ;

    /* ---------------------------------------------------------------------- */
    /* pivot tolerance */
    /* ---------------------------------------------------------------------- */

    relpt = GET_CONTROL (UMFPACK_PIVOT_TOLERANCE,
                         UMFPACK_DEFAULT_PIVOT_TOLERANCE) ;
    relpt = MAX (0.0, MIN (relpt, 1.0)) ;
    PRINTF (("    "ID": pivot tolerance: %g\n",
             (Int) INDEX (UMFPACK_PIVOT_TOLERANCE), relpt)) ;

    /* ---------------------------------------------------------------------- */
    /* block size */
    /* ---------------------------------------------------------------------- */

    nb = GET_CONTROL (UMFPACK_BLOCK_SIZE, UMFPACK_DEFAULT_BLOCK_SIZE) ;
    nb = MAX (1, nb) ;
    PRINTF (("    "ID": block size for dense matrix kernels: "ID"\n",
             (Int) INDEX (UMFPACK_BLOCK_SIZE), nb)) ;

    /* ---------------------------------------------------------------------- */
    /* strategy */
    /* ---------------------------------------------------------------------- */

    strategy = GET_CONTROL (UMFPACK_STRATEGY, UMFPACK_DEFAULT_STRATEGY) ;
    if (strategy < UMFPACK_STRATEGY_AUTO
            || strategy > UMFPACK_STRATEGY_SYMMETRIC)
    {
        strategy = UMFPACK_STRATEGY_AUTO ;
    }

    PRINTF (("    "ID": strategy: "ID,
             (Int) INDEX (UMFPACK_STRATEGY), strategy)) ;

    if (strategy == UMFPACK_STRATEGY_SYMMETRIC)
    {
        PRINTF ((" (symmetric)\n"
                 "        Q = AMD (A+A'), Q not refined during numerical\n"
                 "        factorization, and diagonal pivoting (P=Q') attempted.\n")) ;
    }
    else if (strategy == UMFPACK_STRATEGY_UNSYMMETRIC)
    {
        PRINTF ((" (unsymmetric)\n"
                 "        Q = COLAMD (A), Q refined during numerical\n"
                 "        factorization, and no attempt at diagonal pivoting.\n")) ;
    }
#if 0
    else if (strategy == UMFPACK_STRATEGY_2BY2)
    {
        PRINTF ((" (symmetric, with 2-by-2 block pivoting)\n"
                 "        P2 = row permutation that tries to place large entries on\n"
                 "        the diagonal.  Q = AMD (P2*A+(P2*A)'), Q not refined during\n"
                 "        numerical factorization, attempt to select pivots from the\n"
                 "        diagonal of P2*A.\n")) ;
    }
#endif
    else /* auto strategy */
    {
        strategy = UMFPACK_STRATEGY_AUTO ;
        PRINTF ((" (auto)\n")) ;
    }

    /* ---------------------------------------------------------------------- */
    /* initial allocation parameter */
    /* ---------------------------------------------------------------------- */

    alloc_init = GET_CONTROL (UMFPACK_ALLOC_INIT, UMFPACK_DEFAULT_ALLOC_INIT) ;
    if (alloc_init >= 0)
    {
        PRINTF (("    "ID": initial allocation ratio: %g\n",
                 (Int) INDEX (UMFPACK_ALLOC_INIT), alloc_init)) ;
    }
    else
    {
        s = -alloc_init ;
        s = MAX (1, s) ;
        PRINTF (("    "ID": initial allocation (in Units): "ID"\n",
                 (Int) INDEX (UMFPACK_ALLOC_INIT), s)) ;
    }

    /* ---------------------------------------------------------------------- */
    /* maximum iterative refinement steps */
    /* ---------------------------------------------------------------------- */

    irstep = GET_CONTROL (UMFPACK_IRSTEP, UMFPACK_DEFAULT_IRSTEP) ;
    irstep = MAX (0, irstep) ;
    PRINTF (("    "ID": max iterative refinement steps: "ID"\n",
             (Int) INDEX (UMFPACK_IRSTEP), irstep)) ;

    /* ---------------------------------------------------------------------- */
    /* 2-by-2 pivot tolerance */
    /* ---------------------------------------------------------------------- */

    tol = GET_CONTROL (UMFPACK_2BY2_TOLERANCE, UMFPACK_DEFAULT_2BY2_TOLERANCE) ;
    tol = MAX (0.0, MIN (tol, 1.0)) ;
    PRINTF (("    "ID": 2-by-2 pivot tolerance: %g\n",
             (Int) INDEX (UMFPACK_2BY2_TOLERANCE), tol)) ;

    /* ---------------------------------------------------------------------- */
    /* force fixQ */
    /* ---------------------------------------------------------------------- */

    force_fixQ = GET_CONTROL (UMFPACK_FIXQ, UMFPACK_DEFAULT_FIXQ) ;
    PRINTF (("    "ID": Q fixed during numerical factorization: %g ",
             (Int) INDEX (UMFPACK_FIXQ), force_fixQ)) ;
    if (force_fixQ > 0)
    {
        PRINTF (("(yes)\n")) ;
    }
    else if (force_fixQ < 0)
    {
        PRINTF (("(no)\n")) ;
    }
    else
    {
        PRINTF (("(auto)\n")) ;
    }

    /* ---------------------------------------------------------------------- */
    /* AMD parameters */
    /* ---------------------------------------------------------------------- */

    amd_alpha = GET_CONTROL (UMFPACK_AMD_DENSE, UMFPACK_DEFAULT_AMD_DENSE) ;
    PRINTF (("    "ID": AMD dense row/col parameter:    %g\n",
             (Int) INDEX (UMFPACK_AMD_DENSE), amd_alpha)) ;
    if (amd_alpha < 0)
    {
        PRINTF (("       no \"dense\" rows/columns\n")) ;
    }
    else
    {
        PRINTF (("       \"dense\" rows/columns have > max (16, (%g)*sqrt(n))"
                 " entries\n", amd_alpha)) ;
    }
    PRINTF (("        Only used if the AMD ordering is used.\n")) ;

    /* ---------------------------------------------------------------------- */
    /* pivot tolerance for symmetric pivoting */
    /* ---------------------------------------------------------------------- */

    relpt2 = GET_CONTROL (UMFPACK_SYM_PIVOT_TOLERANCE,
                          UMFPACK_DEFAULT_SYM_PIVOT_TOLERANCE) ;
    relpt2 = MAX (0.0, MIN (relpt2, 1.0)) ;
    PRINTF (("    "ID": diagonal pivot tolerance: %g\n"
             "        Only used if diagonal pivoting is attempted.\n",
             (Int) INDEX (UMFPACK_SYM_PIVOT_TOLERANCE), relpt2)) ;

    /* ---------------------------------------------------------------------- */
    /* scaling */
    /* ---------------------------------------------------------------------- */

    scale = GET_CONTROL (UMFPACK_SCALE, UMFPACK_DEFAULT_SCALE) ;
    if (scale != UMFPACK_SCALE_NONE && scale != UMFPACK_SCALE_MAX)
    {
        scale = UMFPACK_DEFAULT_SCALE ;
    }
    PRINTF (("    "ID": scaling: "ID, (Int) INDEX (UMFPACK_SCALE), scale)) ;
    if (scale == UMFPACK_SCALE_NONE)
    {
        PRINTF ((" (no)")) ;
    }
    else if (scale == UMFPACK_SCALE_SUM)
    {
        PRINTF ((" (divide each row by sum of abs. values in each row)")) ;
    }
    else if (scale == UMFPACK_SCALE_MAX)
    {
        PRINTF ((" (divide each row by max. abs. value in each row)")) ;
    }
    PRINTF (("\n")) ;

    /* ---------------------------------------------------------------------- */
    /* frontal matrix allocation parameter */
    /* ---------------------------------------------------------------------- */

    front_alloc_init = GET_CONTROL (UMFPACK_FRONT_ALLOC_INIT,
                                    UMFPACK_DEFAULT_FRONT_ALLOC_INIT) ;
    front_alloc_init = MIN (1.0, front_alloc_init) ;
    if (front_alloc_init >= 0)
    {
        PRINTF (("    "ID": frontal matrix allocation ratio: %g\n",
                 (Int) INDEX (UMFPACK_FRONT_ALLOC_INIT), front_alloc_init)) ;
    }
    else
    {
        s = -front_alloc_init ;
        s = MAX (1, s) ;
        PRINTF (("    "ID": initial frontal matrix size (# of Entry's): "ID"\n",
                 (Int) INDEX (UMFPACK_FRONT_ALLOC_INIT), s)) ;
    }

    /* ---------------------------------------------------------------------- */
    /* drop tolerance */
    /* ---------------------------------------------------------------------- */

    droptol = GET_CONTROL (UMFPACK_DROPTOL, UMFPACK_DEFAULT_DROPTOL) ;
    PRINTF (("    "ID": drop tolerance: %g\n",
             (Int) INDEX (UMFPACK_DROPTOL), droptol)) ;

    /* ---------------------------------------------------------------------- */
    /* aggressive absorption */
    /* ---------------------------------------------------------------------- */

    aggr = GET_CONTROL (UMFPACK_AGGRESSIVE, UMFPACK_DEFAULT_AGGRESSIVE) ;
    PRINTF (("    "ID": AMD and COLAMD aggressive absorption: %g",
             (Int) INDEX (UMFPACK_AGGRESSIVE), aggr)) ;
    if (aggr != 0.0)
    {
        PRINTF ((" (yes)\n")) ;
    }
    else
    {
        PRINTF ((" (no)\n")) ;
    }

    /* ---------------------------------------------------------------------- */
    /* compile-time options */
    /* ---------------------------------------------------------------------- */

    PRINTF ((
                "\n    The following options can only be changed at compile-time:\n")) ;

    PRINTF (("    "ID": BLAS library used:  ",
             (Int) INDEX (UMFPACK_COMPILED_WITH_BLAS))) ;

#ifdef NBLAS
    PRINTF (("none.  UMFPACK will be slow.\n")) ;
#else
    PRINTF (("Fortran BLAS.  size of BLAS integer: "ID"\n",
             (Int) (sizeof (BLAS_INT)))) ;
#endif

#ifdef MATLAB_MEX_FILE
    PRINTF (("    "ID": compiled for MATLAB\n",
             (Int) INDEX (UMFPACK_COMPILED_FOR_MATLAB))) ;
#else
#ifdef MATHWORKS
    PRINTF (("    "ID": compiled for MATLAB\n",
             (Int) INDEX (UMFPACK_COMPILED_FOR_MATLAB))) ;
#else
    PRINTF (("    "ID": compiled for ANSI C\n",
             (Int) INDEX (UMFPACK_COMPILED_FOR_MATLAB))) ;
#endif
#endif

#ifdef NO_TIMER
    PRINTF (("    "ID": no CPU timer \n",
             (Int) INDEX (UMFPACK_COMPILED_WITH_GETRUSAGE))) ;
#else
#ifndef NPOSIX
    PRINTF (("    "ID": CPU timer is POSIX times ( ) routine.\n",
             (Int) INDEX (UMFPACK_COMPILED_WITH_GETRUSAGE))) ;
#else
#ifdef GETRUSAGE
    PRINTF (("    "ID": CPU timer is getrusage.\n",
             (Int) INDEX (UMFPACK_COMPILED_WITH_GETRUSAGE))) ;
#else
    PRINTF (("    "ID": CPU timer is ANSI C clock (may wrap around).\n",
             (Int) INDEX (UMFPACK_COMPILED_WITH_GETRUSAGE))) ;
#endif
#endif
#endif

#ifndef NDEBUG
    PRINTF ((
                "**** Debugging enabled (UMFPACK will be exceedingly slow!) *****************\n"
                "    "ID": compiled with debugging enabled. ",
                (Int) INDEX (UMFPACK_COMPILED_IN_DEBUG_MODE))) ;
#else
    PRINTF (("    "ID": compiled for normal operation (debugging disabled)\n",
             (Int) INDEX (UMFPACK_COMPILED_IN_DEBUG_MODE))) ;
#endif

    PRINTF (("    computer/operating system: %s\n", UMFPACK_ARCHITECTURE)) ;
    PRINTF (("    size of int: %g UF_long: %g Int: %g pointer: %g"
             " double: %g Entry: %g (in bytes)\n\n", (double) sizeof (int),
             (double) sizeof (UF_long), (double) sizeof (Int),
             (double) sizeof (void *), (double) sizeof (double),
             (double) sizeof (Entry))) ;
}
예제 #12
0
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")) ;
	}
	else /* if (Symbolic->strategy == UMFPACK_STRATEGY_UNSYMMETRIC) */
	{
	    PRINTF (("unsymmetric")) ;
	}
#if 0
	else if (Symbolic->strategy == UMFPACK_STRATEGY_2BY2)
예제 #13
0
GLOBAL Int UMFPACK_report_triplet
(
    Int n_row,
    Int n_col,
    Int nz,
    const Int Ti [ ],
    const Int Tj [ ],
    const double Tx [ ],
#ifdef COMPLEX
    const double Tz [ ],
#endif
    const double Control [UMFPACK_CONTROL]
)
{
    Entry t ;
    Int prl, prl1, k, i, j, do_values ;
#ifdef COMPLEX
    Int split = SPLIT (Tz) ;
#endif

    prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;

    if (prl <= 2)
    {
	return (UMFPACK_OK) ;
    }

    PRINTF (("triplet-form matrix, n_row = "ID", n_col = "ID" nz = "ID". ",
	n_row, n_col, nz)) ;

    if (!Ti || !Tj)
    {
	PRINTF (("ERROR: indices not present\n\n")) ;
	return (UMFPACK_ERROR_argument_missing) ;
    }

    if (n_row <= 0 || n_col <= 0)
    {
	PRINTF (("ERROR: n_row or n_col is <= 0\n\n")) ;
	return (UMFPACK_ERROR_n_nonpositive) ;
    }

    if (nz < 0)
    {
	PRINTF (("ERROR: nz is < 0\n\n")) ;
	return (UMFPACK_ERROR_invalid_matrix) ;
    }

    PRINTF4 (("\n")) ;

    do_values = Tx != (double *) NULL ;

    prl1 = prl ;
    for (k = 0 ; k < nz ; k++)
    {
	i = Ti [k] ;
	j = Tj [k] ;
	PRINTF4 (("    "ID" : "ID" "ID" ", INDEX (k), INDEX (i), INDEX (j))) ;
	if (do_values && prl >= 4)
	{
	    ASSIGN (t, Tx, Tz, k, split) ;
	    PRINT_ENTRY (t) ;
	}
	PRINTF4 (("\n")) ;
	if (i < 0 || i >= n_row || j < 0 || j >= n_col)
	{
	    /* invalid triplet */
	    PRINTF (("ERROR: invalid triplet\n\n")) ;
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
	if (prl == 4 && k == 9 && nz > 10)
	{
	    PRINTF (("    ...\n")) ;
	    prl-- ;
	}
    }
    prl = prl1 ;

    PRINTF4 (("    triplet-form matrix ")) ;
    PRINTF (("OK\n\n")) ;
    return (UMFPACK_OK) ;
}
예제 #14
0
void do_it ( unsigned int base )
{
    unsigned int ra;
    unsigned int beg,end;
    unsigned int rb;
    unsigned int min,max;
    unsigned int rc;
    
    stop_l1cache(); //just in case
    invalidate_l1cache();

    
    hexstrings(base);
    hexstrings(base);
    hexstrings(base);
    hexstring(base);

    
    hexstring(GET_CONTROL());
    CLR_CONTROL(1<<11);
    hexstring(GET_CONTROL());

    max=0;
    min=0; min--;
    for(ra=base+0x6000;ra<base+0x6100;ra+=4)
    {
        unsigned int flag;
        
        PUT32(ra+0x00,0xe2500001);
        PUT32(ra+0x04,0x1afffffd);
        PUT32(ra+0x08,0xe12fff1e);
        GET32(ra+0x08);
        PrefetchFlush();
        
        for(rc=0;rc<4;rc++)
        {
            beg=GET32(ARM_TIMER_CNT);
            HOP(0x20000,ra);
            end=GET32(ARM_TIMER_CNT);
            rb=end-beg;
            flag=0;
            if(rb>gmax) gmax=rb;
            if(rb<gmin) gmin=rb;
            if(rb>max) { flag++; max=rb; }
            if(rb<min) { flag++; min=rb; }
            if(flag)
            {
                hexstrings(ra);
                hexstrings(rb);
                hexstrings(min);
                hexstrings(max);
                hexstring(max-min);
            }
        }
    }

    hexstring(GET_CONTROL());
    SET_CONTROL(1<<11);
    hexstring(GET_CONTROL());
if(1)
{
    max=0;
    min=0; min--;
    for(ra=base+0x6000;ra<base+0x6100;ra+=4)
    {
        unsigned int flag;
        
        PUT32(ra+0x00,0xe2500001);
        PUT32(ra+0x04,0x1afffffd);
        PUT32(ra+0x08,0xe12fff1e);
        GET32(ra+0x08);
        PrefetchFlush();


        for(rc=0;rc<4;rc++)
        {
            beg=GET32(ARM_TIMER_CNT);
            HOP(0x20000,ra);
            end=GET32(ARM_TIMER_CNT);
            rb=end-beg;
            flag=0;
            if(rb>gmax) gmax=rb;
            if(rb<gmin) gmin=rb;
            if(rb>max) { flag++; max=rb; }
            if(rb<min) { flag++; min=rb; }
            if(flag)
            {
                hexstrings(ra);
                hexstrings(rb);
                hexstrings(min);
                hexstrings(max);
                hexstring(max-min);
            }
        }
    }
}
    hexstring(GET_CONTROL());
    CLR_CONTROL(1<<11);
    hexstring(GET_CONTROL());
            ra=GET32(ARM_TIMER_CNT);


    start_l1cache();

    max=0;
    min=0; min--;
    for(ra=base+0x6000;ra<base+0x6100;ra+=4)
    {
        unsigned int flag;
        
        PUT32(ra+0x00,0xe2500001);
        PUT32(ra+0x04,0x1afffffd);
        PUT32(ra+0x08,0xe12fff1e);
        GET32(ra+0x08);
        PrefetchFlush();

        invalidate_l1cache();
        for(rc=0;rc<4;rc++)
        {
            beg=GET32(ARM_TIMER_CNT);
            HOP(0x20000,ra);
            end=GET32(ARM_TIMER_CNT);
            rb=end-beg;
            flag=0;
            if(rb>gmax) gmax=rb;
            if(rb<gmin) gmin=rb;
            if(rb>max) { flag++; max=rb; }
            if(rb<min) { flag++; min=rb; }
            if(flag)
            {
                hexstrings(ra);
                hexstrings(rb);
                hexstrings(min);
                hexstrings(max);
                hexstring(max-min);
            }
        }
    }

    hexstring(GET_CONTROL());
    SET_CONTROL(1<<11);
    hexstring(GET_CONTROL());

    max=0;
    min=0; min--;
    for(ra=base+0x6000;ra<base+0x6100;ra+=4)
    {
        unsigned int flag;
        
        PUT32(ra+0x00,0xe2500001);
        PUT32(ra+0x04,0x1afffffd);
        PUT32(ra+0x08,0xe12fff1e);
        GET32(ra+0x08);
        PrefetchFlush();

        invalidate_l1cache();
        for(rc=0;rc<4;rc++)
        {
            beg=GET32(ARM_TIMER_CNT);
            HOP(0x20000,ra);
            end=GET32(ARM_TIMER_CNT);
            rb=end-beg;
            flag=0;
            if(rb>gmax) gmax=rb;
            if(rb<gmin) gmin=rb;
            if(rb>max) { flag++; max=rb; }
            if(rb<min) { flag++; min=rb; }
            if(flag)
            {
                hexstrings(ra);
                hexstrings(rb);
                hexstrings(min);
                hexstrings(max);
                hexstring(max-min);
            }
        }
    }


    hexstring(GET_CONTROL());
    CLR_CONTROL(1<<11);
    hexstring(GET_CONTROL());

    stop_l1cache();
}