示例#1
0
/*
   -------------------------------------------
   fill *pnrow with the number of rows and 
   *prowind with a pointer to the rows indices

   created -- 98may04, cca
   -------------------------------------------
*/
void
FrontMtx_rowIndices (
   FrontMtx   *frontmtx,
   int         J,
   int         *pnrow,
   int         **prowind
) {
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL || J < 0 || J >= frontmtx->nfront 
   || pnrow == NULL || prowind == NULL ) {
   fprintf(stderr, 
           "\n fatal error in FrontMtx_rowIndices(%p,%d,%p,%p)"
           "\n bad input\n", frontmtx, J, pnrow, prowind) ;
   spoolesFatal();
}
if ( ! FRONTMTX_IS_PIVOTING(frontmtx) ) {
   IVL_listAndSize(frontmtx->symbfacIVL, J, pnrow, prowind) ;
} else if ( FRONTMTX_IS_SYMMETRIC(frontmtx) 
         || FRONTMTX_IS_HERMITIAN(frontmtx) ) {
   IVL_listAndSize(frontmtx->coladjIVL, J, pnrow, prowind) ;
} else if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   IVL_listAndSize(frontmtx->rowadjIVL, J, pnrow, prowind) ;
}
return ; }
示例#2
0
/*
   --------------------------------------------------
   purpose -- fill *pnadj with the number of fronts K
              such that L_{K,J} != 0 and *padj with a
              pointer to a list of those fronts
 
   created -- 98may04, cca
   --------------------------------------------------
*/
void
FrontMtx_lowerAdjFronts (
   FrontMtx   *frontmtx,
   int         J,
   int         *pnadj,
   int         **padj
) {
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL
   || J < 0 || J >= frontmtx->nfront
   || pnadj == NULL || padj == NULL ) {
   fprintf(stderr,
           "\n fatal error in FrontMtx_lowerAdjFronts(%p,%d,%p,%p)"
          "\n bad input\n", frontmtx, J, pnadj, padj) ;
   spoolesFatal();
}
if ( FRONTMTX_IS_1D_MODE(frontmtx) ) {
   fprintf(stderr, "\n fatal error in FrontMtx_lowerAdjFronts()"
           "\n data mode is 1-D, not 2-D\n") ;
   spoolesFatal();
} else if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   IVL_listAndSize(frontmtx->lowerblockIVL, J, pnadj, padj) ;
} else {
   IVL_listAndSize(frontmtx->upperblockIVL, J, pnadj, padj) ;
}
return ; }
示例#3
0
/*
   ---------------------------------------------
   fill *pncol with the number of columns and 
   *pcolind with a pointer to the column indices

   created -- 98may04, cca
   ---------------------------------------------
*/
void
FrontMtx_columnIndices (
   FrontMtx   *frontmtx,
   int         J,
   int         *pncol,
   int         **pcolind
) {
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL || J < 0 || J >= frontmtx->nfront 
   || pncol == NULL || pcolind == NULL ) {
   fprintf(stderr, 
           "\n fatal error in FrontMtx_columnIndices(%p,%d,%p,%p)"
           "\n bad input\n", frontmtx, J, pncol, pcolind) ;
   spoolesFatal();
}
if ( ! FRONTMTX_IS_PIVOTING(frontmtx) ) {
   IVL_listAndSize(frontmtx->symbfacIVL, J, pncol, pcolind) ;
} else {
   IVL_listAndSize(frontmtx->coladjIVL, J, pncol, pcolind) ;
}
return ; }
示例#4
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   -------------------------------------------------
   purpose -- to write an IVL object for a human eye

   return value -- 1 if success, 0 otherwise

   created -- 95sep29, cca
   -------------------------------------------------
*/
int
IVL_writeForHumanEye ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   ierr, j, size, rc ;
int   *ind ;

if ( ivl == NULL || fp == NULL ) {
   fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   spoolesFatal();
}
if ( (rc = IVL_writeStats(ivl, fp)) == 0 ) {
   fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
           "\n rc = %d, return from IVL_writeStats(%p,%p)\n",
           ivl, fp, rc, ivl, fp) ;
   return(0) ;
}
for ( j = 0 ; j < ivl->nlist ; j++ ) {
   IVL_listAndSize(ivl, j, &size, &ind) ;
   if ( size > 0 ) {
      fprintf(fp, "\n %5d :", j) ;
      IVfp80(fp, size, ind, 8, &ierr) ;
      if ( ierr < 0 ) {
         fprintf(stderr, "\n fatal error in IVL_writeForHumanEye(%p,%p)"
                 "\n ierr = %d, return from IVfp80, list %d\n", 
                 ivl, fp, ierr, j) ;
         return(0) ;
      }
   }
}

return(1) ; }
示例#5
0
/*
   --------------------------------------------------
   purpose -- fill *pnadj with the number of fronts K
              such that U_{J,K} != 0 and *padj with a
              pointer to a list of those fronts
 
   created -- 98may04, cca
   --------------------------------------------------
*/
void
FrontMtx_upperAdjFronts (
   FrontMtx   *frontmtx,
   int         J,
   int         *pnadj,
   int         **padj
) {
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL
   || J < 0 || J >= frontmtx->nfront
   || pnadj == NULL || padj == NULL ) {
   fprintf(stderr,
           "\n fatal error in FrontMtx_upperAdjFronts(%p,%d,%p,%p)"
          "\n bad input\n", frontmtx, J, pnadj, padj) ;
   exit(-1) ;
}
if ( FRONTMTX_IS_1D_MODE(frontmtx) ) {
   fprintf(stderr, "\n fatal error in FrontMtx_upperAdjFronts()"
           "\n data mode is 1, not 2\n") ;
   exit(-1) ;
}
IVL_listAndSize(frontmtx->upperblockIVL, J, pnadj, padj) ;
 
return ; }
示例#6
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   --------------------------------------------------
   purpose -- to write an IVL object to a binary file

   return value -- 1 if success, 0 otherwise

   created -- 95sep29, cca
   --------------------------------------------------
*/
int
IVL_writeToBinaryFile ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   j, jsize, nlist, rc ;
int   *jind ;
int   itemp[3] ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || fp == NULL || (nlist = ivl->nlist) <= 0 ) {
   fprintf(stderr, "\n fatal error in IVL_writeToBinaryFile(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   spoolesFatal();
}
itemp[0] = ivl->type ;
itemp[1] = ivl->nlist ;
itemp[2] = ivl->tsize ;
rc = fwrite((void *) itemp, sizeof(int), 3, fp) ;
if ( rc != 3 ) {
   fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
           "\n %d of %d scalar items written\n", ivl, fp, rc, 3) ;
   return(0) ;
}
rc = fwrite((void *) ivl->sizes, sizeof(int), ivl->nlist, fp) ;
if ( rc != ivl->nlist ) {
   fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
           "\n ivl->sizes, %d of %d items written\n",
           ivl, fp, rc, ivl->nlist) ;
   return(0) ;
}
switch ( ivl->type ) {
case IVL_NOTYPE :
   break ;
case IVL_CHUNKED :
case IVL_SOLO    :
case IVL_UNKNOWN :
   for ( j = 0 ; j < ivl->nlist ; j++ ) {
      IVL_listAndSize(ivl, j, &jsize, &jind) ;
      if ( jsize > 0 ) {
         rc = fwrite((void *) jind, sizeof(int), jsize, fp) ;
         if ( rc != jsize ) {
            fprintf(stderr, "\n error in IVL_writeToBinaryFile(%p,%p)"
                    "\n list %d, %d of %d items written\n",
                    ivl, fp, j, rc, jsize) ;
            return(0) ;
         }
      }
   }
   break ;
}

return(1) ; }
示例#7
0
/*
   ------------------------------------------------------------------
   this method is used during the setup for matrix-vector multiplies.
   each processor has computed the vertices it needs from other
   processors, these lists are contained in sendIVL. on return,
   recvIVL contains the lists of vertices this processor must send
   to all others.

   sendIVL -- on input, list[q] contains the vertices needed by
              this processor that are owned by q
   recvIVL -- on output, list[q] contains the vertices owned by
              this processor that are needed by q. note, if NULL
              on input, a new IVL object is allocated
   stats[] -- statistics vector
     stats[0] -- contains # of sends
     stats[1] -- contains # of receives
     stats[2] -- contains # of bytes sent
     stats[3] -- contains # of bytes received
   firsttag -- first tag for messages,
     tags in range [firsttag, firsttag+nproc-1] are used

   return value -- recvIVL

   created -- 98jul26, cca
   ------------------------------------------------------------------
*/
IVL *
IVL_MPI_alltoall (
    IVL        *sendIVL,
    IVL        *recvIVL,
    int        stats[],
    int        msglvl,
    FILE       *msgFile,
    int        firsttag,
    MPI_Comm   comm
) {
    int          count, destination, lasttag, left, myid, nproc, offset, q,
                 recvcount, right, sendcount, source, tag, tagbound ;
    int          *incounts, *outcounts, *recvvec, *sendvec ;
    MPI_Status   status ;
    /*
       ---------------
       check the input
       ---------------
    */
    if ( sendIVL == NULL || stats == NULL || (msglvl > 0 && msgFile == NULL) ) {
        fprintf(msgFile, "\n fatal error in IVL_MPI_alltoall()"
                "\n bad input\n") ;
        exit(-1) ;
    }
    /*
       ---------------------------------------
       get id of self and number of processors
       ---------------------------------------
    */
    MPI_Comm_rank(comm, &myid)  ;
    MPI_Comm_size(comm, &nproc) ;
    if ( sendIVL->nlist != nproc ) {
        fprintf(msgFile, "\n fatal error in IVL_MPI_alltoall()"
                "\n sendIVL: nproc = %d, nlist = %d\n",
                nproc, sendIVL->nlist) ;
        exit(-1) ;
    }
    lasttag = firsttag + nproc ;
    if ( lasttag > (tagbound = maxTagMPI(comm)) ) {
        fprintf(stderr, "\n fatal error in IVL_MPI_alltoall()"
                "\n lasttag = %d, tag_bound = %d", lasttag, tagbound) ;
        exit(-1) ;
    }

    if ( recvIVL == NULL ) {
        recvIVL = IVL_new() ;
    } else {
        IVL_clearData(recvIVL) ;
    }
    IVL_init1(recvIVL, IVL_CHUNKED, nproc) ;
    /*
       ------------------------------------------
       outcounts[] is sendIVL->sizes[]
       incounts[] will be recvIVL->sizes[]
       fill incounts via a call to MPI_Alltoall()
       and then initialize the recvIVL lists.
       ------------------------------------------
    */
    outcounts = sendIVL->sizes ;
    incounts  = IVinit(nproc, 0) ;
    MPI_Alltoall((void *) outcounts, 1, MPI_INT,
                 (void *) incounts,  1, MPI_INT, comm) ;
    for ( q = 0 ; q < nproc ; q++ ) {
        IVL_setList(recvIVL, q, incounts[q], NULL) ;
    }
    IVfree(incounts) ;
    /*
       ---------------------------------------------------
       load list myid of sendIVL into list myid of recvIVL
       ---------------------------------------------------
    */
    IVL_listAndSize(sendIVL, myid, &sendcount, &sendvec) ;
    IVL_setList(recvIVL, myid, sendcount, sendvec) ;
    /*
       ---------------------------------------------------------
       now loop over the processes, send and receive information
       ---------------------------------------------------------
    */
    for ( offset = 1, tag = firsttag ; offset < nproc ; offset++, tag++ ) {
        right = (myid + offset) % nproc ;
        if ( offset <= myid ) {
            left = myid - offset ;
        } else {
            left = nproc + myid - offset ;
        }
        IVL_listAndSize(sendIVL, right, &sendcount, &sendvec) ;
        IVL_listAndSize(recvIVL, left,  &recvcount, &recvvec) ;
        if ( sendcount > 0 ) {
            destination = right ;
            stats[0]++ ;
            stats[2] += sendcount*sizeof(int) ;
        } else {
            destination = MPI_PROC_NULL ;
        }
        if ( recvcount > 0 ) {
            source = left ;
            stats[1]++ ;
            stats[3] += recvcount*sizeof(int) ;
        } else {
            source = MPI_PROC_NULL ;
        }
        if ( msglvl > 2 ) {
            fprintf(msgFile,
                    "\n offset %d, recvcount %d, source %d, sendcount %d, destination %d",
                    offset, recvcount, source, sendcount, destination) ;
            fflush(msgFile) ;
        }
        /*
           -----------------
           do a send/receive
           -----------------
        */
        MPI_Sendrecv((void *) sendvec, sendcount, MPI_INT, destination, tag,
                     (void *) recvvec, recvcount, MPI_INT, source,      tag,
                     comm, &status) ;
        if ( source != MPI_PROC_NULL ) {
            MPI_Get_count(&status, MPI_INT, &count) ;
            if ( count != recvcount ) {
                fprintf(stderr, "\n fatal error in IVL_MPI_alltoall()"
                        "\n proc %d : source %d, count %d, recvcount %d\n",
                        myid, source, count, recvcount) ;
                exit(-1) ;
            }
        }
        if ( msglvl > 2 ) {
            fprintf(msgFile, "\n send/recv completed") ;
            fflush(msgFile) ;
        }
    }
    return(recvIVL) ;
}
示例#8
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   ---------------------------------------------------
   purpose -- to read an IVL object from a binary file

   return value -- 1 if success, 0  if failure

   created -- 95sep29, cca
   ---------------------------------------------------
