⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kwayfm.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
          }          overfill[j*ncon+h] = amax(overfill[j*ncon+h], 0.0);          overfill[j*ncon+h] *= movewgts[j*ncon+h];          if (overfill[j*ncon+h] > 0.0)            overweight = 1;          ASSERTP(ctrl, ognpwgts[j*ncon+h] <= badmaxpwgt[j*ncon+h] ||          pgnpwgts[j*ncon+h] <= ognpwgts[j*ncon+h],          (ctrl, "%.4f %.4f %.4f\n", ognpwgts[j*ncon+h],          badmaxpwgt[j*ncon+h], pgnpwgts[j*ncon+h]));        }      }      /****************************************************/      /* select moves to undo according to overfill array */      /****************************************************/      if (overweight == 1) {        for (iii=0; iii<nmoved; iii++) {          i = moved[iii];          oldto = tmp_where[i];          nvwgt = graph->nvwgt+i*ncon;          my_edegrees = tmp_rinfo[i].degrees;          for (k=0; k<tmp_rinfo[i].ndegrees; k++)            if (my_edegrees[k].edge == where[i])              break;          for (h=0; h<ncon; h++)            if (nvwgt[h] > 0.0 && overfill[oldto*ncon+h] > nvwgt[h]/4.0)              break;          /**********************************/          /* nullify this move if necessary */          /**********************************/          if (k != tmp_rinfo[i].ndegrees && h != ncon) {            moved[iii] = -1;            from = oldto;            to = where[i];            for (h=0; h<ncon; h++) {              overfill[oldto*ncon+h] = amax(overfill[oldto*ncon+h]-nvwgt[h], 0.0);            }            tmp_where[i] = to;            tmp_rinfo[i].ed += tmp_rinfo[i].id-my_edegrees[k].ewgt;            SWAP(tmp_rinfo[i].id, my_edegrees[k].ewgt, j);            if (my_edegrees[k].ewgt == 0) {              tmp_rinfo[i].ndegrees--;              my_edegrees[k].edge = my_edegrees[tmp_rinfo[i].ndegrees].edge;              my_edegrees[k].ewgt = my_edegrees[tmp_rinfo[i].ndegrees].ewgt;            }            else {              my_edegrees[k].edge = from;            }            for (h=0; h<ncon; h++) {              lnpwgts[to*ncon+h] += nvwgt[h];              lnpwgts[from*ncon+h] -= nvwgt[h];            }            /* Update the degrees of adjacent vertices */            for (j=xadj[i]; j<xadj[i+1]; j++) {              /* no need to bother about vertices on different pe's */              if (ladjncy[j] >= nvtxs)                continue;              me = ladjncy[j];              mydomain = tmp_where[me];              myrinfo = tmp_rinfo+me;              your_edegrees = myrinfo->degrees;              if (mydomain == from) {                INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]);              }              else {                if (mydomain == to) {                  INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]);                }              }              /* Remove contribution from the .ed of 'from' */              if (mydomain != from) {                for (k=0; k<myrinfo->ndegrees; k++) {                  if (your_edegrees[k].edge == from) {                    if (your_edegrees[k].ewgt == adjwgt[j]) {                      myrinfo->ndegrees--;                      your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge;                      your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt;                    }                    else {                      your_edegrees[k].ewgt -= adjwgt[j];                    }                    break;                  }                }              }              /* Add contribution to the .ed of 'to' */              if (mydomain != to) {                for (k=0; k<myrinfo->ndegrees; k++) {                  if (your_edegrees[k].edge == to) {                    your_edegrees[k].ewgt += adjwgt[j];                    break;                  }                }                if (k == myrinfo->ndegrees) {                  your_edegrees[myrinfo->ndegrees].edge = to;                  your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j];                }              }            }          }        }      }      /*************************************************/      /* PASS TWO -- commit the remainder of the moves */      /*************************************************/      nlupd = nsupd = nmoves = nchanged = 0;      for (iii=0; iii<nmoved; iii++) {        i = moved[iii];        if (i == -1)          continue;        where[i] = tmp_where[i];        /* Make sure to update the vertex information */        if (htable[i] == 0) {          /* make sure you do the update */          htable[i] = 1;          update[nlupd++] = i;        }        /* Put the vertices adjacent to i into the update array */        for (j=xadj[i]; j<xadj[i+1]; j++) {          k = ladjncy[j];          if (htable[k] == 0) {            htable[k] = 1;            if (k<nvtxs)              update[nlupd++] = k;            else              supdate[nsupd++] = k;          }        }        nmoves++;        nswaps++;        /* check number of zero-gain moves */        for (k=0; k<rinfo[i].ndegrees; k++)          if (rinfo[i].degrees[k].edge == to)            break;        if (rinfo[i].id == rinfo[i].degrees[k].ewgt)          nzgswaps++;        if (graph->pexadj[i+1]-graph->pexadj[i] > 0)          changed[nchanged++] = i;      }      /* Tell interested pe's the new where[] info for the interface vertices */      CommChangedInterfaceData(ctrl, graph, nchanged, changed, where,      swchanges, rwchanges, wspace->pv4);       IFSET(ctrl->dbglvl, DBG_RMOVEINFO,      rprintf(ctrl, "\t[%d %d], [%.4f],  [%d %d %d]\n",      pass, c, badmaxpwgt[0],      GlobalSESum(ctrl, nmoves),      GlobalSESum(ctrl, nsupd),      GlobalSESum(ctrl, nlupd)));      /*-------------------------------------------------------------      / Time to communicate with processors to send the vertices      / whose degrees need to be update.      /-------------------------------------------------------------*/      /* Issue the receives first */      for (i=0; i<nnbrs; i++) {        MPI_Irecv((void *)(rupdate+sendptr[i]), sendptr[i+1]-sendptr[i], IDX_DATATYPE,                  peind[i], 1, ctrl->comm, ctrl->rreq+i);      }      /* Issue the sends next. This needs some preporcessing */      for (i=0; i<nsupd; i++) {        htable[supdate[i]] = 0;        supdate[i] = graph->imap[supdate[i]];      }      iidxsort(nsupd, supdate);      for (j=i=0; i<nnbrs; i++) {        yourlastvtx = vtxdist[peind[i]+1];        for (k=j; k<nsupd && supdate[k] < yourlastvtx; k++);         MPI_Isend((void *)(supdate+j), k-j, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i);        j = k;      }      /* OK, now get into the loop waiting for the send/recv operations to finish */      MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses);      for (i=0; i<nnbrs; i++)         MPI_Get_count(ctrl->statuses+i, IDX_DATATYPE, nupds_pe+i);      MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses);      /*-------------------------------------------------------------      / Place the recieved to-be updated vertices into update[]       /-------------------------------------------------------------*/      for (i=0; i<nnbrs; i++) {        pe_updates = rupdate+sendptr[i];        for (j=0; j<nupds_pe[i]; j++) {          k = pe_updates[j];          if (htable[k-firstvtx] == 0) {            htable[k-firstvtx] = 1;            update[nlupd++] = k-firstvtx;          }        }      }      /*-------------------------------------------------------------      / Update the rinfo of the vertices in the update[] array      /-------------------------------------------------------------*/      for (ii=0; ii<nlupd; ii++) {        i = update[ii];        ASSERT(ctrl, htable[i] == 1);        htable[i] = 0;        mydomain = where[i];        myrinfo = rinfo+i;        tmp_myrinfo = tmp_rinfo+i;        my_edegrees = myrinfo->degrees;        your_edegrees = tmp_myrinfo->degrees;        graph->lmincut -= myrinfo->ed;        myrinfo->ndegrees = 0;        myrinfo->id = 0;        myrinfo->ed = 0;        for (j=xadj[i]; j<xadj[i+1]; j++) {          yourdomain = where[ladjncy[j]];          if (mydomain != yourdomain) {            myrinfo->ed += adjwgt[j];            for (k=0; k<myrinfo->ndegrees; k++) {              if (my_edegrees[k].edge == yourdomain) {                my_edegrees[k].ewgt += adjwgt[j];                your_edegrees[k].ewgt += adjwgt[j];                break;              }            }            if (k == myrinfo->ndegrees) {              my_edegrees[k].edge = yourdomain;              my_edegrees[k].ewgt = adjwgt[j];              your_edegrees[k].edge = yourdomain;              your_edegrees[k].ewgt = adjwgt[j];              myrinfo->ndegrees++;            }            ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]);            ASSERT(ctrl, tmp_myrinfo->ndegrees <= xadj[i+1]-xadj[i]);          }          else {            myrinfo->id += adjwgt[j];          }        }        graph->lmincut += myrinfo->ed;        tmp_myrinfo->id = myrinfo->id;        tmp_myrinfo->ed = myrinfo->ed;        tmp_myrinfo->ndegrees = myrinfo->ndegrees;      }      /* finally, sum-up the partition weights */      MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon,      MPI_FLOAT, MPI_SUM, ctrl->comm);    }    graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2;    if (graph->mincut == oldcut)      break;  }/*  gnswaps = GlobalSESum(ctrl, nswaps);  gnzgswaps = GlobalSESum(ctrl, nzgswaps);  if (mype == 0)    printf("niters: %d, nswaps: %d, nzgswaps: %d\n", pass+1, gnswaps, gnzgswaps);*/  GKfree((void **)&badmaxpwgt, (void **)&update, (void **)&nupds_pe, (void **)&htable, LTERM);  GKfree((void **)&changed, (void **)&pperm, (void **)&perm, (void **)&moved, LTERM);  GKfree((void **)&pgnpwgts, (void **)&ognpwgts, (void **)&overfill, (void **)&movewgts, LTERM);  GKfree((void **)&tmp_where, (void **)&tmp_rinfo, (void **)&tmp_edegrees, LTERM);  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -