Skip to content

Commit bf1f04d

Browse files
Auto merge of #150071 - Kobzol:dist-enzyme, r=<try>
Add dist step for Enzyme try-job: dist-x86_64-linux
2 parents 2dc3024 + 06e9756 commit bf1f04d

File tree

7 files changed

+111
-28
lines changed

7 files changed

+111
-28
lines changed

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,23 +2274,13 @@ impl Step for Assemble {
22742274
builder.compiler(target_compiler.stage - 1, builder.config.host_target);
22752275

22762276
// Build enzyme
2277-
if builder.config.llvm_enzyme && !builder.config.dry_run() {
2277+
if builder.config.llvm_enzyme {
22782278
debug!("`llvm_enzyme` requested");
2279-
let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host });
2280-
if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
2281-
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
2282-
let lib_ext = std::env::consts::DLL_EXTENSION;
2283-
let libenzyme = format!("libEnzyme-{llvm_version_major}");
2284-
let src_lib =
2285-
enzyme_install.join("build/Enzyme").join(&libenzyme).with_extension(lib_ext);
2286-
let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host);
2287-
let target_libdir =
2288-
builder.sysroot_target_libdir(target_compiler, target_compiler.host);
2289-
let dst_lib = libdir.join(&libenzyme).with_extension(lib_ext);
2290-
let target_dst_lib = target_libdir.join(&libenzyme).with_extension(lib_ext);
2291-
builder.copy_link(&src_lib, &dst_lib, FileType::NativeLibrary);
2292-
builder.copy_link(&src_lib, &target_dst_lib, FileType::NativeLibrary);
2293-
}
2279+
let enzyme = builder.ensure(llvm::Enzyme { target: build_compiler.host });
2280+
let target_libdir =
2281+
builder.sysroot_target_libdir(target_compiler, target_compiler.host);
2282+
let target_dst_lib = target_libdir.join(enzyme.enzyme_filename());
2283+
builder.copy_link(&enzyme.enzyme_path(), &target_dst_lib, FileType::NativeLibrary);
22942284
}
22952285

22962286
// Build the libraries for this compiler to link to (i.e., the libraries

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,55 @@ impl Step for LlvmBitcodeLinker {
25922592
}
25932593
}
25942594

2595+
/// Distributes the `enzyme` library so that it can be used by a compiler whose host
2596+
/// is `target`.
2597+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2598+
pub struct Enzyme {
2599+
/// Enzyme will by usable by rustc on this host.
2600+
pub target: TargetSelection,
2601+
}
2602+
2603+
impl Step for Enzyme {
2604+
type Output = Option<GeneratedTarball>;
2605+
const IS_HOST: bool = true;
2606+
2607+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
2608+
run.alias("enzyme")
2609+
}
2610+
2611+
fn is_default_step(builder: &Builder<'_>) -> bool {
2612+
builder.config.llvm_enzyme
2613+
}
2614+
2615+
fn make_run(run: RunConfig<'_>) {
2616+
run.builder.ensure(Enzyme { target: run.target });
2617+
}
2618+
2619+
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
2620+
// This prevents Enzyme from being built for "dist"
2621+
// or "install" on the stable/beta channels. It is not yet stable and
2622+
// should not be included.
2623+
if !builder.build.unstable_features() {
2624+
return None;
2625+
}
2626+
2627+
let target = self.target;
2628+
2629+
let enzyme = builder.ensure(llvm::Enzyme { target });
2630+
2631+
let target_libdir = format!("lib/rustlib/{}/lib", target.triple);
2632+
2633+
// Prepare the image directory
2634+
let mut tarball = Tarball::new(builder, "enzyme", &target.triple);
2635+
tarball.set_overlay(OverlayKind::Enzyme);
2636+
tarball.is_preview(true);
2637+
2638+
tarball.add_file(enzyme.enzyme_path(), target_libdir, FileType::NativeLibrary);
2639+
2640+
Some(tarball.generate())
2641+
}
2642+
}
2643+
25952644
/// Tarball intended for internal consumption to ease rustc/std development.
25962645
///
25972646
/// Should not be considered stable by end users.

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

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ use std::path::{Path, PathBuf};
1414
use std::sync::OnceLock;
1515
use std::{env, fs};
1616

17+
use build_helper::exit;
1718
use build_helper::git::PathFreshness;
1819

20+
use crate::core::build_steps::llvm;
1921
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, StepMetadata};
2022
use crate::core::config::{Config, TargetSelection};
2123
use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
@@ -896,13 +898,28 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option<OsString> {
896898
.or_else(|| env::var_os(var_base))
897899
}
898900

901+
#[derive(Clone)]
902+
pub struct BuiltEnzyme {
903+
/// Path to the libEnzyme dylib.
904+
enzyme: PathBuf,
905+
}
906+
907+
impl BuiltEnzyme {
908+
pub fn enzyme_path(&self) -> PathBuf {
909+
self.enzyme.clone()
910+
}
911+
pub fn enzyme_filename(&self) -> String {
912+
self.enzyme.file_name().unwrap().to_str().unwrap().to_owned()
913+
}
914+
}
915+
899916
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
900917
pub struct Enzyme {
901918
pub target: TargetSelection,
902919
}
903920

904921
impl Step for Enzyme {
905-
type Output = PathBuf;
922+
type Output = BuiltEnzyme;
906923
const IS_HOST: bool = true;
907924

908925
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -914,16 +931,16 @@ impl Step for Enzyme {
914931
}
915932

916933
/// Compile Enzyme for `target`.
917-
fn run(self, builder: &Builder<'_>) -> PathBuf {
934+
fn run(self, builder: &Builder<'_>) -> Self::Output {
918935
builder.require_submodule(
919936
"src/tools/enzyme",
920937
Some("The Enzyme sources are required for autodiff."),
921938
);
939+
let target = self.target;
940+
922941
if builder.config.dry_run() {
923-
let out_dir = builder.enzyme_out(self.target);
924-
return out_dir;
942+
return BuiltEnzyme { enzyme: builder.config.tempdir().join("enzyme-dryrun") };
925943
}
926-
let target = self.target;
927944

928945
let LlvmResult { host_llvm_config, .. } = builder.ensure(Llvm { target: self.target });
929946

@@ -939,6 +956,12 @@ impl Step for Enzyme {
939956
let out_dir = builder.enzyme_out(target);
940957
let stamp = BuildStamp::new(&out_dir).with_prefix("enzyme").add_stamp(smart_stamp_hash);
941958

959+
let llvm_version_major = llvm::get_llvm_version_major(builder, &host_llvm_config);
960+
let lib_ext = std::env::consts::DLL_EXTENSION;
961+
let libenzyme = format!("libEnzyme-{llvm_version_major}");
962+
let build_dir = out_dir.join("lib");
963+
let dylib = build_dir.join(&libenzyme).with_extension(lib_ext);
964+
942965
trace!("checking build stamp to see if we need to rebuild enzyme artifacts");
943966
if stamp.is_up_to_date() {
944967
trace!(?out_dir, "enzyme build artifacts are up to date");
@@ -952,7 +975,15 @@ impl Step for Enzyme {
952975
stamp.path().display()
953976
));
954977
}
955-
return out_dir;
978+
return BuiltEnzyme { enzyme: dylib };
979+
}
980+
981+
let llvm_cmake_dir = builder.llvm_out(target).join("lib/cmake/llvm");
982+
if !builder.config.dry_run() && !llvm_cmake_dir.is_dir() {
983+
builder.info(&format!(
984+
"WARNING: {} does not exist, Enzyme build will likely fail",
985+
llvm_cmake_dir.display()
986+
));
956987
}
957988

958989
trace!(?target, "(re)building enzyme artifacts");
@@ -961,9 +992,6 @@ impl Step for Enzyme {
961992
let _time = helpers::timeit(builder);
962993
t!(fs::create_dir_all(&out_dir));
963994

964-
builder
965-
.config
966-
.update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap());
967995
let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
968996
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
969997

@@ -983,12 +1011,22 @@ impl Step for Enzyme {
9831011
.define("LLVM_ENABLE_ASSERTIONS", "ON")
9841012
.define("ENZYME_EXTERNAL_SHARED_LIB", "ON")
9851013
.define("ENZYME_BC_LOADER", "OFF")
986-
.define("LLVM_DIR", builder.llvm_out(target));
1014+
.define("LLVM_DIR", llvm_cmake_dir);
9871015

9881016
cfg.build();
9891017

1018+
// At this point, `out_dir` should contain the built libEnzyme-<LLVM-version>.<dylib-ext>
1019+
// file.
1020+
if !dylib.exists() {
1021+
eprintln!(
1022+
"`{libenzyme}` not found in `{}`. Either the build has failed or Enzyme was built with a wrong version of LLVM",
1023+
build_dir.display()
1024+
);
1025+
exit!(1);
1026+
}
1027+
9901028
t!(stamp.write());
991-
out_dir
1029+
BuiltEnzyme { enzyme: dylib }
9921030
}
9931031
}
9941032

src/bootstrap/src/core/builder/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,7 @@ impl<'a> Builder<'a> {
979979
dist::LlvmTools,
980980
dist::LlvmBitcodeLinker,
981981
dist::RustDev,
982+
dist::Enzyme,
982983
dist::Bootstrap,
983984
dist::Extended,
984985
// It seems that PlainSourceTarball somehow changes how some of the tools

src/bootstrap/src/core/config/toml/llvm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub fn check_incompatible_options_for_ci_llvm(
117117
enable_warnings,
118118
download_ci_llvm: _,
119119
build_config,
120-
enzyme: _,
120+
enzyme,
121121
} = ci_llvm_config;
122122

123123
err!(current_llvm_config.optimize, optimize);
@@ -139,6 +139,7 @@ pub fn check_incompatible_options_for_ci_llvm(
139139
err!(current_llvm_config.clang, clang);
140140
err!(current_llvm_config.build_config, build_config);
141141
err!(current_llvm_config.plugins, plugins);
142+
err!(current_llvm_config.enzyme, enzyme);
142143

143144
warn!(current_llvm_config.enable_warnings, enable_warnings);
144145

src/bootstrap/src/utils/tarball.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub(crate) enum OverlayKind {
2626
RustAnalyzer,
2727
RustcCodegenCranelift,
2828
LlvmBitcodeLinker,
29+
Enzyme,
2930
}
3031

3132
impl OverlayKind {
@@ -35,6 +36,7 @@ impl OverlayKind {
3536
OverlayKind::Llvm => {
3637
&["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"]
3738
}
39+
OverlayKind::Enzyme => &["src/tools/enzyme/LICENSE", "src/tools/enzyme/Readme.md"],
3840
OverlayKind::Cargo => &[
3941
"src/tools/cargo/README.md",
4042
"src/tools/cargo/LICENSE-MIT",
@@ -94,6 +96,7 @@ impl OverlayKind {
9496
.version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")),
9597
OverlayKind::RustcCodegenCranelift => builder.rust_version(),
9698
OverlayKind::LlvmBitcodeLinker => builder.rust_version(),
99+
OverlayKind::Enzyme => builder.rust_version(),
97100
}
98101
}
99102
}

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.bootstrap-override-lld=true \
9697
--set rust.lto=thin \

0 commit comments

Comments
 (0)