*/
int
IVL_readFromBinaryFile ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   nlist, rc, type ;
int   itemp[3] ;
int   *sizes ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || fp == NULL ) {
   fprintf(stderr, "\n fatal error in IVL_readFromBinaryFile(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   return(0) ;
}
switch ( ivl->type ) {
case IVL_CHUNKED :
case IVL_SOLO    :
   break ;
default :
   fprintf(stderr, "\n error in IVL_readBinaryFile(%p,%p)"
    "\n bad type = %d", ivl, fp, ivl->type) ;
   return(0) ;
}
/*
   -------------------------------------------
   save the ivl type and clear the data fields
   -------------------------------------------
*/
type = ivl->type ;
IVL_clearData(ivl) ;
/*
   -----------------------------------
   read in the three scalar parameters
   type, # of lists, # of indices
   -----------------------------------
*/
if ( (rc = fread((void *) itemp, sizeof(int), 3, fp)) != 3 ) {
   fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
           "\n itemp(3) : %d items of %d read\n", ivl, fp, rc, 3) ;
   return(0) ;
}
nlist = itemp[1] ;
/*
   --------------------------
   read in the sizes[] vector
   --------------------------
*/
sizes = IVinit(nlist, 0) ;
if ( (rc = fread((void *) sizes, sizeof(int), nlist, fp)) != nlist ) {
   fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
           "\n sizes(%d) : %d items of %d read\n", 
           ivl, fp, nlist, rc, nlist) ;
   return(0) ;
}
/*
   ---------------------
   initialize the object
   ---------------------
*/
IVL_init3(ivl, type, nlist, sizes) ;
IVfree(sizes) ;
/*
   -------------------
   read in the indices
   -------------------
*/
switch ( type ) {
case IVL_SOLO : {
   int   ilist, size ;
   int   *ind ;

   for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
      IVL_listAndSize(ivl, ilist, &size, &ind) ;
      if ( (rc = fread((void *) ind, sizeof(int), size, fp)) != size ) {
         fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
                 "\n list %d, %d items of %d read\n", 
                 ivl, fp, ilist, rc, size) ;
         return(0) ;
      }
   }
   } break ;
case IVL_CHUNKED : {
/*
   --------------------------------------------------------
   read in the indices into the contiguous block of storage
   --------------------------------------------------------
*/
   if ( (rc = fread((void *) ivl->chunk->base, 
                    sizeof(int), ivl->tsize, fp)) != ivl->tsize ) {
      fprintf(stderr, "\n error in IVL_readFromBinaryFile(%p,%p)"
              "\n indices(%d) : %d items of %d read\n", 
              ivl, fp, ivl->tsize, rc, ivl->tsize) ;
      return(0) ;
   }
   } break ;
}
return(1) ; }
示例#9
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   -----------------------------------------------------
   purpose -- to write an IVL object to a formatted file

   return value -- 1 if success, 0 otherwise

   created -- 95sep29, cca
   -----------------------------------------------------
*/
int
IVL_writeToFormattedFile ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   count, ierr, j, jsize, nlist, rc ;
int   *jind ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || fp == NULL || (nlist = ivl->nlist) <= 0 ) {
   fprintf(stderr, "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   spoolesFatal();
}
/*
   -------------------------------------
   write out the three scalar parameters
   -------------------------------------
*/
rc = fprintf(fp, "\n %d %d %d", ivl->type, ivl->nlist, ivl->tsize) ;
if ( rc < 0 ) {
   fprintf(stderr, "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
           "\n rc = %d, return from first fprintf\n", ivl, fp, rc) ;
   return(0) ;
}
if ( ivl->nlist > 0 ) {
   IVfp80(fp, ivl->nlist, ivl->sizes, 80, &ierr) ;
   if ( ierr < 0 ) {
      fprintf(stderr, 
              "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
              "\n ierr = %d, return from sizes[] IVfp80\n", 
              ivl, fp, ierr) ;
      return(0) ;
   }
}
switch ( ivl->type ) {
case IVL_NOTYPE :
   break ;
case IVL_UNKNOWN :
case IVL_CHUNKED :
case IVL_SOLO    :
   for ( j = 0, count = 80 ; j < ivl->nlist ; j++ ) {
      IVL_listAndSize(ivl, j, &jsize, &jind) ;
      if ( jsize > 0 ) {
         count = IVfp80(fp, jsize, jind, count, &ierr) ;
         if ( ierr < 0 ) {
            fprintf(stderr, 
                    "\n fatal error in IVL_writeToFormattedFile(%p,%p)"
                    "\n ierr = %d, return from IVfp80, list %d\n", 
                    ivl, fp, ierr, j) ;
            return(0) ;
         }
      }
   }
   break ;
}

return(1) ; }
示例#10
0
/*
   ---------------------------------------------------------------------
   purpose -- take a Graph object and a map to expand it, create and
              return a bigger unit weight Graph object. this is useful 
              for expanding a compressed graph into a unit weight graph.

   created -- 96mar02, cca
   ---------------------------------------------------------------------
*/
Graph *
Graph_expand (
   Graph   *g,
   int     nvtxbig,
   int     map[]
) {
Graph   *gbig ;
int     count, ii, nedge, nvtx, v, vbig, vsize, w ;
int     *head, *indices, *link, *mark, *vadj ;
IVL     *adjIVL, *adjbigIVL ;
/*
   ---------------
   check the input
   ---------------
*/
if ( g == NULL || nvtxbig <= 0 || map == NULL ) {
   fprintf(stderr, "\n fatal error in Graph_expand(%p,%d,%p)"
           "\n bad input\n", g, nvtxbig, map) ;
   spoolesFatal();
}
nvtx   = g->nvtx   ;
adjIVL = g->adjIVL ;
/*
   ----------------------------------------
   set up the linked lists for the vertices
   ----------------------------------------
*/
head = IVinit(nvtx,    -1) ;
link = IVinit(nvtxbig, -1) ;
for ( vbig = 0 ; vbig < nvtxbig ; vbig++ ) {
   v          = map[vbig] ;
   link[vbig] = head[v]   ;
   head[v]    = vbig      ;
}
/*
   --------------------------------
   create the expanded Graph object
   --------------------------------
*/
gbig = Graph_new() ;
Graph_init1(gbig, 0, nvtxbig, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjbigIVL = gbig->adjIVL ;
/*
   -------------------------------------------
   fill the lists in the expanded Graph object
   -------------------------------------------
*/
indices = IVinit(nvtxbig, -1) ;
mark    = IVinit(nvtx,    -1) ;
nedge   = 0 ;
for ( v = 0 ; v < nvtx ; v++ ) {
   if ( head[v] != -1 ) {
/*
      ------------------------------
      load the indices that map to v
      ------------------------------
*/
      mark[v] = v ;
      count   = 0 ;
      for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
         indices[count++] = vbig ;
      }
/*
      ---------------------------------------------------
      load the indices that map to vertices adjacent to v
      ---------------------------------------------------
*/
      IVL_listAndSize(adjIVL, v, &vsize, &vadj) ;
      for ( ii = 0 ; ii < vsize ; ii++ ) {
         w = vadj[ii] ;
         if ( w < nvtx && mark[w] != v ) {
            mark[w] = v ;
            for ( vbig = head[w] ; vbig != -1 ; vbig = link[vbig] ) {
               indices[count++] = vbig ;
            }
         }
      }
/*
      --------------------------------------
      sort the index list in ascending order
      --------------------------------------
*/
      IVqsortUp(count, indices) ;
/*
      -------------------------------------------------------
      each vertex in the big IVL object has its own list.
      -------------------------------------------------------
*/
      for ( vbig = head[v] ; vbig != -1 ; vbig = link[vbig] ) {
         IVL_setList(adjbigIVL, vbig, count, indices) ;
         nedge += count ;
      }
   }
}
gbig->nedges = nedge ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(head)    ;
IVfree(link)    ;
IVfree(indices) ;
IVfree(mark)    ;

return(gbig) ; }
示例#11
0
文件: IO.c 项目: fransklaver/SPOOLES
/*
   ------------------------------------------------------
   purpose -- to read an IVL object from a formatted file

   return value -- 1 if success, 0 if failure

   created -- 95sep29, cca
   ------------------------------------------------------
*/
int
IVL_readFromFormattedFile ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   nlist, rc, type ;
int   itemp[3] ;
int   *sizes ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || fp == NULL ) {
   fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   return(0) ;
}
switch ( ivl->type ) {
case IVL_CHUNKED :
case IVL_SOLO    :
   break ;
default :
   fprintf(stderr, "\n error in IVL_readFormattedFile(%p,%p)"
    "\n bad type = %d", ivl, fp, ivl->type) ;
   return(0) ;
}
/*
   -------------------------------------------
   save the ivl type and clear the data fields
   -------------------------------------------
*/
type = ivl->type ;
IVL_clearData(ivl) ;
/*
   -----------------------------------
   read in the three scalar parameters
   type, # of lists, # of indices
   -----------------------------------
*/
if ( (rc = IVfscanf(fp, 3, itemp)) != 3 ) {
   fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
           "\n %d items of %d read\n", ivl, fp, rc, 3) ;
   return(0) ;
}
nlist = itemp[1] ;
/*
fprintf(stdout, "\n itemp = { %d %d %d } ",
        itemp[0], itemp[1], itemp[2]) ;
*/
/*
   --------------------------
   read in the sizes[] vector
   --------------------------
*/
sizes = IVinit(nlist, 0) ;
if ( (rc = IVfscanf(fp, nlist, sizes)) != nlist ) {
   fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
           "\n %d items of %d read\n", ivl, fp, rc, nlist) ;
   return(0) ;
}
/*
   ---------------------
   initialize the object
   ---------------------
*/
IVL_init3(ivl, type, nlist, sizes) ;
IVfree(sizes) ;
/*
   -----------------------
   now read in the indices
   -----------------------
*/
switch ( type ) {
case IVL_SOLO : {
   int   ilist, size ;
   int   *ind ;

   for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
      IVL_listAndSize(ivl, ilist, &size, &ind) ;
      if ( size > 0 ) {
         if ( (rc = IVfscanf(fp, size, ind)) != size ) {
            fprintf(stderr, 
                    "\n error in IVL_readFromFormattedFile(%p,%p)"
                    "\n list %d, %d items of %d read\n", 
                    ivl, fp, ilist, rc, size) ;
            return(0) ;
         }
      }
   }
   } break ;
