Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/srefine.c
3206 views
/*1* Copyright 1997, Regents of the University of Minnesota2*3* srefine.c4*5* This file contains code for the separator refinement algortihms6*7* Started 8/1/978* George9*10* $Id: srefine.c 10515 2011-07-08 15:46:18Z karypis $11*12*/1314#include "metislib.h"151617/*************************************************************************/18/*! This function is the entry point of the separator refinement.19It does not perform any refinement on graph, but it starts by first20projecting it to the next level finer graph and proceeds from there. */21/*************************************************************************/22void Refine2WayNode(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph)23{2425IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));2627if (graph == orggraph) {28Compute2WayNodePartitionParams(ctrl, graph);29}30else {31do {32graph = graph->finer;3334IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));35Project2WayNodePartition(ctrl, graph);36IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));3738IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));39FM_2WayNodeBalance(ctrl, graph);4041ASSERT(CheckNodePartitionParams(graph));4243switch (ctrl->rtype) {44case METIS_RTYPE_SEP2SIDED:45FM_2WayNodeRefine2Sided(ctrl, graph, ctrl->niter);46break;47case METIS_RTYPE_SEP1SIDED:48FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter);49break;50default:51gk_errexit(SIGERR, "Unknown rtype of %d\n", ctrl->rtype);52}53IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));5455} while (graph != orggraph);56}5758IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));59}606162/*************************************************************************/63/*! This function allocates memory for 2-way node-based refinement */64/**************************************************************************/65void Allocate2WayNodePartitionMemory(ctrl_t *ctrl, graph_t *graph)66{67idx_t nvtxs;6869nvtxs = graph->nvtxs;7071graph->pwgts = imalloc(3, "Allocate2WayNodePartitionMemory: pwgts");72graph->where = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: where");73graph->bndptr = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndptr");74graph->bndind = imalloc(nvtxs, "Allocate2WayNodePartitionMemory: bndind");75graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "Allocate2WayNodePartitionMemory: nrinfo");76}777879/*************************************************************************/80/*! This function computes the edegrees[] to the left & right sides */81/*************************************************************************/82void Compute2WayNodePartitionParams(ctrl_t *ctrl, graph_t *graph)83{84idx_t i, j, nvtxs, nbnd;85idx_t *xadj, *adjncy, *vwgt;86idx_t *where, *pwgts, *bndind, *bndptr, *edegrees;87nrinfo_t *rinfo;88idx_t me, other;8990nvtxs = graph->nvtxs;91xadj = graph->xadj;92vwgt = graph->vwgt;93adjncy = graph->adjncy;9495where = graph->where;96rinfo = graph->nrinfo;97pwgts = iset(3, 0, graph->pwgts);98bndind = graph->bndind;99bndptr = iset(nvtxs, -1, graph->bndptr);100101102/*------------------------------------------------------------103/ Compute now the separator external degrees104/------------------------------------------------------------*/105nbnd = 0;106for (i=0; i<nvtxs; i++) {107me = where[i];108pwgts[me] += vwgt[i];109110ASSERT(me >=0 && me <= 2);111112if (me == 2) { /* If it is on the separator do some computations */113BNDInsert(nbnd, bndind, bndptr, i);114115edegrees = rinfo[i].edegrees;116edegrees[0] = edegrees[1] = 0;117118for (j=xadj[i]; j<xadj[i+1]; j++) {119other = where[adjncy[j]];120if (other != 2)121edegrees[other] += vwgt[adjncy[j]];122}123}124}125126ASSERT(CheckNodeBnd(graph, nbnd));127128graph->mincut = pwgts[2];129graph->nbnd = nbnd;130}131132133/*************************************************************************/134/*! This function projects the node-based bisection */135/*************************************************************************/136void Project2WayNodePartition(ctrl_t *ctrl, graph_t *graph)137{138idx_t i, j, nvtxs;139idx_t *cmap, *where, *cwhere;140graph_t *cgraph;141142cgraph = graph->coarser;143cwhere = cgraph->where;144145nvtxs = graph->nvtxs;146cmap = graph->cmap;147148Allocate2WayNodePartitionMemory(ctrl, graph);149where = graph->where;150151/* Project the partition */152for (i=0; i<nvtxs; i++) {153where[i] = cwhere[cmap[i]];154ASSERTP(where[i] >= 0 && where[i] <= 2, ("%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"\n",155i, cmap[i], where[i], cwhere[cmap[i]]));156}157158FreeGraph(&graph->coarser);159graph->coarser = NULL;160161Compute2WayNodePartitionParams(ctrl, graph);162}163164165