Cloned library METIS with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

219 lines
7.3 KiB

/*!
\file
\brief Functions dealing with memory allocation and workspace management
\date Started 2/24/96
\author George
\author Copyright 1997-2009, Regents of the University of Minnesota
\version $Id: wspace.c 10492 2011-07-06 09:28:42Z karypis $
*/
#include "metislib.h"
/*************************************************************************/
/*! This function allocates memory for the workspace */
/*************************************************************************/
void AllocateWorkSpace(ctrl_t *ctrl, graph_t *graph)
{
size_t coresize;
switch (ctrl->optype) {
case METIS_OP_PMETIS:
coresize = 3*(graph->nvtxs+1)*sizeof(idx_t) +
5*(ctrl->nparts+1)*graph->ncon*sizeof(idx_t) +
5*(ctrl->nparts+1)*graph->ncon*sizeof(real_t);
break;
default:
coresize = 4*(graph->nvtxs+1)*sizeof(idx_t) +
5*(ctrl->nparts+1)*graph->ncon*sizeof(idx_t) +
5*(ctrl->nparts+1)*graph->ncon*sizeof(real_t);
}
ctrl->mcore = gk_mcoreCreate(coresize);
ctrl->nbrpoolsize = 0;
ctrl->nbrpoolcpos = 0;
}
/*************************************************************************/
/*! This function allocates refinement-specific memory for the workspace */
/*************************************************************************/
void AllocateRefinementWorkSpace(ctrl_t *ctrl, idx_t nbrpoolsize_max, idx_t nbrpoolsize)
{
ctrl->nbrpoolsize_max = nbrpoolsize_max;
ctrl->nbrpoolsize = nbrpoolsize;
ctrl->nbrpoolcpos = 0;
ctrl->nbrpoolreallocs = 0;
switch (ctrl->objtype) {
case METIS_OBJTYPE_CUT:
ctrl->cnbrpool = (cnbr_t *)gk_malloc(ctrl->nbrpoolsize*sizeof(cnbr_t),
"AllocateRefinementWorkSpace: cnbrpool");
break;
case METIS_OBJTYPE_VOL:
ctrl->vnbrpool = (vnbr_t *)gk_malloc(ctrl->nbrpoolsize*sizeof(vnbr_t),
"AllocateRefinementWorkSpace: vnbrpool");
break;
default:
gk_errexit(SIGERR, "Unknown objtype of %d\n", ctrl->objtype);
}
/* Allocate the memory for the sparse subdomain graph */
if (ctrl->minconn) {
ctrl->pvec1 = imalloc(ctrl->nparts+1, "AllocateRefinementWorkSpace: pvec1");
ctrl->pvec2 = imalloc(ctrl->nparts+1, "AllocateRefinementWorkSpace: pvec2");
ctrl->maxnads = ismalloc(ctrl->nparts, INIT_MAXNAD, "AllocateRefinementWorkSpace: maxnads");
ctrl->nads = imalloc(ctrl->nparts, "AllocateRefinementWorkSpace: nads");
ctrl->adids = iAllocMatrix(ctrl->nparts, INIT_MAXNAD, 0, "AllocateRefinementWorkSpace: adids");
ctrl->adwgts = iAllocMatrix(ctrl->nparts, INIT_MAXNAD, 0, "AllocateRefinementWorkSpace: adwgts");
}
}
/*************************************************************************/
/*! This function frees the workspace */
/*************************************************************************/
void FreeWorkSpace(ctrl_t *ctrl)
{
gk_mcoreDestroy(&ctrl->mcore, ctrl->dbglvl&METIS_DBG_INFO);
IFSET(ctrl->dbglvl, METIS_DBG_INFO,
printf(" nbrpool statistics\n"
" nbrpoolsize: %12zu nbrpoolcpos: %12zu\n"
" nbrpoolreallocs: %12zu\n\n",
ctrl->nbrpoolsize, ctrl->nbrpoolcpos,
ctrl->nbrpoolreallocs));
gk_free((void **)&ctrl->cnbrpool, &ctrl->vnbrpool, LTERM);
ctrl->nbrpoolsize_max = 0;
ctrl->nbrpoolsize = 0;
ctrl->nbrpoolcpos = 0;
if (ctrl->minconn) {
iFreeMatrix(&(ctrl->adids), ctrl->nparts, INIT_MAXNAD);
iFreeMatrix(&(ctrl->adwgts), ctrl->nparts, INIT_MAXNAD);
gk_free((void **)&ctrl->pvec1, &ctrl->pvec2,
&ctrl->maxnads, &ctrl->nads, LTERM);
}
}
/*************************************************************************/
/*! This function allocate space from the workspace/heap */
/*************************************************************************/
void *wspacemalloc(ctrl_t *ctrl, size_t nbytes)
{
return gk_mcoreMalloc(ctrl->mcore, nbytes);
}
/*************************************************************************/
/*! This function sets a marker in the stack of malloc ops to be used
subsequently for freeing purposes */
/*************************************************************************/
void wspacepush(ctrl_t *ctrl)
{
gk_mcorePush(ctrl->mcore);
}
/*************************************************************************/
/*! This function frees all mops since the last push */
/*************************************************************************/
void wspacepop(ctrl_t *ctrl)
{
gk_mcorePop(ctrl->mcore);
}
/*************************************************************************/
/*! This function allocate space from the core */
/*************************************************************************/
idx_t *iwspacemalloc(ctrl_t *ctrl, idx_t n)
{
return (idx_t *)wspacemalloc(ctrl, n*sizeof(idx_t));
}
/*************************************************************************/
/*! This function allocate space from the core */
/*************************************************************************/
real_t *rwspacemalloc(ctrl_t *ctrl, idx_t n)
{
return (real_t *)wspacemalloc(ctrl, n*sizeof(real_t));
}
/*************************************************************************/
/*! This function allocate space from the core */
/*************************************************************************/
ikv_t *ikvwspacemalloc(ctrl_t *ctrl, idx_t n)
{
return (ikv_t *)wspacemalloc(ctrl, n*sizeof(ikv_t));
}
/*************************************************************************/
/*! This function resets the cnbrpool */
/*************************************************************************/
void cnbrpoolReset(ctrl_t *ctrl)
{
ctrl->nbrpoolcpos = 0;
}
/*************************************************************************/
/*! This function gets the next free index from cnbrpool */
/*************************************************************************/
idx_t cnbrpoolGetNext(ctrl_t *ctrl, idx_t nnbrs)
{
nnbrs = gk_min(ctrl->nparts, nnbrs);
ctrl->nbrpoolcpos += nnbrs;
if (ctrl->nbrpoolcpos > ctrl->nbrpoolsize) {
ctrl->nbrpoolsize += gk_max(10*nnbrs, ctrl->nbrpoolsize/2);
ctrl->nbrpoolsize = gk_min(ctrl->nbrpoolsize, ctrl->nbrpoolsize_max);
ctrl->cnbrpool = (cnbr_t *)gk_realloc(ctrl->cnbrpool,
ctrl->nbrpoolsize*sizeof(cnbr_t), "cnbrpoolGet: cnbrpool");
ctrl->nbrpoolreallocs++;
}
return ctrl->nbrpoolcpos - nnbrs;
}
/*************************************************************************/
/*! This function resets the vnbrpool */
/*************************************************************************/
void vnbrpoolReset(ctrl_t *ctrl)
{
ctrl->nbrpoolcpos = 0;
}
/*************************************************************************/
/*! This function gets the next free index from vnbrpool */
/*************************************************************************/
idx_t vnbrpoolGetNext(ctrl_t *ctrl, idx_t nnbrs)
{
nnbrs = gk_min(ctrl->nparts, nnbrs);
ctrl->nbrpoolcpos += nnbrs;
if (ctrl->nbrpoolcpos > ctrl->nbrpoolsize) {
ctrl->nbrpoolsize += gk_max(10*nnbrs, ctrl->nbrpoolsize/2);
ctrl->nbrpoolsize = gk_min(ctrl->nbrpoolsize, ctrl->nbrpoolsize_max);
ctrl->vnbrpool = (vnbr_t *)gk_realloc(ctrl->vnbrpool,
ctrl->nbrpoolsize*sizeof(vnbr_t), "vnbrpoolGet: vnbrpool");
ctrl->nbrpoolreallocs++;
}
return ctrl->nbrpoolcpos - nnbrs;
}