case IVL_CHUNKED : {
/*
   --------------------------------------------------------
   read in the indices into the contiguous block of storage
   --------------------------------------------------------
*/
   if ( (rc = IVfscanf(fp, ivl->tsize, ivl->chunk->base)) 
        != ivl->tsize ) {
      fprintf(stderr, "\n error in IVL_readFromFormattedFile(%p,%p)"
              "\n %d items of %d read\n", ivl, fp, rc, ivl->tsize) ;
      return(0) ;
   }
   } break ;
}
return(1) ; }
示例#12
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) ; }
示例#13
0
文件: storage.c 项目: bialk/SPOOLES
/*
   ---------------------------------------------------------------
   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 ; }
示例#14
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) ; }
示例#15
0
/*
   --------------------------------------
   purpose -- map the off diagonal blocks 
      to processes in a random fashion

   created -- 98mar19, cca
   --------------------------------------
*/
void
SolveMap_randomMap (
   SolveMap   *solvemap,
   int        symmetryflag,
   IVL        *upperBlockIVL,
   IVL        *lowerBlockIVL,
   int        nproc,
   IV         *ownersIV,
   int        seed,
   int        msglvl,
   FILE       *msgFile
) {
Drand   drand ;
int     ii, J, K, loc, nadj, nblockLower, nblockUpper, 
        nfront, proc ;
int     *adj, *colids, *map, *owners, *rowids ;
/*
   ---------------
   check the input
   ---------------
*/
if ( solvemap == NULL || symmetryflag < 0 
   || upperBlockIVL == NULL || ownersIV == NULL ) {
   fprintf(stderr, 
           "\n fatal error in SolveMap_randomMap(%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_randomMap(): 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) ;
}
/*
   --------------------------------------
   initialize the random number generator
   --------------------------------------
*/
Drand_setDefaultFields(&drand) ;
Drand_setUniform(&drand, 0, nproc) ;
/*
   ----------------------------------------
   map the upper blocks in a random fashion
   ----------------------------------------
*/
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 ) {
         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 ( lowerBlockIVL != NULL ) {
/*
   ----------------------------------------
   map the lower blocks in a random fashion
   ----------------------------------------
*/
   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 ) {
            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++ ;
         }
      }
   }
}
return ; }
示例#16
0
/*
   ----------------------------------------------------
   create a Graph object that holds the adjacency graph 
   of the assembled elements. 

   created -- 95nov03, cca
   ----------------------------------------------------
*/
Graph *
EGraph_mkAdjGraph ( 
   EGraph   *egraph 
) {
int     elem, esize, i, nelem, nvtx, v, vsize, w ;
int     *eind, *head, *link, *marker, *offsets, *vind ;
IVL     *eadjIVL, *gadjIVL ;
Graph   *graph ;
/*
   ---------------
   check the input
   ---------------
*/
if ( egraph == NULL || (eadjIVL = egraph->adjIVL) == NULL ) {
   fprintf(stderr, "\n fatal error in EGraph_mkAdjGraph(%p)"
           "\n bad input\n", egraph) ;
   spoolesFatal();
}
nelem  = egraph->nelem  ;
nvtx   = egraph->nvtx   ;
/*
   --------------------------------
   set up the linked list structure
   --------------------------------
*/
head    = IVinit(nvtx,  -1) ;
link    = IVinit(nelem, -1) ;
offsets = IVinit(nelem,  0) ;
/*
   -----------------------------------------------------------
   sort the vertices in each element list into ascending order
   and link them into their first vertex
   -----------------------------------------------------------
*/
for ( elem = 0 ; elem < nelem ; elem++ ) {
   IVL_listAndSize(eadjIVL, elem, &esize, &eind) ;
   if ( esize > 0 ) {
      IVqsortUp(esize, eind) ;
      v          = eind[0] ;
      link[elem] = head[v] ;
      head[v]    = elem    ;
   }
}
/*
   ---------------------------
   create the new Graph object
   ---------------------------
*/
graph = Graph_new() ;
Graph_init1(graph, egraph->type, nvtx, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
gadjIVL = graph->adjIVL ;
/*
   ----------------------
   loop over the vertices
   ----------------------
*/
vind   = IVinit(nvtx, -1) ;
marker = IVinit(nvtx, -1) ;
for ( v = 0 ; v < nvtx ; v++ ) {
/*
   ---------------------------------
   loop over the supporting elements
   ---------------------------------
*/
   vsize = 0 ;
   vind[vsize++] = v ;
   marker[v]     = v ;
   while ( (elem = head[v]) != -1 ) {
/*
fprintf(stdout, "\n    checking out element %d :", jelem) ;
*/
      head[v] = link[elem] ;
      IVL_listAndSize(eadjIVL, elem, &esize, &eind) ;
      for ( i = 0 ; i < esize ; i++ ) {
         w = eind[i] ;
         if ( marker[w] != v ) {
            marker[w]     = v ;
            vind[vsize++] = w ;
         }
      }
      if ( (i = ++offsets[elem]) < esize ) {
         w          = eind[i] ;
         link[elem] = head[w] ;
         head[w]    = elem    ;
      }
   }
   IVqsortUp(vsize, vind) ;
   IVL_setList(gadjIVL, v, vsize, vind) ;
}
graph->nedges = gadjIVL->tsize ;
if ( egraph->type == 0 ) {
   graph->totvwght = nvtx ;
} else if ( egraph->type == 1 ) {
/*
   ------------------------------
   fill the vertex weights vector
   ------------------------------
*/
   IVcopy(nvtx, graph->vwghts, egraph->vwghts) ;
   graph->totvwght = IVsum(nvtx, graph->vwghts) ;
}
graph->totewght = graph->nedges ;
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(head)    ;
IVfree(link)    ;
IVfree(marker)  ;
IVfree(vind)    ;
IVfree(offsets) ;

return(graph) ; }
示例#17
0
/*
   --------------------------------------------------------------------
   fill *pndom with ndom, the number of domains.
   fill *pnseg with nseg, the number of segments.
   domains are numbered in [0, ndom), segments in [ndom,ndom+nseg).

   return -- an IV object that contains the map 
             from vertices to segments

   created -- 99feb29, cca
   --------------------------------------------------------------------
*/
IV *
GPart_domSegMap (
   GPart   *gpart,
   int     *pndom,
   int     *pnseg
) {
FILE    *msgFile ;
Graph   *g ;
int     adjdom, count, d, first, ierr, ii, jj1, jj2, last, ndom, 
        msglvl, nextphi, nPhi, nPsi, nV, phi, phi0, phi1, phi2, phi3, 
        psi, sigma, size, size0, size1, size2, v, vsize, w ;
int     *adj, *adj0, *adj1, *adj2, *compids, *dmark, *dsmap, *head, 
        *link, *list, *offsets, *PhiToPsi, *PhiToV, *PsiToSigma, 
        *vadj, *VtoPhi ;
IV      *dsmapIV ;
IVL     *PhiByPhi, *PhiByPowD, *PsiByPowD ;
/*
   --------------------
   set the initial time
   --------------------
*/
icputimes = 0 ;
MARKTIME(cputimes[icputimes]) ;
/*
   ---------------
   check the input
   ---------------
*/
if (  gpart == NULL 
   || (g = gpart->g) == NULL 
   || pndom == NULL
   || pnseg == NULL ) {
   fprintf(stderr, "\n fatal error in GPart_domSegMap(%p,%p,%p)"
           "\n bad input\n", gpart, pndom, pnseg) ;
   exit(-1) ;
}
compids = IV_entries(&gpart->compidsIV) ;
msglvl  = gpart->msglvl  ;
msgFile = gpart->msgFile ;
/*
   ------------------------
   create the map IV object
   ------------------------
*/
nV = g->nvtx ;
dsmapIV = IV_new() ;
IV_init(dsmapIV, nV, NULL) ;
dsmap = IV_entries(dsmapIV) ;
/*
   ----------------------------------
   check compids[] and get the number 
   of domains and interface vertices
   ----------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
ndom = nPhi = 0 ;
for ( v = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) < 0 ) {
      fprintf(stderr, 
              "\n fatal error in GPart_domSegMap(%p,%p,%p)"
              "\n compids[%d] = %d\n", gpart, pndom, pnseg,
              v, compids[v]) ;
      exit(-1) ;
   } else if ( d == 0 ) {
      nPhi++ ;
   } else if ( ndom < d ) {
      ndom = d ;
   }
}
*pndom = ndom ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n\n Inside GPart_domSegMap") ;
   fprintf(msgFile, "\n %d domains, %d Phi vertices", ndom, nPhi) ;
}
if ( ndom == 1 ) {
   IVfill(nV, dsmap, 0) ;
   *pndom = 1 ;
   *pnseg = 0 ;
   return(dsmapIV) ;
}
/*
   --------------------------------
   get the maps
   PhiToV : [0,nPhi) |---> [0,nV)
   VtoPhi : [0,nV)   |---> [0,nPhi)
   --------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiToV = IVinit(nPhi, -1) ;
VtoPhi = IVinit(nV,   -1) ;
for ( v = 0, phi = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) == 0 ) {
      PhiToV[phi] = v ;
      VtoPhi[v]   = phi++ ;
   }
}
if ( phi != nPhi ) {
   fprintf(stderr, 
           "\n fatal error in GPart_domSegMap(%p,%p,%p)"
           "\n phi = %d != %d = nPhi\n", 
           gpart, pndom, pnseg, phi, nPhi) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiToV(%d) :", nPhi) ;
   IVfp80(msgFile, nPhi, PhiToV, 15, &ierr) ;
   fflush(msgFile) ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n VtoPhi(%d) :", nV) ;
   IVfp80(msgFile, nV, VtoPhi, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------------------------
   create an IVL object, PhiByPowD, to hold lists from 
   the interface vertices to their adjacent domains
   ---------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
dmark = IVinit(ndom+1, -1) ;
if ( nPhi >= ndom ) {
   list = IVinit(nPhi, -1) ;
} else {
   list = IVinit(ndom, -1) ;
}
PhiByPowD = IVL_new() ;
IVL_init1(PhiByPowD, IVL_CHUNKED, nPhi) ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   v = PhiToV[phi] ;
   Graph_adjAndSize(g, v, &vsize, &vadj) ;
/*
if ( phi == 0 ) {
   int   ierr ;
   fprintf(msgFile, "\n adj(%d,%d) = ", v, phi) ;
   IVfp80(msgFile, vsize, vadj, 15, &ierr) ;
   fflush(msgFile) ;
}
*/
   count = 0 ;
   for ( ii = 0 ; ii < vsize ; ii++ ) {
      if ( (w = vadj[ii]) < nV  
        && (d = compids[w]) > 0 
        && dmark[d] != phi ) {
         dmark[d] = phi ;
         list[count++] = d ;
      }
   }
   if ( count > 0 ) {
      IVqsortUp(count, list) ;
      IVL_setList(PhiByPowD, phi, count, list) ;
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiByPowD : interface x adjacent domains") ;
   IVL_writeForHumanEye(PhiByPowD, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------------
   create an IVL object, PhiByPhi to hold lists
   from the interface vertices to interface vertices.
   (s,t) are in the list if (s,t) is an edge in the graph
   and s and t do not share an adjacent domain
   -------------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiByPhi = IVL_new() ;
IVL_init1(PhiByPhi, IVL_CHUNKED, nPhi) ;
offsets = IVinit(nPhi,  0)  ;
head    = IVinit(nPhi, -1) ;
link    = IVinit(nPhi, -1) ;
for ( phi1 = 0 ; phi1 < nPhi ; phi1++ ) {
   count = 0 ;
   if ( msglvl > 2 ) {
      v = PhiToV[phi1] ;
      Graph_adjAndSize(g, v, &vsize, &vadj) ;
      fprintf(msgFile, "\n checking out phi = %d, v = %d", phi1, v) ;
      fprintf(msgFile, "\n adj(%d) : ", v) ;
      IVfp80(msgFile, vsize, vadj, 10, &ierr) ;
   }
/*
   -------------------------------------------------------------
   get (phi1, phi0) edges that were previously put into the list
   -------------------------------------------------------------
*/
   if ( msglvl > 3 ) {
      if ( head[phi1] == -1 ) {
         fprintf(msgFile, "\n    no previous edges") ;
      } else {
         fprintf(msgFile, "\n    previous edges :") ;
      }
   }
   for ( phi0 = head[phi1] ; phi0 != -1 ; phi0 = nextphi ) {
      if ( msglvl > 3 ) {
         fprintf(msgFile, " %d", phi0) ;
      }
      nextphi = link[phi0] ;
      list[count++] = phi0 ;
      IVL_listAndSize(PhiByPhi, phi0, &size0, &adj0) ;
      if ( (ii = ++offsets[phi0]) < size0 ) {
/*
         ----------------------------
         link phi0 into the next list
         ----------------------------
*/
         phi2       = adj0[ii]   ;
         link[phi0] = head[phi2] ;
         head[phi2] = phi0       ;
      }
   }
/*
   --------------------------
   get new edges (phi1, phi2)
   --------------------------
*/
   IVL_listAndSize(PhiByPowD, phi1, &size1, &adj1) ;
   v = PhiToV[phi1] ;
   Graph_adjAndSize(g, v, &vsize, &vadj) ;
   for ( ii = 0 ; ii < vsize ; ii++ ) {
      if (  (w = vadj[ii]) < nV 
         && compids[w] == 0 
         && (phi2 = VtoPhi[w]) > phi1 ) {
         if ( msglvl > 3 ) {
            fprintf(msgFile, "\n    checking out phi2 = %d", phi2) ;
         }
/*
         --------------------------------------------------
         see if phi1 and phi2 have a common adjacent domain
         --------------------------------------------------
*/
         IVL_listAndSize(PhiByPowD, phi2, &size2, &adj2) ;
         adjdom = 0 ;
         jj1 = jj2 = 0 ;
         while ( jj1 < size1 && jj2 < size2 ) {
            if ( adj1[jj1] < adj2[jj2] ) {
               jj1++ ;
            } else if ( adj1[jj1] > adj2[jj2] ) {
               jj2++ ;
            } else {
               if ( msglvl > 3 ) {
                  fprintf(msgFile, ", common adj domain %d", adj1[jj1]) ;
               }
               adjdom = 1 ;
               break ;
            }
         }
         if ( adjdom == 0 ) {
            if ( msglvl > 3 ) {
               fprintf(msgFile, ", no adjacent domain") ;
            }
            list[count++] = phi2 ;
         }
      }
   }
   if ( count > 0 ) {
/*
      ---------------------
      set the list for phi1
      ---------------------
*/
      IVqsortUp(count, list) ;
      IVL_setList(PhiByPhi, phi1, count, list) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n    edge list for %d :", phi1) ;
         IVfp80(msgFile, count, list, 15, &ierr) ;
      }
      for ( ii = 0, phi2 = -1 ; ii < count ; ii++ ) {
         if ( list[ii] > phi1 ) {
            offsets[phi1] = ii ;
            phi2 = list[ii] ;
            break ;
         }
      }
      if ( phi2 != -1 ) {
      if ( msglvl > 2 ) {
         fprintf(msgFile, 
                 "\n       linking %d into list for %d", phi1, phi2) ;
      }
         link[phi1] = head[phi2] ;
         head[phi2] = phi1       ;
      }
/*
      phi2 = list[0] ;
      link[phi1] = head[phi2] ;
      head[phi2] = phi1 ;
*/
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiByPhi : interface x interface") ;
   IVL_writeForHumanEye(PhiByPhi, msgFile) ;
   fflush(msgFile) ;
}
/*
   --------------------
   get the PhiToPsi map
   --------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PhiToPsi = IVinit(nPhi, -1) ;
nPsi = 0 ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   if ( PhiToPsi[phi] == -1 ) {
/*
      ---------------------------
      phi not yet mapped to a psi
      ---------------------------
*/
      first = last = 0 ;
      list[0] = phi ;
      PhiToPsi[phi] = nPsi ;
      while ( first <= last ) {
         phi2 = list[first++] ;
         IVL_listAndSize(PhiByPhi, phi2, &size, &adj) ;
         for ( ii = 0 ; ii < size ; ii++ ) {
            phi3 = adj[ii] ;
            if ( PhiToPsi[phi3] == -1 ) {
               PhiToPsi[phi3] = nPsi ;
               list[++last] = phi3 ; 
            }
         }
      }
      nPsi++ ;
   }
}
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n nPsi = %d", nPsi) ;
   fflush(msgFile) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PhiToPsi(%d) :", nPhi) ;
   IVfp80(msgFile, nPhi, PhiToPsi, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------
   create an IVL object, Psi --> 2^D
   ---------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
IVfill(nPsi, head, -1) ;
IVfill(nPhi, link, -1) ;
for ( phi = 0 ; phi < nPhi ; phi++ ) {
   psi = PhiToPsi[phi] ;
   link[phi] = head[psi] ;
   head[psi] =   phi     ;
}
PsiByPowD = IVL_new() ;
IVL_init1(PsiByPowD, IVL_CHUNKED, nPsi) ;
IVfill(ndom+1, dmark, -1) ;
for ( psi = 0 ; psi < nPsi ; psi++ ) {
   count = 0 ;
   for ( phi = head[psi] ; phi != -1 ; phi = link[phi] ) {
      v = PhiToV[phi] ;
      Graph_adjAndSize(g, v, &size, &adj) ;
      for ( ii = 0 ; ii < size ; ii++ ) {
         if (  (w = adj[ii]) < nV
            && (d = compids[w]) > 0 
            && dmark[d] != psi ) {
            dmark[d]      = psi ;
            list[count++] =  d  ;
         }
      }
   }
   if ( count > 0 ) {
      IVqsortUp(count, list) ;
      IVL_setList(PsiByPowD, psi, count, list) ;
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n PsiByPowD(%d) :", nPhi) ;
   IVL_writeForHumanEye(PsiByPowD, msgFile) ;
   fflush(msgFile) ;
}
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
/*
   -------------------------------------
   now get the map Psi |---> Sigma that 
   is the equivalence map over PhiByPowD
   -------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
PsiToSigma = IVL_equivMap1(PsiByPowD) ;
*pnseg = 1 + IVmax(nPsi, PsiToSigma, &ii) ;
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n nSigma = %d", *pnseg) ;
   fprintf(msgFile, "\n PsiToSigma(%d) :", nPhi) ;
   IVfp80(msgFile, nPsi, PsiToSigma, 15, &ierr) ;
   fflush(msgFile) ;
}
/*
   --------------------------------------------------------------
   now fill the map from the vertices to the domains and segments
   --------------------------------------------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
for ( v = 0 ; v < nV ; v++ ) {
   if ( (d = compids[v]) > 0 ) {
      dsmap[v] = d - 1 ;
   } else {
      phi      = VtoPhi[v] ;
      psi      = PhiToPsi[phi] ;
      sigma    = PsiToSigma[psi] ;
      dsmap[v] = ndom + sigma ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
IVL_free(PhiByPhi)  ;
IVL_free(PhiByPowD) ;
IVL_free(PsiByPowD) ;
IVfree(PhiToV)      ;
IVfree(VtoPhi)      ;
IVfree(dmark)       ;
IVfree(list)        ;
IVfree(PhiToPsi)    ;
IVfree(head)        ;
IVfree(link)        ;
IVfree(offsets)     ;
IVfree(PsiToSigma)  ;
icputimes++ ;
MARKTIME(cputimes[icputimes]) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n domain/segment map timings split") ;
   fprintf(msgFile, 
   "\n %9.5f : create the DSmap object"
   "\n %9.5f : get numbers of domain and interface vertices"
   "\n %9.5f : generate PhiToV and VtoPhi"
   "\n %9.5f : generate PhiByPowD"
   "\n %9.5f : generate PhiByPhi"
   "\n %9.5f : generate PhiToPsi"
   "\n %9.5f : generate PsiByPowD"
   "\n %9.5f : generate PsiToSigma"
   "\n %9.5f : generate dsmap"
   "\n %9.5f : free working storage"
   "\n %9.5f : total time",
   cputimes[1] - cputimes[0],
   cputimes[2] - cputimes[1],
   cputimes[3] - cputimes[2],
   cputimes[4] - cputimes[3],
   cputimes[5] - cputimes[4],
   cputimes[6] - cputimes[5],
   cputimes[7] - cputimes[6],
   cputimes[8] - cputimes[7],
   cputimes[9] - cputimes[8],
   cputimes[10] - cputimes[9],
   cputimes[11] - cputimes[0]) ;
}

return(dsmapIV) ; }
示例#18
0
文件: QRutil.c 项目: damiannz/spooles
/*
   --------------------------------------------------------------
   purpose -- create and return an A2 object that contains rows
              of A and rows from update matrices of the children.
              the matrix may not be in staircase form

   created -- 98may25, cca
   --------------------------------------------------------------
*/
A2 *
FrontMtx_QR_assembleFront (
   FrontMtx   *frontmtx,
   int        J,
   InpMtx     *mtxA,
   IVL        *rowsIVL,
   int        firstnz[],
   int        colmap[],
   Chv        *firstchild,
   DV         *workDV,
   int        msglvl,
   FILE       *msgFile
) {
A2       *frontJ ;
Chv      *chvI ;
double   *rowI, *rowJ, *rowentA ;
int      ii, irow, irowA, irowI, jcol, jj, jrow, ncolI, ncolJ, 
         nentA, nrowI, nrowJ, nrowFromA ;
int      *colindA, *colindI, *colindJ, *map, *rowids, *rowsFromA ;
/*
   ---------------
   check the input
   ---------------
*/
if ( frontmtx == NULL || mtxA == NULL || rowsIVL == NULL
   || (msglvl > 0 && msgFile == NULL) ) {
   fprintf(stderr, "\n fatal error in FrontMtx_QR_assembleFront()"
           "\n bad input\n") ;
   exit(-1) ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n\n inside FrontMtx_QR_assembleFront(%d)", J) ;
   fflush(msgFile) ;
}
/*
   --------------------------------------------------
   set up the map from global to local column indices
   --------------------------------------------------
*/
FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ;
for ( jcol = 0 ; jcol < ncolJ ; jcol++ ) {
   colmap[colindJ[jcol]] = jcol ;
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n front %d's column indices", J) ;
   IVfprintf(msgFile, ncolJ, colindJ) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------
   compute the size of the front and map the global 
   indices of the update matrices into local indices
   -------------------------------------------------
*/
IVL_listAndSize(rowsIVL, J, &nrowFromA, &rowsFromA) ;
nrowJ = nrowFromA ;
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n %d rows from A", nrowFromA) ;
   fflush(msgFile) ;
}
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowJ += chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   for ( jcol = 0 ; jcol < ncolI ; jcol++ ) {
      colindI[jcol] = colmap[colindI[jcol]] ;
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n %d rows from child %d", chvI->nD, chvI->id) ;
      fflush(msgFile) ;
   }
}
/*
   ----------------------------------------------------------
   get workspace for the rowids[nrowJ] and map[nrowJ] vectors
   ----------------------------------------------------------
*/
if ( sizeof(int) == sizeof(double) ) {
   DV_setSize(workDV, 2*nrowJ) ;
} else if ( 2*sizeof(int) == sizeof(double) ) {
   DV_setSize(workDV, nrowJ) ;
}
rowids = (int *) DV_entries(workDV) ;
map    = rowids + nrowJ ;
IVramp(nrowJ, rowids, 0, 1) ;
IVfill(nrowJ, map, -1) ;
/*
   -----------------------------------------------------------------
   get the map from incoming rows to their place in the front matrix
   -----------------------------------------------------------------
*/
for ( irow = jrow = 0 ; irow < nrowFromA ; irow++, jrow++ ) {
   irowA = rowsFromA[irow] ;
   map[jrow] = colmap[firstnz[irowA]] ;
}
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowI = chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   for ( irow = 0 ; irow < nrowI ; irow++, jrow++ ) {
      map[jrow] = colindI[irow] ;
   }
}
IV2qsortUp(nrowJ, map, rowids) ;
for ( irow = 0 ; irow < nrowJ ; irow++ ) {
   map[rowids[irow]] = irow ;
}
/*
   ----------------------------
   allocate the A2 front object
   ----------------------------
*/
frontJ = A2_new() ;
A2_init(frontJ, frontmtx->type, nrowJ, ncolJ, ncolJ, 1, NULL) ;
A2_zero(frontJ) ;
/*
   ------------------------------------
   load the original rows of the matrix
   ------------------------------------
*/
for ( jrow = 0 ; jrow < nrowFromA ; jrow++ ) {
   irowA = rowsFromA[jrow] ;
   rowJ  = A2_row(frontJ, map[jrow]) ;
   if ( A2_IS_REAL(frontJ) ) {
      InpMtx_realVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
   } else if ( A2_IS_COMPLEX(frontJ) ) {
      InpMtx_complexVector(mtxA, irowA, &nentA, &colindA, &rowentA) ;
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n loading row %d", irowA) ;
      fprintf(msgFile, "\n global indices") ;
      IVfprintf(msgFile, nentA, colindA) ;
      fflush(msgFile) ;
   }
   if ( A2_IS_REAL(frontJ) ) {
      for ( ii = 0 ; ii < nentA ; ii++ ) {
         jj = colmap[colindA[ii]] ;
         rowJ[jj] = rowentA[ii] ;
      }
   } else if ( A2_IS_COMPLEX(frontJ) ) {
      for ( ii = 0 ; ii < nentA ; ii++ ) {
         jj = colmap[colindA[ii]] ;
         rowJ[2*jj]   = rowentA[2*ii]   ;
         rowJ[2*jj+1] = rowentA[2*ii+1] ;
      }
   }
}
if ( msglvl > 3 ) {
   fprintf(msgFile, "\n after assembling rows of A") ;
   A2_writeForHumanEye(frontJ, msgFile) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------
   load the updates from the children 
   ----------------------------------
*/
for ( chvI = firstchild ; chvI != NULL ; chvI = chvI->next ) {
   nrowI = chvI->nD ;
   Chv_columnIndices(chvI, &ncolI, &colindI) ;
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n loading child %d", chvI->id) ;
      fprintf(msgFile, "\n child's column indices") ;
      IVfprintf(msgFile, ncolI, colindI) ;
      Chv_writeForHumanEye(chvI, msgFile) ;
      fflush(msgFile) ;
   }
   rowI = Chv_entries(chvI) ;
   for ( irowI = 0 ; irowI < nrowI ; irowI++, jrow++ ) {
      rowJ = A2_row(frontJ, map[jrow]) ;
      if ( A2_IS_REAL(frontJ) ) {
         for ( ii = irowI ; ii < ncolI ; ii++ ) {
            jj = colindI[ii] ;
            rowJ[jj] = rowI[ii] ;
         }
         rowI += ncolI - irowI - 1 ;
      } else if ( A2_IS_COMPLEX(frontJ) ) {
         for ( ii = irowI ; ii < ncolI ; ii++ ) {
            jj = colindI[ii] ;
            rowJ[2*jj]   = rowI[2*ii]   ;
            rowJ[2*jj+1] = rowI[2*ii+1] ;
         }
         rowI += 2*(ncolI - irowI - 1) ;
      }
   }
   if ( msglvl > 3 ) {
      fprintf(msgFile, "\n after assembling child %d", chvI->id) ;
      A2_writeForHumanEye(frontJ, msgFile) ;
      fflush(msgFile) ;
   }
}
return(frontJ) ; }
示例#19
0
  // 2008/03/12 kazuhide nakata
void Newton::initialize_sparse_bMat(int m, IV *newToOldIV,
				    IVL *symbfacIVL)
{

  //  bMat_type = SPARSE;
  //  printf("SPARSE computation\n");

  int* newToOld;

  newToOld = IV_entries(newToOldIV);

  NewArray(ordering,int,m);
  NewArray(reverse_ordering,int,m);
  for (int i=0; i<m; i++){
    ordering[i] = newToOld[i];
  }
  for (int i=0; i<m; i++){
    reverse_ordering[ordering[i]] = i;
  }
  
  // separate front or back node
  int* counter;
  int nClique = IVL_nlist(symbfacIVL);
  int psize;
  int* pivec;
  bool* bnode;
  int* nFront;

  NewArray(counter,int ,m);
  NewArray(bnode  ,bool,m);
  NewArray(nFront ,int ,nClique);

  for (int k=0; k<m; k++){
    bnode[k] = false;
    counter[k] = -1;
  }

  // search number of front 
  for (int l=nClique-1; l >= 0; l--){
    IVL_listAndSize(symbfacIVL,l,&psize,&pivec);
    int i;
    for (i=0; i<psize; i++){
      int ii = reverse_ordering[pivec[i]];
      if (bnode[ii] == false){
        counter[ii] = psize - i;
        bnode[ii] = true;
      } else {
        nFront[l] = i;
        break;
      }
    }
    if (i == psize){
      nFront[l] = psize;
    }
  }

  // error check
  for (int k=0; k<m; k++){
    if (counter[k] == -1){ 
      rError("Newton::initialize_sparse_bMat: program bug");
    }
  }

  // make index of diagonal
  NewArray(diagonalIndex,int,m+1);
  diagonalIndex[0] = 0;
  for (int k=1; k<m+1; k++){
    diagonalIndex[k] = diagonalIndex[k-1] + counter[k-1];
  }
  
  // initialize sparse_bMat
  sparse_bMat.initialize(m,m,SparseMatrix::SPARSE,diagonalIndex[m]);
  
  // initialize index of sparse_bmat
  int nonzeros = 0;
  for (int l=0; l<nClique; l++){
    IVL_listAndSize(symbfacIVL,l,&psize,&pivec);
    for (int i=0; i<nFront[l]; i++){
      int ii = reverse_ordering[pivec[i]];
      for (int j=i; j<psize; j++){
        int jj = reverse_ordering[pivec[j]];
        int index = diagonalIndex[ii] + j - i;
        sparse_bMat.row_index[index] = ii;
        sparse_bMat.column_index[index] = jj;
        nonzeros++;
      }
    }
  }
  // error check
  if (nonzeros!= sparse_bMat.NonZeroNumber){
    rError("Newton::initialize_sparse_bMat  probram bug");
  }
  sparse_bMat.NonZeroCount = nonzeros;  
  //  sparse_bMat.display();

  DeleteArray(counter);
  DeleteArray(bnode);
  DeleteArray(nFront);
}
示例#20
0
文件: init.c 项目: bialk/SPOOLES
/*
   --------------------------------------------------------------------
   purpose -- to fill submtx with a submatrix of the front matrix.
      the fronts that form the submatrix are found in frontidsIV.

      all information in submtx is local, front #'s are from 0 to
      one less than the number of fronts in the submatrix, equation
      #'s are from 0 to one less than the number of rows and columns
      in the submatrix. the global row and column ids for the submatrix
      are stored in rowsIV and colsIV on return.

   return values ---
      1 -- normal return
     -1 -- submtx is NULL
     -2 -- frontmtx is NULL
     -3 -- frontmtx is not in 2-D mode
     -4 -- frontidsIV is NULL
     -5 -- frontidsIV is invalid
     -6 -- rowsIV is NULL
     -7 -- colsIV is NULL
     -8 -- unable to create front tree
     -9 -- unable to create symbfacIVL
    -10 -- unable to create coladjIVL
    -11 -- unable to create rowadjIVL
    -12 -- unable to create upperblockIVL
    -13 -- unable to create lowerblockIVL

   created -- 98oct17, cca
   --------------------------------------------------------------------
*/
int
FrontMtx_initFromSubmatrix (
   FrontMtx   *submtx,
   FrontMtx   *frontmtx,
   IV         *frontidsIV,
   IV         *rowsIV,
   IV         *colsIV,
   int        msglvl,
   FILE       *msgFile
) {
ETree    *etreeSub ;
int      ii, J, Jsub, K, Ksub, ncol, nfront, nfrontSub, neqnSub, nJ,
         nrow, offset, rc, size, vSub ;
int      *bndwghts, *colind, *colmap, *cols, *frontSubIds, 
         *list, *nodwghts, *rowind, *rowmap, *rows ;
IV       *frontsizesIVsub, *vtxIV ;
IVL      *coladjIVLsub, *lowerblockIVLsub, *rowadjIVLsub, 
         *symbfacIVLsub, *upperblockIVLsub ;
SubMtx   *mtx ;
/*
   ---------------
   check the input
   ---------------
*/
if ( submtx == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n submtx is NULL\n") ;
   return(-1) ;
}
if ( frontmtx == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontmtx is NULL\n") ;
   return(-2) ;
}
if ( ! FRONTMTX_IS_2D_MODE(frontmtx) ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontmtx mode is not 2D\n") ;
   return(-3) ;
}
if ( frontidsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n frontidsIV is NULL\n") ;
   return(-4) ;
}
nfront = FrontMtx_nfront(frontmtx) ;
IV_sizeAndEntries(frontidsIV, &nfrontSub, &frontSubIds) ;
if ( nfrontSub < 0 || nfrontSub > nfront ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n invalid frontidsIV"
           "\n nfrontSub = %d, nfront %d\n", nfrontSub, nfront) ;
   return(-5) ;
}
for ( ii = 0 ; ii < nfrontSub ; ii++ ) {
   if ( (J = frontSubIds[ii]) < 0 || J >= nfront ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
              "\n invalid frontidsIV"
              "\n frontSubIds[%d] = %d, nfront = %d\n",
              ii, J, nfront) ;
      return(-5) ;
   }
}
if ( rowsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n rowsIV is NULL\n") ;
   return(-6) ;
}
if ( colsIV == NULL ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n colsIV is NULL\n") ;
   return(-7) ;
}
/*--------------------------------------------------------------------*/
/*
   -----------------------------------------------------
   clear the data for the submatrix and set the 
   scalar values (some inherited from the global matrix)
   -----------------------------------------------------
*/
FrontMtx_clearData(submtx) ;
submtx->nfront       = nfrontSub ;
submtx->type         = frontmtx->type ;
submtx->symmetryflag = frontmtx->symmetryflag ;
submtx->sparsityflag = frontmtx->sparsityflag ;
submtx->pivotingflag = frontmtx->pivotingflag ;
submtx->dataMode     = FRONTMTX_2D_MODE ;
/*
   ---------------------------------------------------------------
   initialize the front tree for the submatrix.

   note: on return, vtxIV is filled with the vertices originally
   in the submatrix, (pivoting may change this), needed to find
   symbolic factorization IVL object

   note: at return, the boundary weights are likely to be invalid,
   since we have no way of knowing what boundary indices for a
   front are really in the domain. this will be changed after we
   have the symbolic factorization.
   ---------------------------------------------------------------
*/
etreeSub = submtx->frontETree = ETree_new() ;
vtxIV = IV_new() ;
rc = ETree_initFromSubtree(etreeSub, frontidsIV, 
                           frontmtx->frontETree, vtxIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
         "\n unable to create submatrix's front ETree, rc = %d\n", rc) ;
   return(-8) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix ETree") ;
   ETree_writeForHumanEye(etreeSub, msgFile) ;
   fprintf(msgFile, "\n\n submatrix original equations") ;
   IV_writeForHumanEye(vtxIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   ------------------------------------------------------
   set the # of equations (perhap temporarily if pivoting 
   has delayed some rows and columns), and the tree.
   ------------------------------------------------------
*/
submtx->neqns = neqnSub = IV_size(vtxIV) ;
submtx->tree  = etreeSub->tree ;
/*
   -----------------------------------------------------
   initialize the symbolic factorization for the subtree
   -----------------------------------------------------
*/
symbfacIVLsub = submtx->symbfacIVL = IVL_new() ;
rc = IVL_initFromSubIVL(symbfacIVLsub, frontmtx->symbfacIVL,
                        frontidsIV, vtxIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
         "\n unable to create submatrix's symbfac, rc = %d\n", rc) ;
   return(-9) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix symbolic factorizatio") ;
   IVL_writeForHumanEye(symbfacIVLsub, msgFile) ;
   fflush(msgFile) ;
}
/*
   ---------------------------------------------
   adjust the boundary weights of the front tree
   ---------------------------------------------
*/
nodwghts = ETree_nodwghts(etreeSub) ;
bndwghts = ETree_bndwghts(etreeSub) ;
for ( J = 0 ; J < nfrontSub ; J++ ) {
   IVL_listAndSize(symbfacIVLsub, J, &size, &list) ;
   bndwghts[J] = size - nodwghts[J] ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n submatrix ETree after bndweight adjustment") ;
   ETree_writeForHumanEye(etreeSub, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------
   set the front sizes for the submatrix
   -------------------------------------
*/
frontsizesIVsub = submtx->frontsizesIV = IV_new() ;
IV_init(frontsizesIVsub, nfrontSub, NULL) ;
IVgather(nfrontSub, IV_entries(frontsizesIVsub), 
         IV_entries(frontmtx->frontsizesIV),
         IV_entries(frontidsIV)) ;
neqnSub = submtx->neqns = IV_sum(frontsizesIVsub) ;
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n %d equations in submatrix", neqnSub) ;
   fprintf(msgFile, "\n\n front sizes for submatrix") ;
   IV_writeForHumanEye(frontsizesIVsub, msgFile) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------------------------------------
   fill rowsIV and colsIV with the row and column ids of the submatrix
   -------------------------------------------------------------------
*/
IV_setSize(rowsIV, neqnSub) ;
IV_setSize(colsIV, neqnSub) ;
rows = IV_entries(rowsIV) ;
cols = IV_entries(colsIV) ;
for ( Jsub = offset = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   if ( (nJ = FrontMtx_frontSize(submtx, Jsub)) > 0 ) {
      J = frontSubIds[Jsub] ;
      FrontMtx_columnIndices(frontmtx, J, &size, &list) ;
      IVcopy(nJ, cols + offset, list) ;
      FrontMtx_rowIndices(frontmtx, J, &size, &list) ;
      IVcopy(nJ, rows + offset, list) ;
      offset += nJ ;
   }
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n row ids for submatrix") ;
   IV_writeForHumanEye(rowsIV, msgFile) ;
   fprintf(msgFile, "\n\n column ids for submatrix") ;
   IV_writeForHumanEye(colsIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------
   get the row and column adjacencies
   ----------------------------------
*/
if ( FRONTMTX_IS_PIVOTING(frontmtx) ) {
   submtx->neqns = neqnSub ;
   coladjIVLsub  = submtx->coladjIVL = IVL_new() ;
   rc = IVL_initFromSubIVL(coladjIVLsub, frontmtx->coladjIVL,
                           frontidsIV, colsIV) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create submatrix's coladjIVL, rc = %d\n", rc) ;
      return(-10) ;
   }
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n submatrix col adjacency") ;
      IVL_writeForHumanEye(coladjIVLsub, msgFile) ;
      fflush(msgFile) ;
   }
   if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
      rowadjIVLsub = submtx->rowadjIVL = IVL_new() ;
      rc = IVL_initFromSubIVL(rowadjIVLsub, frontmtx->rowadjIVL,
                              frontidsIV, rowsIV) ;
      if ( rc != 1 ) {
         fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create submatrix's rowadjIVL, rc = %d\n", rc) ;
         return(-11) ;
      }
      if ( msglvl > 4 ) {
         fprintf(msgFile, "\n\n submatrix row adjacency") ;
         IVL_writeForHumanEye(rowadjIVLsub, msgFile) ;
         fflush(msgFile) ;
      }
   }
}
IV_free(vtxIV) ;
/*
   ----------------------------------------------
   get the rowmap[] and colmap[] vectors,
   needed to translate indices in the submatrices
   ----------------------------------------------
*/
colmap = IVinit(frontmtx->neqns, -1) ;
for ( ii = 0 ; ii < neqnSub ; ii++ ) {
   colmap[cols[ii]] = ii ;
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   rowmap = IVinit(frontmtx->neqns, -1) ;
   for ( ii = 0 ; ii < neqnSub ; ii++ ) {
      rowmap[rows[ii]] = ii ;
   }
} else {
   rowmap = colmap ;
}
/*
   -----------------------------------------------------------
   get the upper and lower block IVL objects for the submatrix
   -----------------------------------------------------------
*/
upperblockIVLsub = submtx->upperblockIVL = IVL_new() ;
rc = IVL_initFromSubIVL(upperblockIVLsub, frontmtx->upperblockIVL,
                        frontidsIV, frontidsIV) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
        "\n unable to create upperblockIVL, rc = %d\n", rc) ;
   return(-12) ;
}
if ( msglvl > 4 ) {
   fprintf(msgFile, "\n\n upper block adjacency IVL object") ;
   IVL_writeForHumanEye(upperblockIVLsub, msgFile) ;
   fflush(msgFile) ;
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   lowerblockIVLsub = submtx->lowerblockIVL = IVL_new() ;
   rc = IVL_initFromSubIVL(lowerblockIVLsub, frontmtx->lowerblockIVL,
                           frontidsIV, frontidsIV) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in FrontMtx_initFromSubmatrix()"
           "\n unable to create lowerblockIVL, rc = %d\n", rc) ;
      return(-13) ;
   }
   if ( msglvl > 4 ) {
      fprintf(msgFile, "\n\n lower block adjacency IVL object") ;
      IVL_writeForHumanEye(lowerblockIVLsub, msgFile) ;
      fflush(msgFile) ;
   }
}
/*
   ----------------------------------------------------------------
   allocate the vector and hash table(s) for the factor submatrices
   ----------------------------------------------------------------
*/
ALLOCATE(submtx->p_mtxDJJ, struct _SubMtx *, nfrontSub) ;
for ( J = 0 ; J < nfrontSub ; J++ ) {
   submtx->p_mtxDJJ[J] = NULL ;
}
submtx->upperhash = I2Ohash_new() ;
I2Ohash_init(submtx->upperhash, nfrontSub, nfrontSub, nfrontSub) ;
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   submtx->lowerhash = I2Ohash_new() ;
   I2Ohash_init(submtx->lowerhash, nfrontSub, nfrontSub, nfrontSub) ;
}
/*
   -----------------------------------------------------------------
   remove the diagonal submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values, and the row and column
   indices must be mapped to local indices.
   -----------------------------------------------------------------
*/
for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   J = frontSubIds[Jsub] ;
   if ( (mtx = frontmtx->p_mtxDJJ[J]) != NULL ) {
      SubMtx_setIds(mtx, Jsub, Jsub) ;
      SubMtx_columnIndices(mtx, &ncol, &colind) ;
      IVgather(ncol, colind, colmap, colind) ;
      SubMtx_rowIndices(mtx, &nrow, &rowind) ;
      IVgather(nrow, rowind, rowmap, rowind) ;
      submtx->p_mtxDJJ[Jsub] = mtx ;
      frontmtx->p_mtxDJJ[J]  = NULL ;
      submtx->nentD += mtx->nent ;
   }
}
/*
   ----------------------------------------------------------------
   remove the upper triangular submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values. if the matrix is on
   the diagonal, i.e., U(J,J), its row and column indices must be 
   mapped to local indices.
   ----------------------------------------------------------------
*/
for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
   J = frontSubIds[Jsub] ;
   FrontMtx_upperAdjFronts(submtx, Jsub, &size, &list) ;
   for ( ii = 0 ; ii < size ; ii++ ) {
      Ksub = list[ii] ;
      K = frontSubIds[Ksub] ;
      if ( 1 == I2Ohash_remove(frontmtx->upperhash, 
                               J, K, (void *) &mtx) ) {
         SubMtx_setIds(mtx, Jsub, Ksub) ;
         if ( K == J ) {
            SubMtx_columnIndices(mtx, &ncol, &colind) ;
            IVgather(ncol, colind, colmap, colind) ;
            SubMtx_rowIndices(mtx, &nrow, &rowind) ;
            IVgather(nrow, rowind, rowmap, rowind) ;
         }
         I2Ohash_insert(submtx->upperhash, Jsub, Ksub, (void *) mtx) ;
         submtx->nentU += mtx->nent ;
      }
   }
}
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
/*
   ----------------------------------------------------------------
   remove the lower triangular submatrices from the factor matrix
   and insert into the submatrix object. note: front row and column
   ids must be changed to their local values. if the matrix is on
   the diagonal, i.e., L(J,J), its row and column indices must be 
   mapped to local indices.
   ----------------------------------------------------------------
*/
   for ( Jsub = 0 ; Jsub < nfrontSub ; Jsub++ ) {
      J = frontSubIds[Jsub] ;
      FrontMtx_lowerAdjFronts(submtx, Jsub, &size, &list) ;
      for ( ii = 0 ; ii < size ; ii++ ) {
         Ksub = list[ii] ;
         K = frontSubIds[Ksub] ;
         if ( 1 == I2Ohash_remove(frontmtx->lowerhash, 
                                  K, J, (void *) &mtx) ) {
            SubMtx_setIds(mtx, Ksub, Jsub) ;
            if ( K == J ) {
               SubMtx_columnIndices(mtx, &ncol, &colind) ;
               IVgather(ncol, colind, colmap, colind) ;
               SubMtx_rowIndices(mtx, &nrow, &rowind) ;
               IVgather(nrow, rowind, rowmap, rowind) ;
            }
            I2Ohash_insert(submtx->lowerhash, Ksub, Jsub, (void *) mtx);
            submtx->nentL += mtx->nent ;
         }
      }
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(colmap) ;
if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) {
   IVfree(rowmap) ;
}
return(1) ; }
示例#21
0
/*
   -------------------------------------------------------------
   purpose -- 

   the IVL object ivl and IV object ownersIV are both found on 
   each process.  the ownersIV object is identical over all the 
   processes, and owners[ii] tells which processes owns list ii 
   of the ivl object. on return from this method, the ivl object 
   is replicated over all the processes. each process sends 
   the lists that it owns to all the other processes.

   created -- 98apr03, cca
   -------------------------------------------------------------
*/
void
IVL_MPI_allgather (
   IVL        *ivl,
   IV         *ownersIV,
   int        stats[],
   int        msglvl,
   FILE       *msgFile,
   int        firsttag,
   MPI_Comm   comm
) {
int          count, destination, ii, ilist, incount, jlist, 
             jproc, left, maxcount, myid, nlist, nmylists, 
             notherlists, nowners, nproc, offset, outcount, 
             right, size, source, tag ;
int          *counts, *inbuffer, *list, *outbuffer, *owners ;
MPI_Status   status ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || ownersIV == NULL ) {
   fprintf(stderr, "\n fatal error in IVL_MPI_allgather()"
           "\n ivl = %p, ownersIV = %p\n",
           ivl, ownersIV) ;
   exit(-1) ;
}
/*
   ----------------------------------------------
   get id of self, # of processes and # of fronts
   ----------------------------------------------
*/
MPI_Comm_rank(comm, &myid) ;
MPI_Comm_size(comm, &nproc) ;
nlist = ivl->nlist ;
IV_sizeAndEntries(ownersIV, &nowners, &owners) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n\n inside IVL_MPI_allgather()"
           "\n nproc = %d, myid = %d, nlist = %d, nowners = %d",
           nproc, myid, nlist, nowners) ;
   fflush(msgFile) ;
}
if ( nlist != nowners || owners == NULL ) {
   fprintf(stderr, "\n fatal error in IVL_MPI_allgather()"
           "\n nlist = %d, nowners = %d, owners = %p\n",
           nlist, nowners, owners) ;
   exit(-1) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n ivl") ;
   IVL_writeForHumanEye(ivl, msgFile) ;
   fprintf(msgFile, "\n\n ownersIV") ;
   IV_writeForHumanEye(ownersIV, msgFile) ;
   fflush(msgFile) ;
}
/*
   -----------------------------------------------
   step 1 : determine the size of the message that
            this process will send to the others
   -----------------------------------------------
*/
for ( ilist = 0, outcount = 1 ; ilist < nlist ; ilist++ ) {
   if ( owners[ilist] < 0 || owners[ilist] >= nproc ) {
      fprintf(stderr, "\n owners[%d] = %d", ilist, owners[ilist]) ;
      exit(-1) ;
   }
   if ( owners[ilist] == myid ) {
      outcount += 2 ;
      IVL_listAndSize(ivl, ilist, &size, &list) ;
      outcount += size ;
   }
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n outcount = %d", outcount) ;
   fflush(msgFile) ;
}
/*
   ----------------------------------------------------
   do an all-to-all gather/scatter
   counts[jproc] = # of int's in the message from jproc
   ----------------------------------------------------
*/
counts = IVinit(nproc, 0) ;
counts[myid] = outcount ;
MPI_Allgather((void *) &counts[myid], 1, MPI_INT,
              (void *) counts,  1, MPI_INT, comm) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n\n counts") ;
   IVfprintf(msgFile, nproc, counts) ;
   fflush(msgFile) ;
}
/*
   -----------------------------
   set up the in and out buffers
   -----------------------------
*/
if ( outcount > 0 ) {
   outbuffer = IVinit(outcount, -1) ;
   for ( ilist = nmylists = 0, ii = 1 ; ilist < nlist ; ilist++ ) {
      if ( owners[ilist] == myid ) {
         nmylists++ ;
         IVL_listAndSize(ivl, ilist, &size, &list) ;
         outbuffer[ii++] = ilist ;
         outbuffer[ii++] = size  ;
         if ( size > 0 ) {
            IVcopy(size, &outbuffer[ii], list) ;
            ii += size ;
         }
      }
   }
   outbuffer[0] = nmylists ;
   if ( ii != outcount ) {
      fprintf(stderr, "\n myid = %d, ii = %d, outcount = %d",
              myid, ii, outcount) ;
      fprintf(msgFile, "\n myid = %d, ii = %d, outcount = %d",
              myid, ii, outcount) ;
      exit(-1) ;
   }
} else {
   outbuffer = NULL ;
}
maxcount = IVmax(nproc, counts, &jproc) ;
if ( maxcount > 0 ) {
   inbuffer = IVinit(maxcount, -1) ;
} else {
   inbuffer = NULL ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n outbuffer %p, maxcount %d, inbuffer %p",
           outbuffer, maxcount, inbuffer) ;
   fflush(msgFile) ;
}
/*
   -------------------------------------
   step 2: loop over the other processes
      send and receive information
   -------------------------------------
*/
for ( offset = 1, tag = firsttag ; offset < nproc ; offset++, tag++ ) {
   right = (myid + offset) % nproc ;
   if ( offset <= myid ) {
      left = myid - offset ;
   } else {
      left = nproc + myid - offset ;
   }
   if ( outcount > 0 ) {
      destination = right ;
      stats[0]++ ;
      stats[2] += outcount*sizeof(int) ;
   } else {
      destination = MPI_PROC_NULL ;
   }
   incount = counts[left] ;
   if ( incount > 0 ) {
      source = left ;
      stats[1]++ ;
      stats[3] += incount*sizeof(int) ;
   } else {
      source = MPI_PROC_NULL ;
   }
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n offset %d, source %d, destination %d",
              offset, source, destination) ;
      fflush(msgFile) ;
   }
