This patch sometimes crashes PD:
[0.0000000000000000000000000000000001 ( | [expr 1/$f1] | [env~] | [vd~ buffer 100]
[delwrite~ buffer]
The output of expr is inf. The output of env~ is nan
vd~ doesn't always handle nan, and crashes.
A fix for vd~ can look like this:
--- a/pure-data/src/d_delay.c +++ b/pure-data/src/d_delay.c @@ -271,7 +271,11 @@ static t_int *sigvd_perform(t_int *w) t_sample zerodel = x->x_zerodel; while (n--) { - t_sample delsamps = x->x_sr * *in++ - zerodel, frac; + t_sample inval = *in++; + if(isnan(inval)) + inval = 0.0f; + + t_sample delsamps = x->x_sr * inval - zerodel, frac;
In Pd, should objects be able to handle (i.e. "not crash") when they get input values of nan and inf, or should they instead make sure that nan and inf never can be sent out of the objects, or both?
On Tue, Sep 10, 2013 at 10:21 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote: ...
In Pd, should objects be able to handle (i.e. "not crash") when they get input values of nan and inf, or should they instead make sure that nan and inf never can be sent out of the objects, or both?
It is not so much of a problem if an object puts out denormals incidentally and most classes do not provide a check, for reasons of performance. Most important is that objects can not get into a state of recycling nan / inf for a longer period of time (like in a recursive filter's state variable). For table writers it is customary to make sure they don't write any denormal, because other objects have access to the data and could make denormals to recycle. So it is the writing object that has or should have anti-denormals-protection. When using an [s~] and [r~] pair for signal connection, denormals don't go through because [s~] does the check too.
Katja
Perhaps expr should check for denormals as well?
Two fixes then: 1. Check for denormals in expr 2. Add an isnormal call to the floating value in vd~ to avoid crashing if getting a value that fails the if (delsamps < 1.00001f) delsamps = 1.00001f; if (delsamps > limit) delsamps = limit; checks in there.
On Tue, Sep 10, 2013 at 10:57 AM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 10:21 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote: ...
In Pd, should objects be able to handle (i.e. "not crash") when they get input values of nan and inf, or should they instead make sure that nan and inf never can be sent out of the objects, or both?
It is not so much of a problem if an object puts out denormals incidentally and most classes do not provide a check, for reasons of performance. Most important is that objects can not get into a state of recycling nan / inf for a longer period of time (like in a recursive filter's state variable). For table writers it is customary to make sure they don't write any denormal, because other objects have access to the data and could make denormals to recycle. So it is the writing object that has or should have anti-denormals-protection. When using an [s~] and [r~] pair for signal connection, denormals don't go through because [s~] does the check too.
Katja
On Tue, Sep 10, 2013 at 11:12 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
Perhaps expr should check for denormals as well?
Math objects should be able to output denormals. Without that we could not even make test patches to find or debug denormals-issues in other classes.
Two fixes then:
- Check for denormals in expr
- Add an isnormal call to the floating value in vd~ to avoid crashing if
getting a value that fails the if (delsamps < 1.00001f) delsamps = 1.00001f; if (delsamps > limit) delsamps = limit; checks in there.
NAN is unordered, the greater-than test does not handle it indeed.The PD_BIGORSMALL() macro / function as defined in m_pd.h may work well here. Some processors don't have a fast implementation of isnan() etc.
On Tue, Sep 10, 2013 at 10:57 AM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 10:21 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote: ...
In Pd, should objects be able to handle (i.e. "not crash") when they get input values of nan and inf, or should they instead make sure that nan and inf never can be sent out of the objects, or both?
It is not so much of a problem if an object puts out denormals incidentally and most classes do not provide a check, for reasons of performance. Most important is that objects can not get into a state of recycling nan / inf for a longer period of time (like in a recursive filter's state variable). For table writers it is customary to make sure they don't write any denormal, because other objects have access to the data and could make denormals to recycle. So it is the writing object that has or should have anti-denormals-protection. When using an [s~] and [r~] pair for signal connection, denormals don't go through because [s~] does the check too.
Katja
On Tue, Sep 10, 2013 at 11:58 AM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 11:12 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
Perhaps expr should check for denormals as well?
Math objects should be able to output denormals. Without that we could not even make test patches to find or debug denormals-issues in other classes.
Yes, but the problem is that [expr 1/0.00000000000000000000001] sends out inf.
On Tue, Sep 10, 2013 at 12:09 PM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
On Tue, Sep 10, 2013 at 11:58 AM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 11:12 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
Perhaps expr should check for denormals as well?
Math objects should be able to output denormals. Without that we could not even make test patches to find or debug denormals-issues in other classes.
Yes, but the problem is that [expr 1/0.00000000000000000000001] sends out inf.
I meant to say denormals and non-numbers, sorry. For example, this gives 'inf' in Pd:
[2( | [pow 1024]
and this gives '-nan':
[2( | [pow 1024] | [* 0]
Since most processors don't flush denormals and non-numbers to zero by default, Pd classes have to deal with it in some selective way. If all math objects (signal objects in particular) would flush those generally undesired numbers to zero, that would make Pd slower. The compromise is to flush problematic values wherever they cause a serious problem, like recycling NaN's. In your [vd~] example the NaN seems to result in an illegal pointer value. The same issue might happen in other table reading objects with index inlets ([tabread], [tabread4~], [cyclone/poke~]). Did you try that?
Katja
On Tue, Sep 10, 2013 at 1:47 PM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 12:09 PM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
On Tue, Sep 10, 2013 at 11:58 AM, katja katjavetter@gmail.com wrote:
On Tue, Sep 10, 2013 at 11:12 AM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
Perhaps expr should check for denormals as well?
Math objects should be able to output denormals. Without that we could not even make test patches to find or debug denormals-issues in other classes.
Yes, but the problem is that [expr 1/0.00000000000000000000001] sends out inf.
I meant to say denormals and non-numbers, sorry. For example, this gives 'inf' in Pd:
[2( | [pow 1024]
and this gives '-nan':
[2( | [pow 1024] | [* 0]
Since most processors don't flush denormals and non-numbers to zero by default, Pd classes have to deal with it in some selective way. If all math objects (signal objects in particular) would flush those generally undesired numbers to zero, that would make Pd slower. The compromise is to flush problematic values wherever they cause a serious problem, like recycling NaN's. In your [vd~] example the NaN seems to result in an illegal pointer value. The same issue might happen in other table reading objects with index inlets ([tabread], [tabread4~], [cyclone/poke~]). Did you try that?
Thank you! That's what I wanted to know. I'll provide a more thought-through patch for vd~, and perhaps tabread4~ and poke~ as well.
The trouble with vd~ was a real world example (provided by a user) that made radium (with now has pd embedded) crash. He couldn't continue working on his song, since pd patches are saved inside radium song files, and radium crashed as soon as he tried to load the song.
On Tue, Sep 10, 2013 at 2:01 PM, Kjetil Matheussen k.s.matheussen@gmail.com wrote:
Since most processors don't flush denormals and non-numbers to zero by default, Pd classes have to deal with it in some selective way. If all math objects (signal objects in particular) would flush those generally undesired numbers to zero, that would make Pd slower. The compromise is to flush problematic values wherever they cause a serious problem, like recycling NaN's. In your [vd~] example the NaN seems to result in an illegal pointer value. The same issue might happen in other table reading objects with index inlets ([tabread], [tabread4~], [cyclone/poke~]). Did you try that?
Thank you! That's what I wanted to know. I'll provide a more thought-through patch for vd~, and perhaps tabread4~ and poke~ as well.
The trouble with vd~ was a real world example (provided by a user) that made radium (with now has pd embedded) crash. He couldn't continue working on his song, since pd patches are saved inside radium song files, and radium crashed as soon as he tried to load the song.
Oops, that is a nasty case. I was just about to say: it is an open question to what extent Pd must be idiot-proof. After all, Pd can be considered a computer language, a patch can be considered a program, and the programmer has some responsibility too. Why should one send NaN as an index value or delay time to some object? Well, maybe because Pd is often used for wild experiments, like the example case illustrates. Pd should not crash on bugs in a patch I guess.
Katja