Path: blob/devel/elmergrid/src/metis-5.1.0/libmetis/options.c
3206 views
/**1\file2\brief This file contains various routines for dealing with options and ctrl_t.34\date Started 5/12/20115\author George6\author Copyright 1997-2011, Regents of the University of Minnesota7\version\verbatim $Id: options.c 13901 2013-03-24 16:17:03Z karypis $ \endverbatim8*/910#include "metislib.h"111213/*************************************************************************/14/*! This function creates and sets the run parameters (ctrl_t) */15/*************************************************************************/16ctrl_t *SetupCtrl(moptype_et optype, idx_t *options, idx_t ncon, idx_t nparts,17real_t *tpwgts, real_t *ubvec)18{19idx_t i, j;20ctrl_t *ctrl;2122ctrl = (ctrl_t *)gk_malloc(sizeof(ctrl_t), "SetupCtrl: ctrl");2324memset((void *)ctrl, 0, sizeof(ctrl_t));2526switch (optype) {27case METIS_OP_PMETIS:28ctrl->objtype = GETOPTION(options, METIS_OPTION_OBJTYPE, METIS_OBJTYPE_CUT);29ctrl->rtype = METIS_RTYPE_FM;30ctrl->ncuts = GETOPTION(options, METIS_OPTION_NCUTS, 1);31ctrl->niter = GETOPTION(options, METIS_OPTION_NITER, 10);3233if (ncon == 1) {34ctrl->iptype = GETOPTION(options, METIS_OPTION_IPTYPE, METIS_IPTYPE_GROW);35ctrl->ufactor = GETOPTION(options, METIS_OPTION_UFACTOR, PMETIS_DEFAULT_UFACTOR);36ctrl->CoarsenTo = 20;37}38else {39ctrl->iptype = GETOPTION(options, METIS_OPTION_IPTYPE, METIS_IPTYPE_RANDOM);40ctrl->ufactor = GETOPTION(options, METIS_OPTION_UFACTOR, MCPMETIS_DEFAULT_UFACTOR);41ctrl->CoarsenTo = 100;42}4344break;454647case METIS_OP_KMETIS:48ctrl->objtype = GETOPTION(options, METIS_OPTION_OBJTYPE, METIS_OBJTYPE_CUT);49ctrl->iptype = METIS_IPTYPE_METISRB;50ctrl->rtype = METIS_RTYPE_GREEDY;51ctrl->ncuts = GETOPTION(options, METIS_OPTION_NCUTS, 1);52ctrl->niter = GETOPTION(options, METIS_OPTION_NITER, 10);53ctrl->ufactor = GETOPTION(options, METIS_OPTION_UFACTOR, KMETIS_DEFAULT_UFACTOR);54ctrl->minconn = GETOPTION(options, METIS_OPTION_MINCONN, 0);55ctrl->contig = GETOPTION(options, METIS_OPTION_CONTIG, 0);56break;575859case METIS_OP_OMETIS:60ctrl->objtype = GETOPTION(options, METIS_OPTION_OBJTYPE, METIS_OBJTYPE_NODE);61ctrl->rtype = GETOPTION(options, METIS_OPTION_RTYPE, METIS_RTYPE_SEP1SIDED);62ctrl->iptype = GETOPTION(options, METIS_OPTION_IPTYPE, METIS_IPTYPE_EDGE);63ctrl->nseps = GETOPTION(options, METIS_OPTION_NSEPS, 1);64ctrl->niter = GETOPTION(options, METIS_OPTION_NITER, 10);65ctrl->ufactor = GETOPTION(options, METIS_OPTION_UFACTOR, OMETIS_DEFAULT_UFACTOR);66ctrl->compress = GETOPTION(options, METIS_OPTION_COMPRESS, 1);67ctrl->ccorder = GETOPTION(options, METIS_OPTION_CCORDER, 0);68ctrl->pfactor = 0.1*GETOPTION(options, METIS_OPTION_PFACTOR, 0);6970ctrl->CoarsenTo = 100;71break;7273default:74gk_errexit(SIGERR, "Unknown optype of %d\n", optype);75}7677/* common options */78ctrl->ctype = GETOPTION(options, METIS_OPTION_CTYPE, METIS_CTYPE_SHEM);79ctrl->no2hop = GETOPTION(options, METIS_OPTION_NO2HOP, 0);80ctrl->seed = GETOPTION(options, METIS_OPTION_SEED, -1);81ctrl->dbglvl = GETOPTION(options, METIS_OPTION_DBGLVL, 0);82ctrl->numflag = GETOPTION(options, METIS_OPTION_NUMBERING, 0);8384/* set non-option information */85ctrl->optype = optype;86ctrl->ncon = ncon;87ctrl->nparts = nparts;88ctrl->maxvwgt = ismalloc(ncon, 0, "SetupCtrl: maxvwgt");8990/* setup the target partition weights */91if (ctrl->optype != METIS_OP_OMETIS) {92ctrl->tpwgts = rmalloc(nparts*ncon, "SetupCtrl: ctrl->tpwgts");93if (tpwgts) {94rcopy(nparts*ncon, tpwgts, ctrl->tpwgts);95}96else {97for (i=0; i<nparts; i++) {98for (j=0; j<ncon; j++)99ctrl->tpwgts[i*ncon+j] = 1.0/nparts;100}101}102}103else { /* METIS_OP_OMETIS */104/* this is required to allow the pijbm to be defined properly for105the edge-based refinement during initial partitioning */106ctrl->tpwgts = rsmalloc(2, .5, "SetupCtrl: ctrl->tpwgts");107}108109110/* setup the ubfactors */111ctrl->ubfactors = rsmalloc(ctrl->ncon, I2RUBFACTOR(ctrl->ufactor), "SetupCtrl: ubfactors");112if (ubvec)113rcopy(ctrl->ncon, ubvec, ctrl->ubfactors);114for (i=0; i<ctrl->ncon; i++)115ctrl->ubfactors[i] += 0.0000499;116117/* Allocate memory for balance multipliers.118Note that for PMETIS/OMETIS routines the memory allocated is more119than required as balance multipliers for 2 parts is sufficient. */120ctrl->pijbm = rmalloc(nparts*ncon, "SetupCtrl: ctrl->pijbm");121122InitRandom(ctrl->seed);123124IFSET(ctrl->dbglvl, METIS_DBG_INFO, PrintCtrl(ctrl));125126if (!CheckParams(ctrl)) {127FreeCtrl(&ctrl);128return NULL;129}130else {131return ctrl;132}133}134135136/*************************************************************************/137/*! Computes the per-partition/constraint balance multipliers */138/*************************************************************************/139void SetupKWayBalMultipliers(ctrl_t *ctrl, graph_t *graph)140{141idx_t i, j;142143for (i=0; i<ctrl->nparts; i++) {144for (j=0; j<graph->ncon; j++)145ctrl->pijbm[i*graph->ncon+j] = graph->invtvwgt[j]/ctrl->tpwgts[i*graph->ncon+j];146}147}148149150/*************************************************************************/151/*! Computes the per-partition/constraint balance multipliers */152/*************************************************************************/153void Setup2WayBalMultipliers(ctrl_t *ctrl, graph_t *graph, real_t *tpwgts)154{155idx_t i, j;156157for (i=0; i<2; i++) {158for (j=0; j<graph->ncon; j++)159ctrl->pijbm[i*graph->ncon+j] = graph->invtvwgt[j]/tpwgts[i*graph->ncon+j];160}161}162163164/*************************************************************************/165/*! This function prints the various control fields */166/*************************************************************************/167void PrintCtrl(ctrl_t *ctrl)168{169idx_t i, j, modnum;170171printf(" Runtime parameters:\n");172173printf(" Objective type: ");174switch (ctrl->objtype) {175case METIS_OBJTYPE_CUT:176printf("METIS_OBJTYPE_CUT\n");177break;178case METIS_OBJTYPE_VOL:179printf("METIS_OBJTYPE_VOL\n");180break;181case METIS_OBJTYPE_NODE:182printf("METIS_OBJTYPE_NODE\n");183break;184default:185printf("Unknown!\n");186}187188printf(" Coarsening type: ");189switch (ctrl->ctype) {190case METIS_CTYPE_RM:191printf("METIS_CTYPE_RM\n");192break;193case METIS_CTYPE_SHEM:194printf("METIS_CTYPE_SHEM\n");195break;196default:197printf("Unknown!\n");198}199200printf(" Initial partitioning type: ");201switch (ctrl->iptype) {202case METIS_IPTYPE_GROW:203printf("METIS_IPTYPE_GROW\n");204break;205case METIS_IPTYPE_RANDOM:206printf("METIS_IPTYPE_RANDOM\n");207break;208case METIS_IPTYPE_EDGE:209printf("METIS_IPTYPE_EDGE\n");210break;211case METIS_IPTYPE_NODE:212printf("METIS_IPTYPE_NODE\n");213break;214case METIS_IPTYPE_METISRB:215printf("METIS_IPTYPE_METISRB\n");216break;217default:218printf("Unknown!\n");219}220221printf(" Refinement type: ");222switch (ctrl->rtype) {223case METIS_RTYPE_FM:224printf("METIS_RTYPE_FM\n");225break;226case METIS_RTYPE_GREEDY:227printf("METIS_RTYPE_GREEDY\n");228break;229case METIS_RTYPE_SEP2SIDED:230printf("METIS_RTYPE_SEP2SIDED\n");231break;232case METIS_RTYPE_SEP1SIDED:233printf("METIS_RTYPE_SEP1SIDED\n");234break;235default:236printf("Unknown!\n");237}238239printf(" Perform a 2-hop matching: %s\n", (ctrl->no2hop ? "Yes" : "No"));240241printf(" Number of balancing constraints: %"PRIDX"\n", ctrl->ncon);242printf(" Number of refinement iterations: %"PRIDX"\n", ctrl->niter);243printf(" Random number seed: %"PRIDX"\n", ctrl->seed);244245if (ctrl->optype == METIS_OP_OMETIS) {246printf(" Number of separators: %"PRIDX"\n", ctrl->nseps);247printf(" Compress graph prior to ordering: %s\n", (ctrl->compress ? "Yes" : "No"));248printf(" Detect & order connected components separately: %s\n", (ctrl->ccorder ? "Yes" : "No"));249printf(" Prunning factor for high degree vertices: %"PRREAL"\n", ctrl->pfactor);250}251else {252printf(" Number of partitions: %"PRIDX"\n", ctrl->nparts);253printf(" Number of cuts: %"PRIDX"\n", ctrl->ncuts);254printf(" User-supplied ufactor: %"PRIDX"\n", ctrl->ufactor);255256if (ctrl->optype == METIS_OP_KMETIS) {257printf(" Minimize connectivity: %s\n", (ctrl->minconn ? "Yes" : "No"));258printf(" Create contigous partitions: %s\n", (ctrl->contig ? "Yes" : "No"));259}260261modnum = (ctrl->ncon==1 ? 5 : (ctrl->ncon==2 ? 3 : (ctrl->ncon==3 ? 2 : 1)));262printf(" Target partition weights: ");263for (i=0; i<ctrl->nparts; i++) {264if (i%modnum == 0)265printf("\n ");266printf("%4"PRIDX"=[", i);267for (j=0; j<ctrl->ncon; j++)268printf("%s%.2e", (j==0 ? "" : " "), (double)ctrl->tpwgts[i*ctrl->ncon+j]);269printf("]");270}271printf("\n");272}273274printf(" Allowed maximum load imbalance: ");275for (i=0; i<ctrl->ncon; i++)276printf("%.3"PRREAL" ", ctrl->ubfactors[i]);277printf("\n");278279printf("\n");280}281282283/*************************************************************************/284/*! This function checks the validity of user-supplied parameters */285/*************************************************************************/286int CheckParams(ctrl_t *ctrl)287{288idx_t i, j;289real_t sum;290mdbglvl_et dbglvl=METIS_DBG_INFO;291292switch (ctrl->optype) {293case METIS_OP_PMETIS:294if (ctrl->objtype != METIS_OBJTYPE_CUT) {295IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect objective type.\n"));296return 0;297}298if (ctrl->ctype != METIS_CTYPE_RM && ctrl->ctype != METIS_CTYPE_SHEM) {299IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect coarsening scheme.\n"));300return 0;301}302if (ctrl->iptype != METIS_IPTYPE_GROW && ctrl->iptype != METIS_IPTYPE_RANDOM) {303IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect initial partitioning scheme.\n"));304return 0;305}306if (ctrl->rtype != METIS_RTYPE_FM) {307IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect refinement scheme.\n"));308return 0;309}310if (ctrl->ncuts <= 0) {311IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ncuts.\n"));312return 0;313}314if (ctrl->niter <= 0) {315IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect niter.\n"));316return 0;317}318if (ctrl->ufactor <= 0) {319IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ufactor.\n"));320return 0;321}322if (ctrl->numflag != 0 && ctrl->numflag != 1) {323IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect numflag.\n"));324return 0;325}326if (ctrl->nparts <= 0) {327IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect nparts.\n"));328return 0;329}330if (ctrl->ncon <= 0) {331IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ncon.\n"));332return 0;333}334335for (i=0; i<ctrl->ncon; i++) {336sum = rsum(ctrl->nparts, ctrl->tpwgts+i, ctrl->ncon);337if (sum < 0.99 || sum > 1.01) {338IFSET(dbglvl, METIS_DBG_INFO,339printf("Input Error: Incorrect sum of %"PRREAL" for tpwgts for constraint %"PRIDX".\n", sum, i));340return 0;341}342}343for (i=0; i<ctrl->ncon; i++) {344for (j=0; j<ctrl->nparts; j++) {345if (ctrl->tpwgts[j*ctrl->ncon+i] <= 0.0) {346IFSET(dbglvl, METIS_DBG_INFO,347printf("Input Error: Incorrect tpwgts for partition %"PRIDX" and constraint %"PRIDX".\n", j, i));348return 0;349}350}351}352353for (i=0; i<ctrl->ncon; i++) {354if (ctrl->ubfactors[i] <= 1.0) {355IFSET(dbglvl, METIS_DBG_INFO,356printf("Input Error: Incorrect ubfactor for constraint %"PRIDX".\n", i));357return 0;358}359}360361break;362363case METIS_OP_KMETIS:364if (ctrl->objtype != METIS_OBJTYPE_CUT && ctrl->objtype != METIS_OBJTYPE_VOL) {365IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect objective type.\n"));366return 0;367}368if (ctrl->ctype != METIS_CTYPE_RM && ctrl->ctype != METIS_CTYPE_SHEM) {369IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect coarsening scheme.\n"));370return 0;371}372if (ctrl->iptype != METIS_IPTYPE_METISRB) {373IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect initial partitioning scheme.\n"));374return 0;375}376if (ctrl->rtype != METIS_RTYPE_GREEDY) {377IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect refinement scheme.\n"));378return 0;379}380if (ctrl->ncuts <= 0) {381IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ncuts.\n"));382return 0;383}384if (ctrl->niter <= 0) {385IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect niter.\n"));386return 0;387}388if (ctrl->ufactor <= 0) {389IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ufactor.\n"));390return 0;391}392if (ctrl->numflag != 0 && ctrl->numflag != 1) {393IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect numflag.\n"));394return 0;395}396if (ctrl->nparts <= 0) {397IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect nparts.\n"));398return 0;399}400if (ctrl->ncon <= 0) {401IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ncon.\n"));402return 0;403}404if (ctrl->contig != 0 && ctrl->contig != 1) {405IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect contig.\n"));406return 0;407}408if (ctrl->minconn != 0 && ctrl->minconn != 1) {409IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect minconn.\n"));410return 0;411}412413for (i=0; i<ctrl->ncon; i++) {414sum = rsum(ctrl->nparts, ctrl->tpwgts+i, ctrl->ncon);415if (sum < 0.99 || sum > 1.01) {416IFSET(dbglvl, METIS_DBG_INFO,417printf("Input Error: Incorrect sum of %"PRREAL" for tpwgts for constraint %"PRIDX".\n", sum, i));418return 0;419}420}421for (i=0; i<ctrl->ncon; i++) {422for (j=0; j<ctrl->nparts; j++) {423if (ctrl->tpwgts[j*ctrl->ncon+i] <= 0.0) {424IFSET(dbglvl, METIS_DBG_INFO,425printf("Input Error: Incorrect tpwgts for partition %"PRIDX" and constraint %"PRIDX".\n", j, i));426return 0;427}428}429}430431for (i=0; i<ctrl->ncon; i++) {432if (ctrl->ubfactors[i] <= 1.0) {433IFSET(dbglvl, METIS_DBG_INFO,434printf("Input Error: Incorrect ubfactor for constraint %"PRIDX".\n", i));435return 0;436}437}438439break;440441442443case METIS_OP_OMETIS:444if (ctrl->objtype != METIS_OBJTYPE_NODE) {445IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect objective type.\n"));446return 0;447}448if (ctrl->ctype != METIS_CTYPE_RM && ctrl->ctype != METIS_CTYPE_SHEM) {449IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect coarsening scheme.\n"));450return 0;451}452if (ctrl->iptype != METIS_IPTYPE_EDGE && ctrl->iptype != METIS_IPTYPE_NODE) {453IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect initial partitioning scheme.\n"));454return 0;455}456if (ctrl->rtype != METIS_RTYPE_SEP1SIDED && ctrl->rtype != METIS_RTYPE_SEP2SIDED) {457IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect refinement scheme.\n"));458return 0;459}460if (ctrl->nseps <= 0) {461IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect nseps.\n"));462return 0;463}464if (ctrl->niter <= 0) {465IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect niter.\n"));466return 0;467}468if (ctrl->ufactor <= 0) {469IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ufactor.\n"));470return 0;471}472if (ctrl->numflag != 0 && ctrl->numflag != 1) {473IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect numflag.\n"));474return 0;475}476if (ctrl->nparts != 3) {477IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect nparts.\n"));478return 0;479}480if (ctrl->ncon != 1) {481IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ncon.\n"));482return 0;483}484if (ctrl->compress != 0 && ctrl->compress != 1) {485IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect compress.\n"));486return 0;487}488if (ctrl->ccorder != 0 && ctrl->ccorder != 1) {489IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect ccorder.\n"));490return 0;491}492if (ctrl->pfactor < 0.0 ) {493IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect pfactor.\n"));494return 0;495}496497for (i=0; i<ctrl->ncon; i++) {498if (ctrl->ubfactors[i] <= 1.0) {499IFSET(dbglvl, METIS_DBG_INFO,500printf("Input Error: Incorrect ubfactor for constraint %"PRIDX".\n", i));501return 0;502}503}504505break;506507default:508IFSET(dbglvl, METIS_DBG_INFO, printf("Input Error: Incorrect optype\n"));509return 0;510}511512return 1;513}514515516/*************************************************************************/517/*! This function frees the memory associated with a ctrl_t */518/*************************************************************************/519void FreeCtrl(ctrl_t **r_ctrl)520{521ctrl_t *ctrl = *r_ctrl;522523FreeWorkSpace(ctrl);524525gk_free((void **)&ctrl->tpwgts, &ctrl->pijbm,526&ctrl->ubfactors, &ctrl->maxvwgt, &ctrl, LTERM);527528*r_ctrl = NULL;529}530531532533534