Skip to content

Conversation

demroz
Copy link
Contributor

@demroz demroz commented Aug 27, 2025

This feature adds a BOOST_MATH_REVERSE_MODE_ET_ON and BOOST_MATH_REVERSE_MODE_ET_OFF macro to enable/disable expression templates for the reverse mode autodiff library, and adds some documentation regarding this feature.

This is also probably a good place to open a discussions about the future of the library. Adding special function support is most likely the next step, and I'd love some help and advice with that. I'm guessing tgamma and cyl_bessel_j are good places to start.

The other place that I'd like to take this library is adding some optimization routines like gradient descent, SGD, Adam, LBFGS, etc...

@demroz demroz changed the title Feature: add enable/disable macro for expression templates Feature: add enable/disable macro for expression templates in reverse mode autodiff Aug 27, 2025
Copy link

codecov bot commented Aug 27, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.10%. Comparing base (2c943fb) to head (0234808).
⚠️ Report is 29 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1313   +/-   ##
========================================
  Coverage    95.10%   95.10%           
========================================
  Files          796      797    +1     
  Lines        67115    67126   +11     
========================================
+ Hits         63830    63841   +11     
  Misses        3285     3285           

see 7 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2c943fb...0234808. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@demroz
Copy link
Contributor Author

demroz commented Sep 1, 2025

@mborland @ckormanyos is there any chance I can get this looked at? I've been working on some gradient optimizers in the meantime. Should be ready soon-ish

@mborland
Copy link
Member

mborland commented Sep 1, 2025

I will take a look tomorrow morning and leave comments

Copy link
Member

@mborland mborland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By and large this looks like what we talked about in the last thread. Looks generally good to me.


g++ -DBOOST_MATH_REVERSE_MODE_ET_OFF

The expression templated version of this code doesn't currently interact nicely with the Boost.Math special function implementations, and will throw compile time errors. Disabling expression templates will often fix this, however various special functions are implemented in a way that breaks the automatic differentiation chain for certain values. Complete special function support may be added in the future.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be useful to have a table here that lists the special functions that expression templates supports, rather than the user having to experiment on seeing what compiles.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair. Is there any way to add tests that aren't expected to compile without breaking the entire process? If not I can test locally

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. In addition to run in the Jamfile you have the options of run-fail, compile, and compile-fail. Example is here: https://github.com/boostorg/math/blob/develop/test/Jamfile.v2#L1629.

In the build log it'll show failed-as-expected

}

/** @brief
* subtraction float - rvar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the current testing include C++23's <stdfloat> types? If not I think they should be added. It has its own special rules like narrowing is a compilation error rather than a warning.

Copy link
Contributor Author

@demroz demroz Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test_autodiff_reverse.hpp is essentially a slightly modified copy of the forward mode version. It has a macro that checks for __STDCPP_FLOAT_*_T__
here. I believe this is what youre asking about, I've never really worked with C++23's <stdfloat> types

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but you'll need to add this to the top:

#if __has_include(<stdfloat>)
#  include <stdfloat>
#endif

Since the macros are defined inside that header instead of globally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added these tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

es, but you'll need to add this to the top:

Do we still need to query __has_include itself?

#if defined(__has_include)
#if __has_include(<stdfloat>)
#  include <stdfloat>
#endif
#endif

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No; we don't support any compiler that lacks __has_include.

auto ldexp(const expression<RealType, DerivativeOrder, ARG> &arg, const int &i)
{
BOOST_MATH_STD_USING
return arg * pow(static_cast<RealType>(2.0), i);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the case of HUGE_VAL need to be handled here or does the expression template value naturally handle that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It naturally handles huge values correctly. I added an explicit test case for this though. Works as expected

#ifndef BOOST_MATH_REVERSE_MODE_ET_OFF
#define BOOST_MATH_REVERSE_MODE_ET_ON
#endif

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding a check here that there's no crazy configuration problems:

#if defined(BOOST_MATH_REVERSE_MODE_ET_OFF) && defined(BOOST_MATH_REVERSE_MODE_ET_ON)
#  error "BOOST_MATH_REVERSE_MODE_ET_OFF and BOOST_MATH_REVERSE_MODE_ET_ON are mutually exclusive"
#endif

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this commit also changed the default behavior. Instead of if not explicitly ET_OFF then ET_ON, to if not explicitly ET_ON then ET_OFF (via fall through). Should ET_ON be the default for performance reasons? Or should ET_OFF be the default since it has broader compatibility. I would say ET_ON if we tell the user what works with it, and how to turn it off (which are both already covered in docs or previous comments)

@ckormanyos and @jzmaddock in case you guys have an opinion on the matter.

Copy link
Contributor Author

@demroz demroz Sep 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault. I didn't think too hard about about your comment and just copy and pasted that piece of code. I think ET should be enabled ON by default. At least from personal experience its what makes the most sense to me. If there is no objection from @ckormanyos and @jzmaddock I'll fix it in my next commit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ET should be enabled ON by default. At least from personal experience its what makes the most sense to me.

It also makes sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants