Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/refine.c
3206 views
/*1\file2\brief This file contains the driving routines for multilevel refinement34\date Started 7/24/19975\author George6\author Copyright 1997-2009, Regents of the University of Minnesota7\version\verbatim $Id: refine.c 10513 2011-07-07 22:06:03Z karypis $ \endverbatim8*/910#include "metislib.h"111213/*************************************************************************/14/*! This function is the entry point of refinement */15/*************************************************************************/16void Refine2Way(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph, real_t *tpwgts)17{1819IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));2021/* Compute the parameters of the coarsest graph */22Compute2WayPartitionParams(ctrl, graph);2324for (;;) {25ASSERT(CheckBnd(graph));2627IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));2829Balance2Way(ctrl, graph, tpwgts);3031FM_2WayRefine(ctrl, graph, tpwgts, ctrl->niter);3233IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));3435if (graph == orggraph)36break;3738graph = graph->finer;39IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));40Project2WayPartition(ctrl, graph);41IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));42}4344IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));45}464748/*************************************************************************/49/*! This function allocates memory for 2-way edge refinement */50/*************************************************************************/51void Allocate2WayPartitionMemory(ctrl_t *ctrl, graph_t *graph)52{53idx_t nvtxs, ncon;5455nvtxs = graph->nvtxs;56ncon = graph->ncon;5758graph->pwgts = imalloc(2*ncon, "Allocate2WayPartitionMemory: pwgts");59graph->where = imalloc(nvtxs, "Allocate2WayPartitionMemory: where");60graph->bndptr = imalloc(nvtxs, "Allocate2WayPartitionMemory: bndptr");61graph->bndind = imalloc(nvtxs, "Allocate2WayPartitionMemory: bndind");62graph->id = imalloc(nvtxs, "Allocate2WayPartitionMemory: id");63graph->ed = imalloc(nvtxs, "Allocate2WayPartitionMemory: ed");64}656667/*************************************************************************/68/*! This function computes the initial id/ed */69/*************************************************************************/70void Compute2WayPartitionParams(ctrl_t *ctrl, graph_t *graph)71{72idx_t i, j, nvtxs, ncon, nbnd, mincut, istart, iend, tid, ted, me;73idx_t *xadj, *vwgt, *adjncy, *adjwgt, *pwgts;74idx_t *where, *bndptr, *bndind, *id, *ed;7576nvtxs = graph->nvtxs;77ncon = graph->ncon;78xadj = graph->xadj;79vwgt = graph->vwgt;80adjncy = graph->adjncy;81adjwgt = graph->adjwgt;8283where = graph->where;84id = graph->id;85ed = graph->ed;8687pwgts = iset(2*ncon, 0, graph->pwgts);88bndptr = iset(nvtxs, -1, graph->bndptr);89bndind = graph->bndind;9091/* Compute pwgts */92if (ncon == 1) {93for (i=0; i<nvtxs; i++) {94ASSERT(where[i] >= 0 && where[i] <= 1);95pwgts[where[i]] += vwgt[i];96}97ASSERT(pwgts[0]+pwgts[1] == graph->tvwgt[0]);98}99else {100for (i=0; i<nvtxs; i++) {101me = where[i];102for (j=0; j<ncon; j++)103pwgts[me*ncon+j] += vwgt[i*ncon+j];104}105}106107108/* Compute the required info for refinement */109for (nbnd=0, mincut=0, i=0; i<nvtxs; i++) {110istart = xadj[i];111iend = xadj[i+1];112113me = where[i];114tid = ted = 0;115116for (j=istart; j<iend; j++) {117if (me == where[adjncy[j]])118tid += adjwgt[j];119else120ted += adjwgt[j];121}122id[i] = tid;123ed[i] = ted;124125if (ted > 0 || istart == iend) {126BNDInsert(nbnd, bndind, bndptr, i);127mincut += ted;128}129}130131graph->mincut = mincut/2;132graph->nbnd = nbnd;133134}135136137/*************************************************************************/138/*! Projects a partition and computes the refinement params. */139/*************************************************************************/140void Project2WayPartition(ctrl_t *ctrl, graph_t *graph)141{142idx_t i, j, istart, iend, nvtxs, nbnd, me, tid, ted;143idx_t *xadj, *adjncy, *adjwgt;144idx_t *cmap, *where, *bndptr, *bndind;145idx_t *cwhere, *cbndptr;146idx_t *id, *ed;147graph_t *cgraph;148149Allocate2WayPartitionMemory(ctrl, graph);150151cgraph = graph->coarser;152cwhere = cgraph->where;153cbndptr = cgraph->bndptr;154155nvtxs = graph->nvtxs;156cmap = graph->cmap;157xadj = graph->xadj;158adjncy = graph->adjncy;159adjwgt = graph->adjwgt;160161where = graph->where;162id = graph->id;163ed = graph->ed;164165bndptr = iset(nvtxs, -1, graph->bndptr);166bndind = graph->bndind;167168/* Project the partition and record which of these nodes came from the169coarser boundary */170for (i=0; i<nvtxs; i++) {171j = cmap[i];172where[i] = cwhere[j];173cmap[i] = cbndptr[j];174}175176/* Compute the refinement information of the nodes */177for (nbnd=0, i=0; i<nvtxs; i++) {178istart = xadj[i];179iend = xadj[i+1];180181tid = ted = 0;182if (cmap[i] == -1) { /* Interior node. Note that cmap[i] = cbndptr[cmap[i]] */183for (j=istart; j<iend; j++)184tid += adjwgt[j];185}186else { /* Potentially an interface node */187me = where[i];188for (j=istart; j<iend; j++) {189if (me == where[adjncy[j]])190tid += adjwgt[j];191else192ted += adjwgt[j];193}194}195id[i] = tid;196ed[i] = ted;197198if (ted > 0 || istart == iend)199BNDInsert(nbnd, bndind, bndptr, i);200}201graph->mincut = cgraph->mincut;202graph->nbnd = nbnd;203204/* copy pwgts */205icopy(2*graph->ncon, cgraph->pwgts, graph->pwgts);206207FreeGraph(&graph->coarser);208graph->coarser = NULL;209}210211212213