Skip to content

Commit d6d2593

Browse files
committed
Auto merge of #140799 - EnzymeAD:enzyme-static, r=<try>
[DO NOT MERGE] build Enzyme as archive r? ghost try-job: dist-x86_64-linux
2 parents d14d202 + b4244db commit d6d2593

File tree

17 files changed

+141
-173
lines changed

17 files changed

+141
-173
lines changed

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ pub fn rustc_cargo(
12291229

12301230
if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
12311231
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
1232-
cargo.rustflag("-l").rustflag(&format!("Enzyme-{llvm_version_major}"));
1232+
cargo.rustflag("-l").rustflag(&format!("EnzymeStatic-{llvm_version_major}"));
12331233
}
12341234
}
12351235

@@ -2124,8 +2124,8 @@ impl Step for Assemble {
21242124
let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host });
21252125
if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
21262126
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
2127-
let lib_ext = std::env::consts::DLL_EXTENSION;
2128-
let libenzyme = format!("libEnzyme-{llvm_version_major}");
2127+
let lib_ext = "a";
2128+
let libenzyme = format!("libEnzymeStatic-{llvm_version_major}");
21292129
let src_lib =
21302130
enzyme_install.join("build/Enzyme").join(&libenzyme).with_extension(lib_ext);
21312131
let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host);

src/bootstrap/src/core/build_steps/llvm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@ impl Step for Llvm {
541541
}
542542
};
543543

