Skip to content

Commit 68000b0

Browse files
authored
Unrolled build for #149033
Rollup merge of #149033 - ZuseZ4:autodiff-rlib, r=bjorn3 autodiff rlib handling As I learned recently, we now apparently support rlib builds already in some cases. With the last hint from saethlin this seems to now cover all cases. To be sure I'll add a few more testcases before I mark it as ready. Once this PR lands, we should to the best of my knowledge, support autodiff in almost code locations, only vtable/dyn ptr remain unsupported for now. r? ghost closes: #148856 closes: #137520
2 parents 53732d5 + 2d1fc63 commit 68000b0

File tree

7 files changed

+116
-2
lines changed

7 files changed

+116
-2
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::mir::BinOp;
1515
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, HasTypingEnv, LayoutOf};
1616
use rustc_middle::ty::{self, GenericArgsRef, Instance, SimdAlign, Ty, TyCtxt, TypingEnv};
1717
use rustc_middle::{bug, span_bug};
18+
use rustc_session::config::CrateType;
1819
use rustc_span::{Span, Symbol, sym};
1920
use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate};
2021
use rustc_target::callconv::PassMode;
@@ -1136,8 +1137,17 @@ fn codegen_autodiff<'ll, 'tcx>(
11361137
if !tcx.sess.opts.unstable_opts.autodiff.contains(&rustc_session::config::AutoDiff::Enable) {
11371138
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutEnable);
11381139
}
1139-
if tcx.sess.lto() != rustc_session::config::Lto::Fat {
1140-
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
1140+
1141+
let ct = tcx.crate_types();
1142+
let lto = tcx.sess.lto();
1143+
if ct.len() == 1 && ct.contains(&CrateType::Executable) {
1144+
if lto != rustc_session::config::Lto::Fat {
1145+
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
1146+
}
1147+
} else {
1148+
if lto != rustc_session::config::Lto::Fat && !tcx.sess.opts.cg.linker_plugin_lto.enabled() {
1149+
let _ = tcx.dcx().emit_almost_fatal(AutoDiffWithoutLto);
1150+
}
11411151
}
11421152

11431153
let fn_args = instance.args;

compiler/rustc_mir_transform/src/cross_crate_inline.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
3434
return true;
3535
}
3636

37+
// FIXME(autodiff): replace this as per discussion in https://github.com/rust-lang/rust/pull/149033#discussion_r2535465880
38+
if tcx.has_attr(def_id, sym::autodiff_forward)
39+
|| tcx.has_attr(def_id, sym::autodiff_reverse)
40+
|| tcx.has_attr(def_id, sym::rustc_autodiff)
41+
{
42+
return true;
43+
}
44+
3745
if tcx.has_attr(def_id, sym::rustc_intrinsic) {
3846
// Intrinsic fallback bodies are always cross-crate inlineable.
3947
// To ensure that the MIR inliner doesn't cluelessly try to inline fallback

compiler/rustc_monomorphize/src/collector/autodiff.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::collector::{MonoItems, create_fn_mono_item};
77
// mono so this does not interfere in `autodiff` intrinsics
88
// codegen process. If they are unused, LLVM will remove them when
99
// compiling with O3.
10+
// FIXME(autodiff): Remove this whole file, as per discussion in
11+
// https://github.com/rust-lang/rust/pull/149033#discussion_r2535465880
1012
pub(crate) fn collect_autodiff_fn<'tcx>(
1113
tcx: TyCtxt<'tcx>,
1214
instance: ty::Instance<'tcx>,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub fn f(x: f64, y: f64) -> f64 {
2+
2.0 * x + y
3+
}
4+
5+
pub fn g(x: f64) -> f64 {
6+
2.0 * x
7+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(autodiff)]
2+
extern crate simple_dep;
3+
use std::autodiff::*;
4+
5+
#[inline(never)]
6+
pub fn f2(x: f64) -> f64 {
7+
x.sin()
8+
}
9+
10+
#[autodiff_forward(df1_lib, Dual, Dual)]
11+
pub fn _f1(x: f64) -> f64 {
12+
simple_dep::f(x, x) * f2(x)
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
extern crate foo;
2+
3+
fn main() {
4+
//dbg!("Running main.rs");
5+
let enzyme_y1_lib = foo::df1_lib(1.5, 1.0);
6+
println!("output1: {:?}", enzyme_y1_lib.0);
7+
println!("output2: {:?}", enzyme_y1_lib.1);
8+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//@ needs-enzyme
2+
//@ ignore-cross-compile
3+
4+
use run_make_support::{cwd, run, rustc};
5+
6+
fn main() {
7+
// Build the dependency crate.
8+
rustc()
9+
.input("dep.rs")
10+
.arg("-Zautodiff=Enable")
11+
.arg("--edition=2024")
12+
.arg("-Copt-level=3")
13+
.arg("--crate-name=simple_dep")
14+
.arg("-Clinker-plugin-lto")
15+
.arg("--crate-type=lib")
16+
.emit("dep-info,metadata,link")
17+
.run();
18+
19+
let cwd = cwd();
20+
let cwd_str = cwd.to_string_lossy();
21+
22+
let mydep = format!("-Ldependency={cwd_str}");
23+
24+
let simple_dep_rlib =
25+
format!("--extern=simple_dep={}", cwd.join("libsimple_dep.rlib").to_string_lossy());
26+
27+
// Build the main library that depends on `simple_dep`.
28+
rustc()
29+
.input("lib.rs")
30+
.arg("-Zautodiff=Enable")
31+
.arg("--edition=2024")
32+
.arg("-Copt-level=3")
33+
.arg("--crate-name=foo")
34+
.arg("-Clinker-plugin-lto")
35+
.arg("--crate-type=lib")
36+
.emit("dep-info,metadata,link")
37+
.arg(&mydep)
38+
.arg(&simple_dep_rlib)
39+
.run();
40+
41+
let foo_rlib = format!("--extern=foo={}", cwd.join("libfoo.rlib").to_string_lossy());
42+
43+
// Build the final binary linking both rlibs.
44+
rustc()
45+
.input("main.rs")
46+
.arg("-Zautodiff=Enable")
47+
.arg("--edition=2024")
48+
.arg("-Copt-level=3")
49+
.arg("--crate-name=foo")
50+
.arg("-Clto=fat")
51+
.arg("--crate-type=bin")
52+
.emit("dep-info,link")
53+
.arg(&mydep)
54+
.arg(&foo_rlib)
55+
.arg(&simple_dep_rlib)
56+
.run();
57+
58+
// Run the binary and check its output.
59+
let binary = run("foo");
60+
assert!(binary.status().success(), "binary failed to run");
61+
62+
let binary_out = binary.stdout();
63+
let output = String::from_utf8_lossy(&binary_out);
64+
assert!(output.contains("output1: 4.488727439718245"));
65+
assert!(output.contains("output2: 3.3108023673168265"));
66+
}

0 commit comments

Comments
 (0)