/*
   -----------------
   do a send/receive
   -----------------
*/
   MPI_Sendrecv(outbuffer, outcount, MPI_INT, destination, tag,
                inbuffer,  incount,  MPI_INT, source,      tag,
                comm, &status) ;
   if ( source != MPI_PROC_NULL ) {
      MPI_Get_count(&status, MPI_INT, &count) ;
      if ( count != incount ) {
         fprintf(stderr,
                 "\n 1. fatal error in IVL_MPI_allgather()"
                 "\n proc %d : source = %d, count = %d, incount = %d\n",
                 myid, source, count, incount) ;
         exit(-1) ;
      }
   }
/*
   ----------------------------
   set the values in the vector
   ----------------------------
*/
   notherlists = inbuffer[0] ;
   for ( ilist = 0, ii = 1 ; ilist < notherlists ; ilist++ ) {
      jlist = inbuffer[ii++] ;
      size  = inbuffer[ii++] ;
      if ( size > 0 ) {
         IVL_setList(ivl, jlist, size, &inbuffer[ii]) ;
         ii += size ;
      }
   }
   if ( ii != incount ) {
      fprintf(msgFile, "\n ii = %d, incount = %d", ii, incount) ;
      fprintf(stderr, "\n ii = %d, incount = %d", ii, incount) ;
      exit(-1) ;
   }
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n after setting values") ;
      IVL_writeForHumanEye(ivl, msgFile) ;
      fflush(msgFile) ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
IVfree(counts) ;
if ( outbuffer != NULL ) {
   IVfree(outbuffer) ;
}
if ( inbuffer != NULL ) {
   IVfree(inbuffer) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n leaving IVL_MPI_gatherall()") ;
   fflush(msgFile) ;
}
return ; }
示例#22
0
/*
   -------------------------------------------------------------------
   purpose -- take an adjacency structure in the
              (offsets[neqns+1], adjncy[*]) form
              and load the Graph object

   g -- pointer to Graph object, must be initialized with nvtx = neqns
   neqns -- # of equations
   offsets -- offsets vector
   adjncy  -- big adjacency vector
      note, the adjacency for list v is found in
            adjncy[offsets[v]:offsets[v+1]-1]
      also note, offsets[] and adjncy[] must be zero based,
      if (offsets,adjncy) come from a harwell-boeing file, they use
      the fortran numbering, so each value must be decremented to
      conform with C's zero based numbering
   flag -- task flag
      flag = 0 --> just set the adjacency list for v to be that
                   found in adjncy[offsets[v]:offsets[v+1]-1]
      flag = 1 --> the input adjancency is just the upper triangle
                   (or strict upper triangle) as from a harwell-boeing
                   file. fill the Graph object with the full adjacency 
                   structure, including (v,v) edges

   created -- 96mar16, cca
   -------------------------------------------------------------------
*/
void
Graph_fillFromOffsets (
   Graph   *g,
   int     neqns,
   int     offsets[],
   int     adjncy[],
   int     flag
) {
IVL   *adjIVL ;
/*
   ---------------
   check the input
   ---------------
*/
if (  g == NULL 
   || neqns <= 0
   || offsets == NULL
   || adjncy == NULL
   || flag < 0
   || flag > 1 ) {
   fprintf(stderr, 
           "\n fatal error in Graph_fillFromOffsets(%p,%d,%p,%p,%d)"
           "\n bad input\n", g, neqns, offsets, adjncy, flag) ;
   exit(-1) ;
}
/*
   ---------------------------
   initialize the Graph object
   ---------------------------
*/
Graph_init1(g, 0, neqns, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ;
adjIVL = g->adjIVL ;
if ( flag == 0 ) {
   int   count, ii, nedge, v, w ;
   int   *list, *mark ;
/*
   ----------------------------------------------
   simple map, do not enforce symmetric structure
   ----------------------------------------------
*/
   list = IVinit(neqns, -1) ;
   mark = IVinit(neqns, -1) ;
   for ( v = 0, nedge = 0 ; v < neqns ; v++ ) {
      count = 0 ;
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
         w = adjncy[ii] ;
if ( v == neqns ) {
   fprintf(stdout, "\n hey there!! (v,w) = (%d,%d)", v, w) ;
}
         if ( 0 <= w && w < neqns && mark[w] != v ) {
            list[count++] = w ;
            mark[w] = v ;
         }
      }
      if ( mark[v] != v ) {
         list[count++] = v ;
         mark[v] = v ;
      }
      IVqsortUp(count, list) ;
      IVL_setList(adjIVL, v, count, list) ;
      nedge += count ;
   }
   g->totvwght = neqns ;
   g->totewght = g->nedges = nedge ;
/*
   ----------------------------
   now free the working storage
   ----------------------------
*/
   IVfree(list) ;
   IVfree(mark) ;
} else {
   int   ii, jj, u, v, vsize, w ;
   int   *head, *link, *list, *sizes, *vadj ;
   int   **p_adj ;
/*
   -------------------------------------------
   enforce symmetric structure and (v,v) edges
   make a first pass to check the input
   -------------------------------------------
*/
fprintf(stdout, "\n offsets") ;
IVfprintf(stdout, neqns+1, offsets) ;
   for ( v = 0 ; v < neqns ; v++ ) {
fprintf(stdout, "\n v = %d", v) ;
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
fprintf(stdout, "\n    w = %d", adjncy[ii]) ;
         if ( (w = adjncy[ii]) < v || neqns <= w ) {
            fprintf(stderr, 
               "\n fatal error in Graph_fillFromOffsets(%p,%d,%p,%p,%d)"
               "\n list %d, entry %d\n", g, neqns, offsets, adjncy,
               flag, v, w) ;
            exit(-1) ;
         }
      }
   }
   head  = IVinit(neqns, -1) ;
   link  = IVinit(neqns, -1) ;
   list  = IVinit(neqns, -1) ;
   sizes = IVinit(neqns, 0) ;
   p_adj = PIVinit(neqns) ;
   for ( v = 0 ; v < neqns ; v++ ) {
      vsize = 0 ;
/*
      -------------------------
      add edges to vertices < v
      -------------------------
*/
      while ( (u = head[v]) != -1 ) {
         head[v] = link[u] ;
         list[vsize++] = u ;
         if ( --sizes[u] > 0 ) {
            w = *(++p_adj[u]) ;
            link[u] = head[w] ;
            head[w] = u ;
         }
      }
/*
      -----------------
      add in edge (v,v)
      -----------------
*/
      list[vsize++] = v ;
      jj = vsize ;
/*
      -------------------------
      add edges to vertices > v
      -------------------------
*/
      for ( ii = offsets[v] ; ii < offsets[v+1] ; ii++ ) {
         if ( (w = adjncy[ii]) != v ) {
            list[vsize++] = w ;
         }
      }
/*
      ---------------------
      sort and set the list
      ---------------------
*/
      IVqsortUp(vsize, list) ;
      IVL_setList(adjIVL, v, vsize, list) ;
/*
      --------------------------------------------------
      link v to first vertex in its lists greater than v
      --------------------------------------------------
*/
      if ( jj < vsize ) {
         IVL_listAndSize(adjIVL, v, &vsize, &vadj) ;
         w        = vadj[jj]   ;
         link[v]  = head[w]    ;
         head[w]  = v          ;
         sizes[v] = vsize - jj ;
         p_adj[v] = &vadj[jj]  ;
      }
      g->nedges += vsize ;
   }
   g->totvwght = neqns     ;
   g->totewght = g->nedges ;
/*
   ----------------------------
   now free the working storage
   ----------------------------
*/
   IVfree(head)   ;
   IVfree(link)   ;
   IVfree(list)   ;
   IVfree(sizes)  ;
   PIVfree(p_adj) ;
}
return ; }
示例#23
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   --------------------------------------------------------------------
   this program tests the Graph_MPI_Bcast() method

   (1) process root generates a random Graph object
       and computes its checksum
   (2) process root broadcasts the Graph object to the other processors
   (3) each process computes the checksum of its Graph object
   (4) the checksums are compared on root

   created -- 98sep10, cca
   --------------------------------------------------------------------
*/
{
char         *buffer ;
double       chksum, t1, t2 ;
double       *sums ;
Drand        drand ;
int          iproc, length, loc, msglvl, myid, nitem, nproc, 
             nvtx, root, seed, size, type, v ;
int          *list ;
FILE         *msgFile ;
Graph        *graph ;
/*
   ---------------------------------------------------------------
   find out the identity of this process and the number of process
   ---------------------------------------------------------------
*/
MPI_Init(&argc, &argv) ;
MPI_Comm_rank(MPI_COMM_WORLD, &myid) ;
MPI_Comm_size(MPI_COMM_WORLD, &nproc) ;
fprintf(stdout, "\n process %d of %d, argc = %d", myid, nproc, argc) ;
fflush(stdout) ;
if ( argc != 8 ) {
   fprintf(stdout, 
           "\n\n usage : %s msglvl msgFile type nvtx nitem root seed "
           "\n    msglvl      -- message level"
           "\n    msgFile     -- message file"
           "\n    type        -- type of graph"
           "\n    nvtx        -- # of vertices"
           "\n    nitem       -- # of items used to generate graph"
           "\n    root        -- root processor for broadcast"
           "\n    seed        -- random number seed"
           "\n", argv[0]) ;
   return(0) ;
}
msglvl = atoi(argv[1]) ;
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else {
   length = strlen(argv[2]) + 1 + 4 ;
   buffer = CVinit(length, '\0') ;
   sprintf(buffer, "%s.%d", argv[2], myid) ;
   if ( (msgFile = fopen(buffer, "w")) == NULL ) {
      fprintf(stderr, "\n fatal error in %s"
              "\n unable to open file %s\n",
              argv[0], argv[2]) ;
      return(-1) ;
   }
   CVfree(buffer) ;
}
type  = atoi(argv[3]) ;
nvtx  = atoi(argv[4]) ;
nitem = atoi(argv[5]) ;
root  = atoi(argv[6]) ;
seed  = atoi(argv[7]) ;
fprintf(msgFile, 
        "\n %s "
        "\n msglvl  -- %d" 
        "\n msgFile -- %s" 
        "\n type    -- %d" 
        "\n nvtx    -- %d" 
        "\n nitem   -- %d" 
        "\n root    -- %d" 
        "\n seed    -- %d" 
        "\n",
        argv[0], msglvl, argv[2], type, nvtx, nitem, root, seed) ;
fflush(msgFile) ;
/*
   -----------------------
   set up the Graph object
   -----------------------
*/
MARKTIME(t1) ;
graph = Graph_new() ;
if ( myid == root ) {
   InpMtx   *inpmtx ;
   int      nedges, totewght, totvwght, v ;
   int      *adj, *vwghts ;
   IVL      *adjIVL, *ewghtIVL ;
/*
   -----------------------
   generate a random graph
   -----------------------
*/
   inpmtx = InpMtx_new() ;
   InpMtx_init(inpmtx, INPMTX_BY_ROWS, INPMTX_INDICES_ONLY, nitem, 0) ;
   Drand_setDefaultFields(&drand) ;
   Drand_setSeed(&drand, seed) ;
   Drand_setUniform(&drand, 0, nvtx) ;
   Drand_fillIvector(&drand, nitem, InpMtx_ivec1(inpmtx)) ;
   Drand_fillIvector(&drand, nitem, InpMtx_ivec2(inpmtx)) ;
   InpMtx_setNent(inpmtx, nitem) ;
   InpMtx_changeStorageMode(inpmtx, INPMTX_BY_VECTORS) ;
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n inpmtx mtx filled with raw entries") ;
      InpMtx_writeForHumanEye(inpmtx, msgFile) ;
      fflush(msgFile) ;
   }
   adjIVL = InpMtx_fullAdjacency(inpmtx) ;
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n full adjacency structure") ;
      IVL_writeForHumanEye(adjIVL, msgFile) ;
      fflush(msgFile) ;
   }
   nedges = adjIVL->tsize ;
   if ( type == 1 || type == 3 ) {
      Drand_setUniform(&drand, 1, 10) ;
      vwghts = IVinit(nvtx, 0) ;
      Drand_fillIvector(&drand, nvtx, vwghts) ;
      totvwght = IVsum(nvtx, vwghts) ;
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n\n vertex weights") ;
         IVfprintf(msgFile, nvtx, vwghts) ;
         fflush(msgFile) ;
      }
   } else {
      vwghts = NULL ;
      totvwght = nvtx ;
   }
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n totvwght %d", totvwght) ;
      fflush(msgFile) ;
   }
   if ( type == 2 || type == 3 ) {
      ewghtIVL = IVL_new() ;
      IVL_init1(ewghtIVL, IVL_CHUNKED, nvtx) ;
      Drand_setUniform(&drand, 1, 100) ;
      totewght = 0 ;
      for ( v = 0 ; v < nvtx ; v++ ) {
         IVL_listAndSize(adjIVL, v, &size, &adj) ;
         IVL_setList(ewghtIVL, v, size, NULL) ;
         IVL_listAndSize(ewghtIVL, v, &size, &adj) ;
         Drand_fillIvector(&drand, size, adj) ;
         totewght += IVsum(size, adj) ;
      }
      if ( msglvl > 2 ) {
         fprintf(msgFile, "\n\n ewghtIVL") ;
         IVL_writeForHumanEye(ewghtIVL, msgFile) ;
         fflush(msgFile) ;
      }
   } else {
      ewghtIVL = NULL ;
      totewght = nedges ;
   }
   if ( msglvl > 2 ) {
      fprintf(msgFile, "\n\n totewght %d", totewght) ;
      fflush(msgFile) ;
   }
   Graph_init2(graph, type, nvtx, 0, nedges, totvwght, totewght,
               adjIVL, vwghts, ewghtIVL) ;
   InpMtx_free(inpmtx) ;
}
MARKTIME(t2) ;
fprintf(msgFile, 
        "\n CPU %8.3f : initialize the Graph object", t2 - t1) ;
