/* -------------------------------------------------------- purpose -- return an ETree object for a multiple minimum degree ordering graph -- graph to order seed -- random number seed msglvl -- message level, 0 --> no output, 1 --> timings msgFile -- message file created -- 97nov08, cca -------------------------------------------------------- */ ETree * orderViaMMD ( Graph *graph, int seed, int msglvl, FILE *msgFile ) { double t1, t2 ; ETree *etree ; int nvtx, Nvtx ; IV *eqmapIV ; /* --------------- check the input --------------- */ if ( graph == NULL || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in orderViaMMD(%p,%d,%d,%p)" "\n bad input\n", graph, seed, msglvl, msgFile) ; exit(-1) ; } /* ------------------------------ compress the graph if worth it ------------------------------ */ nvtx = graph->nvtx ; MARKTIME(t1) ; eqmapIV = Graph_equivMap(graph) ; MARKTIME(t2) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : get equivalence map", t2 - t1) ; fflush(msgFile) ; } Nvtx = 1 + IV_max(eqmapIV) ; if ( Nvtx <= COMPRESS_FRACTION * nvtx ) { MARKTIME(t1) ; graph = Graph_compress2(graph, eqmapIV, 1) ; MARKTIME(t2) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : compress graph", t2 - t1) ; fflush(msgFile) ; } } else { IV_free(eqmapIV) ; eqmapIV = NULL ; } MARKTIME(t1) ; IVL_sortUp(graph->adjIVL) ; MARKTIME(t2) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : sort adjacency", t2 - t1) ; fflush(msgFile) ; } /* --------------------------------------------- order the vertices and extract the front tree --------------------------------------------- */ { MSMDinfo *info ; MSMD *msmd ; info = MSMDinfo_new() ; info->seed = seed ; info->compressFlag = 2 ; info->msglvl = msglvl ; info->msgFile = msgFile ; msmd = MSMD_new() ; MSMD_order(msmd, graph, NULL, info) ; etree = MSMD_frontETree(msmd) ; if ( msglvl > 1 ) { MSMDinfo_print(info, msgFile) ; } MSMDinfo_free(info) ; MSMD_free(msmd) ; } /* ------------------------------------------------- expand the front tree if the graph was compressed ------------------------------------------------- */ if ( eqmapIV != NULL ) { ETree *etree2 = ETree_expand(etree, eqmapIV) ; ETree_free(etree) ; etree = etree2 ; Graph_free(graph) ; IV_free(eqmapIV) ; } else { MARKTIME(t1) ; IVL_sortUp(graph->adjIVL) ; MARKTIME(t2) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : sort adjacency", t2 - t1) ; fflush(msgFile) ; } } return(etree) ; }
/* ------------------------------------------------------------------ purpose -- return an ETree object for a nested dissection ordering graph -- graph to order maxdomainsize -- used to control the incomplete nested dissection process. any subgraph whose weight is less than maxdomainsize is not split further. seed -- random number seed msglvl -- message level, 0 --> no output, 1 --> timings msgFile -- message file created -- 97nov06, cca ------------------------------------------------------------------ */ ETree * orderViaND ( Graph *graph, int maxdomainsize, int seed, int msglvl, FILE *msgFile ) { double t1, t2 ; DSTree *dstree ; ETree *etree ; int nvtx, Nvtx ; IV *eqmapIV, *stagesIV ; /* --------------- check the input --------------- */ if ( graph == NULL || maxdomainsize <= 0 || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in orderViaND(%p,%d,%d,%d,%p)" "\n bad input\n", graph, maxdomainsize, seed, msglvl, msgFile) ; exit(-1) ; } /* ------------------------------ compress the graph if worth it ------------------------------ */ nvtx = graph->nvtx ; MARKTIME(t1) ; eqmapIV = Graph_equivMap(graph) ; MARKTIME(t2) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n CPU %8.3f : get equivalence map", t2 - t1) ; fflush(msgFile) ; } Nvtx = 1 + IV_max(eqmapIV) ; if ( Nvtx <= COMPRESS_FRACTION * nvtx ) { MARKTIME(t1) ; graph = Graph_compress2(graph, eqmapIV, 1) ; MARKTIME(t2) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n CPU %8.3f : compress graph", t2 - t1) ; fflush(msgFile) ; } } else { IV_free(eqmapIV) ; eqmapIV = NULL ; } MARKTIME(t1) ; IVL_sortUp(graph->adjIVL) ; MARKTIME(t2) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n CPU %8.3f : sort adjacency", t2 - t1) ; fflush(msgFile) ; } /* ----------------------------- get the domain separator tree ----------------------------- */ { GPart *gpart ; DDsepInfo *info ; info = DDsepInfo_new() ; info->seed = seed ; info->maxcompweight = maxdomainsize ; info->alpha = 0.1 ; gpart = GPart_new() ; GPart_init(gpart, graph) ; GPart_setMessageInfo(gpart, msglvl, msgFile) ; dstree = GPart_RBviaDDsep(gpart, info) ; DSTree_renumberViaPostOT(dstree) ; if ( msglvl > 0 ) { DDsepInfo_writeCpuTimes(info, msgFile) ; } DDsepInfo_free(info) ; GPart_free(gpart) ; } /* --------------------- get the stages vector --------------------- */ stagesIV = DSTree_NDstages(dstree) ; DSTree_free(dstree) ; /* --------------------------------------------- order the vertices and extract the front tree --------------------------------------------- */ { MSMDinfo *info ; MSMD *msmd ; info = MSMDinfo_new() ; info->seed = seed ; info->compressFlag = 2 ; info->msglvl = msglvl ; info->msgFile = msgFile ; msmd = MSMD_new() ; MSMD_order(msmd, graph, IV_entries(stagesIV), info) ; etree = MSMD_frontETree(msmd) ; if ( msglvl > 0 ) { MSMDinfo_print(info, msgFile) ; } MSMDinfo_free(info) ; MSMD_free(msmd) ; IV_free(stagesIV) ; } /* ------------------------------------------------- expand the front tree if the graph was compressed ------------------------------------------------- */ if ( eqmapIV != NULL ) { ETree *etree2 = ETree_expand(etree, eqmapIV) ; ETree_free(etree) ; etree = etree2 ; Graph_free(graph) ; IV_free(eqmapIV) ; } else { MARKTIME(t1) ; IVL_sortUp(graph->adjIVL) ; MARKTIME(t2) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n CPU %8.3f : sort adjacency", t2 - t1) ; fflush(msgFile) ; } } return(etree) ; }
/* ------------------------------------------------------------------- purpose -- given an InpMtx object that contains the structure of A, initialize the bridge data structure for the serial factor's and solve's. note: all parameters are pointers to be compatible with fortran's call by reference. return value -- 1 -- normal return -1 -- bridge is NULL -2 -- mtxA is NULL created -- 98sep17, cca ------------------------------------------------------------------- */ int BridgeMT_setup ( BridgeMT *bridge, InpMtx *mtxA ) { double t0, t1, t2 ; ETree *frontETree ; FILE *msgFile ; Graph *graph ; int compressed, msglvl, nedges, neqns, Neqns ; IV *eqmapIV ; IVL *adjIVL, *symbfacIVL ; MARKTIME(t0) ; /* -------------------- check the input data -------------------- */ if ( bridge == NULL ) { fprintf(stderr, "\n fatal error in BridgeMT_setup()" "\n data is NULL\n") ; return(-1) ; } if ( mtxA == NULL ) { fprintf(stderr, "\n fatal error in BridgeMT_setup()" "\n A is NULL\n") ; return(-2) ; } msglvl = bridge->msglvl ; msgFile = bridge->msgFile ; neqns = bridge->neqns ; if ( ! (INPMTX_IS_BY_ROWS(mtxA) || INPMTX_IS_BY_COLUMNS(mtxA)) ) { /* ------------------------------ change coordinate type to rows ------------------------------ */ InpMtx_changeCoordType(mtxA, INPMTX_BY_ROWS) ; } if ( ! INPMTX_IS_BY_VECTORS(mtxA) ) { /* ------------------------------ change storage mode to vectors ------------------------------ */ InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; } /* --------------------------- create a Graph object for A --------------------------- */ MARKTIME(t1) ; graph = Graph_new() ; adjIVL = InpMtx_fullAdjacency(mtxA); nedges = bridge->nedges = IVL_tsize(adjIVL), Graph_init2(graph, 0, neqns, 0, nedges, neqns, nedges, adjIVL, NULL, NULL) ; MARKTIME(t2) ; bridge->cpus[0] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to create Graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n graph of the input matrix") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } /* ------------------ compress the graph ------------------ */ MARKTIME(t1) ; eqmapIV = Graph_equivMap(graph) ; Neqns = bridge->Neqns = 1 + IV_max(eqmapIV) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n graph's equivalence map") ; IV_writeForHumanEye(eqmapIV, msgFile) ; fflush(msgFile) ; } if ( Neqns < bridge->compressCutoff * neqns ) { Graph *cgraph ; /* ------------------ compress the graph ------------------ */ cgraph = Graph_compress2(graph, eqmapIV, 1) ; Graph_free(graph) ; graph = cgraph ; compressed = 1 ; bridge->Nedges = graph->nedges ; } else { compressed = 0 ; } MARKTIME(t2) ; bridge->cpus[1] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to create compressed graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n graph to order") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } /* --------------- order the graph --------------- */ MARKTIME(t1) ; if ( bridge->maxdomainsize <= 0 ) { bridge->maxdomainsize = neqns/32 ; } if ( bridge->maxdomainsize <= 0 ) { bridge->maxdomainsize = 1 ; } if ( bridge->maxnzeros < 0 ) { bridge->maxnzeros = 0.01*neqns ; } if ( bridge->maxsize < 0 ) { bridge->maxsize = neqns ; } frontETree = orderViaBestOfNDandMS(graph, bridge->maxdomainsize, bridge->maxnzeros, bridge->maxsize, bridge->seed, msglvl, msgFile) ; MARKTIME(t2) ; bridge->cpus[2] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to order graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n front tree from ordering") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } MARKTIME(t1) ; if ( compressed == 1 ) { ETree *etree ; IVL *tempIVL ; /* ---------------------------------------------------------- compute the symbolic factorization of the compressed graph ---------------------------------------------------------- */ tempIVL = SymbFac_initFromGraph(frontETree, graph) ; /* ------------------------------------------------------- expand the symbolic factorization to the original graph ------------------------------------------------------- */ symbfacIVL = IVL_expand(tempIVL, eqmapIV) ; IVL_free(tempIVL) ; /* --------------------- expand the front tree --------------------- */ etree = ETree_expand(frontETree, eqmapIV) ; ETree_free(frontETree) ; frontETree = etree ; } else { /* -------------------------------------------------------- compute the symbolic factorization of the original graph -------------------------------------------------------- */ symbfacIVL = SymbFac_initFromGraph(frontETree, graph) ; } MARKTIME(t2) ; bridge->frontETree = frontETree ; bridge->symbfacIVL = symbfacIVL ; /* ---------------------------------------------- get the old-to-new and new-to-old permutations ---------------------------------------------- */ bridge->oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ; bridge->newToOldIV = ETree_newToOldVtxPerm(frontETree) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n old-to-new permutation") ; IV_writeForHumanEye(bridge->oldToNewIV, msgFile) ; fprintf(msgFile, "\n\n new-to-old permutation") ; IV_writeForHumanEye(bridge->newToOldIV, msgFile) ; fflush(msgFile) ; } /* ------------------------------------------------------ overwrite the symbolic factorization with the permuted indices and sort the lists into ascending order ------------------------------------------------------ */ IVL_overwrite(symbfacIVL, bridge->oldToNewIV) ; IVL_sortUp(symbfacIVL) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n symbolic factorization") ; IVL_writeForHumanEye(symbfacIVL, msgFile) ; fflush(msgFile) ; } /* -------------------------------------- permute the vertices in the front tree -------------------------------------- */ ETree_permuteVertices(frontETree, bridge->oldToNewIV) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n permuted front etree") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } MARKTIME(t2) ; bridge->cpus[3] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time for symbolic factorization", t2 - t1) ; fflush(msgFile) ; } /* ------------------------ free the working storage ------------------------ */ Graph_free(graph) ; IV_free(eqmapIV) ; MARKTIME(t2) ; bridge->cpus[4] += t2 - t0 ; return(1) ; }