📄 coarsen.c
字号:
rgraph = (idxtype *)wspace->degrees; sgraph = rgraph + (4+ncon)*nrecv+2*nrecvsize; } else { rgraph = idxmalloc((4+ncon)*nrecv+2*nrecvsize, "CreateCoarseGraph: rgraph"); sgraph = idxmalloc((4+ncon)*nsend+2*nsendsize, "CreateCoarseGraph: sgraph"); } /* Deal with the received portion first */ for (l=i=0; i<nnbrs; i++) { /* Issue a receive only if you are getting something */ if (rlens[i+1]-rlens[i] > 0) { MPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); l += (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i]; } } /* Deal with the sent portion now */ for (ll=l=i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) { /* Issue a send only if you are sending something */ for (k=slens[i]; k<slens[i+1]; k++) { ii = scand[k].val; sgraph[ll++] = firstvtx+ii; sgraph[ll++] = xadj[ii+1]-xadj[ii]; for (h=0; h<ncon; h++) sgraph[ll++] = vwgt[ii*ncon+h]; sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : vsize[ii]; sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { sgraph[ll++] = cmap[ladjncy[jj]]; sgraph[ll++] = adjwgt[jj]; } } ASSERT(ctrl, ll-l == (4+ncon)*(slens[i+1]-slens[i])+2*ssizes[i]); /* myprintf(ctrl, "Sending to pe:%d, %d lists of size %d\n", peind[i], slens[i+1]-slens[i], ssizes[i]); */ MPI_Isend((void *)(sgraph+l), ll-l, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); l = ll; } } /* OK, now get into the loop waiting for the operations to finish */ for (i=0; i<nnbrs; i++) { if (rlens[i+1]-rlens[i] > 0) MPI_Wait(ctrl->rreq+i, &ctrl->status); } for (i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) MPI_Wait(ctrl->sreq+i, &ctrl->status); }#ifdef DEBUG_CONTRACT rprintf(ctrl, "Graphs were sent!\n"); PrintTransferedGraphs(ctrl, nnbrs, peind, slens, rlens, sgraph, rgraph);#endif /************************************************************* * Setup the mapping from indices returned by BSearch to * those that are actually stored **************************************************************/ perm = idxsmalloc(recvptr[nnbrs], -1, "CreateCoarseGraph: perm"); for (j=i=0; i<nrecv; i++) { /* myprintf(ctrl, "For received vertex %d, set perm[%d]=%d\n", rgraph[j], BSearch(graph->nrecv, recvind, rgraph[j]), j+ncon); */ perm[BSearch(graph->nrecv, recvind, rgraph[j])] = j+1; j += (4+ncon)+2*rgraph[j+1]; } /************************************************************* * Finally, create the coarser graph **************************************************************/ /* Allocate memory for the coarser graph, and fire up coarsening */ cxadj = cgraph->xadj = idxmalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); cvwgt = cgraph->vwgt = idxmalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize"); chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome"); } cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); cadjncy = idxmalloc(2*(nkeepsize+nrecvsize), "CreateCoarserGraph: cadjncy"); cadjwgt = cadjncy + nkeepsize+nrecvsize; iset(8192, -1, htable); cxadj[0] = cnvtxs = cnedges = 0; for (i=0; i<nvtxs; i++) { if (match[i] >= KEEP_BIT) { v = firstvtx+i; u = match[i]-KEEP_BIT; if (u>=firstvtx && u<lastvtx && v > u) continue; /* I have already collapsed it as (u,v) */ /* Collapse the v vertex first, which you know is local */ for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] = vwgt[i*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize[cnvtxs] = vsize[i]; chome[cnvtxs] = home[i]; } nedges = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = cmap[ladjncy[j]]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&mask; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } } } } /* Collapse the u vertex next */ if (v != u) { if (u>=firstvtx && u<lastvtx) { /* Local vertex */ u -= firstvtx; for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] += vwgt[u*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize[cnvtxs] += vsize[u]; /* chome[cnvtxs] = home[u]; */ } for (j=xadj[u]; j<xadj[u+1]; j++) { k = cmap[ladjncy[j]]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&mask; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } } } } } else { /* Remote vertex */ u = perm[BSearch(graph->nrecv, recvind, u)]; for (h=0; h<ncon; h++) /* Remember that the +1 stores the vertex weight */ cvwgt[cnvtxs*ncon+h] += rgraph[(u+1)+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize[cnvtxs] += rgraph[u+1+ncon]; chome[cnvtxs] = rgraph[u+2+ncon]; } for (j=0; j<rgraph[u]; j++) { k = rgraph[u+3+ncon+2*j]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&mask; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = rgraph[u+3+ncon+2*j+1]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += rgraph[u+3+ncon+2*j+1]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += rgraph[u+3+ncon+2*j+1]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = rgraph[u+3+ncon+2*j+1]; } } } } } } cnedges += nedges; for (j=cxadj[cnvtxs]; j<cnedges; j++) htable[cadjncy[j]&mask] = -1; /* reset the htable */ cxadj[++cnvtxs] = cnedges; } } cgraph->nedges = cnedges; /* ADD: In order to keep from having to change this too much */ /* ADD: I kept vwgt array and recomputed nvwgt for each coarser graph */ for (j=0; j<cnvtxs; j++) for (h=0; h<ncon; h++) cgraph->nvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); cgraph->adjncy = idxmalloc(cnedges, "CreateCoarserGraph: cadjncy"); cgraph->adjwgt = idxmalloc(cnedges, "CreateCoarserGraph: cadjwgt"); idxcopy(cnedges, cadjncy, cgraph->adjncy); idxcopy(cnedges, cadjwgt, cgraph->adjwgt); free(cadjncy); free(perm); if (rgraph != (idxtype *)wspace->degrees) GKfree((void **)&rgraph, (void **)&sgraph, LTERM);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -