Exemple #1
0
/*
   ------------------------------------------------------------------
   create and return a height metric DV object
   input  : vmetricDV -- a metric defined on the vertices
   output : dmetricDV -- a depth metric defined on the vertices
 
   hmetric[v] = vmetric[v] + max{p(u) = v} hmetric[u] if fch[v] != -1
              = vmetric[v]                            if fch[v] == -1

   created -- 96jun23, cca
   ------------------------------------------------------------------
*/
DV *
Tree_setHeightDmetric (
   Tree   *tree,
   DV     *vmetricDV
) {
int      u, v, val ;
double   *hmetric, *vmetric ;
DV       *hmetricDV ;
/*
   ---------------
   check the input
   ---------------
*/
if (  tree == NULL || tree->n < 1 
   || vmetricDV == NULL 
   || tree->n != DV_size(vmetricDV)
   || (vmetric = DV_entries(vmetricDV)) == NULL ) {
   fprintf(stderr, "\n fatal error in Tree_setHeightDmetric(%p,%p)"
           "\n bad input\n", tree, vmetricDV) ;
   exit(-1) ;
}
hmetricDV = DV_new() ; 
DV_init(hmetricDV, tree->n, NULL) ; 
hmetric = DV_entries(hmetricDV) ;
for ( v = Tree_postOTfirst(tree) ; 
      v != -1 ; 
      v = Tree_postOTnext(tree, v) ) {
   for ( u = tree->fch[v], val = 0 ; u != -1 ; u = tree->sib[u] ) {
      if ( val < hmetric[u] ) {
         val = hmetric[u] ;
      }
   }
   hmetric[v] = val + vmetric[v] ;
}
return(hmetricDV) ; }
Exemple #2
0
/*
   ------------------------------------------------------
   create and return a subtree metric DV object
   input  : vmetricDV -- a metric defined on the vertices
   return : tmetricDV -- a metric defined on the subtrees
  
   created -- 96jun23, cca
   ------------------------------------------------------
*/
DV *
Tree_setSubtreeDmetric (
   Tree   *tree,
   DV     *vmetricDV
) {
int      u, v ;
double   *tmetric, *vmetric ;
DV    *tmetricDV ;
/*
   ---------------
   check the input
   ---------------
*/
if (  tree == NULL || tree->n <= 0 
   || vmetricDV == NULL 
   || tree->n != DV_size(vmetricDV) 
   || (vmetric = DV_entries(vmetricDV)) == NULL ) {
   fprintf(stderr, "\n fatal error in Tree_setSubtreeImetric(%p,%p)"
           "\n bad input\n", tree, vmetricDV) ;
   exit(-1) ;
}
tmetricDV = DV_new() ;
DV_init(tmetricDV, tree->n, NULL) ;
tmetric = DV_entries(tmetricDV) ;
for ( v = Tree_postOTfirst(tree) ; 
      v != -1 ; 
      v = Tree_postOTnext(tree, v) ) {
   tmetric[v] = vmetric[v] ;
   for ( u = tree->fch[v] ; u != -1 ; u = tree->sib[u] ) {
      tmetric[v] += tmetric[u] ;
   }
}
return(tmetricDV) ; }
Exemple #3
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the stack storage to solve for J
               in a forward solve

   created -- 97nov30, cca
   ---------------------------------------------------------------
*/
void
ETree_forwSolveProfile (
   ETree    *etree,
   double   dvec[]
) {
int    I, J, maxstack, nDJ, nfront, nUJ, stack ;
int    *bndwghts, *fch, *nodwghts, *sib ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_forwSolveProfile(%p,%p)"
           "\n bad input\n", etree, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
nfront     = ETree_nfront(etree) ;
fch        = ETree_fch(etree) ;
sib        = ETree_sib(etree) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
maxstack = stack = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
   stack += nDJ + nUJ ;
   dvec[J] = stack ;
   if ( maxstack < stack ) {
      maxstack = stack ;
   }
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, stack = %d",
           J, nDJ, nUJ, stack) ;
#endif
   for ( I = fch[J] ; I != -1 ; I = sib[I] ) {
      stack -= bndwghts[I] ;
   }
   stack -= nDJ ;
}
#if MYDEBUG >= 0
fprintf(stdout, 
        "\n    forward solve : final stack = %d, max stack = %d", 
        stack, maxstack) ;
#endif

