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

📄 lmatch.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
字号:
/* * Copyright 1997, Regents of the University of Minnesota * * coarsen.c * * This file contains code that finds a matching and performs the coarsening * * Started 2/22/96 * George * * $Id: lmatch.c 2501 2007-11-20 02:33:29Z benkirk $ * */#include <parmetislib.h>/************************************************************************** This function finds a HEM matching between local vertices only**************************************************************************/void Mc_LocalMatch_HEM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace){  int h, i, ii, j, k;  int nvtxs, ncon, cnvtxs, firstvtx, maxi, maxidx, edge;   idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *home, *myhome, *shome, *rhome;  idxtype *perm, *match;  float maxnvwgt, *nvwgt;  graph->match_type = MATCH_LOCAL;  maxnvwgt = 1.0/((float)(ctrl->nparts)*MAXVWGT_FACTOR);  IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm));  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));  nvtxs = graph->nvtxs;  ncon = graph->ncon;  xadj = graph->xadj;  nvwgt = graph->nvwgt;  ladjncy = graph->adjncy;  adjwgt = graph->adjwgt;  home = graph->home;  vtxdist = graph->vtxdist;  firstvtx = vtxdist[ctrl->mype];  match = graph->match = idxmalloc(nvtxs+graph->nrecv, "HEM_Match: match");  myhome = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: myhome");  idxset(nvtxs, UNMATCHED, match);  idxset(graph->nrecv, 0, match+nvtxs);  /* Easy way to handle remote vertices */  /*------------------------------------------------------------  / Send/Receive the home information of interface vertices  /------------------------------------------------------------*/  if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) {    idxcopy(nvtxs, home, myhome);    shome = wspace->indices;    rhome = myhome + nvtxs;    CommInterfaceData(ctrl, graph, myhome, shome, rhome);  }  /*************************************************************   * Go now and find a local matching    *************************************************************/  perm = wspace->indices;  FastRandomPermute(nvtxs, perm, 1);  cnvtxs = 0;  for (ii=0; ii<nvtxs; ii++) {    i = perm[ii];    if (match[i] == UNMATCHED) {      maxidx = maxi = -1;      /* Find a heavy-edge matching, if the weight of the vertex is OK */      for (h=0; h<ncon; h++)        if (nvwgt[i*ncon+h] > maxnvwgt)          break;      if (h == ncon) {        for (j=xadj[i]; j<xadj[i+1]; j++) {          edge = ladjncy[j];          /* match only with local vertices */          if (myhome[edge] != myhome[i] || edge >= nvtxs)            continue;          for (h=0; h<ncon; h++)            if (nvwgt[edge*ncon+h] > maxnvwgt)               break;          if (h == ncon) {            if (match[edge] == UNMATCHED &&              (maxi == -1 ||               adjwgt[maxi] < adjwgt[j] ||              (adjwgt[maxi] == adjwgt[j] &&               BetterVBalance(ncon,nvwgt+i*ncon,nvwgt+maxidx*ncon,nvwgt+edge*ncon) >= 0))) {              maxi = j;              maxidx = edge;            }          }        }      }      if (maxi != -1) {        k = ladjncy[maxi];        if (i <= k) {          match[i] = firstvtx+k + KEEP_BIT;          match[k] = firstvtx+i;        }        else {          match[i] = firstvtx+k;          match[k] = firstvtx+i + KEEP_BIT;        }      }      else {        match[i] = (firstvtx+i) + KEEP_BIT;      }      cnvtxs++;    }  }  CommInterfaceData(ctrl, graph, match, wspace->indices, match+nvtxs);  GKfree((void **)(&myhome), LTERM);#ifdef DEBUG_MATCH  PrintVector2(ctrl, nvtxs, firstvtx, match, "Match1");#endif  if (ctrl->dbglvl&DBG_MATCHINFO) {    PrintVector2(ctrl, nvtxs, firstvtx, match, "Match");    myprintf(ctrl, "Cnvtxs: %d\n", cnvtxs);    rprintf(ctrl, "Done with matching...\n");  }  IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm));  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr));  Mc_Local_CreateCoarseGraph(ctrl, graph, wspace, cnvtxs);  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr));}/************************************************************************** This function creates the coarser graph**************************************************************************/void Mc_Local_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int cnvtxs){  int h, i, j, k, l;  int nvtxs, ncon, nedges, firstvtx, cfirstvtx;  int npes=ctrl->npes, mype=ctrl->mype;  int cnedges, v, u;  idxtype *xadj, *vwgt, *vsize, *ladjncy, *adjwgt, *vtxdist, *where, *home;  idxtype *match, *cmap;  idxtype *cxadj, *cvwgt, *cvsize = NULL, *cadjncy, *cadjwgt, *cvtxdist, *chome = NULL, *cwhere = NULL;  float *cnvwgt;  GraphType *cgraph;  int mask=(1<<13)-1, htable[8192], htableidx[8192];  nvtxs = graph->nvtxs;  ncon = graph->ncon;  vtxdist = graph->vtxdist;  xadj = graph->xadj;  vwgt = graph->vwgt;  home = graph->home;  vsize = graph->vsize;  ladjncy = graph->adjncy;  adjwgt = graph->adjwgt;  where = graph->where;  match = graph->match;  firstvtx = vtxdist[mype];  cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap");  /* Initialize the coarser graph */  cgraph = CreateGraph();  cgraph->nvtxs = cnvtxs;  cgraph->level = graph->level+1;  cgraph->ncon = ncon;  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];  /* 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+i)        continue;  /* i has been matched via the (k,i) side */      cmap[i] = cfirstvtx + cnvtxs++;      if (k != firstvtx+i) {        cmap[k-firstvtx] = cmap[i];        match[k-firstvtx] += KEEP_BIT;  /* Add the KEEP_BIT to simplify coding */      }    }  }  CommInterfaceData(ctrl, graph, cmap, wspace->indices, cmap+nvtxs);#ifdef DEBUG_CONTRACT  PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap");#endif  /*************************************************************  * 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");  cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt");  if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION)    chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome");  if (vsize != NULL)    cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize");  if (where != NULL)    cwhere = cgraph->where = idxmalloc(cnvtxs, "CreateCoarserGraph: cwhere");  cadjncy = idxmalloc(2*graph->nedges, "CreateCoarserGraph: cadjncy");  cadjwgt = cadjncy+graph->nedges;  iset(8192, -1, htable);  cxadj[0] = cnvtxs = cnedges = 0;  for (i=0; i<nvtxs; i++) {    v = firstvtx+i;     u = match[i]-KEEP_BIT;    if (v > u)       continue;  /* I have already collapsed it as (u,v) */    /* Collapse the v vertex first, which you know that 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)      chome[cnvtxs] = home[i];    if (vsize != NULL)      cvsize[cnvtxs] = vsize[i];    if (where != NULL)      cwhere[cnvtxs] = where[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) {       u -= firstvtx;      for (h=0; h<ncon; h++)        cvwgt[cnvtxs*ncon+h] += vwgt[u*ncon+h];      if (vsize != NULL)        cvsize[cnvtxs] += vsize[u];      if (where != NULL && cwhere[cnvtxs] != where[u])        myprintf(ctrl, "Something went wrong with the where local matching! %d %d\n", cwhere[cnvtxs], where[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];            }          }        }      }    }    cnedges += nedges;    for (j=cxadj[cnvtxs]; j<cnedges; j++)      htable[cadjncy[j]&mask] = -1;  /* reset the htable */    cxadj[++cnvtxs] = cnedges;  }  cgraph->nedges = cnedges;  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);  GKfree((void **)&cadjncy, (void **)&graph->where, LTERM); /* Note that graph->where works fine even if it is NULL */}

⌨️ 快捷键说明

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