Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix usage of autodiff macro with inner functions #138314

Merged
merged 4 commits into from
Apr 7, 2025

Conversation

haenoe
Copy link
Contributor

@haenoe haenoe commented Mar 10, 2025

This PR adds additional handling into the expansion step of the std::autodiff macro (in compiler/rustc_builtin_macros/src/autodiff.rs), which allows the macro to be applied to inner functions.

#![feature(autodiff)]
use std::autodiff::autodiff;

fn main() {
    #[autodiff(d_inner, Forward, Dual, DualOnly)]
    fn inner(x: f32) -> f32 {
        x * x
    }
}

Previously, the compiler didn't allow this due to only handling Annotatable::Item and Annotatable::AssocItem and missing the handling of Annotatable::Stmt. This resulted in the rather generic error

error: autodiff must be applied to function
 --> src/main.rs:6:5
  |
6 | /     fn inner(x: f32) -> f32 {
7 | |         x * x
8 | |     }
  | |_____^

error: could not compile `enzyme-test` (bin "enzyme-test") due to 1 previous error

This issue was originally reported here.

Quick question: would it make sense to add a ui test to ensure there is no regression on this?
This is my first contribution, so I'm extra grateful for any piece of feedback!! :D

r? @oli-obk

Tracking issue for autodiff: #124509

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 10, 2025
@jieyouxu jieyouxu added the F-autodiff `#![feature(autodiff)]` label Mar 10, 2025
@ZuseZ4
Copy link
Member

ZuseZ4 commented Mar 11, 2025

Thank you for looking into this! Yes, adding a test to avoid regressions would be great.
UI tests are usually more towards stdout/stderr (or runtime) testing. Since this one now works, I would add it under tests/pretty/autodiff_reverse.{rs|pp}. You can just add an example by renaming main to f6, and use --bless when running the test.
With git diff you can then check if the change is what you expect it to be.
The whole test suite just got reworked recently, so it has quite nice docs these days: https://rustc-dev-guide.rust-lang.org/tests/compiletest.html
https://rustc-dev-guide.rust-lang.org/tests/intro.html
and https://rustc-dev-guide.rust-lang.org/tests/best-practices.html are probably the relevant ones.

@oli-obk
Copy link
Contributor

oli-obk commented Mar 11, 2025

@bors delegate=ZuseZ4

@bors
Copy link
Collaborator

bors commented Mar 11, 2025

✌️ @ZuseZ4, you can now approve this pull request!

If @oli-obk told you to "r=me" after making some further change, please make that change, then do @bors r=@oli-obk

@haenoe
Copy link
Contributor Author

haenoe commented Mar 15, 2025

Thank you for looking into this! Yes, adding a test to avoid regressions would be great. UI tests are usually more towards stdout/stderr (or runtime) testing. Since this one now works, I would add it under tests/pretty/autodiff_reverse.{rs|pp}. You can just add an example by renaming main to f6, and use --bless when running the test. With git diff you can then check if the change is what you expect it to be. The whole test suite just got reworked recently, so it has quite nice docs these days: https://rustc-dev-guide.rust-lang.org/tests/compiletest.html https://rustc-dev-guide.rust-lang.org/tests/intro.html and https://rustc-dev-guide.rust-lang.org/tests/best-practices.html are probably the relevant ones.

@ZuseZ4 , thank you for providing more insights into this! The pretty printer tests do indeed sound like a good place for this. Also I've got to express how cool and insightful the docs are -- this is really not something to be taken as granted :D

However, while looking into this I noticed that both tests/pretty/autodiff_{forward,reverse}.rs are currently failing due to the fact that they still include functions which use the autodiff macro in conjuction with DiffMode::{Forward,Reverse}First. These two were removed with commit 061abbc36928cce784c54463c266f4d43d14d419.

It makes sense to open a separate PR fixing these issues before continuing with the inner function test, right?
Have a nice evening ^^'

