00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <metis.h>
00017
00018
00019
00020
00021
00022
00023 void METIS_mCPartGraphKway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy,
00024 idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag,
00025 int *nparts, floattype *rubvec, int *options, int *edgecut,
00026 idxtype *part)
00027 {
00028 int i, j;
00029 GraphType graph;
00030 CtrlType ctrl;
00031
00032 if (*numflag == 1)
00033 Change2CNumbering(*nvtxs, xadj, adjncy);
00034
00035 SetUpGraph(&graph, OP_KMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag);
00036
00037 if (options[0] == 0) {
00038 ctrl.CType = McKMETIS_CTYPE;
00039 ctrl.IType = McKMETIS_ITYPE;
00040 ctrl.RType = McKMETIS_RTYPE;
00041 ctrl.dbglvl = McKMETIS_DBGLVL;
00042 }
00043 else {
00044 ctrl.CType = options[OPTION_CTYPE];
00045 ctrl.IType = options[OPTION_ITYPE];
00046 ctrl.RType = options[OPTION_RTYPE];
00047 ctrl.dbglvl = options[OPTION_DBGLVL];
00048 }
00049 ctrl.optype = OP_KMETIS;
00050 ctrl.CoarsenTo = amax((*nvtxs)/(20*log2Int(*nparts)), 30*(*nparts));
00051
00052 ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo);
00053
00054 InitRandom(-1);
00055
00056 AllocateWorkSpace(&ctrl, &graph, *nparts);
00057
00058 IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl));
00059 IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr));
00060
00061 ASSERT(CheckGraph(&graph));
00062 *edgecut = MCMlevelKWayPartitioning(&ctrl, &graph, *nparts, part, rubvec);
00063
00064 IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr));
00065 IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl));
00066
00067 FreeWorkSpace(&ctrl, &graph);
00068
00069 if (*numflag == 1)
00070 Change2FNumbering(*nvtxs, xadj, adjncy, part);
00071 }
00072
00073
00074
00075
00076
00077 int MCMlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part,
00078 floattype *rubvec)
00079 {
00080 int i, j, nvtxs;
00081 GraphType *cgraph;
00082 int options[10], edgecut;
00083
00084 cgraph = MCCoarsen2Way(ctrl, graph);
00085
00086 IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr));
00087 MocAllocateKWayPartitionMemory(ctrl, cgraph, nparts);
00088
00089 options[0] = 1;
00090 options[OPTION_CTYPE] = MATCH_SBHEM_INFNORM;
00091 options[OPTION_ITYPE] = IPART_RANDOM;
00092 options[OPTION_RTYPE] = RTYPE_FM;
00093 options[OPTION_DBGLVL] = 0;
00094
00095
00096 for (i=0; i<graph->ncon; i++) {
00097 if (rubvec[i] > 1.2)
00098 break;
00099 }
00100 if (i == graph->ncon)
00101 METIS_mCPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon,
00102 cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts,
00103 options, &edgecut, cgraph->where);
00104 else
00105 METIS_mCHPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon,
00106 cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts,
00107 rubvec, options, &edgecut, cgraph->where);
00108
00109
00110 IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr));
00111 IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut));
00112
00113 IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where));
00114
00115 MocRefineKWayHorizontal(ctrl, graph, cgraph, nparts, rubvec);
00116
00117 idxcopy(graph->nvtxs, graph->where, part);
00118
00119 GKfree(&graph->nvwgt, &graph->gdata, &graph->rdata, LTERM);
00120
00121 return graph->mincut;
00122
00123 }
00124