Skip to content

Commit 02d8763

Browse files
committed
add enzyme as submodule and build it during bootstrap
1 parent 8c18a66 commit 02d8763

File tree

12 files changed

+186
-0
lines changed

12 files changed

+186
-0
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@
4747
path = src/tools/rustc-perf
4848
url = https://github.com/rust-lang/rustc-perf.git
4949
shallow = true
50+
[submodule "src/tools/enzyme"]
51+
path = src/tools/enzyme
52+
url = [email protected]:EnzymeAD/Enzyme.git
53+
shallow = true

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,29 @@ impl Step for Assemble {
17721772
// use that to bootstrap this compiler forward.
17731773
let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build);
17741774

1775+
1776+
// Build enzyme
1777+
let enzyme_install =
1778+
Some(builder.ensure(llvm::Enzyme { target: build_compiler.host }));
1779+
//let enzyme_install = if builder.config.llvm_enzyme {
1780+
// Some(builder.ensure(llvm::Enzyme { target: build_compiler.host }))
1781+
//} else {
1782+
// None
1783+
//};
1784+
1785+
if let Some(enzyme_install) = enzyme_install {
1786+
let src_lib = enzyme_install.join("build/Enzyme/LLVMEnzyme-19.so");
1787+
1788+
let libdir = builder.sysroot_libdir(build_compiler, build_compiler.host);
1789+
let target_libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
1790+
let dst_lib = libdir.join("libLLVMEnzyme-19.so");
1791+
let target_dst_lib = target_libdir.join("libLLVMEnzyme-19.so");
1792+
//builder.copy_extra_objects(builder, &compiler, target);
1793+
//builder.copy_extra_objects(builder, &compiler, target);
1794+
builder.copy_link(&src_lib, &dst_lib);
1795+
builder.copy_link(&src_lib, &target_dst_lib);
1796+
}
1797+
17751798
// Build the libraries for this compiler to link to (i.e., the libraries
17761799
// it uses at runtime). NOTE: Crates the target compiler compiles don't
17771800
// link to these. (FIXME: Is that correct? It seems to be correct most

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,7 @@ impl Step for Extended {
15221522
add_component!("llvm-components" => LlvmTools { target });
15231523
add_component!("clippy" => Clippy { compiler, target });
15241524
add_component!("miri" => Miri { compiler, target });
1525+
add_component!("enzyme" => Enzyme { compiler, target });
15251526
add_component!("analysis" => Analysis { compiler, target });
15261527
add_component!("rustc-codegen-cranelift" => CodegenBackend {
15271528
compiler: builder.compiler(stage, target),
@@ -2400,6 +2401,55 @@ impl Step for BuildManifest {
24002401
}
24012402
}
24022403

2404+
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
2405+
pub struct Enzyme {
2406+
pub compiler: Compiler,
2407+
pub target: TargetSelection,
2408+
}
2409+
2410+
impl Step for Enzyme {
2411+
type Output = Option<GeneratedTarball>;
2412+
const DEFAULT: bool = false;
2413+
const ONLY_HOSTS: bool = true;
2414+
2415+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
2416+
run.alias("enzyme")
2417+
}
2418+
2419+
fn make_run(run: RunConfig<'_>) {
2420+
run.builder.ensure(Enzyme {
2421+
compiler: run.builder.compiler_for(
2422+
run.builder.top_stage,
2423+
run.builder.config.build,
2424+
run.target,
2425+
),
2426+
target: run.target,
2427+
});
2428+
}
2429+
2430+
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
2431+
//let build_manifest = builder.tool_exe(Tool::Enzyme);
2432+
2433+
//let tarball = Tarball::new(builder, "enzyme", &self.target.triple);
2434+
//tarball.add_file(build_manifest, "bin", 0o755);
2435+
2436+
//tarball.generate()
2437+
let compiler = self.compiler;
2438+
let target = self.target;
2439+
dbg!(&compiler);
2440+
dbg!("building enzyme in build_steps/dist.rs");
2441+
2442+
let enzyme =
2443+
builder.ensure(tool::Enzyme { compiler, target });
2444+
let mut tarball = Tarball::new(builder, "enzyme", &target.triple);
2445+
tarball.set_overlay(OverlayKind::Enzyme);
2446+
tarball.is_preview(true);
2447+
tarball.add_file(enzyme, "bin", 0o755);
2448+
tarball.add_legal_and_readme_to("share/doc/enzyme");
2449+
Some(tarball.generate())
2450+
}
2451+
}
2452+
24032453
/// Tarball containing artifacts necessary to reproduce the build of rustc.
24042454
///
24052455
/// Currently this is the PGO profile data.

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ impl Step for Llvm {
529529
}
530530
};
531531

