Files
2008-04-15 18:56:58 +01:00

156 lines
4.1 KiB
C

/*
* Copyright 1997, Regents of the University of Minnesota
*
* estmem.c
*
* This file contains code for estimating the amount of memory required by
* the various routines in METIS
*
* Started 11/4/97
* George
*
*/
#include <metislib.h>
/*************************************************************************
* This function computes how much memory will be required by the various
* routines in METIS
**************************************************************************/
void METIS_EstimateMemory(idxtype *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *numflag, idxtype *optype, idxtype *nbytes)
{
idxtype i, j, k, nedges, nlevels;
float vfraction, efraction, vmult, emult;
idxtype coresize, gdata, rdata;
if (*numflag == 1)
Change2CNumbering(*nvtxs, xadj, adjncy);
nedges = xadj[*nvtxs];
InitRandom(-1);
EstimateCFraction(*nvtxs, xadj, adjncy, &vfraction, &efraction);
/* Estimate the amount of memory for coresize */
if (*optype == 2)
coresize = nedges;
else
coresize = 0;
coresize += nedges + 11*(*nvtxs) + 4*1024 + 2*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype));
coresize += 2*(*nvtxs); /* add some more fore other vectors */
gdata = nedges; /* Agk_fsume that the user does not pass weights */
nlevels = (int)(log(100.0/(*nvtxs))/log(vfraction) + .5);
vmult = 0.5 + (1.0 - pow(vfraction, nlevels))/(1.0 - vfraction);
emult = 1.0 + (1.0 - pow(efraction, nlevels+1))/(1.0 - efraction);
gdata += vmult*4*(*nvtxs) + emult*2*nedges;
if ((vmult-1.0)*4*(*nvtxs) + (emult-1.0)*2*nedges < 5*(*nvtxs))
rdata = 0;
else
rdata = 5*(*nvtxs);
*nbytes = sizeof(idxtype)*(coresize+gdata+rdata+(*nvtxs));
if (*numflag == 1)
Change2FNumbering2(*nvtxs, xadj, adjncy);
}
/*************************************************************************
* This function finds a matching using the HEM heuristic
**************************************************************************/
void EstimateCFraction(idxtype nvtxs, idxtype *xadj, idxtype *adjncy, float *vfraction, float *efraction)
{
idxtype i, ii, j, cnvtxs, cnedges, maxidx;
idxtype *match, *cmap, *perm;
cmap = idxmalloc(nvtxs, "cmap");
match = idxsmalloc(nvtxs, UNMATCHED, "match");
perm = idxmalloc(nvtxs, "perm");
RandomPermute(nvtxs, perm, 1);
cnvtxs = 0;
for (ii=0; ii<nvtxs; ii++) {
i = perm[ii];
if (match[i] == UNMATCHED) { /* Unmatched */
maxidx = i;
/* Find a random matching, subject to maxvwgt constraints */
for (j=xadj[i]; j<xadj[i+1]; j++) {
if (match[adjncy[j]] == UNMATCHED) {
maxidx = adjncy[j];
break;
}
}
cmap[i] = cmap[maxidx] = cnvtxs++;
match[i] = maxidx;
match[maxidx] = i;
}
}
cnedges = ComputeCoarseGraphSize(nvtxs, xadj, adjncy, cnvtxs, cmap, match, perm);
*vfraction = (1.0*cnvtxs)/(1.0*nvtxs);
*efraction = (1.0*cnedges)/(1.0*xadj[nvtxs]);
gk_free((void **)&cmap, &match, &perm, LTERM);
}
/*************************************************************************
* This function computes the size of the coarse graph
**************************************************************************/
idxtype ComputeCoarseGraphSize(idxtype nvtxs, idxtype *xadj, idxtype *adjncy, idxtype cnvtxs, idxtype *cmap, idxtype *match, idxtype *perm)
{
idxtype i, j, k, istart, iend, nedges, cnedges, v, u;
idxtype *htable;
htable = idxsmalloc(cnvtxs, -1, "htable");
cnvtxs = cnedges = 0;
for (i=0; i<nvtxs; i++) {
v = perm[i];
if (cmap[v] != cnvtxs)
continue;
htable[cnvtxs] = cnvtxs;
u = match[v];
istart = xadj[v];
iend = xadj[v+1];
for (j=istart; j<iend; j++) {
k = cmap[adjncy[j]];
if (htable[k] != cnvtxs) {
htable[k] = cnvtxs;
cnedges++;
}
}
if (v != u) {
istart = xadj[u];
iend = xadj[u+1];
for (j=istart; j<iend; j++) {
k = cmap[adjncy[j]];
if (htable[k] != cnvtxs) {
htable[k] = cnvtxs;
cnedges++;
}
}
}
cnvtxs++;
}
gk_free((void **)&htable, LTERM);
return cnedges;
}