Example #1
0
/*************************************************************************
* This function is the entry point of refinement
**************************************************************************/
void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, 
       float *ubvec)
{

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

  /* Compute the parameters of the coarsest graph */
  MocComputeKWayPartitionParams(ctrl, graph, nparts);

  for (;;) {
    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr));

    if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
      MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
      MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); 
      ComputeKWayBoundary(ctrl, graph, nparts);
    }

    MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); 

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

    if (graph == orggraph)
      break;

    graph = graph->finer;
    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
    MocProjectKWayPartition(ctrl, graph, nparts);
    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
  }

  if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) {
    MocComputeKWayBalanceBoundary(ctrl, graph, nparts);
    MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); 
    ComputeKWayBoundary(ctrl, graph, nparts);
    MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); 
  }

  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
}
void RefineKWay(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph)
{
  idx_t i, nlevels, contig=ctrl->contig;
  graph_t *ptr;

  IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr));

  /* Determine how many levels are there */
  for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); 

  /* Compute the parameters of the coarsest graph */
  ComputeKWayPartitionParams(ctrl, graph);

  /* Try to minimize the sub-domain connectivity */
  if (ctrl->minconn) 
    EliminateSubDomainEdges(ctrl, graph);
  
  /* Deal with contiguity constraints at the beginning */
  if (contig && FindPartitionInducedComponents(graph, graph->where, NULL, NULL) > ctrl->nparts) { 
    EliminateComponents(ctrl, graph);

    ComputeKWayBoundary(ctrl, graph, BNDTYPE_BALANCE);
    Greedy_KWayOptimize(ctrl, graph, 5, 0, OMODE_BALANCE); 

    ComputeKWayBoundary(ctrl, graph, BNDTYPE_REFINE);
    Greedy_KWayOptimize(ctrl, graph, ctrl->niter, 0, OMODE_REFINE); 

    ctrl->contig = 0;
  }

  /* Refine each successively finer graph */
  for (i=0; ;i++) {
    if (ctrl->minconn && i == nlevels/2) 
      EliminateSubDomainEdges(ctrl, graph);

    IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr));

    if (2*i >= nlevels && !IsBalanced(ctrl, graph, .02)) {
      ComputeKWayBoundary(ctrl, graph, BNDTYPE_BALANCE);
      Greedy_KWayOptimize(ctrl, graph, 1, 0, OMODE_BALANCE); 
      ComputeKWayBoundary(ctrl, graph, BNDTYPE_REFINE);
    }

    Greedy_KWayOptimize(ctrl, graph, ctrl->niter, 5.0, OMODE_REFINE); 

    IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr));

    /* Deal with contiguity constraints in the middle */
    if (contig && i == nlevels/2) {
      if (FindPartitionInducedComponents(graph, graph->where, NULL, NULL) > ctrl->nparts) {
        EliminateComponents(ctrl, graph);

        if (!IsBalanced(ctrl, graph, .02)) {
          ctrl->contig = 1;
          ComputeKWayBoundary(ctrl, graph, BNDTYPE_BALANCE);
          Greedy_KWayOptimize(ctrl, graph, 5, 0, OMODE_BALANCE); 
  
          ComputeKWayBoundary(ctrl, graph, BNDTYPE_REFINE);
          Greedy_KWayOptimize(ctrl, graph, ctrl->niter, 0, OMODE_REFINE); 
          ctrl->contig = 0;
        }
      }
    }

    if (graph == orggraph)
      break;

    graph = graph->finer;

    IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr));
    ASSERT(graph->vwgt != NULL);

    ProjectKWayPartition(ctrl, graph);
    IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr));
  }

  /* Deal with contiguity requirement at the end */
  ctrl->contig = contig;
  if (contig && FindPartitionInducedComponents(graph, graph->where, NULL, NULL) > ctrl->nparts) 
    EliminateComponents(ctrl, graph);

  if (!IsBalanced(ctrl, graph, 0.0)) {
    ComputeKWayBoundary(ctrl, graph, BNDTYPE_BALANCE);
    Greedy_KWayOptimize(ctrl, graph, 10, 0, OMODE_BALANCE); 

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

  if (ctrl->contig) 
    ASSERT(FindPartitionInducedComponents(graph, graph->where, NULL, NULL) == ctrl->nparts);

  IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr));
}
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;
}
Example #4
0
/*************************************************************************
* This function is the entry point of refinement
**************************************************************************/
void RefineKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor)
{
  int i, nlevels, mustfree=0;
  GraphType *ptr;

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

  /* Compute the parameters of the coarsest graph */
  ComputeKWayPartitionParams(ctrl, graph, nparts);

  /* Take care any non-contiguity */
  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr1));
  if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) {
    EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25);
    EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts);
    EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25);
  }
  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr1));

  /* Determine how many levels are there */
  for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); 

  for (i=0; ;i++) {
    /* PrintSubDomainGraph(graph, nparts, graph->where); */
    if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN && (i == nlevels/2 || i == nlevels/2+1))
      EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts);

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

    if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) {
      ComputeKWayBalanceBoundary(ctrl, graph, nparts);
      if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN)
        Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
      else
        Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); 
      ComputeKWayBoundary(ctrl, graph, nparts);
    }

    switch (ctrl->RType) {
      case RTYPE_KWAYRANDOM:
        Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); 
        break;
      case RTYPE_KWAYGREEDY:
        Greedy_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10); 
        break;
      case RTYPE_KWAYRANDOM_MCONN:
        Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); 
        break;
    }
    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr));

    if (graph == orggraph)
      break;

    GKfree(&graph->gdata, LTERM);  /* Deallocate the graph related arrays */

    graph = graph->finer;

    IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr));
    if (graph->vwgt == NULL) {
      graph->vwgt = idxsmalloc(graph->nvtxs, 1, "RefineKWay: graph->vwgt");
      graph->adjwgt = idxsmalloc(graph->nedges, 1, "RefineKWay: graph->adjwgt");
      mustfree = 1;
    }
    ProjectKWayPartition(ctrl, graph, nparts);
    IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr));
  }

  if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) {
    ComputeKWayBalanceBoundary(ctrl, graph, nparts);
    if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) {
      Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
      Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
    }
    else {
      Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); 
      Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); 
    }
  }

  /* Take care any trivial non-contiguity */
  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr2));
  EliminateComponents(ctrl, graph, nparts, tpwgts, ubfactor);
  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr2));

  if (mustfree) 
    GKfree(&graph->vwgt, &graph->adjwgt, LTERM);

  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr));
}