544-
// FIXME(ZuseZ4): Do we need that for Enzyme too?
545544
// When building LLVM with LLVM_LINK_LLVM_DYLIB for macOS, an unversioned
546545
// libLLVM.dylib will be built. However, llvm-config will still look
547546
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
@@ -977,6 +976,7 @@ impl Step for Enzyme {
977976
.env("LLVM_CONFIG_REAL", &llvm_config)
978977
.define("LLVM_ENABLE_ASSERTIONS", "ON")
979978
.define("ENZYME_EXTERNAL_SHARED_LIB", "ON")
979+
.define("ENZYME_STATIC_LIB", "ON")
980980
.define("LLVM_DIR", builder.llvm_out(target));
981981

982982
cfg.build();

src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ ENV RUST_CONFIGURE_ARGS \
8989
--set llvm.thin-lto=true \
9090
--set llvm.libzstd=true \
9191
--set llvm.ninja=false \
92+
--set llvm.enzyme=true \
9293
--set rust.debug-assertions=false \
9394
--set rust.jemalloc \
9495
--set rust.use-lld=true \

src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ ENV RUST_CONFIGURE_ARGS \
9191
--set llvm.thin-lto=true \
9292
--set llvm.ninja=false \
9393
--set llvm.libzstd=true \
94+
--set llvm.enzyme=true \
9495
--set rust.jemalloc \
9596
--set rust.use-lld=true \
9697
--set rust.lto=thin \

src/ci/docker/host-x86_64/x86_64-gnu/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ ENV RUST_CONFIGURE_ARGS \
2929
--enable-sanitizers \
3030
--enable-profiler \
3131
--enable-compiler-docs \
32-
--set llvm.libzstd=true
32+
--set llvm.libzstd=true \
33+
--set llvm.enzyme=true
3334
ENV SCRIPT python3 ../x.py --stage 2 test

src/ci/github-actions/jobs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ auto:
437437
- name: dist-x86_64-apple
438438
env:
439439
SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
440-
RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1
440+
RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set llvm.enzyme=true --set rust.codegen-units=1
441441
# Ensure that host tooling is built to support our minimum support macOS version.
442442
MACOSX_DEPLOYMENT_TARGET: 10.12
443443
MACOSX_STD_DEPLOYMENT_TARGET: 10.12
@@ -454,7 +454,7 @@ auto:
454454
SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim,aarch64-apple-ios-macabi,x86_64-apple-ios-macabi
455455
# Mac Catalyst cannot currently compile the sanitizer:
456456
# https://github.com/rust-lang/rust/issues/129069
457-
RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false
457+
RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false --set llvm.enzyme=true
458458
# Ensure that host tooling is built to support our minimum support macOS version.
459459
# FIXME(madsmtm): This might be redundant, as we're not building host tooling here (?)
460460
MACOSX_DEPLOYMENT_TARGET: 10.12
@@ -485,6 +485,7 @@ auto:
485485
--enable-profiler
486486
--set rust.jemalloc
487487
--set llvm.ninja=false
488+
--set llvm.enzyme=true
488489
--set rust.lto=thin
489490
--set rust.codegen-units=1
490491
SELECT_XCODE: /Applications/Xcode_15.4.app

src/tools/enzyme

Submodule enzyme updated 122 files

tests/codegen/autodiffv2.rs renamed to tests/codegen/autodiff/autodiffv2.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,13 @@
1818
// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
1919
// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
2020
// original function arguments.
21-
//
22-
// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
23-
// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
24-
// try to rewrite the dummy functions later. We should consider to change to pure declarations both
25-
// in our frontend and in the llvm backend to avoid these issues.
2621

2722
#![feature(autodiff)]
2823

2924
use std::autodiff::autodiff;
3025

3126
#[no_mangle]
32-
//#[autodiff(d_square1, Forward, Dual, Dual)]
27+
#[autodiff(d_square1, Forward, Dual, Dual)]
3328
#[autodiff(d_square2, Forward, 4, Dualv, Dualv)]
3429
#[autodiff(d_square3, Forward, 4, Dual, Dual)]
3530
fn square(x: &[f32], y: &mut [f32]) {
@@ -42,6 +37,9 @@ fn square(x: &[f32], y: &mut [f32]) {
4237
y[4] = 1.0 * x[0] + 2.0 * x[1] + 3.0 * x[2] + 4.0 * x[3];
4338
}
4439

40+
// FIXME
41+
// CHECK: start:
42+
4543
fn main() {
4644
let x1 = std::hint::black_box(vec![0.0, 1.0, 2.0, 3.0]);
4745

@@ -78,25 +76,25 @@ fn main() {
7876
let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);
7977

8078
// scalar.
81-
//d_square1(&x1, &z1, &mut y1, &mut dy1_1);
82-
//d_square1(&x1, &z2, &mut y2, &mut dy1_2);
83-
//d_square1(&x1, &z3, &mut y3, &mut dy1_3);
84-
//d_square1(&x1, &z4, &mut y4, &mut dy1_4);
79+
d_square1(&x1, &z1, &mut y1, &mut dy1_1);
80+
d_square1(&x1, &z2, &mut y2, &mut dy1_2);
81+
d_square1(&x1, &z3, &mut y3, &mut dy1_3);
82+
d_square1(&x1, &z4, &mut y4, &mut dy1_4);
8583

8684
// assert y1 == y2 == y3 == y4
87-
//for i in 0..5 {
88-
// assert_eq!(y1[i], y2[i]);
89-
// assert_eq!(y1[i], y3[i]);
90-
// assert_eq!(y1[i], y4[i]);
91-
//}
85+
for i in 0..5 {
86+
assert_eq!(y1[i], y2[i]);
87+
assert_eq!(y1[i], y3[i]);
88+
assert_eq!(y1[i], y4[i]);
89+
}
9290

9391
// batch mode A)
9492
d_square2(&x1, &z5, &mut y5, &mut dy2);
9593

9694
// assert y1 == y2 == y3 == y4 == y5
97-
//for i in 0..5 {
98-
// assert_eq!(y1[i], y5[i]);
99-
//}
95+
for i in 0..5 {
96+
assert_eq!(y1[i], y5[i]);
97+
}
10098

10199
// batch mode B)
102100
d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);

tests/codegen/autodiff/batched2.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat
2+
//@ no-prefer-dynamic
3+
//@ needs-enzyme
4+
//
5+
// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many
6+
// breakages. One benefit is that we match the IR generated by Enzyme only after running it
7+
// through LLVM's O3 pipeline, which will remove most of the noise.
8+
// However, our integration test could also be affected by changes in how rustc lowers MIR into
9+
// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should
10+
// reduce this test to only match the first lines and the ret instructions.
11+
//
12+
// The function tested here has 4 inputs and 5 outputs, so we could either call forward-mode
13+
// autodiff 4 times, or reverse mode 5 times. Since a forward-mode call is usually faster than
14+
// reverse mode, we prefer it here. This file also tests a new optimization (batch mode), which
15+
// allows us to call forward-mode autodiff only once, and get all 5 outputs in a single call.
16+
//
17+
// We support 2 different batch modes. `d_square2` has the same interface as scalar forward-mode,
18+
// but each shadow argument is `width` times larger (thus 16 and 20 elements here).
19+
// `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the
20+
// original function arguments.
21+
//
22+
// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they
23+
// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which
24+
// try to rewrite the dummy functions later. We should consider to change to pure declarations both
25+
// in our frontend and in the llvm backend to avoid these issues.
26+
27+
#![feature(autodiff)]
28+
29+
use std::autodiff::autodiff;
30+
31+
#[no_mangle]
32+
#[autodiff(d_square1, Forward, Dual, Dual)]
33+
#[autodiff(d_square2, Forward, 4, Dualv, Dualv)]
34+
#[autodiff(d_square3, Forward, 4, Dual, Dual)]
35+
fn square(x: &[f32], y: &mut [f32]) {
36+
assert!(x.len() >= 4);
37+
assert!(y.len() >= 5);
38+
y[0] = 4.3 * x[0] + 1.2 * x[1] + 3.4 * x[2] + 2.1 * x[3];
39+
y[1] = 2.3 * x[0] + 4.5 * x[1] + 1.7 * x[2] + 6.4 * x[3];
40+
y[2] = 1.1 * x[0] + 3.3 * x[1] + 2.5 * x[2] + 4.7 * x[3];
41+
y[3] = 5.2 * x[0] + 1.4 * x[1] + 2.6 * x[2] + 3.8 * x[3];
42+
y[4] = 1.0 * x[0] + 2.0 * x[1] + 3.0 * x[2] + 4.0 * x[3];
43+
}
44+
45+
fn main() {
46+
let x1 = std::hint::black_box(vec![0.0, 1.0, 2.0, 3.0]);
47+
48+
let dx1 = std::hint::black_box(vec![1.0; 12]);
49+
50+
let z1 = std::hint::black_box(vec![1.0, 0.0, 0.0, 0.0]);
51+
let z2 = std::hint::black_box(vec![0.0, 1.0, 0.0, 0.0]);
52+
let z3 = std::hint::black_box(vec![0.0, 0.0, 1.0, 0.0]);
53+
let z4 = std::hint::black_box(vec![0.0, 0.0, 0.0, 1.0]);
54+
55+
let z5 = std::hint::black_box(vec![
56+
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
57+
]);
58+
59+
let mut y1 = std::hint::black_box(vec![0.0; 5]);
60+
let mut y2 = std::hint::black_box(vec![0.0; 5]);
61+
let mut y3 = std::hint::black_box(vec![0.0; 5]);
62+
let mut y4 = std::hint::black_box(vec![0.0; 5]);
63+
64+
let mut y5 = std::hint::black_box(vec![0.0; 5]);
65+
66+
let mut y6 = std::hint::black_box(vec![0.0; 5]);
67+
68+
let mut dy1_1 = std::hint::black_box(vec![0.0; 5]);
69+
let mut dy1_2 = std::hint::black_box(vec![0.0; 5]);
70+
let mut dy1_3 = std::hint::black_box(vec![0.0; 5]);
71+
let mut dy1_4 = std::hint::black_box(vec![0.0; 5]);
72+
73+
let mut dy2 = std::hint::black_box(vec![0.0; 20]);
74+
75+
let mut dy3_1 = std::hint::black_box(vec![0.0; 5]);
76+
let mut dy3_2 = std::hint::black_box(vec![0.0; 5]);
77+
let mut dy3_3 = std::hint::black_box(vec![0.0; 5]);
78+
let mut dy3_4 = std::hint::black_box(vec![0.0; 5]);
79+
80+
// scalar.
81+
d_square1(&x1, &z1, &mut y1, &mut dy1_1);
82+
d_square1(&x1, &z2, &mut y2, &mut dy1_2);
83+
d_square1(&x1, &z3, &mut y3, &mut dy1_3);
84+
d_square1(&x1, &z4, &mut y4, &mut dy1_4);
85+
86+
// assert y1 == y2 == y3 == y4
87+
for i in 0..5 {
88+
assert_eq!(y1[i], y2[i]);
89+
assert_eq!(y1[i], y3[i]);
90+
assert_eq!(y1[i], y4[i]);
91+
}
92+
93+
// batch mode A)
94+
d_square2(&x1, &z5, &mut y5, &mut dy2);
95+
96+
// assert y1 == y2 == y3 == y4 == y5
97+
for i in 0..5 {
98+
assert_eq!(y1[i], y5[i]);
99+
}
100+
101+
// batch mode B)
102+
d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4);
103+
for i in 0..5 {
104+
assert_eq!(y5[i], y6[i]);
105+
}
106+
107+
for i in 0..5 {
108+
assert_eq!(dy2[0..5][i], dy3_1[i]);
109+
assert_eq!(dy2[5..10][i], dy3_2[i]);
110+
assert_eq!(dy2[10..15][i], dy3_3[i]);
111+
assert_eq!(dy2[15..20][i], dy3_4[i]);
112+
}
113+
}

tests/ui/autodiff/visibility.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

tests/ui/autodiff/visibility.std_autodiff.stderr

Lines changed: 0 additions & 24 deletions
This file was deleted.

tests/ui/feature-gates/feature-gate-autodiff-use.has_support.stderr

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/ui/feature-gates/feature-gate-autodiff-use.no_support.stderr

Lines changed: 0 additions & 29 deletions
This file was deleted.

tests/ui/feature-gates/feature-gate-autodiff-use.rs

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/ui/feature-gates/feature-gate-autodiff.has_support.stderr

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)