return ; }
Exemple #4
0
/*
   ------------------------------------------------------------------
   create and return a height metric IV object
   input  : vmetricIV -- a metric defined on the vertices
   output : dmetricIV -- a depth metric defined on the vertices
 
   hmetric[v] = vmetric[v] + max{p(u) = v} hmetric[u] if fch[v] != -1
              = vmetric[v]                            if fch[v] == -1

   created -- 96jun23, cca
   ------------------------------------------------------------------
*/
IV *
Tree_setHeightImetric (
   Tree   *tree,
   IV     *vmetricIV
) {
int   u, v, val ;
int   *hmetric, *vmetric ;
IV    *hmetricIV ;
/*
   ---------------
   check the input
   ---------------
*/
if (  tree == NULL || tree->n < 1 
   || vmetricIV == NULL 
   || tree->n != IV_size(vmetricIV)
   || (vmetric = IV_entries(vmetricIV)) == NULL ) {
   fprintf(stderr, "\n fatal error in Tree_setHeightImetric(%p,%p)"
           "\n bad input\n", tree, vmetricIV) ;
   if ( tree != NULL ) {
      Tree_writeForHumanEye(tree, stderr) ;
   }
   if ( vmetricIV != NULL ) {
      IV_writeForHumanEye(vmetricIV, stderr) ;
   }
   exit(-1) ;
}
hmetricIV = IV_new() ; 
IV_init(hmetricIV, tree->n, NULL) ; 
hmetric = IV_entries(hmetricIV) ;
for ( v = Tree_postOTfirst(tree) ; 
      v != -1 ; 
      v = Tree_postOTnext(tree, v) ) {
   for ( u = tree->fch[v], val = 0 ; u != -1 ; u = tree->sib[u] ) {
      if ( val < hmetric[u] ) {
         val = hmetric[u] ;
      }
   }
   hmetric[v] = val + vmetric[v] ;
}
return(hmetricIV) ; }
Exemple #5
0
/*
   --------------------------------------------
   create and return an IV object that contains
   the map from vertices to fundamental chains.

   return value -- # of fundamental chains

   created -- 96jun23, cca
   -------------------------------------------
*/
IV *
Tree_fundChainMap (
   Tree   *tree
) {
int   nfc, u, v ;
int   *map ;
IV    *mapIV ;
/*
   ---------------
   check the input
   ---------------
*/
if ( tree == NULL || tree->n <= 0 ) {
   fprintf(stderr, "\n fatal error in Tree_fundChainMap(%p)"
           "\n bad input\n", tree) ;
   exit(-1) ;
}
mapIV = IV_new() ;
IV_init(mapIV, tree->n, NULL) ;
map = IV_entries(mapIV) ;
for ( v = Tree_postOTfirst(tree), nfc = 0 ;
      v != -1 ;
      v = Tree_postOTnext(tree, v) ) {
   if ( (u = tree->fch[v]) == -1 || tree->sib[u] != -1 ) {
/*
      --------------------
      v starts a new chain
      --------------------
*/
      map[v] = nfc++ ;
   } else {
/*
      -----------------------------------------------
      v belongs in the same chain as its only child u
      -----------------------------------------------
*/
      map[v] = map[u] ;
   }
}
return(mapIV) ; }
Exemple #6
0
/*
   ----------------------------------------------
   purpose -- map the off diagonal blocks to
      processes in a domain decomposition fashion

   created -- 98mar28, cca
   ----------------------------------------------
*/
void
SolveMap_ddMap (
   SolveMap   *solvemap,
   int        symmetryflag,
   IVL        *upperBlockIVL,
   IVL        *lowerBlockIVL,
   int        nproc,
   IV         *ownersIV,
   Tree       *tree,
   int        seed,
   int        msglvl,
   FILE       *msgFile
) {
char    *mark ;
Drand   drand ;
int     ii, I, J, K, loc, nadj, nblockLower, nblockUpper, 
        nfront, proc ;
int     *adj, *colids, *fch, *map, *owners, *rowids, *sib ;
/*
   ---------------
   check the input
   ---------------
*/
if ( solvemap == NULL || symmetryflag < 0 
   || upperBlockIVL == NULL || ownersIV == NULL ) {
   fprintf(stderr, 
           "\n fatal error in SolveMap_ddMap(%p,%d,%p,%p,%p,%d)"
           "\n bad input\n",
           solvemap, symmetryflag, upperBlockIVL, 
           lowerBlockIVL, ownersIV, seed) ;
   spoolesFatal();
}
nfront = IV_size(ownersIV) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, 
           "\n\n SolveMap_ddMap(): nfront = %d, nproc = %d",
           nfront, nproc) ;
   fflush(msgFile) ;
}
/*
   -----------------------------------------------------------
   count the number of upper blocks that do not include U(J,J)
   -----------------------------------------------------------
*/
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n upperBlockIVL = %p", upperBlockIVL) ;
   fflush(msgFile) ;
}
nblockUpper = 0 ;
for ( J = 0 ; J < nfront ; J++ ) {
   IVL_listAndSize(upperBlockIVL, J, &nadj, &adj) ;
   for ( ii = 0 ; ii < nadj ; ii++ ) {
      if ( adj[ii] > J ) {
         nblockUpper++ ;
      }
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n nblockUpper = %d", nblockUpper) ;
   fflush(msgFile) ;
}
/*
   -----------------------------------------------------------
   count the number of lower blocks that do not include L(J,J)
   -----------------------------------------------------------
*/
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n lowerBlockIVL = %p", lowerBlockIVL) ;
   fflush(msgFile) ;
}
nblockLower = 0 ;
if ( lowerBlockIVL != NULL ) {
   for ( J = 0 ; J < nfront ; J++ ) {
      IVL_listAndSize(lowerBlockIVL, J, &nadj, &adj) ;
      for ( ii = 0 ; ii < nadj ; ii++ ) {
         if ( adj[ii] > J ) {
            nblockLower++ ;
         }
      }
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n nblockLower = %d", nblockLower) ;
   fflush(msgFile) ;
}
/*
   ---------------------
   initialize the object
   ---------------------
*/
SolveMap_init(solvemap, symmetryflag, nfront, 
              nproc, nblockUpper, nblockLower) ;
owners = SolveMap_owners(solvemap) ;
/*
   ----------------------
   fill the owners vector
   ----------------------
*/
IVcopy(nfront, owners, IV_entries(ownersIV)) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n owners") ;
   IVfprintf(msgFile, nfront, owners) ;
   fflush(msgFile) ;
}
/*
   -----------------------------------------------------
   mark a node J in the tree as 'D' if it is in a domain
   (owners[J] = owners[I] for all I a descendent of J)
   and 'S' (for the schur complement) otherwise
   -----------------------------------------------------
*/
mark = CVinit(nfront, 'D') ;
fch  = tree->fch ;
sib  = tree->sib ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   for ( I = fch[J] ; I != -1 ; I = sib[I] ) {
      if ( mark[I] != 'D' || owners[I] != owners[J] ) {
         mark[J] = 'S' ; break ;
      }
   }
}
/*
   --------------------------------------
   initialize the random number generator
   --------------------------------------
*/
Drand_setDefaultFields(&drand) ;
Drand_setUniform(&drand, 0, nproc) ;
/*
   -------------------------------
   if J is in a domain
      map(J,K) to owners[J]
   else
      map(J,K) to a random process
   -------------------------------
*/
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n mapping upper blocks") ;
   fflush(msgFile) ;
}
rowids = SolveMap_rowidsUpper(solvemap) ;
colids = SolveMap_colidsUpper(solvemap) ;
map    = SolveMap_mapUpper(solvemap) ;
for ( J = loc = 0 ; J < nfront ; J++ ) {
   IVL_listAndSize(upperBlockIVL, J, &nadj, &adj) ;
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n J = %d", J) ;
      fflush(msgFile) ;
   }
   for ( ii = 0 ; ii < nadj ; ii++ ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n    K = %d", adj[ii]) ;
         fflush(msgFile) ;
      }
      if ( (K = adj[ii]) > J ) {
         if ( mark[J] == 'D' ) {
            proc = owners[J] ;
         } else {
            proc = (int) Drand_value(&drand) ;
         }
         rowids[loc] =   J  ;
         colids[loc] =   K  ;
         map[loc]    = proc ;
         if ( msglvl > 2 ) {
            fprintf(msgFile, ", map[%d] = %d", loc, map[loc]) ;
            fflush(msgFile) ;
         }
         loc++ ;
      }
   }
}
if ( symmetryflag == SPOOLES_NONSYMMETRIC ) {
/*
   -------------------------------
   if J is in a domain
      map(K,J) to owners[J]
   else
      map(K,J) to a random process
   -------------------------------
*/
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n mapping lower blocks") ;
      fflush(msgFile) ;
   }
   rowids = SolveMap_rowidsLower(solvemap) ;
   colids = SolveMap_colidsLower(solvemap) ;
   map    = SolveMap_mapLower(solvemap) ;
   for ( J = loc = 0 ; J < nfront ; J++ ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n J = %d", J) ;
         fflush(msgFile) ;
      }
      IVL_listAndSize(lowerBlockIVL, J, &nadj, &adj) ;
      for ( ii = 0 ; ii < nadj ; ii++ ) {
         if ( msglvl > 2 ) {
            fprintf(msgFile, "\n    K = %d", adj[ii]) ;
            fflush(msgFile) ;
         }
         if ( (K = adj[ii]) > J ) {
            if ( mark[J] == 'D' ) {
               proc = owners[J] ;
            } else {
               proc = (int) Drand_value(&drand) ;
            }
            rowids[loc] =   K  ;
            colids[loc] =   J  ;
            map[loc]    = proc ;
            if ( msglvl > 2 ) {
               fprintf(msgFile, ", map[%d] = %d", loc, map[loc]) ;
               fflush(msgFile) ;
            }
            loc++ ;
         }
      }
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
CVfree(mark) ;

return ; }
Exemple #7
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ------------------------------------------------------
   (1) read in an ETree object.
   (2) read in an Graph object.
   (3) find the optimal domain/schur complement partition
       for a semi-implicit factorization
   
   created -- 96oct03, cca
   ------------------------------------------------------
*/
{
char     *inETreeFileName, *inGraphFileName, *outIVfileName ;
double   alpha, nA21, nfent1, nfops1, nL11, nL22, nPhi, nV, t1, t2 ;
Graph    *graph ;
int      ii, inside, J, K, msglvl, nfind1, nfront, nJ, nleaves1, 
         nnode1, nvtx, rc, sizeJ, totalgain, vsize, v, w ;
int      *adjJ, *compids, *nodwghts, *vadj, *vtxToFront, *vwghts ;
IV       *compidsIV ;
IVL      *symbfacIVL ;
ETree    *etree ;
FILE     *msgFile ;
Tree     *tree ;

if ( argc != 7 ) {
   fprintf(stdout, 
"\n\n usage : %s msglvl msgFile inETreeFile inGraphFile alpha"
"\n         outIVfile "
"\n    msglvl       -- message level"
"\n    msgFile      -- message file"
"\n    inETreeFile  -- input file, must be *.etreef or *.etreeb"
"\n    inGraphFile  -- input file, must be *.graphf or *.graphb"
"\n    alpha        -- weight parameter"
"\n       alpha = 0 --> minimize storage"
"\n       alpha = 1 --> minimize solve ops"
"\n    outIVfile    -- output file for oldToNew vector,"
"\n                    must be *.ivf or *.ivb"
"\n", argv[0]) ;
   return(0) ;
}
msglvl = atoi(argv[1]) ;
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n fatal error in %s"
           "\n unable to open file %s\n",
           argv[0], argv[2]) ;
   return(-1) ;
}
inETreeFileName  = argv[3] ;
inGraphFileName  = argv[4] ;
alpha            = atof(argv[5]) ;
outIVfileName    = argv[6] ;
fprintf(msgFile, 
        "\n %s "
        "\n msglvl        -- %d" 
        "\n msgFile       -- %s" 
        "\n inETreeFile   -- %s" 
        "\n inGraphFile   -- %s" 
        "\n alpha         -- %f" 
        "\n outIVfile     -- %s" 
        "\n",
        argv[0], msglvl, argv[2], 
        inETreeFileName, inGraphFileName, alpha, outIVfileName) ;
fflush(msgFile) ;
/*
   ------------------------
   read in the ETree object
   ------------------------
*/
if ( strcmp(inETreeFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   spoolesFatal();
}
etree = ETree_new() ;
MARKTIME(t1) ;
rc = ETree_readFromFile(etree, inETreeFileName) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in etree from file %s",
        t2 - t1, inETreeFileName) ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from ETree_readFromFile(%p,%s)",
           rc, etree, inETreeFileName) ;
   spoolesFatal();
}
ETree_leftJustify(etree) ;
fprintf(msgFile, "\n\n after reading ETree object from file %s",
        inETreeFileName) ;
if ( msglvl > 2 ) {
   ETree_writeForHumanEye(etree, msgFile) ;
} else {
   ETree_writeStats(etree, msgFile) ;
}
fflush(msgFile) ;
nfront     = ETree_nfront(etree) ;
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
/*
   ------------------------
   read in the Graph object
   ------------------------
*/
if ( strcmp(inGraphFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   spoolesFatal();
}
graph = Graph_new() ;
MARKTIME(t1) ;
rc = Graph_readFromFile(graph, inGraphFileName) ;
nvtx = graph->nvtx ;
vwghts = graph->vwghts ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in graph from file %s",
        t2 - t1, inGraphFileName) ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from Graph_readFromFile(%p,%s)",
           rc, graph, inGraphFileName) ;
   spoolesFatal();
}
fprintf(msgFile, "\n\n after reading Graph object from file %s",
        inGraphFileName) ;
if ( msglvl > 2 ) {
   Graph_writeForHumanEye(graph, msgFile) ;
} else {
   Graph_writeStats(graph, msgFile) ;
}
fflush(msgFile) ;
/*
   ----------------------
   compute the statistics
   ----------------------
*/
nnode1 = etree->tree->n ;
nfind1 = ETree_nFactorIndices(etree) ;
nfent1 = ETree_nFactorEntries(etree, SPOOLES_SYMMETRIC) ;
nfops1 = ETree_nFactorOps(etree, SPOOLES_REAL, SPOOLES_SYMMETRIC) ;
nleaves1 = Tree_nleaves(etree->tree) ;
fprintf(stdout, "\n root front %d has %d vertices",
        etree->tree->root,
        etree->nodwghtsIV->vec[etree->tree->root]) ;
/*
   ---------------------------------
   create the symbolic factorization
   ---------------------------------
*/
symbfacIVL = SymbFac_initFromGraph(etree, graph) ;
if ( msglvl > 2 ) {
   IVL_writeForHumanEye(symbfacIVL, msgFile) ;
} else {
   IVL_writeStats(symbfacIVL, msgFile) ;
}
fflush(msgFile) ;
/*
   --------------------------
   find the optimal partition
   --------------------------
*/
compidsIV = ETree_optPart(etree, graph, symbfacIVL, alpha,
                          &totalgain, msglvl, msgFile) ;
if ( msglvl > 2 ) {
   IV_writeForHumanEye(compidsIV, msgFile) ;
} else {
   IV_writeStats(compidsIV, msgFile) ;
}
fflush(msgFile) ;
compids = IV_entries(compidsIV) ;
/*
   ------------------------------------------------------
   compute the number of vertices in the schur complement
   ------------------------------------------------------
*/
for ( J = 0, nPhi = nV = 0. ; J < nfront ; J++ ) {
   if ( compids[J] == 0 ) {
      nPhi += nodwghts[J] ;
   }
   nV += nodwghts[J] ;
}
/*
   --------------------------------------------
   compute the number of entries in L11 and L22
   --------------------------------------------
*/
nL11 = nL22 = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nJ = nodwghts[J] ;
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n\n front %d, nJ = %d", J, nJ) ;
   }
   IVL_listAndSize(symbfacIVL, J, &sizeJ, &adjJ) ;
   for ( ii = 0, inside = 0 ; ii < sizeJ ; ii++ ) {
      w = adjJ[ii] ;
      K = vtxToFront[w] ;
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    w = %d, K = %d", w, K) ;
      }
      if ( K > J && compids[K] == compids[J] ) {
         inside += (vwghts == NULL) ? 1 : vwghts[w] ;
         if ( msglvl > 3 ) {
            fprintf(msgFile, ", inside") ;
         }
      }
   }
   if ( compids[J] != 0 ) {
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    inside = %d, adding %d to L11",
                 inside, nJ*nJ + 2*nJ*inside) ;
      }
      nL11 += (nJ*(nJ+1))/2 + nJ*inside ;
   } else {
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    inside = %d, adding %d to L22",
                 inside, (nJ*(nJ+1))/2 + nJ*inside) ;
      }
      nL22 += (nJ*(nJ+1))/2 + nJ*inside ;
   }
}
if ( msglvl > 0 ) {
   fprintf(msgFile, "\n |L| = %.0f, |L11| = %.0f, |L22| = %.0f",
           nfent1, nL11, nL22) ;
}
/*
   ------------------------------------
   compute the number of entries in A21
   ------------------------------------
*/
nA21 = 0 ;
if ( vwghts != NULL ) {
   for ( v = 0 ; v < nvtx ; v++ ) {
      J = vtxToFront[v] ;
      if ( compids[J] != 0 ) {
         Graph_adjAndSize(graph, v, &vsize, &vadj) ;
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            K = vtxToFront[w] ;
            if ( compids[K] == 0 ) {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, "\n A21 : v = %d, w = %d", v, w) ;
               }
               nA21 += vwghts[v] * vwghts[w] ;
            }
         }
      }
   }
} else {
   for ( v = 0 ; v < nvtx ; v++ ) {
      J = vtxToFront[v] ;
      if ( compids[J] != 0 ) {
         Graph_adjAndSize(graph, v, &vsize, &vadj) ;
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            K = vtxToFront[w] ;
            if ( compids[K] == 0 ) {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, "\n A21 : v = %d, w = %d", v, w) ;
               }
               nA21++ ;
            }
         }
      }
   }
}
if ( msglvl > 0 ) {
   fprintf(msgFile,
           "\n |L| = %.0f, |L11| = %.0f, |L22| = %.0f, |A21| = %.0f",
           nfent1, nL11, nL22, nA21) ;
   fprintf(msgFile,
      "\n storage: explicit = %.0f, semi-implicit = %.0f, ratio = %.3f"
      "\n opcount: explicit = %.0f, semi-implicit = %.0f, ratio = %.3f",
      nfent1, nL11 + nA21 + nL22,
      nfent1/(nL11 + nA21 + nL22),
      2*nfent1, 4*nL11 + 2*nA21 + 2*nL22,
      2*nfent1/(4*nL11 + 2*nA21 + 2*nL22)) ;
   fprintf(msgFile, "\n ratios %8.3f %8.3f %8.3f",
           nPhi/nV,
           nfent1/(nL11 + nA21 + nL22),
           2*nfent1/(4*nL11 + 2*nA21 + 2*nL22)) ;
}
/*
   ----------------
   free the objects
   ----------------
*/
ETree_free(etree) ;
Graph_free(graph) ;
IVL_free(symbfacIVL) ;

fprintf(msgFile, "\n") ;
fclose(msgFile) ;

return(1) ; }
Exemple #8
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the right-looking general sparse method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 98dec19, cca
   ---------------------------------------------------------------
*/
void
ETree_FSstorageProfile (
   ETree    *etree,
   int      symflag,
   IVL      *symbfacIVL,
   double   dvec[]
) {
char   *incore ;
int    ii, J, K, nDJ, nfront, nUJ, sizeJ, storage ;
int    *bndwghts, *indJ, *mark, *nodwghts, *stor, *vtxToFront ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || symbfacIVL == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_FSstorageProfile(%p,%p,%p)"
           "\n bad input\n", etree, symbfacIVL, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nfront     = ETree_nfront(etree) ;
incore     = CVinit(nfront, 'F') ;
stor       = IVinit(nfront, 0) ;
mark       = IVinit(nfront, -1) ;
/*
   --------------------------------------------
   compute the storage for each front's chevron
   --------------------------------------------
*/
if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
   for ( J = 0 ; J < nfront ; J++ ) {
      nDJ = nodwghts[J] ;
      nUJ = bndwghts[J] ;
      stor[J] = (nDJ*(nDJ+1))/2 + nDJ*nUJ ;
   }
} else {
   for ( J = 0 ; J < nfront ; J++ ) {
      nDJ = nodwghts[J] ;
      nUJ = bndwghts[J] ;
      stor[J] = nDJ*nDJ + 2*nDJ*nUJ ;
   }
}
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
storage = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   if ( incore[J] == 'F' ) {
      storage += stor[J] ;
      incore[J] = 'T' ;
   }
   IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
   mark[J] = J ;
   for ( ii = 0 ; ii < sizeJ ; ii++ ) {
      K = vtxToFront[indJ[ii]] ;
      if ( mark[K] != J ) {
         mark[K] = J ;
         if ( incore[K] == 'F' ) {
            storage += stor[K] ;
            incore[K] = 'T' ;
         }
      }
   }
   dvec[J] = storage ;
   storage -= stor[J] ;
}
IVfree(mark) ;
IVfree(stor) ;
CVfree(incore) ;

return ; }
Exemple #9
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the multifrontal method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 97may21, cca
   ---------------------------------------------------------------
*/
void
ETree_MFstackProfile (
   ETree    *etree,
   int      symflag,
   double   dvec[]
) {
int    I, J, nDJ, nUI, nUJ, stack ;
int    *bndwghts, *fch, *nodwghts, *sib ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || dvec == NULL ) {
   fprintf(stderr, "\n fatal error in ETree_MFstackProfile(%p,%p)"
           "\n bad input\n", etree, dvec) ;
   exit(-1) ;
}
tree     = ETree_tree(etree) ;
nodwghts = ETree_nodwghts(etree) ;
bndwghts = ETree_bndwghts(etree) ;
fch      = ETree_fch(etree) ;
sib      = ETree_sib(etree) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
stack = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, stack = %d",
           J, nDJ, nUJ, stack) ;
#endif
   if ( (I = fch[J]) != -1 ) {
/*
      --------------------------------
      remove last child from the stack
      --------------------------------
*/
      while ( sib[I] != -1 ) {
         I = sib[I] ;
      }
      nUI = bndwghts[I] ;
      if ( symflag == SPOOLES_SYMMETRIC 
        || symflag == SPOOLES_HERMITIAN ) {
         stack -= (nUI*(nUI+1))/2 ;
      } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
         stack -= nUI*nUI ;
      }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    removing last child %d, stack = %d", I, stack) ;
#endif
   }
/*
   ---------------------------------
   add frontal matrix for J to stack
   and store as the storage for J
   ---------------------------------
*/
   dvec[J] = stack + (nDJ + nUJ)*(nDJ + nUJ) ;
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      dvec[J] = stack + ((nDJ + nUJ)*(nDJ + nUJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      dvec[J] = stack + (nDJ + nUJ)*(nDJ + nUJ) ;
   }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    working storage = %.0f", dvec[J]) ;
#endif
   if ( (I = fch[J]) != -1 ) {
/*
      ------------------------------------
      remove other children from the stack
      ------------------------------------
*/
      while ( sib[I] != -1 ) {
         nUI = bndwghts[I] ;
         if ( symflag == SPOOLES_SYMMETRIC 
           || symflag == SPOOLES_HERMITIAN ) {
            stack -= (nUI*(nUI+1))/2 ;
         } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
            stack -= nUI*nUI ;
         }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    removing child %d, stack = %d", I, stack) ;
#endif
         I = sib[I] ;
      }
   }
/*
   --------------------------------
   add update matrix for J to stack
   --------------------------------
*/
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      stack += (nUJ*(nUJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      stack += nUJ*nUJ ;
   }
#if MYDEBUG > 0
      fprintf(stdout, 
           "\n    adding update matrix, stack = %d", stack) ;
#endif
}
#if MYDEBUG >= 0
fprintf(stdout, "\n    MF: final stack = %d", stack) ;
#endif
return ; }
Exemple #10
0
/*
   ---------------------------------------------------------------
   purpose --  fill dvec[J] with the active storage to eliminate J
               using the left-looking general sparse method

   symflag -- symmetry flag, one of SPOOLES_SYMMETRIC,
              SPOOLES_HERMITIAN or SPOOLES_NONSYMMETRIC

   created -- 97may21, cca
   ---------------------------------------------------------------
*/
void
ETree_GSstorageProfile (
   ETree    *etree,
   int      symflag,
   IVL      *symbfacIVL,
   int      *vwghts,
   double   dvec[]
) {
int    count, ii, I, J, K, nDJ, nfront, nUJ, sizeI, sizeJ, storage, v ;
int    *bndwghts, *head, *indI, *indJ, 
       *link, *nodwghts, *offsets, *vtxToFront ;
Tree   *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL || symbfacIVL == NULL || dvec == NULL ) {
   fprintf(stderr, 
           "\n fatal error in ETree_GSstorageProfile(%p,%p,%p,%p)"
           "\n bad input\n", etree, symbfacIVL, vwghts, dvec) ;
   exit(-1) ;
}
tree       = ETree_tree(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
bndwghts   = ETree_bndwghts(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nfront     = ETree_nfront(etree) ;
head       = IVinit(nfront, -1) ;
link       = IVinit(nfront, -1) ;
offsets    = IVinit(nfront,  0) ;
/*
   ---------------------------------------------
   loop over the nodes in a post-order traversal
   ---------------------------------------------
*/
storage = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nDJ = nodwghts[J] ;
   nUJ = bndwghts[J] ;
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      storage += (nDJ*(nDJ + 1))/2 + nDJ*nUJ ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      storage += nDJ*nDJ + 2*nDJ*nUJ ;
   }
   dvec[J] = storage ;
#if MYDEBUG > 0
   fprintf(stdout, 
           "\n working on front %d, nD = %d, nU = %d, storage = %d",
           J, nDJ, nUJ, storage) ;
#endif
/*
   -----------------------------
   loop over the updating fronts
   -----------------------------
*/
   while ( (I = head[J]) != -1 ) {
      head[J] = link[I] ;
      IVL_listAndSize(symbfacIVL, I, &sizeI, &indI) ;
#if MYDEBUG > 0
      fprintf(stdout, 
              "\n    updating front %d, offset = %d, sizeI = %d", 
              I, offsets[I], sizeI) ;
      IVfprintf(stdout, sizeI, indI) ;
#endif
      for ( ii = offsets[I], count = 0, K = -1 ; ii < sizeI ; ii++ ) {
         v = indI[ii] ;
#if MYDEBUG > 0
         fprintf(stdout, "\n       ii = %d, v = %d, K = %d",
                 ii, v, vtxToFront[v]) ;
         fflush(stdout) ;
#endif
         K = vtxToFront[v] ;
         if ( K < 0 || K >= nfront ) {
            fprintf(stderr, "\n\n fatal error"
                    "\n ii = %d, v = %d, K = %d", ii, v, K) ;
            exit(-1) ;
         }
         if ( (K = vtxToFront[v]) != J ) {
#if MYDEBUG > 0
            fprintf(stdout, "\n       linking to next ancestor %d", K) ;
#endif
            link[I] = head[K] ;
            head[K] = I ;
            offsets[I] = ii ;
            break ;
         }
         count += (vwghts == NULL) ? 1 : vwghts[v] ;
#if MYDEBUG > 0
         fprintf(stdout, "\n       count = %d", count) ;
         fflush(stdout) ;
#endif
      }
      if ( symflag == SPOOLES_SYMMETRIC 
        || symflag == SPOOLES_HERMITIAN ) {
         storage -= count*nodwghts[I] ;
      } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
         storage -= 2*count*nodwghts[I] ;
      }
   }
   if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) {
      storage -= (nDJ*(nDJ+1))/2 ;
   } else if ( symflag == SPOOLES_NONSYMMETRIC ) {
      storage -= nDJ*nDJ ;
   }
   if ( nUJ > 0 ) {
      IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
      for ( ii = 0 ; ii < sizeJ ; ii++ ) {
         v = indJ[ii] ;
         if ( (K = vtxToFront[v]) != J ) {
            break ;
         }
      }
      offsets[J] = ii ;
#if MYDEBUG > 0
      fprintf(stdout, "\n    linking to next ancestor %d", K) ;
#endif
      IVL_listAndSize(symbfacIVL, J, &sizeJ, &indJ) ;
      link[J] = head[K] ;
      head[K] = J ;
   }
#if MYDEBUG > 0
   fprintf(stdout, "\n    at end of step %d, storage = %d", 
           J, storage) ;
#endif
}
#if MYDEBUG >= 0
fprintf(stdout, "\n    GS: final storage = %d", storage) ;
#endif
IVfree(head) ;
IVfree(link) ;
IVfree(offsets) ;

return ; }
Exemple #11
0
/*
   -------------------------------------------------
   expand an ETree object by splitting a large front 
   into a chain of smaller fronts.

   created -- 96jun27, cca
   -------------------------------------------------
*/
ETree *
ETree_splitFronts (
   ETree   *etree,
   int     vwghts[],
   int     maxfrontsize,
   int     seed
) {
ETree   *etree2 ;
int     count, front, ii, I, Inew, J, Jnew, nbnd, newsize, nint, nfront,
        nfront2, nsplit, nvtx, prev, size, sizeJ, v, vwght ;
int     *bndwghts, *fch, *head, *indices, *link, *newbndwghts, *newmap, 
        *newnodwghts, *newpar, *nodwghts, *roots, *sib, *vtxToFront ;
Tree    *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if ( etree == NULL
   || (nfront = etree->nfront) <= 0
   || (nvtx = etree->nvtx) <= 0
   || maxfrontsize <= 0 ) {
   fprintf(stderr, "\n fatal error in ETree_splitFronts(%p,%p,%d,%d)"
           "\n bad input\n", etree, vwghts, maxfrontsize, seed) ;
   spoolesFatal();
}
tree       = etree->tree ;
fch        = tree->fch ;
sib        = tree->sib ;
nodwghts   = IV_entries(etree->nodwghtsIV) ;
bndwghts   = IV_entries(etree->bndwghtsIV) ;
vtxToFront = IV_entries(etree->vtxToFrontIV) ;
/*
   --------------------------
   set up the working storage
   --------------------------
*/
newpar      = IVinit(nvtx,   -1) ;
roots       = IVinit(nfront, -1) ;
newmap      = IVinit(nvtx,   -1) ;
newnodwghts = IVinit(nvtx,   -1) ;
newbndwghts = IVinit(nvtx,   -1) ;
head        = IVinit(nfront, -1) ;
link        = IVinit(nvtx,   -1) ;
indices     = IVinit(nvtx,   -1) ;
for ( v = 0 ; v < nvtx ; v++ ) {
   front = vtxToFront[v] ;
   link[v] = head[front] ;
   head[front] = v ;
}
/*
   ------------------------------------------------
   execute a post-order traversal of the front tree
   ------------------------------------------------
*/
nfront2 = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   sizeJ = 0 ;
   for ( v = head[J], count = 0 ; v != -1 ; v = link[v] ) {
      indices[count++] = v ;
      vwght = (vwghts != NULL) ? vwghts[v] : 1 ;
      sizeJ += vwght ;
   }
   if ( sizeJ != nodwghts[J] ) {
      fprintf(stderr, "\n fatal error in ETree_splitFronts(%p,%p,%d,%d)"
             "\n J = %d, sizeJ = %d, nodwght = %d\n", 
             etree, vwghts, maxfrontsize, seed, J, sizeJ, nodwghts[J]) ;
      spoolesFatal();
   }
#if MYDEBUG > 0
   fprintf(stdout, "\n\n checking out front %d, size %d", J, sizeJ) ;
#endif
   if ( sizeJ <= maxfrontsize || fch[J] == -1 ) {
/*
      -------------------------------------------
      this front is small enough (or is a domain)
      -------------------------------------------
*/
      Jnew = nfront2++ ;
      for ( ii = 0 ; ii < count ; ii++ ) {
         v = indices[ii] ;
         newmap[v] = Jnew ;
#if MYDEBUG > 1
            fprintf(stdout, "\n   mapping vertex %d into new front %d",
                    v, Jnew) ;
#endif
      }
      for ( I = fch[J] ; I != -1 ; I = sib[I] ) {
         Inew = roots[I] ;
         newpar[Inew] = Jnew ;
      }
      newnodwghts[Jnew] = nodwghts[J] ;
      newbndwghts[Jnew] = bndwghts[J] ;
      roots[J] = Jnew ;
#if MYDEBUG > 0
      fprintf(stdout, "\n    front is small enough, Jnew = %d", Jnew) ;
#endif
   } else {
/*
      ------------------------------------------
      this front is too large, split into pieces 
      whose size differs by one vertex
      ------------------------------------------
*/
      nsplit  = (sizeJ + maxfrontsize - 1)/maxfrontsize ;
      newsize = sizeJ / nsplit ;
      if ( sizeJ % nsplit != 0 ) {
         newsize++ ;
      }
#if MYDEBUG > 0
      fprintf(stdout, 
         "\n    front is too large, %d target fronts, target size = %d",
         nsplit, newsize) ;
#endif
      prev    = -1 ;
      nint    = nodwghts[J] ;
      nbnd    = nint + bndwghts[J] ;
      if ( seed > 0 ) {
         IVshuffle(count, indices, seed) ;
      }
      ii = 0 ;
      while ( ii < count ) {
         Jnew = nfront2++ ;
         size = 0 ;
         while ( ii < count ) {
            v = indices[ii] ;
            vwght = (vwghts != NULL) ? vwghts[v] : 1 ;
#if MYDEBUG > 0
            fprintf(stdout, 
                "\n   ii = %d, v = %d, vwght = %d, size = %d",
                ii, v, vwght, size) ;
#endif
/*
   -----------------------------------------------
   97aug28, cca
   bug fix. front is created even if it is too big
   -----------------------------------------------
*/
            if ( newsize >= size + vwght || size == 0 ) {
               newmap[v] = Jnew ;
               size += vwght ;
#if MYDEBUG > 0
               fprintf(stdout, 
                "\n   mapping vertex %d into new front %d, size = %d",
                v, Jnew, size) ;
#endif
               ii++ ;
            } else {
               break ;
            }
         }
         if ( prev == -1 ) {
            for ( I = fch[J] ; I != -1 ; I = sib[I] ) {
               Inew = roots[I] ;
               newpar[Inew] = Jnew ;
            }
         } else {
            newpar[prev] = Jnew ;
         }
         prev = Jnew ;
         newnodwghts[Jnew] = size ;
         nbnd = nbnd - size ;
         newbndwghts[Jnew] = nbnd ;
#if MYDEBUG > 0
         fprintf(stdout, "\n    new front %d, size %d, bnd %d",
                 Jnew, newnodwghts[Jnew], newbndwghts[Jnew]) ;
#endif
      }
      roots[J] = Jnew ;
   }
}
/*
   ---------------------------
   create the new ETree object
   ---------------------------
*/
etree2 = ETree_new() ;
ETree_init1(etree2, nfront2, nvtx) ;
IVcopy(nfront2, etree2->tree->par, newpar) ;
Tree_setFchSibRoot(etree2->tree) ;
IVcopy(nvtx, IV_entries(etree2->vtxToFrontIV), newmap) ;
IVcopy(nfront2, IV_entries(etree2->nodwghtsIV), newnodwghts) ;
IVcopy(nfront2, IV_entries(etree2->bndwghtsIV), newbndwghts) ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(newpar) ;
IVfree(roots)  ;
IVfree(newmap) ;
IVfree(newnodwghts) ;
IVfree(newbndwghts) ;
IVfree(head) ;
IVfree(link) ;
IVfree(indices) ;

return(etree2) ; }
Exemple #12
0
/*
   --------------------------------------------------------------------
   purpose -- merge the front tree allowing at most
              maxzeros zero entries inside a front

   return -- 
      IV object that has the old front to new front map

   created -- 96jun23, cca
   modified -- 97dec18, cca
      bug fixed that incorrectly counted the number of zeros in a front
   --------------------------------------------------------------------
*/
ETree *
ETree_mergeFrontsAny (
   ETree   *etree,
   int     maxzeros,
   IV      *nzerosIV
) {
ETree   *etree2 ;
int     J, K, nfront, nvtx, nnew ;
int     *bndwghts, *cost, *fch, *map, *nodwghts, 
        *nzeros, *par, *place, *rep, *sib, *temp ;
IV      *mapIV ;
Tree    *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if (  etree == NULL 
   || (nfront = etree->nfront) <= 0
   || (nvtx = etree->nvtx) <= 0 ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAny(%p,%d)"
           "\n bad input\n", etree, maxzeros) ;
   spoolesFatal();
}
if ( IV_size(nzerosIV) != nfront ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAny(%p,%d,%p)"
           "\n size(nzerosIV) = %d, nfront = %d\n", 
           etree, maxzeros, nzerosIV, IV_size(nzerosIV), nfront) ;
   spoolesFatal();
}
nzeros = IV_entries(nzerosIV) ;
tree     = etree->tree ;
nodwghts = IVinit(nfront, 0) ;
bndwghts = IVinit(nfront, 0) ;
par = IVinit(nfront, -1) ;
fch = IVinit(nfront, -1) ;
sib = IVinit(nfront, -1) ;
IVcopy(nfront, par, tree->par) ;
IVcopy(nfront, fch, tree->fch) ;
IVcopy(nfront, sib, tree->sib) ;
IVcopy(nfront, nodwghts, IV_entries(etree->nodwghtsIV)) ;
IVcopy(nfront, bndwghts, IV_entries(etree->bndwghtsIV)) ;
/*
   ----------------------
   set up working storage
   ----------------------
*/
rep = IVinit(nfront, -1) ;
IVramp(nfront, rep, 0, 1) ;
cost   = IVinit(nfront, 0) ;
/*
   ------------------------------------------
   perform a post-order traversal of the tree
   ------------------------------------------
*/
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n\n ##### visiting front %d", J) ;
   fflush(stdout) ;
#endif
   visitAny(J, par, fch, sib, nodwghts, bndwghts, 
            rep, cost, nzeros, maxzeros) ;
}
#if MYDEBUG > 0
   fprintf(stdout, "\n\n whoa, finished") ;
   fflush(stdout) ;
#endif
/*
   -------------------------------------------------
   take the map from fronts to representative fronts
   and make the map from old fronts to new fronts
   -------------------------------------------------
*/
mapIV = IV_new() ;
IV_init(mapIV, nfront, NULL) ;
map   = IV_entries(mapIV) ;
place = IVinit(nfront, -1) ;
for ( J = 0, nnew = 0 ; J < nfront ; J++ ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n rep[%d] = %d", J, rep[J]) ;
   fflush(stdout) ;
#endif
   if ( rep[J] != J ) {
      K = J ;
      while ( rep[K] != K ) {
#if MYDEBUG > 0
      fprintf(stdout, "\n    rep[%d] = %d", K, rep[K]) ;
      fflush(stdout) ;
#endif
         K = rep[K] ;
      }
      rep[J] = K ;
#if MYDEBUG > 0
      fprintf(stdout, "\n    setting rep[%d] = %d", J, rep[J]) ;
      fflush(stdout) ;
#endif
   } else {
      place[J] = nnew++ ;
   }
}
for ( J = 0 ; J < nfront ; J++ ) {
   K = rep[J] ;
   map[J] = place[K] ;
}
/*
   -------------------------------
   get the compressed ETree object
   -------------------------------
*/
etree2 = ETree_compress(etree, mapIV) ;
/*
   -------------------------
   remap the nzeros[] vector
   -------------------------
*/
temp = IVinit(nfront, 0) ;
IVcopy(nfront, temp, nzeros) ;
IV_setSize(nzerosIV, nnew) ;
nzeros = IV_entries(nzerosIV) ;
for ( J = 0 ; J < nfront ; J++ ) {
   if ( rep[J] == J ) {
      nzeros[map[J]] = temp[J] ;
   }
}
IVfree(temp) ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(par)      ;
IVfree(fch)      ;
IVfree(sib)      ;
IVfree(nodwghts) ;
IVfree(bndwghts) ;
IVfree(rep)      ;
IVfree(cost)     ;
IVfree(place)    ;
IV_free(mapIV)   ;

return(etree2) ; }
Exemple #13
0
/*
   -------------------------------------------------------
   purpose -- merge the front tree allowing a parent 
              to absorb all children when that creates 
              at most maxzeros zero entries inside a front

   return -- 
      IV object that has the old front to new front map

   created -- 98jan29, cca
   -------------------------------------------------------
*/
ETree *
ETree_mergeFrontsAll (
   ETree   *etree,
   int     maxzeros,
   IV      *nzerosIV
) {
ETree   *etree2 ;
int     cost, J, Jall, K, KandBnd, nfront, nvtx, nnew ;
int     *bndwghts, *fch, *map, *nodwghts, *nzeros, *rep, *sib, *temp ;
IV      *mapIV ;
Tree    *tree ;
/*
   ---------------
   check the input
   ---------------
*/
if (  etree == NULL || nzerosIV == NULL
   || (nfront = etree->nfront) <= 0
   || (nvtx = etree->nvtx) <= 0 ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAll(%p,%d,%p)"
           "\n bad input\n", etree, maxzeros, nzerosIV) ;
   if ( etree != NULL ) {
      fprintf(stderr, "\n nfront = %d, nvtx = %d",
              etree->nfront, etree->nvtx) ;
   }
   spoolesFatal();
}
if ( IV_size(nzerosIV) != nfront ) {
   fprintf(stderr, "\n fatal error in ETree_mergeFrontsAll(%p,%d,%p)"
           "\n size(nzerosIV) = %d, nfront = %d\n", 
           etree, maxzeros, nzerosIV, IV_size(nzerosIV), nfront) ;
   spoolesFatal();
}
nzeros = IV_entries(nzerosIV) ;
/*
   ----------------------
   set up working storage
   ----------------------
*/
tree     = etree->tree ;
fch      = ETree_fch(etree) ;
sib      = ETree_sib(etree) ;
nodwghts = IVinit(nfront, 0) ;
IVcopy(nfront, nodwghts, ETree_nodwghts(etree)) ;
bndwghts = ETree_bndwghts(etree) ;
rep = IVinit(nfront, -1) ;
IVramp(nfront, rep, 0, 1) ;
/*
   ------------------------------------------
   perform a post-order traversal of the tree
   ------------------------------------------
*/
for ( K = Tree_postOTfirst(tree) ;
      K != -1 ;
      K = Tree_postOTnext(tree, K) ) {
#if MYDEBUG > 0
   fprintf(stdout, "\n\n ##### visiting front %d", K) ;
   fflush(stdout) ;
#endif
   if ( (J = fch[K]) != -1 ) {
      KandBnd = nodwghts[K] + bndwghts[K] ;
      Jall = 0 ;
      cost = 2*nzeros[K] ;
      for ( J = fch[K] ; J != -1 ; J = sib[J] ) {
         Jall += nodwghts[J] ;
         cost -= nodwghts[J]*nodwghts[J] ;
         cost += 2*nodwghts[J]*(KandBnd - bndwghts[J]) ;
         cost += 2*nzeros[J] ;
      }
      cost += Jall*Jall ;
      cost = cost/2 ;
#if MYDEBUG > 0
      fprintf(stdout, "\n cost = %d", cost) ;
      fflush(stdout) ;
#endif
      if ( cost <= maxzeros ) {
         for ( J = fch[K] ; J != -1 ; J = sib[J] ) {
#if MYDEBUG > 0
            fprintf(stdout, "\n merging %d into %d", J, K) ;
            fflush(stdout) ;
#endif
            rep[J] = K ;
            nodwghts[K] += nodwghts[J] ;
         }
         nzeros[K] = cost ;
      }
   }
}
#if MYDEBUG > 0
   fprintf(stdout, "\n\n whoa, finished") ;
   fflush(stdout) ;
