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 #include "Euclid_dh.h"
00044 #include "Factor_dh.h"
00045 #include "Mat_dh.h"
00046 #include "ilu_dh.h"
00047 #include "Mem_dh.h"
00048 #include "Parser_dh.h"
00049 #include "Hash_dh.h"
00050 #include "getRow_dh.h"
00051 #include "SortedList_dh.h"
00052 #include "ExternalRows_dh.h"
00053 #include "SubdomainGraph_dh.h"
00054
00055
00056 static void iluk_symbolic_row_private (int localRow, int len, int *CVAL,
00057 double *AVAL, ExternalRows_dh extRows,
00058 SortedList_dh sList, Euclid_dh ctx,
00059 bool debug);
00060
00061 static void iluk_numeric_row_private (int new_row, ExternalRows_dh extRows,
00062 SortedList_dh slist, Euclid_dh ctx,
00063 bool debug);
00064
00065 #undef __FUNC__
00066 #define __FUNC__ "iluk_mpi_pilu"
00067 void
00068 iluk_mpi_pilu (Euclid_dh ctx)
00069 {
00070 START_FUNC_DH int from = ctx->from, to = ctx->to;
00071 int i, m;
00072 int *n2o_row;
00073 int *rp, *cval, *diag, *fill;
00074 int beg_row, beg_rowP, end_rowP;
00075 SubdomainGraph_dh sg = ctx->sg;
00076 int *CVAL, len, idx = 0, count;
00077 double *AVAL;
00078 REAL_DH *aval;
00079 Factor_dh F = ctx->F;
00080 SortedList_dh slist = ctx->slist;
00081 ExternalRows_dh extRows = ctx->extRows;
00082 bool bj, noValues, debug = false;
00083
00084
00085 if (logFile != NULL && Parser_dhHasSwitch (parser_dh, "-debug_ilu"))
00086 debug = true;
00087 noValues = Parser_dhHasSwitch (parser_dh, "-noValues");
00088 bj = ctx->F->blockJacobi;
00089
00090 m = F->m;
00091 rp = F->rp;
00092 cval = F->cval;
00093 fill = F->fill;
00094 diag = F->diag;
00095 aval = F->aval;
00096
00097
00098 n2o_row = sg->n2o_row;
00099
00100
00101 if (from != 0)
00102 idx = rp[from];
00103
00104
00105
00106
00107 beg_row = sg->beg_row[myid_dh];
00108
00109
00110
00111 beg_rowP = sg->beg_rowP[myid_dh];
00112 end_rowP = beg_rowP + sg->row_count[myid_dh];
00113
00114
00115
00116 for (i = from; i < to; ++i)
00117 {
00118
00119 int row = n2o_row[i];
00120 int globalRow = row + beg_row;
00121
00122 if (debug)
00123 {
00124 fprintf (logFile,
00125 "\nILU_pilu global: %i old_Local: %i =========================================================\n",
00126 i + 1 + beg_rowP, row + 1);
00127 }
00128
00129 EuclidGetRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00130 CHECK_V_ERROR;
00131
00132 if (debug)
00133 {
00134 int h;
00135 fprintf (logFile, "ILU_pilu EuclidGetRow:\n");
00136 for (h = 0; h < len; ++h)
00137 fprintf (logFile, " %i %g\n", 1 + CVAL[h], AVAL[h]);
00138 }
00139
00140
00141
00142 if (ctx->isScaled)
00143 {
00144 compute_scaling_private (i, len, AVAL, ctx);
00145 CHECK_V_ERROR;
00146 }
00147
00148 SortedList_dhReset (slist, i);
00149 CHECK_V_ERROR;
00150
00151
00152
00153
00154 iluk_symbolic_row_private (i, len, CVAL, AVAL,
00155 extRows, slist, ctx, debug);
00156 CHECK_V_ERROR;
00157
00158
00159 SortedList_dhEnforceConstraint (slist, sg);
00160
00161
00162 if (!noValues)
00163 {
00164 iluk_numeric_row_private (i, extRows, slist, ctx, debug);
00165 CHECK_V_ERROR;
00166 }
00167
00168 EuclidRestoreRow (ctx->A, globalRow, &len, &CVAL, &AVAL);
00169 CHECK_V_ERROR;
00170
00171
00172 count = SortedList_dhReadCount (slist);
00173 CHECK_V_ERROR;
00174
00175
00176 if (idx + count > F->alloc)
00177 {
00178 Factor_dhReallocate (F, idx, count);
00179 CHECK_V_ERROR;
00180 SET_INFO ("REALLOCATED from ilu_mpi_pilu");
00181 cval = F->cval;
00182 fill = F->fill;
00183 aval = F->aval;
00184 }
00185
00186
00187 if (bj)
00188 {
00189 int col;
00190 while (count--)
00191 {
00192 SRecord *sr = SortedList_dhGetSmallest (slist);
00193 CHECK_V_ERROR;
00194 col = sr->col;
00195 if (col >= beg_rowP && col < end_rowP)
00196 {
00197 cval[idx] = col;
00198 if (noValues)
00199 {
00200 aval[idx] = 0.0;
00201 }
00202 else
00203 {
00204 aval[idx] = sr->val;
00205 }
00206 fill[idx] = sr->level;
00207 ++idx;
00208 }
00209 }
00210 }
00211
00212 if (debug)
00213 {
00214 fprintf (logFile, "ILU_pilu ");
00215 while (count--)
00216 {
00217 SRecord *sr = SortedList_dhGetSmallest (slist);
00218 CHECK_V_ERROR;
00219 cval[idx] = sr->col;
00220 aval[idx] = sr->val;
00221 fill[idx] = sr->level;
00222 fprintf (logFile, "%i,%i,%g ; ", 1 + cval[idx], fill[idx],
00223 aval[idx]);
00224 ++idx;
00225 }
00226 fprintf (logFile, "\n");
00227 }
00228
00229 else
00230 {
00231 while (count--)
00232 {
00233 SRecord *sr = SortedList_dhGetSmallest (slist);
00234 CHECK_V_ERROR;
00235 cval[idx] = sr->col;
00236 aval[idx] = sr->val;
00237 fill[idx] = sr->level;
00238 ++idx;
00239 }
00240 }
00241
00242
00243 rp[i + 1] = idx;
00244
00245
00246 {
00247 int temp = rp[i];
00248 bool flag = true;
00249 while (temp < idx)
00250 {
00251 if (cval[temp] == i + beg_rowP)
00252 {
00253 diag[i] = temp;
00254 flag = false;
00255 break;
00256 }
00257 ++temp;
00258 }
00259 if (flag)
00260 {
00261 if (logFile != NULL)
00262 {
00263 int k;
00264 fprintf (logFile,
00265 "Failed to find diag in localRow %i (globalRow %i; ct= %i)\n ",
00266 1 + i, i + 1 + beg_rowP, rp[i + 1] - rp[i]);
00267 for (k = rp[i]; k < rp[i + 1]; ++k)
00268 {
00269 fprintf (logFile, "%i ", cval[i] + 1);
00270 }
00271 fprintf (logFile, "\n\n");
00272 }
00273 sprintf (msgBuf_dh, "failed to find diagonal for localRow: %i",
00274 1 + i);
00275 SET_V_ERROR (msgBuf_dh);
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286 if (!aval[diag[i]])
00287 {
00288 sprintf (msgBuf_dh, "zero diagonal in local row %i", i + 1);
00289 SET_V_ERROR (msgBuf_dh);
00290 }
00291
00292 }
00293
00294
00295 if (bj)
00296 {
00297 int nz = rp[m];
00298 for (i = 0; i < nz; ++i)
00299 cval[i] -= beg_rowP;
00300 }
00301
00302 END_FUNC_DH}
00303
00304
00305 #undef __FUNC__
00306 #define __FUNC__ "iluk_symbolic_row_private"
00307 void
00308 iluk_symbolic_row_private (int localRow, int len, int *CVAL,
00309 double *AVAL, ExternalRows_dh extRows,
00310 SortedList_dh slist, Euclid_dh ctx, bool debug)
00311 {
00312 START_FUNC_DH int level = ctx->level, m = ctx->m;
00313 int beg_row = ctx->sg->beg_row[myid_dh];
00314 int beg_rowP = ctx->sg->beg_rowP[myid_dh];
00315 int *cval = ctx->F->cval, *diag = ctx->F->diag;
00316 int *rp = ctx->F->rp, *fill = ctx->F->fill;
00317 int j, node, col;
00318 int end_rowP = beg_rowP + m;
00319 int level_1, level_2;
00320 int *cvalPtr, *fillPtr;
00321 SRecord sr, *srPtr;
00322 REAL_DH scale, *avalPtr;
00323 double thresh = ctx->sparseTolA;
00324 bool wasInserted;
00325 int count = 0;
00326
00327 scale = ctx->scale[localRow];
00328 ctx->stats[NZA_STATS] += (double) len;
00329
00330
00331 sr.level = 0;
00332 for (j = 0; j < len; ++j)
00333 {
00334 sr.col = CVAL[j];
00335 sr.val = scale * AVAL[j];
00336
00337 wasInserted = SortedList_dhPermuteAndInsert (slist, &sr, thresh);
00338 CHECK_V_ERROR;
00339 if (wasInserted)
00340 ++count;
00341
00342 if (debug)
00343 {
00344 fprintf (logFile, "ILU_pilu inserted from A: col= %i val= %g\n",
00345 1 + CVAL[j], sr.val);
00346 }
00347 }
00348
00349
00350 sr.val = 0.0;
00351 sr.col = localRow + beg_rowP;
00352 srPtr = SortedList_dhFind (slist, &sr);
00353 CHECK_V_ERROR;
00354 if (srPtr == NULL)
00355 {
00356 SortedList_dhInsert (slist, &sr);
00357 CHECK_V_ERROR;
00358 ++count;
00359 if (debug)
00360 {
00361 fprintf (logFile, "ILU_pilu inserted missing diagonal: %i\n",
00362 1 + localRow + beg_row);
00363 }
00364 }
00365 ctx->stats[NZA_USED_STATS] += (double) count;
00366
00367
00368 sr.val = 0.0;
00369 if (level > 0)
00370 {
00371 while (1)
00372 {
00373 srPtr = SortedList_dhGetSmallestLowerTri (slist);
00374 CHECK_V_ERROR;
00375 if (srPtr == NULL)
00376 break;
00377
00378 node = srPtr->col;
00379
00380 if (debug)
00381 {
00382 fprintf (logFile, "ILU_pilu sf updating from row: %i\n",
00383 1 + srPtr->col);
00384 }
00385
00386 level_1 = srPtr->level;
00387 if (level_1 < level)
00388 {
00389
00390
00391 if (node >= beg_rowP && node < end_rowP)
00392 {
00393 node -= beg_rowP;
00394 len = rp[node + 1] - diag[node] - 1;
00395 cvalPtr = cval + diag[node] + 1;
00396 fillPtr = fill + diag[node] + 1;
00397 }
00398
00399
00400 else
00401 {
00402 len = 0;
00403 ExternalRows_dhGetRow (extRows, node, &len, &cvalPtr,
00404 &fillPtr, &avalPtr);
00405 CHECK_V_ERROR;
00406 if (debug && len == 0)
00407 {
00408 fprintf (stderr,
00409 "ILU_pilu sf failed to get extern row: %i\n",
00410 1 + node);
00411 }
00412 }
00413
00414
00415
00416 for (j = 0; j < len; ++j)
00417 {
00418 col = *cvalPtr++;
00419 level_2 = 1 + level_1 + *fillPtr++;
00420 if (level_2 <= level)
00421 {
00422
00423 sr.col = col;
00424 sr.level = level_2;
00425 sr.val = 0.0;
00426 SortedList_dhInsertOrUpdate (slist, &sr);
00427 CHECK_V_ERROR;
00428 }
00429 }
00430 }
00431 }
00432 }
00433 END_FUNC_DH}
00434
00435
00436 #undef __FUNC__
00437 #define __FUNC__ "iluk_numeric_row_private"
00438 void
00439 iluk_numeric_row_private (int new_row, ExternalRows_dh extRows,
00440 SortedList_dh slist, Euclid_dh ctx, bool debug)
00441 {
00442 START_FUNC_DH int m = ctx->m;
00443 int beg_rowP = ctx->sg->beg_rowP[myid_dh];
00444 int end_rowP = beg_rowP + m;
00445 int len, row;
00446 int *rp = ctx->F->rp, *cval = ctx->F->cval, *diag = ctx->F->diag;
00447 REAL_DH *avalPtr, *aval = ctx->F->aval;
00448 int *cvalPtr;
00449 double multiplier, pc, pv;
00450 SRecord sr, *srPtr;
00451
00452
00453
00454 SortedList_dhResetGetSmallest (slist);
00455 CHECK_V_ERROR;
00456 while (1)
00457 {
00458 srPtr = SortedList_dhGetSmallestLowerTri (slist);
00459 CHECK_V_ERROR;
00460 if (srPtr == NULL)
00461 break;
00462
00463
00464
00465
00466 row = srPtr->col;
00467
00468 if (row >= beg_rowP && row < end_rowP)
00469 {
00470 int local_row = row - beg_rowP;
00471
00472 len = rp[local_row + 1] - diag[local_row];
00473 cvalPtr = cval + diag[local_row];
00474 avalPtr = aval + diag[local_row];
00475 }
00476 else
00477 {
00478 len = 0;
00479 ExternalRows_dhGetRow (extRows, row, &len, &cvalPtr,
00480 NULL, &avalPtr);
00481 CHECK_V_ERROR;
00482 if (debug && len == 0)
00483 {
00484 fprintf (stderr, "ILU_pilu failed to get extern row: %i\n",
00485 1 + row);
00486 }
00487
00488 }
00489
00490 if (len)
00491 {
00492
00493 sr.col = row;
00494 srPtr = SortedList_dhFind (slist, &sr);
00495 CHECK_V_ERROR;
00496 if (srPtr == NULL)
00497 {
00498 sprintf (msgBuf_dh,
00499 "find failed for sr.col = %i while factoring local row= %i \n",
00500 1 + sr.col, new_row + 1);
00501 SET_V_ERROR (msgBuf_dh);
00502 }
00503
00504 pc = srPtr->val;
00505
00506 if (pc != 0.0)
00507 {
00508 pv = *avalPtr++;
00509 --len;
00510 ++cvalPtr;
00511 multiplier = pc / pv;
00512 srPtr->val = multiplier;
00513
00514 if (debug)
00515 {
00516 fprintf (logFile,
00517 "ILU_pilu nf updating from row: %i; multiplier = %g\n",
00518 1 + srPtr->col, multiplier);
00519 }
00520
00521
00522 while (len--)
00523 {
00524 sr.col = *cvalPtr++;
00525 sr.val = *avalPtr++;
00526 srPtr = SortedList_dhFind (slist, &sr);
00527 CHECK_V_ERROR;
00528 if (srPtr != NULL)
00529 {
00530 srPtr->val -= (multiplier * sr.val);
00531 }
00532 }
00533 }
00534
00535 else
00536 {
00537 if (debug)
00538 {
00539 fprintf (logFile,
00540 "ILU_pilu NO UPDATE from row: %i; srPtr->val = 0.0\n",
00541 1 + srPtr->col);
00542 }
00543 }
00544
00545 }
00546 }
00547 END_FUNC_DH}