00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "metislib.h"
00016
00017
00018
00019
00020
00021 void ComputePartitionInfoBipartite(graph_t *graph, idx_t nparts, idx_t *where)
00022 {
00023 idx_t i, j, k, nvtxs, ncon, mustfree=0;
00024 idx_t *xadj, *adjncy, *vwgt, *vsize, *adjwgt, *kpwgts, *tmpptr;
00025 idx_t *padjncy, *padjwgt, *padjcut;
00026
00027 nvtxs = graph->nvtxs;
00028 ncon = graph->ncon;
00029 xadj = graph->xadj;
00030 adjncy = graph->adjncy;
00031 vwgt = graph->vwgt;
00032 vsize = graph->vsize;
00033 adjwgt = graph->adjwgt;
00034
00035 if (vwgt == NULL) {
00036 vwgt = graph->vwgt = ismalloc(nvtxs, 1, "vwgt");
00037 mustfree = 1;
00038 }
00039 if (adjwgt == NULL) {
00040 adjwgt = graph->adjwgt = ismalloc(xadj[nvtxs], 1, "adjwgt");
00041 mustfree += 2;
00042 }
00043
00044 printf("%"PRIDX"-way Cut: %5"PRIDX", Vol: %5"PRIDX", ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where));
00045
00046
00047 kpwgts = ismalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts");
00048
00049 for (i=0; i<nvtxs; i++) {
00050 for (j=0; j<ncon; j++)
00051 kpwgts[where[i]*ncon+j] += vwgt[i*ncon+j];
00052 }
00053
00054 if (ncon == 1) {
00055 printf("\tBalance: %5.3"PRREAL" out of %5.3"PRREAL"\n",
00056 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1)),
00057 1.0*nparts*vwgt[iargmax(nvtxs, vwgt)]/(1.0*isum(nparts, kpwgts, 1)));
00058 }
00059 else {
00060 printf("\tBalance:");
00061 for (j=0; j<ncon; j++)
00062 printf(" (%5.3"PRREAL" out of %5.3"PRREAL")",
00063 1.0*nparts*kpwgts[ncon*iargmax_strd(nparts, kpwgts+j, ncon)+j]/(1.0*isum(nparts, kpwgts+j, ncon)),
00064 1.0*nparts*vwgt[ncon*iargmax_strd(nvtxs, vwgt+j, ncon)+j]/(1.0*isum(nparts, kpwgts+j, ncon)));
00065 printf("\n");
00066 }
00067
00068
00069
00070 padjncy = ismalloc(nparts*nparts, 0, "ComputePartitionInfo: padjncy");
00071 padjwgt = ismalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
00072 padjcut = ismalloc(nparts*nparts, 0, "ComputePartitionInfo: padjwgt");
00073
00074 iset(nparts, 0, kpwgts);
00075 for (i=0; i<nvtxs; i++) {
00076 for (j=xadj[i]; j<xadj[i+1]; j++) {
00077 if (where[i] != where[adjncy[j]]) {
00078 padjncy[where[i]*nparts+where[adjncy[j]]] = 1;
00079 padjcut[where[i]*nparts+where[adjncy[j]]] += adjwgt[j];
00080 if (kpwgts[where[adjncy[j]]] == 0) {
00081 padjwgt[where[i]*nparts+where[adjncy[j]]] += vsize[i];
00082 kpwgts[where[adjncy[j]]] = 1;
00083 }
00084 }
00085 }
00086 for (j=xadj[i]; j<xadj[i+1]; j++)
00087 kpwgts[where[adjncy[j]]] = 0;
00088 }
00089
00090 for (i=0; i<nparts; i++)
00091 kpwgts[i] = isum(nparts, padjncy+i*nparts, 1);
00092 printf("Min/Max/Avg/Bal # of adjacent subdomains: %5"PRIDX" %5"PRIDX" %5"PRIDX" %7.3"PRREAL"\n",
00093 kpwgts[iargmin(nparts, kpwgts)], kpwgts[iargmax(nparts, kpwgts)], isum(nparts, kpwgts, 1)/nparts,
00094 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1)));
00095
00096 for (i=0; i<nparts; i++)
00097 kpwgts[i] = isum(nparts, padjcut+i*nparts, 1);
00098 printf("Min/Max/Avg/Bal # of adjacent subdomain cuts: %5"PRIDX" %5"PRIDX" %5"PRIDX" %7.3"PRREAL"\n",
00099 kpwgts[iargmin(nparts, kpwgts)], kpwgts[iargmax(nparts, kpwgts)], isum(nparts, kpwgts, 1)/nparts,
00100 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1)));
00101
00102 for (i=0; i<nparts; i++)
00103 kpwgts[i] = isum(nparts, padjwgt+i*nparts, 1);
00104 printf("Min/Max/Avg/Bal/Frac # of interface nodes: %5"PRIDX" %5"PRIDX" %5"PRIDX" %7.3"PRREAL" %7.3"PRREAL"\n",
00105 kpwgts[iargmin(nparts, kpwgts)], kpwgts[iargmax(nparts, kpwgts)], isum(nparts, kpwgts, 1)/nparts,
00106 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1)), 1.0*isum(nparts, kpwgts, 1)/(1.0*nvtxs));
00107
00108
00109 if (mustfree == 1 || mustfree == 3) {
00110 gk_free((void **)&vwgt, LTERM);
00111 graph->vwgt = NULL;
00112 }
00113 if (mustfree == 2 || mustfree == 3) {
00114 gk_free((void **)&adjwgt, LTERM);
00115 graph->adjwgt = NULL;
00116 }
00117
00118 gk_free((void **)&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM);
00119 }
00120
00121
00122
00123
00124
00125 void ComputePartitionBalance(graph_t *graph, idx_t nparts, idx_t *where, real_t *ubvec)
00126 {
00127 idx_t i, j, nvtxs, ncon;
00128 idx_t *kpwgts, *vwgt;
00129 real_t balance;
00130
00131 nvtxs = graph->nvtxs;
00132 ncon = graph->ncon;
00133 vwgt = graph->vwgt;
00134
00135 kpwgts = ismalloc(nparts, 0, "ComputePartitionInfo: kpwgts");
00136
00137 if (vwgt == NULL) {
00138 for (i=0; i<nvtxs; i++)
00139 kpwgts[where[i]]++;
00140 ubvec[0] = 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*nvtxs);
00141 }
00142 else {
00143 for (j=0; j<ncon; j++) {
00144 iset(nparts, 0, kpwgts);
00145 for (i=0; i<graph->nvtxs; i++)
00146 kpwgts[where[i]] += vwgt[i*ncon+j];
00147
00148 ubvec[j] = 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1));
00149 }
00150 }
00151
00152 gk_free((void **)&kpwgts, LTERM);
00153
00154 }
00155
00156
00157
00158
00159
00160 real_t ComputeElementBalance(idx_t ne, idx_t nparts, idx_t *where)
00161 {
00162 idx_t i;
00163 idx_t *kpwgts;
00164 real_t balance;
00165
00166 kpwgts = ismalloc(nparts, 0, "ComputeElementBalance: kpwgts");
00167
00168 for (i=0; i<ne; i++)
00169 kpwgts[where[i]]++;
00170
00171 balance = 1.0*nparts*kpwgts[iargmax(nparts, kpwgts)]/(1.0*isum(nparts, kpwgts, 1));
00172
00173 gk_free((void **)&kpwgts, LTERM);
00174
00175 return balance;
00176
00177 }
00178
00179