-
-
Notifications
You must be signed in to change notification settings - Fork 371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only swallow domain_errors in various algorithms #3259
Only swallow domain_errors in various algorithms #3259
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
@SteveBronder mind giving this a look? |
de17945
to
759a569
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is fine, one thing I would like clarified is what happens to things like std::out_of_range
errors.
src/stan/services/optimize/bfgs.hpp
Outdated
try { | ||
ret = bfgs.step(); | ||
} catch (const std::exception& e) { | ||
logger.error(e.what()); | ||
return error_codes::SOFTWARE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to the outer part of the while loop?
src/stan/services/optimize/lbfgs.hpp
Outdated
try { | ||
ret = lbfgs.step(); | ||
} catch (const std::exception& e) { | ||
logger.error(e.what()); | ||
return error_codes::SOFTWARE; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. Generally for any while loops I'd like to just have the try on the outside
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved both
// we want to terminate multi-path pathfinder during these unrecoverable | ||
// exceptions | ||
throw; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? One pathfinder can fail while the others succeed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If one path does something unrecoverable like indexes into a vector out of bounds, I think the right thing to do is stop and say "something is clearly wrong with your model".
Besides that, a primary motivation behind this PR is also to implement an exit()
function into the language, which requires the ability to terminate the entire algorithm it is in. If one chain or one path calls exit
, the entire thing still needs to halt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If one path does something unrecoverable like indexes into a vector out of bounds, I think the right thing to do is stop and say "something is clearly wrong with your model".
Are only unrecoverable errors able to be thrown here? Like if the call to log_prob throws it could be from something recoverable like one of the ode solvers failing for a given set of parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pathfinder_impl
catches std::domain_error
s, which is what the ODE solvers throw (and is generally what the math library considers 'recoverable'), so the only exceptions which reach this will be unrecoverable ones from the model or issues in our algorithm
|
out of range can make sense, but what about |
Those have been considered unrecoverable (at least during initialization) for a while. I think if there are usages in Math we want to be recoverable, we should change those to match the others |
Okay looking at this again I think this is fine to merge 👍 |
Submission Checklist
./runTests.py src/test/unit
make cpplint
Summary
Closes #3258. This changes any place which caught
std::exception
from the model to only catchstd::domain_error
, matching what is done during initialization.This prevents odd behavior like an indexing exception that only occurs randomly being swallowed if initialization happens to pass, and allows things like an
exit()
function in the language.Intended Effect
Cause certain exceptions to terminate the inference algorithms.
How to Verify
This model will usually initialize but quickly fail now:
Side Effects
I've installed handlers in the service functions, but code that calls the internals of these algorithms (e.g
run_adaptive_sampler
) not through the services will need to be ready to catch exceptionsAdditionally, if any Math functions raise an exception which is intended to be recoverable but is not a domain_error, they will need updating. Because this is the current behavior in initialization, I suspect we have probably already smoked any of these out.
Documentation
Copyright and Licensing
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company):
Simons Foundation
By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses: