Skip to content

Commit d457856

Browse files
committed
Refactor Enzyme step
1 parent 423280e commit d457856

File tree

2 files changed

+46
-24
lines changed

2 files changed

+46
-24
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/llvm.rs

Lines changed: 40 additions & 8 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,7 @@ impl Step for Enzyme {
952975
stamp.path().display()
953976
));
954977
}
955-
return out_dir;
978+
return BuiltEnzyme { enzyme: dylib };
956979
}
957980

958981
let llvm_cmake_dir = builder.llvm_out(target).join("lib/cmake/llvm");
@@ -969,7 +992,6 @@ impl Step for Enzyme {
969992
let _time = helpers::timeit(builder);
970993
t!(fs::create_dir_all(&out_dir));
971994

972-
builder.config.update_submodule("src/tools/enzyme");
973995
let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
974996
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
975997

@@ -993,8 +1015,18 @@ impl Step for Enzyme {
9931015

9941016
cfg.build();
9951017

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+
9961028
t!(stamp.write());
997-
out_dir
1029+
BuiltEnzyme { enzyme: dylib }
9981030
}
9991031
}
10001032

0 commit comments

Comments
 (0)