#endif
/*
   -------------------------------------------------
   take the map from fronts to representative fronts
   and make the map from old fronts to new fronts
   -------------------------------------------------
*/
mapIV = IV_new() ;
IV_init(mapIV, nfront, NULL) ;
map   = IV_entries(mapIV) ;
for ( J = 0, nnew = 0 ; J < nfront ; J++ ) {
   if ( rep[J] == J ) {
      map[J] = nnew++ ;
   } else {
      K = J ;
      while ( rep[K] != K ) {
         K = rep[K] ;
      }
      rep[J] = K ;
   }
}
for ( J = 0 ; J < nfront ; J++ ) {
   if ( (K = rep[J]) != J ) {
      map[J] = map[K] ;
   }
}
/*
   -------------------------------
   get the compressed ETree object
   -------------------------------
*/
etree2 = ETree_compress(etree, mapIV) ;
/*
   -------------------------
   remap the nzeros[] vector
   -------------------------
*/
temp = IVinit(nfront, 0) ;
IVcopy(nfront, temp, nzeros) ;
IV_setSize(nzerosIV, nnew) ;
nzeros = IV_entries(nzerosIV) ;
for ( J = 0 ; J < nfront ; J++ ) {
   if ( rep[J] == J ) {
      nzeros[map[J]] = temp[J] ;
   }
}
IVfree(temp) ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(nodwghts) ;
IVfree(rep)      ;
IV_free(mapIV)   ;

return(etree2) ; }
Exemple #14
0
/*
   ------------------------------------------------
   purpose -- to get simple x[] and y[] coordinates 
              for the tree vertices

   return values --
      1 -- normal return
     -1 -- tree is NULL
     -2 -- heightflag is invalid
     -3 -- coordflag is invalid
     -4 -- xDV is NULL
     -5 -- yDV is NULL

   created -- 99jan07, cca
   ------------------------------------------------
*/
int
Tree_getSimpleCoords (
   Tree   *tree,
   char   heightflag,
   char   coordflag,
   DV     *xDV,
   DV     *yDV
) {
double   *x, *y ;
int      count, I, J, n, nleaves ;
int      *fch, *par, *sib ;
/*
   ---------------
   check the input
   ---------------
*/
if ( tree == NULL ) {
   fprintf(stderr, "\n error in Tree_getSimpleCoords()"
           "\n tree is NULL\n") ;
   return(-1) ;
}
if ( heightflag != 'D' && heightflag != 'H' ) {
   fprintf(stderr, "\n error in Tree_getSimpleCoords()"
           "\n invalid heightflag = %c\n", heightflag) ;
   return(-2) ;
}
if ( coordflag != 'C' && coordflag != 'P' ) {
   fprintf(stderr, "\n error in Tree_getSimpleCoords()"
           "\n invalid coordflag = %c\n", coordflag) ;
   return(-3) ;
}
if ( xDV == NULL ) {
   fprintf(stderr, "\n error in Tree_getSimpleCoords()"
           "\n xDV is NULL\n") ;
   return(-4) ;
}
if ( yDV == NULL ) {
   fprintf(stderr, "\n error in Tree_getSimpleCoords()"
           "\n yDV is NULL\n") ;
   return(-5) ;
}
n   = tree->n   ;
par = tree->par ;
fch = tree->fch ;
sib = tree->sib ;
DV_setSize(xDV, n) ;
DV_setSize(yDV, n) ;
x = DV_entries(xDV) ;
y = DV_entries(yDV) ;
switch ( heightflag ) {
case 'D' : {
   int   J, K, maxdepth ;

   for ( J = Tree_preOTfirst(tree), maxdepth = 0 ;
         J != -1 ;
         J = Tree_preOTnext(tree, J) ) {
      if ( (K = par[J]) == -1 ) {
         y[J] = 0.0 ;
      } else {
         y[J] = y[K] + 1.0 ;
      }
      if ( maxdepth < y[J] ) {
         maxdepth = y[J] ;
      }
   }
   if ( coordflag == 'C' ) {
      for ( J = 0 ; J < n ; J++ ) {
         y[J] = maxdepth - y[J] ;
      }
   }
   } break ;
case 'H' : {
   int   height, I, J, maxheight ;

   for ( J = Tree_postOTfirst(tree), maxheight = 0 ;
         J != -1 ;
         J = Tree_postOTnext(tree, J) ) {
      if ( (I = fch[J]) == -1 ) {
         y[J] = 0.0 ;
      } else {
         height = y[I] ;
         for ( I = sib[I] ; I != -1 ; I = sib[I] ) {
            if ( height < y[I] ) {
               height = y[I] ;
            }
         }
         y[J] = height + 1.0 ;
      }
      if ( maxheight < y[J] ) {
         maxheight = y[J] ;
      }
   }
   if ( coordflag == 'P' ) {
      for ( J = 0 ; J < n ; J++ ) {
         y[J] = maxheight - y[J] ;
      }
   }
   } break ;
default :
   break ;
}
#if MYDEBUG > 0
   fprintf(stdout, "\n\n y") ;
   DV_writeForHumanEye(yDV, stdout) ;
#endif
DV_zero(xDV) ;
nleaves = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   if ( fch[J] == -1 ) {
      x[J] = nleaves++ ;
   } else {
      for ( I = fch[J], count = 0 ; I != -1 ; I = sib[I] ) {
         x[J] += x[I] ;
         count++ ;
      }
      x[J] /= count ;
   }
}
if ( coordflag == 'C' ) {
   for ( J = 0 ; J < n ; J++ ) {
      x[J] = x[J] / nleaves ;
   }
} else {
   double   r, theta ;

   for ( J = 0 ; J < n ; J++ ) {
      theta = 6.283185 * x[J] / nleaves ;
      r     = y[J] ;
      x[J]  = r * cos(theta) ;
      y[J]  = r * sin(theta) ;
   }
}
#if MYDEBUG > 0
   fprintf(stdout, "\n\n x") ;
   DV_writeForHumanEye(xDV, stdout) ;
#endif
return(1) ; }
Exemple #15
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ----------------------------------------
   get statistics for a semi-implicit solve

   created -- 97dec11, cca
   ----------------------------------------
