/* --------------------------------------------- clear the data fields for a GPart object created -- 95oct05, cca modified -- 95nov29, cca par, fch, sib and vtxMap fields included --------------------------------------------- */ void GPart_clearData ( GPart *gpart ) { if ( gpart == NULL ) { fprintf(stderr, "\n fatal error in GPart_clearData(%p)" "\n bad input\n", gpart) ; exit(-1) ; } IV_clearData(&gpart->compidsIV) ; IV_clearData(&gpart->cweightsIV) ; IV_clearData(&gpart->vtxMapIV) ; GPart_setDefaultFields(gpart) ; return ; }
/* --------------------------------------------------- purpose -- to read an IV object from a binary file return value -- 1 if success, 0 if failure created -- 95oct06, cca --------------------------------------------------- */ int IV_readFromBinaryFile ( IV *iv, FILE *fp ) { int rc, size ; /* --------------- check the input --------------- */ if ( iv == NULL || fp == NULL ) { fprintf(stderr, "\n fatal error in IV_readFromBinaryFile(%p,%p)" "\n bad input\n", iv, fp) ; return(0) ; } IV_clearData(iv) ; /* ------------------------------ read in the size of the vector ------------------------------ */ if ( (rc = fread((void *) &size, sizeof(int), 1, fp)) != 1 ) { fprintf(stderr, "\n error in IV_readFromBinaryFile(%p,%p)" "\n itemp(3) : %d items of %d read\n", iv, fp, rc, 1) ; return(0) ; } /* --------------------- initialize the object --------------------- */ IV_init(iv, size, NULL) ; iv->size = size ; /* ------------------------ read in the vec[] vector ------------------------ */ if ( (rc = fread((void *) iv->vec, sizeof(int), size, fp)) != size ) { fprintf(stderr, "\n error in IV_readFromBinaryFile(%p,%p)" "\n sizes(%d) : %d items of %d read\n", iv, fp, size, rc, size) ; return(0) ; } return(1) ; }
/* ----------------------------------------------------- purpose -- to read an IV object from a formatted file return value -- 1 if success, 0 if failure created -- 95oct06, cca ----------------------------------------------------- */ int IV_readFromFormattedFile ( IV *iv, FILE *fp ) { int rc, size ; /* --------------- check the input --------------- */ if ( iv == NULL || fp == NULL ) { fprintf(stderr, "\n error in IV_readFromFormattedFile(%p,%p)" "\n bad input\n", iv, fp) ; return(0) ; } IV_clearData(iv) ; /* ------------------------------ read in the size of the vector ------------------------------ */ if ( (rc = fscanf(fp, "%d", &size)) != 1 ) { fprintf(stderr, "\n error in IV_readFromFormattedFile(%p,%p)" "\n %d items of %d read\n", iv, fp, rc, 1) ; return(0) ; } /* --------------------- initialize the object --------------------- */ IV_init(iv, size, NULL) ; iv->size = size ; /* ------------------------ read in the vec[] vector ------------------------ */ if ( (rc = IVfscanf(fp, size, iv->vec)) != size ) { fprintf(stderr, "\n error in IV_readFromFormattedFile(%p,%p)" "\n %d items of %d read\n", iv, fp, rc, size) ; return(0) ; } return(1) ; }
/* --------------------------------------------- simplest initialization method if entries != NULL the object does not own the entries, it just points to the entries base address else if size > 0 the object will own the entries, it allocates a vector of size int's. else nothing happens endif created -- 96aug28, cca --------------------------------------------- */ void IV_init ( IV *iv, int size, int *entries ) { if ( iv == NULL || size < 0 ) { fprintf(stderr, "\n fatal error in IV_init(%p,%d,%p)" "\n bad input\n", iv, size, entries) ; exit(-1) ; } /* -------------- clear any data -------------- */ IV_clearData(iv) ; /* ----------------------------- set the size and maximum size ----------------------------- */ iv->maxsize = iv->size = size ; /* ------------------------- set vector and owner flag ------------------------- */ if ( entries != NULL ) { iv->owned = 0 ; iv->vec = entries ; } else if ( size > 0 ) { iv->owned = 1 ; iv->vec = IVinit(size, -1) ; } /* fprintf(stdout, "\n %% leaving IV_init, iv %p, size %d, maxsize %d, entries %p", iv, iv->size, iv->maxsize, iv->vec) ; fflush(stdout) ; */ return ; }
/* ---------------------------------------------------------------- purpose -- if the elimination has halted before all the stages have been eliminated, then create the schur complement graph and the map from the original vertices those in the schur complement graph. schurGraph -- Graph object to contain the schur complement graph VtoPhi -- IV object to contain the map from vertices in V to schur complement vertices in Phi created -- 97feb01, cca ---------------------------------------------------------------- */ void MSMD_makeSchurComplement ( MSMD *msmd, Graph *schurGraph, IV *VtoPhiIV ) { int nedge, nPhi, nvtx, totewght, totvwght ; int *mark, *rep, *VtoPhi, *vwghts ; int count, *list ; int ierr, ii, size, *adj ; int phi, psi, tag ; IP *ip ; IVL *adjIVL ; MSMDvtx *u, *v, *vertices, *vfirst, *vlast, *w ; /* --------------- check the input --------------- */ if ( msmd == NULL || schurGraph == NULL || VtoPhiIV == NULL ) { fprintf(stderr, "\n\n fatal error in MSMD_makeSchurComplement(%p,%p,%p)" "\n bad input\n", msmd, schurGraph, VtoPhiIV) ; exit(-1) ; } vertices = msmd->vertices ; nvtx = msmd->nvtx ; /* ------------------------------------- initialize the V-to-Phi map IV object ------------------------------------- */ IV_clearData(VtoPhiIV) ; IV_setSize(VtoPhiIV, nvtx) ; IV_fill(VtoPhiIV, -2) ; VtoPhi = IV_entries(VtoPhiIV) ; /* --------------------------------------------- count the number of Schur complement vertices --------------------------------------------- */ vfirst = vertices ; vlast = vfirst + nvtx - 1 ; nPhi = 0 ; for ( v = vfirst ; v <= vlast ; v++ ) { #if MYDEBUG > 0 fprintf(stdout, "\n v->id = %d, v->status = %c", v->id, v->status) ; fflush(stdout) ; #endif switch ( v->status ) { case 'L' : case 'E' : case 'I' : break ; case 'B' : VtoPhi[v->id] = nPhi++ ; #if MYDEBUG > 0 fprintf(stdout, ", VtoPhi[%d] = %d", v->id, VtoPhi[v->id]) ; fflush(stdout) ; #endif break ; default : break ; } } #if MYDEBUG > 0 fprintf(stdout, "\n\n nPhi = %d", nPhi) ; fflush(stdout) ; #endif /* ---------------------------------------------------- get the representative vertex id for each Phi vertex ---------------------------------------------------- */ rep = IVinit(nPhi, -1) ; for ( v = vfirst ; v <= vlast ; v++ ) { if ( (phi = VtoPhi[v->id]) >= 0 ) { #if MYDEBUG > 0 fprintf(stdout, "\n rep[%d] = %d", phi, v->id) ; fflush(stdout) ; #endif rep[phi] = v->id ; } } /* ------------------------------------------ set the map for indistinguishable vertices ------------------------------------------ */ for ( v = vfirst ; v <= vlast ; v++ ) { if ( v->status == 'I' ) { w = v ; while ( w->status == 'I' ) { w = w->par ; } #if MYDEBUG > 0 fprintf(stdout, "\n v = %d, status = %c, w = %d, status = %c", v->id, v->status, w->id, w->status) ; fflush(stdout) ; #endif VtoPhi[v->id] = VtoPhi[w->id] ; } } #if MYDEBUG > 0 fprintf(stdout, "\n\n VtoPhi") ; IV_writeForHumanEye(VtoPhiIV, stdout) ; fflush(stdout) ; #endif /* --------------------------- initialize the Graph object --------------------------- */ Graph_clearData(schurGraph) ; Graph_init1(schurGraph, 1, nPhi, 0, 0, IVL_CHUNKED, IVL_CHUNKED) ; adjIVL = schurGraph->adjIVL ; vwghts = schurGraph->vwghts ; #if MYDEBUG > 0 fprintf(stdout, "\n\n schurGraph initialized, nvtx = %d", schurGraph->nvtx) ; fflush(stdout) ; #endif /* ------------------------------- fill the vertex adjacency lists ------------------------------- */ mark = IVinit(nPhi, -1) ; list = IVinit(nPhi, -1) ; nedge = totvwght = totewght = 0 ; for ( phi = 0 ; phi < nPhi ; phi++ ) { /* ----------------------------- get the representative vertex ----------------------------- */ v = vfirst + rep[phi] ; #if MYDEBUG > 0 fprintf(stdout, "\n phi = %d, v = %d", phi, v->id) ; fflush(stdout) ; MSMDvtx_print(v, stdout) ; fflush(stdout) ; #endif count = 0 ; tag = v->id ; /* --------------------------- load self in adjacency list --------------------------- */ mark[phi] = tag ; totewght += v->wght * v->wght ; #if MYDEBUG > 0 fprintf(stdout, "\n mark[%d] = %d", phi, mark[phi]) ; fflush(stdout) ; #endif list[count++] = phi ; /* ---------------------------------------- load boundary lists of adjacent subtrees ---------------------------------------- */ for ( ip = v->subtrees ; ip != NULL ; ip = ip->next ) { u = vertices + ip->val ; size = u->nadj ; adj = u->adj ; #if MYDEBUG > 0 fprintf(stdout, "\n subtree %d :", u->id) ; IVfp80(stdout, size, adj, 15, &ierr) ; fflush(stdout) ; #endif for ( ii = 0 ; ii < size ; ii++ ) { w = vertices + adj[ii] ; #if MYDEBUG > 0 fprintf(stdout, "\n w %d, status %c, psi %d", w->id, w->status, VtoPhi[w->id]) ; fflush(stdout) ; #endif if ( (psi = VtoPhi[w->id]) != -2 && mark[psi] != tag ) { mark[psi] = tag ; #if MYDEBUG > 0 fprintf(stdout, ", mark[%d] = %d", psi, mark[psi]) ; fflush(stdout) ; #endif list[count++] = psi ; totewght += v->wght * w->wght ; } } } /* ---------------------- load adjacent vertices ---------------------- */ size = v->nadj ; adj = v->adj ; for ( ii = 0 ; ii < size ; ii++ ) { w = vertices + adj[ii] ; if ( (psi = VtoPhi[w->id]) != -2 && mark[psi] != tag ) { mark[psi] = tag ; list[count++] = psi ; totewght += v->wght * w->wght ; } } /* --------------------------------------------- sort the list and inform adjacency IVL object --------------------------------------------- */ IVqsortUp(count, list) ; IVL_setList(adjIVL, phi, count, list) ; /* -------------------------------------- set the vertex weight and increment the total vertex weight and edge count -------------------------------------- */ vwghts[phi] = v->wght ; totvwght += v->wght ; nedge += count ; } schurGraph->totvwght = totvwght ; schurGraph->nedges = nedge ; schurGraph->totewght = totewght ; /* ------------------------ free the working storage ------------------------ */ IVfree(list) ; IVfree(mark) ; IVfree(rep) ; return ; }
/* ------------------------- total initializion method created -- 95oct06, cca ------------------------- */ void IV_init2 ( IV *iv, int size, int maxsize, int owned, int *vec ) { /* --------------- check the input --------------- */ if ( iv == NULL ) { fprintf(stderr, "\n fatal error in IV_init2(%p,%d,%d,%d,%p)" "\n bad input\n", iv, size, maxsize, owned, vec) ; exit(-1) ; } if ( size < 0 || maxsize < size ) { fprintf(stderr, "\n fatal error in IV_init2(%p,%d,%d,%d,%p)" "\n size = %d, maxsize = %d \n", iv, size, maxsize, owned, vec, size, maxsize) ; exit(-1) ; } if ( owned < 0 || 1 < owned ) { fprintf(stderr, "\n fatal error in IV_init2(%p,%d,%d,%d,%p)" "\n owned = %d\n", iv, size, maxsize, owned, vec, owned) ; exit(-1) ; } if ( owned == 1 && vec == NULL ) { fprintf(stderr, "\n fatal error in IV_init2(%p,%d,%d,%d,%p)" "\n owned = %d and vec = %p", iv, size, maxsize, owned, vec, owned, vec) ; exit(-1) ; } /* -------------- clear any data -------------- */ IV_clearData(iv) ; if ( vec == NULL ) { /* ---------------------------------------------- no entries input, use the simplest initializer ---------------------------------------------- */ IV_init(iv, size, NULL) ; } else { /* --------------------------------- entries are input, set the fields --------------------------------- */ iv->size = size ; iv->maxsize = maxsize ; iv->owned = owned ; iv->vec = vec ; } return ; }
/* --------------------------------------------------------------------- purpose -- to order the graph using multi-stage minimum degree g -- Graph object stages -- stage vector for vertices, if NULL then all vertices on stage zero. otherwise vertices with stage istage are eliminated before any vertices with stage > istage working storage is free'd, statistics can be accessed through their variables or printed via the void MSMD_printStats(MSMD*,FILE*) method. created -- 96feb25, cca --------------------------------------------------------------------- */ void MSMD_order ( MSMD *msmd, Graph *g, int stages[], MSMDinfo *info ) { double t0, t1, t2, t3 ; int istage, iv, nstage, nvtx ; IP *ip ; MSMDstageInfo *now, *total ; MSMDvtx *v ; /* --------------- check the input --------------- */ MARKTIME(t0) ; if ( msmd == NULL || g == NULL || info == NULL ) { fprintf(stderr, "\n fatal error in MSMD_order(%p,%p,%p,%p)" "\n bad input\n", msmd, g, stages, info) ; exit(-1) ; } if ( info->msglvl > 2 ) { fprintf(info->msgFile, "\n\n inside MSMD_order()") ; if ( stages != NULL ) { int ierr ; fprintf(info->msgFile, "\n stages[%d]", g->nvtx) ; IVfp80(info->msgFile, g->nvtx, stages, 80, &ierr) ; } fflush(info->msgFile) ; } /* ------------------------------- check the information structure ------------------------------- */ if ( MSMDinfo_isValid(info) != 1 ) { fprintf(stderr, "\n fatal error in MSMD_order(%p,%p,%p,%p)" "\n bad MSMDinfo object\n", msmd, g, stages, info) ; exit(-1) ; } /* --------------------- initialize the object --------------------- */ if ( info->msglvl > 3 ) { fprintf(info->msgFile, "\n\n trying to initialize MSMD object ") ; Graph_writeForHumanEye(g, info->msgFile) ; fflush(info->msgFile) ; } MSMD_init(msmd, g, stages, info) ; nvtx = g->nvtx ; nstage = info->nstage ; if ( info->msglvl > 2 ) { fprintf(info->msgFile, "\n\n MSMD object initialized, %d stages", nstage) ; fflush(info->msgFile) ; } /* ------------------------------------ load the reach set with all vertices ------------------------------------ */ if ( info->compressFlag / 4 >= 1 ) { /* ------------------ compress the graph ------------------ */ if ( info->msglvl > 2 ) { fprintf(info->msgFile, "\n\n initial compression") ; fflush(info->msgFile) ; } IV_setSize(&msmd->reachIV, nvtx) ; IV_ramp(&msmd->reachIV, 0, 1) ; MSMD_findInodes(msmd, info) ; if ( info->msglvl > 2 ) { fprintf(info->msgFile, "\n\n %d checked, %d found indistinguishable", info->stageInfo->ncheck, info->stageInfo->nindst) ; fflush(info->msgFile) ; } MSMD_cleanReachSet(msmd, info) ; /* for ( iv = 0, v = msmd->vertices ; iv < nvtx ; iv++, v++ ) { MSMD_cleanEdgeList(msmd, v, info) ; } */ } IV_setSize(&msmd->reachIV, 0) ; /* -------------------- loop over the stages -------------------- */ for ( info->istage = 0 ; info->istage <= nstage ; info->istage++ ) { if ( info->msglvl > 2 ) { fprintf(info->msgFile, "\n\n ##### elimination stage %d", info->istage) ; fflush(info->msgFile) ; } /* if ( info->istage == nstage ) { info->msglvl = 5 ; } */ MARKTIME(t1) ; MSMD_eliminateStage(msmd, info) ; MARKTIME(t2) ; info->stageInfo->cpu = t2 - t1 ; info->stageInfo++ ; } /* ------------- final cleanup ------------- */ { MSMDvtx *first, *last, *v ; IV_setSize(&msmd->reachIV, 0) ; first = msmd->vertices ; last = first + nvtx - 1 ; for ( v = first ; v <= last ; v++ ) { switch ( v->status ) { case 'E' : case 'L' : case 'I' : break ; default : IV_push(&msmd->reachIV, v->id) ; break ; } } /* fprintf(stdout, "\n reach set, %d entries", IV_size(&msmd->reachIV)) ; IV_writeForHumanEye(&msmd->reachIV, stdout) ; */ MSMD_findInodes(msmd, info) ; } /* --------------------------------------------------------- make info->stagInfo point back to beginning of the stages --------------------------------------------------------- */ info->stageInfo -= nstage + 1 ; /* ------------------------ get the total statistics ------------------------ */ for ( istage = 0, now = info->stageInfo, total = info->stageInfo + nstage + 1 ; istage <= nstage ; istage++, now++ ) { total->nstep += now->nstep ; total->nfront += now->nfront ; total->welim += now->welim ; total->nfind += now->nfind ; total->nzf += now->nzf ; total->ops += now->ops ; total->nexact2 += now->nexact2 ; total->nexact3 += now->nexact3 ; total->napprox += now->napprox ; total->ncheck += now->ncheck ; total->nindst += now->nindst ; total->noutmtch += now->noutmtch ; } /* ----------------------------------------------------- free some working storage (leave the MSMDvtx objects so the user can extract the permutations and/or ETree ----------------------------------------------------- */ IIheap_free(msmd->heap) ; msmd->heap = NULL ; IV_clearData(&msmd->ivtmpIV) ; IV_clearData(&msmd->reachIV) ; /* while ( (ip = msmd->baseIP) != NULL ) { msmd->baseIP = ip->next ; IP_free(ip) ; } */ MARKTIME(t3) ; info->totalCPU = t3 - t0 ; return ; }