Exemplo n.º 1
0
/*************************************************************************
* This function finds a matching using the HEM heuristic
**************************************************************************/
void Match_HEM(CtrlType *ctrl, GraphType *graph)
{
  int i, ii, j, k, nvtxs, cnvtxs, maxidx, dim;
  idxtype *xadj, *vwgt, *adjncy;
  idxtype *match, *cmap, *perm, *tperm;
  realtype curwgt, maxwgt;
  realtype *vvol, *vsurf, *adjwgt, *adjwgtsum;

  dim       = ctrl->dim;
  nvtxs     = graph->nvtxs;
  xadj      = graph->xadj;
  vwgt      = graph->vwgt;
  vvol      = graph->vvol;
  vsurf     = graph->vsurf;
  adjncy    = graph->adjncy;
  adjwgt    = graph->adjwgt;
  adjwgtsum = graph->adjwgtsum;

  cmap = graph->cmap = idxsmalloc(nvtxs, -1, "cmap");
  match = idxsmalloc(nvtxs, -1, "match");

  perm = idxmalloc(nvtxs, "perm");
  tperm = idxmalloc(nvtxs, "tperm");

  RandomPermute(nvtxs, tperm, 1);
  BucketSortKeysInc(nvtxs, vwgt[iamax(nvtxs, vwgt)], vwgt, tperm, perm);
  /* RandomPermute(nvtxs, perm, 1);  */

  cnvtxs = 0;

  /* Compute a heavy-edge style matching giving preferance to small vertices */
  for (ii=0; ii<nvtxs; ii++) {
     i = perm[ii];

     if (match[i] == UNMATCHED) {
       maxidx = i;
       maxwgt = 0.0;

       /* Find a heavy-edge matching, subject to maxvwgt constraints */
       for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = adjncy[j];
          curwgt = 1.0/ARATIO2(dim, vsurf[i]+vsurf[k]+adjwgtsum[i]+adjwgtsum[k]-
                   2.0*adjwgt[j], vvol[i]+vvol[k]);
          if (match[k] == UNMATCHED && vwgt[i]+vwgt[k] <= ctrl->maxsize &&
              curwgt > maxwgt) {
            maxwgt = curwgt;
            maxidx = k;
          }
       }

       cmap[i] = cmap[maxidx] = cnvtxs++;
       match[i] = maxidx;
       match[maxidx] = i;
     }
  }

  CreateCoarseGraph(graph, cnvtxs, match, perm);

  IMfree((void**)&tperm, &perm, &match, LTERM);
}
void GrowKWayPartitioning(ctrl_t *ctrl, graph_t *graph)
{
  idx_t v, i, ii, j, nvtxs, nparts, nmis, minvwgt;
  idx_t *xadj, *adjncy, *vwgt, *adjwgt;
  idx_t *where, *pwgts, *minwgt, *maxwgt, *nbrwgt;
  idx_t *perm;
  real_t ubfactor_original;


  WCOREPUSH;

  nvtxs  = graph->nvtxs;
  xadj   = graph->xadj;
  adjncy = graph->adjncy;
  adjwgt = graph->adjwgt;
  vwgt   = graph->vwgt;

  where  = graph->where;
  pwgts  = graph->pwgts;

  nparts = ctrl->nparts;
  
  /* setup the weight intervals of the various subdomains */
  minwgt  = iwspacemalloc(ctrl, nparts);
  maxwgt  = iwspacemalloc(ctrl, nparts);

  for (i=0; i<nparts; i++) {
    maxwgt[i] = ctrl->tpwgts[i]*graph->tvwgt[0]*ctrl->ubfactors[0];
    minwgt[i] = ctrl->tpwgts[i]*graph->tvwgt[0]*(1.0/ctrl->ubfactors[0]);
  }

  /* setup the initial state of the partitioning */
  iset(nvtxs, nparts, where);
  iset(nparts, 0, pwgts);

  perm = iwspacemalloc(ctrl, nvtxs);

  /* compute the weights of the neighborhood */
  nbrwgt = iwspacemalloc(ctrl, nvtxs);
  /*
  for (i=0; i<nvtxs; i++) {
    nbrwgt[i] = vwgt[i];
    for (j=xadj[i]; j<xadj[i+1]; j++) {
      ii = adjncy[j];
      nbrwgt[i] += vwgt[ii]/log2(2+xadj[ii+1]-xadj[ii]);
    }
  }
  */
  for (i=0; i<nvtxs; i++) {
    nbrwgt[i] = 0;
    for (j=xadj[i]; j<xadj[i+1]; j++) 
      nbrwgt[i] += adjwgt[j];
  }
  minvwgt = isum(nvtxs, nbrwgt, 1)/nvtxs;


#ifdef XXX
  perm    = iwspacemalloc(ctrl, nvtxs);
  tperm   = iwspacemalloc(ctrl, nvtxs);
  degrees = iwspacemalloc(ctrl, nvtxs);

  irandArrayPermute(nvtxs, tperm, nvtxs, 1);
  irandArrayPermute(nvtxs, tperm, nvtxs, 0);

  avgdegree = 1.0*(xadj[nvtxs]/nvtxs);
  for (i=0; i<nvtxs; i++) {
    bnum = sqrt(1+xadj[i+1]-xadj[i]);
    degrees[i] = (bnum > avgdegree ? avgdegree : bnum);
  }
  BucketSortKeysInc(ctrl, nvtxs, avgdegree, degrees, tperm, perm);
#endif

  ubfactor_original  = ctrl->ubfactors[0];
  ctrl->ubfactors[0] = 1.05*ubfactor_original;

  /* find an MIS of vertices by randomly traversing the vertices and assign them to
     the different partitions */
  irandArrayPermute(nvtxs, perm, nvtxs, 1);
  for (nmis=0, ii=0; ii<nvtxs; ii++) {
    i=perm[ii];

    if (nbrwgt[i] < minvwgt)
      continue;

    if (where[i] == nparts) {
      pwgts[nmis] = vwgt[i];
      where[i]    = nmis++;

      /* mark first level neighbors */
      for (j=xadj[i]; j<xadj[i+1]; j++) {
        v = adjncy[j];
        if (where[v] == nparts)
          where[v] = nparts+1;
      }
    }
    if (nmis == nparts)
      break;
  }
  printf("  nvtxs: %"PRIDX", nmis: %"PRIDX", minvwgt: %"PRIDX", ii: %"PRIDX"\n", nvtxs, nmis, minvwgt, ii);


  /* if the size of the MIS is not sufficiently large, go and find some additional seeds */
  if (nmis < nparts) {
    minvwgt = .75*minvwgt;

    irandArrayPermute(nvtxs, perm, nvtxs, 0);
    for (ii=0; ii<nvtxs; ii++) {
      i=perm[ii];

      if (nbrwgt[i] < minvwgt)
        continue;

      if (where[i] == nparts) {
        pwgts[nmis] = vwgt[i];
        where[i]    = nmis++;

        /* mark first level neighbors */
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          v = adjncy[j];
          if (where[v] == nparts)
            where[v] = nparts+1;
        }
      }
      if (nmis == nparts)
        break;
    }

    printf("  nvtxs: %"PRIDX", nmis: %"PRIDX"\n", nvtxs, nmis);
  }

  /* if the size of the MIS is not sufficiently large, go and find some additional seeds */
  if (nmis < nparts) {
    irandArrayPermute(nvtxs, perm, nvtxs, 0);
    for (ii=0; ii<nvtxs; ii++) {
      i = perm[ii];

      if (where[i] == nparts+1) { 
        pwgts[nmis] = vwgt[i];
        where[i]    = nmis++;
      }
      if (nmis == nparts)
        break;
    }
    printf("  nvtxs: %"PRIDX", nmis: %"PRIDX"\n", nvtxs, nmis);
  }

  /* set all unassigned vertices to 'nparts' */
  for (i=0; i<nvtxs; i++) {
    if (where[i] >= nparts)
      where[i] = nparts;
  }

  WCOREPOP;

  /* refine the partition */
  ComputeKWayPartitionParams(ctrl, graph);

  if (ctrl->minconn)
    EliminateSubDomainEdges(ctrl, graph);

  for (i=0; i<4; i++) {
    ComputeKWayBoundary(ctrl, graph, BNDTYPE_BALANCE);
    Greedy_KWayOptimize(ctrl, graph, 10, 0, OMODE_BALANCE);
    /*
    for (k=0; k<nparts; k++)
      printf("%"PRIDX"\n", graph->pwgts[k]);
    exit(0);
    */


    ComputeKWayBoundary(ctrl, graph, BNDTYPE_REFINE);
    Greedy_KWayOptimize(ctrl, graph, ctrl->niter, 1, OMODE_REFINE);
    Greedy_KWayEdgeCutOptimize(ctrl, graph, ctrl->niter);
  }

  ctrl->ubfactors[0] = ubfactor_original;
}
Exemplo n.º 3
0
/*************************************************************************
* This function finds a matching using the HEM heuristic
**************************************************************************/
void Match_SHEM(CtrlType *ctrl, GraphType *graph)
{
  int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree;
  idxtype *xadj, *vwgt, *adjncy, *adjwgt;
  idxtype *match, *cmap, *degrees, *perm, *tperm;

  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));

  nvtxs = graph->nvtxs;
  xadj = graph->xadj;
  vwgt = graph->vwgt;
  adjncy = graph->adjncy;
  adjwgt = graph->adjwgt;

  cmap = graph->cmap;
  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));

  perm = idxwspacemalloc(ctrl, nvtxs);
  tperm = idxwspacemalloc(ctrl, nvtxs);
  degrees = idxwspacemalloc(ctrl, nvtxs);

  RandomPermute(nvtxs, tperm, 1);
  avgdegree = 0.7*(xadj[nvtxs]/nvtxs);
  for (i=0; i<nvtxs; i++)
    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);

  cnvtxs = 0;

  /* Take care any islands. Islands are matched with non-islands due to coarsening */
  for (ii=0; ii<nvtxs; ii++) {
    i = perm[ii];

    if (match[i] == UNMATCHED) {  /* Unmatched */
      if (xadj[i] < xadj[i+1])
        break;

      maxidx = i;
      for (j=nvtxs-1; j>ii; j--) {
        k = perm[j];
        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
          maxidx = k;
          break;
        }
      }

      cmap[i] = cmap[maxidx] = cnvtxs++;
      match[i] = maxidx;
      match[maxidx] = i;
    }
  }

  /* Continue with normal matching */
  for (; ii<nvtxs; ii++) {
    i = perm[ii];

    if (match[i] == UNMATCHED) {  /* Unmatched */
      maxidx = i;
      maxwgt = 0;

      /* Find a heavy-edge matching, subject to maxvwgt constraints */
      for (j=xadj[i]; j<xadj[i+1]; j++) {
        if (match[adjncy[j]] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) {
          maxwgt = adjwgt[j];
          maxidx = adjncy[j];
        }
      }

      cmap[i] = cmap[maxidx] = cnvtxs++;
      match[i] = maxidx;
      match[maxidx] = i;
    }
  }

  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));

  idxwspacefree(ctrl, nvtxs);  /* degrees */
  idxwspacefree(ctrl, nvtxs);  /* tperm */

  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);

  idxwspacefree(ctrl, nvtxs);
  idxwspacefree(ctrl, nvtxs);
}
Exemplo n.º 4
0
/*************************************************************************
* This function finds a matching using the HEM heuristic
**************************************************************************/
void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm)
{
  int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree;
  idxtype *xadj, *adjncy, *adjwgt;
  idxtype *match, *cmap, *degrees, *perm, *tperm;
  float *nvwgt, vbal;

  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr));

  nvtxs = graph->nvtxs;
  ncon = graph->ncon;
  xadj = graph->xadj;
  nvwgt = graph->nvwgt;
  adjncy = graph->adjncy;
  adjwgt = graph->adjwgt;

  cmap = graph->cmap;
  match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs));

  perm = idxwspacemalloc(ctrl, nvtxs);
  tperm = idxwspacemalloc(ctrl, nvtxs);
  degrees = idxwspacemalloc(ctrl, nvtxs);

  RandomPermute(nvtxs, tperm, 1);
  avgdegree = (int)(0.7*(xadj[nvtxs]/nvtxs));
  for (i=0; i<nvtxs; i++) 
    degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]);
  BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm);

  cnvtxs = 0;

  /* Take care any islands. Islands are matched with non-islands due to coarsening */
  for (ii=0; ii<nvtxs; ii++) {
    i = perm[ii];

    if (match[i] == UNMATCHED) {  /* Unmatched */
      if (xadj[i] < xadj[i+1])
        break;

      maxidx = i;
      for (j=nvtxs-1; j>ii; j--) {
        k = perm[j];
        if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) {
          maxidx = k;
          break;
        }
      }

      cmap[i] = cmap[maxidx] = cnvtxs++;
      match[i] = maxidx;
      match[maxidx] = i;
    }
  }

  /* Continue with normal matching */
  for (; ii<nvtxs; ii++) {
    i = perm[ii];

    if (match[i] == UNMATCHED) {  /* Unmatched */
      maxidx = i;
      maxwgt = -1;
      vbal = 0.0;

      /* Find a heavy-edge matching, subject to maxvwgt constraints */
      for (j=xadj[i]; j<xadj[i+1]; j++) {
        k = adjncy[j];
        if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) {
          if (maxidx != i)
            vbal = BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon);

          if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) {
            maxwgt = adjwgt[j];
            maxidx = k;
          }
        }
      }

      cmap[i] = cmap[maxidx] = cnvtxs++;
      match[i] = maxidx;
      match[maxidx] = i;
    }
  }

  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr));

  idxwspacefree(ctrl, nvtxs);  /* degrees */
  idxwspacefree(ctrl, nvtxs);  /* tperm */

  CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm);

  idxwspacefree(ctrl, nvtxs);
  idxwspacefree(ctrl, nvtxs);
}