181 lines
5.0 KiB
C
181 lines
5.0 KiB
C
/* ========================================================================= */
|
|
/* === AMD_dump ============================================================ */
|
|
/* ========================================================================= */
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* AMD, Copyright (c) Timothy A. Davis, */
|
|
/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
|
|
/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */
|
|
/* web: http://www.cise.ufl.edu/research/sparse/amd */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
/* Debugging routines for AMD. Not used if NDEBUG is not defined at compile-
|
|
* time (the default). See comments in amd_internal.h on how to enable
|
|
* debugging. Not user-callable.
|
|
*/
|
|
|
|
#include "amd_internal.h"
|
|
|
|
#ifndef NDEBUG
|
|
|
|
/* This global variable is present only when debugging */
|
|
GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */
|
|
|
|
/* ========================================================================= */
|
|
/* === AMD_debug_init ====================================================== */
|
|
/* ========================================================================= */
|
|
|
|
/* Sets the debug print level, by reading the file debug.amd (if it exists) */
|
|
|
|
GLOBAL void AMD_debug_init ( char *s )
|
|
{
|
|
FILE *f ;
|
|
f = fopen ("debug.amd", "r") ;
|
|
if (f == (FILE *) NULL)
|
|
{
|
|
AMD_debug = -999 ;
|
|
}
|
|
else
|
|
{
|
|
fscanf (f, ID, &AMD_debug) ;
|
|
fclose (f) ;
|
|
}
|
|
if (AMD_debug >= 0)
|
|
{
|
|
printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ;
|
|
}
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
/* === AMD_dump ============================================================ */
|
|
/* ========================================================================= */
|
|
|
|
/* Dump AMD's data structure, except for the hash buckets. This routine
|
|
* cannot be called when the hash buckets are non-empty.
|
|
*/
|
|
|
|
GLOBAL void AMD_dump (
|
|
Int n, /* A is n-by-n */
|
|
Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */
|
|
Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1]
|
|
* holds the matrix on input */
|
|
Int Len [ ], /* len [0..n-1]: length for row i */
|
|
Int iwlen, /* length of iw */
|
|
Int pfree, /* iw [pfree ... iwlen-1] is empty on input */
|
|
Int Nv [ ], /* nv [0..n-1] */
|
|
Int Next [ ], /* next [0..n-1] */
|
|
Int Last [ ], /* last [0..n-1] */
|
|
Int Head [ ], /* head [0..n-1] */
|
|
Int Elen [ ], /* size n */
|
|
Int Degree [ ], /* size n */
|
|
Int W [ ], /* size n */
|
|
Int nel
|
|
)
|
|
{
|
|
Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ;
|
|
|
|
if (AMD_debug < 0) return ;
|
|
ASSERT (pfree <= iwlen) ;
|
|
AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ;
|
|
for (i = 0 ; i < n ; i++)
|
|
{
|
|
pe = Pe [i] ;
|
|
elen = Elen [i] ;
|
|
nv = Nv [i] ;
|
|
len = Len [i] ;
|
|
w = W [i] ;
|
|
|
|
if (elen >= EMPTY)
|
|
{
|
|
if (nv == 0)
|
|
{
|
|
AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ;
|
|
ASSERT (elen == EMPTY) ;
|
|
if (pe == EMPTY)
|
|
{
|
|
AMD_DEBUG3 ((" dense node\n")) ;
|
|
ASSERT (w == 1) ;
|
|
}
|
|
else
|
|
{
|
|
ASSERT (pe < EMPTY) ;
|
|
AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i])));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i));
|
|
AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ;
|
|
ASSERT (elen >= 0) ;
|
|
ASSERT (nv > 0 && pe >= 0) ;
|
|
p = pe ;
|
|
AMD_DEBUG3 ((" e/s: ")) ;
|
|
if (elen == 0) AMD_DEBUG3 ((" : ")) ;
|
|
ASSERT (pe + len <= pfree) ;
|
|
for (k = 0 ; k < len ; k++)
|
|
{
|
|
j = Iw [p] ;
|
|
AMD_DEBUG3 ((" "ID"", j)) ;
|
|
ASSERT (j >= 0 && j < n) ;
|
|
if (k == elen-1) AMD_DEBUG3 ((" : ")) ;
|
|
p++ ;
|
|
}
|
|
AMD_DEBUG3 (("\n")) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
e = i ;
|
|
if (w == 0)
|
|
{
|
|
AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ;
|
|
ASSERT (nv > 0 && pe < 0) ;
|
|
AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ;
|
|
}
|
|
else
|
|
{
|
|
AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ;
|
|
ASSERT (nv > 0 && pe >= 0) ;
|
|
p = pe ;
|
|
AMD_DEBUG3 ((" : ")) ;
|
|
ASSERT (pe + len <= pfree) ;
|
|
for (k = 0 ; k < len ; k++)
|
|
{
|
|
j = Iw [p] ;
|
|
AMD_DEBUG3 ((" "ID"", j)) ;
|
|
ASSERT (j >= 0 && j < n) ;
|
|
p++ ;
|
|
}
|
|
AMD_DEBUG3 (("\n")) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* this routine cannot be called when the hash buckets are non-empty */
|
|
AMD_DEBUG3 (("\nDegree lists:\n")) ;
|
|
if (nel >= 0)
|
|
{
|
|
cnt = 0 ;
|
|
for (deg = 0 ; deg < n ; deg++)
|
|
{
|
|
if (Head [deg] == EMPTY) continue ;
|
|
ilast = EMPTY ;
|
|
AMD_DEBUG3 ((ID": \n", deg)) ;
|
|
for (i = Head [deg] ; i != EMPTY ; i = Next [i])
|
|
{
|
|
AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n",
|
|
i, Next [i], Last [i], Degree [i])) ;
|
|
ASSERT (i >= 0 && i < n && ilast == Last [i] &&
|
|
deg == Degree [i]) ;
|
|
cnt += Nv [i] ;
|
|
ilast = i ;
|
|
}
|
|
AMD_DEBUG3 (("\n")) ;
|
|
}
|
|
ASSERT (cnt == n - nel) ;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|