/* orderViaND.c */
#include "../misc.h"
#include "../../timings.h"
/*
---------------------------------------------------------------------
COMPRESS_FRACTION ---
if # coarse graph vertices < COMPRESS_FRACTION * # of vertices then
use the compressed graph
endif
---------------------------------------------------------------------
*/
#define COMPRESS_FRACTION 0.75
/*--------------------------------------------------------------------*/
/*
------------------------------------------------------------------
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) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1