00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <parmetislib.h>
00016
00017
00018
00019
00020
00021
00022 GraphType *Moc_MoveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace)
00023 {
00024 int h, i, ii, j, jj, nvtxs, ncon, nparts;
00025 idxtype *xadj, *vwgt, *adjncy, *adjwgt, *mvtxdist;
00026 idxtype *where, *newlabel, *lpwgts, *gpwgts;
00027 idxtype *sgraph, *rgraph;
00028 KeyValueType *sinfo, *rinfo;
00029 GraphType *mgraph;
00030
00031 nparts = ctrl->nparts;
00032 ASSERT(ctrl, nparts == ctrl->npes);
00033
00034 nvtxs = graph->nvtxs;
00035 ncon = graph->ncon;
00036 xadj = graph->xadj;
00037 vwgt = graph->vwgt;
00038 adjncy = graph->adjncy;
00039 adjwgt = graph->adjwgt;
00040 where = graph->where;
00041
00042 mvtxdist = idxmalloc(nparts+1, "MoveGraph: mvtxdist");
00043
00044
00045 lpwgts = wspace->pv1;
00046 gpwgts = wspace->pv2;
00047 sinfo = wspace->pepairs1;
00048 rinfo = wspace->pepairs2;
00049 for (i=0; i<nparts; i++)
00050 sinfo[i].key = sinfo[i].val = 0;
00051
00052 for (i=0; i<nvtxs; i++) {
00053 sinfo[where[i]].key++;
00054 sinfo[where[i]].val += xadj[i+1]-xadj[i];
00055 }
00056 for (i=0; i<nparts; i++)
00057 lpwgts[i] = sinfo[i].key;
00058
00059 MPI_Scan((void *)lpwgts, (void *)gpwgts, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00060 MPI_Allreduce((void *)lpwgts, (void *)mvtxdist, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00061
00062 MAKECSR(i, nparts, mvtxdist);
00063
00064
00065 for (i=0; i<nparts; i++)
00066
00067 gpwgts[i] = mvtxdist[i] + gpwgts[i] - lpwgts[i];
00068
00069 newlabel = idxmalloc(nvtxs+graph->nrecv, "MoveGraph: newlabel");
00070
00071 for (i=0; i<nvtxs; i++)
00072 newlabel[i] = gpwgts[where[i]]++;
00073
00074
00075 CommInterfaceData(ctrl, graph, newlabel, wspace->indices, newlabel+nvtxs);
00076
00077
00078 MPI_Alltoall((void *)sinfo, 2, IDX_DATATYPE, (void *)rinfo, 2, IDX_DATATYPE, ctrl->comm);
00079
00080
00081 lpwgts[0] = 0;
00082 gpwgts[0] = 0;
00083 for (i=0; i<nparts; i++) {
00084 lpwgts[i+1] = lpwgts[i] + (1+ncon)*sinfo[i].key + 2*sinfo[i].val;
00085 gpwgts[i+1] = gpwgts[i] + (1+ncon)*rinfo[i].key + 2*rinfo[i].val;
00086 }
00087
00088
00089 if (lpwgts[nparts]+gpwgts[nparts] > wspace->maxcore) {
00090
00091 free(wspace->core);
00092 wspace->maxcore = lpwgts[nparts]+4*gpwgts[nparts];
00093 wspace->core = idxmalloc(wspace->maxcore, "Moc_MoveGraph: wspace->core");
00094 }
00095
00096 sgraph = wspace->core;
00097 rgraph = wspace->core + lpwgts[nparts];
00098
00099
00100 for (i=0; i<nparts; i++) {
00101 if (rinfo[i].key > 0)
00102 MPI_Irecv((void *)(rgraph+gpwgts[i]), gpwgts[i+1]-gpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->rreq+i);
00103 else
00104 ASSERT(ctrl, gpwgts[i+1]-gpwgts[i] == 0);
00105 }
00106
00107
00108 for (i=0; i<nvtxs; i++) {
00109 ii = lpwgts[where[i]];
00110 sgraph[ii++] = xadj[i+1]-xadj[i];
00111 for (h=0; h<ncon; h++)
00112 sgraph[ii++] = vwgt[i*ncon+h];
00113 for (j=xadj[i]; j<xadj[i+1]; j++) {
00114 sgraph[ii++] = newlabel[adjncy[j]];
00115 sgraph[ii++] = adjwgt[j];
00116 }
00117 lpwgts[where[i]] = ii;
00118 }
00119
00120 for (i=nparts; i>0; i--)
00121 lpwgts[i] = lpwgts[i-1];
00122 lpwgts[0] = 0;
00123
00124 for (i=0; i<nparts; i++) {
00125 if (sinfo[i].key > 0)
00126 MPI_Isend((void *)(sgraph+lpwgts[i]), lpwgts[i+1]-lpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->sreq+i);
00127 else
00128 ASSERT(ctrl, lpwgts[i+1]-lpwgts[i] == 0);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138 for (i=0; i<nparts; i++) {
00139 if (sinfo[i].key > 0)
00140 MPI_Wait(ctrl->sreq+i, &ctrl->status);
00141 }
00142 for (i=0; i<nparts; i++) {
00143 if (rinfo[i].key > 0)
00144 MPI_Wait(ctrl->rreq+i, &ctrl->status);
00145 }
00146
00147
00148 mgraph = CreateGraph();
00149 mgraph->gnvtxs = graph->gnvtxs;
00150 mgraph->ncon = ncon;
00151 mgraph->level = 0;
00152 mgraph->nvtxs = mgraph->nedges = 0;
00153 for (i=0; i<nparts; i++) {
00154 mgraph->nvtxs += rinfo[i].key;
00155 mgraph->nedges += rinfo[i].val;
00156 }
00157 nvtxs = mgraph->nvtxs;
00158 xadj = mgraph->xadj = idxmalloc(nvtxs+1, "MMG: mgraph->xadj");
00159 vwgt = mgraph->vwgt = idxmalloc(nvtxs*ncon, "MMG: mgraph->vwgt");
00160 adjncy = mgraph->adjncy = idxmalloc(mgraph->nedges, "MMG: mgraph->adjncy");
00161 adjwgt = mgraph->adjwgt = idxmalloc(mgraph->nedges, "MMG: mgraph->adjwgt");
00162 mgraph->vtxdist = mvtxdist;
00163
00164 for (jj=ii=i=0; i<nvtxs; i++) {
00165 xadj[i] = rgraph[ii++];
00166 for (h=0; h<ncon; h++)
00167 vwgt[i*ncon+h] = rgraph[ii++];
00168 for (j=0; j<xadj[i]; j++) {
00169 adjncy[jj] = rgraph[ii++];
00170 adjwgt[jj++] = rgraph[ii++];
00171 }
00172 }
00173 MAKECSR(i, nvtxs, xadj);
00174
00175 ASSERTP(ctrl, jj == mgraph->nedges, (ctrl, "%d %d\n", jj, mgraph->nedges));
00176 ASSERTP(ctrl, ii == gpwgts[nparts], (ctrl, "%d %d %d %d %d\n", ii, gpwgts[nparts], jj, mgraph->nedges, nvtxs));
00177
00178 free(newlabel);
00179
00180 #ifdef DEBUG
00181 IFSET(ctrl->dbglvl, DBG_INFO, rprintf(ctrl, "Checking moved graph...\n"));
00182 CheckMGraph(ctrl, mgraph);
00183 IFSET(ctrl->dbglvl, DBG_INFO, rprintf(ctrl, "Moved graph is consistent.\n"));
00184 #endif
00185
00186 return mgraph;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 void ProjectInfoBack(CtrlType *ctrl, GraphType *graph, idxtype *info, idxtype *minfo,
00198 WorkSpaceType *wspace)
00199 {
00200 int i, nvtxs, nparts;
00201 idxtype *where, *auxinfo, *sinfo, *rinfo;
00202
00203 nparts = ctrl->npes;
00204
00205 nvtxs = graph->nvtxs;
00206 where = graph->where;
00207
00208 sinfo = wspace->pv1;
00209 rinfo = wspace->pv2;
00210
00211
00212 idxset(nparts, 0, rinfo);
00213 for (i=0; i<nvtxs; i++)
00214 rinfo[where[i]]++;
00215
00216
00217 MPI_Alltoall((void *)rinfo, 1, IDX_DATATYPE, (void *)sinfo, 1, IDX_DATATYPE, ctrl->comm);
00218
00219 MAKECSR(i, nparts, sinfo);
00220 MAKECSR(i, nparts, rinfo);
00221
00222
00223 auxinfo = idxmalloc(rinfo[nparts], "ProjectInfoBack: auxinfo");
00224
00225
00226
00227
00228 for (i=0; i<nparts; i++) {
00229 if (rinfo[i+1]-rinfo[i] > 0)
00230 MPI_Irecv((void *)(auxinfo+rinfo[i]), rinfo[i+1]-rinfo[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->rreq+i);
00231 }
00232
00233 for (i=0; i<nparts; i++) {
00234 if (sinfo[i+1]-sinfo[i] > 0)
00235 MPI_Isend((void *)(minfo+sinfo[i]), sinfo[i+1]-sinfo[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->sreq+i);
00236 }
00237
00238
00239 for (i=0; i<nparts; i++) {
00240 if (rinfo[i+1]-rinfo[i] > 0)
00241 MPI_Wait(ctrl->rreq+i, &ctrl->status);
00242 }
00243 for (i=0; i<nparts; i++) {
00244 if (sinfo[i+1]-sinfo[i] > 0)
00245 MPI_Wait(ctrl->sreq+i, &ctrl->status);
00246 }
00247
00248
00249 for (i=0; i<nvtxs; i++)
00250 info[i] = auxinfo[rinfo[where[i]]++];
00251
00252 free(auxinfo);
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 void FindVtxPerm(CtrlType *ctrl, GraphType *graph, idxtype *perm, WorkSpaceType *wspace)
00262 {
00263 int i, nvtxs, nparts;
00264 idxtype *xadj, *adjncy, *adjwgt, *mvtxdist;
00265 idxtype *where, *lpwgts, *gpwgts;
00266
00267 nparts = ctrl->nparts;
00268
00269 nvtxs = graph->nvtxs;
00270 xadj = graph->xadj;
00271 adjncy = graph->adjncy;
00272 adjwgt = graph->adjwgt;
00273 where = graph->where;
00274
00275 mvtxdist = idxmalloc(nparts+1, "MoveGraph: mvtxdist");
00276
00277
00278 lpwgts = wspace->pv1;
00279 gpwgts = wspace->pv2;
00280
00281
00282 idxset(nparts, 0, lpwgts);
00283 for (i=0; i<nvtxs; i++)
00284 lpwgts[where[i]]++;
00285
00286 MPI_Scan((void *)lpwgts, (void *)gpwgts, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00287 MPI_Allreduce((void *)lpwgts, (void *)mvtxdist, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00288
00289 MAKECSR(i, nparts, mvtxdist);
00290
00291 for (i=0; i<nparts; i++)
00292 gpwgts[i] = mvtxdist[i] + gpwgts[i] - lpwgts[i];
00293
00294 for (i=0; i<nvtxs; i++)
00295 perm[i] = gpwgts[where[i]]++;
00296
00297 free(mvtxdist);
00298
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 void CheckMGraph(CtrlType *ctrl, GraphType *graph)
00308 {
00309 int i, j, jj, k, nvtxs, firstvtx, lastvtx;
00310 idxtype *xadj, *adjncy, *vtxdist;
00311
00312
00313 nvtxs = graph->nvtxs;
00314 xadj = graph->xadj;
00315 adjncy = graph->adjncy;
00316 vtxdist = graph->vtxdist;
00317
00318 firstvtx = vtxdist[ctrl->mype];
00319 lastvtx = vtxdist[ctrl->mype+1];
00320
00321 for (i=0; i<nvtxs; i++) {
00322 for (j=xadj[i]; j<xadj[i+1]; j++) {
00323 ASSERT(ctrl, firstvtx+i != adjncy[j]);
00324 if (adjncy[j] >= firstvtx && adjncy[j] < lastvtx) {
00325 k = adjncy[j]-firstvtx;
00326 for (jj=xadj[k]; jj<xadj[k+1]; jj++) {
00327 if (adjncy[jj] == firstvtx+i)
00328 break;
00329 }
00330 if (jj == xadj[k+1])
00331 myprintf(ctrl, "(%d %d) but not (%d %d)\n", firstvtx+i, k, k, firstvtx+i);
00332 }
00333 }
00334 }
00335 }
00336
00337
00338