Rollup merge of #140697 - Sa4dUs:split-autodiff, r=ZuseZ4
Split `autodiff` into `autodiff_forward` and `autodiff_reverse` This PR splits `#[autodiff]` macro so `#[autodiff(df, Reverse, args)]` would become `#[autodiff_reverse(df, args)]` and `#[autodiff(df, Forward, args)]` would become `#[autodiff_forwad(df, args)]`.
This commit is contained in:
commit
7f5f29b663
32 changed files with 234 additions and 217 deletions
|
|
@ -56,7 +56,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 = unknown Mode: `{$mode}`. Use `Forward` or `Reverse`
|
||||
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}
|
||||
|
|
|
|||
|
|
@ -86,27 +86,23 @@ mod llvm_enzyme {
|
|||
ecx: &mut ExtCtxt<'_>,
|
||||
meta_item: &ThinVec<MetaItemInner>,
|
||||
has_ret: bool,
|
||||
mode: DiffMode,
|
||||
) -> AutoDiffAttrs {
|
||||
let dcx = ecx.sess.dcx();
|
||||
let mode = name(&meta_item[1]);
|
||||
let Ok(mode) = DiffMode::from_str(&mode) else {
|
||||
dcx.emit_err(errors::AutoDiffInvalidMode { span: meta_item[1].span(), mode });
|
||||
return AutoDiffAttrs::error();
|
||||
};
|
||||
|
||||
// Now we check, whether the user wants autodiff in batch/vector mode, or scalar mode.
|
||||
// If he doesn't specify an integer (=width), we default to scalar mode, thus width=1.
|
||||
let mut first_activity = 2;
|
||||
let mut first_activity = 1;
|
||||
|
||||
let width = if let [_, _, x, ..] = &meta_item[..]
|
||||
let width = if let [_, x, ..] = &meta_item[..]
|
||||
&& let Some(x) = width(x)
|
||||
{
|
||||
first_activity = 3;
|
||||
first_activity = 2;
|
||||
match x.try_into() {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
dcx.emit_err(errors::AutoDiffInvalidWidth {
|
||||
span: meta_item[2].span(),
|
||||
span: meta_item[1].span(),
|
||||
width: x,
|
||||
});
|
||||
return AutoDiffAttrs::error();
|
||||
|
|
@ -165,6 +161,24 @@ mod llvm_enzyme {
|
|||
ts.push(TokenTree::Token(comma.clone(), Spacing::Alone));
|
||||
}
|
||||
|
||||
pub(crate) fn expand_forward(
|
||||
ecx: &mut ExtCtxt<'_>,
|
||||
expand_span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
expand_with_mode(ecx, expand_span, meta_item, item, DiffMode::Forward)
|
||||
}
|
||||
|
||||
pub(crate) fn expand_reverse(
|
||||
ecx: &mut ExtCtxt<'_>,
|
||||
expand_span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
item: Annotatable,
|
||||
) -> Vec<Annotatable> {
|
||||
expand_with_mode(ecx, expand_span, meta_item, item, DiffMode::Reverse)
|
||||
}
|
||||
|
||||
/// We expand the autodiff macro to generate a new placeholder function which passes
|
||||
/// type-checking and can be called by users. The function body of the placeholder function will
|
||||
/// later be replaced on LLVM-IR level, so the design of the body is less important and for now
|
||||
|
|
@ -198,11 +212,12 @@ mod llvm_enzyme {
|
|||
/// ```
|
||||
/// FIXME(ZuseZ4): Once autodiff is enabled by default, make this a doc comment which is checked
|
||||
/// in CI.
|
||||
pub(crate) fn expand(
|
||||
pub(crate) fn expand_with_mode(
|
||||
ecx: &mut ExtCtxt<'_>,
|
||||
expand_span: Span,
|
||||
meta_item: &ast::MetaItem,
|
||||
mut item: Annotatable,
|
||||
mode: DiffMode,
|
||||
) -> Vec<Annotatable> {
|
||||
if cfg!(not(llvm_enzyme)) {
|
||||
ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span });
|
||||
|
|
@ -245,29 +260,41 @@ mod llvm_enzyme {
|
|||
// create TokenStream from vec elemtents:
|
||||
// meta_item doesn't have a .tokens field
|
||||
let mut ts: Vec<TokenTree> = vec![];
|
||||
if meta_item_vec.len() < 2 {
|
||||
// At the bare minimum, we need a fnc name and a mode, even for a dummy function with no
|
||||
// input and output args.
|
||||
if meta_item_vec.len() < 1 {
|
||||
// At the bare minimum, we need a fnc name.
|
||||
dcx.emit_err(errors::AutoDiffMissingConfig { span: item.span() });
|
||||
return vec![item];
|
||||
}
|
||||
|
||||
meta_item_inner_to_ts(&meta_item_vec[1], &mut ts);
|
||||
let mode_symbol = match mode {
|
||||
DiffMode::Forward => sym::Forward,
|
||||
DiffMode::Reverse => sym::Reverse,
|
||||
_ => unreachable!("Unsupported mode: {:?}", mode),
|
||||
};
|
||||
|
||||
// Insert mode token
|
||||
let mode_token = Token::new(TokenKind::Ident(mode_symbol, false.into()), Span::default());
|
||||
ts.insert(0, TokenTree::Token(mode_token, Spacing::Joint));
|
||||
ts.insert(
|
||||
1,
|
||||
TokenTree::Token(Token::new(TokenKind::Comma, Span::default()), Spacing::Alone),
|
||||
);
|
||||
|
||||
// Now, if the user gave a width (vector aka batch-mode ad), then we copy it.
|
||||
// If it is not given, we default to 1 (scalar mode).
|
||||
let start_position;
|
||||
let kind: LitKind = LitKind::Integer;
|
||||
let symbol;
|
||||
if meta_item_vec.len() >= 3
|
||||
&& let Some(width) = width(&meta_item_vec[2])
|
||||
if meta_item_vec.len() >= 2
|
||||
&& let Some(width) = width(&meta_item_vec[1])
|
||||
{
|
||||
start_position = 3;
|
||||
start_position = 2;
|
||||
symbol = Symbol::intern(&width.to_string());
|
||||
} else {
|
||||
start_position = 2;
|
||||
start_position = 1;
|
||||
symbol = sym::integer(1);
|
||||
}
|
||||
|
||||
let l: Lit = Lit { kind, symbol, suffix: None };
|
||||
let t = Token::new(TokenKind::Literal(l), Span::default());
|
||||
let comma = Token::new(TokenKind::Comma, Span::default());
|
||||
|
|
@ -289,7 +316,7 @@ mod llvm_enzyme {
|
|||
ts.pop();
|
||||
let ts: TokenStream = TokenStream::from_iter(ts);
|
||||
|
||||
let x: AutoDiffAttrs = from_ast(ecx, &meta_item_vec, has_ret);
|
||||
let x: AutoDiffAttrs = from_ast(ecx, &meta_item_vec, has_ret, mode);
|
||||
if !x.is_active() {
|
||||
// We encountered an error, so we return the original item.
|
||||
// This allows us to potentially parse other attributes.
|
||||
|
|
@ -1017,4 +1044,4 @@ mod llvm_enzyme {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) use llvm_enzyme::expand;
|
||||
pub(crate) use llvm_enzyme::{expand_forward, expand_reverse};
|
||||
|
|
|
|||
|
|
@ -180,14 +180,6 @@ mod autodiff {
|
|||
pub(crate) act: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_autodiff_mode)]
|
||||
pub(crate) struct AutoDiffInvalidMode {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
pub(crate) mode: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_autodiff_width)]
|
||||
pub(crate) struct AutoDiffInvalidWidth {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@
|
|||
#![allow(internal_features)]
|
||||
#![allow(rustc::diagnostic_outside_of_impl)]
|
||||
#![allow(rustc::untranslatable_diagnostic)]
|
||||
#![cfg_attr(not(bootstrap), feature(autodiff))]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(autodiff)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(if_let_guard)]
|
||||
|
|
@ -112,7 +112,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
|||
|
||||
register_attr! {
|
||||
alloc_error_handler: alloc_error_handler::expand,
|
||||
autodiff: autodiff::expand,
|
||||
autodiff_forward: autodiff::expand_forward,
|
||||
autodiff_reverse: autodiff::expand_reverse,
|
||||
bench: test::expand_bench,
|
||||
cfg_accessible: cfg_accessible::Expander,
|
||||
cfg_eval: cfg_eval::expand,
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.check_generic_attr(hir_id, attr, target, Target::Fn);
|
||||
self.check_proc_macro(hir_id, target, ProcMacroKind::Derive)
|
||||
}
|
||||
[sym::autodiff, ..] => {
|
||||
[sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => {
|
||||
self.check_autodiff(hir_id, attr, span, target)
|
||||
}
|
||||
[sym::coroutine, ..] => {
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ symbols! {
|
|||
FnMut,
|
||||
FnOnce,
|
||||
Formatter,
|
||||
Forward,
|
||||
From,
|
||||
FromIterator,
|
||||
FromResidual,
|
||||
|
|
@ -339,6 +340,7 @@ symbols! {
|
|||
Result,
|
||||
ResumeTy,
|
||||
Return,
|
||||
Reverse,
|
||||
Right,
|
||||
Rust,
|
||||
RustaceansAreAwesome,
|
||||
|
|
@ -522,7 +524,8 @@ symbols! {
|
|||
audit_that,
|
||||
augmented_assignments,
|
||||
auto_traits,
|
||||
autodiff,
|
||||
autodiff_forward,
|
||||
autodiff_reverse,
|
||||
automatically_derived,
|
||||
avx,
|
||||
avx10_target_feature,
|
||||
|
|
|
|||
|
|
@ -225,10 +225,11 @@ pub mod assert_matches {
|
|||
|
||||
// We don't export this through #[macro_export] for now, to avoid breakage.
|
||||
#[unstable(feature = "autodiff", issue = "124509")]
|
||||
#[cfg(not(bootstrap))]
|
||||
/// Unstable module containing the unstable `autodiff` macro.
|
||||
pub mod autodiff {
|
||||
#[unstable(feature = "autodiff", issue = "124509")]
|
||||
pub use crate::macros::builtin::autodiff;
|
||||
pub use crate::macros::builtin::{autodiff_forward, autodiff_reverse};
|
||||
}
|
||||
|
||||
#[unstable(feature = "contracts", issue = "128044")]
|
||||
|
|
|
|||
|
|
@ -1519,20 +1519,41 @@ pub(crate) mod builtin {
|
|||
($file:expr $(,)?) => {{ /* compiler built-in */ }};
|
||||
}
|
||||
|
||||
/// Automatic Differentiation macro which allows generating a new function to compute
|
||||
/// the derivative of a given function. It may only be applied to a function.
|
||||
/// The expected usage syntax is
|
||||
/// `#[autodiff(NAME, MODE, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]`
|
||||
/// where:
|
||||
/// NAME is a string that represents a valid function name.
|
||||
/// MODE is any of Forward, Reverse, ForwardFirst, ReverseFirst.
|
||||
/// INPUT_ACTIVITIES consists of one valid activity for each input parameter.
|
||||
/// OUTPUT_ACTIVITY must not be set if we implicitly return nothing (or explicitly return
|
||||
/// `-> ()`). Otherwise it must be set to one of the allowed activities.
|
||||
/// This macro uses forward-mode automatic differentiation to generate a new function.
|
||||
/// It may only be applied to a function. The new function will compute the derivative
|
||||
/// of the function to which the macro was applied.
|
||||
///
|
||||
/// The expected usage syntax is:
|
||||
/// `#[autodiff_forward(NAME, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]`
|
||||
///
|
||||
/// - `NAME`: A string that represents a valid function name.
|
||||
/// - `INPUT_ACTIVITIES`: Specifies one valid activity for each input parameter.
|
||||
/// - `OUTPUT_ACTIVITY`: Must not be set if the function implicitly returns nothing
|
||||
/// (or explicitly returns `-> ()`). Otherwise, it must be set to one of the allowed activities.
|
||||
#[unstable(feature = "autodiff", issue = "124509")]
|
||||
#[allow_internal_unstable(rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
pub macro autodiff($item:item) {
|
||||
#[cfg(not(bootstrap))]
|
||||
pub macro autodiff_forward($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
/// This macro uses reverse-mode automatic differentiation to generate a new function.
|
||||
/// It may only be applied to a function. The new function will compute the derivative
|
||||
/// of the function to which the macro was applied.
|
||||
///
|
||||
/// The expected usage syntax is:
|
||||
/// `#[autodiff_reverse(NAME, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]`
|
||||
///
|
||||
/// - `NAME`: A string that represents a valid function name.
|
||||
/// - `INPUT_ACTIVITIES`: Specifies one valid activity for each input parameter.
|
||||
/// - `OUTPUT_ACTIVITY`: Must not be set if the function implicitly returns nothing
|
||||
/// (or explicitly returns `-> ()`). Otherwise, it must be set to one of the allowed activities.
|
||||
#[unstable(feature = "autodiff", issue = "124509")]
|
||||
#[allow_internal_unstable(rustc_attrs)]
|
||||
#[rustc_builtin_macro]
|
||||
#[cfg(not(bootstrap))]
|
||||
pub macro autodiff_reverse($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -276,12 +276,12 @@
|
|||
// tidy-alphabetical-start
|
||||
|
||||
// stabilization was reverted after it hit beta
|
||||
#![cfg_attr(not(bootstrap), feature(autodiff))]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(allocator_internals)]
|
||||
#![feature(allow_internal_unsafe)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(asm_experimental_arch)]
|
||||
#![feature(autodiff)]
|
||||
#![feature(cfg_sanitizer_cfi)]
|
||||
#![feature(cfg_target_thread_local)]
|
||||
#![feature(cfi_encoding)]
|
||||
|
|
@ -636,12 +636,15 @@ pub mod simd {
|
|||
#[doc(inline)]
|
||||
pub use crate::std_float::StdFloat;
|
||||
}
|
||||
|
||||
#[unstable(feature = "autodiff", issue = "124509")]
|
||||
#[cfg(not(bootstrap))]
|
||||
/// This module provides support for automatic differentiation.
|
||||
pub mod autodiff {
|
||||
/// This macro handles automatic differentiation.
|
||||
pub use core::autodiff::autodiff;
|
||||
pub use core::autodiff::{autodiff_forward, autodiff_reverse};
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub mod task {
|
||||
//! Types and Traits for working with asynchronous tasks.
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_forward;
|
||||
|
||||
#[autodiff(d_square3, Forward, Dual, DualOnly)]
|
||||
#[autodiff(d_square2, Forward, 4, Dual, DualOnly)]
|
||||
#[autodiff(d_square1, Forward, 4, Dual, Dual)]
|
||||
#[autodiff_forward(d_square3, Dual, DualOnly)]
|
||||
#[autodiff_forward(d_square2, 4, Dual, DualOnly)]
|
||||
#[autodiff_forward(d_square1, 4, Dual, Dual)]
|
||||
#[no_mangle]
|
||||
fn square(x: &f32) -> f32 {
|
||||
x * x
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
//@ needs-enzyme
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
fn square<T: std::ops::Mul<Output = T> + Copy>(x: &T) -> T {
|
||||
*x * *x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@
|
|||
// identical function calls in the LLVM-IR, while having two different calls in the Rust code.
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
fn square(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
||||
#[autodiff(d_square2, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square2, Duplicated, Active)]
|
||||
fn square2(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
fn square(x: &f64) -> f64 {
|
||||
x * x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
//@ needs-enzyme
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
#[no_mangle]
|
||||
fn square(x: &f64) -> f64 {
|
||||
x * x
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
#![feature(autodiff)]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[no_mangle]
|
||||
#[autodiff(df, Reverse, Active, Active, Active)]
|
||||
#[autodiff_reverse(df, Active, Active, Active)]
|
||||
fn primal(x: f32, y: f32) -> f64 {
|
||||
(x * x * y) as f64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ extern crate std;
|
|||
|
||||
// Test that forward mode ad macros are expanded correctly.
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::{autodiff_forward, autodiff_reverse};
|
||||
|
||||
#[rustc_autodiff]
|
||||
#[inline(never)]
|
||||
|
|
|
|||
|
|
@ -7,48 +7,48 @@
|
|||
|
||||
// Test that forward mode ad macros are expanded correctly.
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::{autodiff_forward, autodiff_reverse};
|
||||
|
||||
#[autodiff(df1, Forward, Dual, Const, Dual)]
|
||||
#[autodiff_forward(df1, Dual, Const, Dual)]
|
||||
pub fn f1(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[autodiff(df2, Forward, Dual, Const, Const)]
|
||||
#[autodiff_forward(df2, Dual, Const, Const)]
|
||||
pub fn f2(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[autodiff(df3, Forward, Dual, Const, Const)]
|
||||
#[autodiff_forward(df3, Dual, Const, Const)]
|
||||
pub fn f3(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Not the most interesting derivative, but who are we to judge
|
||||
#[autodiff(df4, Forward)]
|
||||
#[autodiff_forward(df4)]
|
||||
pub fn f4() {}
|
||||
|
||||
// We want to be sure that the same function can be differentiated in different ways
|
||||
#[autodiff(df5_rev, Reverse, Duplicated, Const, Active)]
|
||||
#[autodiff(df5_x, Forward, Dual, Const, Const)]
|
||||
#[autodiff(df5_y, Forward, Const, Dual, Const)]
|
||||
#[autodiff_reverse(df5_rev, Duplicated, Const, Active)]
|
||||
#[autodiff_forward(df5_x, Dual, Const, Const)]
|
||||
#[autodiff_forward(df5_y, Const, Dual, Const)]
|
||||
pub fn f5(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
struct DoesNotImplDefault;
|
||||
#[autodiff(df6, Forward, Const)]
|
||||
#[autodiff_forward(df6, Const)]
|
||||
pub fn f6() -> DoesNotImplDefault {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Make sure, that we add the None for the default return.
|
||||
#[autodiff(df7, Forward, Const)]
|
||||
#[autodiff_forward(df7, Const)]
|
||||
pub fn f7(x: f32) -> () {}
|
||||
|
||||
#[autodiff(f8_1, Forward, Dual, DualOnly)]
|
||||
#[autodiff(f8_2, Forward, 4, Dual, DualOnly)]
|
||||
#[autodiff(f8_3, Forward, 4, Dual, Dual)]
|
||||
#[autodiff_forward(f8_1, Dual, DualOnly)]
|
||||
#[autodiff_forward(f8_2, 4, Dual, DualOnly)]
|
||||
#[autodiff_forward(f8_3, 4, Dual, Dual)]
|
||||
#[no_mangle]
|
||||
fn f8(x: &f32) -> f32 {
|
||||
unimplemented!()
|
||||
|
|
@ -56,15 +56,15 @@ fn f8(x: &f32) -> f32 {
|
|||
|
||||
// We want to make sure that we can use the macro for functions defined inside of functions
|
||||
pub fn f9() {
|
||||
#[autodiff(d_inner_1, Forward, Dual, DualOnly)]
|
||||
#[autodiff(d_inner_2, Forward, Dual, Dual)]
|
||||
#[autodiff_forward(d_inner_1, Dual, DualOnly)]
|
||||
#[autodiff_forward(d_inner_2, Dual, Dual)]
|
||||
fn inner(x: f32) -> f32 {
|
||||
x * x
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we can handle generics
|
||||
#[autodiff(d_square, Reverse, Duplicated, Active)]
|
||||
#[autodiff_reverse(d_square, Duplicated, Active)]
|
||||
pub fn f10<T: std::ops::Mul<Output = T> + Copy>(x: &T) -> T {
|
||||
*x * *x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ extern crate std;
|
|||
|
||||
// Test that reverse mode ad macros are expanded correctly.
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[rustc_autodiff]
|
||||
#[inline(never)]
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@
|
|||
|
||||
// Test that reverse mode ad macros are expanded correctly.
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
#[autodiff(df1, Reverse, Duplicated, Const, Active)]
|
||||
#[autodiff_reverse(df1, Duplicated, Const, Active)]
|
||||
pub fn f1(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Not the most interesting derivative, but who are we to judge
|
||||
#[autodiff(df2, Reverse)]
|
||||
#[autodiff_reverse(df2)]
|
||||
pub fn f2() {}
|
||||
|
||||
#[autodiff(df3, Reverse, Duplicated, Const, Active)]
|
||||
#[autodiff_reverse(df3, Duplicated, Const, Active)]
|
||||
pub fn f3(x: &[f64], y: f64) -> f64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
@ -27,12 +27,12 @@ enum Foo { Reverse }
|
|||
use Foo::Reverse;
|
||||
// What happens if we already have Reverse in type (enum variant decl) and value (enum variant
|
||||
// constructor) namespace? > It's expected to work normally.
|
||||
#[autodiff(df4, Reverse, Const)]
|
||||
#[autodiff_reverse(df4, Const)]
|
||||
pub fn f4(x: f32) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[autodiff(df5, Reverse, DuplicatedOnly, Duplicated)]
|
||||
#[autodiff_reverse(df5, DuplicatedOnly, Duplicated)]
|
||||
pub fn f5(x: *const f32, y: &f32) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ extern crate std;
|
|||
//@ pretty-compare-only
|
||||
//@ pp-exact:inherent_impl.pp
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
struct Foo {
|
||||
a: f64,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
//@ pretty-compare-only
|
||||
//@ pp-exact:inherent_impl.pp
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
|
||||
struct Foo {
|
||||
a: f64,
|
||||
|
|
@ -17,7 +17,7 @@ trait MyTrait {
|
|||
}
|
||||
|
||||
impl MyTrait for Foo {
|
||||
#[autodiff(df, Reverse, Const, Active, Active)]
|
||||
#[autodiff_reverse(df, Const, Active, Active)]
|
||||
fn f(&self, x: f64) -> f64 {
|
||||
self.a * 0.25 * (x * x - 1.0 - 2.0 * x.ln())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,38 +7,38 @@
|
|||
|
||||
// Test that invalid ad macros give nice errors and don't ICE.
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::{autodiff_forward, autodiff_reverse};
|
||||
|
||||
// We can't use Duplicated on scalars
|
||||
#[autodiff(df1, Reverse, Duplicated)]
|
||||
#[autodiff_reverse(df1, Duplicated)]
|
||||
pub fn f1(x: f64) {
|
||||
//~^ ERROR Duplicated can not be used for this type
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Too many activities
|
||||
#[autodiff(df3, Reverse, Duplicated, Const)]
|
||||
#[autodiff_reverse(df3, Duplicated, Const)]
|
||||
pub fn f3(x: f64) {
|
||||
//~^^ ERROR expected 1 activities, but found 2
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// To few activities
|
||||
#[autodiff(df4, Reverse)]
|
||||
#[autodiff_reverse(df4)]
|
||||
pub fn f4(x: f64) {
|
||||
//~^^ ERROR expected 1 activities, but found 0
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// We can't use Dual in Reverse mode
|
||||
#[autodiff(df5, Reverse, Dual)]
|
||||
#[autodiff_reverse(df5, Dual)]
|
||||
pub fn f5(x: f64) {
|
||||
//~^^ ERROR Dual can not be used in Reverse Mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// We can't use Duplicated in Forward mode
|
||||
#[autodiff(df6, Forward, Duplicated)]
|
||||
#[autodiff_forward(df6, Duplicated)]
|
||||
pub fn f6(x: f64) {
|
||||
//~^^ ERROR Duplicated can not be used in Forward Mode
|
||||
//~^^ ERROR Duplicated can not be used for this type
|
||||
|
|
@ -46,36 +46,36 @@ pub fn f6(x: f64) {
|
|||
}
|
||||
|
||||
fn dummy() {
|
||||
#[autodiff(df7, Forward, Dual)]
|
||||
#[autodiff_forward(df7, Dual)]
|
||||
let mut x = 5;
|
||||
//~^ ERROR autodiff must be applied to function
|
||||
|
||||
#[autodiff(df7, Forward, Dual)]
|
||||
#[autodiff_forward(df7, Dual)]
|
||||
x = x + 3;
|
||||
//~^^ ERROR attributes on expressions are experimental [E0658]
|
||||
//~^^ ERROR autodiff must be applied to function
|
||||
|
||||
#[autodiff(df7, Forward, Dual)]
|
||||
#[autodiff_forward(df7, Dual)]
|
||||
let add_one_v2 = |x: u32| -> u32 { x + 1 };
|
||||
//~^ ERROR autodiff must be applied to function
|
||||
}
|
||||
|
||||
// Malformed, where args?
|
||||
#[autodiff]
|
||||
#[autodiff_forward]
|
||||
pub fn f7(x: f64) {
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Malformed, where args?
|
||||
#[autodiff()]
|
||||
#[autodiff_forward()]
|
||||
pub fn f8(x: f64) {
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Invalid attribute syntax
|
||||
#[autodiff = ""]
|
||||
#[autodiff_forward = ""]
|
||||
pub fn f9(x: f64) {
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
|
|
@ -84,29 +84,15 @@ pub fn f9(x: f64) {
|
|||
fn fn_exists() {}
|
||||
|
||||
// We colide with an already existing function
|
||||
#[autodiff(fn_exists, Reverse, Active)]
|
||||
#[autodiff_reverse(fn_exists, Active)]
|
||||
pub fn f10(x: f64) {
|
||||
//~^^ ERROR the name `fn_exists` is defined multiple times [E0428]
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Malformed, missing a mode
|
||||
#[autodiff(df11)]
|
||||
pub fn f11() {
|
||||
//~^ ERROR autodiff requires at least a name and mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Invalid Mode
|
||||
#[autodiff(df12, Debug)]
|
||||
pub fn f12() {
|
||||
//~^^ ERROR unknown Mode: `Debug`. Use `Forward` or `Reverse`
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Invalid, please pick one Mode
|
||||
// or use two autodiff macros.
|
||||
#[autodiff(df13, Forward, Reverse)]
|
||||
#[autodiff_reverse(df13, Reverse)]
|
||||
pub fn f13() {
|
||||
//~^^ ERROR did not recognize Activity: `Reverse`
|
||||
unimplemented!()
|
||||
|
|
@ -117,7 +103,7 @@ struct Foo {}
|
|||
// We can't handle Active structs, because that would mean (in the general case), that we would
|
||||
// need to allocate and initialize arbitrary user types. We have Duplicated/Dual input args for
|
||||
// that. FIXME: Give a nicer error and suggest to the user to have a `&mut Foo` input instead.
|
||||
#[autodiff(df14, Reverse, Active, Active)]
|
||||
#[autodiff_reverse(df14, Active, Active)]
|
||||
fn f14(x: f32) -> Foo {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
@ -127,14 +113,14 @@ type MyFloat = f32;
|
|||
// We would like to support type alias to f32/f64 in argument type in the future,
|
||||
// but that requires us to implement our checks at a later stage
|
||||
// like THIR which has type information available.
|
||||
#[autodiff(df15, Reverse, Active, Active)]
|
||||
#[autodiff_reverse(df15, Active, Active)]
|
||||
fn f15(x: MyFloat) -> f32 {
|
||||
//~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433]
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// We would like to support type alias to f32/f64 in return type in the future
|
||||
#[autodiff(df16, Reverse, Active, Active)]
|
||||
#[autodiff_reverse(df16, Active, Active)]
|
||||
fn f16(x: f32) -> MyFloat {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
@ -145,40 +131,40 @@ struct F64Trans {
|
|||
}
|
||||
|
||||
// We would like to support `#[repr(transparent)]` f32/f64 wrapper in return type in the future
|
||||
#[autodiff(df17, Reverse, Active, Active)]
|
||||
#[autodiff_reverse(df17, Active, Active)]
|
||||
fn f17(x: f64) -> F64Trans {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// We would like to support `#[repr(transparent)]` f32/f64 wrapper in argument type in the future
|
||||
#[autodiff(df18, Reverse, Active, Active)]
|
||||
#[autodiff_reverse(df18, Active, Active)]
|
||||
fn f18(x: F64Trans) -> f64 {
|
||||
//~^^ ERROR failed to resolve: use of undeclared type `F64Trans` [E0433]
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Invalid return activity
|
||||
#[autodiff(df19, Forward, Dual, Active)]
|
||||
#[autodiff_forward(df19, Dual, Active)]
|
||||
fn f19(x: f32) -> f32 {
|
||||
//~^^ ERROR invalid return activity Active in Forward Mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[autodiff(df20, Reverse, Active, Dual)]
|
||||
#[autodiff_reverse(df20, Active, Dual)]
|
||||
fn f20(x: f32) -> f32 {
|
||||
//~^^ ERROR invalid return activity Dual in Reverse Mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Duplicated cannot be used as return activity
|
||||
#[autodiff(df21, Reverse, Active, Duplicated)]
|
||||
#[autodiff_reverse(df21, Active, Duplicated)]
|
||||
fn f21(x: f32) -> f32 {
|
||||
//~^^ ERROR invalid return activity Duplicated in Reverse Mode
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
struct DoesNotImplDefault;
|
||||
#[autodiff(df22, Forward, Dual)]
|
||||
#[autodiff_forward(df22, Dual)]
|
||||
pub fn f22() -> DoesNotImplDefault {
|
||||
//~^^ ERROR the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied
|
||||
unimplemented!()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0658]: attributes on expressions are experimental
|
||||
--> $DIR/autodiff_illegal.rs:53:5
|
||||
|
|
||||
LL | #[autodiff(df7, Forward, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_forward(df7, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
|
||||
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
|
||||
|
|
@ -17,26 +17,26 @@ LL | pub fn f1(x: f64) {
|
|||
error: expected 1 activities, but found 2
|
||||
--> $DIR/autodiff_illegal.rs:20:1
|
||||
|
|
||||
LL | #[autodiff(df3, Reverse, Duplicated, Const)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(df3, Duplicated, Const)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: expected 1 activities, but found 0
|
||||
--> $DIR/autodiff_illegal.rs:27:1
|
||||
|
|
||||
LL | #[autodiff(df4, Reverse)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(df4)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: Dual can not be used in Reverse Mode
|
||||
--> $DIR/autodiff_illegal.rs:34:1
|
||||
|
|
||||
LL | #[autodiff(df5, Reverse, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(df5, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: Duplicated can not be used in Forward Mode
|
||||
--> $DIR/autodiff_illegal.rs:41:1
|
||||
|
|
||||
LL | #[autodiff(df6, Forward, Duplicated)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_forward(df6, Duplicated)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: Duplicated can not be used for this type
|
||||
--> $DIR/autodiff_illegal.rs:42:14
|
||||
|
|
@ -95,69 +95,54 @@ error[E0428]: the name `fn_exists` is defined multiple times
|
|||
LL | fn fn_exists() {}
|
||||
| -------------- previous definition of the value `fn_exists` here
|
||||
...
|
||||
LL | #[autodiff(fn_exists, Reverse, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn_exists` redefined here
|
||||
LL | #[autodiff_reverse(fn_exists, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `fn_exists` redefined here
|
||||
|
|
||||
= note: `fn_exists` must be defined only once in the value namespace of this module
|
||||
|
||||
error: autodiff requires at least a name and mode
|
||||
--> $DIR/autodiff_illegal.rs:95:1
|
||||
|
|
||||
LL | / pub fn f11() {
|
||||
LL | |
|
||||
LL | | unimplemented!()
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: unknown Mode: `Debug`. Use `Forward` or `Reverse`
|
||||
--> $DIR/autodiff_illegal.rs:101:18
|
||||
|
|
||||
LL | #[autodiff(df12, Debug)]
|
||||
| ^^^^^
|
||||
|
||||
error: did not recognize Activity: `Reverse`
|
||||
--> $DIR/autodiff_illegal.rs:109:27
|
||||
--> $DIR/autodiff_illegal.rs:95:26
|
||||
|
|
||||
LL | #[autodiff(df13, Forward, Reverse)]
|
||||
| ^^^^^^^
|
||||
LL | #[autodiff_reverse(df13, Reverse)]
|
||||
| ^^^^^^^
|
||||
|
||||
error: invalid return activity Active in Forward Mode
|
||||
--> $DIR/autodiff_illegal.rs:161:1
|
||||
--> $DIR/autodiff_illegal.rs:147:1
|
||||
|
|
||||
LL | #[autodiff(df19, Forward, Dual, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_forward(df19, Dual, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid return activity Dual in Reverse Mode
|
||||
--> $DIR/autodiff_illegal.rs:167:1
|
||||
--> $DIR/autodiff_illegal.rs:153:1
|
||||
|
|
||||
LL | #[autodiff(df20, Reverse, Active, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(df20, Active, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid return activity Duplicated in Reverse Mode
|
||||
--> $DIR/autodiff_illegal.rs:174:1
|
||||
--> $DIR/autodiff_illegal.rs:160:1
|
||||
|
|
||||
LL | #[autodiff(df21, Reverse, Active, Duplicated)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(df21, Active, Duplicated)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared type `MyFloat`
|
||||
--> $DIR/autodiff_illegal.rs:130:1
|
||||
--> $DIR/autodiff_illegal.rs:116:1
|
||||
|
|
||||
LL | #[autodiff(df15, Reverse, Active, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat`
|
||||
LL | #[autodiff_reverse(df15, Active, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat`
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared type `F64Trans`
|
||||
--> $DIR/autodiff_illegal.rs:154:1
|
||||
--> $DIR/autodiff_illegal.rs:140:1
|
||||
|
|
||||
LL | #[autodiff(df18, Reverse, Active, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans`
|
||||
LL | #[autodiff_reverse(df18, Active, Active)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans`
|
||||
|
||||
error[E0599]: the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied
|
||||
--> $DIR/autodiff_illegal.rs:181:1
|
||||
--> $DIR/autodiff_illegal.rs:167:1
|
||||
|
|
||||
LL | struct DoesNotImplDefault;
|
||||
| ------------------------- doesn't satisfy `DoesNotImplDefault: Default`
|
||||
LL | #[autodiff(df22, Forward, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called on `(DoesNotImplDefault, DoesNotImplDefault)` due to unsatisfied trait bounds
|
||||
LL | #[autodiff_forward(df22, Dual)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called on `(DoesNotImplDefault, DoesNotImplDefault)` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`DoesNotImplDefault: Default`
|
||||
|
|
@ -168,7 +153,7 @@ LL + #[derive(Default)]
|
|||
LL | struct DoesNotImplDefault;
|
||||
|
|
||||
|
||||
error: aborting due to 23 previous errors
|
||||
error: aborting due to 21 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0428, E0433, E0599, E0658.
|
||||
For more information about an error, try `rustc --explain E0428`.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ use proc_macro::TokenStream;
|
|||
|
||||
#[proc_macro_attribute]
|
||||
#[macro_use]
|
||||
pub fn autodiff(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
pub fn autodiff_forward(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
item // identity proc-macro
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@
|
|||
#![feature(autodiff)]
|
||||
|
||||
#[cfg(std_autodiff)]
|
||||
use std::autodiff::autodiff;
|
||||
|
||||
use std::autodiff::autodiff_forward;
|
||||
extern crate my_macro;
|
||||
use my_macro::autodiff; // bring `autodiff` in scope
|
||||
use my_macro::autodiff_forward; // bring `autodiff_forward` in scope
|
||||
|
||||
#[autodiff]
|
||||
//[std_autodiff]~^^^ ERROR the name `autodiff` is defined multiple times
|
||||
#[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() {}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
error[E0252]: the name `autodiff` is defined multiple times
|
||||
--> $DIR/visibility.rs:12:5
|
||||
error[E0252]: the name `autodiff_forward` is defined multiple times
|
||||
--> $DIR/visibility.rs:11:5
|
||||
|
|
||||
LL | use std::autodiff::autodiff;
|
||||
| ----------------------- previous import of the macro `autodiff` here
|
||||
...
|
||||
LL | use my_macro::autodiff; // bring `autodiff` in scope
|
||||
| ^^^^^^^^^^^^^^^^^^ `autodiff` reimported here
|
||||
LL | use std::autodiff::autodiff_forward;
|
||||
| ------------------------------- previous import of the macro `autodiff_forward` here
|
||||
LL | extern crate my_macro;
|
||||
LL | use my_macro::autodiff_forward; // bring `autodiff_forward` in scope
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `autodiff_forward` reimported here
|
||||
|
|
||||
= note: `autodiff` must be defined only once in the macro namespace of this module
|
||||
= note: `autodiff_forward` must be defined only once in the macro namespace of this module
|
||||
help: you can use `as` to change the binding name of the import
|
||||
|
|
||||
LL | use my_macro::autodiff as other_autodiff; // bring `autodiff` in scope
|
||||
| +++++++++++++++++
|
||||
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:14:1
|
||||
--> $DIR/visibility.rs:13:1
|
||||
|
|
||||
LL | #[autodiff]
|
||||
| ^^^^^^^^^^^
|
||||
LL | #[autodiff_forward(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0658]: use of unstable library feature `autodiff`
|
||||
--> $DIR/feature-gate-autodiff-use.rs:13:3
|
||||
|
|
||||
LL | #[autodiff(dfoo, Reverse)]
|
||||
| ^^^^^^^^
|
||||
LL | #[autodiff_reverse(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
|
||||
= help: add `#![feature(autodiff)]` to the crate attributes to enable
|
||||
|
|
@ -11,8 +11,8 @@ LL | #[autodiff(dfoo, Reverse)]
|
|||
error[E0658]: use of unstable library feature `autodiff`
|
||||
--> $DIR/feature-gate-autodiff-use.rs:9:5
|
||||
|
|
||||
LL | use std::autodiff::autodiff;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | use std::autodiff::autodiff_reverse;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
|
||||
= help: add `#![feature(autodiff)]` to the crate attributes to enable
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0658]: use of unstable library feature `autodiff`
|
||||
--> $DIR/feature-gate-autodiff-use.rs:13:3
|
||||
|
|
||||
LL | #[autodiff(dfoo, Reverse)]
|
||||
| ^^^^^^^^
|
||||
LL | #[autodiff_reverse(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
|
||||
= help: add `#![feature(autodiff)]` to the crate attributes to enable
|
||||
|
|
@ -11,14 +11,14 @@ LL | #[autodiff(dfoo, Reverse)]
|
|||
error: this rustc version does not support autodiff
|
||||
--> $DIR/feature-gate-autodiff-use.rs:13:1
|
||||
|
|
||||
LL | #[autodiff(dfoo, Reverse)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | #[autodiff_reverse(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0658]: use of unstable library feature `autodiff`
|
||||
--> $DIR/feature-gate-autodiff-use.rs:9:5
|
||||
|
|
||||
LL | use std::autodiff::autodiff;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | use std::autodiff::autodiff_reverse;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #124509 <https://github.com/rust-lang/rust/issues/124509> for more information
|
||||
= help: add `#![feature(autodiff)]` to the crate attributes to enable
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::autodiff::autodiff;
|
||||
use std::autodiff::autodiff_reverse;
|
||||
//[has_support]~^ ERROR use of unstable library feature `autodiff`
|
||||
//[no_support]~^^ ERROR use of unstable library feature `autodiff`
|
||||
|
||||
#[autodiff(dfoo, Reverse)]
|
||||
#[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
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error: cannot find attribute `autodiff` in this scope
|
||||
error: cannot find attribute `autodiff_reverse` in this scope
|
||||
--> $DIR/feature-gate-autodiff.rs:9:3
|
||||
|
|
||||
LL | #[autodiff(dfoo, Reverse)]
|
||||
| ^^^^^^^^
|
||||
LL | #[autodiff_reverse(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider importing this attribute macro
|
||||
|
|
||||
LL + use std::autodiff::autodiff;
|
||||
LL + use std::autodiff::autodiff_reverse;
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
error: cannot find attribute `autodiff` in this scope
|
||||
error: cannot find attribute `autodiff_reverse` in this scope
|
||||
--> $DIR/feature-gate-autodiff.rs:9:3
|
||||
|
|
||||
LL | #[autodiff(dfoo, Reverse)]
|
||||
| ^^^^^^^^
|
||||
LL | #[autodiff_reverse(dfoo)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: consider importing this attribute macro
|
||||
|
|
||||
LL + use std::autodiff::autodiff;
|
||||
LL + use std::autodiff::autodiff_reverse;
|
||||
|
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// This checks that without the autodiff feature enabled, we can't use it.
|
||||
|
||||
#[autodiff(dfoo, Reverse)]
|
||||
//[has_support]~^ ERROR cannot find attribute `autodiff` in this scope
|
||||
//[no_support]~^^ ERROR cannot find attribute `autodiff` in this scope
|
||||
#[autodiff_reverse(dfoo)]
|
||||
//[has_support]~^ ERROR cannot find attribute `autodiff_reverse` in this scope
|
||||
//[no_support]~^^ ERROR cannot find attribute `autodiff_reverse` in this scope
|
||||
fn foo() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue