Beispiel #1
0
void metis_mcpartgraphkway__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
{
  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
}
Beispiel #2
0
void METIS_MCPARTGRAPHKWAY(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part)
{
  METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part);
}
Beispiel #3
0
/*************************************************************************
* This function is the entry point for KMETIS
**************************************************************************/
void *METIS_PartGraphForContact(idxtype *nvtxs, idxtype *xadj, idxtype *adjncy, 
                double *xyzcoords, idxtype *sflag, idxtype *numflag, idxtype *nparts, 
                idxtype *options, idxtype *edgecut, idxtype *part) 
{
  idxtype i, j, ii, dim, ncon, wgtflag, mcnumflag, nnodes, nlnodes, nclean, naclean, ndirty, maxdepth, rwgtflag, rnumflag;
  idxtype *mcvwgt, *dtpart, *marker, *leafpart;
  idxtype *adjwgt;
  float rubvec[2], lbvec[2];
  GraphType graph, *cgraph;
  ContactInfoType *cinfo;
  DKeyValueType *xyzcand[3];

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

  /*---------------------------------------------------------------------
   * Allocate memory for the contact info type
   *---------------------------------------------------------------------*/
  cinfo = (ContactInfoType *)gk_malloc(sizeof(ContactInfoType), "METIS_PartGraphForContact: cinfo");
  cinfo->leafptr  = idxsmalloc(*nvtxs+1, 0, "METIS_PartGraphForContact: leafptr");
  cinfo->leafind  = idxsmalloc(*nvtxs, 0, "METIS_PartGraphForContact: leafind");
  cinfo->leafwgt  = idxsmalloc(*nvtxs, 0, "METIS_PartGraphForContact: leafwgt");
  cinfo->part     = idxsmalloc(*nvtxs, 0, "METIS_PartGraphForContact: part");
  leafpart = cinfo->leafpart = idxmalloc(*nvtxs, "METIS_PartGraphForContact: leafpart");
  cinfo->dtree    = (DTreeNodeType *)gk_malloc(sizeof(DTreeNodeType)*(*nvtxs), "METIS_PartGraphForContact: cinfo->dtree");
  cinfo->nvtxs    = *nvtxs;

  /*---------------------------------------------------------------------
   * Compute the initial k-way partitioning 
   *---------------------------------------------------------------------*/
  mcvwgt = idxsmalloc(2*(*nvtxs), 0, "METIS_PartGraphForContact: mcvwgt");
  for (i=0; i<*nvtxs; i++) {
    mcvwgt[2*i+0] = 1;
    mcvwgt[2*i+1] = (sflag[i] == 0 ? 0 : 1);
  }

  adjwgt = idxmalloc(xadj[*nvtxs], "METIS_PartGraphForContact: adjwgt");
  for (i=0; i<*nvtxs; i++) {
    for (j=xadj[i]; j<xadj[i+1]; j++) 
      adjwgt[j] = (sflag[i] && sflag[adjncy[j]] ? 5 : 1);
  }

  rubvec[0] = 1.03;
  rubvec[1] = 1.05;
  ncon = 2;
  mcnumflag = 0;
  wgtflag   = 1;

  METIS_mCPartGraphKway(nvtxs, &ncon, xadj, adjncy, mcvwgt, adjwgt, &wgtflag, &mcnumflag,
                        nparts, rubvec, options, edgecut, part);

  /* The following is just for stat reporting purposes */
  SetUpGraph(&graph, OP_KMETIS, *nvtxs, 2, xadj, adjncy, mcvwgt, NULL, 0);
  graph.vwgt = mcvwgt;
  ComputePartitionBalance(&graph, *nparts, part, lbvec);
  mprintf("  %D-way Edge-Cut: %7D, Balance: %5.2f %5.2f\n", *nparts, ComputeCut(&graph, part), lbvec[0], lbvec[1]);


  /*---------------------------------------------------------------------
   * Induce the decission tree
   *---------------------------------------------------------------------*/
  dtpart = idxmalloc(*nvtxs, "METIS_PartGraphForContact: dtpart");
  marker = idxsmalloc(*nvtxs, 0, "METIS_PartGraphForContact: marker");

  for (dim=0; dim<3; dim++) {
    xyzcand[dim] = (DKeyValueType *)gk_malloc(sizeof(DKeyValueType)*(*nvtxs), "METIS_PartGraphForContact: xyzcand[dim]");
    for (i=0; i<*nvtxs; i++) {
      xyzcand[dim][i].key = xyzcoords[3*i+dim];
      xyzcand[dim][i].val = i;
    }
    idkeysort(*nvtxs, xyzcand[dim]);
  }


  nnodes = nlnodes = nclean = naclean = ndirty = maxdepth = 0;
  InduceDecissionTree(*nvtxs, xyzcand, sflag, *nparts, part,
                      *nvtxs/(20*(*nparts)), *nvtxs/(20*(*nparts)*(*nparts)), 0.90,
                      &nnodes, &nlnodes, cinfo->dtree, leafpart, dtpart,
                      &nclean, &naclean, &ndirty, &maxdepth, marker);

  mprintf("NNodes: %5D, NLNodes: %5D, NClean: %5D, NAClean: %5D, NDirty: %5D, MaxDepth: %3D\n", nnodes, nlnodes, nclean, naclean, ndirty, maxdepth);


  /*---------------------------------------------------------------------
   * Create the tree-induced coarse graph and refine it
   *---------------------------------------------------------------------*/
  cgraph = CreatePartitionGraphForContact(*nvtxs, xadj, adjncy, mcvwgt, adjwgt, nlnodes, leafpart);

  for (i=0; i<*nvtxs; i++)
    part[leafpart[i]] = dtpart[i];

  ComputePartitionBalance(cgraph, *nparts, part, lbvec);
  mprintf("  %D-way Edge-Cut: %7D, Balance: %5.2f %5.2f\n", *nparts, ComputeCut(cgraph, part), lbvec[0], lbvec[1]);


  rwgtflag = 3;
  rnumflag = 0;
  METIS_mCRefineGraphKway(&(cgraph->nvtxs), &ncon, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, 
                          cgraph->adjwgt, &rwgtflag, &rnumflag, nparts, rubvec, options, edgecut, 
                          part);

  ComputePartitionBalance(cgraph, *nparts, part, lbvec);
  mprintf("  %D-way Edge-Cut: %7D, Balance: %5.2f %5.2f\n", *nparts, ComputeCut(cgraph, part), lbvec[0], lbvec[1]);


  /*---------------------------------------------------------------------
   * Use that to compute the partition of the original graph
   *---------------------------------------------------------------------*/
  idxcopy(cgraph->nvtxs, part, dtpart);
  for (i=0; i<*nvtxs; i++)
    part[i] = dtpart[leafpart[i]];

  ComputePartitionBalance(&graph, *nparts, part, lbvec);
  idxset(*nvtxs, 1, graph.vwgt);
  mprintf("  %D-way Edge-Cut: %7D, Volume: %7D, Balance: %5.2f %5.2f\n", *nparts, 
           ComputeCut(&graph, part), ComputeVolume(&graph, part), lbvec[0], lbvec[1]);


  /*---------------------------------------------------------------------
   * Induce the final decission tree
   *---------------------------------------------------------------------*/
  nnodes = nlnodes = nclean = naclean = ndirty = maxdepth = 0;
  InduceDecissionTree(*nvtxs, xyzcand, sflag, *nparts, part,
                      *nvtxs/((40)*(*nparts)), 1, 1.00,
                      &nnodes, &nlnodes, cinfo->dtree, leafpart, dtpart, 
                      &nclean, &naclean, &ndirty, &maxdepth, marker);

  mprintf("NNodes: %5D, NLNodes: %5D, NClean: %5D, NAClean: %5D, NDirty: %5D, MaxDepth: %3D\n", nnodes, nlnodes, nclean, naclean, ndirty, maxdepth);

  
  /*---------------------------------------------------------------------
   * Populate the remaining fields of the cinfo data structure
   *---------------------------------------------------------------------*/
  cinfo->nnodes = nnodes;
  cinfo->nleafs = nlnodes;
  idxcopy(*nvtxs, part, cinfo->part);

  BuildDTLeafContents(cinfo, sflag);

  CheckDTree(*nvtxs, xyzcoords, part, cinfo);

  gk_free((void **)&mcvwgt, &dtpart, &xyzcand[0], &xyzcand[1], &xyzcand[2], &marker, &adjwgt, LTERM);

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

  return (void *)cinfo;
}
Beispiel #4
0
/*************************************************************************
* Let the game begin
**************************************************************************/
main(int argc, char *argv[])
{
  int i, nparts, options[10];
  idxtype *part;
  float rubvec[MAXNCON], lbvec[MAXNCON];
  GraphType graph;
  char filename[256];
  int numflag = 0, wgtflag = 0, edgecut;
  timer TOTALTmr, METISTmr, IOTmr;

  if (argc != 3) {
    printf("Usage: %s <GraphFile> <Nparts>\n",argv[0]);
    exit(0);
  }
    
  strcpy(filename, argv[1]);
  nparts = atoi(argv[2]);

  if (nparts < 2) {
    printf("The number of partitions should be greater than 1!\n");
    exit(0);
  }

  cleartimer(TOTALTmr);
  cleartimer(METISTmr);
  cleartimer(IOTmr);

  starttimer(TOTALTmr);
  starttimer(IOTmr);
  ReadGraph(&graph, filename, &wgtflag);
  if (graph.nvtxs <= 0) {
    printf("Empty graph. Nothing to do.\n");
    exit(0);
  }
  stoptimer(IOTmr);

  printf("**********************************************************************\n");
  printf("%s", METISTITLE);
  printf("Graph Information ---------------------------------------------------\n");
  printf("  Name: %s, #Vertices: %d, #Edges: %d, #Parts: %d\n", filename, graph.nvtxs, graph.nedges/2, nparts);
  if (graph.ncon > 1)
    printf("  Balancing Constraints: %d\n", graph.ncon);
  printf("\nK-way Partitioning... -----------------------------------------------\n");

  part = idxmalloc(graph.nvtxs, "main: part");
  options[0] = 0;

  starttimer(METISTmr);
  if (graph.ncon == 1) {
    METIS_PartGraphKway(&graph.nvtxs, graph.xadj, graph.adjncy, graph.vwgt, graph.adjwgt, 
          &wgtflag, &numflag, &nparts, options, &edgecut, part);
  }
  else {
    for (i=0; i<graph.ncon; i++)
      rubvec[i] = HORIZONTAL_IMBALANCE;

    METIS_mCPartGraphKway(&graph.nvtxs, &graph.ncon, graph.xadj, graph.adjncy, graph.vwgt, 
          graph.adjwgt, &wgtflag, &numflag, &nparts, rubvec, options, &edgecut, part);
  }
  stoptimer(METISTmr);

  ComputePartitionBalance(&graph, nparts, part, lbvec);

  printf("  %d-way Edge-Cut: %7d, Balance: ", nparts, edgecut);
  for (i=0; i<graph.ncon; i++)
    printf("%5.2f ", lbvec[i]);
  printf("\n");

  starttimer(IOTmr);
  WritePartition(filename, part, graph.nvtxs, nparts); 
  stoptimer(IOTmr);
  stoptimer(TOTALTmr);

  printf("\nTiming Information --------------------------------------------------\n");
  printf("  I/O:          \t\t %7.3f\n", gettimer(IOTmr));
  printf("  Partitioning: \t\t %7.3f   (KMETIS time)\n", gettimer(METISTmr));
  printf("  Total:        \t\t %7.3f\n", gettimer(TOTALTmr));
  printf("**********************************************************************\n");


  GKfree(&graph.xadj, &graph.adjncy, &graph.vwgt, &graph.adjwgt, &part, LTERM);
}  
Beispiel #5
0
JNIEXPORT jint JNICALL Java_jprime_JMetis_mcPartitionGraph(
		JNIEnv * env,
		jobject obj,
		jboolean j_force_PartGraphRecursive,
		jboolean j_force_PartGraphKway,
		jint j_num_vertices,
		jint j_num_constraints,
		jintArray j_xadj,
		jintArray j_adjncy,
		jintArray j_vwgt,
		jintArray j_adjwgt,
		jint j_wgtflag,
		jint j_nparts,
		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;
	int idx, edges_cut=-1, num_vertices=0, num_constraints, nparts=0, wgtflag=0, numflag=0;
	float* ubvec=0;
	jsize xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len;

	//copy the jsize vars
	num_vertices=j_num_vertices;
	num_constraints=j_num_constraints;
	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);

	//create/get local copies
	xadj                      = (*env)->GetIntArrayElements(env,j_xadj,0);
	adjncy                    = (*env)->GetIntArrayElements(env,j_adjncy,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) {
		//printf("[0]nparts=%i, num_vertices=%i, num_constraints=%i, wgtflag=%i, xadj_len=%i, adjncy_len=%i, vwgt_len=%i, adjwgt_len=%i, options_len=%i, partioned_nodes_len=%i\n",
		//		nparts, num_vertices, num_constraints, wgtflag, xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len);
		METIS_mCPartGraphRecursive(
				&num_vertices,
				&num_constraints,
				xadj,
				adjncy,
				vwgt,
				adjwgt,
				&wgtflag,
				&numflag,
				&nparts,
				options,
				&edges_cut,
				partioned_nodes);
	}
	else {
		//printf("[1]nparts=%i, num_vertices=%i, num_constraints=%i, wgtflag=%i, xadj_len=%i, adjncy_len=%i, vwgt_len=%i, adjwgt_len=%i, options_len=%i, partioned_nodes_len=%i\n",
		//		nparts, num_vertices, num_constraints, wgtflag, xadj_len, adjncy_len, vwgt_len, adjwgt_len, options_len, partioned_nodes_len);
		ubvec = (float*)malloc(sizeof(float)*num_constraints);
		for(idx=0;idx<num_constraints;idx++) {
			ubvec[idx]=1.1; //manual says should be larger than 1.03 so 1.1 seems reasonable
		}
		METIS_mCPartGraphKway(
				&num_vertices, //int *nvtxs,
				&num_constraints,//int *ncon,
				xadj,//idxtype *xadj,
				adjncy,//idxtype *adjncy,
				vwgt,//idxtype *vwgt,
				adjwgt,//idxtype *adjwgt,
				&wgtflag,//int *wgtflag,
				&numflag,//int *numflag,
				&nparts, //int *nparts,
				ubvec,//float *rubvec,
				options,//int *options,
				&edges_cut,//int *edgecut,
				partioned_nodes); //idxtype *part)
		free(ubvec);
	}

	//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;
}