Incorrect forward derivative for dynamic and rectangular Eigen matrix-vector products
- 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
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