C++ __enzyme_autodiff modifying arguements in unexpected ways
- Dominant language
- LLVM
- Stars
- 1.7k
- Forks
- 188
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 26
Description
I have the following snippet that has been working consistently:
```C++
using ModelFunc = std::tuple (*)(double, double, double, double, const alloys::Alloy&);
template
inline double wrapper(double V, double R, double dT, double C0, const alloys::Alloy& A)
{
std::tuple f{MODELFUNC(V, R, dT, C0, A)};
return std::get(f);
}
struct Jacobian{double df1dV{}; double df1dR{}; double df2dV{}; double df2dR{};};
template
inline Jacobian calculateGrads(double V, double R, double dT, double C0, const alloys::Alloy& A)
{
Jacobian J{};
J.df1dV = __enzyme_autodiff(
(void*)wrapper,
enzyme_out, V, enzyme_const, R, enzyme_const, dT, enzyme_const, C0, enzyme_const, &A
);
J.df1dR = __enzyme_autodiff(
(void*)wrapper,
enzyme_const, V, enzyme_out, R, enzyme_const, dT, enzyme_const, C0, enzyme_const, &A
);
J.df2dV = __enzyme_autodiff(
(void*)wrapper,
enzyme_out, V, enzyme_const, R, enzyme_const, dT, enzyme_const, C0, enzyme_const, &A
);
J.df2dR = __enzyme_autodiff(
(void*)wrapper,
enzyme_const, V, enzyme_out, R, enzyme_const, dT, enzyme_const, C0, enzyme_const, &A
);
return J;
}
```
However my latest ModelFunc, which calls member functions of one of its arguements (A), has been returning incorrect gradients.
On debugging, i found that each of the 4 __enzyme_autodiff calls here are somehow modifying one of the member variables of A.
The ModelFunc and wrapper functions cannot modify A as they take A by const reference, and all of A's member variables and member functions are const.
However I could never get the snippet above to run without passing A by adress to __enzyme_autodiff.
Is there a way to pass class objects to __enzyme_autodiff by copy / const reference / pointer to const or otherwise prevent __enzyme_autodiff from modifying objects passed to it?
Could this be a bug aswell? If so, I can try reducing this to a simpler, reproducable example.
Contributor guide
Research direction
Start with the provided C++ snippet, especially the __enzyme_autodiff calls, wrapper, and ModelFunc member-function calls. Reduce it to a reproducible example that records A before and after differentiation, then determine whether the mutation is expected or indicates a bug; done means the behavior and required usage or fix are clearly established.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100