EnzymeAD / EnzymeAD/Enzyme

Forward-over-reverse Hessian is NaN at `-O2`, correct at `-O0`/`-O1`/`-O3` and with `-fno-slp-vectorize`

Open
#3,165 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
LLVM
Stars
1.7k
Forks
188
Avg merge
1d 22h
Merged PRs (30d)
26

Description

Enzyme produces NaN at `-O2` at the forward-over-reverse hessian, while the other flags `-O0`, `-O1`, `-O3` produce the correct Hessian results. However, with `-O2 -fno-slp-vectorize`, it produces the correct results.

Minimal reproducible example:

```cpp
#include
#include
using namespace std;

void f(float *x, float *out) {
float t3[5] = {0.6f, 0.6f, 0.6f, 0.6f, 0.6f};
float s0 = exp(atan2(acos(exp(x[0])) - atan2(sin(x[0]), x[0]),
atan2(x[0], -2.0f) + x[0]));
for (int i = 0; i < 5; i++) {
float t0 = s0 + x[i];
float t2 = s0 + cos(asinh(sqrt(s0) / x[i])) + t0;
t3[i] = t3[i] * log(pow(s0, atan2(pow(s0, s0), pow(s0, t3[i])))) + t2;
out[i] = acosh(t0) * t2 + t3[i];
}
}

extern int enzyme_dup;
extern int enzyme_const;
template RT __enzyme_autodiff(void *, T...);
template RT __enzyme_fwddiff(void *, T...);

void grad(float *x, float *dx, float *y, float *dy) {
__enzyme_autodiff((void *)f, enzyme_dup, x, dx, enzyme_dup, y, dy);
}

int main() {
float x[5] = {-0.9383832812309265f, -0.45288288593292236f,
-0.24080416560173035f, -0.6241748332977295f,
-0.4739071726799011f};
float dx[5] = {1, 0, 0, 0, 0};
float y[5] = {0}, dy[5] = {1, 0, 0, 0, 0};
float g[5] = {0}, h[5] = {0};

__enzyme_fwddiff((void *)grad, enzyme_dup, x, dx, enzyme_dup, g, h,
enzyme_const, y, enzyme_const, dy);

for (int i = 0; i < 5; i++)
printf("%.9g ", h[i]);
printf("\n");
}
```

Build and run:

```bash
clang++ -std=c++17 -O2 repro.cpp -I $ENZYME_INC -fplugin=$ENZYME -o repro
./repro
```

Output:

```
-O0 3.91245604 0 0 0 0
-O1 3.91245651 0 0 0 0
-O2 -nan 0 0 0 0 <-- wrong
-O3 3.91245627 0 0 0 0
-O2 -fno-slp-vectorize 3.91245651 0 0 0 0
```

Environment: clang 16.0.6, Enzyme `main` at `a9975371`, x86-64 (AMD EPYC 9654, AVX-512).

Contributor guide

Open the contributing guide

Research direction

Start with the repro.cpp entry points, __enzyme_fwddiff and __enzyme_autodiff, and build it with clang++ 16.0.6 at -O2; compare the output with -O1, -O3, and -fno-slp-vectorize. Investigate the SLP-vectorization interaction with forward-over-reverse Hessian generation. Done means the -O2 run produces the correct Hessian instead of NaN while the other configurations remain correct.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.