Rollup merge of #150060 - ZuseZ4:autodiff-dlopen-ice, r=Kobzol

autodiff: emit an error if we fail to find libEnzyme

Tested manually by moving libEnzyme-21.so away. We should adjust the error msg. once we have the component up.

It's the first usage within rustc of this experimental feature, but afaik we're open to dogfooding those for test purpose, right?

r? ``@Kobzol``
This commit is contained in:
Jacob Pratt 2025-12-16 23:10:10 -05:00 committed by GitHub
commit 641100c391
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 12 deletions

View file

@ -1,9 +1,10 @@
codegen_llvm_autodiff_component_unavailable = failed to load our autodiff backend. Did you install it via rustup?
codegen_llvm_autodiff_without_enable = using the autodiff feature requires -Z autodiff=Enable
codegen_llvm_autodiff_without_lto = using the autodiff feature requires setting `lto="fat"` in your Cargo.toml
codegen_llvm_copy_bitcode = failed to copy bitcode to object file: {$err}
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
codegen_llvm_from_llvm_diag = {$message}

View file

@ -32,6 +32,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
}
}
#[cfg(feature = "llvm_enzyme")]
#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_component_unavailable)]
pub(crate) struct AutoDiffComponentUnavailable;
#[derive(Diagnostic)]
#[diag(codegen_llvm_autodiff_without_lto)]
pub(crate) struct AutoDiffWithoutLto;

View file

@ -13,6 +13,7 @@
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
#![feature(macro_derive)]
#![feature(once_cell_try)]
#![feature(trim_prefix_suffix)]
#![feature(try_blocks)]
// tidy-alphabetical-end
@ -247,7 +248,9 @@ impl CodegenBackend for LlvmCodegenBackend {
use crate::back::lto::enable_autodiff_settings;
if sess.opts.unstable_opts.autodiff.contains(&AutoDiff::Enable) {
drop(llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot));
if let Err(_) = llvm::EnzymeWrapper::get_or_init(&sess.opts.sysroot) {
sess.dcx().emit_fatal(crate::errors::AutoDiffComponentUnavailable);
}
enable_autodiff_settings(&sess.opts.unstable_opts.autodiff);
}
}

View file

@ -199,15 +199,13 @@ pub(crate) mod Enzyme_AD {
/// Safe to call multiple times - subsequent calls are no-ops due to OnceLock.
pub(crate) fn get_or_init(
sysroot: &rustc_session::config::Sysroot,
) -> MutexGuard<'static, Self> {
ENZYME_INSTANCE
.get_or_init(|| {
Self::call_dynamic(sysroot)
.unwrap_or_else(|e| bug!("failed to load Enzyme: {e}"))
.into()
})
.lock()
.unwrap()
) -> Result<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
let mtx: &'static Mutex<EnzymeWrapper> = ENZYME_INSTANCE.get_or_try_init(|| {
let w = Self::call_dynamic(sysroot)?;
Ok::<_, Box<dyn std::error::Error>>(Mutex::new(w))
})?;
Ok(mtx.lock().unwrap())
}
/// Get the EnzymeWrapper instance. Panics if not initialized.
@ -475,7 +473,7 @@ pub(crate) mod Fallback_AD {
impl EnzymeWrapper {
pub(crate) fn get_or_init(
_sysroot: &rustc_session::config::Sysroot,
) -> MutexGuard<'static, Self> {
) -> Result<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
}