-
-
Notifications
You must be signed in to change notification settings - Fork 15.6k
Simplify mono entry-point computation for GPU Offload #162279
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
Open
ZuseZ4
wants to merge
1
commit into
rust-lang:main
Choose a base branch
from
ZuseZ4:offload-device-kernel-roots
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #![crate_type = "rlib"] | ||
|
|
||
| // This tests two things. | ||
| // | ||
| // First, if we directly compile this for the device, then helper should not end up in the LLVM-IR, | ||
| // despite being pub. This makes sure that our mono collector overwrite works. | ||
| // | ||
| // Second, when we compile host.rs, this file becomes a dependency. In that case its MIR should be | ||
| // available, since our Device pass forces `InliningThreshold::Always`. | ||
| #[inline(never)] | ||
| pub fn helper(x: &mut f32) { | ||
| *x = 1.0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #![feature(gpu_offload, rustc_attrs)] | ||
| #![allow(internal_features, dead_code)] | ||
|
|
||
| extern crate dep; | ||
|
|
||
| // Launched by `main`, so the manifest lists it and the device pass compiles it, together with | ||
| // everything it reaches. | ||
| #[rustc_offload_kernel] | ||
| fn launched(x: &mut f32) { | ||
| dep::helper(x); | ||
| } | ||
|
|
||
| // Never launched, so it is not in the manifest and the device pass drops it, despite attribute. | ||
| #[rustc_offload_kernel] | ||
| fn dormant(x: &mut f32) { | ||
| *x = 2.0; | ||
| } | ||
|
|
||
| // Public, but not reachable from any launched kernel. | ||
| pub fn plain_pub(x: &mut f32) { | ||
| *x = 3.0; | ||
| } | ||
|
|
||
| // Offload previously kept the normal mono roots, so we'd need to add various `#[cfg(...)]` | ||
| // attributes to functions like main that shouldn't end up on the Device. This tests that our new | ||
| // mono logic keeps working and correctly disregards this function during device compilation. | ||
| fn main() { | ||
| let mut x = 0.0f32; | ||
| core::offload::offload! { | ||
| kernel = launched, | ||
| args = (&mut x,), | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // With a manifest, the device pass compiles exactly the kernels the host launches and whatever | ||
| // they reach, nothing else. That includes reaching into dependencies: their functions are made | ||
| // available for instantiation by `-Zoffload=Device` itself, so the dependencies do not have to | ||
| // codegen anything for the device, and the kernel crate ends up self-contained. | ||
|
|
||
| //@ needs-offload | ||
|
|
||
| use std::path::Path; | ||
|
|
||
| use run_make_support::{rfs, rustc}; | ||
|
|
||
| fn defines(ll: &str, name: &str) -> bool { | ||
| ll.lines().any(|line| line.starts_with("define") && line.contains(name)) | ||
| } | ||
|
|
||
| fn main() { | ||
| // Host build of the dependency, so the metadata pass can resolve `dep::helper`. | ||
| rustc().input("dep.rs").run(); | ||
|
|
||
| // Pass 1: Our manifest now includes both generic and non-generic kernels that were launched. | ||
| rustc() | ||
| .input("host.rs") | ||
| .extern_("dep", "libdep.rlib") | ||
| .arg("-Zunstable-options") | ||
| .arg("-Zoffload=HostMetadata=kernels.manifest") | ||
| .arg("-Csymbol-mangling-version=v0") | ||
| .arg("-Clto=fat") | ||
| .emit("metadata") | ||
| .run(); | ||
|
|
||
| // Pass 2a: the dependency for the device. It reads a manifest naming kernels in a crate it | ||
| // has never heard of, has no launched kernels of its own, and so has nothing to codegen. | ||
| // FIXME(offload): In the future, we should add better errorhandling here. It's fine to not find | ||
| // the kernels mentioned in the manifest if this is just a dep. However, if the Manifest entry | ||
| // names this crate and the path to the Kernel does not resolve, then we should error. The | ||
| // decoder should be able to tell the difference between both cases. | ||
| rustc() | ||
| .input("dep.rs") | ||
| .arg("-Zunstable-options") | ||
| .arg("-Zoffload=Device=kernels.manifest") | ||
| .arg("-Csymbol-mangling-version=v0") | ||
| .codegen_units(1) | ||
| .emit("link,llvm-ir") | ||
| .out_dir("device") | ||
| .run(); | ||
| if Path::new("device/dep.ll").exists() { | ||
| let dep_ll = rfs::read_to_string("device/dep.ll"); | ||
| assert!(!defines(&dep_ll, "helper"), "`dep::helper` was codegened in its own crate"); | ||
| } | ||
|
|
||
| // Pass 2b: the kernel crate for the device. | ||
| rustc() | ||
| .input("host.rs") | ||
| .extern_("dep", "device/libdep.rlib") | ||
| .arg("-Zunstable-options") | ||
| .arg("-Zoffload=Device=kernels.manifest") | ||
| .arg("-Csymbol-mangling-version=v0") | ||
| .arg("-Clto=fat") | ||
| .codegen_units(1) | ||
| .emit("llvm-ir") | ||
| .out_dir("device") | ||
| .run(); | ||
| let ll = rfs::read_to_string("device/host.ll"); | ||
| assert!(defines(&ll, "launched"), "the launched kernel is missing"); | ||
| assert!(defines(&ll, "helper"), "`dep::helper` was not instantiated in the kernel crate"); | ||
| assert!(!defines(&ll, "dormant"), "an unlaunched kernel was compiled"); | ||
| assert!(!defines(&ll, "plain_pub"), "a function no kernel reaches was compiled"); | ||
| // The entry point would be a root under the usual rules; on the device it is not launched. | ||
| assert!(!defines(&ll, "main"), "the host entry point was compiled for the device"); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't help forcing codegen to happen in the bin crate for
#[unsafe(no_mangle)],#[rustc_std_internal_symbol]and EII functions and the panic handler. As well as statics. Those are still only codegened locally as there is only allowed to be a single instance of them.View changes since the review