Esempio n. 1
0
/*************************************************************************
* This function takes a graph and produces a bisection of it
**************************************************************************/
int MlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor)
{
  int i, j, nvtxs, tvwgt, tpwgts2[2];
  GraphType *cgraph;
  int wgtflag=3, numflag=0, options[10], edgecut;

  cgraph = Coarsen2Way(ctrl, graph);

  IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
  AllocateKWayPartitionMemory(ctrl, cgraph, nparts);

  options[0] = 1; 
  options[OPTION_CTYPE] = MATCH_SHEMKWAY;
  options[OPTION_ITYPE] = IPART_GGPKL;
  options[OPTION_RTYPE] = RTYPE_FM;
  options[OPTION_DBGLVL] = 0;

  METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, 
                            cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, 
                            &edgecut, cgraph->where);

  IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
  IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut));

  IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where));

  RefineKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor);

  idxcopy(graph->nvtxs, graph->where, part);

  GKfree(&graph->gdata, &graph->rdata, LTERM);

  return graph->mincut;

}
Esempio n. 2
0
/*************************************************************************
* This function is the entry point for PMETIS
**************************************************************************/
void METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
                              idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, 
                              int *options, int *edgecut, idxtype *part)
{
  int i;
  floattype *tpwgts;

  tpwgts = fmalloc(*nparts, "KMETIS: tpwgts");
  for (i=0; i<*nparts; i++) 
    tpwgts[i] = 1.0/(1.0*(*nparts));

  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, 
                            tpwgts, options, edgecut, part);

  free(tpwgts);
}
Esempio n. 3
0
/*************************************************************************
* This function is the entry point for PMETIS
**************************************************************************/
void METIS_PartGraphRecursive(idxtype *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, 
                              idxtype *adjwgt, idxtype *wgtflag, idxtype *numflag, idxtype *nparts, 
                              idxtype *options, idxtype *edgecut, idxtype *part)
{
  idxtype i;
  float *tpwgts;

  tpwgts = gk_fmalloc(*nparts, "KMETIS: tpwgts");
  for (i=0; i<*nparts; i++) 
    tpwgts[i] = 1.0/(1.0*(*nparts));

  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, 
                            tpwgts, options, edgecut, part);

  gk_free((void **)&tpwgts, LTERM);
}
Esempio n. 4
0
void metis_wpartgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
{
  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
}
Esempio n. 5
0
void METIS_WPARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part)
{
  METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part);
}
Esempio n. 6
0
// Call Metis with options from dictionary.
Foam::label Foam::metisDecomp::decompose
(
    const List<int>& adjncy,
    const List<int>& xadj,
    const scalarField& cWeights,

    List<int>& finalDecomp
)
{
    // C style numbering
    int numFlag = 0;

    // Method of decomposition
    // recursive: multi-level recursive bisection (default)
    // k-way: multi-level k-way
    word method("k-way");

    int numCells = xadj.size()-1;

    // decomposition options. 0 = use defaults
    List<int> options(5, 0);

    // processor weights initialised with no size, only used if specified in
    // a file
    Field<floatScalar> processorWeights;

    // cell weights (so on the vertices of the dual)
    List<int> cellWeights;

    // face weights (so on the edges of the dual)
    List<int> faceWeights;


    // Check for externally provided cellweights and if so initialise weights
    scalar minWeights = gMin(cWeights);
    if (cWeights.size() > 0)
    {
        if (minWeights <= 0)
        {
            WarningIn
            (
                "metisDecomp::decompose"
                "(const pointField&, const scalarField&)"
            )   << "Illegal minimum weight " << minWeights
                << endl;
        }

        if (cWeights.size() != numCells)
        {
            FatalErrorIn
            (
                "metisDecomp::decompose"
                "(const pointField&, const scalarField&)"
            )   << "Number of cell weights " << cWeights.size()
                << " does not equal number of cells " << numCells
                << exit(FatalError);
        }
        // Convert to integers.
        cellWeights.setSize(cWeights.size());
        forAll(cellWeights, i)
        {
            cellWeights[i] = int(cWeights[i]/minWeights);
        }
    }


    // Check for user supplied weights and decomp options
    if (decompositionDict_.found("metisCoeffs"))
    {
        const dictionary& metisCoeffs =
            decompositionDict_.subDict("metisCoeffs");
        word weightsFile;

        if (metisCoeffs.readIfPresent("method", method))
        {
            if (method != "recursive" && method != "k-way")
            {
                FatalErrorIn("metisDecomp::decompose()")
                        << "Method " << method << " in metisCoeffs in dictionary : "
                        << decompositionDict_.name()
                        << " should be 'recursive' or 'k-way'"
                        << exit(FatalError);
            }

            Info<< "metisDecomp : Using Metis method     " << method
                << nl << endl;
        }

        if (metisCoeffs.readIfPresent("options", options))
        {
            if (options.size() != 5)
            {
                FatalErrorIn("metisDecomp::decompose()")
                        << "Number of options in metisCoeffs in dictionary : "
                        << decompositionDict_.name()
                        << " should be 5"
                        << exit(FatalError);
            }

            Info<< "metisDecomp : Using Metis options     " << options
                << nl << endl;
        }

        if (metisCoeffs.readIfPresent("processorWeights", processorWeights))
        {
            processorWeights /= sum(processorWeights);

            if (processorWeights.size() != nProcessors_)
            {
                FatalErrorIn("metisDecomp::decompose(const pointField&)")
                        << "Number of processor weights "
                        << processorWeights.size()
                        << " does not equal number of domains " << nProcessors_
                        << exit(FatalError);
            }
        }

        //if (metisCoeffs.readIfPresent("cellWeightsFile", weightsFile))
        //{
        //    Info<< "metisDecomp : Using cell-based weights." << endl;
        //
        //    IOList<int> cellIOWeights
        //    (
        //        IOobject
        //        (
        //            weightsFile,
        //            mesh_.time().timeName(),
        //            mesh_,
        //            IOobject::MUST_READ,
        //            IOobject::AUTO_WRITE
        //        )
        //    );
        //    cellWeights.transfer(cellIOWeights);
        //
        //    if (cellWeights.size() != xadj.size()-1)
        //    {
        //        FatalErrorIn("metisDecomp::decompose(const pointField&)")
        //            << "Number of cell weights " << cellWeights.size()
        //            << " does not equal number of cells " << xadj.size()-1
        //            << exit(FatalError);
        //    }
        //}
    }

    int nProcs = nProcessors_;

    // output: cell -> processor addressing
    finalDecomp.setSize(numCells);

    // output: number of cut edges
    int edgeCut = 0;

    // Vertex weight info
    int wgtFlag = 0;
    int* vwgtPtr = NULL;
    int* adjwgtPtr = NULL;

    if (cellWeights.size())
    {
        vwgtPtr = cellWeights.begin();
        wgtFlag += 2;       // Weights on vertices
    }
    if (faceWeights.size())
    {
        adjwgtPtr = faceWeights.begin();
        wgtFlag += 1;       // Weights on edges
    }

    if (method == "recursive")
    {
        if (processorWeights.size())
        {
            METIS_WPartGraphRecursive
            (
                &numCells,         // num vertices in graph
                const_cast<List<int>&>(xadj).begin(),   // indexing into adjncy
                const_cast<List<int>&>(adjncy).begin(), // neighbour info
                vwgtPtr,           // vertexweights
                adjwgtPtr,         // no edgeweights
                &wgtFlag,
                &numFlag,
                &nProcs,
                processorWeights.begin(),
                options.begin(),
                &edgeCut,
                finalDecomp.begin()
            );
        }
        else
        {
            METIS_PartGraphRecursive
            (
                &numCells,         // num vertices in graph
                const_cast<List<int>&>(xadj).begin(),   // indexing into adjncy
                const_cast<List<int>&>(adjncy).begin(), // neighbour info
                vwgtPtr,           // vertexweights
                adjwgtPtr,         // no edgeweights
                &wgtFlag,
                &numFlag,
                &nProcs,
                options.begin(),
                &edgeCut,
                finalDecomp.begin()
            );
        }
    }
    else
    {
        if (processorWeights.size())
        {
            METIS_WPartGraphKway
            (
                &numCells,         // num vertices in graph
                const_cast<List<int>&>(xadj).begin(),   // indexing into adjncy
                const_cast<List<int>&>(adjncy).begin(), // neighbour info
                vwgtPtr,           // vertexweights
                adjwgtPtr,         // no edgeweights
                &wgtFlag,
                &numFlag,
                &nProcs,
                processorWeights.begin(),
                options.begin(),
                &edgeCut,
                finalDecomp.begin()
            );
        }
        else
        {
            METIS_PartGraphKway
            (
                &numCells,         // num vertices in graph
                const_cast<List<int>&>(xadj).begin(),   // indexing into adjncy
                const_cast<List<int>&>(adjncy).begin(), // neighbour info
                vwgtPtr,           // vertexweights
                adjwgtPtr,         // no edgeweights
                &wgtFlag,
                &numFlag,
                &nProcs,
                options.begin(),
                &edgeCut,
                finalDecomp.begin()
            );
        }
    }

    return edgeCut;
}
Esempio n. 7
0
JNIEXPORT jint JNICALL Java_jprime_JMetis_wPartitionGraph(
		JNIEnv * env,
		jobject obj,
		jboolean j_force_PartGraphRecursive,
		jboolean j_force_PartGraphKway,
		jint j_num_vertices,
		jintArray j_xadj,
		jintArray j_adjncy,
		jintArray j_vwgt,
		jintArray j_adjwgt,
		jint j_wgtflag,
		jint j_nparts,
		jfloatArray j_part_weights,
		jintArray j_options,
		jintArray j_partioned_nodes){
	mysrand(7654321L);
	//delcare vars
	jint * xadj=NULL, * adjncy=NULL,* vwgt=NULL, * adjwgt=NULL, * options=NULL, * partioned_nodes=NULL;
	jfloat* part_weights=NULL;
	int idx, edges_cut=-1, num_vertices=0, nparts=0, wgtflag=0, numflag=0;
	jsize xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len, part_weights_len;

	//copy the jsize vars
	num_vertices=j_num_vertices;
	nparts=j_nparts;
	wgtflag=j_wgtflag;

	//get array lengths
	xadj_len            = (*env)->GetArrayLength(env,j_xadj);
	adjncy_len          = (*env)->GetArrayLength(env,j_adjncy);
	vwgt_len            = (*env)->GetArrayLength(env,j_vwgt);
	adjwgt_len          = (*env)->GetArrayLength(env,j_adjwgt);
	options_len         = (*env)->GetArrayLength(env,j_options);
	partioned_nodes_len = (*env)->GetArrayLength(env,j_partioned_nodes);
	part_weights_len    = (*env)->GetArrayLength(env,j_part_weights);

	//create/get local copies
	xadj                      = (*env)->GetIntArrayElements(env,j_xadj,0);
	adjncy                    = (*env)->GetIntArrayElements(env,j_adjncy,0);
	part_weights              = (*env)->GetFloatArrayElements(env,j_part_weights,0);
	if(vwgt_len>0)    vwgt    = (*env)->GetIntArrayElements(env,j_vwgt,0);
	if(adjwgt_len>0)  adjwgt  = (*env)->GetIntArrayElements(env,j_adjwgt,0);
	if(options_len>0) options = (*env)->GetIntArrayElements(env,j_options,0);
	partioned_nodes           = (int*)malloc(sizeof(int)*partioned_nodes_len);

	//call func
	if((j_nparts<8 || j_force_PartGraphRecursive) && !j_force_PartGraphKway) {
		METIS_WPartGraphRecursive(
				&num_vertices,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				part_weights,
				options,
				&edges_cut,
				partioned_nodes);
	}
	else {
		METIS_WPartGraphKway(
				&num_vertices,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				part_weights,
				options,
				&edges_cut,
				partioned_nodes);
	}

	//pop partioned_nodes
	(*env)->SetIntArrayRegion(env,j_partioned_nodes,0,partioned_nodes_len,partioned_nodes);

	//free local copies
	free(partioned_nodes);
	(*env)->ReleaseIntArrayElements(env, j_xadj, xadj, 0);
	(*env)->ReleaseIntArrayElements(env, j_adjncy, adjncy, 0);
	if(vwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_vwgt, vwgt, 0);
	if(adjwgt_len>0) (*env)->ReleaseIntArrayElements(env, j_adjwgt, adjwgt, 0);
	if(options_len>0) (*env)->ReleaseIntArrayElements(env, j_options, options, 0);
	return edges_cut;
}