00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <parmetislib.h>
00015
00016
00017
00018
00019
00020 void ParallelReMapGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace)
00021 {
00022 int i, nvtxs, nparts;
00023 idxtype *where, *vsize, *map, *lpwgts;
00024
00025 IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm));
00026 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RemapTmr));
00027
00028 if (ctrl->npes != ctrl->nparts) {
00029 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RemapTmr));
00030 return;
00031 }
00032
00033 nvtxs = graph->nvtxs;
00034 where = graph->where;
00035 vsize = graph->vsize;
00036 nparts = ctrl->nparts;
00037
00038 map = wspace->pv1;
00039 lpwgts = idxset(nparts, 0, wspace->pv2);
00040
00041 for (i=0; i<nvtxs; i++)
00042 lpwgts[where[i]] += (vsize == NULL) ? 1 : vsize[i];
00043
00044 ParallelTotalVReMap(ctrl, lpwgts, map, wspace, NREMAP_PASSES, graph->ncon);
00045
00046 for (i=0; i<nvtxs; i++)
00047 where[i] = map[where[i]];
00048
00049 IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm));
00050 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RemapTmr));
00051 }
00052
00053
00054
00055
00056
00057
00058 void ParallelTotalVReMap(CtrlType *ctrl, idxtype *lpwgts, idxtype *map,
00059 WorkSpaceType *wspace, int npasses, int ncon)
00060 {
00061 int i, ii, j, k, nparts, mype;
00062 int pass, maxipwgt, nmapped, oldwgt, newwgt, done;
00063 idxtype *rowmap, *mylpwgts;
00064 KeyValueType *recv, send;
00065 int nsaved, gnsaved;
00066
00067 mype = ctrl->mype;
00068 nparts = ctrl->nparts;
00069 recv = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*nparts, "remap: recv");
00070 mylpwgts = idxmalloc(nparts, "mylpwgts");
00071
00072 done = nmapped = 0;
00073 idxset(nparts, -1, map);
00074 rowmap = idxset(nparts, -1, wspace->pv3);
00075 idxcopy(nparts, lpwgts, mylpwgts);
00076 for (pass=0; pass<npasses; pass++) {
00077 maxipwgt = idxamax(nparts, mylpwgts);
00078
00079 if (mylpwgts[maxipwgt] > 0 && !done) {
00080 send.key = -mylpwgts[maxipwgt];
00081 send.val = mype*nparts+maxipwgt;
00082 }
00083 else {
00084 send.key = 0;
00085 send.val = -1;
00086 }
00087
00088
00089 MPI_Allgather((void *)&send, 2, IDX_DATATYPE, (void *)recv, 2, IDX_DATATYPE, ctrl->comm);
00090
00091 ikeysort(nparts, recv);
00092 if (recv[0].key == 0)
00093 break;
00094
00095
00096 for (ii=0; ii<nparts; ii++) {
00097 i = recv[ii].val;
00098
00099 if (i == -1)
00100 continue;
00101
00102 j = i % nparts;
00103 k = i / nparts;
00104 if (map[j] == -1 && rowmap[k] == -1 && SimilarTpwgts(ctrl->tpwgts, ncon, j, k)) {
00105 map[j] = k;
00106 rowmap[k] = j;
00107 nmapped++;
00108 mylpwgts[j] = 0;
00109 if (mype == k)
00110 done = 1;
00111 }
00112
00113 if (nmapped == nparts)
00114 break;
00115 }
00116
00117 if (nmapped == nparts)
00118 break;
00119 }
00120
00121
00122 if (nmapped < nparts) {
00123 for (i=j=0; j<nparts && nmapped<nparts; j++) {
00124 if (map[j] == -1) {
00125 for (; i<nparts; i++) {
00126 if (rowmap[i] == -1 && SimilarTpwgts(ctrl->tpwgts, ncon, i, j)) {
00127 map[j] = i;
00128 rowmap[i] = j;
00129 nmapped++;
00130 break;
00131 }
00132 }
00133 }
00134 }
00135 }
00136
00137
00138
00139 if (nmapped < nparts) {
00140 for (i=0; i<nparts; i++)
00141 map[i] = i;
00142 IFSET(ctrl->dbglvl, DBG_REMAP, rprintf(ctrl, "Savings from parallel remapping: %0\n"));
00143 }
00144 else {
00145
00146 oldwgt = lpwgts[mype];
00147 newwgt = lpwgts[rowmap[mype]];
00148 nsaved = newwgt - oldwgt;
00149 gnsaved = GlobalSESum(ctrl, nsaved);
00150
00151
00152 if (gnsaved <= 0) {
00153 for (i=0; i<nparts; i++)
00154 map[i] = i;
00155 }
00156 IFSET(ctrl->dbglvl, DBG_REMAP, rprintf(ctrl, "Savings from parallel remapping: %d\n", amax(0,gnsaved)));
00157 }
00158
00159 GKfree((void **)&recv, (void **)&mylpwgts, LTERM);
00160
00161 }
00162
00163
00164
00165
00166
00167
00168 int SimilarTpwgts(floattype *tpwgts, int ncon, int s1, int s2)
00169 {
00170 int i;
00171
00172 for (i=0; i<ncon; i++)
00173 if (fabs(tpwgts[s1*ncon+i]-tpwgts[s2*ncon+i]) > SMALLFLOAT)
00174 break;
00175
00176 if (i == ncon)
00177 return 1;
00178
00179 return 0;
00180 }
00181