示例#1
0
/*************************************************************************
* This function is the entry point for ONCMETIS
**************************************************************************/
void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, 
                  idxtype *perm, idxtype *iperm) 
{
  int i, ii, j, l, wflag, nflag;
  GraphType graph;
  CtrlType ctrl;
  idxtype *cptr, *cind, *piperm;

  if (*numflag == 1)
    Change2CNumbering(*nvtxs, xadj, adjncy);

  if (options[0] == 0) {  /* Use the default parameters */
    ctrl.CType   = ONMETIS_CTYPE;
    ctrl.IType   = ONMETIS_ITYPE;
    ctrl.RType   = ONMETIS_RTYPE;
    ctrl.dbglvl  = ONMETIS_DBGLVL;
    ctrl.oflags  = ONMETIS_OFLAGS;
    ctrl.pfactor = ONMETIS_PFACTOR;
    ctrl.nseps   = ONMETIS_NSEPS;
  }
  else {
    ctrl.CType   = options[OPTION_CTYPE];
    ctrl.IType   = options[OPTION_ITYPE];
    ctrl.RType   = options[OPTION_RTYPE];
    ctrl.dbglvl  = options[OPTION_DBGLVL];
    ctrl.oflags  = options[OPTION_OFLAGS];
    ctrl.pfactor = options[OPTION_PFACTOR];
    ctrl.nseps   = options[OPTION_NSEPS];
  }
  if (ctrl.nseps < 1)
    ctrl.nseps = 1;

  ctrl.optype = OP_ONMETIS;
  ctrl.CoarsenTo = 100;

  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));

  InitRandom(-1);

  if (ctrl.pfactor > 0) { 
    /*============================================================
    * Prune the dense columns
    ==============================================================*/
    piperm = idxmalloc(*nvtxs, "ONMETIS: piperm");

    PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (float)(0.1*ctrl.pfactor));
  }
  else if (ctrl.oflags&OFLAG_COMPRESS) {
    /*============================================================
    * Compress the graph 
    ==============================================================*/
    cptr = idxmalloc(*nvtxs+1, "ONMETIS: cptr");
    cind = idxmalloc(*nvtxs, "ONMETIS: cind");

    CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind);

    if (graph.nvtxs >= COMPRESSION_FRACTION*(*nvtxs)) {
      ctrl.oflags--; /* We actually performed no compression */
      GKfree((void**)&cptr, &cind, LTERM);
    }
    else if (2*graph.nvtxs < *nvtxs && ctrl.nseps == 1)
      ctrl.nseps = 2;
  }
  else {
    SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0);
  }


  /*=============================================================
  * Do the nested dissection ordering 
  --=============================================================*/
  ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo);
  AllocateWorkSpace(&ctrl, &graph, 2);

  if (ctrl.oflags&OFLAG_CCMP) 
    MlevelNestedDissectionCC(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);
  else
    MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs);

  FreeWorkSpace(&ctrl, &graph);

  if (ctrl.pfactor > 0) { /* Order any prunned vertices */
    if (graph.nvtxs < *nvtxs) { 
      idxcopy(graph.nvtxs, iperm, perm);  /* Use perm as an auxiliary array */
      for (i=0; i<graph.nvtxs; i++)
        iperm[piperm[i]] = perm[i];
      for (i=graph.nvtxs; i<*nvtxs; i++)
        iperm[piperm[i]] = i;
    }

    GKfree((void**)&piperm, LTERM);
  }
  else if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */
    if (graph.nvtxs < COMPRESSION_FRACTION*(*nvtxs)) { 
      /* construct perm from iperm */
      for (i=0; i<graph.nvtxs; i++)
        perm[iperm[i]] = i; 
      for (l=ii=0; ii<graph.nvtxs; ii++) {
        i = perm[ii];
        for (j=cptr[i]; j<cptr[i+1]; j++)
          iperm[cind[j]] = l++;
      }
    }

    GKfree((void**)&cptr, &cind, LTERM);
  }


  for (i=0; i<*nvtxs; i++)
    perm[iperm[i]] = i;

  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));

  if (*numflag == 1)
    Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm);

}
示例#2
0
/*************************************************************************
* This function is the entry point for PWMETIS that accepts exact weights
* for the target partitions
**************************************************************************/
void METIS_mCPartGraphRecursive2(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, 
       idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
       float *tpwgts, int *options, int *edgecut, idxtype *part)
{
  int i, j;
  GraphType graph;
  CtrlType ctrl;
  float *mytpwgts;
  float avgwgt;

  if (*numflag == 1)
    Change2CNumbering(*nvtxs, xadj, adjncy);

  SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag);
  graph.npwgts = NULL;
  mytpwgts = fmalloc(*nparts, "mytpwgts");
  scopy(*nparts, tpwgts, mytpwgts);

  if (options[0] == 0) {  /* Use the default parameters */
    ctrl.CType  = McPMETIS_CTYPE;
    ctrl.IType  = McPMETIS_ITYPE;
    ctrl.RType  = McPMETIS_RTYPE;
    ctrl.dbglvl = McPMETIS_DBGLVL;
  }
  else {
    ctrl.CType  = options[OPTION_CTYPE];
    ctrl.IType  = options[OPTION_ITYPE];
    ctrl.RType  = options[OPTION_RTYPE];
    ctrl.dbglvl = options[OPTION_DBGLVL];
  }
  ctrl.optype = OP_PMETIS;
  ctrl.CoarsenTo = 100;

  ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);

  InitRandom(options[7]);

  AllocateWorkSpace(&ctrl, &graph, *nparts);

  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));

  ASSERT(CheckGraph(&graph));
  *edgecut = MCMlevelRecursiveBisection2(&ctrl, &graph, *nparts, mytpwgts, part, 1.000, 0);