@ZuseZ4
Copy link
Member

ZuseZ4 commented Mar 15, 2025

Yes I agree, I think one reason why I ended up being a rustc developer rather than working on other projects is the documentation. I don't have a pc this weekend, but my batching PR contains fixes for those. You can cherry pick them if you want, or I'll make a PR for that on Monday. I had hoped to get it done for the weekend, but unfortunately ran out of time.

@haenoe
Copy link
Contributor Author

haenoe commented Mar 15, 2025

Okidoki! Don't stress, I'll just rebase when the changes are in master.
Enjoy your weekend!

@ZuseZ4 ZuseZ4 mentioned this pull request Mar 17, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 21, 2025
Autodiff cleanups

Splitting out some cleanups to reduce the size of my batching PR and simplify `@haenoe` 's [PR](rust-lang#138314).

r? `@oli-obk`

Tracking:

- rust-lang#124509
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 21, 2025
Autodiff cleanups

Splitting out some cleanups to reduce the size of my batching PR and simplify ``@haenoe`` 's [PR](rust-lang#138314).

r? ``@oli-obk``

Tracking:

- rust-lang#124509
Kobzol added a commit to Kobzol/rust that referenced this pull request Mar 21, 2025
Autodiff cleanups

Splitting out some cleanups to reduce the size of my batching PR and simplify ```@haenoe``` 's [PR](rust-lang#138314).

r? ```@oli-obk```

Tracking:

- rust-lang#124509
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Mar 21, 2025
Autodiff cleanups

Splitting out some cleanups to reduce the size of my batching PR and simplify ````@haenoe```` 's [PR](rust-lang#138314).

r? ````@oli-obk````

Tracking:

- rust-lang#124509
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Mar 21, 2025
Rollup merge of rust-lang#138627 - EnzymeAD:autodiff-cleanups, r=oli-obk

Autodiff cleanups

Splitting out some cleanups to reduce the size of my batching PR and simplify ``@haenoe`` 's [PR](rust-lang#138314).

r? ``@oli-obk``

Tracking:

- rust-lang#124509
@bors
Copy link
Collaborator

bors commented Mar 21, 2025

☔ The latest upstream changes (presumably #138791) made this pull request unmergeable. Please resolve the merge conflicts.

@haenoe haenoe force-pushed the autodiff-inner-function branch from 5024ae1 to 35812e2 Compare March 21, 2025 23:31
@haenoe
Copy link
Contributor Author

haenoe commented Mar 23, 2025

Hey @ZuseZ4
Rebased this to master and also tried to integrate your fixes regarding the duplicated attributes via your same_attribute function.
Quick question: Do you think this simple test suffices to test the expansion logic? Or would you add one/two more advanced usages (e.g. multiple derivatives).

@ZuseZ4
Copy link
Member

ZuseZ4 commented Mar 24, 2025

looks good, but I will check again later when I'm on my computer. For the test I would just add a second autodiff macro with an in any way different config to the same function/test, to verify that even after future refactors we don't add inline or autodiff attributes multiple time to the source functions.
Also, we usually use bug! instead of unreachable if we have previously tested assumptions, can you move them over?

@bors
Copy link
Collaborator

bors commented Mar 25, 2025

☔ The latest upstream changes (presumably #138933) made this pull request unmergeable. Please resolve the merge conflicts.

@haenoe haenoe force-pushed the autodiff-inner-function branch from 35812e2 to 013edbe Compare April 1, 2025 05:30
@rustbot
Copy link
Collaborator

rustbot commented Apr 1, 2025

Some changes occurred in compiler/rustc_builtin_macros/src/autodiff.rs

cc @ZuseZ4

@haenoe
Copy link
Contributor Author

haenoe commented Apr 1, 2025

Hey @ZuseZ4!
Sorry for the long silence, I didn't have access to my computer :/
But now I am able to be more responsive, so let me know if you have any more feedback!

@rust-log-analyzer

This comment has been minimized.

@ZuseZ4
Copy link
Member

ZuseZ4 commented Apr 1, 2025

No worries, and the test looks good, thanks!
However something else seem to have broken in the meantime, maybe you can try to rebase locally onto the latest master and see if that builds?
Also, #138740 also modifies a lot of code, including our frontend, so you'll likely need to rebase once it lands anyway.

@haenoe haenoe force-pushed the autodiff-inner-function branch from 013edbe to 928f4e8 Compare April 1, 2025 08:19
@rustbot
Copy link
Collaborator

rustbot commented Apr 1, 2025

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 4, 2025

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 4, 2025
@ZuseZ4
Copy link
Member

ZuseZ4 commented Apr 5, 2025

Unfortunate, but as predicted. @haenoe the diff should hopefully be easy to fix, can you rebase one more time, so we can add it back to the CI?

@bors
Copy link
Collaborator

bors commented Apr 5, 2025

☔ The latest upstream changes (presumably #139396) made this pull request unmergeable. Please resolve the merge conflicts.

@haenoe
Copy link
Contributor Author

haenoe commented Apr 5, 2025

Yess of course! Will look at it when I'm at my computer in ~2 hours.
Glad to see things moving so quickly :D

haenoe added 3 commits April 6, 2025 21:14
- fix errors caused by the move of `ast::Item::ident` (see rust-lang#138740)
- move the logic of getting `sig`, `vis`, and `ident` from two seperate
  `match` statements into one (less repetition especially with the
  nested `match`)
Verify that the expanded `inline` and `rustc_autodiff` macros are not
duplicated.
@haenoe haenoe force-pushed the autodiff-inner-function branch from 284672a to 0108d40 Compare April 6, 2025 19:44
@haenoe
Copy link
Contributor Author

haenoe commented Apr 6, 2025

This took longer than expected, because I ran into some very weird LLVM ERRORs and had to recompile a bunch of times xD

@rust-log-analyzer

This comment has been minimized.

@haenoe haenoe force-pushed the autodiff-inner-function branch from 0108d40 to bf69443 Compare April 6, 2025 20:09
@ZuseZ4
Copy link
Member

ZuseZ4 commented Apr 6, 2025

Yes, I also sometimes need to recompile llvm on updates, worst case I rm -rf build, but that's rarely necessary.

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Apr 6, 2025

📌 Commit bf69443 has been approved by ZuseZ4

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 6, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Apr 7, 2025
…ZuseZ4

fix usage of `autodiff` macro with inner functions

This PR adds additional handling into the expansion step of the `std::autodiff` macro (in `compiler/rustc_builtin_macros/src/autodiff.rs`), which allows the macro to be applied to inner functions.

```rust
#![feature(autodiff)]
use std::autodiff::autodiff;

fn main() {
    #[autodiff(d_inner, Forward, Dual, DualOnly)]
    fn inner(x: f32) -> f32 {
        x * x
    }
}
```

Previously, the compiler didn't allow this due to only handling `Annotatable::Item` and `Annotatable::AssocItem` and missing the handling of `Annotatable::Stmt`. This resulted in the rather generic error

```
error: autodiff must be applied to function
 --> src/main.rs:6:5
  |
6 | /     fn inner(x: f32) -> f32 {
7 | |         x * x
8 | |     }
  | |_____^

error: could not compile `enzyme-test` (bin "enzyme-test") due to 1 previous error
```

This issue was originally reported [here](EnzymeAD#184).

Quick question: would it make sense to add a ui test to ensure there is no regression on this?
This is my first contribution, so I'm extra grateful for any piece of feedback!! :D

r? `@oli-obk`

Tracking issue for autodiff: rust-lang#124509
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 7, 2025
Rollup of 4 pull requests

Successful merges:

 - rust-lang#138314 (fix usage of `autodiff` macro with inner functions)
 - rust-lang#138766 (coverage: Deal with unused functions and their names in one place)
 - rust-lang#139298 (Allow for missing invisible close delim when reparsing an expression.)
 - rust-lang#139426 (Make the UnifyKey and UnifyValue imports non-nightly)

r? `@ghost`
`@rustbot` modify labels: rollup
@haenoe
Copy link
Contributor Author

haenoe commented Apr 7, 2025

Had a weird thing happen, where adding --bless to x test tests/pretty caused a full LLVM rebuild.
That's definitely unexpected, right?

@ZuseZ4
Copy link
Member

ZuseZ4 commented Apr 7, 2025

My experience is that if you rebase across an LLVM update, then the very first x command will often work once,
and every following one (including x test) will cause the full llvm rebuild, presumably because it realizes that the llvm submodule has changed.

But I also have to say that this specific rebase was strange, when I updated my local rust builds, two of them ran into an LLVM issue that some option was already known, so I had to delete the whole build folder, this happens rarely.

If you in the future run into an issue where x isn't rebuilding all of llvm, but everything starting from rustc_llvm onwards (without an obvious reason), then there is a good chance that rust-analyzer is causing it, feel free to ping me in that case.

But after all, the vast majority of rustc devs don't build LLVM at all, so there are also fewer people to test, report, and fix bootstrap issues related to it. I hope to get rid of the requirement of building LLVM from source, but that requires fighting cmake, something I am not too keen about.

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 7, 2025
Rollup of 5 pull requests

Successful merges:

 - rust-lang#138314 (fix usage of `autodiff` macro with inner functions)
 - rust-lang#139426 (Make the UnifyKey and UnifyValue imports non-nightly)
 - rust-lang#139431 (Remove LLVM 18 inline ASM span fallback)
 - rust-lang#139456 (style guide: add let-chain rules)
 - rust-lang#139467 (More trivial tweaks)

r? `@ghost`
`@rustbot` modify labels: rollup
@haenoe
Copy link
Contributor Author

haenoe commented Apr 7, 2025

Yes the option thingy was the problem I ran into also!
Do we rebuild LLVM on the rustc side as a "conservative" measure? Or are there just so many changes when LLVM is bumped that 4000+ objects have to be rebuilt?

Do any of the other "experimental" features (thinking primarily of gpu offloading) that need some custom [llvm] config provide some way of downloading LLVM from CI?

@bors bors merged commit 5a43d92 into rust-lang:master Apr 7, 2025
6 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 7, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 7, 2025
Rollup merge of rust-lang#138314 - haenoe:autodiff-inner-function, r=ZuseZ4

fix usage of `autodiff` macro with inner functions

This PR adds additional handling into the expansion step of the `std::autodiff` macro (in `compiler/rustc_builtin_macros/src/autodiff.rs`), which allows the macro to be applied to inner functions.

```rust
#![feature(autodiff)]
use std::autodiff::autodiff;

fn main() {
    #[autodiff(d_inner, Forward, Dual, DualOnly)]
    fn inner(x: f32) -> f32 {
        x * x
    }
}
```

Previously, the compiler didn't allow this due to only handling `Annotatable::Item` and `Annotatable::AssocItem` and missing the handling of `Annotatable::Stmt`. This resulted in the rather generic error

```
error: autodiff must be applied to function
 --> src/main.rs:6:5
  |
6 | /     fn inner(x: f32) -> f32 {
7 | |         x * x
8 | |     }
  | |_____^

error: could not compile `enzyme-test` (bin "enzyme-test") due to 1 previous error
```

This issue was originally reported [here](EnzymeAD#184).

Quick question: would it make sense to add a ui test to ensure there is no regression on this?
This is my first contribution, so I'm extra grateful for any piece of feedback!! :D

r? `@oli-obk`

Tracking issue for autodiff: rust-lang#124509
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-autodiff `#![feature(autodiff)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants