00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <parmetislib.h>
00018
00019 #define DEBUG_SETUPINFO_
00020
00021
00022
00023
00024
00025 void SetUp(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace)
00026 {
00027 int i, j, k, islocal, penum, gnvtxs, nvtxs, nlocal, firstvtx, lastvtx, nsend, nrecv, nnbrs, nadj;
00028 int npes=ctrl->npes, mype=ctrl->mype;
00029 idxtype *vtxdist, *xadj, *adjncy;
00030 idxtype *peind, *recvptr, *recvind, *sendptr, *sendind;
00031 idxtype *receive, *pemap, *imap, *lperm;
00032 idxtype *pexadj, *peadjncy, *peadjloc, *startsind;
00033 KeyValueType *recvrequests, *sendrequests, *adjpairs;
00034
00035 IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm));
00036 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SetupTmr));
00037
00038 gnvtxs = graph->gnvtxs;
00039 nvtxs = graph->nvtxs;
00040 vtxdist = graph->vtxdist;
00041 xadj = graph->xadj;
00042 adjncy = graph->adjncy;
00043
00044 firstvtx = vtxdist[mype];
00045 lastvtx = vtxdist[mype+1];
00046
00047 pemap = wspace->pv1;
00048 idxset(npes, -1, pemap);
00049
00050 lperm = graph->lperm = idxmalloc(nvtxs, "SetUp: graph->lperm");
00051 for (i=0; i<nvtxs; i++)
00052 lperm[i] = i;
00053
00054
00055
00056
00057 receive = wspace->indices;
00058 adjpairs = wspace->pairs;
00059
00060 for (nlocal = nadj = i = 0; i<nvtxs; i++) {
00061 islocal = 1;
00062 for (j=xadj[i]; j<xadj[i+1]; j++) {
00063 k = adjncy[j];
00064 if (k >= firstvtx && k < lastvtx) {
00065 adjncy[j] = k-firstvtx;
00066 continue;
00067 }
00068 adjpairs[nadj].key = k;
00069 adjpairs[nadj++].val = j;
00070 islocal = 0;
00071 }
00072 if (islocal) {
00073 lperm[i] = lperm[nlocal];
00074 lperm[nlocal++] = i;
00075 }
00076 }
00077
00078
00079 ikeysort(nadj, adjpairs);
00080 adjpairs[nadj].key = gnvtxs+1;
00081 for (nrecv=i=0; i<nadj; i++) {
00082 adjncy[adjpairs[i].val] = nvtxs+nrecv;
00083 if (adjpairs[i].key != adjpairs[i+1].key)
00084 receive[nrecv++] = adjpairs[i].key;
00085 }
00086
00087
00088
00089 peind = graph->peind = idxmalloc(npes, "SetUp: peind");
00090 recvptr = graph->recvptr = idxmalloc(npes+1, "SetUp: recvptr");
00091 recvind = graph->recvind = idxmalloc(nrecv, "SetUp: recvind");
00092
00093
00094 idxcopy(nrecv, receive, recvind);
00095
00096 i = nnbrs = recvptr[0] = 0;
00097 for (penum=0; penum<npes; penum++) {
00098 for (j=i; j<nrecv; j++) {
00099 if (recvind[j] >= vtxdist[penum+1])
00100 break;
00101 }
00102 if (j > i) {
00103 peind[nnbrs] = penum;
00104 recvptr[++nnbrs] = j;
00105 i = j;
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114 recvrequests = wspace->pepairs1;
00115 sendrequests = wspace->pepairs2;
00116 for (i=0; i<npes; i++)
00117 recvrequests[i].key = 0;
00118 for (i=0; i<nnbrs; i++) {
00119 recvrequests[peind[i]].key = recvptr[i+1]-recvptr[i];
00120 recvrequests[peind[i]].val = nvtxs+recvptr[i];
00121 }
00122 MPI_Alltoall((void *)recvrequests, 2, IDX_DATATYPE, (void *)sendrequests, 2, IDX_DATATYPE, ctrl->comm);
00123
00124
00125 sendptr = graph->sendptr = idxmalloc(npes+1, "SetUp: sendptr");
00126 startsind = wspace->pv2;
00127 for (j=i=0; i<npes; i++) {
00128 if (sendrequests[i].key > 0) {
00129 sendptr[j] = sendrequests[i].key;
00130 startsind[j] = sendrequests[i].val;
00131 j++;
00132 }
00133 }
00134 ASSERT(ctrl, nnbrs == j);
00135 MAKECSR(i, j, sendptr);
00136
00137 nsend = sendptr[nnbrs];
00138 sendind = graph->sendind = idxmalloc(nsend, "SetUp: sendind");
00139
00140
00141
00142 for (i=0; i<nnbrs; i++) {
00143 MPI_Irecv((void *)(sendind+sendptr[i]), sendptr[i+1]-sendptr[i], IDX_DATATYPE,
00144 peind[i], 1, ctrl->comm, ctrl->rreq+i);
00145 }
00146
00147
00148 for (i=0; i<nnbrs; i++) {
00149 MPI_Isend((void *)(recvind+recvptr[i]), recvptr[i+1]-recvptr[i], IDX_DATATYPE,
00150 peind[i], 1, ctrl->comm, ctrl->sreq+i);
00151 }
00152
00153 MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses);
00154 MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses);
00155
00156
00157
00158
00159 pexadj = graph->pexadj = idxsmalloc(nvtxs+1, 0, "SetUp: pexadj");
00160 peadjncy = graph->peadjncy = idxmalloc(nsend, "SetUp: peadjncy");
00161 peadjloc = graph->peadjloc = idxmalloc(nsend, "SetUp: peadjloc");
00162
00163 for (i=0; i<nsend; i++) {
00164 ASSERTP(ctrl, sendind[i] >= firstvtx && sendind[i] < lastvtx, (ctrl, "%d %d %d\n", sendind[i], firstvtx, lastvtx));
00165 pexadj[sendind[i]-firstvtx]++;
00166 }
00167 MAKECSR(i, nvtxs, pexadj);
00168
00169 for (i=0; i<nnbrs; i++) {
00170 for (j=sendptr[i]; j<sendptr[i+1]; j++) {
00171 k = pexadj[sendind[j]-firstvtx]++;
00172 peadjncy[k] = i;
00173 peadjloc[k] = startsind[i]++;
00174 }
00175 }
00176 ASSERT(ctrl, pexadj[nvtxs] == nsend);
00177
00178 for (i=nvtxs; i>0; i--)
00179 pexadj[i] = pexadj[i-1];
00180 pexadj[0] = 0;
00181
00182
00183 graph->nnbrs = nnbrs;
00184 graph->nrecv = nrecv;
00185 graph->nsend = nsend;
00186 graph->nlocal = nlocal;
00187
00188
00189
00190 imap = graph->imap = idxmalloc(nvtxs+nrecv, "SetUp: imap");
00191 for (i=0; i<nvtxs; i++)
00192 imap[i] = firstvtx+i;
00193 for (i=0; i<nrecv; i++)
00194 imap[nvtxs+i] = recvind[i];
00195
00196
00197
00198 if (wspace->nlarge < nrecv+nsend) {
00199 free(wspace->indices);
00200 free(wspace->pairs);
00201 wspace->nlarge = nrecv+nsend;
00202 wspace->indices = idxmalloc(wspace->nlarge, "SetUp: wspace->indices");
00203 wspace->pairs = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*wspace->nlarge, "SetUp: wspace->pairs");
00204 }
00205
00206 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SetupTmr));
00207
00208 #ifdef DEBUG_SETUPINFO
00209 rprintf(ctrl, "[%5d %5d] \tl:[%5d %5d] \ts:[%5d, %5d] \tr:[%5d, %5d]\n",
00210 GlobalSEMin(ctrl, nvtxs), GlobalSEMax(ctrl, nvtxs),
00211 GlobalSEMin(ctrl, nlocal), GlobalSEMax(ctrl, nlocal),
00212 GlobalSEMin(ctrl, nsend), GlobalSEMax(ctrl, nsend),
00213 GlobalSEMin(ctrl, nrecv), GlobalSEMax(ctrl, nrecv));
00214
00215 PrintSetUpInfo(ctrl, graph);
00216 #endif
00217 }
00218
00219