Mirror of rust-lang/enzyme
  • LLVM 53.8%
  • C++ 36.8%
  • MLIR 5.7%
  • C 1.7%
  • Fortran 0.9%
  • Other 1%
Find a file
William Moses 7a55d0364c
cacheForReverse: don't cache an argument, rebuild it in the reverse (#3206)
`GradientUtils::cacheForReverse` accepts an arbitrary `Value *`, and a custom
augmented forward handler (`EnzymeRegisterCallHandler`) may return one of the
call's own primal or shadow operands as its primal return, shadow return, or
tape value. When that operand is a function argument, it is available unchanged
in the split consumer pass, so caching it in the tape is unnecessary -- and
previously crashed in `CreateAugmentedPrimal` when trying to `cast<Instruction>`
on `VMap[v]` to place the tape store.

Encode `(argNo, isShadow)` on the original function directly as a negative
`tapeIndices` entry (`<= -2`, disjoint from struct slot indices `>= 0`,
single-element non-struct tapes `-1`, and `IndexMappingError`) and rewind
`tapeidx` without appending a dummy `UndefValue` to `addedTapeVals`:

- No `uncachedTapeArgs` map or plumbing on `AugmentedReturn` / `GradientUtils`
  is needed, and no unused slot is emitted into the physical tape struct (or
  into functions that otherwise need no tape at all).
- Preserve negative `<= -2` entries when `removeTapeStruct` collapses a single
  physical tape element to `-1` and when OpenMP reverse tasks inspect
  `subdata->tapeIndices`.
- Preserve `originalToNewFn` without clobbering `newToOriginalFn` when replacing
  a call's primal return with an argument (`CacheType::Self`).
- Add a loadable C-API test plugin (`EnzymeTestCallHandler`) and LIT test
  (`cache_for_reverse_arg.ll`) covering `CacheType::Shadow` (no tape, scalar
  tape, struct tape, loop), `CacheType::Tape`, and `CacheType::Self`.
2026-11-03 10:36:59 -06:00
.devcontainer Export compile_commands.json to enable clangd support (#1753) 2024-02-26 14:35:59 -05:00
.github Hand C API callbacks an LLVMBuilderRef LLVM 24 owns (#3531) 2026-10-28 21:37:08 -05:00
.packaging Build Enzyme_jll for LLVM 23 (#3502) 2026-10-19 13:45:20 -05:00
enzyme cacheForReverse: don't cache an argument, rebuild it in the reverse (#3206) 2026-11-03 10:36:59 -06:00
integration Build sumMIT against a pinned pyre commit (#3474) 2026-10-11 18:26:56 -04:00
.gitattributes Revert "Integrate LLVM at llvm/llvm-project@ede40da1f8c1" 2024-09-09 19:09:10 +00:00
.gitignore update to recent LLVM/MLIR changes (#2907) 2026-06-29 18:03:08 +00:00
CITATION.bib Add a citation.bib file which is automatically being picked up by GitHub. (#941) 2022-12-09 22:11:40 +00:00
CONTRIBUTING.md Initial version of contributing guide. (#506) 2022-02-14 02:06:55 +01:00
fortitude.toml Add workflow for Fortran linting (#3130) 2026-09-16 11:25:00 +00:00
fpm.toml Provide a fpm.toml for the Fortran interface (#3080) 2026-08-05 20:39:44 +02:00
LICENSE Revert "Integrate LLVM at llvm/llvm-project@ede40da1f8c1" 2024-09-09 19:09:10 +00:00
Readme.md add link to fortran bindings (#2967) 2026-07-22 12:58:55 -05:00
zizmor.yml Add GitHub Actions linting workflow (#3145) 2026-09-16 13:18:01 +00:00

The Enzyme High-Performance Automatic Differentiator of LLVM and MLIR

Enzyme is a plugin that performs automatic differentiation (AD) of statically analyzable LLVM and MLIR.

Enzyme can be used by calling __enzyme_autodiff on a function to be differentiated as shown below. Running the Enzyme transformation pass then replaces the call to __enzyme_autodiff with the gradient of its first argument.

double foo(double);

double grad_foo(double x) {
    return __enzyme_autodiff(foo, x);
}

Enzyme is highly-efficient and its ability to perform AD on optimized code allows Enzyme to meet or exceed the performance of state-of-the-art AD tools.

Detailed information on installing and using Enzyme can be found on our website: https://enzyme.mit.edu.

A short example of how to install Enzyme is below:

cd /path/to/Enzyme/enzyme
mkdir build && cd build
cmake -G Ninja .. -DLLVM_DIR=/path/to/llvm/lib/cmake/llvm -DLLVM_EXTERNAL_LIT=/path/to/lit/lit.py
ninja

Or, install Enzyme using a package manager:

Homebrew

brew install enzyme

Spack

spack install enzyme

Nix

nix-shell -p enzyme

To get involved or if you have questions, please join our mailing list.

If using this code in an academic setting, please cite the following three papers (first for Enzyme as a whole, second for GPU+optimizations, and third for AD of all other parallel programs (OpenMP, MPI, Julia Tasks, etc.)):

@inproceedings{NEURIPS2020_9332c513,
 author = {Moses, William and Churavy, Valentin},
 booktitle = {Advances in Neural Information Processing Systems},
 editor = {H. Larochelle and M. Ranzato and R. Hadsell and M. F. Balcan and H. Lin},
 pages = {12472--12485},
 publisher = {Curran Associates, Inc.},
 title = {Instead of Rewriting Foreign Code for Machine Learning, Automatically Synthesize Fast Gradients},
 url = {https://proceedings.neurips.cc/paper/2020/file/9332c513ef44b682e9347822c2e457ac-Paper.pdf},
 volume = {33},
 year = {2020}
}
@inproceedings{10.1145/3458817.3476165,
author = {Moses, William S. and Churavy, Valentin and Paehler, Ludger and H\"{u}ckelheim, Jan and Narayanan, Sri Hari Krishna and Schanen, Michel and Doerfert, Johannes},
title = {Reverse-Mode Automatic Differentiation and Optimization of GPU Kernels via Enzyme},
year = {2021},
isbn = {9781450384421},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/3458817.3476165},
doi = {10.1145/3458817.3476165},
booktitle = {Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis},
articleno = {61},
numpages = {16},
keywords = {CUDA, LLVM, ROCm, HPC, AD, GPU, automatic differentiation},
location = {St. Louis, Missouri},
series = {SC '21}
}
@inproceedings{10.5555/3571885.3571964,
author = {Moses, William S. and Narayanan, Sri Hari Krishna and Paehler, Ludger and Churavy, Valentin and Schanen, Michel and H\"{u}ckelheim, Jan and Doerfert, Johannes and Hovland, Paul},
title = {Scalable Automatic Differentiation of Multiple Parallel Paradigms through Compiler Augmentation},
year = {2022},
isbn = {9784665454445},
publisher = {IEEE Press},
booktitle = {Proceedings of the International Conference on High Performance Computing, Networking, Storage and Analysis},
articleno = {60},
numpages = {18},
keywords = {automatic differentiation, tasks, OpenMP, compiler, Julia, parallel, Enzyme, C++, RAJA, hybrid parallelization, MPI, distributed, LLVM},
location = {Dallas, Texas},
series = {SC '22}
}

Julia bindings, Rust bindings, and Fortran bindings are available for Enzyme.