[Ipopt] Catch (...) statements in Ipopt
Stefan Vigerske
stefan at math.hu-berlin.de
Wed May 24 06:56:33 EDT 2017
Hi,
I thought about adding a RethrowNonBonminException(bool) to
BonBabSetupBase, but getting this to all places that it may be needed
within Bonmin seemed to be more effort.
There was already a check for a NO_CATCH_ALL define at some places in
the Bonmin code. I've now added a check for this to other catch(...)
places where it was misses and added an
IpIpoptApplication::RethrowNonIpoptException(true) call to the
Bonmin/Ipopt interface (BonIpoptSolver.cpp).
This is only in trunk for now.
Would that be sufficient for you? So you would have to compile with
-DNO_CATCH_ALL.
Stefan
On 05/16/2017 07:01 PM, David Wilkinson wrote:
> Hi Stefan:
>
> I am using Ipopt via Bonmin, and it is not immediately obvious now to
> get the IpotApplication object on which to call
> RethrowNonIpoptException(). My goal is to avoid making any modifications
> in the Bonmin/Ipopt source code (otherwise I could just hard-wire
> rethrow_nonipoptexception_ to true in the IpoptApplication constructors).
>
> The way I use Bonmin (based on the example in the Bonmin documentation)
> is something like
>
> // BonminOptimizer.cpp
> // Implementation of driver class for Bonmin
>
> using namespace Bonmin;
> using namespace Ipopt;
>
> // m_babPtr member is a smart pointer to Bonmin::Bab object
>
> void BonminOptimizer::Run()
> {
> BonminSetup bonmin(someArg);
> // work with options
> bonmin.initialize(GetRawPtr(myTminlp)); // creates first instance
> try
> {
> m_babPtr.reset(new Bab());
> m_babPtr->branchAndBound(bonmin); // creates second instance
> }
> // some catch statements
> // save some results
> }
>
> This code indirectly creates two instances of IpoptApplication, as
> indicated in the comments. It is the second one that catches exceptions
> thrown in the TMINLP object of my driver application, but this
> IpoptApplication object is not directly available in the above function,
> because the branchAndBound() call does not return until the optimization
> is completed.
>
> I have actually been able to get what I want by doing the following:
>
> // BonminOptimizer.cpp
>
> void BonminOptimizer::RethrowNonIpoptException(bool dorethrow) const
> {
> CbcModel& model = m_babPtr->model();
> OsiTMINLPInterface* p =
> static_cast<OsiTMINLPInterface*>(model.solver());
> IpoptSolver* pSolver = static_cast<IpoptSolver*>(p->solver());
> IpoptApplication& app = pSolver->getIpoptApp();
> app.RethrowNonIpoptException(dorethrow);
> }
>
> The above method is called from
>
> // MyTMINLP.cpp
>
> void MyTMINLP::CheckOptimizerStatus()
> {
> // This method is called from each evaluation method in MyTMINLP
> // m_pOptimizer is a member pointer to BonminOptimizer object
> // m_bRethrow is a member bool, initially false
>
> if (!m_bRethrow) // IpoptApplication object is not yet in rethrow mode
> {
> m_pOptimizer->RethrowNonIpoptException(true); put in rethrow mode
> m_bRethrow = true;
> }
> m_pOptimizer->CheckStatus(); // this may throw (by design)
> }
>
> This seems to work but, as you can imagine, it took me a long time to
> figure out how to get the IpoptApplication object, and it is extremely
> clunky.
>
> Might there be simpler way to do this?
>
> If not, maybe this is a defect in Bonmin rather than Ipopt, but it would
> be much easier if there were some global way to set
> rethrow_nonipoptexception_, or if it could be set via the options.
>
> Sorry for the long post...
>
> David Wilkinson
>
> ==========================================
>
> Stefan Vigerske wrote:
>> Hi,
>>
>> you can change the value of rethrow_nonipoptexception_ via
>> IpoptApplication::RethrowNonIpoptException():
>>
>> https://www.coin-or.org/Ipopt/doxygen/classIpopt_1_1IpoptApplication.html#a985d4b2f4b443b7aef8d6e924c49b5ce
>>
>>
>>
>> Best,
>> Stefan
>>
>> On 05/13/2017 12:47 PM, David Wilkinson wrote:
>>> I have a Bonmin/Ipopt client application that (rightly or wrongly)
>>> uses C++
>>> exceptions for flow control in abnormal situations. In some of these
>>> situations, the exception is getting caught by catch (...) statements in
>>> Ipopt::IpoptApplication. The content in some (but not all) of these
>>> catch
>>> (...) statements is protected by a variable
>>> rethrow_nonipoptexception_, but
>>> this variable is hard-wired to be false, and so cannot be used to change
>>> behavior without modifying source code.
>>>
>>> Suggestion:
>>>
>>> The content of all occurrences of catch (...) in Ipopt::IpoptApplication
>>> should be protected by this rethrow_nonipoptexception_ variable, and its
>>> value should be controllable by a preprocessor symbol.
>>>
>>> There are examples of catch (...) statements in other parts of
>>> COIN-OR (Bonmin
>>> and Clp) that are not harmful to my client application, but perhaps
>>> these
>>> should also be protected in a similar manner.
>>>
>>> Thanks,
>>>
>>> David Wilkinson
>>> _______________________________________________
>>> Ipopt mailing list
>>> Ipopt at list.coin-or.org
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__list.coin-2Dor.org_mailman_listinfo_ipopt&d=DwICAg&c=Ngd-ta5yRYsqeUsEDgxhcqsYYY1Xs5ogLxWPA_2Wlc4&r=BRcuJnQr5NAzU29t80hk2rsLc4vrlRySBDabuq0O1ZI&m=uUZR1xuZjRHb2iwG1M6a4OZH7EZH4pOHxKw1tfWL5TE&s=_8Ow3ENlrd9SRhRDClaTgphGxyICFFwa7JbRD6uhG6o&e=
>>>
>>>
>>
>>
>
--
http://www.gams.com/~stefan
More information about the Ipopt
mailing list