void ComputeKWayPartitionParams(ctrl_t *ctrl, graph_t *graph) { idx_t i, j, k, l, nvtxs, ncon, nparts, nbnd, mincut, me, other; idx_t *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr; nparts = ctrl->nparts; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; pwgts = iset(nparts*ncon, 0, graph->pwgts); bndind = graph->bndind; bndptr = iset(nvtxs, -1, graph->bndptr); nbnd = mincut = 0; /* Compute pwgts */ if (ncon == 1) { for (i=0; i<nvtxs; i++) { ASSERT(where[i] >= 0 && where[i] < nparts); pwgts[where[i]] += vwgt[i]; } } else { for (i=0; i<nvtxs; i++) { me = where[i]; for (j=0; j<ncon; j++) pwgts[me*ncon+j] += vwgt[i*ncon+j]; } } /* Compute the required info for refinement */ switch (ctrl->objtype) { case METIS_OBJTYPE_CUT: { ckrinfo_t *myrinfo; cnbr_t *mynbrs; memset(graph->ckrinfo, 0, sizeof(ckrinfo_t)*nvtxs); cnbrpoolReset(ctrl); for (i=0; i<nvtxs; i++) { me = where[i]; myrinfo = graph->ckrinfo+i; for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[adjncy[j]]) myrinfo->id += adjwgt[j]; else myrinfo->ed += adjwgt[j]; } /* Time to compute the particular external degrees */ if (myrinfo->ed > 0) { mincut += myrinfo->ed; myrinfo->inbr = cnbrpoolGetNext(ctrl, xadj[i+1]-xadj[i]+1); mynbrs = ctrl->cnbrpool + myrinfo->inbr; for (j=xadj[i]; j<xadj[i+1]; j++) { other = where[adjncy[j]]; if (me != other) { for (k=0; k<myrinfo->nnbrs; k++) { if (mynbrs[k].pid == other) { mynbrs[k].ed += adjwgt[j]; break; } } if (k == myrinfo->nnbrs) { mynbrs[k].pid = other; mynbrs[k].ed = adjwgt[j]; myrinfo->nnbrs++; } } } ASSERT(myrinfo->nnbrs <= xadj[i+1]-xadj[i]); /* Only ed-id>=0 nodes are considered to be in the boundary */ if (myrinfo->ed-myrinfo->id >= 0) BNDInsert(nbnd, bndind, bndptr, i); } else { myrinfo->inbr = -1; } } graph->mincut = mincut/2; graph->nbnd = nbnd; } ASSERT(CheckBnd2(graph)); break; case METIS_OBJTYPE_VOL: { vkrinfo_t *myrinfo; vnbr_t *mynbrs; memset(graph->vkrinfo, 0, sizeof(vkrinfo_t)*nvtxs); vnbrpoolReset(ctrl); /* Compute now the id/ed degrees */ for (i=0; i<nvtxs; i++) { me = where[i]; myrinfo = graph->vkrinfo+i; for (j=xadj[i]; j<xadj[i+1]; j++) { if (me == where[adjncy[j]]) myrinfo->nid++; else myrinfo->ned++; } /* Time to compute the particular external degrees */ if (myrinfo->ned > 0) { mincut += myrinfo->ned; myrinfo->inbr = vnbrpoolGetNext(ctrl, xadj[i+1]-xadj[i]+1); mynbrs = ctrl->vnbrpool + myrinfo->inbr; for (j=xadj[i]; j<xadj[i+1]; j++) { other = where[adjncy[j]]; if (me != other) { for (k=0; k<myrinfo->nnbrs; k++) { if (mynbrs[k].pid == other) { mynbrs[k].ned++; break; } } if (k == myrinfo->nnbrs) { mynbrs[k].gv = 0; mynbrs[k].pid = other; mynbrs[k].ned = 1; myrinfo->nnbrs++; } } } ASSERT(myrinfo->nnbrs <= xadj[i+1]-xadj[i]); } else { myrinfo->inbr = -1; } } graph->mincut = mincut/2; ComputeKWayVolGains(ctrl, graph); } ASSERT(graph->minvol == ComputeVolume(graph, graph->where)); break; default: gk_errexit(SIGERR, "Unknown objtype of %d\n", ctrl->objtype); } }
void ProjectKWayPartition(ctrl_t *ctrl, graph_t *graph) { idx_t i, j, k, nvtxs, nbnd, nparts, me, other, istart, iend, tid, ted; idx_t *xadj, *adjncy, *adjwgt; idx_t *cmap, *where, *bndptr, *bndind, *cwhere, *htable; graph_t *cgraph; WCOREPUSH; nparts = ctrl->nparts; cgraph = graph->coarser; cwhere = cgraph->where; nvtxs = graph->nvtxs; cmap = graph->cmap; xadj = graph->xadj; adjncy = graph->adjncy; adjwgt = graph->adjwgt; AllocateKWayPartitionMemory(ctrl, graph); where = graph->where; bndind = graph->bndind; bndptr = iset(nvtxs, -1, graph->bndptr); htable = iset(nparts, -1, iwspacemalloc(ctrl, nparts)); /* Compute the required info for refinement */ switch (ctrl->objtype) { case METIS_OBJTYPE_CUT: ASSERT(CheckBnd2(cgraph)); { ckrinfo_t *myrinfo; cnbr_t *mynbrs; /* go through and project partition and compute id/ed for the nodes */ for (i=0; i<nvtxs; i++) { k = cmap[i]; where[i] = cwhere[k]; cmap[i] = cgraph->ckrinfo[k].ed; /* For optimization */ } memset(graph->ckrinfo, 0, sizeof(ckrinfo_t)*nvtxs); cnbrpoolReset(ctrl); for (nbnd=0, i=0; i<nvtxs; i++) { istart = xadj[i]; iend = xadj[i+1]; myrinfo = graph->ckrinfo+i; if (cmap[i] == 0) { /* Interior node. Note that cmap[i] = crinfo[cmap[i]].ed */ for (tid=0, j=istart; j<iend; j++) tid += adjwgt[j]; myrinfo->id = tid; myrinfo->inbr = -1; } else { /* Potentially an interface node */ myrinfo->inbr = cnbrpoolGetNext(ctrl, iend-istart+1); mynbrs = ctrl->cnbrpool + myrinfo->inbr; me = where[i]; for (tid=0, ted=0, j=istart; j<iend; j++) { other = where[adjncy[j]]; if (me == other) { tid += adjwgt[j]; } else { ted += adjwgt[j]; if ((k = htable[other]) == -1) { htable[other] = myrinfo->nnbrs; mynbrs[myrinfo->nnbrs].pid = other; mynbrs[myrinfo->nnbrs++].ed = adjwgt[j]; } else { mynbrs[k].ed += adjwgt[j]; } } } myrinfo->id = tid; myrinfo->ed = ted; /* Remove space for edegrees if it was interior */ if (ted == 0) { ctrl->nbrpoolcpos -= iend-istart+1; myrinfo->inbr = -1; } else { if (ted-tid >= 0) BNDInsert(nbnd, bndind, bndptr, i); for (j=0; j<myrinfo->nnbrs; j++) htable[mynbrs[j].pid] = -1; } } } graph->nbnd = nbnd; } ASSERT(CheckBnd2(graph)); break; case METIS_OBJTYPE_VOL: { vkrinfo_t *myrinfo; vnbr_t *mynbrs; ASSERT(cgraph->minvol == ComputeVolume(cgraph, cgraph->where)); /* go through and project partition and compute id/ed for the nodes */ for (i=0; i<nvtxs; i++) { k = cmap[i]; where[i] = cwhere[k]; cmap[i] = cgraph->vkrinfo[k].ned; /* For optimization */ } memset(graph->vkrinfo, 0, sizeof(vkrinfo_t)*nvtxs); vnbrpoolReset(ctrl); for (i=0; i<nvtxs; i++) { istart = xadj[i]; iend = xadj[i+1]; myrinfo = graph->vkrinfo+i; if (cmap[i] == 0) { /* Note that cmap[i] = crinfo[cmap[i]].ed */ myrinfo->nid = iend-istart; myrinfo->inbr = -1; } else { /* Potentially an interface node */ myrinfo->inbr = vnbrpoolGetNext(ctrl, iend-istart+1); mynbrs = ctrl->vnbrpool + myrinfo->inbr; me = where[i]; for (tid=0, ted=0, j=istart; j<iend; j++) { other = where[adjncy[j]]; if (me == other) { tid++; } else { ted++; if ((k = htable[other]) == -1) { htable[other] = myrinfo->nnbrs; mynbrs[myrinfo->nnbrs].gv = 0; mynbrs[myrinfo->nnbrs].pid = other; mynbrs[myrinfo->nnbrs++].ned = 1; } else { mynbrs[k].ned++; } } } myrinfo->nid = tid; myrinfo->ned = ted; /* Remove space for edegrees if it was interior */ if (ted == 0) { ctrl->nbrpoolcpos -= iend-istart+1; myrinfo->inbr = -1; } else { for (j=0; j<myrinfo->nnbrs; j++) htable[mynbrs[j].pid] = -1; } } } ComputeKWayVolGains(ctrl, graph); ASSERT(graph->minvol == ComputeVolume(graph, graph->where)); } break; default: gk_errexit(SIGERR, "Unknown objtype of %d\n", ctrl->objtype); } graph->mincut = cgraph->mincut; icopy(nparts*graph->ncon, cgraph->pwgts, graph->pwgts); FreeGraph(&graph->coarser); graph->coarser = NULL; WCOREPOP; }
/************************************************************************* * This function projects a partition, and at the same time computes the * parameters for refinement. **************************************************************************/ void ProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) { int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees; idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; idxtype *cmap, *where, *bndptr, *bndind; idxtype *cwhere; GraphType *cgraph; RInfoType *crinfo, *rinfo, *myrinfo; EDegreeType *myedegrees; idxtype *htable; cgraph = graph->coarser; cwhere = cgraph->where; crinfo = cgraph->rinfo; nvtxs = graph->nvtxs; cmap = graph->cmap; xadj = graph->xadj; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; AllocateKWayPartitionMemory(ctrl, graph, nparts); where = graph->where; rinfo = graph->rinfo; bndind = graph->bndind; bndptr = idxset(nvtxs, -1, graph->bndptr); /* Go through and project partition and compute id/ed for the nodes */ for (i=0; i<nvtxs; i++) { k = cmap[i]; where[i] = cwhere[k]; cmap[i] = crinfo[k].ed; /* For optimization */ } htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); ctrl->wspace.cdegree = 0; for (nbnd=0, i=0; i<nvtxs; i++) { me = where[i]; myrinfo = rinfo+i; myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; myrinfo->edegrees = NULL; myrinfo->id = adjwgtsum[i]; if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ istart = xadj[i]; iend = xadj[i+1]; myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; ctrl->wspace.cdegree += iend-istart; ndegrees = 0; for (j=istart; j<iend; j++) { other = where[adjncy[j]]; if (me != other) { myrinfo->ed += adjwgt[j]; if ((k = htable[other]) == -1) { htable[other] = ndegrees; myedegrees[ndegrees].pid = other; myedegrees[ndegrees++].ed = adjwgt[j]; } else { myedegrees[k].ed += adjwgt[j]; } } } myrinfo->id -= myrinfo->ed; /* Remove space for edegrees if it was interior */ if (myrinfo->ed == 0) { myrinfo->edegrees = NULL; ctrl->wspace.cdegree -= iend-istart; } else { if (myrinfo->ed-myrinfo->id >= 0) BNDInsert(nbnd, bndind, bndptr, i); myrinfo->ndegrees = ndegrees; for (j=0; j<ndegrees; j++) htable[myedegrees[j].pid] = -1; } } } idxcopy(nparts, cgraph->pwgts, graph->pwgts); graph->mincut = cgraph->mincut; graph->nbnd = nbnd; FreeGraph(graph->coarser); graph->coarser = NULL; idxwspacefree(ctrl, nparts); ASSERT(CheckBnd2(graph)); }