/* 
{
idxtype wgt[2048], minwgt, maxwgt, sumwgt;

printf("nvtxs: %d, nparts: %d, ncon: %d\n", graph.nvtxs, *nparts, *ncon);
for (i=0; i<(*nparts)*(*ncon); i++)
  wgt[i] = 0;
for (i=0; i<graph.nvtxs; i++)
  for (j=0; j<*ncon; j++)
    wgt[part[i]*(*ncon)+j] += vwgt[i*(*ncon)+j];

for (j=0; j<*ncon; j++) {
 minwgt = maxwgt = sumwgt = 0;
 for (i=0; i<(*nparts); i++) {
   minwgt = (wgt[i*(*ncon)+j] < wgt[minwgt*(*ncon)+j]) ? i : minwgt;
   maxwgt = (wgt[i*(*ncon)+j] > wgt[maxwgt*(*ncon)+j]) ? i : maxwgt;
   sumwgt += wgt[i*(*ncon)+j];
 }
 avgwgt = (float)sumwgt / (float)*nparts;
 printf("min: %5d, max: %5d, avg: %5.2f, balance: %6.3f\n", wgt[minwgt*(*ncon)+j], wgt[maxwgt*(*ncon)+j], avgwgt, (float)wgt[maxwgt*(*ncon)+j] / avgwgt);
}
printf("\n");
}
*/

  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));

  FreeWorkSpace(&ctrl, &graph);
  GKfree((void *)&mytpwgts, LTERM);

  if (*numflag == 1)
    Change2FNumbering(*nvtxs, xadj, adjncy, part);
}
示例#3
0
/*************************************************************************
* This function is the entry point for the node ND code for ParMETIS
**************************************************************************/
void METIS_NodeNDP(int nvtxs, idxtype *xadj, idxtype *adjncy, int npes, 
                   int *options, idxtype *perm, idxtype *iperm, idxtype *sizes) 
{
  int i, ii, j, l, wflag, nflag;
  GraphType graph;
  CtrlType ctrl;
  idxtype *cptr, *cind;

  if (options[0] == 0) {  /* Use the default parameters */
    ctrl.CType   = ONMETIS_CTYPE;
    ctrl.IType   = ONMETIS_ITYPE;
    ctrl.RType   = ONMETIS_RTYPE;
    ctrl.dbglvl  = ONMETIS_DBGLVL;
    ctrl.oflags  = ONMETIS_OFLAGS;
    ctrl.pfactor = ONMETIS_PFACTOR;
    ctrl.nseps   = ONMETIS_NSEPS;
  }
  else {
    ctrl.CType   = options[OPTION_CTYPE];
    ctrl.IType   = options[OPTION_ITYPE];
    ctrl.RType   = options[OPTION_RTYPE];
    ctrl.dbglvl  = options[OPTION_DBGLVL];
    ctrl.oflags  = options[OPTION_OFLAGS];
    ctrl.pfactor = options[OPTION_PFACTOR];
    ctrl.nseps   = options[OPTION_NSEPS];
  }
  if (ctrl.nseps < 1)
    ctrl.nseps = 1;

  ctrl.optype = OP_ONMETIS;
  ctrl.CoarsenTo = 100;

  IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
  IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));

  InitRandom(-1);

  if (ctrl.oflags&OFLAG_COMPRESS) {
    /*============================================================
    * Compress the graph 
    ==============================================================*/
    cptr = idxmalloc(nvtxs+1, "ONMETIS: cptr");
    cind = idxmalloc(nvtxs, "ONMETIS: cind");

    CompressGraph(&ctrl, &graph, nvtxs, xadj, adjncy, cptr, cind);

    if (graph.nvtxs >= COMPRESSION_FRACTION*(nvtxs)) {
      ctrl.oflags--; /* We actually performed no compression */
      GKfree(&cptr, &cind, LTERM);
    }
    else if (2*graph.nvtxs < nvtxs && ctrl.nseps == 1)
      ctrl.nseps = 2;
  }
  else {
    SetUpGraph(&graph, OP_ONMETIS, nvtxs, 1, xadj, adjncy, NULL, NULL, 0);
  }


  /*=============================================================
  * Do the nested dissection ordering 
  --=============================================================*/
  ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo);
  AllocateWorkSpace(&ctrl, &graph, 2);

  idxset(2*npes-1, 0, sizes);
  MlevelNestedDissectionP(&ctrl, &graph, iperm, graph.nvtxs, npes, 0, sizes);

  FreeWorkSpace(&ctrl, &graph);

  if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */
    if (graph.nvtxs < COMPRESSION_FRACTION*(nvtxs)) { 
      /* construct perm from iperm */
      for (i=0; i<graph.nvtxs; i++)
        perm[iperm[i]] = i; 
      for (l=ii=0; ii<graph.nvtxs; ii++) {
        i = perm[ii];
        for (j=cptr[i]; j<cptr[i+1]; j++)
          iperm[cind[j]] = l++;
      }
    }

    GKfree(&cptr, &cind, LTERM);
  }


  for (i=0; i<nvtxs; i++)
    perm[iperm[i]] = i;

  IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
  IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));

}
void mlmclWithGraph(GraphType *graph,idxtype* indices,Options opt)
{
	GraphType *cgraph,*t;
	int nvtxs=graph->nvtxs;
	CtrlType ctrl;
	int levels=0;
	Matrix *M=NULL;

	int ct = ctrl.CoarsenTo = opt.coarsenTo, runMcl=0;
	ctrl.CType=opt.matchType;
/*	if ( nvtxs > 50000 )
		ctrl.CType = MATCH_POWERLAW_FC; */
	ctrl.optype=OP_KMETIS;
//	ctrl.maxvwgt = (int) round( ((ct>100)?nvtxs/100: nvtxs/ct));
//	ctrl.maxvwgt = (ctrl.maxvwgt > 5000 ) ? 5000 : ctrl.maxvwgt ;
	ctrl.dbglvl=1;

	if ( ct < 5 )
		ctrl.maxvwgt = (int) ceil( (1.5*nvtxs)/ct );
	else if ( ct <= 100 )
		ctrl.maxvwgt = (int) ceil( (2.0*nvtxs)/ct );
	else if ( ct > 100 )
	{
		// we can allow some imbalance here.
		ctrl.maxvwgt = (int) ceil( 10.0 * nvtxs/ct );
	}

	my_AllocateWorkSpace(&ctrl,graph);

	cgraph = Coarsen2Way(&ctrl,graph);	

	FreeWorkSpace(&ctrl, graph);

//	printf( "Coarsen time:%.2f\n",gettimer(ctrl.CoarsenTmr) );
	for(levels=0,t=cgraph;t->finer!=NULL;t=t->finer,levels++);

	printf("Coarsened %d levels\n", levels);
	printf("Number of vertices in coarsest graph:%d\n", cgraph->nvtxs);
//	printf("In lib/mlmcl.c: penalty_power:%.1f\n", opt.penalty_power);
	fflush(stdout);

	while ( cgraph != NULL )
	{
		Matrix *M0, *Mnew;
		int iters;
//		dump_graph(cgraph);
		M0=setupCanonicalMatrix(cgraph->nvtxs, cgraph->nedges,
			cgraph->xadj, cgraph->adjncy, cgraph->adjwgt, opt.ncutify);

		if ( cgraph->coarser != NULL )
		{
			// if this is not the original graph, then we don't
			// need the adjacency information in the graph
			// anymore. M0 is what we want, and we have it, so we
			// can free cgraph->gdata.
			GKfree( (void**)&(cgraph->gdata), LTERM);
		}

		if ( cgraph->coarser == NULL )
		{
		// if this is the coarsest graph, flow matrix is same as
		// the transition matrix. 
			M=M0;
	//		dumpMatrix(M);
		}

		if (cgraph->finer == NULL)
			iters=opt.num_last_iter;
		else
			iters=opt.iter_per_level;

		if ( cgraph->coarser == NULL )
		{;
			//printRow(M,35);
			//printRow(M,36);
		}

		Mnew=dprmcl(M,M0,cgraph, opt, iters, levels);
		// M would have been freed in mclForMultiLevel, so no
		// need to free it here.
	/*	if ( M0 != NULL )
		{
			freeMatrix(M0);
		} */

		if ( cgraph->coarser == NULL )
		{
			//printRow(Mnew,35);
			//printRow(Mnew,36);
		}

		if ( runMcl > 0 && cgraph->finer == NULL )
		{
			/* run original mcl so that the matrix moves closer to
			 * convergence */
			M=dprmcl(Mnew,Mnew,cgraph, opt, iters/2,levels);
			/* Mnew would not have been freed in mclForMultiLevel
			 * above. */
			freeMatrix(Mnew);
		}
		else
		{
			M=Mnew;
		}

		if ( cgraph->finer != NULL )
		{
			int nnzRefinedGraph = 2*M->nnz;
			if ( ctrl.CType == MATCH_POWERLAW_FC )
			{
				int ii;
				nnzRefinedGraph = 0;
				for ( ii=0; ii<cgraph->finer->nvtxs; ii++ )
				{
					int tx=cgraph->finer->cmap[ii];
					nnzRefinedGraph +=
					M->xadj[tx+1]-M->xadj[tx];
				}
			}
			else if ( ctrl.CType == MATCH_HASH  && levels <= 3 )
			{
				int ii;
				nnzRefinedGraph=0;
				for ( ii=0; ii<cgraph->nvtxs; ii++ )
				{
					nnzRefinedGraph += cgraph->vwgt[ii] *
							(M->xadj[ii+1] - M->xadj[ii]);
				}
			}
//			dumpMatrix(M);
			Mnew=propagateFlow(M,cgraph,cgraph->finer,nnzRefinedGraph);
//			dumpMatrix(Mnew);
			if ( M != NULL )
			{
				freeMatrix(M);
			}
			M=Mnew;
		}
		cgraph=cgraph->finer;

		// These two didn't get freed earlier, when we freed
		// gdata.
		if ( cgraph != NULL )
		{
			GKfree( (void**)&(cgraph->coarser->vwgt),
					(void**)&(cgraph->coarser->rmap1), LTERM);
		}

		levels--;
		printf("Done level %d\n", levels+1);
		fflush(stdout);
	}

	getAttractorsForAll(M);
	idxcopy(nvtxs, M->attractors, indices);

/*	int nClusters = 0;
	wgttype minWgt = 0;
	idxtype *ret = getNodesToComponentMap(M, &nClusters, minWgt);
	idxcopy(nvtxs, ret, indices);
	free(ret);
*/
	freeMatrix(M);
}