[Ipopt] Catch (...) statements in Ipopt

David Wilkinson xyz-coin at effisols.com
Sun Jun 4 16:43:52 EDT 2017


Hi Stefan:

Sorry, I missed this response.

I think a NO_CATCH_ALL macro would be easier for me, unless there are other 
places in COIN-OR where the catch (...) is actually useful.

Having figured out how to turn the catch (...) off via BonBabSetupBase, one 
other thought I had was that IpIpoptApplication::RethrowNonIpoptException() 
should return bool (the previous value) so that one could restore the previous 
value after the danger of unwanted catch was passed.

Thanks,

David Wilkinson

============

Stefan Vigerske wrote:
> 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=
>>>>
>>>>
>>>
>>>
>>
>
>


More information about the Ipopt mailing list