532+
533+
// Manuel: TODO: Do we need that for Enzyme too?
532534
// When building LLVM with LLVM_LINK_LLVM_DYLIB for macOS, an unversioned
533535
// libLLVM.dylib will be built. However, llvm-config will still look
534536
// for a versioned path like libLLVM-14.dylib. Manually create a symbolic
@@ -849,6 +851,76 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option<OsString> {
849851
.or_else(|| env::var_os(var_base))
850852
}
851853

854+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
855+
pub struct Enzyme {
856+
pub target: TargetSelection,
857+
}
858+
859+
impl Step for Enzyme {
860+
type Output = PathBuf;
861+
const ONLY_HOSTS: bool = true;
862+
863+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
864+
run.path("src/tools/enzyme/enzyme")
865+
}
866+
867+
fn make_run(run: RunConfig<'_>) {
868+
run.builder.ensure(Enzyme { target: run.target });
869+
}
870+
871+
/// Compile Enzyme for `target`.
872+
fn run(self, builder: &Builder<'_>) -> PathBuf {
873+
builder.require_submodule(
874+
"src/tools/enzyme",
875+
Some("The Enzyme sources are required for autodiff."),
876+
);
877+
if builder.config.dry_run() {
878+
let out_dir = builder.enzyme_out(self.target);
879+
return out_dir;
880+
}
881+
let target = self.target;
882+
883+
let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: self.target });
884+
885+
let out_dir = builder.enzyme_out(target);
886+
let done_stamp = out_dir.join("enzyme-finished-building");
887+
if done_stamp.exists() {
888+
return out_dir;
889+
}
890+
891+
builder.info(&format!("Building Enzyme for {}", target));
892+
let _time = helpers::timeit(&builder);
893+
t!(fs::create_dir_all(&out_dir));
894+
895+
builder.update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap());
896+
let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
897+
// TODO: Find a nicer way to use Enzyme Debug builds
898+
//cfg.profile("Debug");
899+
//cfg.define("CMAKE_BUILD_TYPE", "Debug");
900+
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
901+
902+
// Re-use the same flags as llvm to control the level of debug information
903+
// generated for lld.
904+
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
905+
(false, _) => "Debug",
906+
(true, false) => "Release",
907+
(true, true) => "RelWithDebInfo",
908+
};
909+
910+
cfg.out_dir(&out_dir)
911+
.profile(profile)
912+
.env("LLVM_CONFIG_REAL", &llvm_config)
913+
.define("LLVM_ENABLE_ASSERTIONS", "ON")
914+
.define("ENZYME_EXTERNAL_SHARED_LIB", "OFF")
915+
.define("LLVM_DIR", builder.llvm_out(target));
916+
917+
cfg.build();
918+
919+
t!(File::create(&done_stamp));
920+
out_dir
921+
}
922+
}
923+
852924
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
853925
pub struct Lld {
854926
pub target: TargetSelection,

src/bootstrap/src/core/build_steps/tool.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ bootstrap_tool!(
325325
Compiletest, "src/tools/compiletest", "compiletest", is_unstable_tool = true, allow_features = "test";
326326
BuildManifest, "src/tools/build-manifest", "build-manifest";
327327
RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
328+
Enzyme, "src/tools/enzyme", "enzyme";
328329
RustInstaller, "src/tools/rust-installer", "rust-installer";
329330
RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes";
330331
LintDocs, "src/tools/lint-docs", "lint-docs";

src/bootstrap/src/core/builder.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ impl<'a> Builder<'a> {
798798
tool::Miri,
799799
tool::CargoMiri,
800800
llvm::Lld,
801+
llvm::Enzyme,
801802
llvm::CrtBeginEnd,
802803
tool::RustdocGUITest,
803804
tool::OptimizedDist,
@@ -1582,6 +1583,10 @@ impl<'a> Builder<'a> {
15821583
rustflags.arg(sysroot_str);
15831584
}
15841585

1586+
// https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20link.20new.20library.20into.20stage1.2Frustc
1587+
rustflags.arg("-l");
1588+
rustflags.arg("LLVMEnzyme-19");
1589+
15851590
let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling {
15861591
Some(setting) => {
15871592
// If an explicit setting is given, use that

src/bootstrap/src/core/config/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ pub struct Config {
213213
// llvm codegen options
214214
pub llvm_assertions: bool,
215215
pub llvm_tests: bool,
216+
pub llvm_enzyme: bool,
216217
pub llvm_plugins: bool,
217218
pub llvm_optimize: bool,
218219
pub llvm_thin_lto: bool,
@@ -876,6 +877,7 @@ define_config! {
876877
release_debuginfo: Option<bool> = "release-debuginfo",
877878
assertions: Option<bool> = "assertions",
878879
tests: Option<bool> = "tests",
880+
enzyme: Option<bool> = "enzyme",
879881
plugins: Option<bool> = "plugins",
880882
ccache: Option<StringOrBool> = "ccache",
881883
static_libstdcpp: Option<bool> = "static-libstdcpp",
@@ -1561,6 +1563,7 @@ impl Config {
15611563
// we'll infer default values for them later
15621564
let mut llvm_assertions = None;
15631565
let mut llvm_tests = None;
1566+
let mut llvm_enzyme = None;
15641567
let mut llvm_plugins = None;
15651568
let mut debug = None;
15661569
let mut debug_assertions = None;
@@ -1707,6 +1710,8 @@ impl Config {
17071710
config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
17081711
config.rustc_parallel =
17091712
parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
1713+
config.llvm_enzyme =
1714+
llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly");
17101715
config.rustc_default_linker = default_linker;
17111716
config.musl_root = musl_root.map(PathBuf::from);
17121717
config.save_toolstates = save_toolstates.map(PathBuf::from);
@@ -1791,6 +1796,7 @@ impl Config {
17911796
release_debuginfo,
17921797
assertions,
17931798
tests,
1799+
enzyme,
17941800
plugins,
17951801
ccache,
17961802
static_libstdcpp,
@@ -1824,6 +1830,7 @@ impl Config {
18241830
set(&mut config.ninja_in_file, ninja);
18251831
llvm_assertions = assertions;
18261832
llvm_tests = tests;
1833+
llvm_enzyme = enzyme;
18271834
llvm_plugins = plugins;
18281835
set(&mut config.llvm_optimize, optimize_toml);
18291836
set(&mut config.llvm_thin_lto, thin_lto);
@@ -2025,6 +2032,7 @@ impl Config {
20252032

20262033
config.llvm_assertions = llvm_assertions.unwrap_or(false);
20272034
config.llvm_tests = llvm_tests.unwrap_or(false);
2035+
config.llvm_enzyme = llvm_enzyme.unwrap_or(true);
20282036
config.llvm_plugins = llvm_plugins.unwrap_or(false);
20292037
config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true));
20302038

src/bootstrap/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
7575
#[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
7676
const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
7777
(None, "bootstrap", None),
78+
(Some(Mode::Rustc), "llvm_enzyme", None),
79+
(Some(Mode::Codegen), "llvm_enzyme", None),
80+
(Some(Mode::ToolRustc), "llvm_enzyme", None),
7881
(Some(Mode::Rustc), "parallel_compiler", None),
7982
(Some(Mode::ToolRustc), "parallel_compiler", None),
8083
(Some(Mode::ToolRustc), "rust_analyzer", None),
@@ -138,6 +141,7 @@ pub struct Build {
138141
clippy_info: GitInfo,
139142
miri_info: GitInfo,
140143
rustfmt_info: GitInfo,
144+
enzyme_info: GitInfo,
141145
in_tree_llvm_info: GitInfo,
142146
local_rebuild: bool,
143147
fail_fast: bool,
@@ -304,6 +308,7 @@ impl Build {
304308
let clippy_info = GitInfo::new(omit_git_hash, &src.join("src/tools/clippy"));
305309
let miri_info = GitInfo::new(omit_git_hash, &src.join("src/tools/miri"));
306310
let rustfmt_info = GitInfo::new(omit_git_hash, &src.join("src/tools/rustfmt"));
311+
let enzyme_info = GitInfo::new(omit_git_hash, &src.join("src/tools/enzyme"));
307312

308313
// we always try to use git for LLVM builds
309314
let in_tree_llvm_info = GitInfo::new(false, &src.join("src/llvm-project"));
@@ -391,6 +396,7 @@ impl Build {
391396
clippy_info,
392397
miri_info,
393398
rustfmt_info,
399+
enzyme_info,
394400
in_tree_llvm_info,
395401
cc: RefCell::new(HashMap::new()),
396402
cxx: RefCell::new(HashMap::new()),
@@ -849,6 +855,10 @@ impl Build {
849855
}
850856
}
851857

858+
fn enzyme_out(&self, target: TargetSelection) -> PathBuf {
859+
self.out.join(&*target.triple).join("enzyme")
860+
}
861+
852862
fn lld_out(&self, target: TargetSelection) -> PathBuf {
853863
self.out.join(&*target.triple).join("lld")
854864
}

src/bootstrap/src/utils/tarball.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub(crate) enum OverlayKind {
2020
Cargo,
2121
Clippy,
2222
Miri,
23+
Enzyme,
2324
Rustfmt,
2425
Rls,
2526
RustAnalyzer,
@@ -61,6 +62,10 @@ impl OverlayKind {
6162
"src/tools/rust-analyzer/LICENSE-APACHE",
6263
"src/tools/rust-analyzer/LICENSE-MIT",
6364
],
65+
OverlayKind::Enzyme => &[
66+
"src/tools/enzyme/README.md",
67+
"src/tools/enzyme/LICENSE",
68+
],
6469
OverlayKind::RustcCodegenCranelift => &[
6570
"compiler/rustc_codegen_cranelift/Readme.md",
6671
"compiler/rustc_codegen_cranelift/LICENSE-APACHE",
@@ -93,6 +98,9 @@ impl OverlayKind {
9398
OverlayKind::RustAnalyzer => builder
9499
.rust_analyzer_info
95100
.version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")),
101+
OverlayKind::Enzyme => {
102+
builder.enzyme_info.version(builder, &builder.release_num("enzyme"))
103+
}
96104
OverlayKind::RustcCodegenCranelift => builder.rust_version(),
97105
OverlayKind::LlvmBitcodeLinker => builder.rust_version(),
98106
}

src/tools/build-manifest/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ impl Builder {
470470
| PkgType::Rls
471471
| PkgType::RustAnalyzer
472472
| PkgType::Rustfmt
473+
| PkgType::Enzyme
473474
| PkgType::LlvmTools
474475
| PkgType::RustAnalysis
475476
| PkgType::JsonDocs

0 commit comments

Comments
 (0)