Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/graph.c
3206 views
/**1\file2\brief Functions that deal with setting up the graphs for METIS.34\date Started 7/25/19975\author George6\author Copyright 1997-2009, Regents of the University of Minnesota7\version\verbatim $Id: graph.c 10513 2011-07-07 22:06:03Z karypis $ \endverbatim8*/910#include "metislib.h"111213/*************************************************************************/14/*! This function sets up the graph from the user input */15/*************************************************************************/16graph_t *SetupGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t ncon, idx_t *xadj,17idx_t *adjncy, idx_t *vwgt, idx_t *vsize, idx_t *adjwgt)18{19idx_t i, j, k, sum;20real_t *nvwgt;21graph_t *graph;2223/* allocate the graph and fill in the fields */24graph = CreateGraph();2526graph->nvtxs = nvtxs;27graph->nedges = xadj[nvtxs];28graph->ncon = ncon;2930graph->xadj = xadj;31graph->free_xadj = 0;3233graph->adjncy = adjncy;34graph->free_adjncy = 0;353637/* setup the vertex weights */38if (vwgt) {39graph->vwgt = vwgt;40graph->free_vwgt = 0;41}42else {43vwgt = graph->vwgt = ismalloc(ncon*nvtxs, 1, "SetupGraph: vwgt");44}4546graph->tvwgt = imalloc(ncon, "SetupGraph: tvwgts");47graph->invtvwgt = rmalloc(ncon, "SetupGraph: invtvwgts");48for (i=0; i<ncon; i++) {49graph->tvwgt[i] = isum(nvtxs, vwgt+i, ncon);50graph->invtvwgt[i] = 1.0/(graph->tvwgt[i] > 0 ? graph->tvwgt[i] : 1);51}525354if (ctrl->objtype == METIS_OBJTYPE_VOL) {55/* Setup the vsize */56if (vsize) {57graph->vsize = vsize;58graph->free_vsize = 0;59}60else {61vsize = graph->vsize = ismalloc(nvtxs, 1, "SetupGraph: vsize");62}6364/* Allocate memory for edge weights and initialize them to the sum of the vsize */65adjwgt = graph->adjwgt = imalloc(graph->nedges, "SetupGraph: adjwgt");66for (i=0; i<nvtxs; i++) {67for (j=xadj[i]; j<xadj[i+1]; j++)68adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];69}70}71else { /* For edgecut minimization */72/* setup the edge weights */73if (adjwgt) {74graph->adjwgt = adjwgt;75graph->free_adjwgt = 0;76}77else {78adjwgt = graph->adjwgt = ismalloc(graph->nedges, 1, "SetupGraph: adjwgt");79}80}818283/* setup various derived info */84SetupGraph_tvwgt(graph);8586if (ctrl->optype == METIS_OP_PMETIS || ctrl->optype == METIS_OP_OMETIS)87SetupGraph_label(graph);8889ASSERT(CheckGraph(graph, ctrl->numflag, 1));9091return graph;92}939495/*************************************************************************/96/*! Set's up the tvwgt/invtvwgt info */97/*************************************************************************/98void SetupGraph_tvwgt(graph_t *graph)99{100idx_t i;101102if (graph->tvwgt == NULL)103graph->tvwgt = imalloc(graph->ncon, "SetupGraph_tvwgt: tvwgt");104if (graph->invtvwgt == NULL)105graph->invtvwgt = rmalloc(graph->ncon, "SetupGraph_tvwgt: invtvwgt");106107for (i=0; i<graph->ncon; i++) {108graph->tvwgt[i] = isum(graph->nvtxs, graph->vwgt+i, graph->ncon);109graph->invtvwgt[i] = 1.0/(graph->tvwgt[i] > 0 ? graph->tvwgt[i] : 1);110}111}112113114/*************************************************************************/115/*! Set's up the label info */116/*************************************************************************/117void SetupGraph_label(graph_t *graph)118{119idx_t i;120121if (graph->label == NULL)122graph->label = imalloc(graph->nvtxs, "SetupGraph_label: label");123124for (i=0; i<graph->nvtxs; i++)125graph->label[i] = i;126}127128129/*************************************************************************/130/*! Setup the various arrays for the splitted graph */131/*************************************************************************/132graph_t *SetupSplitGraph(graph_t *graph, idx_t snvtxs, idx_t snedges)133{134graph_t *sgraph;135136sgraph = CreateGraph();137138sgraph->nvtxs = snvtxs;139sgraph->nedges = snedges;140sgraph->ncon = graph->ncon;141142/* Allocate memory for the splitted graph */143sgraph->xadj = imalloc(snvtxs+1, "SetupSplitGraph: xadj");144sgraph->vwgt = imalloc(sgraph->ncon*snvtxs, "SetupSplitGraph: vwgt");145sgraph->adjncy = imalloc(snedges, "SetupSplitGraph: adjncy");146sgraph->adjwgt = imalloc(snedges, "SetupSplitGraph: adjwgt");147sgraph->label = imalloc(snvtxs, "SetupSplitGraph: label");148sgraph->tvwgt = imalloc(sgraph->ncon, "SetupSplitGraph: tvwgt");149sgraph->invtvwgt = rmalloc(sgraph->ncon, "SetupSplitGraph: invtvwgt");150151if (graph->vsize)152sgraph->vsize = imalloc(snvtxs, "SetupSplitGraph: vsize");153154return sgraph;155}156157158/*************************************************************************/159/*! This function creates and initializes a graph_t data structure */160/*************************************************************************/161graph_t *CreateGraph(void)162{163graph_t *graph;164165graph = (graph_t *)gk_malloc(sizeof(graph_t), "CreateGraph: graph");166167InitGraph(graph);168169return graph;170}171172173/*************************************************************************/174/*! This function initializes a graph_t data structure */175/*************************************************************************/176void InitGraph(graph_t *graph)177{178memset((void *)graph, 0, sizeof(graph_t));179180/* graph size constants */181graph->nvtxs = -1;182graph->nedges = -1;183graph->ncon = -1;184graph->mincut = -1;185graph->minvol = -1;186graph->nbnd = -1;187188/* memory for the graph structure */189graph->xadj = NULL;190graph->vwgt = NULL;191graph->vsize = NULL;192graph->adjncy = NULL;193graph->adjwgt = NULL;194graph->label = NULL;195graph->cmap = NULL;196graph->tvwgt = NULL;197graph->invtvwgt = NULL;198199/* by default these are set to true, but the can be explicitly changed afterwards */200graph->free_xadj = 1;201graph->free_vwgt = 1;202graph->free_vsize = 1;203graph->free_adjncy = 1;204graph->free_adjwgt = 1;205206207/* memory for the partition/refinement structure */208graph->where = NULL;209graph->pwgts = NULL;210graph->id = NULL;211graph->ed = NULL;212graph->bndptr = NULL;213graph->bndind = NULL;214graph->nrinfo = NULL;215graph->ckrinfo = NULL;216graph->vkrinfo = NULL;217218/* linked-list structure */219graph->coarser = NULL;220graph->finer = NULL;221}222223224/*************************************************************************/225/*! This function frees the refinement/partition memory stored in a graph */226/*************************************************************************/227void FreeRData(graph_t *graph)228{229230/* The following is for the -minconn and -contig to work properly in231the vol-refinement routines */232if ((void *)graph->ckrinfo == (void *)graph->vkrinfo)233graph->ckrinfo = NULL;234235236/* free partition/refinement structure */237gk_free((void **)&graph->where, &graph->pwgts, &graph->id, &graph->ed,238&graph->bndptr, &graph->bndind, &graph->nrinfo, &graph->ckrinfo,239&graph->vkrinfo, LTERM);240}241242243/*************************************************************************/244/*! This function deallocates any memory stored in a graph */245/*************************************************************************/246void FreeGraph(graph_t **r_graph)247{248graph_t *graph;249250graph = *r_graph;251252/* free graph structure */253if (graph->free_xadj)254gk_free((void **)&graph->xadj, LTERM);255if (graph->free_vwgt)256gk_free((void **)&graph->vwgt, LTERM);257if (graph->free_vsize)258gk_free((void **)&graph->vsize, LTERM);259if (graph->free_adjncy)260gk_free((void **)&graph->adjncy, LTERM);261if (graph->free_adjwgt)262gk_free((void **)&graph->adjwgt, LTERM);263264/* free partition/refinement structure */265FreeRData(graph);266267gk_free((void **)&graph->tvwgt, &graph->invtvwgt, &graph->label,268&graph->cmap, &graph, LTERM);269270*r_graph = NULL;271}272273274275276