Beispiel #1
0
/*
   -----------------------------------------------------------
   purpose -- to write out the statistics for the Graph object

   return value -- 1 if success, 0 otherwise

   created -- 95sep29, cca
   -----------------------------------------------------------
*/
int
Graph_writeStats ( 
   Graph    *graph, 
   FILE   *fp 
) {
int   rc ;
/*
   ---------------
   check the input
   ---------------
*/
if ( graph == NULL || fp == NULL ) {
   fprintf(stderr, "\n error in Graph_writeStats(%p,%p)"
           "\n bad input\n", graph, fp) ;
   spoolesFatal();
}
switch ( graph->type ) {
case 0 : 
   rc = fprintf(fp, "\n Graph : unweighted graph object :") ;
   break ;
case 1 : 
   rc = fprintf(fp, "\n Graph : vertices weighted graph object :") ;
   break ;
case 2 : 
   rc = fprintf(fp, "\n Graph : edges weighted graph object :") ;
   break ;
case 3 : 
   rc = fprintf(fp, 
            "\n Graph : vertices and edges weighted graph object :") ;
   break ;
default :
   fprintf(stderr, "\n fatal error in Graph_writeStats(%p,%p)"
           "\n invalid graph->type = %d\n", graph, fp, graph->type) ;
   return(0) ;
}
if ( rc < 0 ) { goto IO_error ; }
fflush(fp) ;
rc = fprintf(fp, 
             "\n %d internal vertices, %d boundary vertices, %d edges",
             graph->nvtx, graph->nvbnd, graph->nedges) ;
if ( rc < 0 ) { goto IO_error ; }
fflush(fp) ;
rc = fprintf(fp, 
             "\n %d internal vertex weight, %d boundary vertex weight",
(graph->vwghts != NULL) ? IVsum(graph->nvtx, graph->vwghts) : graph->nvtx,
(graph->vwghts != NULL) ? IVsum(graph->nvbnd, graph->vwghts + graph->nvtx) : graph->nvbnd) ;
if ( rc < 0 ) { goto IO_error ; }
if ( graph->type >= 2 ) {
   rc = fprintf(fp, "\n %d total edge weight",
                graph->totewght) ;
}
if ( rc < 0 ) { goto IO_error ; }

return(1) ;

IO_error :
   fprintf(stderr, "\n fatal error in Graph_writeStats(%p,%p)"
           "\n rc = %d, return from fprintf\n", graph, fp, rc) ;
   return(0) ;
}
Beispiel #2
0
/*
   -----------------------
   initialize the object

   created -- 95oct07, cca
   -----------------------
*/
void
BKL_init (
   BKL     *bkl,
   BPG     *bpg,
   float   alpha
) {
/*
   ---------------
   check the input
   ---------------
*/
if ( bkl == NULL || bpg == NULL ) {
   fprintf(stderr, "\n fatal error in BKL_init(%p,%p,%f)"
           "\n bad input\n", bkl, bpg, alpha) ;
   exit(-1) ;
}
/*
   --------------
   clear the data
   --------------
*/
BKL_clearData(bkl) ;
/*
   ---------------------
   initialize the fields
   ---------------------
*/
bkl->bpg  = bpg ;
bkl->ndom = bpg->nX ;
bkl->nseg = bpg->nY ;
bkl->nreg = bpg->nX + bpg->nY ;
if ( bpg->graph->vwghts == NULL ) {
   bkl->totweight = bkl->nreg ;
   bkl->regwghts  = IVinit(bkl->nreg, 1) ;
} else {
   bkl->regwghts  = bpg->graph->vwghts ;
   bkl->totweight = IVsum(bkl->nreg, bkl->regwghts) ; 
}
bkl->colors = IVinit(bkl->nreg, 0) ;
bkl->alpha  = alpha ;

return ; }
Beispiel #3
0
/*
   ----------------------------------------------------
   purpose -- to read a Graph object from a binary file

   return value -- 1 if success, 0  if failure

   created -- 95sep29, cca
   ----------------------------------------------------
*/
int
Graph_readFromBinaryFile ( 
   Graph   *graph, 
   FILE    *fp 
) {
int   nedges, nvbnd, nvtx, rc, totewght, totvwght, type ;
int   itemp[6] ;
int   *vwghts ;
IVL   *adjIVL, *ewghtIVL ;
/*
   ---------------
   check the input
   ---------------
*/
if ( graph == NULL || fp == NULL ) {
   fprintf(stderr, "\n fatal error in Graph_readFromBinaryFile(%p,%p)"
           "\n bad input\n", graph, fp) ;
   return(0) ;
}
/*
   ---------------------
   clear the data fields
   ---------------------
*/
Graph_clearData(graph) ;
/*
   ---------------------------------------------
   read in the six scalar parameters
   type, nvtx, nvbnd, nedges, totvwght, totewght
   ---------------------------------------------
*/
if ( (rc = fread((void *) itemp, sizeof(int), 6, fp)) != 6 ) {
   fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
           "\n %d items of %d read\n", graph, fp, rc, 6) ;
   return(0) ;
}
type     = itemp[0] ;
nvtx     = itemp[1] ;
nvbnd    = itemp[2] ;
nedges   = itemp[3] ;
totvwght = itemp[4] ;
totewght = itemp[5] ;
/*
   --------------------------------------------------
   create the adjIVL IVL object, 
   set its type to IVL_CHUNKED, then read in its data
   --------------------------------------------------
*/
adjIVL = IVL_new() ;
IVL_setDefaultFields(adjIVL) ;
adjIVL->type = IVL_CHUNKED ;
rc = IVL_readFromBinaryFile(adjIVL, fp) ;
if ( rc != 1 ) {
   fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
           "\n trying to read in adjIVL"
           "\n return code %d from IVL_readBinaryFile(%p,%p)",
           graph, fp, rc, adjIVL, fp) ;
   return(0) ;
}
if ( type % 2 == 1 ) {
   int   nvtot, wght ;
/*
   --------------------------
   vertex weights are present
   --------------------------
*/
   nvtot  = nvtx + nvbnd ;
   vwghts = IVinit2(nvtot) ;
   if ( (rc = fread((void *) vwghts, sizeof(int), nvtot, fp)) != nvtot){
      fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
              "\n %d items of %d read\n", graph, fp, rc, nvtx+nvbnd) ;
      return(0) ;
   }
   wght = IVsum(nvtot, vwghts) ;
   if ( wght != totvwght ) {
      fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
              "\n totvwght = %d, IVsum(vwghts) = %d\n",
              graph, fp, totvwght, wght) ;
      return(0) ;
   }
} else {
   vwghts = NULL ;
}
if ( type > 2 ) {
   int   wght ;
/*
   -----------------------------------------------------
   edge weights are present, create the ewghtIVL object, 
   set its type to IVL_CHUNKED, then read in its data
   -----------------------------------------------------
*/
   ewghtIVL = IVL_new() ;
   IVL_setDefaultFields(ewghtIVL) ;
   ewghtIVL->type = IVL_CHUNKED ;
   rc = IVL_readFromBinaryFile(ewghtIVL, fp) ;
   if ( rc != 1 ) {
      fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
              "\n trying to read in ewghtIVL"
              "\n return code %d from IVL_readBinaryFile(%p,%p)",
              graph, fp, rc, ewghtIVL, fp) ;
      return(0) ;
   }
   wght = IVL_sum(ewghtIVL) ;
   if ( wght != totewght ) {
      fprintf(stderr, "\n error in Graph_readFromBinaryFile(%p,%p)"
              "\n totewght = %d, IVL_sum(ewghtIVL) = %d\n",
              graph, fp, totewght, wght) ;
      return(0) ;
   }
} else {
   ewghtIVL = NULL ;
}
/*
   ---------------------
   initialize the object
   ---------------------
*/
Graph_init2(graph, type, nvtx, nvbnd, nedges, totvwght, totewght,
            adjIVL, vwghts, ewghtIVL) ;

return(1) ; }
Beispiel #4
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) ; }
Beispiel #5
0
/*
   ---------------------------------------------------------
   purpose -- to write out the statistics for the IVL object

   return value -- 1 if success, 0 otherwise

   created -- 95sep29, cca
   ---------------------------------------------------------
*/
int
IVL_writeStats ( 
   IVL    *ivl, 
   FILE   *fp 
) {
int   nactive, rc ;
/*
   ---------------
   check the input
   ---------------
*/
if ( ivl == NULL || fp == NULL ) {
   fprintf(stderr, "\n error in IVL_writeStats(%p,%p)"
           "\n bad input\n", ivl, fp) ;
   spoolesFatal();
}
nactive = 0 ;
if ( ivl->nlist > 0 ) {
   nactive = IVsum(ivl->nlist, ivl->sizes) ;
}
rc = fprintf(fp, "\n IVL : integer vector list object :") ;
if ( rc < 0 ) { goto IO_error ; }
rc = fprintf(fp, "\n type %d", ivl->type) ;
if ( rc < 0 ) { goto IO_error ; }
switch ( ivl->type ) {
case IVL_CHUNKED : rc = fprintf(fp, ", chunked storage") ; break ;
case IVL_SOLO    : rc = fprintf(fp, ", solo storage")    ; break ;
case IVL_UNKNOWN : rc = fprintf(fp, ", unknown storage") ; break ;
}
if ( rc < 0 ) { goto IO_error ; }
rc = fprintf(fp, 
             "\n %d lists, %d maximum lists, %d tsize, %d total bytes",
             ivl->nlist, ivl->maxnlist, ivl->tsize, IVL_sizeOf(ivl)) ;
if ( rc < 0 ) { goto IO_error ; }
switch ( ivl->type ) {
case IVL_CHUNKED : {
   Ichunk   *chunk ;
   int      nalloc, nchunk ;

   nalloc = nchunk = 0 ;
   for ( chunk = ivl->chunk ; chunk != NULL ; chunk = chunk->next){
      nchunk++ ;
      nalloc += chunk->size ;
   }
   rc = fprintf(fp, "\n %d chunks, %d active entries, %d allocated",
                nchunk, nactive, nalloc) ;
   if ( rc < 0 ) { goto IO_error ; }
   if ( nalloc > 0 ) {
      rc = fprintf(fp, ", %.2f %% used", (100.*nactive)/nalloc) ;
      if ( rc < 0 ) { goto IO_error ; }
   }
   } break ;
case IVL_SOLO :
   rc = fprintf(fp, 
                "\n %d lists separately allocated, %d active entries",
                ivl->nlist, nactive) ;
  if ( rc < 0 ) { goto IO_error ; }
   break ;
}
return(1) ;

IO_error :
   fprintf(stderr, "\n fatal error in IVL_writeStats(%p,%p)"
           "\n rc = %d, return from fprintf\n", ivl, fp, rc) ;
   return(0) ;
}
Beispiel #6
0
/*--------------------------------------------------------------------*/
int
main ( int argc, char *argv[] )
/*
   ---------------------------------------------
   test the Drand random number generator object
   ---------------------------------------------
*/
{
double   ddot, dmean, param1, param2 ;
double   *dvec ;
Drand    drand ;
FILE     *msgFile ;
int      distribution, ierr, imean, msglvl, n, seed1, seed2 ;
int      *ivec ;

if ( argc != 9 ) {
   fprintf(stderr, 
"\n\n usage : testDrand msglvl msgFile "
"\n         distribution param1 param2 seed1 seed2 n"
"\n    msglvl       -- message level"
"\n    msgFile      -- message file"
"\n    distribution -- 1 for uniform(param1,param2)"
"\n                 -- 2 for normal(param1,param2)"
"\n    param1       -- first parameter"
"\n    param2       -- second parameter"
"\n    seed1        -- first random number seed"
"\n    seed2        -- second random number seed"
"\n    n            -- length of the vector"
"\n"
) ;
   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) ;
}
distribution = atoi(argv[3]) ;
if ( distribution < 1 || distribution > 2 ) {
   fprintf(stderr, "\n fatal error in testDrand"
           "\n distribution must be 1 (uniform) or 2 (normal)") ;
   exit(-1) ;
}
param1 = atof(argv[4]) ;
param2 = atof(argv[5]) ;
seed1  = atoi(argv[6]) ;
seed2  = atoi(argv[7]) ;
n      = atoi(argv[8]) ;

Drand_init(&drand) ;
Drand_setSeeds(&drand, seed1, seed2) ;
switch ( distribution ) {
case 1 : 
   fprintf(msgFile, "\n uniform in [%f,%f]", param1, param2) ;
   Drand_setUniform(&drand, param1, param2) ; 
   break ;
case 2 : 
   fprintf(msgFile, "\n normal(%f,%f)", param1, param2) ;
   Drand_setNormal(&drand, param1, param2) ; 
   break ;
}
/*
   ---------------------------------------------
   fill the integer and double precision vectors
   ---------------------------------------------
*/
dvec = DVinit(n, 0.0) ;
Drand_fillDvector(&drand, n, dvec) ;
dmean = DVsum(n, dvec)/n ;
ddot  = DVdot(n, dvec, dvec) ;
if ( msglvl > 0 ) {
   fprintf(msgFile, "\n dvec mean = %.4f, variance = %.4f",
           dmean, sqrt(fabs(ddot - n*dmean)/n)) ;
}
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n dvec") ;
   DVfprintf(msgFile, n, dvec) ;
}
DVqsortUp(n, dvec) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n sorted dvec") ;
   DVfprintf(msgFile, n, dvec) ;
}
ivec = IVinit(n, 0) ;
Drand_fillIvector(&drand, n, ivec) ;
imean = IVsum(n, ivec)/n ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n ivec") ;
   IVfp80(msgFile, n, ivec, 80, &ierr) ;
}
IVqsortUp(n, ivec) ;
if ( msglvl > 1 ) {
   fprintf(msgFile, "\n sorted ivec") ;
   IVfp80(msgFile, n, ivec, 80, &ierr) ;
}

fprintf(msgFile, "\n") ;

return(1) ; }
Beispiel #7
0
/*
   ------------------------------------------------------------
   compute an old-to-new ordering for 
   local nested dissection in three dimensions

   n1       -- number of grid points in first direction
   n2       -- number of grid points in second direction
   n3       -- number of grid points in third direction
   p1       -- number of domains in first direction
   p2       -- number of domains in second direction
   p3       -- number of domains in third direction
   dsizes1  -- domain sizes in first direction, size p1
               if NULL, then we construct our own
   dsizes2  -- domain sizes in second direction, size p2
               if NULL, then we construct our own
   dsizes3  -- domain sizes in third direction, size p3
               if NULL, then we construct our own
   oldToNew -- old-to-new permutation vector

   note : the following must hold
      n1 > 0, n2 >0, n3 > 0,
      n1 >= 2*p1 - 1, n2 >= 2*p2 - 1, n3 >= 2*p3 - 1, p3 > 1
      sum(dsizes1) = n1 - p1 + 1, sum(dsizes2) = n2 - p2 + 1
      sum(dsizes3) = n3 - p3 + 1

   created -- 95nov16, cca
   ------------------------------------------------------------
*/
void
localND3D ( 
   int   n1, 
   int   n2, 
   int   n3, 
   int   p1, 
   int   p2, 
   int   p3,
   int   dsizes1[], 
   int   dsizes2[], 
   int   dsizes3[], 
   int   oldToNew[] 
) {
int   i, idom, ijk, isw, j, jdom, jsw, k, kdom, ksw, 
      length1, length2, length3, m, m1, m2, m3, msize, now, nvtx ;
int   *length1s, *length2s, *length3s, *isws, *jsws, *ksws, *temp ;
/*
   ---------------
   check the input
   ---------------
*/
if ( n1 <= 0 || n2 <= 0 || n3 <= 0
   || 2*p1 - 1 > n1 || 2*p2 - 1 > n2 || 2*p3 - 1 > n3 ) {
   fprintf(stderr, "\n error in input data") ;
   return ; 
}
if ( p3 <= 1 ) {
   fprintf(stderr, "\n p3 must be > 1") ;
   return ; 
}
if ( oldToNew == NULL ) {
   fprintf(stderr, "\n oldToNew = NULL") ;
   return ; 
}
if ( dsizes1 != NULL && IVsum(p1, dsizes1) != n1 - p1 + 1 ) {
   fprintf(stderr, "\n IVsum(p1, dsizes1) != n1 - p1 + 1 ") ;
   return ; 
}
if ( dsizes2 != NULL && IVsum(p2, dsizes2) != n2 - p2 + 1 ) {
   fprintf(stderr, "\n IVsum(p2, dsizes2) != n2 - p2 + 1 ") ;
   return ; 
}
if ( dsizes3 != NULL && IVsum(p3, dsizes3) != n3 - p3 + 1 ) {
   fprintf(stderr, "\n IVsum(p3, dsizes3) != n3 - p3 + 1 ") ;
   return ; 
}
if ( dsizes1 != NULL && IVmin(p1, dsizes1, &i) <= 0 ) {
   fprintf(stderr, "\n IVmin(p1, dsizes1) must be > 0") ;
   return ; 
}
if ( dsizes2 != NULL && IVmin(p2, dsizes2, &i) <= 0 ) {
   fprintf(stderr, "\n IVmin(p2, dsizes2) must be > 0") ;
   return ; 
}
if ( dsizes3 != NULL && IVmin(p3, dsizes3, &i) <= 0 ) {
   fprintf(stderr, "\n IVmin(p3, dsizes3) must be > 0") ;
   return ; 
}
nvtx = n1*n2*n3 ;
/*
   ----------------------------------
   construct the domain sizes vectors
   ----------------------------------
*/
if ( dsizes1 == NULL ) {
   length1s = IVinit(p1, 0) ;
   length1 = (n1 - p1 + 1) / p1 ;
   m1 = (n1 - p1 + 1) % p1 ;
   for ( i = 0 ; i < m1 ; i++ ) {
      length1s[i] = length1 + 1 ;
   }
   for ( ; i < p1 ; i++ ) {
      length1s[i] = length1 ;
   }
} else {
   length1s = dsizes1 ;
}
if ( dsizes2 == NULL ) {
   length2s = IVinit(p2, 0) ;
   length2 = (n2 - p2 + 1) / p2 ;
   m2 = (n2 - p2 + 1) % p2 ;
   for ( i = 0 ; i < m2 ; i++ ) {
      length2s[i] = length2 + 1 ;
   }
   for ( ; i < p2 ; i++ ) {
      length2s[i] = length2 ;
   }
} else {
   length2s = dsizes2 ;
}
if ( dsizes3 == NULL ) {
   length3s = IVinit(p3, 0) ;
   length3 = (n3 - p3 + 1) / p3 ;
   m3 = (n3 - p3 + 1) % p3 ;
   for ( i = 0 ; i < m3 ; i++ ) {
      length3s[i] = length3 + 1 ;
   }
   for ( ; i < p3 ; i++ ) {
      length3s[i] = length3 ;
   }
} else {
   length3s = dsizes3 ;
}
#if MYDEBUG > 0
fprintf(stdout, "\n inside localND3D") ;
fprintf(stdout, 
        "\n n1 = %d, n2 = %d, n3 = %d, p1 = %d, p2 = %dm p3 = %d", 
        n1, n2, n3, p1, p2, p3) ;
fprintf(stdout, "\n length1s[%d] = ", p1) ;
IVfp80(stdout, p1, length1s, 12) ;
fprintf(stdout, "\n length2s[%d] = ", p2) ;
IVfp80(stdout, p2, length2s, 12) ;
fprintf(stdout, "\n length3s[%d] = ", p3) ;
IVfp80(stdout, p3, length3s, 13) ;
#endif
/*
   ---------------------------------------
   determine the first and last domain ids 
   and the array of southwest points
   ---------------------------------------
*/
isws = IVinit(p1, -1) ;
for ( idom = 0, isw = 0 ; idom < p1 ; idom++ ) {
   isws[idom] = isw ;
   isw += length1s[idom] + 1 ;
}
jsws = IVinit(p2, -1) ;
for ( jdom = 0, jsw = 0 ; jdom < p2 ; jdom++ ) {
   jsws[jdom] = jsw ;
   jsw += length2s[jdom] + 1 ;
}
ksws = IVinit(p3, -1) ;
for ( kdom = 0, ksw = 0 ; kdom < p3 ; kdom++ ) {
   ksws[kdom] = ksw ;
   ksw += length3s[kdom] + 1 ;
}
#if MYDEBUG > 1
fprintf(stdout, "\n isws[%d] = ", p1) ;
IVfp80(stdout, p1, isws, 12) ;
fprintf(stdout, "\n jsws[%d] = ", p2) ;
IVfp80(stdout, p2, jsws, 12) ;
fprintf(stdout, "\n ksws[%d] = ", p3) ;
IVfp80(stdout, p3, ksws, 12) ;
#endif
/*
   ----------------------------------------------------------------
   create a temporary permutation vector for the domains' orderings
   ----------------------------------------------------------------
*/
msize = IVmax(p1, length1s, &i) * IVmax(p2, length2s, &i) 
                                * IVmax(p3, length3s, &k) ;
temp  = IVinit(msize, -1) ;
/*
   ------------------------
   fill in the domain nodes
   ------------------------
*/
now = 0 ;
for ( kdom = 0 ; kdom < p3 ; kdom++ ) {
   ksw     = ksws[kdom] ;
   length3 = length3s[kdom] ;
   for ( jdom = 0 ; jdom < p2 ; jdom++ ) {
      jsw     = jsws[jdom] ;
      length2 = length2s[jdom] ;
      for ( idom = 0 ; idom < p1 ; idom++ ) {
         isw     = isws[idom] ;
         length1 = length1s[idom] ;
/*
fprintf(stdout, "\n domain (%d,%d,%d), size %d x %d x %d",
        idom, jdom, kdom, length1, length2, length3) ;
fprintf(stdout, "\n (isw, jsw, ksw) = (%d, %d, %d)",
        isw, jsw, ksw) ;
*/
         mkNDperm(length1, length2, length3, temp, 
                  0, length1-1, 0, length2-1, 0, length3-1) ;
         for ( m = 0 ; m < length1*length2*length3 ; m++ ) {
            ijk = temp[m] ;
/*
fprintf(stdout, "\n    m = %d, ijk = %d", m, ijk) ;
*/
            k   = ksw + ijk / (length1*length2) ;
            ijk = ijk % (length1*length2) ;
            j   = jsw + ijk / length1 ;
            i   = isw + ijk % length1 ;
/*
fprintf(stdout, ", (i, j, k) = (%d, %d, %d)", i, j, k) ;
*/
            ijk = i + j*n1 + k*n1*n2 ;
            oldToNew[ijk] = now++ ;
         }
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n old-to-new after domains are numbered") ;
fp3DGrid(n1, n2, n3, oldToNew, stdout) ;
#endif
/*
   ---------------------------------
   fill in the lower separator nodes
   ---------------------------------
*/
for ( kdom = 0 ; kdom < (p3/2) ; kdom++ ) {
   ksw  = ksws[kdom] ;
   length3   = length3s[kdom] ;
   for ( jdom = 0 ; jdom < p2 ; jdom++ ) {
      jsw  = jsws[jdom] ;
      length2   = length2s[jdom] ;
      for ( idom = 0 ; idom < p1 ; idom++ ) {
         isw  = isws[idom] ;
         length1   = length1s[idom] ;
/*
   -------
   3 faces
   -------
*/
         if ( isw > 0 ) {
            i = isw - 1 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
         if ( jsw > 0 ) {
            j = jsw - 1 ;
            for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
               for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
         if ( ksw > 0 ) {
            k = ksw - 1 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
/*
         -----------
         three edges
         -----------
*/
         if ( isw > 0 && jsw > 0 ) {
            i = isw - 1 ;
            j = jsw - 1 ;
            for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
         if ( isw > 0 && ksw > 0 ) {
            i = isw - 1 ;
            k = ksw - 1 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
         if ( jsw > 0 && ksw > 0 ) {
            j = jsw - 1 ;
            k = ksw - 1 ;
            for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
/*
         ----------------
         one corner point
         ----------------
*/
         if ( isw > 0 && jsw > 0 && ksw > 0 ) {
            i = isw - 1 ;
            j = jsw - 1 ;
            k = ksw - 1 ;
            ijk = i + j*n1 + k*n1*n2 ;
            oldToNew[ijk] = now++ ;
         }
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n after the lower separators filled in") ;
fp2DGrid(n1, n2, oldToNew, stdout) ;
#endif
/*
   ---------------------------------
   fill in the upper separator nodes
   ---------------------------------
*/
for ( kdom = p3 - 1 ; kdom >= (p3/2) ; kdom-- ) {
   ksw  = ksws[kdom] ;
   length3   = length3s[kdom] ;
   for ( jdom = p2 - 1 ; jdom >= 0 ; jdom-- ) {
      jsw  = jsws[jdom] ;
      length2   = length2s[jdom] ;
      for ( idom = p1 - 1 ; idom >= 0 ; idom-- ) {
         isw  = isws[idom] ;
         length1   = length1s[idom] ;
/*
         -------
         3 faces
         -------
*/
         if ( isw + length1 < n1 ) {
            i = isw + length1 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
         if ( jsw + length2 < n2 ) {
            j = jsw + length2 ;
            for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
               for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
         if ( ksw + length3 < n3 ) {
            k = ksw + length3 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
                  ijk = i + j*n1 + k*n1*n2 ;
                  oldToNew[ijk] = now++ ;
               }
            }
         }
/*
         -----------
         three edges
         -----------
*/
         if ( isw + length1 < n1 && jsw + length2 < n2 ) {
            i = isw + length1 ;
            j = jsw + length2 ;
            for ( k = ksw ; k <= ksw + length3 - 1 ; k++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
         if ( isw + length1 < n1 && ksw + length3 < n3 ) {
            i = isw + length1 ;
            k = ksw + length3 ;
            for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
         if ( jsw + length2 < n2 && ksw + length3 < n3 ) {
            j = jsw + length2 ;
            k = ksw + length3 ;
            for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
               ijk = i + j*n1 + k*n1*n2 ;
               oldToNew[ijk] = now++ ;
            }
         }
/*
         ----------------
         one corner point
         ----------------
*/
         if ( isw + length1 < n1 && jsw + length2 < n2 
                                 && ksw + length3 < n3 ) {
            i = isw + length1 ;
            j = jsw + length2 ;
            k = ksw + length3 ;
            ijk = i + j*n1 + k*n1*n2 ;
            oldToNew[ijk] = now++ ;
         }
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n after the upper separators filled in") ;
fp2DGrid(n1, n2, oldToNew, stdout) ;
#endif
/*
   -------------------------------
   fill in the top level separator
   -------------------------------
*/
m1 = p3 / 2 ;
for ( kdom = 0, k = 0 ; kdom < m1 ; kdom++ ) {
   k += length3s[kdom] + 1 ;
}
k-- ;
for ( j = 0 ; j < n2 ; j++ ) { 
   for ( i = 0 ; i < n1 ; i++ ) { 
      ijk = i + j*n1 + k*n1*n2 ;
      oldToNew[ijk] = now++ ;
   }
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
if ( dsizes1 == NULL ) {
   IVfree(length1s) ;
}
if ( dsizes2 == NULL ) {
   IVfree(length2s) ;
}
if ( dsizes3 == NULL ) {
   IVfree(length3s) ;
}
IVfree(isws) ;
IVfree(jsws) ;
IVfree(ksws) ;
IVfree(temp) ;

return ; }
Beispiel #8
0
/*
   ------------------------------------------------------------
   compute an old-to-new ordering for 
   local nested dissection in two dimensions

   n1       -- number of grid points in first direction
   n2       -- number of grid points in second direction
   p1       -- number of domains in first direction
   p2       -- number of domains in second direction
   dsizes1  -- domain sizes in first direction, size p1
               if NULL, then we construct our own
   dsizes2  -- domain sizes in second direction, size p2
               if NULL, then we construct our own
   oldToNew -- old-to-new permutation vector

   note : the following must hold
      n1 > 0, n2 >0, n1 >= 2*p1 - 1, n2 >= 2*p2 - 1, p2 > 1
      sum(dsizes1) = n1 - p1 + 1 and sum(dsizes2) = n2 - p2 + 1

   created -- 95nov16, cca
   ------------------------------------------------------------
*/
void
localND2D ( 
   int   n1, 
   int   n2, 
   int   p1, 
   int   p2, 
   int   dsizes1[], 
   int   dsizes2[], 
   int   oldToNew[] 
) {
int   i, idom, ij, isw, j, jdom, jsw, length1, length2, 
      m, m1, m2, msize, now, nvtx ;
int   *length1s, *length2s, *isws, *jsws, *temp ;
/*
   ---------------
   check the input
   ---------------
*/
if ( n1 <= 0 || n2 <= 0 || 2*p1 - 1 > n1 || 2*p2 - 1 > n2 
   || oldToNew == NULL ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n bad input\n",
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew) ;
   exit(-1) ; 
}
if ( p2 <= 1 ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n p2 = %d, must be > 1", 
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew, p2) ;
   exit(-1) ; 
}
if ( dsizes1 != NULL && IVsum(p1, dsizes1) != n1 - p1 + 1 ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n IVsum(p1, dsizes1) = %d != %d = n1 - p1 + 1 ",
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew, 
           IVsum(p1, dsizes1), n1 - p1 + 1) ;
   return ; 
}
if ( dsizes1 != NULL && IVmin(p1, dsizes1, &i) <= 0 ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n IVmin(p1, dsizes1) = %d must be > 0",
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew, 
           IVmin(p1, dsizes1, &i)) ;
   return ; 
}
if ( dsizes2 != NULL && IVsum(p2, dsizes2) != n2 - p2 + 1 ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n IVsum(p2, dsizes2) = %d != %d = n2 - p2 + 1 ",
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew, 
           IVsum(p2, dsizes2), n2 - p2 + 1) ;
   return ; 
}
if ( dsizes2 != NULL && IVmin(p2, dsizes2, &i) <= 0 ) {
   fprintf(stderr, "\n fatal error in localND2D(%d,%d,%d,%d,%p,%p,%p)"
           "\n IVmin(p2, dsizes2) = %d must be > 0",
           n1, n2, p1, p2, dsizes1, dsizes2, oldToNew, 
           IVmin(p2, dsizes2, &i)) ;
   return ; 
}
nvtx = n1*n2 ;
/*
   ----------------------------------
   construct the domain sizes vectors
   ----------------------------------
*/
if ( dsizes1 == NULL ) {
   length1s = IVinit(p1, 0) ;
   length1  = (n1 - p1 + 1) / p1 ;
   m1       = (n1 - p1 + 1) % p1 ;
   for ( i = 0 ; i < m1 ; i++ ) {
      length1s[i] = length1 + 1 ;
   }
   for ( ; i < p1 ; i++ ) {
      length1s[i] = length1 ;
   }
} else {
   length1s = dsizes1 ;
}
if ( dsizes2 == NULL ) {
   length2s = IVinit(p2, 0) ;
   length2  = (n2 - p2 + 1) / p2 ;
   m2       = (n2 - p2 + 1) % p2 ;
   for ( i = 0 ; i < m2 ; i++ ) {
      length2s[i] = length2 + 1 ;
   }
   for ( ; i < p2 ; i++ ) {
      length2s[i] = length2 ;
   }
} else {
   length2s = dsizes2 ;
}
#if MYDEBUG > 0
fprintf(stdout, "\n inside localND2D") ;
fprintf(stdout, "\n n1 = %d, n2 = %d, p1 = %d, p2 = %d", 
        n1, n2, p1, p2) ;
fprintf(stdout, "\n length1s[%d] = ", p1) ;
IVfp80(stdout, p1, length1s, 12) ;
fprintf(stdout, "\n length2s[%d] = ", p2) ;
IVfp80(stdout, p2, length2s, 12) ;
#endif
/*
   ---------------------------------------
   determine the first and last domain ids 
   and the array of southwest points
   ---------------------------------------
*/
isws = IVinit(p1, -1) ;
for ( idom = 0, isw = 0 ; idom < p1 ; idom++ ) {
   isws[idom] = isw ;
   isw += length1s[idom] + 1 ;
}
jsws = IVinit(p2, -1) ;
for ( jdom = 0, jsw = 0 ; jdom < p2 ; jdom++ ) {
   jsws[jdom] = jsw ;
   jsw += length2s[jdom] + 1 ;
}
#if MYDEBUG > 1
fprintf(stdout, "\n isws[%d] = ", p1) ;
IVfp80(stdout, p1, isws, 12) ;
fprintf(stdout, "\n jsws[%d] = ", p2) ;
IVfp80(stdout, p2, jsws, 12) ;
#endif
/*
   ----------------------------------------------------------------
   create a temporary permutation vector for the domains' orderings
   ----------------------------------------------------------------
*/
msize = IVmax(p1, length1s, &i) * IVmax(p2, length2s, &i) ;
temp  = IVinit(msize, -1) ;
/*
   ------------------------
   fill in the domain nodes
   ------------------------
*/
now = 0 ;
for ( jdom = 0; jdom < p2 ; jdom++ ) {
   jsw     = jsws[jdom] ;
   length2 = length2s[jdom] ;
   for ( idom = 0 ; idom < p1 ; idom++ ) {
      length1 = length1s[idom] ;
      isw     = isws[idom] ;
      mkNDperm(length1, length2, 1, temp, 0, length1-1, 
               0, length2-1, 0, 0) ;
      for ( m = 0 ; m < length1*length2 ; m++ ) {
         ij = temp[m] ;
         i  = isw + (ij % length1) ;
         j  = jsw + (ij / length1) ;
         ij = i + j*n1 ;
         oldToNew[ij] = now++ ;
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n old-to-new after domains are numbered") ;
fp2DGrid(n1, n2, oldToNew, stdout) ;
#endif
/*
   ---------------------------------
   fill in the lower separator nodes
   ---------------------------------
*/
for ( jdom = 0 ; jdom < (p2/2) ; jdom++ ) {
   jsw     = jsws[jdom] ;
   length2 = length2s[jdom] ;
   for ( idom = 0 ; idom < p1 ; idom++ ) {
      isw     = isws[idom] ;
      length1 = length1s[idom] ;
      if ( isw > 0 ) {
         i = isw - 1 ;
         for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
            ij = i + j*n1 ;
            oldToNew[ij] = now++ ;
         }
      }
      if ( isw > 0 && jsw > 0 ) {
         i = isw - 1 ;
         j = jsw - 1 ;
         ij = i + j*n1 ;
         oldToNew[ij] = now++ ;
      }
      if ( jsw > 0 ) {
         j = jsw - 1 ;
         for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
            ij = i + j*n1 ;
            oldToNew[ij] = now++ ;
         }
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n after the lower separators filled in") ;
fp2DGrid(n1, n2, oldToNew, stdout) ;
#endif
/*
   ---------------------------------
   fill in the upper separator nodes
   ---------------------------------
*/
for ( jdom = p2 - 1 ; jdom >= (p2/2) ; jdom-- ) {
   jsw     = jsws[jdom] ;
   length2 = length2s[jdom] ;
   for ( idom = p1 - 1 ; idom >= 0 ; idom-- ) {
      isw     = isws[idom] ;
      length1 = length1s[idom] ;
      if ( isw + length1 < n1 ) {
         i = isw + length1 ;
         for ( j = jsw ; j <= jsw + length2 - 1 ; j++ ) {
            ij = i + j*n1 ;
            oldToNew[ij] = now++ ;
         }
      }
      if ( isw + length1 < n1 && jsw + length2 < n2 ) {
         i = isw + length1 ;
         j = jsw + length2 ;
         ij = i + j*n1 ;
         oldToNew[ij] = now++ ;
      }
      if ( jsw + length2 < n2 ) {
         j = jsw + length2 ;
         for ( i = isw ; i <= isw + length1 - 1 ; i++ ) {
            ij = i + j*n1 ;
            oldToNew[ij] = now++ ;
         }
      }
   }
}
#if MYDEBUG > 2
fprintf(stdout, "\n after the upper separators filled in") ;
fp2DGrid(n1, n2, oldToNew, stdout) ;
#endif
/*
   -------------------------------
   fill in the top level separator
   -------------------------------
*/
m1 = p2 / 2 ;
for ( jdom = 0, j = 0 ; jdom < m1 ; jdom++ ) {
   j += length2s[jdom] + 1 ;
}
j-- ;
for ( i = 0 ; i < n1 ; i++ ) { 
   ij = i + j*n1 ;
   oldToNew[ij] = now++ ;
}
/*
   ------------------------
   free the working storage
   ------------------------
*/
if ( dsizes1 == NULL ) {
   IVfree(length1s) ;
}
if ( dsizes2 == NULL ) {
   IVfree(length2s) ;
}
IVfree(isws) ;
IVfree(jsws) ;
IVfree(temp) ;

return ; }
Beispiel #9
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) ; }
Beispiel #10
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) ; }
Beispiel #11
0
/*
   ------------------------------------------------------------------
   purpose -- to find indistinguishable nodes in the reach set

   flag = 0 --> return
   flag = 1 --> check out nodes that are 2-adj
   flag = 2 --> check out nodes that are both 2-adj and not

   note: the reach set is not changed.

   created -- 96feb15, cca
   modified -- 97feb07, cca
      very tricky "bug"
      was : sum += ip->val for subtrees
            sum += IVsum(nvedge, vedges) for uncovered edges
      now : sum += ip->val + 1 for subtrees
            sum += IVsum(nvedge, vedges) + nvedge for uncovered edges
      checksums were "wrong" due to vertex 0 adding nothing
      to the checksum. beware 0-indexing.
   ------------------------------------------------------------------
*/
void
MSMD_findInodes ( 
   MSMD       *msmd,
   MSMDinfo   *info
) {
int             first, flag, i, ierr, iv, iw, j, k, keepon, nlist, 
                nreach, nvedge, sum, vid, vchk, vcount, wid ;
int             *chk, *list, *reach, *vedges, *wedges ;
IP              *ip, *ipv, *ipw, *vsubtrees ;
MSMDvtx         *v, *w ;
/*
   ---------------
   check the input
   ---------------
*/
if ( msmd == NULL || info == NULL ) {
   fprintf(stderr, "\n fatal error in MSMD_findInodes(%p,%p)"
           "\n bad input\n", msmd, info) ;
   exit(-1) ;
}
if ( (flag = info->compressFlag % 4) == 0 ) {
/*
   ---------------------------------------
   no compression requested, simple return
   ---------------------------------------
*/
   return ;
}
/*
   ---------------------------------
   if the reach set is empty, return
   ---------------------------------
*/
if ( (nreach = IV_size(&msmd->reachIV)) == 0 ) {
   return ; 
}
/*
reach = msmd->reach ;
*/
reach = IV_entries(&msmd->reachIV) ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n inside MSMD_findInodes(%p)"
           "\n reach(%d) :", msmd, nreach) ;
   IVfp80(info->msgFile, nreach, reach, 10, &ierr);
   fflush(info->msgFile) ;
}
/*
   -------------------------------------------------------
   load the front of the reach set with nodes to be tested
   -------------------------------------------------------
*/
chk = IV_entries(&msmd->ivtmpIV) ;
list = reach ;
if ( flag == 1 ) {
/*
   -------------------------------------------
   work only with nodes adjacent to 2 subtrees
   -------------------------------------------
*/
   i = 0 ; j = nreach - 1 ;
   while ( i <= j ) {
      vid = list[i] ;
      v = msmd->vertices + vid ;
      if (  v->nadj != 0 || (ip = v->subtrees) == NULL
        || (ip = ip->next) == NULL || ip->next != NULL ) {
/*
         --------------------------------
         vertex is not 2-adj, swap to end
         --------------------------------
*/
         list[i] = list[j] ;
         list[j] = vid     ;
         j-- ;
      } else {
/*
         --------------------------
         vertex is 2-adj, keep here
         --------------------------
*/
         i++ ;
      }
   }
   nlist = j + 1 ;
} else {
/*
   ---------------------------------
   put all reached nodes in the list
   ---------------------------------
*/
   nlist = nreach ;
}
if ( nlist == 0 ) {
   return ; 
}
/*
   -----------------------------------------------------
   compute the the checksums and count adjacent subtrees
   for all vertices in the list
   -----------------------------------------------------
*/
for ( k = 0 ; k < nlist ; k++ ) {
   vid    = list[k] ;
   v      = msmd->vertices + vid ;
   vcount = 0 ;
   sum    = 0 ;
   if ( info->msglvl > 4 ) {
      fprintf(info->msgFile, "\n vertex %d", vid) ;
      fflush(info->msgFile) ;
   }
   for ( ipv = v->subtrees ; ipv != NULL ; ipv = ipv->next ) {
/*
      ------------------------------------
      add adjacent subtree to the checksum
      ------------------------------------
*/
      sum += ipv->val + 1 ;
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n    adjacent subtree %d, sum = %d",
                 ipv->val, sum) ;
         fflush(info->msgFile) ;
      }
      vcount++ ;
   }
   if ( (nvedge = v->nadj) > 0 && (vedges = v->adj) != NULL ) {
      sum += IVsum(nvedge, vedges) + nvedge ;
      if ( info->msglvl > 4 ) {
         fprintf(info->msgFile, "\n    %d adjacent edges :",
                 nvedge) ;
         IVfp80(info->msgFile, nvedge, vedges, 20, &ierr) ;
         fprintf(info->msgFile, " : sum = %d", sum) ;
         fflush(info->msgFile) ;
      }
      IVqsortUp(nvedge, vedges) ;
   }
/*
   -----------------
   save the checksum
   -----------------
*/
   chk[k] = sum ;
}
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n before sort, list array") ;
   fflush(info->msgFile) ;
   IVfp80(info->msgFile, nlist, list, 80, &ierr) ;
   fflush(info->msgFile) ;
   fprintf(info->msgFile, "\n chk array") ;
   fflush(info->msgFile) ;
   IVfp80(info->msgFile, nlist, chk, 80, &ierr) ;
   fflush(info->msgFile) ;
}
/*
   -----------------------------------------------------
   sort the vertices in the reach set by their checksums
   -----------------------------------------------------
*/
IV2qsortUp(nlist, chk, list) ;
if ( info->msglvl > 3 ) {
   fprintf(info->msgFile, "\n after sort, reach array") ;
   IVfp80(info->msgFile, nlist, list, 80, &ierr) ;
   fprintf(info->msgFile, "\n chk array") ;
   IVfp80(info->msgFile, nlist, chk, 80, &ierr) ;
   fflush(info->msgFile) ;
}
/*
   ----------------------------------------
   detect and purge indistinguishable nodes
   ----------------------------------------
*/
for ( iv = 0 ; iv < nlist ; iv++ ) {
   vid = list[iv] ;
   v   = msmd->vertices + vid ;
   if ( v->status == 'I' ) {
/*
      -----------------------------------------------------
      vertex has been found indistinguishable, skip to next
      -----------------------------------------------------
*/
      continue ;
   }
/*
   ---------------------------
   test against other vertices
   ---------------------------
*/
   vchk      = chk[iv]     ;
   nvedge    = v->nadj     ;
   vedges    = v->adj      ;
   vsubtrees = v->subtrees ;
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, 
              "\n checking out v = %d, vchk = %d, status = %c",
              v->id, vchk, v->status) ;
      fflush(info->msgFile) ;
   }
/*
   ---------------------------------------------------
   check v against all vertices with the same checksum
   ---------------------------------------------------
*/
   if ( info->msglvl > 3 ) {
      fprintf(info->msgFile, "\n checking out v = %d, status = %d",
              v->id, v->stage) ;
      fflush(info->msgFile) ;
   }
   first =  1 ;
   for ( iw = iv + 1 ; iw < nlist && chk[iw] == vchk ; iw++ ) {
      wid = reach[iw] ;
      w   = msmd->vertices + wid ;
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n     w = %d, status = %c, status = %d",
                 w->id, w->status, w->stage) ;
         fflush(info->msgFile) ;
      }
      if (  w->status == 'I' 
         || v->stage != w->stage
         || nvedge != w->nadj ) {
/*
         ------------------------------------
         w has been found indistinguishable
            or
         v and w do not lie on the same stage
            or
         edge counts are not the same
         ------------------------------------
*/
         continue ;
      }
/*
      ----------------------------------------
      w and v check out so far, check to see 
      if all vertices adjacent to w are marked
      ----------------------------------------
*/
      if ( info->msglvl > 3 ) {
         fprintf(info->msgFile, 
                 "\n    checking %d against %d", wid, vid) ;
         fflush(info->msgFile) ;
      }
/*
      ---------------------------------------------------------------
      check to see if the subtree lists and edge lists are indentical
      ---------------------------------------------------------------
*/
      info->stageInfo->ncheck++ ;
      keepon = 1 ;
      ipv = vsubtrees ;
      ipw = w->subtrees ;
      while ( ipv != NULL && ipw != NULL ) {
         if ( ipv->val != ipw->val ) {
            keepon = 0 ;
            break ;
         }
         ipv = ipv->next ;
         ipw = ipw->next ;
      }
      if ( keepon == 1 ) {
         wedges = w->adj ;
         for ( k = 0 ; k < nvedge ; k++ ) {
            if ( vedges[k] != wedges[k] ) {
               keepon = 0 ;
               break ;
            }
         }
      }
      if ( keepon == 1 ) {
/*
         ---------------------------------------------
         w and v are indistinguishable, merge w into v
         ---------------------------------------------
*/
         if ( info->msglvl > 1 ) {
            fprintf(info->msgFile, 
                    "\n %d absorbs %d, wght = %d, status[%d] = %c", 
                    v->id, w->id, w->wght, w->id, w->status) ;
            fflush(info->msgFile) ;
         }
         v->wght   += w->wght  ;
         w->wght   =  0 ;
         w->status =  'I' ;
         w->nadj   =  0 ;
         w->adj    = NULL ;
         w->par    =  v ;
         if ( (ipw = w->subtrees) != NULL ) {
            while ( ipw->next != NULL ) {
               ipw = ipw->next ;
            }
            ipw->next   = msmd->freeIP ;
            msmd->freeIP = ipw ;
            w->subtrees = NULL ;
         }
         info->stageInfo->nindst++ ;
      }
   }
}
if ( info->msglvl > 4 ) {
   fprintf(info->msgFile, 
         "\n MSMD_findInodes(%p), all done checking the nodes", msmd) ;
   fflush(info->msgFile) ;
}

return ; }
Beispiel #12
0
/*
   -----------------------------------------------------------
   purpose -- to write out the statistics for the BPG object

   return value -- 1 if success, 0 otherwise

   created -- 95oct06, cca
   -----------------------------------------------------------
*/
int
BPG_writeStats ( 
   BPG    *bpg, 
   FILE   *fp 
) {
int   rc ;
/*
   ---------------
   check the input
   ---------------
*/
if ( bpg == NULL || fp == NULL ) {
   fprintf(stderr, "\n error in BPG_writeStats(%p,%p)"
           "\n bad input\n", bpg, fp) ;
   spoolesFatal();
}
if ( bpg->graph == NULL ) {
   fprintf(stderr, "\n warning in BPG_writeStats(%p,%p)"
           "\n bpg->graph = NULL\n", bpg, fp) ;
   return(1) ;
}
switch ( bpg->graph->type ) {
case 0 : 
   rc = fprintf(fp, "\n BPG : unweighted bpg object :") ;
   break ;
case 1 : 
   rc = fprintf(fp, "\n BPG : vertices weighted bpg object :") ;
   break ;
case 2 : 
   rc = fprintf(fp, "\n BPG : edges weighted bpg object :") ;
   break ;
case 3 : 
   rc = fprintf(fp, 
            "\n BPG : vertices and edges weighted bpg object :") ;
   break ;
default :
   fprintf(stderr, "\n fatal error in BPG_writeStats(%p,%p)"
           "\n invalid bpg->g->type = %d\n", 
           bpg, fp, bpg->graph->type) ;
   return(0) ;
}
if ( rc < 0 ) { goto IO_error ; }
fflush(fp) ;
rc = fprintf(fp, " nX = %d, nY = %d", bpg->nX, bpg->nY) ;
if ( rc < 0 ) { goto IO_error ; }
fflush(fp) ;
if ( bpg->graph != NULL ) {
   if ( bpg->graph->vwghts != NULL ) {
      rc = fprintf(fp, ", |X| = %d, |Y| = %d", 
                  IVsum(bpg->nX, bpg->graph->vwghts),
                  IVsum(bpg->nY, bpg->graph->vwghts + bpg->nX)) ;
   } else {
      rc = fprintf(fp, ", |X| = %d, |Y| = %d", bpg->nX, bpg->nY) ;
   }
}
if ( rc < 0 ) { goto IO_error ; }
fflush(fp) ;

return(1) ;

IO_error :
   fprintf(stderr, "\n fatal error in BPG_writeStats(%p,%p)"
           "\n rc = %d, return from fprintf\n", bpg, fp, rc) ;
   return(0) ;
}