00001
00010 #include <GKlib.h>
00011
00012
00014
00015 typedef struct {
00016 int type;
00017 int niter;
00018 float eps;
00019 float lamda;
00020
00021 char *infile;
00022 char *outfile;
00023 } params_t;
00024
00025
00027
00028 #define CMD_NITER 1
00029 #define CMD_EPS 2
00030 #define CMD_LAMDA 3
00031 #define CMD_TYPE 4
00032 #define CMD_HELP 10
00033
00034
00035
00037
00038 static struct gk_option long_options[] = {
00039 {"type", 1, 0, CMD_TYPE},
00040 {"niter", 1, 0, CMD_NITER},
00041 {"lamda", 1, 0, CMD_LAMDA},
00042 {"eps", 1, 0, CMD_EPS},
00043 {"help", 0, 0, CMD_HELP},
00044 {0, 0, 0, 0}
00045 };
00046
00047
00048
00049
00050
00051 static char helpstr[][100] = {
00052 " ",
00053 "Usage: gkgraph [options] <graph-file> [<out-file>]",
00054 " ",
00055 " Required parameters",
00056 " graph-file",
00057 " The name of the file storing the graph. The file is in ",
00058 " Metis' graph format.",
00059 " ",
00060 " Optional parameters",
00061 " -niter=int",
00062 " Specifies the maximum number of iterations. [default: 100]",
00063 " ",
00064 " -lamda=float",
00065 " Specifies the follow-the-adjacent-links probability. [default: 0.80]",
00066 " ",
00067 " -eps=float",
00068 " Specifies the error tollerance. [default: 1e-10]",
00069 " ",
00070 " -help",
00071 " Prints this message.",
00072 ""
00073 };
00074
00075 static char shorthelpstr[][100] = {
00076 " ",
00077 " Usage: gkgraph [options] <graph-file> [<out-file>]",
00078 " use 'gkgraph -help' for a summary of the options.",
00079 ""
00080 };
00081
00082
00083
00084
00086
00087 double compute_compactness(params_t *params, gk_graph_t *graph, int32_t *perm);
00088 void reorder_centroid(params_t *params, gk_graph_t *graph, int32_t *perm);
00089 void print_init_info(params_t *params, gk_graph_t *graph);
00090 void print_final_info(params_t *params);
00091 params_t *parse_cmdline(int argc, char *argv[]);
00092
00093
00094
00096
00097 int main(int argc, char *argv[])
00098 {
00099 ssize_t i, j, v;
00100 params_t *params;
00101 gk_graph_t *graph, *pgraph;
00102 int32_t *perm;
00103
00104
00105 params = parse_cmdline(argc, argv);
00106
00107
00108 graph = gk_graph_Read(params->infile, GK_GRAPH_FMT_METIS, 0, 0, 0);
00109
00110
00111 print_init_info(params, graph);
00112
00113
00114
00115 printf("Initial compactness: %le\n", compute_compactness(params, graph, NULL));
00116
00117
00118
00119 for (i=0; i<1; i++) {
00120 v = RandomInRange(graph->nvtxs);
00121 gk_graph_ComputeBFSOrdering(graph, v, &perm, NULL);
00122 printf("BFS from %8d. Compactness: %le\n",
00123 (int) v, compute_compactness(params, graph, perm));
00124
00125 pgraph = gk_graph_Reorder(graph, perm, NULL);
00126 gk_graph_Write(pgraph, "bfs.metis", GK_GRAPH_FMT_METIS);
00127 gk_graph_Free(&pgraph);
00128
00129 gk_graph_ComputeBestFOrdering(graph, v, params->type, &perm, NULL);
00130 printf("BestF from %8d. Compactness: %le\n",
00131 (int) v, compute_compactness(params, graph, perm));
00132
00133 pgraph = gk_graph_Reorder(graph, perm, NULL);
00134 gk_graph_Write(pgraph, "bestf.metis", GK_GRAPH_FMT_METIS);
00135 gk_graph_Free(&pgraph);
00136
00137 #ifdef XXX
00138 for (j=0; j<params->niter; j++) {
00139 reorder_centroid(params, graph, perm);
00140 printf("\tAfter centroid; Compactness: %le\n",
00141 compute_compactness(params, graph, perm));
00142 }
00143
00144 pgraph = gk_graph_Reorder(graph, perm, NULL);
00145 gk_graph_Write(pgraph, "centroid.metis", GK_GRAPH_FMT_METIS);
00146 gk_graph_Free(&pgraph);
00147 #endif
00148 gk_free((void **)&perm, LTERM);
00149 }
00150
00151 gk_graph_Free(&graph);
00152
00153
00154 print_final_info(params);
00155 }
00156
00157
00158
00159
00160
00162
00163 double compute_compactness(params_t *params, gk_graph_t *graph, int32_t *perm)
00164 {
00165 int i, v, u, nvtxs;
00166 ssize_t j, *xadj;
00167 int32_t *adjncy;
00168 double compactness=0.0;
00169 int *freq;
00170
00171 nvtxs = graph->nvtxs;
00172 xadj = graph->xadj;
00173 adjncy = graph->adjncy;
00174
00175 freq = gk_ismalloc(nvtxs, 0, "compute_compactness: freq");
00176
00177 for (i=0; i<nvtxs; i++) {
00178 v = (perm == NULL ? i : perm[i]);
00179 for (j=xadj[i]; j<xadj[i+1]; j++) {
00180 u = (perm == NULL ? adjncy[j] : perm[adjncy[j]]);
00181 compactness += fabs(v-u);
00182 freq[gk_abs(v-u)]++;
00183 }
00184 }
00185
00186
00187
00188
00189
00190
00191
00192 printf("\tnsmall: %d\n", freq[1]+freq[2]+freq[3]);
00193
00194 return compactness/xadj[nvtxs];
00195 }
00196
00197
00198
00200
00201 void reorder_centroid(params_t *params, gk_graph_t *graph, int32_t *perm)
00202 {
00203 int i, v, u, nvtxs;
00204 ssize_t j, *xadj;
00205 int32_t *adjncy;
00206 gk_fkv_t *cand;
00207 double displacement;
00208
00209 nvtxs = graph->nvtxs;
00210 xadj = graph->xadj;
00211 adjncy = graph->adjncy;
00212
00213 cand = gk_fkvmalloc(nvtxs, "reorder_centroid: cand");
00214
00215 for (i=0; i<nvtxs; i++) {
00216 v = perm[i];
00217 displacement = 0.0;
00218
00219 for (j=xadj[i]; j<xadj[i+1]; j++) {
00220 u = perm[adjncy[j]];
00221 displacement += u-v;
00222
00223 }
00224
00225 cand[i].val = i;
00226 cand[i].key = v + displacement*params->lamda/(xadj[i+1]-xadj[i]);
00227 }
00228
00229
00230 gk_fkvsorti(nvtxs, cand);
00231
00232
00233
00234 gk_i32set(nvtxs, -1, perm);
00235 for (i=0; i<nvtxs; i++) {
00236 if (perm[cand[i].val] != -1)
00237 errexit("Resetting perm[%d] = %d\n", cand[i].val, perm[cand[i].val]);
00238 perm[cand[i].val] = i;
00239 }
00240
00241 gk_free((void **)&cand, LTERM);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00253
00254 void print_init_info(params_t *params, gk_graph_t *graph)
00255 {
00256 printf("*******************************************************************************\n");
00257 printf(" gkgraph\n\n");
00258 printf("Graph Information ----------------------------------------------------------\n");
00259 printf(" input file=%s, [%d, %zd]\n",
00260 params->infile, graph->nvtxs, graph->xadj[graph->nvtxs]);
00261
00262 printf("\n");
00263 printf("Options --------------------------------------------------------------------\n");
00264 printf(" type=%d, niter=%d, lamda=%f, eps=%e\n",
00265 params->type, params->niter, params->lamda, params->eps);
00266
00267 printf("\n");
00268 printf("Working... -----------------------------------------------------------------\n");
00269 }
00270
00271
00272
00274
00275 void print_final_info(params_t *params)
00276 {
00277 printf("\n");
00278 printf("Memory Usage Information -----------------------------------------------------\n");
00279 printf(" Maximum memory used: %10zd bytes\n", (ssize_t) gk_GetMaxMemoryUsed());
00280 printf(" Current memory used: %10zd bytes\n", (ssize_t) gk_GetCurMemoryUsed());
00281 printf("********************************************************************************\n");
00282 }
00283
00284
00285
00287
00288 params_t *parse_cmdline(int argc, char *argv[])
00289 {
00290 int i;
00291 int c, option_index;
00292 params_t *params;
00293
00294 params = (params_t *)gk_malloc(sizeof(params_t), "parse_cmdline: params");
00295
00296
00297 params->type = 1;
00298 params->niter = 1;
00299 params->eps = 1e-10;
00300 params->lamda = 0.20;
00301 params->infile = NULL;
00302
00303
00304
00305 while ((c = gk_getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
00306 switch (c) {
00307 case CMD_TYPE:
00308 if (gk_optarg) params->type = atoi(gk_optarg);
00309 break;
00310 case CMD_NITER:
00311 if (gk_optarg) params->niter = atoi(gk_optarg);
00312 break;
00313 case CMD_EPS:
00314 if (gk_optarg) params->eps = atof(gk_optarg);
00315 break;
00316 case CMD_LAMDA:
00317 if (gk_optarg) params->lamda = atof(gk_optarg);
00318 break;
00319
00320 case CMD_HELP:
00321 for (i=0; strlen(helpstr[i]) > 0; i++)
00322 printf("%s\n", helpstr[i]);
00323 exit(0);
00324 break;
00325 case '?':
00326 default:
00327 printf("Illegal command-line option(s)\nUse %s -help for a summary of the options.\n", argv[0]);
00328 exit(0);
00329 }
00330 }
00331
00332 if (argc-gk_optind != 1) {
00333 printf("Unrecognized parameters.");
00334 for (i=0; strlen(shorthelpstr[i]) > 0; i++)
00335 printf("%s\n", shorthelpstr[i]);
00336 exit(0);
00337 }
00338
00339 params->infile = gk_strdup(argv[gk_optind++]);
00340
00341 if (argc-gk_optind > 0)
00342 params->outfile = gk_strdup(argv[gk_optind++]);
00343 else
00344 params->outfile = gk_strdup("gkgraph.out");
00345
00346 if (!gk_fexists(params->infile))
00347 errexit("input file %s does not exist.\n", params->infile);
00348
00349 return params;
00350 }
00351