fflush(msgFile) ;
if ( msglvl > 2 ) {
   Graph_writeForHumanEye(graph, msgFile) ;
} else {
   Graph_writeStats(graph, msgFile) ;
}
fflush(msgFile) ;
if ( myid == root ) {
/*
   ----------------------------------------
   compute the checksum of the Graph object
   ----------------------------------------
*/
   chksum = graph->type + graph->nvtx + graph->nvbnd 
          + graph->nedges + graph->totvwght + graph->totewght ;
   for ( v = 0 ; v < nvtx ; v++ ) {
      IVL_listAndSize(graph->adjIVL, v, &size, &list) ;
      chksum += 1 + v + size + IVsum(size, list) ;
   }
   if ( graph->vwghts != NULL ) {
      chksum += IVsum(nvtx, graph->vwghts) ;
   }
   if ( graph->ewghtIVL != NULL ) {
      for ( v = 0 ; v < nvtx ; v++ ) {
         IVL_listAndSize(graph->ewghtIVL, v, &size, &list) ;
         chksum += 1 + v + size + IVsum(size, list) ;
      }
   }
   fprintf(msgFile, "\n\n local chksum = %12.4e", chksum) ;
   fflush(msgFile) ;
}
/*
   --------------------------
   broadcast the Graph object
   --------------------------
*/
MARKTIME(t1) ;
graph = Graph_MPI_Bcast(graph, root, msglvl, msgFile, MPI_COMM_WORLD) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %8.3f : broadcast the Graph object", t2 - t1) ;
if ( msglvl > 2 ) {
   Graph_writeForHumanEye(graph, msgFile) ;
} else {
   Graph_writeStats(graph, msgFile) ;
}
/*
   ----------------------------------------
   compute the checksum of the Graph object
   ----------------------------------------
*/
chksum = graph->type + graph->nvtx + graph->nvbnd 
       + graph->nedges + graph->totvwght + graph->totewght ;
for ( v = 0 ; v < nvtx ; v++ ) {
   IVL_listAndSize(graph->adjIVL, v, &size, &list) ;
   chksum += 1 + v + size + IVsum(size, list) ;
}
if ( graph->vwghts != NULL ) {
   chksum += IVsum(nvtx, graph->vwghts) ;
}
if ( graph->ewghtIVL != NULL ) {
   for ( v = 0 ; v < nvtx ; v++ ) {
      IVL_listAndSize(graph->ewghtIVL, v, &size, &list) ;
      chksum += 1 + v + size + IVsum(size, list) ;
   }
}
fprintf(msgFile, "\n\n local chksum = %12.4e", chksum) ;
fflush(msgFile) ;
/*
   ---------------------------------------
   gather the checksums from the processes
   ---------------------------------------
*/
sums = DVinit(nproc, 0.0) ;
MPI_Gather((void *) &chksum, 1, MPI_DOUBLE, 
           (void *) sums, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD) ;
if ( myid == 0 ) {
   fprintf(msgFile, "\n\n sums") ;
   DVfprintf(msgFile, nproc, sums) ;
   for ( iproc = 0 ; iproc < nproc ; iproc++ ) {
      sums[iproc] -= chksum ;
   }
   fprintf(msgFile, "\n\n errors") ;
   DVfprintf(msgFile, nproc, sums) ;
   fprintf(msgFile, "\n\n maxerror = %12.4e", DVmax(nproc, sums, &loc));
}
/*
   ----------------
   free the objects
   ----------------
*/
DVfree(sums) ;
Graph_free(graph) ;
/*
   ------------------------
   exit the MPI environment
   ------------------------
*/
MPI_Finalize() ;

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

return(0) ; }
示例#24
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   -------------------------------------------------
   this program tests the IVL_MPI_allgather() method

   (1) each process generates the same owners[n] map
   (2) each process creates an IVL object 
       and fills its owned lists with random numbers
   (3) the processes gather-all's the lists of ivl

   created -- 98apr03, cca
   -------------------------------------------------
*/
{
char         *buffer ;
double       chksum, globalsum, t1, t2 ;
Drand        drand ;
int          ilist, length, myid, msglvl, nlist, 
             nproc, rc, seed, size, tag ;
int          *list, *owners, *vec ;
int          stats[4], tstats[4] ;
IV           *ownersIV ;
IVL          *ivl ;
FILE         *msgFile ;
/*
   ---------------------------------------------------------------
   find out the identity of this process and the number of process
   ---------------------------------------------------------------
*/
MPI_Init(&argc, &argv) ;
MPI_Comm_rank(MPI_COMM_WORLD, &myid) ;
MPI_Comm_size(MPI_COMM_WORLD, &nproc) ;
fprintf(stdout, "\n process %d of %d, argc = %d", myid, nproc, argc) ;
fflush(stdout) ;
if ( argc != 5 ) {
   fprintf(stdout, 
           "\n\n usage : %s msglvl msgFile n seed "
           "\n    msglvl  -- message level"
           "\n    msgFile -- message file"
           "\n    nlist   -- number of lists in the IVL object"
           "\n    seed    -- random number seed"
           "\n", argv[0]) ;
   return(0) ;
}
msglvl = atoi(argv[1]) ;
if ( strcmp(argv[2], "stdout") == 0 ) {
   msgFile = stdout ;
} else {
   length = strlen(argv[2]) + 1 + 4 ;
   buffer = CVinit(length, '\0') ;
   sprintf(buffer, "%s.%d", argv[2], myid) ;
   if ( (msgFile = fopen(buffer, "w")) == NULL ) {
      fprintf(stderr, "\n fatal error in %s"
              "\n unable to open file %s\n",
              argv[0], argv[2]) ;
      return(-1) ;
   }
   CVfree(buffer) ;
}
nlist = atoi(argv[3]) ;
seed  = atoi(argv[4]) ;
fprintf(msgFile, 
        "\n %s "
        "\n msglvl  -- %d" 
        "\n msgFile -- %s" 
        "\n nlist   -- %d" 
        "\n seed    -- %d" 
        "\n",
        argv[0], msglvl, argv[2], nlist, seed) ;
fflush(msgFile) ;
/*
   ----------------------------
   generate the ownersIV object
   ----------------------------
*/
MARKTIME(t1) ;
ownersIV = IV_new() ;
IV_init(ownersIV, nlist, NULL) ;
owners = IV_entries(ownersIV) ;
Drand_setDefaultFields(&drand) ;
Drand_setSeed(&drand, seed) ;
Drand_setUniform(&drand, 0, nproc) ;
Drand_fillIvector(&drand, nlist, owners) ;
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %8.3f : initialize the ownersIV object",
        t2 - t1) ;
fflush(msgFile) ;
fprintf(msgFile, "\n\n ownersIV generated") ;
if ( msglvl > 2 ) {
   IV_writeForHumanEye(ownersIV, msgFile) ;
} else {
   IV_writeStats(ownersIV, msgFile) ;
}
fflush(msgFile) ;
/*
   --------------------------------------------
   set up the IVL object and fill owned entries
   --------------------------------------------
*/
MARKTIME(t1) ;
ivl = IVL_new() ;
IVL_init1(ivl, IVL_CHUNKED, nlist) ;
vec = IVinit(nlist, -1) ;
Drand_setSeed(&drand, seed + myid) ;
Drand_setUniform(&drand, 0, nlist) ;
for ( ilist = 0 ; ilist < nlist ; ilist++ ) {
   if ( owners[ilist] == myid ) {
      size = (int) Drand_value(&drand) ;
      Drand_fillIvector(&drand, size, vec) ;
      IVL_setList(ivl, ilist, size, vec) ;
   }
}
MARKTIME(t2) ;
fprintf(msgFile, "\n CPU %8.3f : initialize the IVL object",
        t2 - t1) ;
fflush(msgFile) ;
if ( msglvl > 2 ) {
   IVL_writeForHumanEye(ivl, msgFile) ;
} else {
   IVL_writeStats(ivl, msgFile) ;
}
fflush(msgFile) ;
/*
   --------------------------------------------
   compute the local checksum of the ivl object
   --------------------------------------------
*/
for ( ilist = 0, chksum = 0.0 ; ilist < nlist ; ilist++ ) {
   if ( owners[ilist] == myid ) {
      IVL_listAndSize(ivl, ilist, &size, &list) ;
      chksum += 1 + ilist + size + IVsum(size, list) ;
   }
}
fprintf(msgFile, "\n\n local partial chksum = %12.4e", chksum) ;
fflush(msgFile) ;
/*
   -----------------------
   get the global checksum
   -----------------------
*/
rc = MPI_Allreduce((void *) &chksum, (void *) &globalsum, 
                   1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD) ;
/*
   --------------------------------
   execute the all-gather operation
   --------------------------------
*/
tag = 47 ;
IVzero(4, stats) ;
IVL_MPI_allgather(ivl, ownersIV, 
                  stats, msglvl, msgFile, tag, MPI_COMM_WORLD) ;
if ( msglvl > 0 ) {
   fprintf(msgFile, "\n\n return from IVL_MPI_allgather()") ;
   fprintf(msgFile, 
           "\n local send stats : %10d messages with %10d bytes"
           "\n local recv stats : %10d messages with %10d bytes",
           stats[0], stats[2], stats[1], stats[3]) ;
   fflush(msgFile) ;
}
MPI_Reduce((void *) stats, (void *) tstats, 4, MPI_INT,
          MPI_SUM, 0, MPI_COMM_WORLD) ;
if ( myid == 0 ) {
   fprintf(msgFile, 
           "\n total send stats : %10d messages with %10d bytes"
           "\n total recv stats : %10d messages with %10d bytes",
           tstats[0], tstats[2], tstats[1], tstats[3]) ;
   fflush(msgFile) ;
}
if ( msglvl > 2 ) {
   fprintf(msgFile, "\n\n ivl") ;
   IVL_writeForHumanEye(ivl, msgFile) ;
   fflush(msgFile) ;
}
/*
   -----------------------------------------
   compute the checksum of the entire object
   -----------------------------------------
*/
for ( ilist = 0, chksum = 0.0 ; ilist < nlist ; ilist++ ) {
   IVL_listAndSize(ivl, ilist, &size, &list) ;
   chksum += 1 + ilist + size + IVsum(size, list) ;
}
fprintf(msgFile, 
        "\n globalsum = %12.4e, chksum = %12.4e, error = %12.4e",
        globalsum, chksum, fabs(globalsum - chksum)) ;
fflush(msgFile) ;
/*
   ----------------
   free the objects
   ----------------
*/
IV_free(ownersIV) ;
IVL_free(ivl) ;
/*
   ------------------------
   exit the MPI environment
   ------------------------
*/
MPI_Finalize() ;

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

return(0) ; }
示例#25
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 ; }
示例#26
0
文件: storage.c 项目: bialk/SPOOLES
/*
   ---------------------------------------------------------------
   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 ; }