remove llvm_enzyme and enzyme fallbacks from most places, enable the autodiff frontend on nightly

This commit is contained in:
Manuel Drehwald 2025-12-19 11:02:57 -08:00
parent ed0006a7ba
commit c34ea6e56d
21 changed files with 46 additions and 223 deletions

View file

@ -55,7 +55,6 @@ builtin_macros_assert_requires_expression = macro requires an expression as an a
builtin_macros_autodiff = autodiff must be applied to function
builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode
builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode
builtin_macros_autodiff_not_build = this rustc version does not support autodiff
builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found}
builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode
builtin_macros_autodiff_ty_activity = {$act} can not be used for this type

View file

@ -209,11 +209,6 @@ mod llvm_enzyme {
mut item: Annotatable,
mode: DiffMode,
) -> Vec<Annotatable> {
// FIXME(bjorn3) maybe have the backend directly tell if autodiff is supported?
if cfg!(not(feature = "llvm_enzyme")) {
ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span });
return vec![item];
}
let dcx = ecx.sess.dcx();
// first get information about the annotable item: visibility, signature, name and generic

View file

@ -216,17 +216,6 @@ mod autodiff {
}
}
pub(crate) use ad_fallback::*;
mod ad_fallback {
use super::*;
#[derive(Diagnostic)]
#[diag(builtin_macros_autodiff_not_build)]
pub(crate) struct AutoDiffSupportNotBuild {
#[primary_span]
pub(crate) span: Span,
}
}
#[derive(Diagnostic)]
#[diag(builtin_macros_concat_bytes_invalid)]
pub(crate) struct ConcatBytesInvalid {

View file

@ -14,7 +14,7 @@ bitflags = "2.4.1"
gimli = "0.31"
itertools = "0.12"
libc = "0.2"
libloading = { version = "0.9.0", optional = true }
libloading = { version = "0.9.0" }
measureme = "12.0.1"
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
rustc-demangle = "0.1.21"
@ -47,7 +47,7 @@ tracing = "0.1"
[features]
# tidy-alphabetical-start
check_only = ["rustc_llvm/check_only"]
llvm_enzyme = ["dep:libloading"]
llvm_enzyme = []
llvm_offload = []
# tidy-alphabetical-end

View file

@ -528,7 +528,6 @@ fn thin_lto(
}
}
#[cfg(feature = "llvm_enzyme")]
pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
let mut enzyme = llvm::EnzymeWrapper::get_instance();

View file

@ -568,8 +568,7 @@ pub(crate) unsafe fn llvm_optimize(
// FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting
// differentiated.
let consider_ad =
cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable);
let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable);
let run_enzyme = autodiff_stage == AutodiffStage::DuringAD;
let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore);
let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter);
@ -819,8 +818,7 @@ pub(crate) fn optimize(
// If we know that we will later run AD, then we disable vectorization and loop unrolling.
// Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD).
let consider_ad =
cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable);
let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable);
let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD };
// The embedded bitcode is used to run LTO/ThinLTO.
// The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO.

View file

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

View file

@ -242,7 +242,9 @@ impl CodegenBackend for LlvmCodegenBackend {
fn init(&self, sess: &Session) {
llvm_util::init(sess); // Make sure llvm is inited
#[cfg(feature = "llvm_enzyme")]
// autodiff is based on Enzyme, a library which we might not have available, when it was
// neither build, nor downloaded via rustup. If autodiff is used, but not available we emit
// an early error here and abort compilation.
{
use rustc_session::config::AutoDiff;

View file

@ -86,10 +86,8 @@ pub(crate) enum LLVMRustVerifierFailureAction {
LLVMReturnStatusAction = 2,
}
#[cfg(feature = "llvm_enzyme")]
pub(crate) use self::Enzyme_AD::*;
#[cfg(feature = "llvm_enzyme")]
pub(crate) mod Enzyme_AD {
use std::ffi::{c_char, c_void};
use std::sync::{Mutex, MutexGuard, OnceLock};
@ -450,147 +448,6 @@ pub(crate) mod Enzyme_AD {
}
}
#[cfg(not(feature = "llvm_enzyme"))]
pub(crate) use self::Fallback_AD::*;
#[cfg(not(feature = "llvm_enzyme"))]
pub(crate) mod Fallback_AD {
#![allow(unused_variables)]
use std::ffi::c_void;
use std::sync::{Mutex, MutexGuard};
use libc::c_char;
use rustc_codegen_ssa::back::write::CodegenContext;
use rustc_codegen_ssa::traits::WriteBackendMethods;
use super::{CConcreteType, CTypeTreeRef, Context, EnzymeTypeTree};
pub(crate) struct EnzymeWrapper {
pub registerEnzymeAndPassPipeline: *const c_void,
}
impl EnzymeWrapper {
pub(crate) fn get_or_init(
_sysroot: &rustc_session::config::Sysroot,
) -> Result<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
}
pub(crate) fn init<'a, B: WriteBackendMethods>(
_cgcx: &'a CodegenContext<B>,
) -> &'static Mutex<Self> {
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
}
pub(crate) fn get_instance() -> MutexGuard<'static, Self> {
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
}
pub(crate) fn new_type_tree(&self) -> CTypeTreeRef {
unimplemented!()
}
pub(crate) fn new_type_tree_ct(
&self,
t: CConcreteType,
ctx: &Context,
) -> *mut EnzymeTypeTree {
unimplemented!()
}
pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef {
unimplemented!()
}
pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) {
unimplemented!()
}
pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool {
unimplemented!()
}
pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) {
unimplemented!()
}
pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) {
unimplemented!()
}
pub(crate) fn shift_indicies_eq(
&self,
tree: CTypeTreeRef,
data_layout: *const c_char,
offset: i64,
max_size: i64,
add_offset: u64,
) {
unimplemented!()
}
pub(crate) fn tree_insert_eq(
&self,
tree: CTypeTreeRef,
indices: *const i64,
len: usize,
ct: CConcreteType,
ctx: &Context,
) {
unimplemented!()
}
pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char {
unimplemented!()
}
pub(crate) fn tree_to_string_free(&self, ch: *const c_char) {
unimplemented!()
}
pub(crate) fn get_max_type_depth(&self) -> usize {
unimplemented!()
}
pub(crate) fn set_inline(&mut self, val: bool) {
unimplemented!()
}
pub(crate) fn set_print_perf(&mut self, print: bool) {
unimplemented!()
}
pub(crate) fn set_print_activity(&mut self, print: bool) {
unimplemented!()
}
pub(crate) fn set_print_type(&mut self, print: bool) {
unimplemented!()
}
pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) {
unimplemented!()
}
pub(crate) fn set_print(&mut self, print: bool) {
unimplemented!()
}
pub(crate) fn set_strict_aliasing(&mut self, strict: bool) {
unimplemented!()
}
pub(crate) fn set_loose_types(&mut self, loose: bool) {
unimplemented!()
}
pub(crate) fn set_rust_rules(&mut self, val: bool) {
unimplemented!()
}
}
}
impl TypeTree {
pub(crate) fn new() -> TypeTree {
let wrapper = EnzymeWrapper::get_instance();

View file

@ -1,15 +1,10 @@
use rustc_ast::expand::typetree::FncTree;
#[cfg(feature = "llvm_enzyme")]
use {
crate::attributes,
crate::llvm::EnzymeWrapper,
rustc_ast::expand::typetree::TypeTree as RustTypeTree,
std::ffi::{CString, c_char, c_uint},
};
use std::ffi::{CString, c_char, c_uint};
use crate::llvm::{self, Value};
use rustc_ast::expand::typetree::{FncTree, TypeTree as RustTypeTree};
use crate::attributes;
use crate::llvm::{self, EnzymeWrapper, Value};
#[cfg(feature = "llvm_enzyme")]
fn to_enzyme_typetree(
rust_typetree: RustTypeTree,
_data_layout: &str,
@ -19,7 +14,6 @@ fn to_enzyme_typetree(
process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx);
enzyme_tt
}
#[cfg(feature = "llvm_enzyme")]
fn process_typetree_recursive(
enzyme_tt: &mut llvm::TypeTree,
rust_typetree: &RustTypeTree,
@ -57,13 +51,21 @@ fn process_typetree_recursive(
}
}
#[cfg(feature = "llvm_enzyme")]
#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))]
pub(crate) fn add_tt<'ll>(
llmod: &'ll llvm::Module,
llcx: &'ll llvm::Context,
fn_def: &'ll Value,
tt: FncTree,
) {
// TypeTree processing uses functions from Enzyme, which we might not have available if we did
// not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but
// skipping this function increases the chance that Enzyme fails to compile some code.
// FIXME(autodiff): In the future we should conditionally run this function even without the
// `llvm_enzyme` feature, in case that libEnzyme was provided via rustup.
#[cfg(not(feature = "llvm_enzyme"))]
return;
let inputs = tt.args;
let ret_tt: RustTypeTree = tt.ret;
@ -113,13 +115,3 @@ pub(crate) fn add_tt<'ll>(
enzyme_wrapper.tree_to_string_free(c_str.as_ptr());
}
}
#[cfg(not(feature = "llvm_enzyme"))]
pub(crate) fn add_tt<'ll>(
_llmod: &'ll llvm::Module,
_llcx: &'ll llvm::Context,
_fn_def: &'ll Value,
_tt: FncTree,
) {
unimplemented!()
}

View file

@ -1,6 +1,6 @@
#![feature(prelude_import)]
#![no_std]
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
#[macro_use]

View file

@ -1,4 +1,4 @@
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
//@ pretty-mode:expanded

View file

@ -1,6 +1,6 @@
#![feature(prelude_import)]
#![no_std]
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
#[macro_use]

View file

@ -1,4 +1,4 @@
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
//@ pretty-mode:expanded

View file

@ -1,6 +1,6 @@
#![feature(prelude_import)]
#![no_std]
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
#[macro_use]

View file

@ -1,4 +1,4 @@
//@ needs-enzyme
//@ only-nightly
#![feature(autodiff)]
//@ pretty-mode:expanded

View file

@ -1,5 +1,6 @@
//@ ignore-enzyme
//@ revisions: std_autodiff no_std_autodiff
//@ only-nightly
//@[no_std_autodiff] check-pass
//@ proc-macro: my_macro.rs
#![crate_type = "lib"]
@ -12,5 +13,4 @@ use my_macro::autodiff_forward; // bring `autodiff_forward` in scope
#[autodiff_forward(dfoo)]
//[std_autodiff]~^^^ ERROR the name `autodiff_forward` is defined multiple times
//[std_autodiff]~^^ ERROR this rustc version does not support autodiff
fn foo() {}

View file

@ -1,5 +1,5 @@
error[E0252]: the name `autodiff_forward` is defined multiple times
--> $DIR/visibility.rs:11:5
--> $DIR/visibility.rs:12:5
|
LL | use std::autodiff::autodiff_forward;
| ------------------------------- previous import of the macro `autodiff_forward` here
@ -13,12 +13,6 @@ help: you can use `as` to change the binding name of the import
LL | use my_macro::autodiff_forward as other_autodiff_forward; // bring `autodiff_forward` in scope
| +++++++++++++++++++++++++
error: this rustc version does not support autodiff
--> $DIR/visibility.rs:13:1
|
LL | #[autodiff_forward(dfoo)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0252`.

View file

@ -1,5 +1,5 @@
error[E0658]: use of unstable library feature `autodiff`
--> $DIR/feature-gate-autodiff-use.rs:13:3
--> $DIR/feature-gate-autodiff-use.rs:16:3
|
LL | #[autodiff_reverse(dfoo)]
| ^^^^^^^^^^^^^^^^

View file

@ -1,17 +1,22 @@
//@ revisions: has_support no_support
//@[no_support] ignore-enzyme
//@[has_support] needs-enzyme
//@ revisions: nightly stable
//@[nightly] only-nightly
//@[stable] only-stable
// This checks that without enabling the autodiff feature, we can't import std::autodiff::autodiff;
#![crate_type = "lib"]
use std::autodiff::autodiff_reverse;
//[has_support]~^ ERROR use of unstable library feature `autodiff`
//[no_support]~^^ ERROR use of unstable library feature `autodiff`
//[nightly]~^ ERROR use of unstable library feature `autodiff`
//[stable]~^^ ERROR use of unstable library feature `autodiff`
//[stable]~| NOTE see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
//[stable]~| HELP add `#![feature(autodiff)]` to the crate attributes to enable
//[stable]~| NOTE this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
#[autodiff_reverse(dfoo)]
//[has_support]~^ ERROR use of unstable library feature `autodiff` [E0658]
//[no_support]~^^ ERROR use of unstable library feature `autodiff` [E0658]
//[no_support]~| ERROR this rustc version does not support autodiff
//[nightly]~^ ERROR use of unstable library feature `autodiff` [E0658]
//[stable]~^^ ERROR use of unstable library feature `autodiff` [E0658]
//[stable]~| NOTE see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
//[stable]~| HELP add `#![feature(autodiff)]` to the crate attributes to enable
//[stable]~| NOTE this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
fn foo() {}

View file

@ -1,5 +1,5 @@
error[E0658]: use of unstable library feature `autodiff`
--> $DIR/feature-gate-autodiff-use.rs:13:3
--> $DIR/feature-gate-autodiff-use.rs:16:3
|
LL | #[autodiff_reverse(dfoo)]
| ^^^^^^^^^^^^^^^^
@ -8,12 +8,6 @@ LL | #[autodiff_reverse(dfoo)]
= help: add `#![feature(autodiff)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: this rustc version does not support autodiff
--> $DIR/feature-gate-autodiff-use.rs:13:1
|
LL | #[autodiff_reverse(dfoo)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0658]: use of unstable library feature `autodiff`
--> $DIR/feature-gate-autodiff-use.rs:9:5
|
@ -24,6 +18,6 @@ LL | use std::autodiff::autodiff_reverse;
= help: add `#![feature(autodiff)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.