Skip to content

Commit 2efa31b

Browse files
committed
Auto merge of #57937 - denzp:nvptx, r=nagisa
NVPTX target specification This change adds a built-in `nvptx64-nvidia-cuda` GPGPU no-std target specification and a basic PTX assembly smoke tests. The approach is taken here and the target spec is based on `ptx-linker`, a project started about 1.5 years ago. Key feature: bitcode object files being linked with LTO into the final module on the linker's side. Prior to this change, the linker used a `ld` linker-flavor, but I think, having the special CLI convention is a more reliable way. Questions about further progress on reliable CUDA workflow with Rust: 1. Is it possible to create a test suite `codegen-asm` to verify end-to-end integration with LLVM backend? 1. How would it be better to organise no-std `compile-fail` tests: add `#![no_std]` where possible and mark others as `ignore-nvptx` directive, or alternatively, introduce `compile-fail-no-std` test suite? 1. Can we have the `ptx-linker` eventually be integrated as `rls` or `clippy`? Hopefully, this should allow to statically link against LLVM used in Rust and get rid of the [current hacky solution](https://github.com/denzp/rustc-llvm-proxy). 1. Am I missing some methods from `rustc_codegen_ssa::back::linker::Linker` that can be useful for bitcode-only linking? Currently, there are no major public CUDA projects written in Rust I'm aware of, but I'm expecting to have a built-in target will create a solid foundation for further experiments and awesome crates. Related to #38789 Fixes #38787 Fixes #38786
2 parents 852701a + 49931fd commit 2efa31b

File tree

19 files changed

+483
-61
lines changed

19 files changed

+483
-61
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ matrix:
168168
if: branch = auto
169169
- env: IMAGE=i686-gnu-nopt
170170
if: branch = auto
171-
- env: IMAGE=wasm32-unknown
171+
- env: IMAGE=test-various
172172
if: branch = auto
173173
- env: IMAGE=x86_64-gnu
174174
if: branch = auto

