Skip to content

Commit

Permalink
initial linear solver logging updates
Browse files Browse the repository at this point in the history
  • Loading branch information
gardner48 committed Jun 22, 2024
1 parent a0aeb9c commit 532b546
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 23 deletions.
56 changes: 38 additions & 18 deletions src/cvode/cvode_ls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1646,10 +1646,9 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
sunrealtype bnorm = ZERO;
sunrealtype deltar, delta, w_mean;
int curiter, nli_inc, retval;
#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG
sunrealtype resnorm;
long int nps_inc;
#endif

/* only used with logging */
SUNDIALS_MAYBE_UNUSED long int nps_inc;

/* access CVLsMem structure */
if (cv_mem->cv_lmem == NULL)
Expand All @@ -1670,16 +1669,31 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
{
deltar = cvls_mem->eplifac * cv_mem->cv_tq[4];
bnorm = N_VWrmsNorm(b, weight);

SUNLogInfo(CV_LOGGER, __func__, "begin-linear-solve",
"iterative = 1, b-norm = %.16g, b-tol = %.16g, res-tol = %.16g",
bnorm, deltar, deltar * cvls_mem->nrmfac);

if (bnorm <= deltar)
{
if (curiter > 0) { N_VConst(ZERO, b); }
cvls_mem->last_flag = CVLS_SUCCESS;

SUNLogInfo(CV_LOGGER, __func__, "end-linear-solve",
"status = success small rhs", "");

return (cvls_mem->last_flag);
}
/* Adjust tolerance for 2-norm */
delta = deltar * cvls_mem->nrmfac;
}
else { delta = ZERO; }
else
{
delta = ZERO;

SUNLogInfo(CV_LOGGER, __func__, "begin-linear-solve",
"iterative = 0", "");
}

/* Set vectors ycur and fcur for use by the Atimes and Psolve
interface routines */
Expand All @@ -1695,6 +1709,10 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
cvProcessError(cv_mem, CVLS_SUNLS_FAIL, __LINE__, __func__, __FILE__,
"Error in calling SUNLinSolSetScalingVectors");
cvls_mem->last_flag = CVLS_SUNLS_FAIL;

SUNLogInfo(CV_LOGGER, __func__, "end-linear-solve",
"status = failed set scaling vectors", "");

return (cvls_mem->last_flag);
}

Expand Down Expand Up @@ -1725,12 +1743,15 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,

/* Set zero initial guess flag */
retval = SUNLinSolSetZeroGuess(cvls_mem->LS, SUNTRUE);
if (retval != SUN_SUCCESS) { return (-1); }
if (retval != SUN_SUCCESS)
{
SUNLogInfo(CV_LOGGER, __func__, "end-linear-solve",
"status = failed set zero guess", "");
return (-1);
}

#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG
/* Store previous nps value in nps_inc */
nps_inc = cvls_mem->nps;
#endif

/* If a user-provided jtsetup routine is supplied, call that here */
if (cvls_mem->jtsetup)
Expand All @@ -1742,6 +1763,9 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
{
cvProcessError(cv_mem, retval, __LINE__, __func__, __FILE__,
MSG_LS_JTSETUP_FAILED);

SUNLogInfo(CV_LOGGER, __func__, "end-linear-solve",
"status = failed J-times setup", "");
return (cvls_mem->last_flag);
}
}
Expand All @@ -1758,15 +1782,9 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
}

/* Retrieve statistics from iterative linear solvers */
#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG
resnorm = ZERO;
#endif
nli_inc = 0;
if (cvls_mem->iterative)
{
#if SUNDIALS_LOGGING_LEVEL >= SUNDIALS_LOGGING_DEBUG
if (cvls_mem->LS->ops->resnorm) resnorm = SUNLinSolResNorm(cvls_mem->LS);
#endif
if (cvls_mem->LS->ops->numiters)
{
nli_inc = SUNLinSolNumIters(cvls_mem->LS);
Expand All @@ -1780,10 +1798,12 @@ int cvLsSolve(CVodeMem cv_mem, N_Vector b, N_Vector weight, N_Vector ynow,
/* Interpret solver return value */
cvls_mem->last_flag = retval;

SUNLogDebug(CV_LOGGER, __func__, "ls-stats",
"bnorm = %" RSYM ", resnorm = %" RSYM
", ls_iters = %i, prec_solves = %i",
bnorm, resnorm, nli_inc, (int)(cvls_mem->nps - nps_inc));
SUNLogInfoIf(retval == SUN_SUCCESS, CV_LOGGER, __func__, "end-linear-solve",
"status = success, iters = %i, p-solves = %i",
nli_inc, (int)(cvls_mem->nps - nps_inc));
SUNLogInfoIf(retval != SUN_SUCCESS, CV_LOGGER, __func__, "end-linear-solve",
"status = failed, retval = %i, iters = %i, p-solves = %i", retval,
nli_inc, (int)(cvls_mem->nps - nps_inc));

switch (retval)
{
Expand Down
75 changes: 70 additions & 5 deletions src/sunlinsol/spgmr/sunlinsol_spgmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
/* If preconditioning, check if psolve has been set */
SUNAssert(!(preOnLeft || preOnRight) || psolve, SUN_ERR_ARG_CORRUPT);

SUNLogInfo(S->sunctx->logger, __func__, "begin-linear-iterate", "", "");

/* Set vtemp and V[0] to initial (unscaled) residual r_0 = b - A*x_0 */
if (*zeroguess)
{
Expand All @@ -424,6 +426,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_ATIMES_FAIL_UNREC
: SUNLS_ATIMES_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed matvec", "");

return (LASTFLAG(S));
}
N_VLinearSum(ONE, b, -ONE, vtemp, vtemp);
Expand All @@ -441,6 +447,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_PSOLVE_FAIL_UNREC
: SUNLS_PSOLVE_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed preconditioner solve", "");

return (LASTFLAG(S));
}
}
Expand All @@ -467,16 +477,22 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
SUNCheckLastErr();
*res_norm = r_norm = beta = SUNRsqrt(r_norm);

SUNLogDebug(S->sunctx->logger, __func__, "initial-residual",
"nli = %li, resnorm = %.16g", (long int)0, *res_norm);

if (r_norm <= delta)
{
*zeroguess = SUNFALSE;
LASTFLAG(S) = SUN_SUCCESS;

SUNLogInfo(S->sunctx->logger, __func__,
"end-linear-iterate", "cur-iter = 0, total-iters = 0, res-norm = %.16g, status = success",
*res_norm);

return (LASTFLAG(S));
}

SUNLogInfo(S->sunctx->logger, __func__,
"end-linear-iterate", "cur-iter = 0, total-iters = 0, res-norm = %.16g, status = continue",
*res_norm);

/* Initialize rho to avoid compiler warning message */
rho = beta;

Expand All @@ -501,6 +517,8 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
/* Inner loop: generate Krylov sequence and Arnoldi basis */
for (l = 0; l < l_max; l++)
{
SUNLogInfo(S->sunctx->logger, __func__, "begin-linear-iterate", "", "");

(*nli)++;
krydim = l_plus_1 = l + 1;

Expand Down Expand Up @@ -529,6 +547,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_PSOLVE_FAIL_UNREC
: SUNLS_PSOLVE_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed preconditioner solve", "");

return (LASTFLAG(S));
}
}
Expand All @@ -540,6 +562,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_ATIMES_FAIL_UNREC
: SUNLS_ATIMES_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed matvec", "");

return (LASTFLAG(S));
}

Expand All @@ -552,6 +578,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_PSOLVE_FAIL_UNREC
: SUNLS_PSOLVE_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed preconditioner solve", "");

return (LASTFLAG(S));
}
}
Expand Down Expand Up @@ -589,15 +619,20 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
{
*zeroguess = SUNFALSE;
LASTFLAG(S) = SUNLS_QRFACT_FAIL;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed QR factorization", "");

return (LASTFLAG(S));
}

/* Update residual norm estimate; break if convergence test passes */
rotation_product *= givens[2 * l + 1];
*res_norm = rho = SUNRabs(rotation_product * r_norm);

SUNLogDebug(S->sunctx->logger, __func__, "iterate-residual",
"nli = %li, resnorm = %.16g", (long int)*nli, *res_norm);
SUNLogInfo(S->sunctx->logger, __func__,
"linear-iterate", "cur-iter = %i, total-iters = %i, res-norm = %.16g",
l + 1, *nli, *res_norm);

if (rho <= delta)
{
Expand All @@ -608,6 +643,9 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
/* Normalize V[l+1] with norm value from the Gram-Schmidt routine */
N_VScale(ONE / Hes[l_plus_1][l], V[l_plus_1], V[l_plus_1]);
SUNCheckLastErr();

SUNLogInfoIf(l < l_max - 1, S->sunctx->logger, __func__,
"end-linear-iterate", "status = continue", "");
}

/* Inner loop is done. Compute the new correction vector xcor */
Expand All @@ -619,6 +657,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
{
*zeroguess = SUNFALSE;
LASTFLAG(S) = SUNLS_QRSOL_FAIL;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed QR solve", "");

return (LASTFLAG(S));
}

Expand Down Expand Up @@ -651,6 +693,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_PSOLVE_FAIL_UNREC
: SUNLS_PSOLVE_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed preconditioner solve", "");

return (LASTFLAG(S));
}
}
Expand All @@ -674,6 +720,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,

*zeroguess = SUNFALSE;
LASTFLAG(S) = SUN_SUCCESS;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = success", "");

return (LASTFLAG(S));
}

Expand Down Expand Up @@ -701,6 +751,9 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
Xv[k] = V[k];
}
SUNCheckCall(N_VLinearCombination(krydim + 1, cv, Xv, V[0]));

SUNLogInfo(S->sunctx->logger, __func__,
"end-linear-iterate", "status = continue", "");
}

/* Failed to converge, even after allowed restarts.
Expand All @@ -723,6 +776,10 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,
*zeroguess = SUNFALSE;
LASTFLAG(S) = (status < 0) ? SUNLS_PSOLVE_FAIL_UNREC
: SUNLS_PSOLVE_FAIL_REC;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed preconditioner solve", "");

return (LASTFLAG(S));
}
}
Expand All @@ -746,11 +803,19 @@ int SUNLinSolSolve_SPGMR(SUNLinearSolver S, SUNDIALS_MAYBE_UNUSED SUNMatrix A,

*zeroguess = SUNFALSE;
LASTFLAG(S) = SUNLS_RES_REDUCED;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed residual reduced", "");

return (LASTFLAG(S));
}

*zeroguess = SUNFALSE;
LASTFLAG(S) = SUNLS_CONV_FAIL;

SUNLogInfo(S->sunctx->logger, __func__, "end-linear-iterate",
"status = failed max iterations", "");

return (LASTFLAG(S));
}

Expand Down

0 comments on commit 532b546

Please sign in to comment.