FAQ¶
The questions below come up repeatedly in Clad’s issues and discussions.
Clang says “Clad doesn’t appear to be loaded”¶
The full message is:
static assertion failed: clad doesn't appear to be loaded; make sure that
you pass clad.so to clang.
clad/Differentiator/Differentiator.h is an ordinary header and compiles on
its own, but the derivative is produced by the plugin, not by the header. If
the compile command does not load the plugin, there is nothing to produce it,
and Clad says so instead of letting you link a program whose derivatives are
all missing.
Add the plugin to the command line:
clang++ -std=c++17 -I /full/path/to/include/ \
-fplugin=/full/path/to/lib/clad.so SourceFile.cpp
Installation and usage has the details, including the spelling older Clang releases need.
Clang cannot load clad.so, or reports an undefined symbol¶
Clad is a Clang plugin, so it is built against one particular Clang and has to be loaded into that same one. Loading it into a different build gives an undefined symbol at load time, and loading it into a different version makes Clad refuse to run: it compares the version of the Clang loading it against the version it was built against.
Point the compile command at the clang++ Clad was built against. Note that
the Apple releases of Clang do not load Clad at all – install an upstream LLVM.
Should I use forward mode or reverse mode?¶
Count the inputs you need derivatives for. One run of forward mode
(clad::differentiate) gives you the derivative with respect to one input;
one run of reverse mode (clad::gradient) gives you the derivatives with
respect to every input at once. Both cost a small multiple of the original
function.
So a function with many inputs and one output – the usual case, a scalar cost or likelihood – wants reverse mode. A function with one input and many outputs wants forward mode. Core concepts explains why.
How do I differentiate with respect to an array?¶
If the parameter has a known size, pass an array of the same size for its derivative:
#include "clad/Differentiator/Differentiator.h"
#include <cstdio>
double weighted(double x[3]) { return x[0] * x[1] + x[2]; }
int main() {
auto g = clad::gradient(weighted);
double x[3] = {2, 3, 4}, dx[3] = {};
g.execute(x, dx);
printf("dx = {%g, %g, %g}\n", dx[0], dx[1], dx[2]); // prints: dx = {3, 2, 1}
}
If it is a pointer whose length is only known at run time, wrap the derivative
in a clad::array_ref so Clad knows how far it may write:
#include "clad/Differentiator/Differentiator.h"
#include <cstdio>
double sum_sq(const double* x, int n) {
double s = 0;
for (int i = 0; i < n; ++i)
s += x[i] * x[i];
return s;
}
int main() {
auto g = clad::gradient(sum_sq, "x");
double y[4] = {1, 2, 3, 4}, dy[4] = {};
clad::array_ref<double> dy_ref(dy, 4);
g.execute(y, 4, dy_ref);
printf("dy = {%g, %g, %g, %g}\n", dy[0], dy[1], dy[2],
dy[3]); // prints: dy = {2, 4, 6, 8}
}
Clad warns that a function has no definition¶
The warning reads:
attempted differentiation of function 'f' without definition and no
suitable overload was found in namespace 'custom_derivatives'
Clad differentiates source code, so it needs the body of every function it reaches. A function declared in a header but defined in another translation unit, or in a library you only link against, has no body to differentiate.
There are three ways forward. Make the definition visible, by moving it into a
header or into the same translation unit. Write a custom derivative that tells
Clad what the derivative of that function is – see
Custom derivatives; the -fclad-porting-hints
flag makes Clad name the signature it is looking for. Or leave it, and let
Clad fall back to numerical differentiation, which is what it does by default;
compiling with -DCLAD_NO_NUM_DIFF turns the fallback off and makes the
missing definition an error.
How do I see the code Clad generated?¶
CladFunction::dump() prints it, and CladFunction::getCode() returns it
as a string:
auto df = clad::differentiate(f, "x");
df.dump();
That shows the one derivative you asked for. To see everything Clad generated for a translation unit, including the derivatives it produced for nested calls, or to get a file you can compile and step through in a debugger, see Debug functionalities.
Can Clad differentiate templates and overloaded functions?¶
Yes, but you have to say which function you mean, because the name alone stands for several. See Differentiating Templates and Overloaded Functions.
I think a derivative is wrong. What should I report?¶
Please open an issue with:
the smallest function that still shows the problem, in one file;
what Clad generated for it, from
dump();the value you expected and the value you got;
the Clang version and the Clad version or commit.
A derivative that disagrees with a finite difference of the original function is good evidence, and the generated code usually shows where the derivative went wrong, so those two together are the most useful thing to send.