00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <parmetislib.h>
00016
00017
00018
00019
00020
00021 void SetUpConnectGraph(GraphType *graph, MatrixType *matrix, idxtype *workspace)
00022 {
00023 int i, ii, j, jj, k, l;
00024 int nvtxs, nrows;
00025 idxtype *xadj, *adjncy, *where;
00026 idxtype *rowptr, *colind;
00027 idxtype *pcounts, *perm, *marker;
00028 floattype *values;
00029
00030 nvtxs = graph->nvtxs;
00031 xadj = graph->xadj;
00032 adjncy = graph->adjncy;
00033 where = graph->where;
00034
00035 nrows = matrix->nrows;
00036 rowptr = matrix->rowptr;
00037 colind = matrix->colind;
00038 values = matrix->values;
00039
00040 perm = workspace;
00041 marker = idxset(nrows, -1, workspace+nvtxs);
00042 pcounts = idxset(nrows+1, 0, workspace+nvtxs+nrows);
00043
00044 for (i=0; i<nvtxs; i++)
00045 pcounts[where[i]]++;
00046 MAKECSR(i, nrows, pcounts);
00047
00048 for (i=0; i<nvtxs; i++)
00049 perm[pcounts[where[i]]++] = i;
00050
00051 for (i=nrows; i>0; i--)
00052 pcounts[i] = pcounts[i-1];
00053 pcounts[0] = 0;
00054
00055
00056
00057
00058 rowptr[0] = k = 0;
00059 for (ii=0; ii<nrows; ii++) {
00060 colind[k++] = ii;
00061 marker[ii] = ii;
00062
00063 for (jj=pcounts[ii]; jj<pcounts[ii+1]; jj++) {
00064 i = perm[jj];
00065 for (j=xadj[i]; j<xadj[i+1]; j++) {
00066 l = where[adjncy[j]];
00067 if (marker[l] != ii) {
00068 colind[k] = l;
00069 values[k++] = -1.0;
00070 marker[l] = ii;
00071 }
00072 }
00073 }
00074 values[rowptr[ii]] = (floattype)(k-rowptr[ii]-1);
00075 rowptr[ii+1] = k;
00076 }
00077 matrix->nnzs = rowptr[nrows];
00078
00079 return;
00080 }
00081
00082
00083
00084
00085
00086
00087 void Mc_ComputeMoveStatistics(CtrlType *ctrl, GraphType *graph, int *nmoved, int *maxin, int *maxout)
00088 {
00089 int i, nvtxs, nparts, myhome;
00090 idxtype *vwgt, *where;
00091 idxtype *lend, *gend, *lleft, *gleft, *lstart, *gstart;
00092
00093 nvtxs = graph->nvtxs;
00094 vwgt = graph->vwgt;
00095 where = graph->where;
00096 nparts = ctrl->nparts;
00097
00098 lstart = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lstart");
00099 gstart = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gstart");
00100 lleft = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lleft");
00101 gleft = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gleft");
00102 lend = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lend");
00103 gend = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gend");
00104
00105 for (i=0; i<nvtxs; i++) {
00106 myhome = (ctrl->ps_relation == COUPLED) ? ctrl->mype : graph->home[i];
00107 lstart[myhome] += (graph->vsize == NULL) ? 1 : graph->vsize[i];
00108 lend[where[i]] += (graph->vsize == NULL) ? 1 : graph->vsize[i];
00109 if (where[i] != myhome)
00110 lleft[myhome] += (graph->vsize == NULL) ? 1 : graph->vsize[i];
00111 }
00112
00113
00114
00115 MPI_Allreduce((void *)lstart, (void *)gstart, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00116 MPI_Allreduce((void *)lleft, (void *)gleft, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00117 MPI_Allreduce((void *)lend, (void *)gend, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm);
00118
00119 *nmoved = idxsum(nparts, gleft);
00120 *maxout = gleft[idxamax(nparts, gleft)];
00121 for (i=0; i<nparts; i++)
00122 lstart[i] = gend[i]+gleft[i]-gstart[i];
00123 *maxin = lstart[idxamax(nparts, lstart)];
00124
00125 GKfree((void **)&lstart, (void **)&gstart, (void **)&lleft, (void **)&gleft, (void **)&lend, (void **)&gend, LTERM);
00126 }
00127
00128
00129
00130
00131 int Mc_ComputeSerialTotalV(GraphType *graph, idxtype *home)
00132 {
00133 int i;
00134 int totalv = 0;
00135
00136 for (i=0; i<graph->nvtxs; i++) {
00137 if (graph->where[i] != home[i])
00138 totalv += (graph->vsize == NULL) ? graph->vwgt[i*graph->ncon] : graph->vsize[i];
00139 }
00140
00141 return totalv;
00142 }
00143
00144
00145
00146
00147
00148
00149 void ComputeLoad(GraphType *graph, int nparts, floattype *load, floattype *tpwgts, int index)
00150 {
00151 int i;
00152 int nvtxs, ncon;
00153 idxtype *where;
00154 floattype *nvwgt;
00155
00156 nvtxs = graph->nvtxs;
00157 ncon = graph->ncon;
00158 where = graph->where;
00159 nvwgt = graph->nvwgt;
00160
00161 sset(nparts, 0.0, load);
00162
00163 for (i=0; i<nvtxs; i++)
00164 load[where[i]] += nvwgt[i*ncon+index];
00165
00166 ASSERTS(fabs(ssum(nparts, load)-1.0) < 0.001);
00167
00168 for (i=0; i<nparts; i++) {
00169 load[i] -= tpwgts[i*ncon+index];
00170 }
00171
00172 return;
00173 }
00174
00175
00176
00177
00178
00179 void ConjGrad2(MatrixType *A, floattype *b, floattype *x, floattype tol, floattype *workspace)
00180 {
00181 int i, k, n;
00182 floattype *p, *r, *q, *z, *M;
00183 floattype alpha, beta, rho, rho_1 = -1.0, error, bnrm2, tmp;
00184 idxtype *rowptr, *colind;
00185 floattype *values;
00186
00187 n = A->nrows;
00188 rowptr = A->rowptr;
00189 colind = A->colind;
00190 values = A->values;
00191
00192
00193 p = workspace;
00194 r = workspace + n;
00195 q = workspace + 2*n;
00196 z = workspace + 3*n;
00197 M = workspace + 4*n;
00198
00199 for (i=0; i<n; i++) {
00200 x[i] = 0.0;
00201 if (values[rowptr[i]] != 0.0)
00202 M[i] = 1.0/values[rowptr[i]];
00203 else
00204 M[i] = 0.0;
00205 }
00206
00207
00208 mvMult2(A, x, r);
00209 for (i=0; i<n; i++)
00210 r[i] = b[i]-r[i];
00211
00212 bnrm2 = snorm2(n, b);
00213 if (bnrm2 > 0.0) {
00214 error = snorm2(n, r) / bnrm2;
00215
00216 if (error > tol) {
00217
00218 for (k=0; k<n; k++) {
00219 for (i=0; i<n; i++)
00220 z[i] = r[i]*M[i];
00221
00222 rho = sdot(n, r, z);
00223
00224 if (k == 0)
00225 scopy(n, z, p);
00226 else {
00227 if (rho_1 != 0.0)
00228 beta = rho/rho_1;
00229 else
00230 beta = 0.0;
00231 for (i=0; i<n; i++)
00232 p[i] = z[i] + beta*p[i];
00233 }
00234
00235 mvMult2(A, p, q);
00236
00237 tmp = sdot(n, p, q);
00238 if (tmp != 0.0)
00239 alpha = rho/tmp;
00240 else
00241 alpha = 0.0;
00242 saxpy(n, alpha, p, x);
00243 saxpy(n, -alpha, q, r);
00244 error = snorm2(n, r) / bnrm2;
00245 if (error < tol)
00246 break;
00247
00248 rho_1 = rho;
00249 }
00250 }
00251 }
00252 }
00253
00254
00255
00256
00257
00258 void mvMult2(MatrixType *A, floattype *v, floattype *w)
00259 {
00260 int i, j;
00261
00262 for (i = 0; i < A->nrows; i++)
00263 w[i] = 0.0;
00264
00265 for (i = 0; i < A->nrows; i++)
00266 for (j = A->rowptr[i]; j < A->rowptr[i+1]; j++)
00267 w[i] += A->values[j] * v[A->colind[j]];
00268
00269 return;
00270 }
00271
00272
00273
00274
00275
00276 void ComputeTransferVector(int ncon, MatrixType *matrix, floattype *solution,
00277 floattype *transfer, int index)
00278 {
00279 int j, k;
00280 int nrows;
00281 idxtype *rowptr, *colind;
00282
00283 nrows = matrix->nrows;
00284 rowptr = matrix->rowptr;
00285 colind = matrix->colind;
00286
00287 for (j=0; j<nrows; j++) {
00288 for (k=rowptr[j]+1; k<rowptr[j+1]; k++) {
00289 if (solution[j] > solution[colind[k]]) {
00290 transfer[k*ncon+index] = solution[j] - solution[colind[k]];
00291 }
00292 else {
00293 transfer[k*ncon+index] = 0.0;
00294 }
00295 }
00296 }
00297 }
00298