1 /*
2  * Copyright 1994-2011, Regents of the University of Minnesota
3  *
4  * mpmetis.c
5  *
6  * Drivers for the mesh partitioning routines
7  *
8  * Started 8/28/94
9  * George
10  *
11  * $Id: mpmetis.c 10567 2011-07-13 16:17: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 options[METIS_NOPTIONS];
25   mesh_t *mesh;
26   idx_t *epart, *npart;
27   idx_t objval;
28   params_t *params;
29   int status=0;
30 
31   params = parse_cmdline(argc, argv);
32 
33   gk_startcputimer(params->iotimer);
34   mesh = ReadMesh(params);
35 
36   if (mesh->ncon > 1) {
37     printf("*** Meshes with more than one balancing constraint are not supported yet.\n");
38     exit(0);
39   }
40 
41   ReadTPwgts(params, mesh->ncon);
42   gk_stopcputimer(params->iotimer);
43 
44   MPPrintInfo(params, mesh);
45 
46   epart = imalloc(mesh->ne, "main: epart");
47   npart = imalloc(mesh->nn, "main: npart");
48 
49   METIS_SetDefaultOptions(options);
50   options[METIS_OPTION_PTYPE]   = params->ptype;
51   options[METIS_OPTION_OBJTYPE] = params->objtype;
52   options[METIS_OPTION_CTYPE]   = params->ctype;
53   options[METIS_OPTION_IPTYPE]  = params->iptype;
54   options[METIS_OPTION_RTYPE]   = params->rtype;
55   options[METIS_OPTION_DBGLVL]  = params->dbglvl;
56   options[METIS_OPTION_UFACTOR] = params->ufactor;
57   options[METIS_OPTION_MINCONN] = params->minconn;
58   options[METIS_OPTION_CONTIG]  = params->contig;
59   options[METIS_OPTION_SEED]    = params->seed;
60   options[METIS_OPTION_NITER]   = params->niter;
61   options[METIS_OPTION_NCUTS]   = params->ncuts;
62 
63 
64   gk_malloc_init();
65   gk_startcputimer(params->parttimer);
66 
67   switch (params->gtype) {
68     case METIS_GTYPE_DUAL:
69       status = METIS_PartMeshDual(&mesh->ne, &mesh->nn, mesh->eptr, mesh->eind,
70                    mesh->ewgt, NULL, &params->ncommon, &params->nparts,
71                    params->tpwgts, options, &objval, epart, npart);
72       break;
73 
74     case METIS_GTYPE_NODAL:
75       status = METIS_PartMeshNodal(&mesh->ne, &mesh->nn, mesh->eptr, mesh->eind,
76                    NULL, NULL, &params->nparts, params->tpwgts, options, &objval,
77                    epart, npart);
78       break;
79   }
80 
81   gk_stopcputimer(params->parttimer);
82   if (gk_GetCurMemoryUsed() != 0)
83         printf("***It seems that Metis did not free all of its memory! Report this.\n");
84   params->maxmemory = gk_GetMaxMemoryUsed();
85   gk_malloc_cleanup(0);
86 
87   if (status != METIS_OK) {
88     printf("\n***Metis returned with an error.\n");
89   }
90   else {
91     if (!params->nooutput) {
92       /* Write the solution */
93       gk_startcputimer(params->iotimer);
94       WriteMeshPartition(params->filename, params->nparts, mesh->ne, epart, mesh->nn, npart);
95       gk_stopcputimer(params->iotimer);
96     }
97 
98     MPReportResults(params, mesh, epart, npart, objval);
99   }
100 
101   FreeMesh(&mesh);
102   gk_free((void **)&epart, &npart, LTERM);
103   gk_free((void **)&params->filename, &params->tpwgtsfile, &params->tpwgts,
104       &params->ubvecstr, &params->ubvec, &params, LTERM);
105 
106 }
107 
108 
109 /*************************************************************************/
110 /*! This function prints run parameters */
111 /*************************************************************************/
MPPrintInfo(params_t * params,mesh_t * mesh)112 void MPPrintInfo(params_t *params, mesh_t *mesh)
113 {
114   if (params->ufactor == -1) {
115     if (params->ptype == METIS_PTYPE_KWAY)
116       params->ufactor = KMETIS_DEFAULT_UFACTOR;
117     else
118       params->ufactor = PMETIS_DEFAULT_UFACTOR;
119   }
120 
121   printf("******************************************************************************\n");
122   printf("%s", METISTITLE);
123   printf(" (HEAD: %s, Built on: %s, %s)\n", SVNINFO, __DATE__, __TIME__);
124   printf(" size of idx_t: %zubits, real_t: %zubits, idx_t *: %zubits\n",
125       8*sizeof(idx_t), 8*sizeof(real_t), 8*sizeof(idx_t *));
126   printf("\n");
127   printf("Mesh Information ------------------------------------------------------------\n");
128   printf(" Name: %s, #Elements: %"PRIDX", #Nodes: %"PRIDX", #Parts: %"PRIDX"\n",
129       params->filename, mesh->ne, mesh->nn, params->nparts);
130   if (mesh->ncon > 1)
131     printf("  Balancing Constraints: %"PRIDX"\n", mesh->ncon);
132 
133   printf("\n");
134   printf("Options ---------------------------------------------------------------------\n");
135   printf(" ptype=%s, objtype=%s, ctype=%s, rtype=%s, iptype=%s\n",
136       ptypenames[params->ptype], objtypenames[params->objtype], ctypenames[params->ctype],
137       rtypenames[params->rtype], iptypenames[params->iptype]);
138 
139   printf(" dbglvl=%"PRIDX", ufactor=%.3f, minconn=%s, contig=%s, nooutput=%s\n",
140       params->dbglvl,
141       I2RUBFACTOR(params->ufactor),
142       (params->minconn  ? "YES" : "NO"),
143       (params->contig   ? "YES" : "NO"),
144       (params->nooutput ? "YES" : "NO")
145       );
146 
147   printf(" seed=%"PRIDX", niter=%"PRIDX", ncuts=%"PRIDX"\n",
148       params->seed, params->niter, params->ncuts);
149 
150   printf(" gtype=%s, ncommon=%"PRIDX", niter=%"PRIDX", ncuts=%"PRIDX"\n",
151       gtypenames[params->gtype], params->ncommon, params->niter, params->ncuts);
152 
153   printf("\n");
154   switch (params->ptype) {
155     case METIS_PTYPE_RB:
156       printf("Recursive Partitioning ------------------------------------------------------\n");
157       break;
158     case METIS_PTYPE_KWAY:
159       printf("Direct k-way Partitioning ---------------------------------------------------\n");
160       break;
161   }
162 }
163 
164 
165 /*************************************************************************/
166 /*! This function does any post-partitioning reporting */
167 /*************************************************************************/
MPReportResults(params_t * params,mesh_t * mesh,idx_t * epart,idx_t * npart,idx_t objval)168 void MPReportResults(params_t *params, mesh_t *mesh, idx_t *epart, idx_t *npart,
169          idx_t objval)
170 {
171 
172   gk_startcputimer(params->reporttimer);
173 
174   /* ComputePartitionInfo(params, graph, part); */
175 
176   printf(" - %s: %"PRIDX".\n\n",
177       (params->objtype == METIS_OBJTYPE_CUT ? "Edgecut" : "Volume"), objval);
178 
179   gk_stopcputimer(params->reporttimer);
180 
181 
182   printf("\nTiming Information ----------------------------------------------------------\n");
183   printf("  I/O:          \t\t %7.3"PRREAL" sec\n", gk_getcputimer(params->iotimer));
184   printf("  Partitioning: \t\t %7.3"PRREAL" sec   (METIS time)\n", gk_getcputimer(params->parttimer));
185   printf("  Reporting:    \t\t %7.3"PRREAL" sec\n", gk_getcputimer(params->reporttimer));
186   printf("\nMemory Information ----------------------------------------------------------\n");
187   printf("  Max memory used:\t\t %7.3"PRREAL" MB\n", (real_t)(params->maxmemory/(1024.0*1024.0)));
188   printf("******************************************************************************\n");
189 
190 }
191