Skip to content

Commit 4acaa64

Browse files
author
Yi Zhang
committed
remove KINGetReturnFlagName as it contains mem leak
1 parent f360721 commit 4acaa64

6 files changed

Lines changed: 44 additions & 18 deletions

File tree

stan/math/prim/err/check_flag_sundials.hpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <kinsol/kinsol.h>
55
#include <cvodes/cvodes.h>
66
#include <stan/math/prim/meta.hpp>
7-
#include <stan/math/prim/err/throw_domain_error.hpp>
7+
#include <stan/math/prim/err/domain_error.hpp>
88

99
namespace stan {
1010
namespace math {
@@ -34,26 +34,50 @@ inline void cvodes_check(int flag, const char* func_name) {
3434
}
3535

3636
/**
37-
* Throws an exception message when the function KINSol()
38-
* (call to the solver) fails. When the exception is caused
37+
* Throws an exception message when the functions in KINSOL
38+
* fails. When the exception is caused
39+
* by a tuning parameter the user controls, gives a specific
40+
* error. "KINGetReturnFlagName()" from sundials has a mem leak bug so
41+
* until it's fixed we cannot use it to extract flag error string.
42+
*
43+
* @param flag Error flag
44+
* @param func_name calling function name
45+
* @throw <code>std::runtime_error</code> if the flag is negative.
46+
*/
47+
inline void kinsol_check(int flag, const char* func_name) {
48+
std::ostringstream ss;
49+
if (flag < 0) {
50+
ss << "algebra_solver failed with error flag " << flag << ".";
51+
throw std::runtime_error(ss.str());
52+
}
53+
}
54+
55+
/**
56+
* Throws an exception message when the KINSol() call fails.
57+
* When the exception is caused
3958
* by a tuning parameter the user controls, gives a specific
4059
* error.
4160
*
4261
* @param flag Error flag
62+
* @param func_name calling function name
63+
* @param max_num_steps max number of nonlinear iters
4364
* @throw <code>std::runtime_error</code> if the flag is negative.
65+
* @throw <code>std::domain_error</code> if the flag indicates max
66+
* number of steps is exceeded..
4467
*/
45-
inline void kinsol_check(int flag, const char* func_name) {
46-
std::ostringstream ss;
47-
if (flag < 0) {
48-
ss << func_name << " failed with error flag " << flag << ": "
49-
<< KINGetReturnFlagName(flag) << ".";
68+
inline void kinsol_check(int flag, const char* func_name, long int max_num_steps) { // NOLINT(runtime/int)
69+
std::ostringstream ss;
5070
if (flag == -6) {
51-
throw std::domain_error(ss.str());
52-
} else {
71+
domain_error("algebra_solver", "maximum number of iterations",
72+
max_num_steps, "(", ") was exceeded in the solve.");
73+
} else if (flag == -11) {
74+
ss << "The linear solver’s setup function failed in an unrecoverable manner.";
75+
throw std::runtime_error(ss.str());
76+
} else if (flag < 0) {
77+
ss << "algebra_solver failed with error flag " << flag << ".";
5378
throw std::runtime_error(ss.str());
5479
}
5580
}
56-
}
5781

5882
} // namespace math
5983
} // namespace stan

stan/math/rev/functor/algebra_solver_fp.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,9 @@ struct FixedPointSolver<KinsolFixedPointEnv<F>, fp_jac_type> {
244244
CHECK_KINSOL_CALL(KINInit(mem, &env.kinsol_f_system, env.nv_x_));
245245
CHECK_KINSOL_CALL(KINSetFuncNormTol(mem, f_tol));
246246
CHECK_KINSOL_CALL(KINSetUserData(mem, static_cast<void*>(&env)));
247-
CHECK_KINSOL_CALL(
248-
KINSol(mem, env.nv_x_, KIN_FP, env.nv_u_scal_, env.nv_f_scal_));
247+
kinsol_check(KINSol(mem, env.nv_x_, KIN_FP, env.nv_u_scal_, env.nv_f_scal_),
248+
"KINSol", max_num_steps);
249+
249250

250251
for (int i = 0; i < N; ++i) {
251252
x(i) = NV_Ith_S(env.nv_x_, i);

stan/math/rev/functor/kinsol_solve.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ Eigen::VectorXd kinsol_solve(const F1& f, const Eigen::VectorXd& x,
109109
for (int i = 0; i < N; i++)
110110
NV_Ith_S(nv_x, i) = x(i);
111111

112-
CHECK_KINSOL_CALL(KINSol(kinsol_data.kinsol_memory_, nv_x,
113-
global_line_search, scaling, scaling));
112+
kinsol_check(KINSol(kinsol_data.kinsol_memory_, nv_x,
113+
global_line_search, scaling, scaling),
114+
"KINSol", max_num_steps);
114115

115116
for (int i = 0; i < N; i++)
116117
x_solution(i) = NV_Ith_S(nv_x, i);

test/unit/math/rev/functor/algebra_solver_fp_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ TEST_F(FP_2d_func_test, exception_handling) {
521521

522522
{
523523
std::stringstream err_msg;
524-
err_msg << "KIN_MAXITER_REACHED";
524+
err_msg << "maximum number of iterations";
525525
std::string msg = err_msg.str();
526526
EXPECT_THROW_MSG(algebra_solver_fp(f, x, y, x_r, x_i, u_scale, f_scale, 0,
527527
f_tol, max_num_steps), // NOLINT

test/unit/math/rev/functor/algebra_solver_newton_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ TEST_F(degenerate_eq_test, newton_guess_saddle_point_dbl) {
9999
// a saddle point.
100100
using stan::math::algebra_solver_newton;
101101
std::stringstream err_msg;
102-
err_msg << "KIN_LSETUP_FAIL";
102+
err_msg << "The linear solver’s setup function failed in an unrecoverable manner";
103103
std::string msg = err_msg.str();
104104

105105
EXPECT_THROW_MSG(algebra_solver_newton(degenerate_eq_functor(), x_guess_3,

test/unit/math/rev/functor/util_algebra_solver.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ void inline unsolvable_flag_test(Eigen::Matrix<T, Eigen::Dynamic, 1>& y,
426426
std::vector<double> dat;
427427
std::vector<int> dat_int;
428428
std::stringstream err_msg;
429-
err_msg << "KIN_LSETUP_FAIL";
429+
err_msg << "The linear solver’s setup function failed in an unrecoverable manner.";
430430
std::string msg = err_msg.str();
431431
EXPECT_THROW_MSG(general_algebra_solver(is_newton, unsolvable_eq_functor(), x,
432432
y, dat, dat_int),

0 commit comments

Comments
 (0)