1 /*!
2 \file cmdline_gpmetis.c
3 \brief Command-line argument parsing for gpmetis
4 
5 \date 12/24/2008
6 \author George
7 \version\verbatim $Id: cmdline_gpmetis.c 13901 2013-03-24 16:17:03Z karypis $\endverbatim
8 */
9 
10 #include "metisbin.h"
11 
12 
13 /*-------------------------------------------------------------------
14  * Command-line options
15  *-------------------------------------------------------------------*/
16 static struct gk_option long_options[] = {
17   {"ptype",          1,      0,      METIS_OPTION_PTYPE},
18   {"objtype",        1,      0,      METIS_OPTION_OBJTYPE},
19 
20   {"ctype",          1,      0,      METIS_OPTION_CTYPE},
21   {"iptype",         1,      0,      METIS_OPTION_IPTYPE},
22 /*  {"rtype",          1,      0,      METIS_OPTION_RTYPE}, */
23 
24 /*  {"balanced",       0,      0,      METIS_OPTION_BALANCE}, */
25 
26   {"no2hop",         0,      0,      METIS_OPTION_NO2HOP},
27   {"minconn",        0,      0,      METIS_OPTION_MINCONN},
28   {"contig",         0,      0,      METIS_OPTION_CONTIG},
29 
30   {"nooutput",       0,      0,      METIS_OPTION_NOOUTPUT},
31 
32   {"ufactor",        1,      0,      METIS_OPTION_UFACTOR},
33   {"niter",          1,      0,      METIS_OPTION_NITER},
34   {"ncuts",          1,      0,      METIS_OPTION_NCUTS},
35 
36   {"tpwgts",         1,      0,      METIS_OPTION_TPWGTS},
37   {"ubvec",          1,      0,      METIS_OPTION_UBVEC},
38 
39   {"seed",           1,      0,      METIS_OPTION_SEED},
40 
41   {"dbglvl",         1,      0,      METIS_OPTION_DBGLVL},
42 
43   {"help",           0,      0,      METIS_OPTION_HELP},
44   {0,                0,      0,      0}
45 };
46 
47 
48 
49 /*-------------------------------------------------------------------
50  * Mappings for the various parameter values
51  *-------------------------------------------------------------------*/
52 static gk_StringMap_t ptype_options[] = {
53  {"rb",                 METIS_PTYPE_RB},
54  {"kway",               METIS_PTYPE_KWAY},
55  {NULL,                 0}
56 };
57 
58 static gk_StringMap_t objtype_options[] = {
59  {"cut",                METIS_OBJTYPE_CUT},
60  {"vol",                METIS_OBJTYPE_VOL},
61  {NULL,                 0}
62 };
63 
64 static gk_StringMap_t ctype_options[] = {
65  {"rm",                 METIS_CTYPE_RM},
66  {"shem",               METIS_CTYPE_SHEM},
67  {NULL,                 0}
68 };
69 
70 static gk_StringMap_t iptype_options[] = {
71  {"grow",               METIS_IPTYPE_GROW},
72  {"random",             METIS_IPTYPE_RANDOM},
73  {NULL,                 0}
74 };
75 
76 static gk_StringMap_t rtype_options[] = {
77  {"fm",                METIS_RTYPE_FM},
78  {"greedy",            METIS_RTYPE_GREEDY},
79  {NULL,                 0}
80 };
81 
82 
83 
84 /*-------------------------------------------------------------------
85  * Mini help
86  *-------------------------------------------------------------------*/
87 static char helpstr[][100] =
88 {
89 " ",
90 "Usage: gpmetis [options] graphfile nparts",
91 " ",
92 " Required parameters",
93 "    graphfile   Stores the graph to be partitioned.",
94 "    nparts      The number of partitions to split the graph.",
95 " ",
96 " Optional parameters",
97 "  -ptype=string",
98 "     Specifies the scheme to be used for computing the k-way partitioning.",
99 "     The possible values are:",
100 "        rb       - Recursive bisectioning",
101 "        kway     - Direct k-way partitioning [default]",
102 " ",
103 "  -ctype=string",
104 "     Specifies the scheme to be used to match the vertices of the graph",
105 "     during the coarsening.",
106 "     The possible values are:",
107 "        rm       - Random matching",
108 "        shem     - Sorted heavy-edge matching [default]",
109 " ",
110 "  -iptype=string [applies only when -ptype=rb]",
111 "     Specifies the scheme to be used to compute the initial partitioning",
112 "     of the graph.",
113 "     The possible values are:",
114 "        grow     - Grow a bisection using a greedy scheme [default for ncon=1]",
115 "        random   - Compute a bisection at random [default for ncon>1]",
116 " ",
117 "  -objtype=string [applies only when -ptype=kway]",
118 "     Specifies the objective that the partitioning routines will optimize.",
119 "     The possible values are:",
120 "        cut      - Minimize the edgecut [default]",
121 "        vol      - Minimize the total communication volume",
122 " ",
123 /*
124 "  -rtype=string",
125 "     Specifies the scheme to be used for refinement.",
126 "     The possible values are:",
127 "        fm       - 2-way FM refinement [default for -ptype=rb]",
128 "        random   - Random k-way refinement",
129 "        greedy   - Greedy k-way refinement [default for -ptype=kway]",
130 " ",
131 */
132 "  -no2hop",
133 "     Specifies that the coarsening will not perform any 2-hop matchings",
134 "     when the standard matching fails to sufficiently contract the graph.",
135 " ",
136 "  -contig [applies only when -ptype=kway]",
137 "     Specifies that the partitioning routines should try to produce",
138 "     partitions that are contiguous. Note that if the input graph is not",
139 "     connected this option is ignored.",
140 " ",
141 "  -minconn [applies only when -ptype=kway]",
142 "     Specifies that the partitioning routines should try to minimize the",
143 "     maximum degree of the subdomain graph, i.e., the graph in which each",
144 "     partition is a node, and edges connect subdomains with a shared",
145 "     interface.",
146 " ",
147 "  -tpwgts=filename",
148 "     Specifies the name of the file that stores the target weights for",
149 "     each partition. By default, all partitions are assumed to be of ",
150 "     the same size.",
151 " ",
152 "  -ufactor=int",
153 "     Specifies the maximum allowed load imbalance among the partitions.",
154 "     A value of x indicates that the allowed load imbalance is 1+x/1000.",
155 "     For ptype=rb, the load imbalance is measured as the ratio of the ",
156 "     2*max(left,right)/(left+right), where left and right are the sizes",
157 "     of the respective partitions at each bisection. ",
158 "     For ptype=kway, the load imbalance is measured as the ratio of ",
159 "     max_i(pwgts[i])/avgpwgt, where pwgts[i] is the weight of the ith",
160 "     partition and avgpwgt is the sum of the total vertex weights divided",
161 "     by the number of partitions requested.",
162 "     For ptype=rb, the default value is 1 (i.e., load imbalance of 1.001).",
163 "     For ptype=kway, the default value is 30 (i.e., load imbalance of 1.03).",
164 " ",
165 "  -ubvec=string",
166 "     Applies only for multi-constraint partitioning and specifies the per",
167 "     constraint allowed load imbalance among partitions. The required ",
168 "     parameter corresponds to a space separated set of floating point",
169 "     numbers, one for each of the constraints. For example, for three",
170 "     constraints, the string can be \"1.02 1.2 1.35\" indicating a ",
171 "     desired maximum load imbalance of 2%, 20%, and 35%, respectively.",
172 "     The load imbalance is defined in a way similar to ufactor.",
173 "     If supplied, this parameter takes priority over ufactor.",
174 " ",
175 "  -niter=int",
176 "     Specifies the number of iterations for the refinement algorithms",
177 "     at each stage of the uncoarsening process. Default is 10.",
178 " ",
179 "  -ncuts=int",
180 "     Specifies the number of different partitionings that it will compute.",
181 "     The final partitioning is the one that achieves the best edgecut or",
182 "     communication volume. Default is 1.",
183 " ",
184 "  -nooutput",
185 "     Specifies that no partitioning file should be generated.",
186 " ",
187 /*
188 "  -balance",
189 "     Specifies that the final partitioning should contain nparts-1 equal",
190 "     size partitions with the last partition having upto nparts-1 fewer",
191 "     vertices.",
192 " ",
193 */
194 "  -seed=int",
195 "     Selects the seed of the random number generator.  ",
196 " ",
197 "  -dbglvl=int      ",
198 "     Selects the dbglvl.  ",
199 " ",
200 "  -help",
201 "     Prints this message.",
202 ""
203 };
204 
205 static char shorthelpstr[][100] = {
206 " ",
207 "   Usage: gpmetis [options] <filename> <nparts>",
208 "          use 'gpmetis -help' for a summary of the options.",
209 ""
210 };
211 
212 
213 
214 /*************************************************************************
215 * This is the entry point of the command-line argument parser
216 **************************************************************************/
parse_cmdline(int argc,char * argv[])217 params_t *parse_cmdline(int argc, char *argv[])
218 {
219   int i, j, k;
220   int c, option_index;
221   params_t *params;
222 
223   params = (params_t *)gk_malloc(sizeof(params_t), "parse_cmdline");
224   memset((void *)params, 0, sizeof(params_t));
225 
226   /* initialize the params data structure */
227   params->ptype         = METIS_PTYPE_KWAY;
228   params->objtype       = METIS_OBJTYPE_CUT;
229   params->ctype         = METIS_CTYPE_SHEM;
230   params->iptype        = -1;
231   params->rtype         = -1;
232 
233   params->no2hop        = 0;
234   params->minconn       = 0;
235   params->contig        = 0;
236 
237   params->nooutput      = 0;
238   params->wgtflag       = 3;
239 
240   params->ncuts         = 1;
241   params->niter         = 10;
242 
243   params->dbglvl        = 0;
244   params->balance       = 0;
245   params->seed          = -1;
246   params->dbglvl        = 0;
247 
248   params->tpwgtsfile    = NULL;
249 
250   params->filename      = NULL;
251   params->nparts        = 1;
252 
253   params->ufactor       = -1;
254 
255   params->ubvecstr      = NULL;
256   params->ubvec         = NULL;
257 
258 
259   gk_clearcputimer(params->iotimer);
260   gk_clearcputimer(params->parttimer);
261   gk_clearcputimer(params->reporttimer);
262 
263 
264   /* Parse the command line arguments  */
265   while ((c = gk_getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
266     switch (c) {
267       case METIS_OPTION_PTYPE:
268         if (gk_optarg)
269           if ((params->ptype = gk_GetStringID(ptype_options, gk_optarg)) == -1)
270             errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
271         break;
272       case METIS_OPTION_OBJTYPE:
273         if (gk_optarg)
274           if ((params->objtype = gk_GetStringID(objtype_options, gk_optarg)) == -1)
275             errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
276         break;
277       case METIS_OPTION_CTYPE:
278         if (gk_optarg)
279           if ((params->ctype = gk_GetStringID(ctype_options, gk_optarg)) == -1)
280             errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
281         break;
282       case METIS_OPTION_IPTYPE:
283         if (gk_optarg)
284           if ((params->iptype = gk_GetStringID(iptype_options, gk_optarg)) == -1)
285             errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
286         break;
287 
288 /*
289       case METIS_OPTION_RTYPE:
290         if (gk_optarg)
291           if ((params->rtype = gk_GetStringID(rtype_options, gk_optarg)) == -1)
292             errexit("Invalid option -%s=%s\n", long_options[option_index].name, gk_optarg);
293         break;
294 */
295 
296       case METIS_OPTION_NO2HOP:
297         params->no2hop = 1;
298         break;
299 
300       case METIS_OPTION_CONTIG:
301         params->contig = 1;
302         break;
303 
304       case METIS_OPTION_MINCONN:
305         params->minconn = 1;
306         break;
307 
308       case METIS_OPTION_NOOUTPUT:
309         params->nooutput = 1;
310         break;
311 
312       case METIS_OPTION_BALANCE:
313         params->balance = 1;
314         break;
315 
316       case METIS_OPTION_TPWGTS:
317         if (gk_optarg) params->tpwgtsfile = gk_strdup(gk_optarg);
318         break;
319 
320       case METIS_OPTION_UBVEC:
321         if (gk_optarg) params->ubvecstr = gk_strdup(gk_optarg);
322         break;
323 
324       case METIS_OPTION_NCUTS:
325         if (gk_optarg) params->ncuts = (idx_t)atoi(gk_optarg);
326         break;
327       case METIS_OPTION_NITER:
328         if (gk_optarg) params->niter = (idx_t)atoi(gk_optarg);
329         break;
330 
331       case METIS_OPTION_UFACTOR:
332         if (gk_optarg) params->ufactor = (idx_t)atoi(gk_optarg);
333         break;
334 
335       case METIS_OPTION_SEED:
336         if (gk_optarg) params->seed = (idx_t)atoi(gk_optarg);
337         break;
338 
339       case METIS_OPTION_DBGLVL:
340         if (gk_optarg) params->dbglvl = (idx_t)atoi(gk_optarg);
341         break;
342 
343       case METIS_OPTION_HELP:
344         for (i=0; strlen(helpstr[i]) > 0; i++)
345           printf("%s\n", helpstr[i]);
346         exit(0);
347         break;
348       case '?':
349       default:
350         errexit("Illegal command-line option(s)\n"
351                 "Use %s -help for a summary of the options.\n", argv[0]);
352     }
353   }
354 
355   if (argc-gk_optind != 2) {
356     printf("Missing parameters.");
357     for (i=0; strlen(shorthelpstr[i]) > 0; i++)
358       printf("%s\n", shorthelpstr[i]);
359     exit(0);
360   }
361 
362   params->filename = gk_strdup(argv[gk_optind++]);
363   params->nparts   = atoi(argv[gk_optind++]);
364 
365   if (params->nparts < 2)
366     errexit("The number of partitions should be greater than 1!\n");
367 
368 
369   /* Set the ptype-specific defaults */
370   if (params->ptype == METIS_PTYPE_RB) {
371     params->rtype   = METIS_RTYPE_FM;
372   }
373   if (params->ptype == METIS_PTYPE_KWAY) {
374     params->iptype  = METIS_IPTYPE_METISRB;
375     params->rtype   = METIS_RTYPE_GREEDY;
376   }
377 
378   /* Check for invalid parameter combination */
379   if (params->ptype == METIS_PTYPE_RB) {
380     if (params->contig)
381       errexit("***The -contig option cannot be specified with rb partitioning. Will be ignored.\n");
382     if (params->minconn)
383       errexit("***The -minconn option cannot be specified with rb partitioning. Will be ignored. \n");
384     if (params->objtype == METIS_OBJTYPE_VOL)
385       errexit("The -objtype=vol option cannot be specified with rb partitioning.\n");
386   }
387 
388   return params;
389 }
390 
391 
392