EnzymeAD / EnzymeAD/Enzyme

Incorrect forward derivative for dynamic and rectangular Eigen matrix-vector products

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

Description

## Description

Forward-mode differentiation of an Eigen matrix-vector product produces an
incorrect output tangent for dynamically sized square matrices and for some
statically sized rectangular matrices.

Statically sized square matrices work as expected.

The differentiated operation is:

```cpp
y = A * x;
```

With the tangent vector

```cpp
dx = [1, 0, ..., 0]
```

the expected output tangent is:

```cpp
dy = A * dx = A.col(0)
```

## Observed behavior

The reproducer contains three tests:

```text
[ OK ] EigenEnzyme.StaticSquareMatmul
[ FAILED ] EigenEnzyme.DynamicSquareMatmul
[ FAILED ] EigenEnzyme.StaticRectangularMatmul
```

For example, for a dynamic `2x2` matrix with `A = 2 * Identity()`:

```text
Expected:
2
0

Actual:
4
2
```

The dynamic square case fails for all tested sizes. Some statically sized
rectangular dimension combinations fail as well.

## Expected behavior

The forward derivative should satisfy:

```cpp
dy.isApprox(A * dx)
```

For this reproducer, that is equivalent to:

```cpp
dy.isApprox(A.col(0))
```

for all tested static and dynamic dimensions.

## Versions

- Clang: 20.1.2
- LLVM: 20.1.2
- Enzyme: 0.0.290
- Eigen: 5.0.1

## Reproducer

See the attached test file.

## Build and run

```sh
/usr/bin/clang++ \
-isystem /usr/local/include/eigen3 \
-O3 \
-fplugin=/usr/local/lib/ClangEnzyme-20.so \
eigen.cpp \
-o eigen_test \
-lgtest \
-lgtest_main

./eigen_test
```

## Compilation Warnings
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %5, align 8 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %4, align 8, !tbaa !5 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %10, align 8, !tbaa !12 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %4, align 8, !tbaa !5 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %10, align 8, !tbaa !12 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %4, align 8, !tbaa !5 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %10, align 8, !tbaa !12 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %4, align 8, !tbaa !5 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %10, align 8, !tbaa !12 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %4, align 8, !tbaa !5 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.
warning: Enzyme: Mismatched activity for: store ptr %2, ptr %10, align 8, !tbaa !12 const val: ptr %2. If this value may be active at runtime, enable runtime activity analysis (pass "enzyme_runtime_activity" to __enzyme_autodiff); otherwise its derivative will be assumed zero.

[test.log](https://github.com/user-attachments/files/31253325/test.log)
[eigen.cpp](https://github.com/user-attachments/files/31253326/eigen.cpp)

Contributor guide

Open the contributing guide

Research direction

Start by building and running the attached eigen.cpp with the command in the issue, then review test.log and compare the passing StaticSquareMatmul case with the failing dynamic and rectangular cases. Trace how Enzyme handles the Eigen matrix-vector product and forward tangent, and add or update regression coverage so dy matches A * dx for the reported static and dynamic dimensions.

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
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.