00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "ilu_dh.h"
00046 #include "Mem_dh.h"
00047 #include "Parser_dh.h"
00048 #include "Euclid_dh.h"
00049 #include "getRow_dh.h"
00050 #include "Factor_dh.h"
00051 #include "SubdomainGraph_dh.h"
00052
00053 static bool check_constraint_private (Euclid_dh ctx, int b, int j);
00054
00055 static int symbolic_row_private (int localRow,
00056 int *list, int *marker, int *tmpFill,
00057 int len, int *CVAL, double *AVAL,
00058 int *o2n_col, Euclid_dh ctx, bool debug);
00059
00060 static int numeric_row_private (int localRow,
00061 int len, int *CVAL, double *AVAL,
00062 REAL_DH * work, int *o2n_col, Euclid_dh ctx,
00063 bool debug);
00064
00065
00066 #undef __FUNC__
00067 #define __FUNC__ "compute_scaling_private"
00068 void
00069 compute_scaling_private (int row, int len, double *AVAL, Euclid_dh ctx)
00070 {
00071 START_FUNC_DH double tmp = 0.0;
00072 int j;
00073
00074 for (j = 0; j < len; ++j)
00075 tmp = MAX (tmp, fabs (AVAL[j]));
00076 if (tmp)
00077 {
00078 ctx->scale[row] = 1.0 / tmp;
00079 }
00080 END_FUNC_DH}
00081
00082 #if 0
00083
00084
00085 #undef __FUNC__
00086 #define __FUNC__ "fixPivot_private"
00087 double
00088 fixPivot_private (int row, int len, float *vals)
00089 {
00090 START_FUNC_DH int i;
00091 float max = 0.0;
00092 bool debug = false;
00093
00094 for (i = 0; i < len; ++i)
00095 {
00096 float tmp = fabs (vals[i]);
00097 max = MAX (max, tmp);
00098 }
00099 END_FUNC_VAL (max * ctxPrivate->pivotFix)}
00100
00101 #endif
00102
00103
00104
00105
00106 #undef __FUNC__
00107 #define __FUNC__ "iluk_seq"
00108 void
00109 iluk_seq (Euclid_dh ctx)
00110 {
00111 START_FUNC_DH int *rp, *cval, *diag;
00112 int *CVAL;
00113 int i, j, len, count, col, idx = 0;
00114 int *list, *marker, *fill, *tmpFill;
00115 int temp, m, from = ctx->from, to = ctx->to;
00116 int *n2o_row, *o2n_col, beg_row, beg_rowP;
00117 double *AVAL;
00118 REAL_DH *work, *aval;
00119 Factor_dh F = ctx->F;
00120 SubdomainGraph_dh sg = ctx->sg;
00121 bool debug = false;
00122
00123 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00124 debug = true;
00125
00126 m = F->m;
00127 rp = F->rp;
00128 cval = F->cval;
00129 fill = F->fill;
00130 diag = F->diag;
00131 aval = F->aval;
00132 work = ctx->work;
00133 count = rp[from];
00134
00135 if (sg == NULL)
00136 {
00137 SET_V_ERROR ("subdomain graph is NULL");
00138 }
00139
00140 n2o_row = ctx->sg->n2o_row;
00141 o2n_col = ctx->sg->o2n_col;
00142 beg_row = ctx->sg->beg_row[myid_dh];
00143 beg_rowP = ctx->sg->beg_rowP[myid_dh];
00144
00145
00146 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00147 CHECK_V_ERROR;
00148 marker = (int *) MALLOC_DH (m * sizeof (int));
00149 CHECK_V_ERROR;
00150 tmpFill = (int *) MALLOC_DH (m * sizeof (int));
00151 CHECK_V_ERROR;
00152 for (i = 0; i < m; ++i)
00153 marker[i] = -1;
00154
00155
00156 for (i = 0; i < m; ++i)
00157 work[i] = 0.0;
00158
00159
00160
00161
00162
00163
00164
00165 for (i = from; i < to; ++i)
00166 {
00167 int row = n2o_row[i];
00168 int globalRow = row + beg_row;
00169
00170
00171
00172
00173 if (debug)
00174 {
00175 fprintf (logFile,
00176 "ILU_seq ================================= starting local row: %i, (global= %i) level= %i\n",
00177 i + 1, i + 1 + sg->beg_rowP[myid_dh], ctx->level);
00178 }
00179
00180 EuclidGetRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00181 CHECK_V_ERROR;
00182
00183
00184 if (ctx->isScaled)
00185 {
00186 compute_scaling_private (i, len, AVAL, ctx);
00187 CHECK_V_ERROR;
00188 }
00189
00190
00191
00192
00193 count = symbolic_row_private (i, list, marker, tmpFill,
00194 len, CVAL, AVAL, o2n_col, ctx, debug);
00195 CHECK_V_ERROR;
00196
00197
00198 if (idx + count > F->alloc)
00199 {
00200 Factor_dhReallocate (F, idx, count);
00201 CHECK_V_ERROR;
00202 SET_INFO ("REALLOCATED from ilu_seq");
00203 cval = F->cval;
00204 fill = F->fill;
00205 aval = F->aval;
00206 }
00207
00208
00209 col = list[m];
00210 while (count--)
00211 {
00212 cval[idx] = col;
00213 fill[idx] = tmpFill[col];
00214 ++idx;
00215
00216
00217 col = list[col];
00218 }
00219
00220
00221 rp[i + 1] = idx;
00222
00223
00224 temp = rp[i];
00225 while (cval[temp] != i)
00226 ++temp;
00227 diag[i] = temp;
00228
00229
00230
00231
00232
00233 numeric_row_private (i, len, CVAL, AVAL, work, o2n_col, ctx, debug);
00234 CHECK_V_ERROR EuclidRestoreRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00235 CHECK_V_ERROR;
00236
00237
00238
00239
00240 if (debug)
00241 {
00242 fprintf (logFile, "ILU_seq: ");
00243 for (j = rp[i]; j < rp[i + 1]; ++j)
00244 {
00245 col = cval[j];
00246 aval[j] = work[col];
00247 work[col] = 0.0;
00248 fprintf (logFile, "%i,%i,%g ; ", 1 + cval[j], fill[j], aval[j]);
00249 fflush (logFile);
00250 }
00251 fprintf (logFile, "\n");
00252 }
00253 else
00254 {
00255 for (j = rp[i]; j < rp[i + 1]; ++j)
00256 {
00257 col = cval[j];
00258 aval[j] = work[col];
00259 work[col] = 0.0;
00260 }
00261 }
00262
00263
00264 if (!aval[diag[i]])
00265 {
00266 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00267 SET_V_ERROR (msgBuf_dh);
00268 }
00269 }
00270
00271 FREE_DH (list);
00272 CHECK_V_ERROR;
00273 FREE_DH (tmpFill);
00274 CHECK_V_ERROR;
00275 FREE_DH (marker);
00276 CHECK_V_ERROR;
00277
00278
00279 if (beg_rowP)
00280 {
00281 int start = rp[from];
00282 int stop = rp[to];
00283 for (i = start; i < stop; ++i)
00284 cval[i] += beg_rowP;
00285 }
00286
00287
00288
00289
00290 for (i = to + 1; i < m; ++i)
00291 rp[i] = 0;
00292
00293 END_FUNC_DH}
00294
00295
00296 #undef __FUNC__
00297 #define __FUNC__ "iluk_seq_block"
00298 void
00299 iluk_seq_block (Euclid_dh ctx)
00300 {
00301 START_FUNC_DH int *rp, *cval, *diag;
00302 int *CVAL;
00303 int h, i, j, len, count, col, idx = 0;
00304 int *list, *marker, *fill, *tmpFill;
00305 int temp, m;
00306 int *n2o_row, *o2n_col, *beg_rowP, *n2o_sub, blocks;
00307 int *row_count, *dummy = NULL, dummy2[1];
00308 double *AVAL;
00309 REAL_DH *work, *aval;
00310 Factor_dh F = ctx->F;
00311 SubdomainGraph_dh sg = ctx->sg;
00312 bool bj = false, constrained = false;
00313 int discard = 0;
00314 int gr = -1;
00315 bool debug = false;
00316
00317 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00318 debug = true;
00319
00320
00321
00322
00323 if (!strcmp (ctx->algo_par, "bj"))
00324 bj = true;
00325 constrained = !Parser_dhHasSwitch (parser_dh, "-unconstrained");
00326
00327 m = F->m;
00328 rp = F->rp;
00329 cval = F->cval;
00330 fill = F->fill;
00331 diag = F->diag;
00332 aval = F->aval;
00333 work = ctx->work;
00334
00335 if (sg != NULL)
00336 {
00337 n2o_row = sg->n2o_row;
00338 o2n_col = sg->o2n_col;
00339 row_count = sg->row_count;
00340
00341 beg_rowP = sg->beg_rowP;
00342 n2o_sub = sg->n2o_sub;
00343 blocks = sg->blocks;
00344 }
00345
00346 else
00347 {
00348 dummy = (int *) MALLOC_DH (m * sizeof (int));
00349 CHECK_V_ERROR;
00350 for (i = 0; i < m; ++i)
00351 dummy[i] = i;
00352 n2o_row = dummy;
00353 o2n_col = dummy;
00354 dummy2[0] = m;
00355 row_count = dummy2;
00356
00357 beg_rowP = dummy;
00358 n2o_sub = dummy;
00359 blocks = 1;
00360 }
00361
00362
00363 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00364 CHECK_V_ERROR;
00365 marker = (int *) MALLOC_DH (m * sizeof (int));
00366 CHECK_V_ERROR;
00367 tmpFill = (int *) MALLOC_DH (m * sizeof (int));
00368 CHECK_V_ERROR;
00369 for (i = 0; i < m; ++i)
00370 marker[i] = -1;
00371
00372
00373 for (i = 0; i < m; ++i)
00374 work[i] = 0.0;
00375
00376
00377
00378 for (h = 0; h < blocks; ++h)
00379 {
00380
00381 int curBlock = n2o_sub[h];
00382 int first_row = beg_rowP[curBlock];
00383 int end_row = first_row + row_count[curBlock];
00384
00385 if (debug)
00386 {
00387 fprintf (logFile, "\n\nILU_seq BLOCK: %i @@@@@@@@@@@@@@@ \n",
00388 curBlock);
00389 }
00390
00391 for (i = first_row; i < end_row; ++i)
00392 {
00393 int row = n2o_row[i];
00394 ++gr;
00395
00396 if (debug)
00397 {
00398 fprintf (logFile,
00399 "ILU_seq global: %i local: %i =================================\n",
00400 1 + gr, 1 + i - first_row);
00401 }
00402
00403
00404
00405
00406 EuclidGetRow (ctx->A, row, &len, &CVAL, &AVAL);
00407 CHECK_V_ERROR;
00408
00409
00410 if (ctx->isScaled)
00411 {
00412 compute_scaling_private (i, len, AVAL, ctx);
00413 CHECK_V_ERROR;
00414 }
00415
00416
00417
00418
00419 count = symbolic_row_private (i, list, marker, tmpFill,
00420 len, CVAL, AVAL, o2n_col, ctx, debug);
00421 CHECK_V_ERROR;
00422
00423
00424 if (idx + count > F->alloc)
00425 {
00426 Factor_dhReallocate (F, idx, count);
00427 CHECK_V_ERROR;
00428 SET_INFO ("REALLOCATED from ilu_seq");
00429 cval = F->cval;
00430 fill = F->fill;
00431 aval = F->aval;
00432 }
00433
00434
00435 col = list[m];
00436 while (count--)
00437 {
00438
00439
00440 if (constrained && !bj)
00441 {
00442 if (col >= first_row && col < end_row)
00443 {
00444 cval[idx] = col;
00445 fill[idx] = tmpFill[col];
00446 ++idx;
00447 }
00448 else
00449 {
00450 if (check_constraint_private (ctx, curBlock, col))
00451 {
00452 cval[idx] = col;
00453 fill[idx] = tmpFill[col];
00454 ++idx;
00455 }
00456 else
00457 {
00458 ++discard;
00459 }
00460 }
00461 col = list[col];
00462 }
00463
00464
00465 else if (bj)
00466 {
00467 if (col >= first_row && col < end_row)
00468 {
00469 cval[idx] = col;
00470 fill[idx] = tmpFill[col];
00471 ++idx;
00472 }
00473 else
00474 {
00475 ++discard;
00476 }
00477 col = list[col];
00478 }
00479
00480
00481 else
00482 {
00483 cval[idx] = col;
00484 fill[idx] = tmpFill[col];
00485 ++idx;
00486 col = list[col];
00487 }
00488 }
00489
00490
00491 rp[i + 1] = idx;
00492
00493
00494 temp = rp[i];
00495 while (cval[temp] != i)
00496 ++temp;
00497 diag[i] = temp;
00498
00499
00500 numeric_row_private (i, len, CVAL, AVAL, work, o2n_col, ctx, debug);
00501 CHECK_V_ERROR EuclidRestoreRow (ctx->A, row, &len, &CVAL, &AVAL);
00502 CHECK_V_ERROR;
00503
00504
00505
00506
00507 if (debug)
00508 {
00509 fprintf (logFile, "ILU_seq: ");
00510 for (j = rp[i]; j < rp[i + 1]; ++j)
00511 {
00512 col = cval[j];
00513 aval[j] = work[col];
00514 work[col] = 0.0;
00515 fprintf (logFile, "%i,%i,%g ; ", 1 + cval[j], fill[j],
00516 aval[j]);
00517 }
00518 fprintf (logFile, "\n");
00519 }
00520
00521
00522 else
00523 {
00524 for (j = rp[i]; j < rp[i + 1]; ++j)
00525 {
00526 col = cval[j];
00527 aval[j] = work[col];
00528 work[col] = 0.0;
00529 }
00530 }
00531
00532
00533 if (!aval[diag[i]])
00534 {
00535 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00536 SET_V_ERROR (msgBuf_dh);
00537 }
00538 }
00539 }
00540
00541
00542
00543 if (dummy != NULL)
00544 {
00545 FREE_DH (dummy);
00546 CHECK_V_ERROR;
00547 }
00548 FREE_DH (list);
00549 CHECK_V_ERROR;
00550 FREE_DH (tmpFill);
00551 CHECK_V_ERROR;
00552 FREE_DH (marker);
00553 CHECK_V_ERROR;
00554
00555 END_FUNC_DH}
00556
00557
00558
00559
00560
00561
00562
00563
00564 #undef __FUNC__
00565 #define __FUNC__ "symbolic_row_private"
00566 int
00567 symbolic_row_private (int localRow,
00568 int *list, int *marker, int *tmpFill,
00569 int len, int *CVAL, double *AVAL,
00570 int *o2n_col, Euclid_dh ctx, bool debug)
00571 {
00572 START_FUNC_DH int level = ctx->level, m = ctx->F->m;
00573 int *cval = ctx->F->cval, *diag = ctx->F->diag, *rp = ctx->F->rp;
00574 int *fill = ctx->F->fill;
00575 int count = 0;
00576 int j, node, tmp, col, head;
00577 int fill1, fill2, beg_row;
00578 double val;
00579 double thresh = ctx->sparseTolA;
00580 REAL_DH scale;
00581
00582 scale = ctx->scale[localRow];
00583 ctx->stats[NZA_STATS] += (double) len;
00584 beg_row = ctx->sg->beg_row[myid_dh];
00585
00586
00587
00588
00589
00590 list[m] = m;
00591 for (j = 0; j < len; ++j)
00592 {
00593 tmp = m;
00594 col = *CVAL++;
00595 col -= beg_row;
00596 col = o2n_col[col];
00597 val = *AVAL++;
00598 val *= scale;
00599
00600 if (fabs (val) > thresh || col == localRow)
00601 {
00602 ++count;
00603 while (col > list[tmp])
00604 tmp = list[tmp];
00605 list[col] = list[tmp];
00606 list[tmp] = col;
00607 tmpFill[col] = 0;
00608 marker[col] = localRow;
00609 }
00610 }
00611
00612
00613 if (marker[localRow] != localRow)
00614 {
00615 tmp = m;
00616 while (localRow > list[tmp])
00617 tmp = list[tmp];
00618 list[localRow] = list[tmp];
00619 list[tmp] = localRow;
00620 tmpFill[localRow] = 0;
00621 marker[localRow] = localRow;
00622 ++count;
00623 }
00624 ctx->stats[NZA_USED_STATS] += (double) count;
00625
00626
00627 head = m;
00628 if (level > 0)
00629 {
00630 while (list[head] < localRow)
00631 {
00632 node = list[head];
00633 fill1 = tmpFill[node];
00634
00635 if (debug)
00636 {
00637 fprintf (logFile, "ILU_seq sf updating from row: %i\n",
00638 1 + node);
00639 }
00640
00641 if (fill1 < level)
00642 {
00643 for (j = diag[node] + 1; j < rp[node + 1]; ++j)
00644 {
00645 col = cval[j];
00646 fill2 = fill1 + fill[j] + 1;
00647
00648 if (fill2 <= level)
00649 {
00650
00651
00652
00653 if (marker[col] < localRow)
00654 {
00655 tmp = head;
00656 marker[col] = localRow;
00657 tmpFill[col] = fill2;
00658 while (col > list[tmp])
00659 tmp = list[tmp];
00660 list[col] = list[tmp];
00661 list[tmp] = col;
00662 ++count;
00663 }
00664
00665
00666 else
00667 {
00668 tmpFill[col] =
00669 (fill2 < tmpFill[col]) ? fill2 : tmpFill[col];
00670 }
00671 }
00672 }
00673 }
00674 head = list[head];
00675 }
00676 }
00677 END_FUNC_VAL (count)}
00678
00679
00680 #undef __FUNC__
00681 #define __FUNC__ "numeric_row_private"
00682 int
00683 numeric_row_private (int localRow,
00684 int len, int *CVAL, double *AVAL,
00685 REAL_DH * work, int *o2n_col, Euclid_dh ctx, bool debug)
00686 {
00687 START_FUNC_DH double pc, pv, multiplier;
00688 int j, k, col, row;
00689 int *rp = ctx->F->rp, *cval = ctx->F->cval;
00690 int *diag = ctx->F->diag;
00691 int beg_row;
00692 double val;
00693 REAL_DH *aval = ctx->F->aval, scale;
00694
00695 scale = ctx->scale[localRow];
00696 beg_row = ctx->sg->beg_row[myid_dh];
00697
00698
00699
00700 for (j = rp[localRow]; j < rp[localRow + 1]; ++j)
00701 {
00702 col = cval[j];
00703 work[col] = 0.0;
00704 }
00705
00706
00707
00708 for (j = 0; j < len; ++j)
00709 {
00710 col = *CVAL++;
00711 col -= beg_row;
00712 val = *AVAL++;
00713 col = o2n_col[col];
00714 work[col] = val * scale;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723 for (j = rp[localRow]; j < diag[localRow]; ++j)
00724 {
00725 row = cval[j];
00726 pc = work[row];
00727
00728
00729 pv = aval[diag[row]];
00730
00731
00732
00733
00734
00735
00736
00737 if (pc != 0.0 && pv != 0.0)
00738 {
00739 multiplier = pc / pv;
00740 work[row] = multiplier;
00741
00742 if (debug)
00743 {
00744 fprintf (logFile,
00745 "ILU_seq nf updating from row: %i; multiplier= %g\n",
00746 1 + row, multiplier);
00747 }
00748
00749 for (k = diag[row] + 1; k < rp[row + 1]; ++k)
00750 {
00751 col = cval[k];
00752 work[col] -= (multiplier * aval[k]);
00753 }
00754 }
00755 else
00756 {
00757 if (debug)
00758 {
00759 fprintf (logFile,
00760 "ILU_seq nf NO UPDATE from row %i; pc = %g; pv = %g\n",
00761 1 + row, pc, pv);
00762 }
00763 }
00764 }
00765
00766
00767 #if 0
00768 if (fabs (work[i]) <= pivotTol)
00769 {
00770
00771 aval[diag[i]] = pivotFix;
00772 }
00773 #endif
00774
00775 END_FUNC_VAL (0)}
00776
00777
00778
00779
00780
00781 int ilut_row_private (int localRow, int *list, int *o2n_col, int *marker,
00782 int len, int *CVAL, double *AVAL,
00783 REAL_DH * work, Euclid_dh ctx, bool debug);
00784
00785 #undef __FUNC__
00786 #define __FUNC__ "ilut_seq"
00787 void
00788 ilut_seq (Euclid_dh ctx)
00789 {
00790 START_FUNC_DH int *rp, *cval, *diag, *CVAL;
00791 int i, len, count, col, idx = 0;
00792 int *list, *marker;
00793 int temp, m, from, to;
00794 int *n2o_row, *o2n_col, beg_row, beg_rowP;
00795 double *AVAL, droptol;
00796 REAL_DH *work, *aval, val;
00797 Factor_dh F = ctx->F;
00798 SubdomainGraph_dh sg = ctx->sg;
00799 bool debug = false;
00800
00801 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00802 debug = true;
00803
00804 m = F->m;
00805 rp = F->rp;
00806 cval = F->cval;
00807 diag = F->diag;
00808 aval = F->aval;
00809 work = ctx->work;
00810 from = ctx->from;
00811 to = ctx->to;
00812 count = rp[from];
00813 droptol = ctx->droptol;
00814
00815 if (sg == NULL)
00816 {
00817 SET_V_ERROR ("subdomain graph is NULL");
00818 }
00819
00820 n2o_row = ctx->sg->n2o_row;
00821 o2n_col = ctx->sg->o2n_col;
00822 beg_row = ctx->sg->beg_row[myid_dh];
00823 beg_rowP = ctx->sg->beg_rowP[myid_dh];
00824
00825
00826
00827 list = (int *) MALLOC_DH ((m + 1) * sizeof (int));
00828 CHECK_V_ERROR;
00829 marker = (int *) MALLOC_DH (m * sizeof (int));
00830 CHECK_V_ERROR;
00831 for (i = 0; i < m; ++i)
00832 marker[i] = -1;
00833 rp[0] = 0;
00834
00835
00836 for (i = 0; i < m; ++i)
00837 work[i] = 0.0;
00838
00839
00840 for (i = from; i < to; ++i)
00841 {
00842 int row = n2o_row[i];
00843 int globalRow = row + beg_row;
00844 EuclidGetRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00845 CHECK_V_ERROR;
00846
00847
00848 compute_scaling_private (i, len, AVAL, ctx);
00849 CHECK_V_ERROR;
00850
00851
00852 count = ilut_row_private (i, list, o2n_col, marker,
00853 len, CVAL, AVAL, work, ctx, debug);
00854 CHECK_V_ERROR;
00855
00856 EuclidRestoreRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00857 CHECK_V_ERROR;
00858
00859
00860 if (idx + count > F->alloc)
00861 {
00862 Factor_dhReallocate (F, idx, count);
00863 CHECK_V_ERROR;
00864 SET_INFO ("REALLOCATED from ilu_seq");
00865 cval = F->cval;
00866 aval = F->aval;
00867 }
00868
00869
00870
00871
00872
00873 col = list[m];
00874 while (count--)
00875 {
00876 val = work[col];
00877 if (col == i || fabs (val) > droptol)
00878 {
00879 cval[idx] = col;
00880 aval[idx++] = val;
00881 work[col] = 0.0;
00882 }
00883 col = list[col];
00884 }
00885
00886
00887 rp[i + 1] = idx;
00888
00889
00890 temp = rp[i];
00891 while (cval[temp] != i)
00892 ++temp;
00893 diag[i] = temp;
00894
00895
00896 if (!aval[diag[i]])
00897 {
00898 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00899 SET_V_ERROR (msgBuf_dh);
00900 }
00901 }
00902
00903
00904 if (beg_rowP)
00905 {
00906 int start = rp[from];
00907 int stop = rp[to];
00908 for (i = start; i < stop; ++i)
00909 cval[i] += beg_rowP;
00910 }
00911
00912 FREE_DH (list);
00913 FREE_DH (marker);
00914 END_FUNC_DH}
00915
00916
00917 #undef __FUNC__
00918 #define __FUNC__ "ilut_row_private"
00919 int
00920 ilut_row_private (int localRow, int *list, int *o2n_col, int *marker,
00921 int len, int *CVAL, double *AVAL,
00922 REAL_DH * work, Euclid_dh ctx, bool debug)
00923 {
00924 START_FUNC_DH Factor_dh F = ctx->F;
00925 int j, col, m = ctx->m, *rp = F->rp, *cval = F->cval;
00926 int tmp, *diag = F->diag;
00927 int head;
00928 int count = 0, beg_row;
00929 double val;
00930 double mult, *aval = F->aval;
00931 double scale, pv, pc;
00932 double droptol = ctx->droptol;
00933 double thresh = ctx->sparseTolA;
00934
00935 scale = ctx->scale[localRow];
00936 ctx->stats[NZA_STATS] += (double) len;
00937 beg_row = ctx->sg->beg_row[myid_dh];
00938
00939
00940
00941
00942
00943
00944 list[m] = m;
00945 for (j = 0; j < len; ++j)
00946 {
00947 tmp = m;
00948 col = *CVAL++;
00949 col -= beg_row;
00950 col = o2n_col[col];
00951 val = *AVAL++;
00952 val *= scale;
00953
00954 if (fabs (val) > thresh || col == localRow)
00955 {
00956 ++count;
00957 while (col > list[tmp])
00958 tmp = list[tmp];
00959 list[col] = list[tmp];
00960 list[tmp] = col;
00961 work[col] = val;
00962 marker[col] = localRow;
00963 }
00964 }
00965
00966
00967 if (marker[localRow] != localRow)
00968 {
00969 tmp = m;
00970 while (localRow > list[tmp])
00971 tmp = list[tmp];
00972 list[localRow] = list[tmp];
00973 list[tmp] = localRow;
00974 marker[localRow] = localRow;
00975 ++count;
00976 }
00977
00978
00979 head = m;
00980 while (list[head] < localRow)
00981 {
00982 int row = list[head];
00983
00984
00985 pc = work[row];
00986 if (pc != 0.0)
00987 {
00988 pv = aval[diag[row]];
00989 mult = pc / pv;
00990
00991
00992 if (fabs (mult) > droptol)
00993 {
00994 work[row] = mult;
00995
00996 for (j = diag[row] + 1; j < rp[row + 1]; ++j)
00997 {
00998 col = cval[j];
00999 work[col] -= (mult * aval[j]);
01000
01001
01002 if (marker[col] < localRow)
01003 {
01004 marker[col] = localRow;
01005 tmp = head;
01006 while (col > list[tmp])
01007 tmp = list[tmp];
01008 list[col] = list[tmp];
01009 list[tmp] = col;
01010 ++count;
01011 }
01012 }
01013 }
01014 }
01015 head = list[head];
01016 }
01017
01018 END_FUNC_VAL (count)}
01019
01020
01021 #undef __FUNC__
01022 #define __FUNC__ "check_constraint_private"
01023 bool
01024 check_constraint_private (Euclid_dh ctx, int p1, int j)
01025 {
01026 START_FUNC_DH bool retval = false;
01027 int i, p2;
01028 int *nabors, count;
01029 SubdomainGraph_dh sg = ctx->sg;
01030
01031 if (sg == NULL)
01032 {
01033 SET_ERROR (-1, "ctx->sg == NULL");
01034 }
01035
01036 p2 = SubdomainGraph_dhFindOwner (ctx->sg, j, true);
01037
01038
01039 nabors = sg->adj + sg->ptrs[p1];
01040 count = sg->ptrs[p1 + 1] - sg->ptrs[p1];
01041
01042
01043
01044
01045
01046
01047
01048 for (i = 0; i < count; ++i)
01049 {
01050
01051
01052 if (nabors[i] == p2)
01053 {
01054 retval = true;
01055 break;
01056 }
01057 }
01058
01059 END_FUNC_VAL (retval)}