EnzymeAD / EnzymeAD/Enzyme

C++ __enzyme_autodiff modifying arguements in unexpected ways

Open
#2,994 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.