/************************************************************************* * 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 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 computes cuts and balance information **************************************************************************/ void ComputePartitionInfo(GraphType *graph, int nparts, idxtype *where) { int i, j, /*k,*/ nvtxs, ncon, mustfree=0; idxtype *xadj, *adjncy, *vwgt, *adjwgt, *kpwgts, *tmpptr; idxtype *padjncy, *padjwgt, *padjcut; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; adjncy = graph->adjncy; vwgt = graph->vwgt; adjwgt = graph->adjwgt; if (vwgt == NULL) { vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt"); mustfree = 1; } if (adjwgt == NULL) { adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt"); mustfree += 2; } printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where)); /* Compute balance information */ kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts"); for (i=0; i<nvtxs; i++) { for (j=0; j<ncon; j++) kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j]; } if (ncon == 1) { printf("\tBalance: %5.3f out of %5.3f\n", 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*nparts*vwgt[idxamax(nvtxs, vwgt)]/(1.0*idxsum(nparts, kpwgts))); } else { printf("\tBalance:"); for (j=0; j<ncon; j++) printf(" (%5.3f out of %5.3f)", 1.0*nparts*kpwgts[ncon*idxamax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon)), 1.0*nparts*vwgt[ncon*idxamax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*idxsum_strd(nparts, kpwgts+j, ncon))); printf("\n"); } /* Compute p-adjncy information */ padjncy = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy"); padjwgt = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); padjcut = idxsmalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt"); idxset(nparts, 0, kpwgts); for (i=0; i<nvtxs; i++) { for (j=xadj[i]; j<xadj[i+1]; j++) { if (where[i] != where[adjncy[j]]) { padjncy[where[i]*nparts+where[adjncy[j]]] = 1; padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j]; if (kpwgts[where[adjncy[j]]] == 0) { padjwgt[where[i]*nparts+where[adjncy[j]]]++; kpwgts[where[adjncy[j]]] = 1; } } } for (j=xadj[i]; j<xadj[i+1]; j++) kpwgts[where[adjncy[j]]] = 0; } for (i=0; i<nparts; i++) kpwgts[i] = idxsum(nparts, padjncy+i*nparts); printf("Min/Max/Avg/Bal # of adjacent subdomains: %5d %5d %5.2f %7.3f\n", kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], 1.0*idxsum(nparts, kpwgts)/(1.0*nparts), 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); for (i=0; i<nparts; i++) kpwgts[i] = idxsum(nparts, padjcut+i*nparts); printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5d %5d %5d %7.3f\n", kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts))); for (i=0; i<nparts; i++) kpwgts[i] = idxsum(nparts, padjwgt+i*nparts); printf("Min/Max/Avg/Bal/Frac # of interface nodes: %5d %5d %5d %7.3f %7.3f\n", kpwgts[idxamin(nparts, kpwgts)], kpwgts[idxamax(nparts, kpwgts)], idxsum(nparts, kpwgts)/nparts, 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)), 1.0*idxsum(nparts, kpwgts)/(1.0*nvtxs)); tmpptr = graph->where; graph->where = where; for (i=0; i<nparts; i++) IsConnectedSubdomain(NULL, graph, i, 1); graph->where = tmpptr; if (mustfree == 1 || mustfree == 3) { free(vwgt); graph->vwgt = NULL; } if (mustfree == 2 || mustfree == 3) { free(adjwgt); graph->adjwgt = NULL; } GKfree((void**)&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM); }