coin-or / CppAD

A C++ Algorithmic Differentiation Package: Home Page
https://cppad.readthedocs.io
Other
446 stars 94 forks source link

Potential build mistake in third party tool in use of NDEBUG flag - CppAD compiled in Release #183

Closed a-jp closed 3 months ago

a-jp commented 11 months ago

Hi,

I've been periodically getting errors like:
cppad-20230806 error from a known source: yq = f.Forward(q, xq): a zero order Taylor coefficient is nan.

Not all the time, and when I don't get them the code gives the result I expect validated from elsewhere. Looking at some of the responses on the issues tracker it appears that it's "OK" to have NaN and this doesn't mean there is an error. Would you be able to confirm that this is correct?

If so, and as I said it doesn't happen all the time, and when it doesn't happen the code produces correct results, I was looking to turn it off. My CppAD build is built in release, and I use it in my own cmake based project. In release build of my own project I still get these errors. Looking at the source it appears that in release mode these should not be printed. The CppAD build is fine, but for the headers that get included in a third party code like mine, NDEBUG does not appear to be defined unless I explicitly knew to do so, and therefore they get called non-the-less.

Really then my question is what should I do in cmake in a third party lib to correctly import/set all the flags I need for a release or indeed debug build of CppAD?

At the moment, all I do is:

find_package(PkgConfig REQUIRED) pkg_check_modules(CPPAD REQUIRED IMPORTED_TARGET cppad) later on... target_link_libraries(${LIB_NAME_CPP} PUBLIC PkgConfig::CPPAD)

I've just found out to stop the above, I needed to add this:

target_compile_definitions(${LIB_NAME_CPP} PRIVATE NDEBUG=1)

Would there be a better way of doing this in cmake?

Finally, could you confirm that my NaN are ok to be ignored, as noted when I set NDEBUG the code runs fine and to completion so I'm a bit confused on this aspect. I had expected a major code speed up when setting NDEBUG and that didn't happen either, is that correct?

Many thanks, Andy

bradbell commented 11 months ago

You have a function y = f(x) and some of the components of y are nan, perhaps you are not using these components (for a particular case). You can disable this check with https://cppad.readthedocs.io/en/latest/check_for_nan.html

a-jp commented 11 months ago

My usage of CppAD is via the IPopt wrapper, and the error comes as a results of a call to solve within IPOPT. I wouldn't really therefore know where to put this?

Would you have any views on the NDEBUG type questions that brought this to my attention?

bradbell commented 11 months ago

Now I understand. We would have to add a true/false check_for_nan option to ipopt_solve (similar to the reteape opotion); see options on https://cppad.readthedocs.io/en/latest/ipopt_solve.html#options and https://github.com/coin-or/CppAD/blob/master/include/cppad/ipopt/solve.hpp

Then we would use this option value to set check_for_nan at line 242 beginning of the solve_callback constructor;

      adfun_.check_for_nan( check_for_nan )

see https://github.com/coin-or/CppAD/blob/master/include/cppad/ipopt/solve_callback.hpp

I am currently busy with other things, and would appreciate it if you would give this a try and see if it solves your problem.

a-jp commented 11 months ago

Ok, I'll give it ago thanks for your help.

If you have a minute just to consider whether the behaviour that I've found with NDEBUG is expected in terms of using a release-compiled version of CppAD in another project that is also compiled in release-mode, that would be most helpful. My expectation would be that debug checks are not trigger from a release build of CppAD - which they are with my current cmake-usage above.

bradbell commented 11 months ago

If you have a minute just to consider whether the behaviour that I've found with NDEBUG is expected in terms of using a release-compiled version of CppAD in another project that is also compiled in release-mode, that would be most helpful.

If you look at https://github.com/coin-or/CppAD/blob/master/include/cppad/core/forward/forward.hpp and search for check_for_nan, you will see that the error message in question is inside a

# ifndef NDEBUG
...
# endif

block. So I do not know how it is getting printed if the CppAD code is being built with NDEBUG defined ? Please inform me if you figure this out.

a-jp commented 11 months ago

So I do not know how it is getting printed if the CppAD code is being built with NDEBUG defined ? Please inform me if you figure this out.

-- Like I say above, that's kind of my whole point, I've no idea how it's getting in there, but it does...

bradbell commented 11 months ago

Are you using the cmake_build_type option to configure CppAD ?; see https://cppad.readthedocs.io/en/latest/cmake.html#cmake-build-type

It may also help to check the value of CMAKE_BUILD_TYPE output by the cmake command; i.e., it should be -- CMAKE_BUILD_TYPE = Release

a-jp commented 11 months ago

yep, that's the one I use. As far as I can work out the problem is that on make install the include files put into the include dir of the install location still have these # ifndef NDEBUG within them. When you then include CppAD in your own project as I tried to explain above using PkgConfig, NDEBUG is not defined since it's nothing to do with my project. So these parts get triggered. I think that's what's happening.

bradbell commented 11 months ago

This is just a side issue that may be relevant to you. If you are building a library that may use both debug and release CppAD code, you need to define CPPAD_DEBUG_AND_RELEASE https://cppad.readthedocs.io/en/latest/preprocessor.html#cppad-debug-and-release

a-jp commented 11 months ago

Ok thanks. Good to know. At the moment it's just release CppAD and release my own code base that includes and links to CppAD.

bradbell commented 3 months ago

Is there still an open issue here (from your point of view) ? If not, would you please close this issue.

raisin commented 3 months ago

The following two links 404:

  1. https://cppad.readthedocs.io/en/latest/ipopt_solve.html#options
  2. https://cppad.readthedocs.io/en/latest/preprocessor.html#cppad-debug-and-release

You've documented things very clearly. It's a shame those links don't work. Is there an alternative way to access the same information?

bradbell commented 3 months ago

@raisin Seems like the language (en) has dropped from the links, try:

https://cppad.readthedocs.io/latest/ipopt_solve.html#options https://cppad.readthedocs.io/latest/preprocessor.html#cppad-debug-and-release