Rev 155 | Blame | Last modification | View Log | Download | RSS feed
/** Copyright 1997, Regents of the University of Minnesota** ccgraph.c** This file contains the functions that create the coarse graph** Started 8/11/97* George** $Id: ccgraph.c,v 1.1 2003/12/31 21:32:30 bates Exp $**/#include <metis.h>/************************************************************************** This function creates the coarser graph**************************************************************************/void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm){int i, j, jj, k, kk, /* l, */ m, istart, iend, nvtxs, nedges, ncon,cnedges, v, u, mask, dovsize;idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;idxtype *cmap, *htable;idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;float *nvwgt, *cnvwgt;GraphType *cgraph;dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0);mask = HTLENGTH;if (cnvtxs < 8*mask || graph->nedges/graph->nvtxs > 15) {CreateCoarseGraphNoMask(ctrl, graph, cnvtxs, match, perm);return;}IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));nvtxs = graph->nvtxs;ncon = graph->ncon;xadj = graph->xadj;vwgt = graph->vwgt;vsize = graph->vsize;nvwgt = graph->nvwgt;adjncy = graph->adjncy;adjwgt = graph->adjwgt;adjwgtsum = graph->adjwgtsum;cmap = graph->cmap;/* Initialize the coarser graph */cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize);cxadj = cgraph->xadj;cvwgt = cgraph->vwgt;cvsize = cgraph->vsize;cnvwgt = cgraph->nvwgt;cadjwgtsum = cgraph->adjwgtsum;cadjncy = cgraph->adjncy;cadjwgt = cgraph->adjwgt;iend = xadj[nvtxs];auxadj = ctrl->wspace.auxcore;memcpy(auxadj, adjncy, iend*sizeof(idxtype));for (i=0; i<iend; i++)auxadj[i] = cmap[auxadj[i]];htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1));cxadj[0] = cnvtxs = cnedges = 0;for (i=0; i<nvtxs; i++) {v = perm[i];if (cmap[v] != cnvtxs)continue;u = match[v];if (ncon == 1)cvwgt[cnvtxs] = vwgt[v];elsescopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);if (dovsize)cvsize[cnvtxs] = vsize[v];cadjwgtsum[cnvtxs] = adjwgtsum[v];nedges = 0;istart = xadj[v];iend = xadj[v+1];for (j=istart; j<iend; j++) {k = auxadj[j];kk = k&mask;if ((m = htable[kk]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = adjwgt[j];htable[kk] = nedges++;}else if (cadjncy[m] == k) {cadjwgt[m] += adjwgt[j];}else {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == k) {cadjwgt[jj] += adjwgt[j];break;}}if (jj == nedges) {cadjncy[nedges] = k;cadjwgt[nedges++] = adjwgt[j];}}}if (v != u) {if (ncon == 1)cvwgt[cnvtxs] += vwgt[u];elsesaxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);if (dovsize)cvsize[cnvtxs] += vsize[u];cadjwgtsum[cnvtxs] += adjwgtsum[u];istart = xadj[u];iend = xadj[u+1];for (j=istart; j<iend; j++) {k = auxadj[j];kk = k&mask;if ((m = htable[kk]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = adjwgt[j];htable[kk] = nedges++;}else if (cadjncy[m] == k) {cadjwgt[m] += adjwgt[j];}else {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == k) {cadjwgt[jj] += adjwgt[j];break;}}if (jj == nedges) {cadjncy[nedges] = k;cadjwgt[nedges++] = adjwgt[j];}}}/* Remove the contracted adjacency weight */jj = htable[cnvtxs&mask];if (jj >= 0 && cadjncy[jj] != cnvtxs) {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == cnvtxs)break;}}if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */cadjwgtsum[cnvtxs] -= cadjwgt[jj];cadjncy[jj] = cadjncy[--nedges];cadjwgt[jj] = cadjwgt[nedges];}}ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));for (j=0; j<nedges; j++)htable[cadjncy[j]&mask] = -1; /* Zero out the htable */htable[cnvtxs&mask] = -1;cnedges += nedges;cxadj[++cnvtxs] = cnedges;cadjncy += nedges;cadjwgt += nedges;}cgraph->nedges = cnedges;ReAdjustMemory(graph, cgraph, dovsize);IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));idxwspacefree(ctrl, mask+1);}/************************************************************************** This function creates the coarser graph**************************************************************************/void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm){int i, j, k, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, dovsize;idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj;idxtype *cmap, *htable;idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum;float *nvwgt, *cnvwgt;GraphType *cgraph;dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0);IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));nvtxs = graph->nvtxs;ncon = graph->ncon;xadj = graph->xadj;vwgt = graph->vwgt;vsize = graph->vsize;nvwgt = graph->nvwgt;adjncy = graph->adjncy;adjwgt = graph->adjwgt;adjwgtsum = graph->adjwgtsum;cmap = graph->cmap;/* Initialize the coarser graph */cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize);cxadj = cgraph->xadj;cvwgt = cgraph->vwgt;cvsize = cgraph->vsize;cnvwgt = cgraph->nvwgt;cadjwgtsum = cgraph->adjwgtsum;cadjncy = cgraph->adjncy;cadjwgt = cgraph->adjwgt;htable = idxset(cnvtxs, -1, idxwspacemalloc(ctrl, cnvtxs));iend = xadj[nvtxs];auxadj = ctrl->wspace.auxcore;memcpy(auxadj, adjncy, iend*sizeof(idxtype));for (i=0; i<iend; i++)auxadj[i] = cmap[auxadj[i]];cxadj[0] = cnvtxs = cnedges = 0;for (i=0; i<nvtxs; i++) {v = perm[i];if (cmap[v] != cnvtxs)continue;u = match[v];if (ncon == 1)cvwgt[cnvtxs] = vwgt[v];elsescopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon);if (dovsize)cvsize[cnvtxs] = vsize[v];cadjwgtsum[cnvtxs] = adjwgtsum[v];nedges = 0;istart = xadj[v];iend = xadj[v+1];for (j=istart; j<iend; j++) {k = auxadj[j];if ((m = htable[k]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = adjwgt[j];htable[k] = nedges++;}else {cadjwgt[m] += adjwgt[j];}}if (v != u) {if (ncon == 1)cvwgt[cnvtxs] += vwgt[u];elsesaxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1);if (dovsize)cvsize[cnvtxs] += vsize[u];cadjwgtsum[cnvtxs] += adjwgtsum[u];istart = xadj[u];iend = xadj[u+1];for (j=istart; j<iend; j++) {k = auxadj[j];if ((m = htable[k]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = adjwgt[j];htable[k] = nedges++;}else {cadjwgt[m] += adjwgt[j];}}/* Remove the contracted adjacency weight */if ((j = htable[cnvtxs]) != -1) {ASSERT(cadjncy[j] == cnvtxs);cadjwgtsum[cnvtxs] -= cadjwgt[j];cadjncy[j] = cadjncy[--nedges];cadjwgt[j] = cadjwgt[nedges];htable[cnvtxs] = -1;}}ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d\n", cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt)));for (j=0; j<nedges; j++)htable[cadjncy[j]] = -1; /* Zero out the htable */cnedges += nedges;cxadj[++cnvtxs] = cnedges;cadjncy += nedges;cadjwgt += nedges;}cgraph->nedges = cnedges;ReAdjustMemory(graph, cgraph, dovsize);IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));idxwspacefree(ctrl, cnvtxs);}/************************************************************************** This function creates the coarser graph**************************************************************************/void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph,int cnvtxs, idxtype *match, idxtype *perm){int i, j, jj, k, kk, /* l, */ m, istart, iend, nvtxs, nedges, ncon,cnedges, v, u, mask;idxtype *xadj, *adjncy, *adjwgtsum, *auxadj;idxtype *cmap, *htable;idxtype *cxadj, *cvwgt, *cadjncy, *cadjwgt, *cadjwgtsum;float *nvwgt, *cnvwgt;GraphType *cgraph;IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));nvtxs = graph->nvtxs;ncon = graph->ncon;xadj = graph->xadj;nvwgt = graph->nvwgt;adjncy = graph->adjncy;adjwgtsum = graph->adjwgtsum;cmap = graph->cmap;/* Initialize the coarser graph */cgraph = SetUpCoarseGraph(graph, cnvtxs, 0);cxadj = cgraph->xadj;cvwgt = cgraph->vwgt;cnvwgt = cgraph->nvwgt;cadjwgtsum = cgraph->adjwgtsum;cadjncy = cgraph->adjncy;cadjwgt = cgraph->adjwgt;iend = xadj[nvtxs];auxadj = ctrl->wspace.auxcore;memcpy(auxadj, adjncy, iend*sizeof(idxtype));for (i=0; i<iend; i++)auxadj[i] = cmap[auxadj[i]];mask = HTLENGTH;htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1));cxadj[0] = cnvtxs = cnedges = 0;for (i=0; i<nvtxs; i++) {v = perm[i];if (cmap[v] != cnvtxs)continue;u = match[v];cvwgt[cnvtxs] = 1;cadjwgtsum[cnvtxs] = adjwgtsum[v];nedges = 0;istart = xadj[v];iend = xadj[v+1];for (j=istart; j<iend; j++) {k = auxadj[j];kk = k&mask;if ((m = htable[kk]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = 1;htable[kk] = nedges++;}else if (cadjncy[m] == k) {cadjwgt[m]++;}else {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == k) {cadjwgt[jj]++;break;}}if (jj == nedges) {cadjncy[nedges] = k;cadjwgt[nedges++] = 1;}}}if (v != u) {cvwgt[cnvtxs]++;cadjwgtsum[cnvtxs] += adjwgtsum[u];istart = xadj[u];iend = xadj[u+1];for (j=istart; j<iend; j++) {k = auxadj[j];kk = k&mask;if ((m = htable[kk]) == -1) {cadjncy[nedges] = k;cadjwgt[nedges] = 1;htable[kk] = nedges++;}else if (cadjncy[m] == k) {cadjwgt[m]++;}else {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == k) {cadjwgt[jj]++;break;}}if (jj == nedges) {cadjncy[nedges] = k;cadjwgt[nedges++] = 1;}}}/* Remove the contracted adjacency weight */jj = htable[cnvtxs&mask];if (jj >= 0 && cadjncy[jj] != cnvtxs) {for (jj=0; jj<nedges; jj++) {if (cadjncy[jj] == cnvtxs)break;}}if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */cadjwgtsum[cnvtxs] -= cadjwgt[jj];cadjncy[jj] = cadjncy[--nedges];cadjwgt[jj] = cadjwgt[nedges];}}ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v]));for (j=0; j<nedges; j++)htable[cadjncy[j]&mask] = -1; /* Zero out the htable */htable[cnvtxs&mask] = -1;cnedges += nedges;cxadj[++cnvtxs] = cnedges;cadjncy += nedges;cadjwgt += nedges;}cgraph->nedges = cnedges;ReAdjustMemory(graph, cgraph, 0);IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));idxwspacefree(ctrl, mask+1);}/************************************************************************** Setup the various arrays for the coarse graph**************************************************************************/GraphType *SetUpCoarseGraph(GraphType *graph, int cnvtxs, int dovsize){GraphType *cgraph;cgraph = CreateGraph();cgraph->nvtxs = cnvtxs;cgraph->ncon = graph->ncon;cgraph->finer = graph;graph->coarser = cgraph;/* Allocate memory for the coarser graph */if (graph->ncon == 1) {if (dovsize) {cgraph->gdata = idxmalloc(5*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");cgraph->xadj = cgraph->gdata;cgraph->vwgt = cgraph->gdata + cnvtxs+1;cgraph->vsize = cgraph->gdata + 2*cnvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 3*cnvtxs+1;cgraph->cmap = cgraph->gdata + 4*cnvtxs+1;cgraph->adjncy = cgraph->gdata + 5*cnvtxs+1;cgraph->adjwgt = cgraph->gdata + 5*cnvtxs+1 + graph->nedges;}else {cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");cgraph->xadj = cgraph->gdata;cgraph->vwgt = cgraph->gdata + cnvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1;cgraph->cmap = cgraph->gdata + 3*cnvtxs+1;cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1;cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges;}}else {if (dovsize) {cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");cgraph->xadj = cgraph->gdata;cgraph->vsize = cgraph->gdata + cnvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1;cgraph->cmap = cgraph->gdata + 3*cnvtxs+1;cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1;cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges;}else {cgraph->gdata = idxmalloc(3*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata");cgraph->xadj = cgraph->gdata;cgraph->adjwgtsum = cgraph->gdata + cnvtxs+1;cgraph->cmap = cgraph->gdata + 2*cnvtxs+1;cgraph->adjncy = cgraph->gdata + 3*cnvtxs+1;cgraph->adjwgt = cgraph->gdata + 3*cnvtxs+1 + graph->nedges;}cgraph->nvwgt = fmalloc(graph->ncon*cnvtxs, "SetUpCoarseGraph: nvwgt");}return cgraph;}/************************************************************************** This function re-adjusts the amount of memory that was allocated if* it will lead to significant savings**************************************************************************/void ReAdjustMemory(GraphType *graph, GraphType *cgraph, int dovsize){if (cgraph->nedges > 100000 && graph->nedges < 0.7*graph->nedges) {idxcopy(cgraph->nedges, cgraph->adjwgt, cgraph->adjncy+cgraph->nedges);if (graph->ncon == 1) {if (dovsize) {cgraph->gdata = realloc(cgraph->gdata, (5*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));/* Do this, in case everything was copied into new space */cgraph->xadj = cgraph->gdata;cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1;cgraph->vsize = cgraph->gdata + 2*cgraph->nvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 3*cgraph->nvtxs+1;cgraph->cmap = cgraph->gdata + 4*cgraph->nvtxs+1;cgraph->adjncy = cgraph->gdata + 5*cgraph->nvtxs+1;cgraph->adjwgt = cgraph->gdata + 5*cgraph->nvtxs+1 + cgraph->nedges;}else {cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));/* Do this, in case everything was copied into new space */cgraph->xadj = cgraph->gdata;cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1;cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1;cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1;cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges;}}else {if (dovsize) {cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));/* Do this, in case everything was copied into new space */cgraph->xadj = cgraph->gdata;cgraph->vsize = cgraph->gdata + cgraph->nvtxs+1;cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1;cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1;cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1;cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges;}else {cgraph->gdata = realloc(cgraph->gdata, (3*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype));/* Do this, in case everything was copied into new space */cgraph->xadj = cgraph->gdata;cgraph->adjwgtsum = cgraph->gdata + cgraph->nvtxs+1;cgraph->cmap = cgraph->gdata + 2*cgraph->nvtxs+1;cgraph->adjncy = cgraph->gdata + 3*cgraph->nvtxs+1;cgraph->adjwgt = cgraph->gdata + 3*cgraph->nvtxs+1 + cgraph->nedges;}}}}