Skip to content

Commit

Permalink
Add amdgpu target
Browse files Browse the repository at this point in the history
Add target and compile the amdgpu llvm backend.
  • Loading branch information
Flakebi committed Jan 2, 2025
1 parent bf6f8a4 commit c47a2c9
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 7 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,8 @@ supported_targets! {

("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),

("amdgcn-amd-amdhsa", amdgcn_amd_amdhsa),

("xtensa-esp32-none-elf", xtensa_esp32_none_elf),
("xtensa-esp32-espidf", xtensa_esp32_espidf),
("xtensa-esp32s2-none-elf", xtensa_esp32s2_none_elf),
Expand Down
47 changes: 47 additions & 0 deletions compiler/rustc_target/src/spec/targets/amdgcn_amd_amdhsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetOptions};

pub(crate) fn target() -> Target {
Target {
arch: "amdgpu".into(),
data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(),
llvm_target: "amdgcn-amd-amdhsa".into(),
metadata: crate::spec::TargetMetadata {
description: Some("AMD GPU".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 64,

options: TargetOptions {
os: "amdhsa".into(),
vendor: "amd".into(),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()),

max_atomic_width: Some(64),

// Unwinding on GPUs is not useful.
panic_strategy: PanicStrategy::Abort,

// amdgpu backend does not support libcalls.
no_builtins: true,
simd_types_indirect: false,

// Allow `cdylib` crate type.
dynamic_linking: true,
only_cdylib: true,
executables: false,
dll_prefix: "".into(),
dll_suffix: ".elf".into(),

// The LLVM backend does not support stack canaries for this target
supports_stack_protector: false,

// Force LTO, object linking does not yet work with amdgpu.
requires_lto: true,

..Default::default()
},
}
}
2 changes: 1 addition & 1 deletion config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
# the resulting rustc being unable to compile for the disabled architectures.
#
# To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html.
#targets = "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
#targets = "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"

# LLVM experimental targets to build support for. These targets are specified in
# the same format as above, but since these targets are experimental, they are
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/download-ci-llvm-stamp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.

Last change is for: /~https://github.com/rust-lang/rust/pull/129788
Last change is for: /~https://github.com/rust-lang/rust/pull/134740
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ impl Step for Llvm {
let llvm_targets = match &builder.config.llvm_targets {
Some(s) => s,
None => {
"AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
"AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
Sparc;SystemZ;WebAssembly;X86"
}
};
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [\*-apple-watchos](platform-support/apple-watchos.md)
- [\*-apple-visionos](platform-support/apple-visionos.md)
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
- [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
- [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
- [arm-none-eabi](platform-support/arm-none-eabi.md)
- [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
Expand Down
2 changes: 2 additions & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ target | std | host | notes
`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
[`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian)
[`amdgcn-amd-amdhsa`](platform-support/amdgcn-amd-amdhsa.md) | * | | `-Ctarget-cpu=gfx...` to specify [the AMD GPU] to compile for
[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers
[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin
[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
Expand Down Expand Up @@ -418,3 +419,4 @@ target | std | host | notes
[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3

[runs on NVIDIA GPUs]: /~https://github.com/japaric-archived/nvptx#targets
[the AMD GPU]: https://llvm.org/docs/AMDGPUUsage.html#processors
96 changes: 96 additions & 0 deletions src/doc/rustc/src/platform-support/amdgcn-amd-amdhsa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# `amdgcn-amd-amdhsa`

**Tier: 3**

AMD GPU target for compute/HSA (Heterogeneous System Architecture).

## Target maintainers

- [@Flakebi](/~https://github.com/Flakebi)

## Requirements

AMD GPUs can be targeted via cross-compilation.
The default binary format is ELF.
Binaries can be loaded by the HSA runtime implemented in [ROCR-Runtime].

Binaries must be built with no-std.
They can use `core` and `alloc` (`alloc` only if an allocator is supplied).
At least one function needs to use the `"amdgpu-kernel"` calling convention.
These functions can be used as kernel entrypoints in HSA.

## Building the target

The target is included in rustc.

## Building Rust programs

The amdgpu target supports many hardware generations, which need different binaries.
The generations are all exposed as different target-cpus in the backend.
As there are many, Rust does not ship pre-compiled libraries for this target.
Therefore, you have to build your own copy of `core` by using `cargo -Zbuild-std=core` or similar.

To build a binary that can be loaded with HSA, create a no-std library:
```rust
// src/lib.rs
#![feature(abi_amdgpu_kernel)]
#![no_std]

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}

#[no_mangle]
pub extern "amdgpu-kernel" fn kernel(/* Arguments */) {
// Code
}
```

Build the library as `cdylib`:
```toml
# Cargo.toml
[lib]
crate-type = ["cdylib"]

[profile.dev]
lto = true # LTO must be explicitly enabled for now
[profile.release]
lto = true
```

The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`).
The GPU version on the current system can be found e.g. with [`rocminfo`].

Example `.cargo/config.toml` file to set the target and GPU generation:
```toml
# .cargo/config.toml
[build]
target = "amdgcn-amd-amdhsa"
rustflags = ["-Ctarget-cpu=gfx1100"]

[unstable]
build-std = ["core"] # Optional: "alloc"
```

<!-- Mention an allocator once a suitable one exists for amdgpu -->

<!-- Mention HSA bindings once they work
## Testing
Does the target support running binaries, or do binaries have varying
expectations that prevent having a standard way to run them? If users can run
binaries, can they do so in some common emulator, or do they need native
hardware? Does the target support running the Rust testsuite?
-->

## Additional information

More information can be found on the [LLVM page for amdgpu]

[ROCR-Runtime]: /~https://github.com/ROCm/ROCR-Runtime
[supported by LLVM]: https://llvm.org/docs/AMDGPUUsage.html#processors
[LLVM page for amdgpu]: https://llvm.org/docs/AMDGPUUsage.html
[`rocminfo`]: /~https://github.com/ROCm/rocminfo
1 change: 1 addition & 0 deletions src/tools/build-manifest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ static TARGETS: &[&str] = &[
"aarch64-unknown-none-softfloat",
"aarch64-unknown-redox",
"aarch64-unknown-uefi",
"amdgcn-amd-amdhsa",
"arm64e-apple-darwin",
"arm64e-apple-ios",
"arm64e-apple-tvos",
Expand Down
21 changes: 21 additions & 0 deletions tests/assembly/targets/targets-amdgpu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@ assembly-output: emit-asm
// ignore-tidy-linelength
//@ revisions: amdgcn_amd_amdhsa
//@ [amdgcn_amd_amdhsa] compile-flags: --target amdgcn-amd-amdhsa
//@ [amdgcn_amd_amdhsa] needs-llvm-components: amdgpu

// Sanity-check that each target can produce assembly code.

#![feature(no_core, lang_items)]
#![no_std]
#![no_core]
#![crate_type = "lib"]

#[lang = "sized"]
trait Sized {}

pub fn test() -> u8 {
42
}

// CHECK: .version
8 changes: 4 additions & 4 deletions tests/ui/check-cfg/well-known-values.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_arch = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
= note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
Expand Down Expand Up @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_os = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
Expand Down Expand Up @@ -230,7 +230,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
LL | target_vendor = "_UNEXPECTED_VALUE",
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
= note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
Expand Down Expand Up @@ -285,7 +285,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
| |
| help: there is a expected value with a similar name: `"linux"`
|
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration

warning: 29 warnings emitted
Expand Down

0 comments on commit c47a2c9

Please sign in to comment.