Skip to content

Commit

Permalink
Add page to documentation explaining clad::immediate_mode
Browse files Browse the repository at this point in the history
  • Loading branch information
MihailMihov committed Oct 29, 2024
1 parent 6d1e43e commit 38f708f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/userDocs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ The User Guide
user/tutorials
user/UsingEnzymeWithinClad
user/UsingVectorMode.rst
user/UsingImmediateMode
user/FAQ
user/DevelopersDocumentation
user/IntroductionToClangForCladContributors
Expand Down
70 changes: 70 additions & 0 deletions docs/userDocs/source/user/UsingImmediateMode.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
Using Clad-generated derivatives in an immediate context
**********************************************************

The derivatives that Clad generates are valid C++ code, which
could in theory be executed at compile-time (or in an immediate
context as the C++ standard calls it). When a function is differentiated
all attributes, such as `constexpr` and `consteval` are kept, but
it is important to understand the interface that Clad provides for
those derivatives to the user.

When Clad differentiates a function (e.g. with `clad::differentiate`)
the user receives a `CladFunction`, which contains a function pointer to
the generated derivative, among many other things. Unfortunately
due to how the C++ standard is written handling function pointers
in an immediate context is very restricted and care needs to be taken to
not violate the rules or the compiler won't be able to evaluate our
`constexpr`/`consteval` functions during translation.

Currently to get a `CladFunction` that is usable in immediate
mode the user has to pass `clad::immediate_mode` to the differentiation
function and that removes the ability to dump the generated derivative,
but it may be possible to add support for that in the future.

Usage of Clad's immediate mode
================================================

The following code snippet shows how one can request Clad to use the immediate mode for
differentiation::

#include "clad/Differentiator/Differentiator.h"

constexpr double fn(double x, double y) {
return (x + y) / 2;
}

constexpr double fn_test() {
auto dx = clad::differentiate<clad::immediate_mode>(fn, "x");

return dx.execute(4, 7);
}

int main(){
constexpr double fn_result = fn_test();

printf("%.2f\n", fn_result);
}

It is neccessary both to pass the `clad::immediate_mode` option to `clad::differentiate`
and to keep both the call to `clad::differentiate` and all it's `.execute(...)` calls in
the same immediate context, as the C++ standard forbids having a function pointer to an
immediate function outside of an immediate context. (It is not possible to do the
differentiation and executions in main as `dx` would contain such a pointer, but `main` is
not and can not be immediate)

When using `constexpr` there is no easy way to tell whether the functions are actually
being evaluated during translation, so it is a good idea to use either `consteval` or an
`if consteval` (in C++23 and newer) to check if the immediate contexts are behaving
as expected or assign the results to a variable marked `constexpr` as that would fail if
the expression that is being assigned isn't immediate.

Use cases supported by Clad's immediate mode
================================================

Currently Clad's immediate mode is primarily meant to be used in the forward mode
(`clad::differentiate`) as internal data structures that Clad needs for differentiating
loops, etc. are not yet usable in an immediate context.

Both `constexpr` and `consteval` are supported as Clad doesn't actually rely on these
specific keywords for it's support, but instead uses clang's API to determine if the functions
are immediate and should be differentiated eariler.

0 comments on commit 38f708f

Please sign in to comment.