Hi Oliver,

I mostly agree with this course of action and your analysis.  And I agree
it is not be necessary to introduce a new error type.  This was a
suggestion to deal with Patrick's speed concerns.  I am more worried about
bad program termination and will not run ARTS with such a flag.

I wish for the opposite of "-DNO_ASSERTS=1" to be added though.  The
asserts in matpack, as you point out, cause a 30% delay in access if we use
them as throws, and most people generally do not want that.  I can,
however, live with this speed reduction in some critical applications I am
running.  I would therefore prefer if these speed critical asserts can also
be changed into logic-errors or some such.  This might be
"-DCATCH_ALL_ASSERTS=1"?  A name suggestion would be
"ARTS_CRITICAL_ASSERT(condition, errmsg)", to try and keep with your naming
theme.

I really want all standard asserts out of ARTS.

//Richard

Den tis 26 mars 2019 kl 11:46 skrev Oliver Lemke <
oliver.le...@uni-hamburg.de>:

> Hi Patrick and Richard,
>
> I think we're mixing up two issues with error handling in ARTS which
> should be discussed separately:
>
> 1. There are instances where ARTS currently exits non-gracefully which is
> painful esp. for python API users.
>
> 2. How to better organize where errors are checked and which checks can be
> skipped in release mode.
>
> I will concentrate on point 1 in this email because that's what I think
> triggered the whole discussion. For users who mainly use the ARTS API,
> asserts and uncaught exceptions are painful. Since their occurrence leads
> to process termination, this means in case of the Python API, it will kill
> the whole Python process. This is very annoying if you're working in an
> interactive shell such as ipython, because your whole session will die if
> this occurs. Therefore, our main focus should first of all be on fixing
> these issues.
>
> Currently, when we catch exceptions at higher levels such as main agenda
> execution, ybatch loop or the ARTS API interface, we only catch exceptions
> of type std::runtime_error. If an unforeseen std::exception from any
> library function is thrown, it'll lead to program termination. This issue
> is rather easy to solve by explicitly catching std::exception in addition
> to std::runtime_error in the appropriate places and handle them just as
> gracefully. I will take care of adding the code where necessary.
>
> For assertions, the fix is a bit more involved. Since they can't be
> caught, we would need to replace them with a new mechanism. As the
> benchmarks have shown we won't lose (much) performance if we use try/catch
> blocks instead. There are very few exceptions such as index operators in
> matpack which should better be left alone.
> After discussion yesterday with Stefan, we came up with the following
> proposal: Introduce a couple of convenience methods (macros) that can be
> used similar to how the standard assert works now:
>
> ARTS_ASSERT(condition, errmsg)
>
> This would work the same as 'assert' except that it will be throwing a
> runtime_error in case the condition is not fulfilled. Also, this statement
> will be skipped if ARTS is compiled in release mode. They could also be
> turned off in any configuration by the already existing cmake flag
> '-DNO_ASSERT=1'. If anyone feels that the current name of this option
> doesn't properly reflect its purpose, it can be renamed of course.


> ARTS_THROW(condition, errmsg)
>
> This will be the same as ARTS_ASSERT except that will always be active.
>
> Both macros will take care of adding the function name, filename and
> linenumber to the error message.
>
> More complex checks have to be implemented in a custom try/catch block of
> course. And blocks that should be possible to be deactivated should be
> placed inside a preprocessor block such as DEBUG_ONLY. Again here, if the
> name seems inappropriate, another macro that does the same thing with a
> better fitting name could be introduced. So we could have IGNORABLE as an
> alias to DEBUG_ONLY and -DIGNORE_ERRORS=1 as an alias for -DNO_ASSERT=1 . I
> don't see why we need both because in Release mode we would want to
> activate both options anyway, right?
>
> With respect to point 2., I don't see yet a clear strategy or way to give
> a clear definition on which errors should be ignorable and which not. Since
> the past has clearly proven that is already difficult to decide when to use
> an assertion and when a runtime_error, I don't fancy the idea of
> introducing a third class of errors that's defined as 'Can be turned off if
> the user knows what he's doing'. Correct me if I'm wrong Richard, but
> that's basically what you want to achieve with the proposed 'IGNORABLE'
> flag?
>
> Cheers,
> Oliver
>
>
> > On 25 Mar 2019, at 19:47, Patrick Eriksson <patrick.eriks...@chalmers.se>
> wrote:
> >
> > Hi Richard,
> >
> > I can agree  on that this is not always critical for efficiency as long
> as the check is a simple comparison. But some checks are much more
> demanding. For example, the altitudes in z_field should be strictly
> increasing. If you have a large 3D atmosphere, it will be very costly to
> repeat this check for every single ppath calculation. And should this be
> checked also in other places where z_field is used? For example, if you use
> iyIndependentBeamApproximation you will repeat the check as also the DISORT
> and RT4 methods should check this, as they can be called without providing
> a ppath.
> >
> > Further, I don't follow what strategy you propose. The discussion around
> planck indicated that you wanted the checks as far down as possible. But
> the last email seems to indicate that you also want checks higher up, e.g.
> before entering interpolation. I assume we don't want checks on every
> level. So we need to be clear about at what level the checks shall be
> placed. If not, everybody will be lazy and hope that a check somewhere else
> catches the problem.
> >
> > In any case, it should be easier to provide informative error messages
> if problems are identified early on. That is, easier to pinpoint the reason
> to the problem.
> >
> > Bye,
> >
> > Patrick
> >
> >
> >
> > On 2019-03-25 12:24, Richard Larsson wrote:
> >> Hi Patrick,
> >> Just some quick points.
> >> Den sön 24 mars 2019 kl 10:29 skrev Patrick Eriksson <
> patrick.eriks...@chalmers.se <mailto:patrick.eriks...@chalmers.se>>:
> >>    Hi Richard,
> >>    A great initiative. How errors are thrown can for sure be improved.
> We
> >>    are both lacking such checks (still to many cases where an assert
> shows
> >>    up instead on a proper error message), and they errors are probably
> >>    implemented inconsistently.
> >>    When it comes to use try/catch, I leave the discussion to others.
> >>    But I must bring up another aspect here, on what level to apply
> asserts
> >>    and errors. My view is that we have decided that such basic
> >>    functions as
> >>    planck should only contain asserts. For efficiency reasons.
> >> Two things.
> >> First, Oliver tested the speeds here.  The results are random in
> physics_funcs.cc:
> >> number_density (100 million calls, averaged over 5 runs):
> >> with assert:    0.484s
> >> with try/catch: 0.502s, 3.8% slower than assert
> >> no checks:      0.437s, 9.8% faster than assert
> >> dinvplanckdI (20 million calls, averaged over 5 runs):
> >> with assert:    0.576s
> >> with try/catch: 0.563s, 2.3% faster than assert
> >> no checks:      0.561s, 2.7% faster than assert
> >> but with no notable differences.  (We are not spending any of our time
> in these functions really, so +-10% is nothing.)  One thing that asserts do
> that are nicer that they are completely gone when NDEBUG is set.  We might
> therefore want to wrap the deeper function-calls in something that removes
> these errors from the compilers view.  We have the DEBUG_ONLY-environments
> for that, but a negative temperature is not a debug-thing.  I suggested to
> Oliver we introduce a flag that allows us to remove some parts or all parts
> of the error-checking code on the behest of the user.  I do not know what
> to name said flag so the code is readable.  "IGNORABLE()" in ARTS and
> "-DIGNORE_ERRORS=1" in cmake to set the flag that everything in the
> previous parenthesis is not passed to the compiler?  This could be used to
> generate your 'faster' code but errors would just be completely ignored; of
> course, users would have to be warned that any OS error or memory error
> could still follow...
> >> The second point I have is that I really do not see the points of the
> asserts at all.  Had they allowed the compiler to make guesses, that would
> be somewhat nice.  But in practice, they just barely indicate what the
> issues are by comparing some numbers or indices before terminating a
> program.  They don't offer any solutions, and they should really never ever
> occur.  I would simply ban them from use in ARTS, switch to throws, and
> allow the user to tell the compiler to allow building a properly
> non-debug-able version of ARTS where all errors are ignored as above.
> >>    For a pure forward model run, a negative frequency or temperature
> would
> >>    come from f_grid and t_field, respectively. We decided to introduce
> >>    special check methods, such as atmfields_checkedCalc, to e.g. catch
> >>    negative temperatures in input.
> >> I think it would be better if we simply removed the *_checkedCalc
> functions entirely (as a demand for executing code; they are still good for
> sanity checkups).  I think they mess up the logic of many things.  Agendas
> that work use these outputs when they don't need them, and the methods have
> to manually check the input anyways because you cannot allow segfaults.  It
> is not the agendas that need these checks.  It is the methods calling these
> agendas.  And they only need to checks for ensuring they have understood
> what they want to do.  And even if the checked value is positive when you
> reach a function, you cannot say in that method if the check was for the
> data you have now, for data sometime long ago in the program flow, or just
> a bit someone set before calling the code.  So all the inputs have to be
> checked anyways.
> >> For the atmfields_checkedCalc call in particular, it would make more
> sense to have this part of the iy-methods more than anything else.  Since
> ppath is generated externally now (compared to when the iy-methods last had
> an updated error-handling), ppath needs also be checked with the fields
> themselves anyways or you can have segfaults in the interpolations.
> >>    When doing OEM, negative temperatures can pop up after each iteration
> >>    and this should be checked. But not by planck, this should happen on
> a
> >>    higher level.
> >>    A simple solution here is to include a call of atmfields_checkedCalc
> >>    etc. in inversion_iterate_agenda. The drawback is that some data
> >>    will be
> >>    checked over and over again despite not being changed.
> >>    So it could be discussed if checks should be added to the OEM part.
> >>    That
> >>    data changed in an iteration, should be checked for unphysical
> values.
> >>    That is, I think there are more things to discuss than you bring up
> in
> >>    your email. So don't start anything big before we have reached a
> common
> >>    view here.
> >> Right, I won't.
> >> With hope,
> >> //Richard
> > _______________________________________________
> > arts_dev.mi mailing list
> > arts_dev.mi@lists.uni-hamburg.de
> > https://mailman.rrz.uni-hamburg.de/mailman/listinfo/arts_dev.mi
>
>
_______________________________________________
arts_dev.mi mailing list
arts_dev.mi@lists.uni-hamburg.de
https://mailman.rrz.uni-hamburg.de/mailman/listinfo/arts_dev.mi

Reply via email to