1 /*
2  * Copyright 1994-2011, Regents of the University of Minnesota
3  *
4  * gpmetis.c
5  *
6  * Drivers for the partitioning routines
7  *
8  * Started 8/28/94
9  * George
10  *
11  * $Id: gpmetis.c 13900 2013-03-24 15:27:07Z karypis $
12  *
13  */
14 
15 #include "metisbin.h"
16 
17 
18 
19 /*************************************************************************/
20 /*! Let the game begin! */
21 /*************************************************************************/
main(int argc,char * argv[])22 int main(int argc, char *argv[])
23 {
24   idx_t i;
25   char *curptr, *newptr;
26   idx_t options[METIS_NOPTIONS];
27   graph_t *graph;
28   idx_t *part;
29   idx_t objval;
30   params_t *params;
31   int status=0;
32 
33   params = parse_cmdline(argc, argv);
34 
35   gk_startcputimer(params->iotimer);
36   graph = ReadGraph(params);
37 
38   ReadTPwgts(params, graph->ncon);
39   gk_stopcputimer(params->iotimer);
40 
41   /* Check if the graph is contiguous */
42   if (params->contig && !IsConnected(graph, 0)) {
43     printf("***The input graph is not contiguous.\n"
44            "***The specified -contig option will be ignored.\n");
45     params->contig = 0;
46   }
47 
48   /* Get ubvec if supplied */
49   if (params->ubvecstr) {
50     params->ubvec = rmalloc(graph->ncon, "main");
51     curptr = params->ubvecstr;
52     for (i=0; i<graph->ncon; i++) {
53       params->ubvec[i] = strtoreal(curptr, &newptr);
54       if (curptr == newptr)
55         errexit("Error parsing entry #%"PRIDX" of ubvec [%s] (possibly missing).\n",
56             i, params->ubvecstr);
57       curptr = newptr;
58     }
59   }
60 
61   /* Setup iptype */
62   if (params->iptype == -1) {
63     if (params->ptype == METIS_PTYPE_RB) {
64       if (graph->ncon == 1)
65         params->iptype = METIS_IPTYPE_GROW;
66       else
67         params->iptype = METIS_IPTYPE_RANDOM;
68     }
69   }
70 
71   GPPrintInfo(params, graph);
72 
73   part = imalloc(graph->nvtxs, "main: part");
74 
75   METIS_SetDefaultOptions(options);
76   options[METIS_OPTION_OBJTYPE] = params->objtype;
77   options[METIS_OPTION_CTYPE]   = params->ctype;
78   options[METIS_OPTION_IPTYPE]  = params->iptype;
79   options[METIS_OPTION_RTYPE]   = params->rtype;
80   options[METIS_OPTION_NO2HOP]  = params->no2hop;
81   options[METIS_OPTION_MINCONN] = params->minconn;
82   options[METIS_OPTION_CONTIG]  = params->contig;
83   options[METIS_OPTION_SEED]    = params->seed;
84   options[METIS_OPTION_NITER]   = params->niter;
85   options[METIS_OPTION_NCUTS]   = params->ncuts;
86   options[METIS_OPTION_UFACTOR] = params->ufactor;
87   options[METIS_OPTION_DBGLVL]  = params->dbglvl;
88 
89   gk_malloc_init();
90   gk_startcputimer(params->parttimer);
91 
92   switch (params->ptype) {
93     case METIS_PTYPE_RB:
94       status = METIS_PartGraphRecursive(&graph->nvtxs, &graph->ncon, graph->xadj,
95                    graph->adjncy, graph->vwgt, graph->vsize, graph->adjwgt,
96                    &params->nparts, params->tpwgts, params->ubvec, options,
97                    &objval, part);
98       break;
99 
100     case METIS_PTYPE_KWAY:
101       status = METIS_PartGraphKway(&graph->nvtxs, &graph->ncon, graph->xadj,
102                    graph->adjncy, graph->vwgt, graph->vsize, graph->adjwgt,
103                    &params->nparts, params->tpwgts, params->ubvec, options,
104                    &objval, part);
105       break;
106 
107   }
108 
109   gk_stopcputimer(params->parttimer);
110 
111   if (gk_GetCurMemoryUsed() != 0)
112     printf("***It seems that Metis did not free all of its memory! Report this.\n");
113   params->maxmemory = gk_GetMaxMemoryUsed();
114   gk_malloc_cleanup(0);
115 
116 
117   if (status != METIS_OK) {
118     printf("\n***Metis returned with an error.\n");
119   }
120   else {
121     if (!params->nooutput) {
122       /* Write the solution */
123       gk_startcputimer(params->iotimer);
124       WritePartition(params->filename, part, graph->nvtxs, params->nparts);
125       gk_stopcputimer(params->iotimer);
126     }
127 
128     GPReportResults(params, graph, part, objval);
129   }
130 
131   FreeGraph(&graph);
132   gk_free((void **)&part, LTERM);
133   gk_free((void **)&params->filename, &params->tpwgtsfile, &params->tpwgts,
134       &params->ubvecstr, &params->ubvec, &params, LTERM);
135 
136 }
137 
138 
139 /*************************************************************************/
140 /*! This function prints run parameters */
141 /*************************************************************************/
GPPrintInfo(params_t * params,graph_t * graph)142 void GPPrintInfo(params_t *params, graph_t *graph)
143 {
144   idx_t i;
145 
146   if (params->ufactor == -1) {
147     if (params->ptype == METIS_PTYPE_KWAY)
148       params->ufactor = KMETIS_DEFAULT_UFACTOR;
149     else if (graph->ncon == 1)
150       params->ufactor = PMETIS_DEFAULT_UFACTOR;
151     else
152       params->ufactor = MCPMETIS_DEFAULT_UFACTOR;
153   }
154 
155   printf("******************************************************************************\n");
156   printf("%s", METISTITLE);
157   printf(" (HEAD: %s, Built on: %s, %s)\n", SVNINFO, __DATE__, __TIME__);
158   printf(" size of idx_t: %zubits, real_t: %zubits, idx_t *: %zubits\n",
159       8*sizeof(idx_t), 8*sizeof(real_t), 8*sizeof(idx_t *));
160   printf("\n");
161   printf("Graph Information -----------------------------------------------------------\n");
162   printf(" Name: %s, #Vertices: %"PRIDX", #Edges: %"PRIDX", #Parts: %"PRIDX"\n",
163       params->filename, graph->nvtxs, graph->nedges/2, params->nparts);
164   if (graph->ncon > 1)
165     printf(" Balancing constraints: %"PRIDX"\n", graph->ncon);
166 
167   printf("\n");
168   printf("Options ---------------------------------------------------------------------\n");
169   printf(" ptype=%s, objtype=%s, ctype=%s, rtype=%s, iptype=%s\n",
170       ptypenames[params->ptype], objtypenames[params->objtype], ctypenames[params->ctype],
171       rtypenames[params->rtype], iptypenames[params->iptype]);
172 
173   printf(" dbglvl=%"PRIDX", ufactor=%.3f, no2hop=%s, minconn=%s, contig=%s, nooutput=%s\n",
174       params->dbglvl,
175       I2RUBFACTOR(params->ufactor),
176       (params->no2hop   ? "YES" : "NO"),
177       (params->minconn  ? "YES" : "NO"),
178       (params->contig   ? "YES" : "NO"),
179       (params->nooutput ? "YES" : "NO")
180       );
181 
182   printf(" seed=%"PRIDX", niter=%"PRIDX", ncuts=%"PRIDX"\n",
183       params->seed, params->niter, params->ncuts);
184 
185   if (params->ubvec) {
186     printf(" ubvec=(");
187     for (i=0; i<graph->ncon; i++)
188       printf("%s%.2e", (i==0?"":" "), (double)params->ubvec[i]);
189     printf(")\n");
190   }
191 
192   printf("\n");
193   switch (params->ptype) {
194     case METIS_PTYPE_RB:
195       printf("Recursive Partitioning ------------------------------------------------------\n");
196       break;
197     case METIS_PTYPE_KWAY:
198       printf("Direct k-way Partitioning ---------------------------------------------------\n");
199       break;
200   }
201 }
202 
203 
204 /*************************************************************************/
205 /*! This function does any post-partitioning reporting */
206 /*************************************************************************/
GPReportResults(params_t * params,graph_t * graph,idx_t * part,idx_t objval)207 void GPReportResults(params_t *params, graph_t *graph, idx_t *part, idx_t objval)
208 {
209   gk_startcputimer(params->reporttimer);
210   ComputePartitionInfo(params, graph, part);
211 
212   gk_stopcputimer(params->reporttimer);
213 
214   printf("\nTiming Information ----------------------------------------------------------\n");
215   printf("  I/O:          \t\t %7.3"PRREAL" sec\n", gk_getcputimer(params->iotimer));
216   printf("  Partitioning: \t\t %7.3"PRREAL" sec   (METIS time)\n", gk_getcputimer(params->parttimer));
217   printf("  Reporting:    \t\t %7.3"PRREAL" sec\n", gk_getcputimer(params->reporttimer));
218   printf("\nMemory Information ----------------------------------------------------------\n");
219   printf("  Max memory used:\t\t %7.3"PRREAL" MB\n", (real_t)(params->maxmemory/(1024.0*1024.0)));
220   printf("******************************************************************************\n");
221 
222 }
223