diff options
Diffstat (limited to 'benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c')
| -rw-r--r-- | benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c | 616 |
1 files changed, 616 insertions, 0 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c new file mode 100644 index 0000000..9a93784 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c @@ -0,0 +1,616 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * graph.c + * + * This file contains functions that deal with setting up the graphs + * for METIS. + * + * Started 7/25/97 + * George + * + * $Id: graph.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include <metis.h> + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, + idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag) +{ + int i, j, k, sum, gsize; + float *nvwgt; + idxtype tvwgt[MAXNCON]; + + if (OpType == OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) { + SetUpGraphKway(graph, nvtxs, xadj, adjncy); + return; + } + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + + if (ncon == 1) { /* We are in the non mC mode */ + gsize = 0; + if ((wgtflag&2) == 0) + gsize += nvtxs; + if ((wgtflag&1) == 0) + gsize += graph->nedges; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + + /* Create the vertex/edge weight vectors if they are not supplied */ + gsize = 0; + if ((wgtflag&2) == 0) { + vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vwgt = vwgt; + + if ((wgtflag&1) == 0) { + adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); + gsize += graph->nedges; + } + else + graph->adjwgt = adjwgt; + + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; i<nvtxs; i++) { + sum = 0; + for (j=xadj[i]; j<xadj[i+1]; j++) + sum += adjwgt[j]; + graph->adjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + else { /* Set up the graph in MOC mode */ + gsize = 0; + if ((wgtflag&1) == 0) + gsize += graph->nedges; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + gsize = 0; + + for (i=0; i<ncon; i++) + tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon); + + nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); + + for (i=0; i<nvtxs; i++) { + for (j=0; j<ncon; j++) + nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]); + } + + + /* Create the edge weight vectors if they are not supplied */ + if ((wgtflag&1) == 0) { + adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); + gsize += graph->nedges; + } + else + graph->adjwgt = adjwgt; + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; i<nvtxs; i++) { + sum = 0; + for (j=xadj[i]; j<xadj[i+1]; j++) + sum += adjwgt[j]; + graph->adjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + + if (OpType != OP_KMETIS && OpType != OP_KVMETIS) { + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + + for (i=0; i<nvtxs; i++) + graph->label[i] = i; + } + +} + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy) +{ + int i; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = 1; + graph->xadj = xadj; + graph->vwgt = NULL; + graph->adjncy = adjncy; + graph->adjwgt = NULL; + + graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); + graph->adjwgtsum = graph->gdata; + graph->cmap = graph->gdata + nvtxs; + + /* Compute the initial values of the adjwgtsum */ + for (i=0; i<nvtxs; i++) + graph->adjwgtsum[i] = xadj[i+1]-xadj[i]; + +} + + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, + idxtype *adjncy, float *nvwgt, idxtype *adjwgt) +{ + int i, j, sum; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + graph->adjwgt = adjwgt; + + graph->nvwgt = fmalloc(nvtxs*ncon, "SetUpGraph2: graph->nvwgt"); + scopy(nvtxs*ncon, nvwgt, graph->nvwgt); + + graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata; + for (i=0; i<nvtxs; i++) { + sum = 0; + for (j=xadj[i]; j<xadj[i+1]; j++) + sum += adjwgt[j]; + graph->adjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata+nvtxs; + + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + for (i=0; i<nvtxs; i++) + graph->label[i] = i; + +} + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, + idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag) +{ + int i, j, k, sum, gsize; + idxtype *adjwgt; + float *nvwgt; + idxtype tvwgt[MAXNCON]; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + + if (ncon == 1) { /* We are in the non mC mode */ + gsize = graph->nedges; /* This is for the edge weights */ + if ((wgtflag&2) == 0) + gsize += nvtxs; /* vwgts */ + if ((wgtflag&1) == 0) + gsize += nvtxs; /* vsize */ + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + + /* Create the vertex/edge weight vectors if they are not supplied */ + gsize = 0; + if ((wgtflag&2) == 0) { + vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vwgt = vwgt; + + if ((wgtflag&1) == 0) { + vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vsize = vsize; + + /* Allocate memory for edge weights and initialize them to the sum of the vsize */ + adjwgt = graph->adjwgt = graph->gdata+gsize; + gsize += graph->nedges; + + for (i=0; i<nvtxs; i++) { + for (j=xadj[i]; j<xadj[i+1]; j++) + adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]]; + } + + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; i<nvtxs; i++) { + sum = 0; + for (j=xadj[i]; j<xadj[i+1]; j++) + sum += adjwgt[j]; + graph->adjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + else { /* Set up the graph in MOC mode */ + gsize = graph->nedges; + if ((wgtflag&1) == 0) + gsize += nvtxs; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + gsize = 0; + + /* Create the normalized vertex weights along each constrain */ + if ((wgtflag&2) == 0) + vwgt = idxsmalloc(nvtxs, 1, "SetUpGraph: vwgt"); + + for (i=0; i<ncon; i++) + tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon); + + nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); + + for (i=0; i<nvtxs; i++) { + for (j=0; j<ncon; j++) + nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]); + } + if ((wgtflag&2) == 0) + free(vwgt); + + + /* Create the vsize vector if it is not supplied */ + if ((wgtflag&1) == 0) { + vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vsize = vsize; + + /* Allocate memory for edge weights and initialize them to the sum of the vsize */ + adjwgt = graph->adjwgt = graph->gdata+gsize; + gsize += graph->nedges; + + for (i=0; i<nvtxs; i++) { + for (j=xadj[i]; j<xadj[i+1]; j++) + adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]]; + } + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; i<nvtxs; i++) { + sum = 0; + for (j=xadj[i]; j<xadj[i+1]; j++) + sum += adjwgt[j]; + graph->adjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + + if (OpType != OP_KVMETIS) { + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + + for (i=0; i<nvtxs; i++) + graph->label[i] = i; + } + +} + + +/************************************************************************* +* This function randomly permutes the adjacency lists of a graph +**************************************************************************/ +void RandomizeGraph(GraphType *graph) +{ + int i, j, k, l, tmp, nvtxs; + idxtype *xadj, *adjncy, *adjwgt; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + for (i=0; i<nvtxs; i++) { + l = xadj[i+1]-xadj[i]; + for (j=xadj[i]; j<xadj[i+1]; j++) { + k = xadj[i] + RandomInRange(l); + SWAP(adjncy[j], adjncy[k], tmp); + SWAP(adjwgt[j], adjwgt[k], tmp); + } + } +} + + +/************************************************************************* +* This function checks whether or not partition pid is contigous +**************************************************************************/ +int IsConnectedSubdomain(CtrlType *ctrl, GraphType *graph, int pid, int report) +{ + int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; + idxtype *xadj, *adjncy, *where, *touched, *queue; + idxtype *cptr; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + cptr = idxmalloc(nvtxs+1, "IsConnected: cptr"); + + nleft = 0; + for (i=0; i<nvtxs; i++) { + if (where[i] == pid) + nleft++; + } + + for (i=0; i<nvtxs; i++) { + if (where[i] == pid) + break; + } + + touched[i] = 1; + queue[0] = i; + first = 0; last = 1; + + cptr[0] = 0; /* This actually points to queue */ + ncmps = 0; + while (first != nleft) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + for (i=0; i<nvtxs; i++) { + if (where[i] == pid && !touched[i]) + break; + } + queue[last++] = i; + touched[i] = 1; + } + + i = queue[first++]; + for (j=xadj[i]; j<xadj[i+1]; j++) { + k = adjncy[j]; + if (where[k] == pid && !touched[k]) { + queue[last++] = k; + touched[k] = 1; + } + } + } + cptr[++ncmps] = first; + + if (ncmps > 1 && report) { + printf("The graph has %d connected components in partition %d:\t", ncmps, pid); + for (i=0; i<ncmps; i++) { + wgt = 0; + for (j=cptr[i]; j<cptr[i+1]; j++) + wgt += graph->vwgt[queue[j]]; + printf("[%5d %5d] ", cptr[i+1]-cptr[i], wgt); + /* + if (cptr[i+1]-cptr[i] == 1) + printf("[%d %d] ", queue[cptr[i]], xadj[queue[cptr[i]]+1]-xadj[queue[cptr[i]]]); + */ + } + printf("\n"); + } + + GKfree(&touched, &queue, &cptr, LTERM); + + return (ncmps == 1 ? 1 : 0); +} + + +/************************************************************************* +* This function checks whether a graph is contigous or not +**************************************************************************/ +int IsConnected(CtrlType *ctrl, GraphType *graph, int report) +{ + int i, j, k, nvtxs, first, last; + idxtype *xadj, *adjncy, *touched, *queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + + touched[0] = 1; + queue[0] = 0; + first = 0; last = 1; + + while (first < last) { + i = queue[first++]; + for (j=xadj[i]; j<xadj[i+1]; j++) { + k = adjncy[j]; + if (!touched[k]) { + queue[last++] = k; + touched[k] = 1; + } + } + } + + if (first != nvtxs && report) + printf("The graph is not connected. It has %d disconnected vertices!\n", nvtxs-first); + + return (first == nvtxs ? 1 : 0); +} + + +/************************************************************************* +* This function checks whether or not partition pid is contigous +**************************************************************************/ +int IsConnected2(GraphType *graph, int report) +{ + int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; + idxtype *xadj, *adjncy, *where, *touched, *queue; + idxtype *cptr; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + cptr = idxmalloc(nvtxs+1, "IsConnected: cptr"); + + nleft = nvtxs; + touched[0] = 1; + queue[0] = 0; + first = 0; last = 1; + + cptr[0] = 0; /* This actually points to queue */ + ncmps = 0; + while (first != nleft) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + for (i=0; i<nvtxs; i++) { + if (!touched[i]) + break; + } + queue[last++] = i; + touched[i] = 1; + } + + i = queue[first++]; + for (j=xadj[i]; j<xadj[i+1]; j++) { + k = adjncy[j]; + if (!touched[k]) { + queue[last++] = k; + touched[k] = 1; + } + } + } + cptr[++ncmps] = first; + + if (ncmps > 1 && report) { + printf("%d connected components:\t", ncmps); + for (i=0; i<ncmps; i++) { + if (cptr[i+1]-cptr[i] > 200) + printf("[%5d] ", cptr[i+1]-cptr[i]); + } + printf("\n"); + } + + GKfree(&touched, &queue, &cptr, LTERM); + + return (ncmps == 1 ? 1 : 0); +} + + +/************************************************************************* +* This function returns the number of connected components in cptr,cind +* The separator of the graph is used to split it and then find its components. +**************************************************************************/ +int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind) +{ + int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; + idxtype *xadj, *adjncy, *where, *touched, *queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: queue"); + + for (i=0; i<graph->nbnd; i++) + touched[graph->bndind[i]] = 1; + + queue = cind; + + nleft = 0; + for (i=0; i<nvtxs; i++) { + if (where[i] != 2) + nleft++; + } + + for (i=0; i<nvtxs; i++) { + if (where[i] != 2) + break; + } + + touched[i] = 1; + queue[0] = i; + first = 0; last = 1; + + cptr[0] = 0; /* This actually points to queue */ + ncmps = 0; + while (first != nleft) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + for (i=0; i<nvtxs; i++) { + if (!touched[i]) + break; + } + queue[last++] = i; + touched[i] = 1; + } + + i = queue[first++]; + for (j=xadj[i]; j<xadj[i+1]; j++) { + k = adjncy[j]; + if (!touched[k]) { + queue[last++] = k; + touched[k] = 1; + } + } + } + cptr[++ncmps] = first; + + free(touched); + + return ncmps; +} + + + |
