1

What are the general strategies to start debugging numerical code, when:

  • code compiled with aggressive optimization flags, produces occational NaN's and Inf's in the output
  • code compiled with -g (which implies -O0) for running with debugger, does not produce NaN's and Inf's anymore?

In this case I was working with the Portland Group C++ compiler, pgCC, and used optimization options

-w -fast -O3 -Mipa=fast -Mfprelaxed -Minline=levels:10

and then just

-w -g

for the debugging version. But I am sure a similar situation could happen with g++ as well.

EDIT: Adding print statements is not a very alluring option, as the code is not written by me, it's several thousands of lines large, and I have no idea to narrow the search; the NaN's might originate pretty much from anywhere.

Sampo Smolander
  • 1,605
  • 2
  • 15
  • 33
  • Can you add print statements? – Oliver Charlesworth Apr 13 '12 at 13:16
  • 2
    If correctness has greater value than speed, stay away from optimizations that you don't control. – Alexey Frunze Apr 13 '12 at 13:58
  • Alex: It would be nice to locate the suspicious lines in the source code, to be a able to look at them, and decide if they seem correct of not. – Sampo Smolander Apr 13 '12 at 14:02
  • 1
    It's not the lines that are suspicious it's the fact that when you have limited numerical precision, regular mathematical laws of commutativity and distributivity stop working and when the compiler reorders the operations at its whim in the assumption that the laws still work, you start getting bizarre results. – Alexey Frunze Apr 13 '12 at 14:17

3 Answers3

3

I would try to see if you can enable floating point exceptions like done here, then see if there's an exception thrown from some signaling nan. There's probably some compiler flag in your compiler to enable these exceptions.

Short of that I'd do manual binary search. That is, write a function that dumps all variables. Then split the program in half, not by lines of code, but by what is actually run, and isolate it. In other words, roll up your sleeves and get in there.

Edit: This may not apply to your case, since the link I gave you was very Win32 specific. But maybe it will give you some leads. Or you could try the code on a free MS compiler?

Community
  • 1
  • 1
Chris A.
  • 6,817
  • 2
  • 25
  • 43
  • +1: [Wolf Fence in Alaska](http://www.google.com/search?q=wolf+fence+in+alaska) (AKA binary search) is highly effective when used correctly. 20 passes will reduce your problem space by a factor of 2^20, or 1,000,000+. It is especially useful when dealing with Black Box® problems, a class which includes optimizing compilers. – Peter Rowell Apr 14 '12 at 19:17
2

The Portland Group compilers provide some options to accompany the directive -Mfprelaxed; I'd try setting these one by one and seeing which ones make a difference. You may want just to drop this directive from your compilation altogether.

High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
2

I'd like to point out that in the case of g++ the -g flag does not suppress optimizations (that is, it does not imply -O0). An optimized executable containing debugging information is harder to debug but it is certainly possible to do so.

jmbr
  • 3,298
  • 23
  • 23