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

📄 coarsen.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1997, Regents of the University of Minnesota * * mcoarsen.c * * This file contains code that performs graph coarsening * * Started 2/22/96 * George * * $Id: coarsen.c 2501 2007-11-20 02:33:29Z benkirk $ * */#include <parmetislib.h>/************************************************************************** This function creates the coarser graph**************************************************************************/void Moc_Global_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph,	WorkSpaceType *wspace, int cnvtxs){  int h, i, j, k, l, ii, jj, ll, nnbrs, nvtxs, nedges, ncon;  int firstvtx, lastvtx, cfirstvtx, clastvtx, otherlastvtx;  int npes=ctrl->npes, mype=ctrl->mype;  int cnedges, nsend, nrecv, nkeepsize, nrecvsize, nsendsize, v, u;  idxtype *xadj, *ladjncy, *adjwgt, *vwgt, *vsize, *vtxdist, *home;  idxtype *match, *cmap, *rcmap, *scmap;  idxtype *cxadj, *cadjncy, *cadjwgt, *cvwgt, *cvsize = NULL, *chome = NULL, *cvtxdist;  idxtype *rsizes, *ssizes, *rlens, *slens, *rgraph, *sgraph, *perm;  idxtype *peind, *recvptr, *recvind;  float *nvwgt, *cnvwgt;  GraphType *cgraph;  KeyValueType *scand, *rcand;  int mask=(1<<13)-1, htable[8192], htableidx[8192];  nvtxs = graph->nvtxs;  ncon = graph->ncon;  vtxdist = graph->vtxdist;  xadj = graph->xadj;  vwgt = graph->vwgt;  vsize = graph->vsize;  nvwgt = graph->nvwgt;  home = graph->home;  ladjncy = graph->adjncy;  adjwgt = graph->adjwgt;  match = graph->match;  firstvtx = vtxdist[mype];  lastvtx = vtxdist[mype+1];  cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap");  nnbrs = graph->nnbrs;  peind = graph->peind;  recvind = graph->recvind;  recvptr = graph->recvptr;  /* Use wspace->indices as the tmp space for map of the boundary   * vertices that are sent and received */  scmap = wspace->indices;  rcmap = cmap + nvtxs;  /* Initialize the coarser graph */  cgraph = CreateGraph();  cgraph->nvtxs = cnvtxs;  cgraph->ncon = ncon;  cgraph->level = graph->level+1;  cgraph->finer = graph;  graph->coarser = cgraph;  /*************************************************************  * Obtain the vtxdist of the coarser graph   **************************************************************/  cvtxdist = cgraph->vtxdist = idxmalloc(npes+1, "CreateCoarseGraph: cvtxdist");  cvtxdist[npes] = cnvtxs;  /* Use last position in the cvtxdist as a temp buffer */  MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm);  MAKECSR(i, npes, cvtxdist);  cgraph->gnvtxs = cvtxdist[npes];#ifdef DEBUG_CONTRACT  PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist");#endif  /*************************************************************  * Construct the cmap vector   **************************************************************/  cfirstvtx = cvtxdist[mype];  clastvtx = cvtxdist[mype+1];  /* Create the cmap of what you know so far locally */  cnvtxs = 0;  for (i=0; i<nvtxs; i++) {    if (match[i] >= KEEP_BIT) {      k = match[i] - KEEP_BIT;      if (k>=firstvtx && k<firstvtx+i)        continue;  /* Both (i,k) are local and i has been matched via the (k,i) side */      cmap[i] = cfirstvtx + cnvtxs++;      if (k != firstvtx+i && (k>=firstvtx && k<lastvtx)) { /* I'm matched locally */        cmap[k-firstvtx] = cmap[i];        match[k-firstvtx] += KEEP_BIT;  /* Add the KEEP_BIT to simplify coding */      }    }  }  ASSERT(ctrl, cnvtxs == clastvtx-cfirstvtx);  CommInterfaceData(ctrl, graph, cmap, scmap, rcmap);  /* Update the cmap of the locally stored vertices that will go away.    * The remote processor assigned cmap for them */  for (i=0; i<nvtxs; i++) {    if (match[i] < KEEP_BIT) { /* Only vertices that go away satisfy this*/      cmap[i] = rcmap[BSearch(graph->nrecv, recvind, match[i])];    }  }  CommInterfaceData(ctrl, graph, cmap, scmap, rcmap);#ifdef DEBUG_CONTRACT  PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap");#endif  /*************************************************************  * Determine how many adjcency lists you need to send/receive.  **************************************************************/  /* Use wspace->pairs as the tmp space for the boundary vertices that are sent and received */  scand = wspace->pairs;  rcand = graph->rcand = (KeyValueType *)GKmalloc(recvptr[nnbrs]*sizeof(KeyValueType), "CreateCoarseGraph: rcand");  nkeepsize = nsend = nrecv = 0;  for (i=0; i<nvtxs; i++) {    if (match[i] < KEEP_BIT) { /* This is going away */      scand[nsend].key = match[i];      scand[nsend].val = i;      nsend++;    }    else {      nkeepsize += (xadj[i+1]-xadj[i]);      k = match[i]-KEEP_BIT;      if (k<firstvtx || k>=lastvtx) { /* This is comming from afar */        rcand[nrecv].key = k;        rcand[nrecv].val = cmap[i] - cfirstvtx;  /* Set it for use during the partition projection */        ASSERT(ctrl, rcand[nrecv].val>=0 && rcand[nrecv].val<cnvtxs);        nrecv++;      }    }  }#ifdef DEBUG_CONTRACT  PrintPairs(ctrl, nsend, scand, "scand");  PrintPairs(ctrl, nrecv, rcand, "rcand");#endif  /***************************************************************  * Determine how many lists and their sizes  you will send and   * received for each of the neighboring PEs  ****************************************************************/  rsizes = wspace->pv1;  ssizes = wspace->pv2;  idxset(nnbrs, 0, ssizes);  idxset(nnbrs, 0, rsizes);  rlens = graph->rlens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->rlens");  slens = graph->slens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->slens");  /* Take care the sending data first */  ikeyvalsort(nsend, scand);  slens[0] = 0;  for (k=i=0; i<nnbrs; i++) {    otherlastvtx = vtxdist[peind[i]+1];    for (; k<nsend && scand[k].key < otherlastvtx; k++)      ssizes[i] += (xadj[scand[k].val+1]-xadj[scand[k].val]);    slens[i+1] = k;  }  /* Take care the receiving data next. You cannot yet determine the rsizes[] */  ikeyvalsort(nrecv, rcand);  rlens[0] = 0;  for (k=i=0; i<nnbrs; i++) {    otherlastvtx = vtxdist[peind[i]+1];    for (; k<nrecv && rcand[k].key < otherlastvtx; k++);    rlens[i+1] = k;  }#ifdef DEBUG_CONTRACT  PrintVector(ctrl, nnbrs+1, 0, slens, "slens");  PrintVector(ctrl, nnbrs+1, 0, rlens, "rlens");#endif  /***************************************************************  * Exchange size information  ****************************************************************/  /* Issue the receives first. */  for (i=0; i<nnbrs; i++) {    if (rlens[i+1]-rlens[i] > 0)  /* Issue a receive only if you are getting something */      MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i);  }  /* Take care the sending data next */  for (i=0; i<nnbrs; i++) {    if (slens[i+1]-slens[i] > 0)  /* Issue a send only if you are sending something */      MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i);  }  /* 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  PrintVector(ctrl, nnbrs, 0, rsizes, "rsizes");  PrintVector(ctrl, nnbrs, 0, ssizes, "ssizes");#endif  /*************************************************************  * Allocate memory for received/sent graphs and start sending   * and receiving data.  * rgraph and sgraph is a different data structure than CSR  * to facilitate single message exchange.  **************************************************************/  nrecvsize = idxsum(nnbrs, rsizes);  nsendsize = idxsum(nnbrs, ssizes);  if ((4+ncon)*(nrecv+nsend) + 2*(nrecvsize+nsendsize) <= wspace->nlarge) {  

⌨️ 快捷键说明

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