00001
00010 #include <GKlib.h>
00011
00012 #define OMPMINOPS 50000
00013
00014
00018
00019 gk_graph_t *gk_graph_Create()
00020 {
00021 gk_graph_t *graph;
00022
00023 graph = (gk_graph_t *)gk_malloc(sizeof(gk_graph_t), "gk_graph_Create: graph");
00024
00025 gk_graph_Init(graph);
00026
00027 return graph;
00028 }
00029
00030
00031
00035
00036 void gk_graph_Init(gk_graph_t *graph)
00037 {
00038 memset(graph, 0, sizeof(gk_graph_t));
00039 graph->nvtxs = -1;
00040 }
00041
00042
00043
00047
00048 void gk_graph_Free(gk_graph_t **graph)
00049 {
00050 if (*graph == NULL)
00051 return;
00052 gk_graph_FreeContents(*graph);
00053 gk_free((void **)graph, LTERM);
00054 }
00055
00056
00057
00062
00063 void gk_graph_FreeContents(gk_graph_t *graph)
00064 {
00065 gk_free((void *)&graph->xadj, &graph->adjncy,
00066 &graph->iadjwgt, &graph->fadjwgt,
00067 &graph->ivwgts, &graph->fvwgts,
00068 &graph->ivsizes, &graph->fvsizes,
00069 &graph->vlabels,
00070 LTERM);
00071 }
00072
00073
00074
00084
00085 gk_graph_t *gk_graph_Read(char *filename, int format, int isfewgts,
00086 int isfvwgts, int isfvsizes)
00087 {
00088 ssize_t i, k, l;
00089 size_t nfields, nvtxs=0, nedges=0, fmt, ncon, lnlen;
00090 int32_t ival;
00091 float fval;
00092 int readsizes=0, readwgts=0, readvals=0, numbering=0;
00093 char *line=NULL, *head, *tail, fmtstr[256];
00094 FILE *fpin=NULL;
00095 gk_graph_t *graph=NULL;
00096
00097
00098 if (!gk_fexists(filename))
00099 gk_errexit(SIGERR, "File %s does not exist!\n", filename);
00100
00101 if (format == GK_GRAPH_FMT_METIS) {
00102 fpin = gk_fopen(filename, "r", "gk_graph_Read: fpin");
00103 do {
00104 if (gk_getline(&line, &lnlen, fpin) <= 0)
00105 gk_errexit(SIGERR, "Premature end of input file: file:%s\n", filename);
00106 } while (line[0] == '%');
00107
00108 fmt = ncon = 0;
00109 nfields = sscanf(line, "%zu %zu %zu %zu", &nvtxs, &nedges, &fmt, &ncon);
00110 if (nfields < 2)
00111 gk_errexit(SIGERR, "Header line must contain at least 2 integers (#vtxs and #edges).\n");
00112
00113 nedges *= 2;
00114
00115 if (fmt > 111)
00116 gk_errexit(SIGERR, "Cannot read this type of file format [fmt=%zu]!\n", fmt);
00117
00118 sprintf(fmtstr, "%03zu", fmt%1000);
00119 readsizes = (fmtstr[0] == '1');
00120 readwgts = (fmtstr[1] == '1');
00121 readvals = (fmtstr[2] == '1');
00122 numbering = 1;
00123 ncon = (ncon == 0 ? 1 : ncon);
00124 }
00125 else {
00126 gk_errexit(SIGERR, "Unrecognized format: %d\n", format);
00127 }
00128
00129 graph = gk_graph_Create();
00130
00131 graph->nvtxs = nvtxs;
00132
00133 graph->xadj = gk_zmalloc(nvtxs+1, "gk_graph_Read: xadj");
00134 graph->adjncy = gk_i32malloc(nedges, "gk_graph_Read: adjncy");
00135 if (readvals) {
00136 if (isfewgts)
00137 graph->fadjwgt = gk_fmalloc(nedges, "gk_graph_Read: fadjwgt");
00138 else
00139 graph->iadjwgt = gk_i32malloc(nedges, "gk_graph_Read: iadjwgt");
00140 }
00141
00142 if (readsizes) {
00143 if (isfvsizes)
00144 graph->fvsizes = gk_fmalloc(nvtxs, "gk_graph_Read: fvsizes");
00145 else
00146 graph->ivsizes = gk_i32malloc(nvtxs, "gk_graph_Read: ivsizes");
00147 }
00148
00149 if (readwgts) {
00150 if (isfvwgts)
00151 graph->fvwgts = gk_fmalloc(nvtxs*ncon, "gk_graph_Read: fvwgts");
00152 else
00153 graph->ivwgts = gk_i32malloc(nvtxs*ncon, "gk_graph_Read: ivwgts");
00154 }
00155
00156
00157
00158
00159
00160 numbering = (numbering ? - 1 : 0);
00161 for (graph->xadj[0]=0, k=0, i=0; i<nvtxs; i++) {
00162 do {
00163 if (gk_getline(&line, &lnlen, fpin) == -1)
00164 gk_errexit(SIGERR, "Pregraphure end of input file: file while reading row %d\n", i);
00165 } while (line[0] == '%');
00166
00167 head = line;
00168 tail = NULL;
00169
00170
00171 if (readsizes) {
00172 if (isfvsizes) {
00173 #ifdef __MSC__
00174 graph->fvsizes[i] = (float)strtod(head, &tail);
00175 #else
00176 graph->fvsizes[i] = strtof(head, &tail);
00177 #endif
00178 if (tail == head)
00179 gk_errexit(SIGERR, "The line for vertex %zd does not have size information\n", i+1);
00180 if (graph->fvsizes[i] < 0)
00181 gk_errexit(SIGERR, "The size for vertex %zd must be >= 0\n", i+1);
00182 }
00183 else {
00184 graph->ivsizes[i] = strtol(head, &tail, 0);
00185 if (tail == head)
00186 gk_errexit(SIGERR, "The line for vertex %zd does not have size information\n", i+1);
00187 if (graph->ivsizes[i] < 0)
00188 gk_errexit(SIGERR, "The size for vertex %zd must be >= 0\n", i+1);
00189 }
00190 head = tail;
00191 }
00192
00193
00194 if (readwgts) {
00195 for (l=0; l<ncon; l++) {
00196 if (isfvwgts) {
00197 #ifdef __MSC__
00198 graph->fvwgts[i*ncon+l] = (float)strtod(head, &tail);
00199 #else
00200 graph->fvwgts[i*ncon+l] = strtof(head, &tail);
00201 #endif
00202 if (tail == head)
00203 gk_errexit(SIGERR, "The line for vertex %zd does not have enough weights "
00204 "for the %d constraints.\n", i+1, ncon);
00205 if (graph->fvwgts[i*ncon+l] < 0)
00206 gk_errexit(SIGERR, "The weight vertex %zd and constraint %zd must be >= 0\n", i+1, l);
00207 }
00208 else {
00209 graph->ivwgts[i*ncon+l] = strtol(head, &tail, 0);
00210 if (tail == head)
00211 gk_errexit(SIGERR, "The line for vertex %zd does not have enough weights "
00212 "for the %d constraints.\n", i+1, ncon);
00213 if (graph->ivwgts[i*ncon+l] < 0)
00214 gk_errexit(SIGERR, "The weight vertex %zd and constraint %zd must be >= 0\n", i+1, l);
00215 }
00216 head = tail;
00217 }
00218 }
00219
00220
00221
00222 while (1) {
00223 ival = (int)strtol(head, &tail, 0);
00224 if (tail == head)
00225 break;
00226 head = tail;
00227
00228 if ((graph->adjncy[k] = ival + numbering) < 0)
00229 gk_errexit(SIGERR, "Error: Invalid column number %d at row %zd.\n", ival, i);
00230
00231 if (readvals) {
00232 if (isfewgts) {
00233 #ifdef __MSC__
00234 fval = (float)strtod(head, &tail);
00235 #else
00236 fval = strtof(head, &tail);
00237 #endif
00238 if (tail == head)
00239 gk_errexit(SIGERR, "Value could not be found for edge! Vertex:%zd, NNZ:%zd\n", i, k);
00240
00241 graph->fadjwgt[k] = fval;
00242 }
00243 else {
00244 ival = strtol(head, &tail, 0);
00245 if (tail == head)
00246 gk_errexit(SIGERR, "Value could not be found for edge! Vertex:%zd, NNZ:%zd\n", i, k);
00247
00248 graph->iadjwgt[k] = ival;
00249 }
00250 head = tail;
00251 }
00252 k++;
00253 }
00254 graph->xadj[i+1] = k;
00255 }
00256
00257 if (k != nedges)
00258 gk_errexit(SIGERR, "gk_graph_Read: Something wrong with the number of edges in "
00259 "the input file. nedges=%zd, Actualnedges=%zd.\n", nedges, k);
00260
00261 gk_fclose(fpin);
00262
00263 gk_free((void **)&line, LTERM);
00264
00265 return graph;
00266 }
00267
00268
00269
00276
00277 void gk_graph_Write(gk_graph_t *graph, char *filename, int format)
00278 {
00279 ssize_t i, j;
00280 int hasvwgts, hasvsizes, hasewgts;
00281 FILE *fpout;
00282
00283 if (format != GK_GRAPH_FMT_METIS)
00284 gk_errexit(SIGERR, "Unknown file format. %d\n", format);
00285
00286 if (filename)
00287 fpout = gk_fopen(filename, "w", "gk_graph_Write: fpout");
00288 else
00289 fpout = stdout;
00290
00291
00292 hasewgts = (graph->iadjwgt || graph->fadjwgt);
00293 hasvwgts = (graph->ivwgts || graph->fvwgts);
00294 hasvsizes = (graph->ivsizes || graph->fvsizes);
00295
00296
00297 fprintf(fpout, "%d %zd", graph->nvtxs, graph->xadj[graph->nvtxs]/2);
00298 if (hasvwgts || hasvsizes || hasewgts)
00299 fprintf(fpout, " %d%d%d", hasvsizes, hasvwgts, hasewgts);
00300 fprintf(fpout, "\n");
00301
00302
00303 for (i=0; i<graph->nvtxs; i++) {
00304 if (hasvsizes) {
00305 if (graph->ivsizes)
00306 fprintf(fpout, " %d", graph->ivsizes[i]);
00307 else
00308 fprintf(fpout, " %f", graph->fvsizes[i]);
00309 }
00310
00311 if (hasvwgts) {
00312 if (graph->ivwgts)
00313 fprintf(fpout, " %d", graph->ivwgts[i]);
00314 else
00315 fprintf(fpout, " %f", graph->fvwgts[i]);
00316 }
00317
00318 for (j=graph->xadj[i]; j<graph->xadj[i+1]; j++) {
00319 fprintf(fpout, " %d", graph->adjncy[j]+1);
00320 if (hasewgts) {
00321 if (graph->iadjwgt)
00322 fprintf(fpout, " %d", graph->iadjwgt[j]);
00323 else
00324 fprintf(fpout, " %f", graph->fadjwgt[j]);
00325 }
00326 }
00327 fprintf(fpout, "\n");
00328 }
00329 if (filename)
00330 gk_fclose(fpout);
00331 }
00332
00333
00334
00339
00340 gk_graph_t *gk_graph_Dup(gk_graph_t *graph)
00341 {
00342 gk_graph_t *ngraph;
00343
00344 ngraph = gk_graph_Create();
00345
00346 ngraph->nvtxs = graph->nvtxs;
00347
00348
00349 if (graph->xadj)
00350 ngraph->xadj = gk_zcopy(graph->nvtxs+1, graph->xadj,
00351 gk_zmalloc(graph->nvtxs+1, "gk_graph_Dup: xadj"));
00352 if (graph->ivwgts)
00353 ngraph->ivwgts = gk_i32copy(graph->nvtxs, graph->ivwgts,
00354 gk_i32malloc(graph->nvtxs, "gk_graph_Dup: ivwgts"));
00355 if (graph->ivsizes)
00356 ngraph->ivsizes = gk_i32copy(graph->nvtxs, graph->ivsizes,
00357 gk_i32malloc(graph->nvtxs, "gk_graph_Dup: ivsizes"));
00358 if (graph->vlabels)
00359 ngraph->vlabels = gk_i32copy(graph->nvtxs, graph->vlabels,
00360 gk_i32malloc(graph->nvtxs, "gk_graph_Dup: ivlabels"));
00361 if (graph->fvwgts)
00362 ngraph->fvwgts = gk_fcopy(graph->nvtxs, graph->fvwgts,
00363 gk_fmalloc(graph->nvtxs, "gk_graph_Dup: fvwgts"));
00364 if (graph->fvsizes)
00365 ngraph->fvsizes = gk_fcopy(graph->nvtxs, graph->fvsizes,
00366 gk_fmalloc(graph->nvtxs, "gk_graph_Dup: fvsizes"));
00367
00368
00369 if (graph->adjncy)
00370 ngraph->adjncy = gk_i32copy(graph->xadj[graph->nvtxs], graph->adjncy,
00371 gk_i32malloc(graph->xadj[graph->nvtxs], "gk_graph_Dup: adjncy"));
00372 if (graph->iadjwgt)
00373 ngraph->iadjwgt = gk_i32copy(graph->xadj[graph->nvtxs], graph->iadjwgt,
00374 gk_i32malloc(graph->xadj[graph->nvtxs], "gk_graph_Dup: iadjwgt"));
00375 if (graph->fadjwgt)
00376 ngraph->fadjwgt = gk_fcopy(graph->xadj[graph->nvtxs], graph->fadjwgt,
00377 gk_fmalloc(graph->xadj[graph->nvtxs], "gk_graph_Dup: fadjwgt"));
00378
00379 return ngraph;
00380 }
00381
00382
00383
00390
00391 gk_graph_t *gk_graph_ExtractSubgraph(gk_graph_t *graph, int vstart, int nvtxs)
00392 {
00393 ssize_t i;
00394 gk_graph_t *ngraph;
00395
00396 if (vstart+nvtxs > graph->nvtxs)
00397 return NULL;
00398
00399 ngraph = gk_graph_Create();
00400
00401 ngraph->nvtxs = nvtxs;
00402
00403
00404 if (graph->xadj)
00405 ngraph->xadj = gk_zcopy(nvtxs+1, graph->xadj+vstart,
00406 gk_zmalloc(nvtxs+1, "gk_graph_ExtractSubgraph: xadj"));
00407 for (i=nvtxs; i>=0; i--)
00408 ngraph->xadj[i] -= ngraph->xadj[0];
00409 ASSERT(ngraph->xadj[0] == 0);
00410
00411 if (graph->ivwgts)
00412 ngraph->ivwgts = gk_i32copy(nvtxs, graph->ivwgts+vstart,
00413 gk_i32malloc(nvtxs, "gk_graph_ExtractSubgraph: ivwgts"));
00414 if (graph->ivsizes)
00415 ngraph->ivsizes = gk_i32copy(nvtxs, graph->ivsizes+vstart,
00416 gk_i32malloc(nvtxs, "gk_graph_ExtractSubgraph: ivsizes"));
00417 if (graph->vlabels)
00418 ngraph->vlabels = gk_i32copy(nvtxs, graph->vlabels+vstart,
00419 gk_i32malloc(nvtxs, "gk_graph_ExtractSubgraph: vlabels"));
00420
00421 if (graph->fvwgts)
00422 ngraph->fvwgts = gk_fcopy(nvtxs, graph->fvwgts+vstart,
00423 gk_fmalloc(nvtxs, "gk_graph_ExtractSubgraph: fvwgts"));
00424 if (graph->fvsizes)
00425 ngraph->fvsizes = gk_fcopy(nvtxs, graph->fvsizes+vstart,
00426 gk_fmalloc(nvtxs, "gk_graph_ExtractSubgraph: fvsizes"));
00427
00428
00429 ASSERT(ngraph->xadj[nvtxs] == graph->xadj[vstart+nvtxs]-graph->xadj[vstart]);
00430 if (graph->adjncy)
00431 ngraph->adjncy = gk_i32copy(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00432 graph->adjncy+graph->xadj[vstart],
00433 gk_i32malloc(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00434 "gk_graph_ExtractSubgraph: adjncy"));
00435 if (graph->iadjwgt)
00436 ngraph->iadjwgt = gk_i32copy(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00437 graph->iadjwgt+graph->xadj[vstart],
00438 gk_i32malloc(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00439 "gk_graph_ExtractSubgraph: iadjwgt"));
00440 if (graph->fadjwgt)
00441 ngraph->fadjwgt = gk_fcopy(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00442 graph->fadjwgt+graph->xadj[vstart],
00443 gk_fmalloc(graph->xadj[vstart+nvtxs]-graph->xadj[vstart],
00444 "gk_graph_ExtractSubgraph: fadjwgt"));
00445
00446 return ngraph;
00447 }
00448
00449
00450
00459
00460 gk_graph_t *gk_graph_Reorder(gk_graph_t *graph, int32_t *perm, int32_t *iperm)
00461 {
00462 ssize_t j, jj, *xadj;
00463 int i, k, u, v, nvtxs;
00464 int freeperm=0, freeiperm=0;
00465 int32_t *adjncy;
00466 gk_graph_t *ngraph;
00467
00468 if (perm == NULL && iperm == NULL)
00469 return NULL;
00470
00471 ngraph = gk_graph_Create();
00472
00473 ngraph->nvtxs = nvtxs = graph->nvtxs;
00474 xadj = graph->xadj;
00475 adjncy = graph->adjncy;
00476
00477
00478 if (graph->xadj)
00479 ngraph->xadj = gk_zmalloc(nvtxs+1, "gk_graph_Reorder: xadj");
00480
00481 if (graph->ivwgts)
00482 ngraph->ivwgts = gk_i32malloc(nvtxs, "gk_graph_Reorder: ivwgts");
00483
00484 if (graph->ivsizes)
00485 ngraph->ivsizes = gk_i32malloc(nvtxs, "gk_graph_Reorder: ivsizes");
00486
00487 if (graph->vlabels)
00488 ngraph->vlabels = gk_i32malloc(nvtxs, "gk_graph_Reorder: ivlabels");
00489
00490 if (graph->fvwgts)
00491 ngraph->fvwgts = gk_fmalloc(nvtxs, "gk_graph_Reorder: fvwgts");
00492
00493 if (graph->fvsizes)
00494 ngraph->fvsizes = gk_fmalloc(nvtxs, "gk_graph_Reorder: fvsizes");
00495
00496
00497 if (graph->adjncy)
00498 ngraph->adjncy = gk_i32malloc(graph->xadj[nvtxs], "gk_graph_Reorder: adjncy");
00499
00500 if (graph->iadjwgt)
00501 ngraph->iadjwgt = gk_i32malloc(graph->xadj[nvtxs], "gk_graph_Reorder: iadjwgt");
00502
00503 if (graph->fadjwgt)
00504 ngraph->fadjwgt = gk_fmalloc(graph->xadj[nvtxs], "gk_graph_Reorder: fadjwgt");
00505
00506
00507
00508 if (perm == NULL) {
00509 freeperm = 1;
00510 perm = gk_i32malloc(nvtxs, "gk_graph_Reorder: perm");
00511 for (i=0; i<nvtxs; i++)
00512 perm[iperm[i]] = i;
00513 }
00514 if (iperm == NULL) {
00515 freeiperm = 1;
00516 iperm = gk_i32malloc(nvtxs, "gk_graph_Reorder: iperm");
00517 for (i=0; i<nvtxs; i++)
00518 iperm[perm[i]] = i;
00519 }
00520
00521
00522 ngraph->xadj[0] = jj = 0;
00523 for (v=0; v<nvtxs; v++) {
00524 u = iperm[v];
00525 for (j=xadj[u]; j<xadj[u+1]; j++, jj++) {
00526 ngraph->adjncy[jj] = perm[adjncy[j]];
00527 if (graph->iadjwgt)
00528 ngraph->iadjwgt[jj] = graph->iadjwgt[j];
00529 if (graph->fadjwgt)
00530 ngraph->fadjwgt[jj] = graph->fadjwgt[j];
00531 }
00532 if (graph->ivwgts)
00533 ngraph->ivwgts[v] = graph->ivwgts[u];
00534 if (graph->fvwgts)
00535 ngraph->fvwgts[v] = graph->fvwgts[u];
00536 if (graph->ivsizes)
00537 ngraph->ivsizes[v] = graph->ivsizes[u];
00538 if (graph->fvsizes)
00539 ngraph->fvsizes[v] = graph->fvsizes[u];
00540 if (graph->vlabels)
00541 ngraph->vlabels[v] = graph->vlabels[u];
00542
00543 ngraph->xadj[v+1] = jj;
00544 }
00545
00546
00547
00548 if (freeperm)
00549 gk_free((void **)&perm, LTERM);
00550 if (freeiperm)
00551 gk_free((void **)&iperm, LTERM);
00552
00553 return ngraph;
00554 }
00555
00556
00557
00571
00572 int gk_graph_FindComponents(gk_graph_t *graph, int32_t *cptr, int32_t *cind)
00573 {
00574 ssize_t i, ii, j, jj, k, nvtxs, first, last, ntodo, ncmps;
00575 ssize_t *xadj;
00576 int32_t *adjncy, *pos, *todo;
00577 int32_t mustfree_ccsr=0, mustfree_where=0;
00578
00579 nvtxs = graph->nvtxs;
00580 xadj = graph->xadj;
00581 adjncy = graph->adjncy;
00582
00583
00584 if (cptr == NULL) {
00585 cptr = gk_i32malloc(nvtxs+1, "gk_graph_FindComponents: cptr");
00586 cind = gk_i32malloc(nvtxs, "gk_graph_FindComponents: cind");
00587 mustfree_ccsr = 1;
00588 }
00589
00590
00591
00592 todo = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_FindComponents: todo"));
00593
00594
00595
00596
00597 pos = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_FindComponents: pos"));
00598
00599
00600
00601 ncmps = -1;
00602 ntodo = nvtxs;
00603 first = last = 0;
00604
00605
00606 while (ntodo > 0) {
00607 if (first == last) {
00608 cptr[++ncmps] = first;
00609
00610 ASSERT(pos[todo[0]] != -1);
00611 i = todo[0];
00612
00613 cind[last++] = i;
00614 pos[i] = -1;
00615 }
00616
00617 i = cind[first++];
00618
00619
00620
00621
00622
00623 k = pos[i];
00624 j = todo[k] = todo[--ntodo];
00625 pos[j] = k;
00626
00627 for (j=xadj[i]; j<xadj[i+1]; j++) {
00628 k = adjncy[j];
00629 if (pos[k] != -1) {
00630 cind[last++] = k;
00631 pos[k] = -1;
00632 }
00633 }
00634 }
00635 cptr[++ncmps] = first;
00636
00637 if (mustfree_ccsr)
00638 gk_free((void **)&cptr, &cind, LTERM);
00639
00640 gk_free((void **)&pos, &todo, LTERM);
00641
00642 return (int) ncmps;
00643 }
00644
00645
00646
00664
00665 void gk_graph_ComputeBFSOrdering(gk_graph_t *graph, int v, int32_t **r_perm,
00666 int32_t **r_iperm)
00667 {
00668 ssize_t j, *xadj;
00669 int i, k, nvtxs, first, last;
00670 int32_t *adjncy, *cot, *pos;
00671
00672 if (graph->nvtxs <= 0)
00673 return;
00674
00675 nvtxs = graph->nvtxs;
00676 xadj = graph->xadj;
00677 adjncy = graph->adjncy;
00678
00679
00680 pos = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_ComputeBFSOrdering: pos"));
00681
00682
00683
00684
00685
00686 cot = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_ComputeBFSOrdering: cot"));
00687
00688
00689
00690 pos[0] = cot[0] = v;
00691 pos[v] = cot[v] = 0;
00692
00693
00694 first = last = 0;
00695 while (first < nvtxs) {
00696 if (first == last) {
00697 k = cot[last];
00698 ASSERT(pos[k] != -1);
00699 pos[k] = -1;
00700 last++;
00701 }
00702
00703 i = cot[first++];
00704 for (j=xadj[i]; j<xadj[i+1]; j++) {
00705 k = adjncy[j];
00706
00707 if (pos[k] != -1) {
00708
00709
00710
00711 cot[pos[k]] = cot[last];
00712
00713 pos[cot[last]] = pos[k];
00714
00715 cot[last++] = k;
00716 pos[k] = -1;
00717 }
00718 }
00719 }
00720
00721
00722 if (r_perm != NULL) {
00723
00724 for (i=0; i<nvtxs; i++)
00725 pos[cot[i]] = i;
00726
00727 *r_perm = pos;
00728 pos = NULL;
00729 }
00730
00731 if (r_iperm != NULL) {
00732 *r_iperm = cot;
00733 cot = NULL;
00734 }
00735
00736
00737
00738 gk_free((void **)&pos, &cot, LTERM);
00739
00740 }
00741
00742
00743
00761
00762 void gk_graph_ComputeBestFOrdering0(gk_graph_t *graph, int v, int type,
00763 int32_t **r_perm, int32_t **r_iperm)
00764 {
00765 ssize_t j, jj, *xadj;
00766 int i, k, u, nvtxs;
00767 int32_t *adjncy, *perm, *degrees, *minIDs, *open;
00768 gk_i32pq_t *queue;
00769
00770 if (graph->nvtxs <= 0)
00771 return;
00772
00773 nvtxs = graph->nvtxs;
00774 xadj = graph->xadj;
00775 adjncy = graph->adjncy;
00776
00777
00778 degrees = gk_i32smalloc(nvtxs, 0, "gk_graph_ComputeBestFOrdering: degrees");
00779
00780
00781 minIDs = gk_i32smalloc(nvtxs, nvtxs+1, "gk_graph_ComputeBestFOrdering: minIDs");
00782
00783
00784 open = gk_i32malloc(nvtxs, "gk_graph_ComputeBestFOrdering: open");
00785
00786
00787
00788
00789 perm = gk_i32smalloc(nvtxs, -1, "gk_graph_ComputeBestFOrdering: perm");
00790
00791
00792 queue = gk_i32pqCreate(nvtxs);
00793 for (i=0; i<nvtxs; i++)
00794 gk_i32pqInsert(queue, i, 0);
00795 gk_i32pqUpdate(queue, v, 1);
00796
00797 open[0] = v;
00798
00799
00800 for (i=0; i<nvtxs; i++) {
00801 if ((v = gk_i32pqGetTop(queue)) == -1)
00802 gk_errexit(SIGERR, "The priority queue got empty ahead of time [i=%d].\n", i);
00803 if (perm[v] != -1)
00804 gk_errexit(SIGERR, "The perm[%d] has already been set.\n", v);
00805 perm[v] = i;
00806
00807
00808 for (j=xadj[v]; j<xadj[v+1]; j++) {
00809 u = adjncy[j];
00810 if (perm[u] == -1) {
00811 degrees[u]++;
00812 minIDs[u] = (i < minIDs[u] ? i : minIDs[u]);
00813
00814 switch (type) {
00815 case 1:
00816 gk_i32pqUpdate(queue, u, 1);
00817 break;
00818 case 2:
00819 gk_i32pqUpdate(queue, u, degrees[u]);
00820 break;
00821 case 3:
00822 for (k=0, jj=xadj[u]; jj<xadj[u+1]; jj++) {
00823 if (perm[adjncy[jj]] != -1)
00824 k += perm[adjncy[jj]];
00825 }
00826 gk_i32pqUpdate(queue, u, k);
00827 break;
00828 case 4:
00829
00830 for (k=0, jj=xadj[u]; jj<xadj[u+1]; jj++) {
00831 if (perm[adjncy[jj]] != -1)
00832 k += (i-perm[adjncy[jj]]);
00833 }
00834 gk_i32pqUpdate(queue, u, k);
00835 break;
00836 default:
00837 ;
00838 }
00839 }
00840 }
00841 }
00842
00843
00844
00845 if (r_perm != NULL) {
00846 *r_perm = perm;
00847 perm = NULL;
00848 }
00849
00850 if (r_iperm != NULL) {
00851
00852 for (i=0; i<nvtxs; i++)
00853 degrees[perm[i]] = i;
00854
00855 *r_iperm = degrees;
00856 degrees = NULL;
00857 }
00858
00859
00860
00861
00862 gk_i32pqDestroy(queue);
00863 gk_free((void **)&perm, °rees, &minIDs, &open, LTERM);
00864
00865 }
00866
00867
00868
00886
00887 void gk_graph_ComputeBestFOrdering(gk_graph_t *graph, int v, int type,
00888 int32_t **r_perm, int32_t **r_iperm)
00889 {
00890 ssize_t j, jj, *xadj;
00891 int i, k, u, nvtxs, nopen, ntodo;
00892 int32_t *adjncy, *perm, *degrees, *wdegrees, *sod, *level, *ot, *pos;
00893 gk_i32pq_t *queue;
00894
00895 if (graph->nvtxs <= 0)
00896 return;
00897
00898 nvtxs = graph->nvtxs;
00899 xadj = graph->xadj;
00900 adjncy = graph->adjncy;
00901
00902
00903 degrees = gk_i32smalloc(nvtxs, 0, "gk_graph_ComputeBestFOrdering: degrees");
00904
00905
00906 wdegrees = gk_i32smalloc(nvtxs, 0, "gk_graph_ComputeBestFOrdering: wdegrees");
00907
00908
00909 sod = gk_i32smalloc(nvtxs, 0, "gk_graph_ComputeBestFOrdering: sod");
00910
00911
00912 level = gk_i32smalloc(nvtxs, 0, "gk_graph_ComputeBestFOrdering: level");
00913
00914
00915
00916
00917
00918 ot = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_FindComponents: ot"));
00919
00920
00921 pos = gk_i32incset(nvtxs, 0, gk_i32malloc(nvtxs, "gk_graph_FindComponents: pos"));
00922
00923
00924 perm = gk_i32smalloc(nvtxs, -1, "gk_graph_ComputeBestFOrdering: perm");
00925
00926
00927 queue = gk_i32pqCreate(nvtxs);
00928 gk_i32pqInsert(queue, v, 1);
00929
00930
00931 pos[0] = ot[0] = v;
00932 pos[v] = ot[v] = 0;
00933 nopen = 1;
00934 ntodo = nvtxs;
00935
00936
00937 for (i=0; i<nvtxs; i++) {
00938 if (nopen == 0) {
00939 gk_i32pqInsert(queue, ot[0], 1);
00940 nopen++;
00941 }
00942
00943 if ((v = gk_i32pqGetTop(queue)) == -1)
00944 gk_errexit(SIGERR, "The priority queue got empty ahead of time [i=%d].\n", i);
00945
00946 if (perm[v] != -1)
00947 gk_errexit(SIGERR, "The perm[%d] has already been set.\n", v);
00948 perm[v] = i;
00949
00950 if (ot[pos[v]] != v)
00951 gk_errexit(SIGERR, "Something went wrong [ot[pos[%d]]!=%d.\n", v, v);
00952 if (pos[v] >= nopen)
00953 gk_errexit(SIGERR, "The position of v is not in open list. pos[%d]=%d is >=%d.\n", v, pos[v], nopen);
00954
00955
00956 ot[pos[v]] = ot[nopen-1];
00957 pos[ot[nopen-1]] = pos[v];
00958 if (ntodo > nopen) {
00959 ot[nopen-1] = ot[ntodo-1];
00960 pos[ot[ntodo-1]] = nopen-1;
00961 }
00962 nopen--;
00963 ntodo--;
00964
00965 for (j=xadj[v]; j<xadj[v+1]; j++) {
00966 u = adjncy[j];
00967 if (perm[u] == -1) {
00968
00969
00970 if (degrees[u] == 0) {
00971 ot[pos[u]] = ot[nopen];
00972 pos[ot[nopen]] = pos[u];
00973 ot[nopen] = u;
00974 pos[u] = nopen;
00975 nopen++;
00976
00977 level[u] = level[v]+1;
00978 gk_i32pqInsert(queue, u, 0);
00979 }
00980
00981
00982
00983 degrees[u]++;
00984
00985
00986 switch (type) {
00987 case 1:
00988 gk_i32pqUpdate(queue, u, 1000*(i+1)+degrees[u]);
00989 break;
00990
00991 case 2:
00992 gk_i32pqUpdate(queue, u, degrees[u]);
00993 break;
00994
00995 case 3:
00996 wdegrees[u] += i;
00997 gk_i32pqUpdate(queue, u, wdegrees[u]);
00998 break;
00999
01000 case 4:
01001
01002 ;
01003 break;
01004
01005 case 5:
01006 gk_i32pqUpdate(queue, u, -(1000*level[u] - degrees[u]));
01007 break;
01008
01009 case 6:
01010 gk_i32pqUpdate(queue, u, (i+1)*degrees[u]);
01011 break;
01012
01013 default:
01014 ;
01015 }
01016 }
01017 }
01018
01019 if (type == 4) {
01020 for (j=0; j<nopen; j++) {
01021 u = ot[j];
01022 if (perm[u] != -1)
01023 gk_errexit(SIGERR, "For i=%d, the open list contains a closed vertex: ot[%zd]=%d, perm[%d]=%d.\n", i, j, u, u, perm[u]);
01024 sod[u] += degrees[u];
01025 if (i<1000 || i%25==0)
01026 gk_i32pqUpdate(queue, u, sod[u]);
01027 }
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037 }
01038
01039
01040
01041 if (r_perm != NULL) {
01042 *r_perm = perm;
01043 perm = NULL;
01044 }
01045
01046 if (r_iperm != NULL) {
01047
01048 for (i=0; i<nvtxs; i++)
01049 degrees[perm[i]] = i;
01050
01051 *r_iperm = degrees;
01052 degrees = NULL;
01053 }
01054
01055
01056
01057
01058 gk_i32pqDestroy(queue);
01059 gk_free((void **)&perm, °rees, &wdegrees, &sod, &ot, &pos, &level, LTERM);
01060
01061 }
01062
01063
01064
01083
01084 void gk_graph_SingleSourceShortestPaths(gk_graph_t *graph, int v, void **r_sps)
01085 {
01086 ssize_t *xadj;
01087 int i, u, nvtxs;
01088 int32_t *adjncy, *inqueue;
01089
01090 if (graph->nvtxs <= 0)
01091 return;
01092
01093 nvtxs = graph->nvtxs;
01094 xadj = graph->xadj;
01095 adjncy = graph->adjncy;
01096
01097 inqueue = gk_i32smalloc(nvtxs, 0, "gk_graph_SingleSourceShortestPaths: inqueue");
01098
01099
01100 if (graph->iadjwgt != NULL) {
01101 gk_i32pq_t *queue;
01102 int32_t *adjwgt;
01103 int32_t *sps;
01104
01105 adjwgt = graph->iadjwgt;
01106
01107 queue = gk_i32pqCreate(nvtxs);
01108 gk_i32pqInsert(queue, v, 0);
01109 inqueue[v] = 1;
01110
01111 sps = gk_i32smalloc(nvtxs, -1, "gk_graph_SingleSourceShortestPaths: sps");
01112 sps[v] = 0;
01113
01114
01115 while ((v = gk_i32pqGetTop(queue)) != -1) {
01116 inqueue[v] = 2;
01117
01118
01119 for (i=xadj[v]; i<xadj[v+1]; i++) {
01120 u = adjncy[i];
01121 if (inqueue[u] == 2)
01122 continue;
01123
01124 if (sps[u] < 0 || sps[v]+adjwgt[i] < sps[u]) {
01125 sps[u] = sps[v]+adjwgt[i];
01126
01127 if (inqueue[u])
01128 gk_i32pqUpdate(queue, u, -sps[u]);
01129 else {
01130 gk_i32pqInsert(queue, u, -sps[u]);
01131 inqueue[u] = 1;
01132 }
01133 }
01134 }
01135 }
01136
01137 *r_sps = (void *)sps;
01138
01139 gk_i32pqDestroy(queue);
01140 }
01141 else {
01142 gk_fpq_t *queue;
01143 float *adjwgt;
01144 float *sps;
01145
01146 adjwgt = graph->fadjwgt;
01147
01148 queue = gk_fpqCreate(nvtxs);
01149 gk_fpqInsert(queue, v, 0);
01150 inqueue[v] = 1;
01151
01152 sps = gk_fsmalloc(nvtxs, -1, "gk_graph_SingleSourceShortestPaths: sps");
01153 sps[v] = 0;
01154
01155
01156 while ((v = gk_fpqGetTop(queue)) != -1) {
01157 inqueue[v] = 2;
01158
01159
01160 for (i=xadj[v]; i<xadj[v+1]; i++) {
01161 u = adjncy[i];
01162 if (inqueue[u] == 2)
01163 continue;
01164
01165 if (sps[u] < 0 || sps[v]+adjwgt[i] < sps[u]) {
01166 sps[u] = sps[v]+adjwgt[i];
01167
01168 if (inqueue[u])
01169 gk_fpqUpdate(queue, u, -sps[u]);
01170 else {
01171 gk_fpqInsert(queue, u, -sps[u]);
01172 inqueue[u] = 1;
01173 }
01174 }
01175 }
01176 }
01177
01178 *r_sps = (void *)sps;
01179
01180 gk_fpqDestroy(queue);
01181 }
01182
01183 gk_free((void **)&inqueue, LTERM);
01184
01185 }
01186
01187
01188
01189 #ifdef XXX
01190
01191
01195
01196 void gk_graph_SortAdjacencies(gk_graph_t *graph)
01197 {
01198 int n, nn=0;
01199 ssize_t *ptr;
01200 int *ind;
01201 float *val;
01202
01203 switch (what) {
01204 case GK_CSR_ROW:
01205 if (!graph->rowptr)
01206 gk_errexit(SIGERR, "Row-based view of the graphrix does not exists.\n");
01207
01208 n = graph->nrows;
01209 ptr = graph->rowptr;
01210 ind = graph->rowind;
01211 val = graph->rowval;
01212 break;
01213
01214 case GK_CSR_COL:
01215 if (!graph->colptr)
01216 gk_errexit(SIGERR, "Column-based view of the graphrix does not exists.\n");
01217
01218 n = graph->ncols;
01219 ptr = graph->colptr;
01220 ind = graph->colind;
01221 val = graph->colval;
01222 break;
01223
01224 default:
01225 gk_errexit(SIGERR, "Invalid index type of %d.\n", what);
01226 return;
01227 }
01228
01229 #pragma omp parallel if (n > 100)
01230 {
01231 ssize_t i, j, k;
01232 gk_ikv_t *cand;
01233 float *tval;
01234
01235 #pragma omp single
01236 for (i=0; i<n; i++)
01237 nn = gk_max(nn, ptr[i+1]-ptr[i]);
01238
01239 cand = gk_ikvmalloc(nn, "gk_graph_SortIndices: cand");
01240 tval = gk_fmalloc(nn, "gk_graph_SortIndices: tval");
01241
01242 #pragma omp for schedule(static)
01243 for (i=0; i<n; i++) {
01244 for (k=0, j=ptr[i]; j<ptr[i+1]; j++) {
01245 if (j > ptr[i] && ind[j] < ind[j-1])
01246 k = 1;
01247 cand[j-ptr[i]].val = j-ptr[i];
01248 cand[j-ptr[i]].key = ind[j];
01249 tval[j-ptr[i]] = val[j];
01250 }
01251 if (k) {
01252 gk_ikvsorti(ptr[i+1]-ptr[i], cand);
01253 for (j=ptr[i]; j<ptr[i+1]; j++) {
01254 ind[j] = cand[j-ptr[i]].key;
01255 val[j] = tval[cand[j-ptr[i]].val];
01256 }
01257 }
01258 }
01259
01260 gk_free((void **)&cand, &tval, LTERM);
01261 }
01262
01263 }
01264
01265
01266
01273
01274 gk_graph_t *gk_graph_ExtractRows(gk_graph_t *graph, int nrows, int *rind)
01275 {
01276 ssize_t i, ii, j, nnz;
01277 gk_graph_t *ngraph;
01278
01279 ngraph = gk_graph_Create();
01280
01281 ngraph->nrows = nrows;
01282 ngraph->ncols = graph->ncols;
01283
01284 for (nnz=0, i=0; i<nrows; i++)
01285 nnz += graph->rowptr[rind[i]+1]-graph->rowptr[rind[i]];
01286
01287 ngraph->rowptr = gk_zmalloc(ngraph->nrows+1, "gk_graph_ExtractPartition: rowptr");
01288 ngraph->rowind = gk_imalloc(nnz, "gk_graph_ExtractPartition: rowind");
01289 ngraph->rowval = gk_fmalloc(nnz, "gk_graph_ExtractPartition: rowval");
01290
01291 ngraph->rowptr[0] = 0;
01292 for (nnz=0, j=0, ii=0; ii<nrows; ii++) {
01293 i = rind[ii];
01294 gk_icopy(graph->rowptr[i+1]-graph->rowptr[i], graph->rowind+graph->rowptr[i], ngraph->rowind+nnz);
01295 gk_fcopy(graph->rowptr[i+1]-graph->rowptr[i], graph->rowval+graph->rowptr[i], ngraph->rowval+nnz);
01296 nnz += graph->rowptr[i+1]-graph->rowptr[i];
01297 ngraph->rowptr[++j] = nnz;
01298 }
01299 ASSERT(j == ngraph->nrows);
01300
01301 return ngraph;
01302 }
01303
01304
01305
01312
01313 gk_graph_t *gk_graph_ExtractPartition(gk_graph_t *graph, int *part, int pid)
01314 {
01315 ssize_t i, j, nnz;
01316 gk_graph_t *ngraph;
01317
01318 ngraph = gk_graph_Create();
01319
01320 ngraph->nrows = 0;
01321 ngraph->ncols = graph->ncols;
01322
01323 for (nnz=0, i=0; i<graph->nrows; i++) {
01324 if (part[i] == pid) {
01325 ngraph->nrows++;
01326 nnz += graph->rowptr[i+1]-graph->rowptr[i];
01327 }
01328 }
01329
01330 ngraph->rowptr = gk_zmalloc(ngraph->nrows+1, "gk_graph_ExtractPartition: rowptr");
01331 ngraph->rowind = gk_imalloc(nnz, "gk_graph_ExtractPartition: rowind");
01332 ngraph->rowval = gk_fmalloc(nnz, "gk_graph_ExtractPartition: rowval");
01333
01334 ngraph->rowptr[0] = 0;
01335 for (nnz=0, j=0, i=0; i<graph->nrows; i++) {
01336 if (part[i] == pid) {
01337 gk_icopy(graph->rowptr[i+1]-graph->rowptr[i], graph->rowind+graph->rowptr[i], ngraph->rowind+nnz);
01338 gk_fcopy(graph->rowptr[i+1]-graph->rowptr[i], graph->rowval+graph->rowptr[i], ngraph->rowval+nnz);
01339 nnz += graph->rowptr[i+1]-graph->rowptr[i];
01340 ngraph->rowptr[++j] = nnz;
01341 }
01342 }
01343 ASSERT(j == ngraph->nrows);
01344
01345 return ngraph;
01346 }
01347
01348
01349
01359
01360 gk_graph_t **gk_graph_Split(gk_graph_t *graph, int *color)
01361 {
01362 ssize_t i, j;
01363 int nrows, ncolors;
01364 ssize_t *rowptr;
01365 int *rowind;
01366 float *rowval;
01367 gk_graph_t **sgraphs;
01368
01369 nrows = graph->nrows;
01370 rowptr = graph->rowptr;
01371 rowind = graph->rowind;
01372 rowval = graph->rowval;
01373
01374 ncolors = gk_imax(rowptr[nrows], color)+1;
01375
01376 sgraphs = (gk_graph_t **)gk_malloc(sizeof(gk_graph_t *)*ncolors, "gk_graph_Split: sgraphs");
01377 for (i=0; i<ncolors; i++) {
01378 sgraphs[i] = gk_graph_Create();
01379 sgraphs[i]->nrows = graph->nrows;
01380 sgraphs[i]->ncols = graph->ncols;
01381 sgraphs[i]->rowptr = gk_zsmalloc(nrows+1, 0, "gk_graph_Split: sgraphs[i]->rowptr");
01382 }
01383
01384 for (i=0; i<nrows; i++) {
01385 for (j=rowptr[i]; j<rowptr[i+1]; j++)
01386 sgraphs[color[j]]->rowptr[i]++;
01387 }
01388 for (i=0; i<ncolors; i++)
01389 MAKECSR(j, nrows, sgraphs[i]->rowptr);
01390
01391 for (i=0; i<ncolors; i++) {
01392 sgraphs[i]->rowind = gk_imalloc(sgraphs[i]->rowptr[nrows], "gk_graph_Split: sgraphs[i]->rowind");
01393 sgraphs[i]->rowval = gk_fmalloc(sgraphs[i]->rowptr[nrows], "gk_graph_Split: sgraphs[i]->rowval");
01394 }
01395
01396 for (i=0; i<nrows; i++) {
01397 for (j=rowptr[i]; j<rowptr[i+1]; j++) {
01398 sgraphs[color[j]]->rowind[sgraphs[color[j]]->rowptr[i]] = rowind[j];
01399 sgraphs[color[j]]->rowval[sgraphs[color[j]]->rowptr[i]] = rowval[j];
01400 sgraphs[color[j]]->rowptr[i]++;
01401 }
01402 }
01403
01404 for (i=0; i<ncolors; i++)
01405 SHIFTCSR(j, nrows, sgraphs[i]->rowptr);
01406
01407 return sgraphs;
01408 }
01409
01410
01411
01427
01428 gk_graph_t *gk_graph_Prune(gk_graph_t *graph, int what, int minf, int maxf)
01429 {
01430 ssize_t i, j, nnz;
01431 int nrows, ncols;
01432 ssize_t *rowptr, *nrowptr;
01433 int *rowind, *nrowind, *collen;
01434 float *rowval, *nrowval;
01435 gk_graph_t *ngraph;
01436
01437 ngraph = gk_graph_Create();
01438
01439 nrows = ngraph->nrows = graph->nrows;
01440 ncols = ngraph->ncols = graph->ncols;
01441
01442 rowptr = graph->rowptr;
01443 rowind = graph->rowind;
01444 rowval = graph->rowval;
01445
01446 nrowptr = ngraph->rowptr = gk_zmalloc(nrows+1, "gk_graph_Prune: nrowptr");
01447 nrowind = ngraph->rowind = gk_imalloc(rowptr[nrows], "gk_graph_Prune: nrowind");
01448 nrowval = ngraph->rowval = gk_fmalloc(rowptr[nrows], "gk_graph_Prune: nrowval");
01449
01450
01451 switch (what) {
01452 case GK_CSR_COL:
01453 collen = gk_ismalloc(ncols, 0, "gk_graph_Prune: collen");
01454
01455 for (i=0; i<nrows; i++) {
01456 for (j=rowptr[i]; j<rowptr[i+1]; j++) {
01457 ASSERT(rowind[j] < ncols);
01458 collen[rowind[j]]++;
01459 }
01460 }
01461 for (i=0; i<ncols; i++)
01462 collen[i] = (collen[i] >= minf && collen[i] <= maxf ? 1 : 0);
01463
01464 nrowptr[0] = 0;
01465 for (nnz=0, i=0; i<nrows; i++) {
01466 for (j=rowptr[i]; j<rowptr[i+1]; j++) {
01467 if (collen[rowind[j]]) {
01468 nrowind[nnz] = rowind[j];
01469 nrowval[nnz] = rowval[j];
01470 nnz++;
01471 }
01472 }
01473 nrowptr[i+1] = nnz;
01474 }
01475 gk_free((void **)&collen, LTERM);
01476 break;
01477
01478 case GK_CSR_ROW:
01479 nrowptr[0] = 0;
01480 for (nnz=0, i=0; i<nrows; i++) {
01481 if (rowptr[i+1]-rowptr[i] >= minf && rowptr[i+1]-rowptr[i] <= maxf) {
01482 for (j=rowptr[i]; j<rowptr[i+1]; j++, nnz++) {
01483 nrowind[nnz] = rowind[j];
01484 nrowval[nnz] = rowval[j];
01485 }
01486 }
01487 nrowptr[i+1] = nnz;
01488 }
01489 break;
01490
01491 default:
01492 gk_graph_Free(&ngraph);
01493 gk_errexit(SIGERR, "Unknown prunning type of %d\n", what);
01494 return NULL;
01495 }
01496
01497 return ngraph;
01498 }
01499
01500
01501
01502
01510
01511 void gk_graph_Normalize(gk_graph_t *graph, int what, int norm)
01512 {
01513 ssize_t i, j;
01514 int n;
01515 ssize_t *ptr;
01516 float *val, sum;
01517
01518 if (what&GK_CSR_ROW && graph->rowval) {
01519 n = graph->nrows;
01520 ptr = graph->rowptr;
01521 val = graph->rowval;
01522
01523 #pragma omp parallel if (ptr[n] > OMPMINOPS)
01524 {
01525 #pragma omp for private(j,sum) schedule(static)
01526 for (i=0; i<n; i++) {
01527 for (sum=0.0, j=ptr[i]; j<ptr[i+1]; j++){
01528 if (norm == 2)
01529 sum += val[j]*val[j];
01530 else if (norm == 1)
01531 sum += val[j];
01532 }
01533 if (sum > 0) {
01534 if (norm == 2)
01535 sum=1.0/sqrt(sum);
01536 else if (norm == 1)
01537 sum=1.0/sum;
01538 for (j=ptr[i]; j<ptr[i+1]; j++)
01539 val[j] *= sum;
01540
01541 }
01542 }
01543 }
01544 }
01545
01546 if (what&GK_CSR_COL && graph->colval) {
01547 n = graph->ncols;
01548 ptr = graph->colptr;
01549 val = graph->colval;
01550
01551 #pragma omp parallel if (ptr[n] > OMPMINOPS)
01552 {
01553 #pragma omp for private(j,sum) schedule(static)
01554 for (i=0; i<n; i++) {
01555 for (sum=0.0, j=ptr[i]; j<ptr[i+1]; j++)
01556 if (norm == 2)
01557 sum += val[j]*val[j];
01558 else if (norm == 1)
01559 sum += val[j];
01560 if (sum > 0) {
01561 if (norm == 2)
01562 sum=1.0/sqrt(sum);
01563 else if (norm == 1)
01564 sum=1.0/sum;
01565 for (j=ptr[i]; j<ptr[i+1]; j++)
01566 val[j] *= sum;
01567 }
01568 }
01569 }
01570 }
01571 }
01572
01573
01574 #endif