*/
{
char     *inGraphFileName, *inETreeFileName, *inMapFileName ;
double   nA21, nL, nL11, nL22, nPhi, nV, t1, t2 ;
ETree    *etree ;
int      ii, inside, J, K, msglvl, nfront, nJ, 
         nvtx, rc, sizeJ, v, vsize, w ;
int      *adjJ, *frontmap, *map, *nodwghts, 
         *vadj, *vtxToFront, *vwghts ;
IV       *mapIV ;
IVL      *symbfacIVL ;
Graph    *graph ;
FILE     *msgFile ;
Tree     *tree ;

if ( argc != 6 ) {
   fprintf(stdout, 
     "\n\n usage : %s msglvl msgFile GraphFile ETreeFile mapFile "
     "\n    msglvl    -- message level"
     "\n    msgFile   -- message file"
     "\n    GraphFile -- input graph file, must be *.graphf or *.graphb"
     "\n    ETreeFile -- input ETree file, must be *.etreef or *.etreeb"
     "\n    mapFile   -- input map IV file, must be *.ivf or *.ivb"
     "\n",
argv[0]) ;
   return(0) ;
}
msglvl = atoi(argv[1]) ;
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else if ( (msgFile = fopen(argv[2], "a")) == NULL ) {
   fprintf(stderr, "\n fatal error in %s"
           "\n unable to open file %s\n",
           argv[0], argv[2]) ;
   return(-1) ;
}
inGraphFileName = argv[3] ;
inETreeFileName = argv[4] ;
inMapFileName   = argv[5] ;
fprintf(msgFile, 
        "\n %s "
        "\n msglvl        -- %d" 
        "\n msgFile       -- %s" 
        "\n GraphFile     -- %s" 
        "\n ETreeFile     -- %s" 
        "\n mapFile       -- %s" 
        "\n",
        argv[0], msglvl, argv[2], 
        inGraphFileName, inETreeFileName, inMapFileName) ;
fflush(msgFile) ;
/*
   ------------------------
   read in the Graph object
   ------------------------
*/
graph = Graph_new() ;
if ( strcmp(inGraphFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   exit(0) ;
}
MARKTIME(t1) ;
rc = Graph_readFromFile(graph, inGraphFileName) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in graph from file %s",
        t2 - t1, inGraphFileName) ;
nvtx   = graph->nvtx ;
vwghts = graph->vwghts ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from Graph_readFromFile(%p,%s)",
           rc, graph, inGraphFileName) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n after reading Graph object from file %s",
           inGraphFileName) ;
   Graph_writeForHumanEye(graph, msgFile) ;
   fflush(msgFile) ;
}
/*
   ------------------------
   read in the ETree object
   ------------------------
*/
etree = ETree_new() ;
if ( strcmp(inETreeFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   exit(0) ;
}
MARKTIME(t1) ;
rc = ETree_readFromFile(etree, inETreeFileName) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in etree from file %s",
        t2 - t1, inETreeFileName) ;
nfront     = ETree_nfront(etree) ;
tree       = ETree_tree(etree) ;
vtxToFront = ETree_vtxToFront(etree) ;
nodwghts   = ETree_nodwghts(etree) ;
nL         = ETree_nFactorEntries(etree, 2) ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from ETree_readFromFile(%p,%s)",
           rc, etree, inETreeFileName) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n after reading ETree object from file %s",
           inETreeFileName) ;
   ETree_writeForHumanEye(etree, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------
   read in the map IV object
   -------------------------
*/
mapIV = IV_new() ;
if ( strcmp(inMapFileName, "none") == 0 ) {
   fprintf(msgFile, "\n no file to read from") ;
   exit(0) ;
}
MARKTIME(t1) ;
rc = IV_readFromFile(mapIV, inMapFileName) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %9.5f : read in mapIV from file %s",
        t2 - t1, inMapFileName) ;
map = IV_entries(mapIV) ;
if ( rc != 1 ) {
   fprintf(msgFile, "\n return value %d from IV_readFromFile(%p,%s)",
           rc, mapIV, inMapFileName) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n after reading IV object from file %s",
           inMapFileName) ;
   IV_writeForHumanEye(mapIV, msgFile) ;
   fflush(msgFile) ;
}
nV = nPhi = 0 ;
if ( vwghts == NULL ) {
   for ( v = 0 ; v < nvtx ; v++ ) {
      nV++ ;
      if ( map[v] == 0 ) {
         nPhi++ ;
      }
   }
} else {
   for ( v = 0 ; v < nvtx ; v++ ) {
      nV += vwghts[v] ;
      if ( map[v] == 0 ) {
         nPhi += vwghts[v] ;
      }
   }
}
fprintf(msgFile, "\n nPhi = %.0f, nV = %.0f", nPhi, nV) ;
/*
   -------------------------
   get the frontmap[] vector
   -------------------------
*/
frontmap = IVinit(nfront, -1) ;
for ( v = 0 ; v < nvtx ; v++ ) {
   J = vtxToFront[v] ;
   if ( frontmap[J] == -1 ) {
      frontmap[J] = map[v] ;
   } else if ( frontmap[J] != map[v] ) {
      fprintf(msgFile, "\n\n error, frontmap[%d] = %d, map[%d] = %d",
              J, frontmap[J], v, map[v]) ;
   }
}
/*
   ----------------------------------
   compute the symbolic factorization
   ----------------------------------
*/
symbfacIVL = SymbFac_initFromGraph(etree, graph) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n symbolic factorization") ;
   IVL_writeForHumanEye(symbfacIVL, msgFile) ;
   fflush(msgFile) ;
}
/*
   --------------------------------------------
   compute the number of entries in L11 and L22
   --------------------------------------------
*/
nL11 = nL22 = 0 ;
for ( J = Tree_postOTfirst(tree) ;
      J != -1 ;
      J = Tree_postOTnext(tree, J) ) {
   nJ = nodwghts[J] ;
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n\n front %d, nJ = %d", J, nJ) ;
   }
   IVL_listAndSize(symbfacIVL, J, &sizeJ, &adjJ) ;
   for ( ii = 0, inside = 0 ; ii < sizeJ ; ii++ ) {
      w = adjJ[ii] ;
      K = vtxToFront[w] ;
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    w = %d, K = %d", w, K) ;
      }
      if ( K > J && frontmap[K] == frontmap[J] ) {
         inside += (vwghts == NULL) ? 1 : vwghts[w] ;
         if ( msglvl > 3 ) {
            fprintf(msgFile, ", inside") ;
         }
      }
   }
   if ( frontmap[J] != 0 ) {
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    inside = %d, adding %d to L11",
                 inside, nJ*nJ + 2*nJ*inside) ;
      }
      nL11 += nJ*nJ + 2*nJ*inside ;
   } else {
      if ( msglvl > 3 ) {
         fprintf(msgFile, "\n    inside = %d, adding %d to L22",
                 inside, nJ*nJ + 2*nJ*inside) ;
      }
      nL22 += nJ*nJ + 2*nJ*inside ;
   }
}
if ( msglvl > 0 ) {
   fprintf(msgFile, "\n |L| = %.0f, |L11| = %.0f, |L22| = %.0f", 
           nL, nL11, nL22) ;
}
/*
   ------------------------------------
   compute the number of entries in A21
   ------------------------------------
*/
nA21 = 0 ;
if ( vwghts != NULL ) {
   for ( v = 0 ; v < nvtx ; v++ ) {
      if ( map[v] == 0 ) {
         Graph_adjAndSize(graph, v, &vsize, &vadj) ;
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            if ( map[v] != map[w] ) {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, "\n A21 : v = %d, w = %d", v, w) ;
               }
               nA21 += vwghts[v] * vwghts[w] ;
            }
         }
      }
   }
} else {
   for ( v = 0 ; v < nvtx ; v++ ) {
      if ( map[v] == 0 ) {
         Graph_adjAndSize(graph, v, &vsize, &vadj) ;
         for ( ii = 0 ; ii < vsize ; ii++ ) {
            w = vadj[ii] ;
            if ( map[v] != map[w] ) {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, "\n A21 : v = %d, w = %d", v, w) ;
               }
               nA21++ ;
            }
         }
      }
   }
}
if ( msglvl > 0 ) {
   fprintf(msgFile, 
           "\n |L| = %.0f, |L11| = %.0f, |L22| = %.0f, |A21| = %.0f", 
           nL, nL11, nL22, nA21) ;
   fprintf(msgFile, 
      "\n storage: explicit = %.0f, semi-implicit = %.0f, ratio = %.3f"
      "\n opcount: explicit = %.0f, semi-implicit = %.0f, ratio = %.3f",
      nL, nL11 + nA21 + nL22, 
      nL/(nL11 + nA21 + nL22),
      2*nL, 4*nL11 + 2*nA21 + 2*nL22,
      2*nL/(4*nL11 + 2*nA21 + 2*nL22)) ;
   fprintf(msgFile, "\n ratios %8.3f %8.3f %8.3f",
           nPhi/nV,
           nL/(nL11 + nA21 + nL22),
           2*nL/(4*nL11 + 2*nA21 + 2*nL22)) ;
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
Graph_free(graph) ;
ETree_free(etree) ;
IV_free(mapIV) ;
IVL_free(symbfacIVL) ;
IVfree(frontmap) ;

fprintf(msgFile, "\n") ;
fclose(msgFile) ;

return(1) ; }