src/bootstrap/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ impl Build {
831831
!target.contains("msvc") &&
832832
!target.contains("emscripten") &&
833833
!target.contains("wasm32") &&
834+
!target.contains("nvptx") &&
834835
!target.contains("fuchsia") {
835836
Some(self.cc(target))
836837
} else {

src/bootstrap/sanity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub fn check(build: &mut Build) {
156156
panic!("the iOS target is only supported on macOS");
157157
}
158158

159-
if target.contains("-none-") {
159+
if target.contains("-none-") || target.contains("nvptx") {
160160
if build.no_std(*target).is_none() {
161161
let target = build.config.target_config.entry(target.clone())
162162
.or_default();
@@ -165,7 +165,7 @@ pub fn check(build: &mut Build) {
165165
}
166166

167167
if build.no_std(*target) == Some(false) {
168-
panic!("All the *-none-* targets are no-std targets")
168+
panic!("All the *-none-* and nvptx* targets are no-std targets")
169169
}
170170
}
171171

src/ci/docker/dist-various-2/Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ ENV TARGETS=$TARGETS,x86_64-sun-solaris
7070
ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32
7171
ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi
7272
ENV TARGETS=$TARGETS,x86_64-fortanix-unknown-sgx
73+
ENV TARGETS=$TARGETS,nvptx64-nvidia-cuda
7374

7475
ENV X86_FORTANIX_SGX_LIBS="/x86_64-fortanix-unknown-sgx/lib/"
7576

src/ci/docker/wasm32-unknown/Dockerfile src/ci/docker/test-various/Dockerfile

+14-5
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1313
gdb \
1414
xz-utils
1515

16+
# FIXME: build the `ptx-linker` instead.
17+
RUN curl -sL https://github.com/denzp/rust-ptx-linker/releases/download/v0.9.0-alpha.2/rust-ptx-linker.linux64.tar.gz | \
18+
tar -xzvC /usr/bin
19+
1620
RUN curl -sL https://nodejs.org/dist/v9.2.0/node-v9.2.0-linux-x64.tar.xz | \
17-
tar -xJ
21+
tar -xJ
1822

1923
COPY scripts/sccache.sh /scripts/
2024
RUN sh /scripts/sccache.sh
2125

22-
ENV TARGETS=wasm32-unknown-unknown
23-
2426
ENV RUST_CONFIGURE_ARGS \
2527
--set build.nodejs=/node-v9.2.0-linux-x64/bin/node \
2628
--set rust.lld
@@ -31,11 +33,18 @@ ENV RUST_CONFIGURE_ARGS \
3133
# other contexts as well
3234
ENV NO_DEBUG_ASSERTIONS=1
3335

34-
ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \
36+
ENV WASM_TARGETS=wasm32-unknown-unknown
37+
ENV WASM_SCRIPT python2.7 /checkout/x.py test --target $WASM_TARGETS \
3538
src/test/run-make \
3639
src/test/ui \
3740
src/test/run-pass \
3841
src/test/compile-fail \
3942
src/test/mir-opt \
4043
src/test/codegen-units \
41-
src/libcore \
44+
src/libcore
45+
46+
ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
47+
ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \
48+
src/test/run-make
49+
50+
ENV SCRIPT $WASM_SCRIPT && $NVPTX_SCRIPT

src/librustc/ty/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
16751675
}
16761676
false
16771677
}
1678+
1679+
/// Determine whether identifiers in the assembly have strict naming rules.
1680+
/// Currently, only NVPTX* targets need it.
1681+
pub fn has_strict_asm_symbol_naming(&self) -> bool {
1682+
self.gcx.sess.target.target.arch.contains("nvptx")
1683+
}
16781684
}
16791685

16801686
impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {

src/librustc_codegen_ssa/back/link.rs

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
149149
LinkerFlavor::Ld => "ld",
150150
LinkerFlavor::Msvc => "link.exe",
151151
LinkerFlavor::Lld(_) => "lld",
152+
LinkerFlavor::PtxLinker => "rust-ptx-linker",
152153
}), flavor)),
153154
(Some(linker), None) => {
154155
let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") {

src/librustc_codegen_ssa/back/linker.rs

+131-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
1313
use rustc::middle::dependency_format::Linkage;
1414
use rustc::session::Session;
1515
use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
16-
CrossLangLto};
16+
CrossLangLto, Lto};
1717
use rustc::ty::TyCtxt;
1818
use rustc_target::spec::{LinkerFlavor, LldFlavor};
1919
use serialize::{json, Encoder};
@@ -83,6 +83,10 @@ impl LinkerInfo {
8383
LinkerFlavor::Lld(LldFlavor::Wasm) => {
8484
Box::new(WasmLd::new(cmd, sess, self)) as Box<dyn Linker>
8585
}
86+
87+
LinkerFlavor::PtxLinker => {
88+
Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>
89+
}
8690
}
8791
}
8892
}
@@ -1080,3 +1084,129 @@ fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec<String> {
10801084

10811085
symbols
10821086
}
1087+
1088+
/// Much simplified and explicit CLI for the NVPTX linker. The linker operates
1089+
/// with bitcode and uses LLVM backend to generate a PTX assembly.
1090+
pub struct PtxLinker<'a> {
1091+
cmd: Command,
1092+
sess: &'a Session,
1093+
}
1094+
1095+
impl<'a> Linker for PtxLinker<'a> {
1096+
fn link_rlib(&mut self, path: &Path) {
1097+
self.cmd.arg("--rlib").arg(path);
1098+
}
1099+
1100+
fn link_whole_rlib(&mut self, path: &Path) {
1101+
self.cmd.arg("--rlib").arg(path);
1102+
}
1103+
1104+
fn include_path(&mut self, path: &Path) {
1105+
self.cmd.arg("-L").arg(path);
1106+
}
1107+
1108+
fn debuginfo(&mut self) {
1109+
self.cmd.arg("--debug");
1110+
}
1111+
1112+
fn add_object(&mut self, path: &Path) {
1113+
self.cmd.arg("--bitcode").arg(path);
1114+
}
1115+
1116+
fn args(&mut self, args: &[String]) {
1117+
self.cmd.args(args);
1118+
}
1119+
1120+
fn optimize(&mut self) {
1121+
match self.sess.lto() {
1122+
Lto::Thin | Lto::Fat | Lto::ThinLocal => {
1123+
self.cmd.arg("-Olto");
1124+
},
1125+
1126+
Lto::No => { },
1127+
};
1128+
}
1129+
1130+
fn output_filename(&mut self, path: &Path) {
1131+
self.cmd.arg("-o").arg(path);
1132+
}
1133+
1134+
fn finalize(&mut self) -> Command {
1135+
// Provide the linker with fallback to internal `target-cpu`.
1136+
self.cmd.arg("--fallback-arch").arg(match self.sess.opts.cg.target_cpu {
1137+
Some(ref s) => s,
1138+
None => &self.sess.target.target.options.cpu
1139+
});
1140+
1141+
::std::mem::replace(&mut self.cmd, Command::new(""))
1142+
}
1143+
1144+
fn link_dylib(&mut self, _lib: &str) {
1145+
panic!("external dylibs not supported")
1146+
}
1147+
1148+
fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
1149+
panic!("external dylibs not supported")
1150+
}
1151+
1152+
fn link_staticlib(&mut self, _lib: &str) {
1153+
panic!("staticlibs not supported")
1154+
}
1155+
1156+
fn link_whole_staticlib(&mut self, _lib: &str, _search_path: &[PathBuf]) {
1157+
panic!("staticlibs not supported")
1158+
}
1159+
1160+
fn framework_path(&mut self, _path: &Path) {
1161+
panic!("frameworks not supported")
1162+
}
1163+
1164+
fn link_framework(&mut self, _framework: &str) {
1165+
panic!("frameworks not supported")
1166+
}
1167+
1168+
fn position_independent_executable(&mut self) {
1169+
}
1170+
1171+
fn full_relro(&mut self) {
1172+
}
1173+
1174+
fn partial_relro(&mut self) {
1175+
}
1176+
1177+
fn no_relro(&mut self) {
1178+
}
1179+
1180+
fn build_static_executable(&mut self) {
1181+
}
1182+
1183+
fn gc_sections(&mut self, _keep_metadata: bool) {
1184+
}
1185+
1186+
fn pgo_gen(&mut self) {
1187+
}
1188+
1189+
fn no_default_libraries(&mut self) {
1190+
}
1191+
1192+
fn build_dylib(&mut self, _out_filename: &Path) {
1193+
}
1194+
1195+
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType) {
1196+
}
1197+
1198+
fn subsystem(&mut self, _subsystem: &str) {
1199+
}
1200+
1201+
fn no_position_independent_executable(&mut self) {
1202+
}
1203+
1204+
fn group_start(&mut self) {
1205+
}
1206+
1207+
fn group_end(&mut self) {
1208+
}
1209+
1210+
fn cross_lang_lto(&mut self) {
1211+
}
1212+
}

src/librustc_codegen_utils/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(nll)]
1313
#![allow(unused_attributes)]
1414
#![feature(rustc_diagnostic_macros)]
15+
#![feature(in_band_lifetimes)]
1516

1617
#![recursion_limit="256"]
1718

0 commit comments

Comments
 (0)