00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "metislib.h"
00016
00017
00018
00019
00020
00021
00022 int METIS_PartMeshNodal(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind,
00023 idx_t *vwgt, idx_t *vsize, idx_t *nparts, real_t *tpwgts,
00024 idx_t *options, idx_t *objval, idx_t *epart, idx_t *npart)
00025 {
00026 int sigrval=0, renumber=0, ptype;
00027 idx_t *xadj=NULL, *adjncy=NULL;
00028 idx_t ncon=1, pnumflag=0;
00029 int rstatus=METIS_OK;
00030
00031
00032 if (!gk_malloc_init())
00033 return METIS_ERROR_MEMORY;
00034
00035 gk_sigtrap();
00036
00037 if ((sigrval = gk_sigcatch()) != 0)
00038 goto SIGTHROW;
00039
00040 renumber = GETOPTION(options, METIS_OPTION_NUMBERING, 0);
00041 ptype = GETOPTION(options, METIS_OPTION_PTYPE, METIS_PTYPE_KWAY);
00042
00043
00044 if (renumber) {
00045 ChangeMesh2CNumbering(*ne, eptr, eind);
00046 options[METIS_OPTION_NUMBERING] = 0;
00047 }
00048
00049
00050 rstatus = METIS_MeshToNodal(ne, nn, eptr, eind, &pnumflag, &xadj, &adjncy);
00051 if (rstatus != METIS_OK)
00052 raise(SIGERR);
00053
00054
00055 if (ptype == METIS_PTYPE_KWAY)
00056 rstatus = METIS_PartGraphKway(nn, &ncon, xadj, adjncy, vwgt, vsize, NULL,
00057 nparts, tpwgts, NULL, options, objval, npart);
00058 else
00059 rstatus = METIS_PartGraphRecursive(nn, &ncon, xadj, adjncy, vwgt, vsize, NULL,
00060 nparts, tpwgts, NULL, options, objval, npart);
00061
00062 if (rstatus != METIS_OK)
00063 raise(SIGERR);
00064
00065
00066 InduceRowPartFromColumnPart(*ne, eptr, eind, epart, npart, *nparts, tpwgts);
00067
00068
00069 SIGTHROW:
00070 if (renumber) {
00071 ChangeMesh2FNumbering2(*ne, *nn, eptr, eind, epart, npart);
00072 options[METIS_OPTION_NUMBERING] = 1;
00073 }
00074
00075 METIS_Free(xadj);
00076 METIS_Free(adjncy);
00077
00078 gk_siguntrap();
00079 gk_malloc_cleanup(0);
00080
00081 return metis_rcode(sigrval);
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 int METIS_PartMeshDual(idx_t *ne, idx_t *nn, idx_t *eptr, idx_t *eind,
00091 idx_t *vwgt, idx_t *vsize, idx_t *ncommon, idx_t *nparts,
00092 real_t *tpwgts, idx_t *options, idx_t *objval, idx_t *epart,
00093 idx_t *npart)
00094 {
00095 int sigrval=0, renumber=0, ptype;
00096 idx_t i, j;
00097 idx_t *xadj=NULL, *adjncy=NULL, *nptr=NULL, *nind=NULL;
00098 idx_t ncon=1, pnumflag=0;
00099 int rstatus = METIS_OK;
00100
00101
00102 if (!gk_malloc_init())
00103 return METIS_ERROR_MEMORY;
00104
00105 gk_sigtrap();
00106
00107 if ((sigrval = gk_sigcatch()) != 0)
00108 goto SIGTHROW;
00109
00110 renumber = GETOPTION(options, METIS_OPTION_NUMBERING, 0);
00111 ptype = GETOPTION(options, METIS_OPTION_PTYPE, METIS_PTYPE_KWAY);
00112
00113
00114 if (renumber) {
00115 ChangeMesh2CNumbering(*ne, eptr, eind);
00116 options[METIS_OPTION_NUMBERING] = 0;
00117 }
00118
00119
00120 rstatus = METIS_MeshToDual(ne, nn, eptr, eind, ncommon, &pnumflag, &xadj, &adjncy);
00121 if (rstatus != METIS_OK)
00122 raise(SIGERR);
00123
00124
00125 if (ptype == METIS_PTYPE_KWAY)
00126 rstatus = METIS_PartGraphKway(ne, &ncon, xadj, adjncy, vwgt, vsize, NULL,
00127 nparts, tpwgts, NULL, options, objval, epart);
00128 else
00129 rstatus = METIS_PartGraphRecursive(ne, &ncon, xadj, adjncy, vwgt, vsize, NULL,
00130 nparts, tpwgts, NULL, options, objval, epart);
00131
00132 if (rstatus != METIS_OK)
00133 raise(SIGERR);
00134
00135
00136
00137 nptr = ismalloc(*nn+1, 0, "METIS_PartMeshDual: nptr");
00138 nind = imalloc(eptr[*ne], "METIS_PartMeshDual: nind");
00139
00140 for (i=0; i<*ne; i++) {
00141 for (j=eptr[i]; j<eptr[i+1]; j++)
00142 nptr[eind[j]]++;
00143 }
00144 MAKECSR(i, *nn, nptr);
00145
00146 for (i=0; i<*ne; i++) {
00147 for (j=eptr[i]; j<eptr[i+1]; j++)
00148 nind[nptr[eind[j]]++] = i;
00149 }
00150 SHIFTCSR(i, *nn, nptr);
00151
00152
00153 InduceRowPartFromColumnPart(*nn, nptr, nind, npart, epart, *nparts, tpwgts);
00154
00155 gk_free((void **)&nptr, &nind, LTERM);
00156
00157
00158 SIGTHROW:
00159 if (renumber) {
00160 ChangeMesh2FNumbering2(*ne, *nn, eptr, eind, epart, npart);
00161 options[METIS_OPTION_NUMBERING] = 1;
00162 }
00163
00164 METIS_Free(xadj);
00165 METIS_Free(adjncy);
00166
00167 gk_siguntrap();
00168 gk_malloc_cleanup(0);
00169
00170 return metis_rcode(sigrval);
00171 }
00172
00173
00174
00175
00178
00179 void InduceRowPartFromColumnPart(idx_t nrows, idx_t *rowptr, idx_t *rowind,
00180 idx_t *rpart, idx_t *cpart, idx_t nparts, real_t *tpwgts)
00181 {
00182 idx_t i, j, k, me;
00183 idx_t nnbrs, *pwgts, *nbrdom, *nbrwgt, *nbrmrk;
00184 idx_t *itpwgts;
00185
00186 pwgts = ismalloc(nparts, 0, "InduceRowPartFromColumnPart: pwgts");
00187 nbrdom = ismalloc(nparts, 0, "InduceRowPartFromColumnPart: nbrdom");
00188 nbrwgt = ismalloc(nparts, 0, "InduceRowPartFromColumnPart: nbrwgt");
00189 nbrmrk = ismalloc(nparts, -1, "InduceRowPartFromColumnPart: nbrmrk");
00190
00191 iset(nrows, -1, rpart);
00192
00193
00194 itpwgts = imalloc(nparts, "InduceRowPartFromColumnPart: itpwgts");
00195 if (tpwgts == NULL) {
00196 iset(nparts, 1+nrows/nparts, itpwgts);
00197 }
00198 else {
00199 for (i=0; i<nparts; i++)
00200 itpwgts[i] = 1+nrows*tpwgts[i];
00201 }
00202
00203
00204
00205 for (i=0; i<nrows; i++) {
00206 if (rowptr[i+1]-rowptr[i] == 0) {
00207 rpart[i] = -2;
00208 continue;
00209 }
00210
00211 me = cpart[rowind[rowptr[i]]];
00212 for (j=rowptr[i]+1; j<rowptr[i+1]; j++) {
00213 if (cpart[rowind[j]] != me)
00214 break;
00215 }
00216 if (j == rowptr[i+1]) {
00217 rpart[i] = me;
00218 pwgts[me]++;
00219 }
00220 }
00221
00222
00223
00224 for (i=0; i<nrows; i++) {
00225 if (rpart[i] == -1) {
00226 for (nnbrs=0, j=rowptr[i]; j<rowptr[i+1]; j++) {
00227 me = cpart[rowind[j]];
00228 if (nbrmrk[me] == -1) {
00229 nbrdom[nnbrs] = me;
00230 nbrwgt[nnbrs] = 1;
00231 nbrmrk[me] = nnbrs++;
00232 }
00233 else {
00234 nbrwgt[nbrmrk[me]]++;
00235 }
00236 }
00237 ASSERT(nnbrs > 0);
00238
00239
00240 rpart[i] = nbrdom[iargmax(nnbrs, nbrwgt)];
00241
00242
00243 if (pwgts[rpart[i]] > itpwgts[rpart[i]]) {
00244 for (j=0; j<nnbrs; j++) {
00245 if (pwgts[nbrdom[j]] < itpwgts[nbrdom[j]] ||
00246 pwgts[nbrdom[j]]-itpwgts[nbrdom[j]] < pwgts[rpart[i]]-itpwgts[rpart[i]]) {
00247 rpart[i] = nbrdom[j];
00248 break;
00249 }
00250 }
00251 }
00252 pwgts[rpart[i]]++;
00253
00254
00255 for (j=0; j<nnbrs; j++)
00256 nbrmrk[nbrdom[j]] = -1;
00257 }
00258 }
00259
00260 gk_free((void **)&pwgts, &nbrdom, &nbrwgt, &nbrmrk, &itpwgts, LTERM);
00261
00262 }