Skip to content

Commit 13d7a3c

Browse files
committed
Add amdgpu_dispatch_ptr intrinsic
Add a rustc intrinsic `amdgpu_dispatch_ptr` to access the kernel dispatch packet on amdgpu. The HSA kernel dispatch packet contains important information like the launch size and workgroup size. The Rust intrinsic lowers to the `llvm.amdgcn.dispatch.ptr` LLVM intrinsic, which returns a `ptr addrspace(4)`, plus an addrspacecast to `addrspace(0)`, so it can be returned as a Rust reference. The returned pointer/reference is valid for the whole program lifetime, and is therefore `'static`. The return type of the intrinsic (`*const ()`) does not mention the struct so that rustc does not need to know the exact struct type. An alternative would be to define the struct as lang item or add a generic argument to the function. Short version: ```rust #[cfg(target_arch = "amdgpu")] pub fn amdgpu_dispatch_ptr() -> *const (); ```
1 parent fcd6309 commit 13d7a3c

File tree

7 files changed

+60
-0
lines changed

7 files changed

+60
-0
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,11 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
560560
return Ok(());
561561
}
562562

563+
sym::amdgpu_dispatch_ptr => {
564+
let val = self.call_intrinsic("llvm.amdgcn.dispatch.ptr", &[], &[]);
565+
self.pointercast(val, self.type_ptr())
566+
}
567+
563568
_ if name.as_str().starts_with("simd_") => {
564569
// Unpack non-power-of-2 #[repr(packed, simd)] arguments.
565570
// This gives them the expected layout of a regular #[repr(simd)] vector.

compiler/rustc_codegen_ssa/src/mir/intrinsic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
112112
| sym::unreachable
113113
| sym::cold_path
114114
| sym::breakpoint
115+
| sym::amdgpu_dispatch_ptr
115116
| sym::assert_zero_valid
116117
| sym::assert_mem_uninitialized_valid
117118
| sym::assert_inhabited

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
7070
| sym::add_with_overflow
7171
| sym::aggregate_raw_ptr
7272
| sym::align_of
73+
| sym::amdgpu_dispatch_ptr
7374
| sym::assert_inhabited
7475
| sym::assert_mem_uninitialized_valid
7576
| sym::assert_zero_valid
@@ -285,6 +286,7 @@ pub(crate) fn check_intrinsic_type(
285286
let (n_tps, n_cts, inputs, output) = match intrinsic_name {
286287
sym::autodiff => (4, 0, vec![param(0), param(1), param(2)], param(3)),
287288
sym::abort => (0, 0, vec![], tcx.types.never),
289+
sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),
288290
sym::unreachable => (0, 0, vec![], tcx.types.never),
289291
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
290292
sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ symbols! {
454454
alu32,
455455
always,
456456
amdgpu,
457+
amdgpu_dispatch_ptr,
457458
analysis,
458459
and,
459460
and_then,

library/core/src/intrinsics/gpu.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Intrinsics for GPU targets.
2+
//!
3+
//! Intrinsics in this module are intended for use on GPU targets.
4+
//! They can be target specific but in general GPU targets are similar.
5+
6+
#![unstable(feature = "gpu_intrinsics", issue = "none")]
7+
8+
/// Returns a pointer to the HSA kernel dispatch packet.
9+
///
10+
/// A `gpu-kernel` on amdgpu is always launched through a kernel dispatch packet.
11+
/// The dispatch packet contains the workgroup size, launch size and other data.
12+
/// The content is defined by the [HSA Platform System Architecture Specification],
13+
/// which is implemented e.g. in AMD's [hsa.h].
14+
/// The intrinsic returns a unit pointer so that rustc does not need to know the packet struct.
15+
/// The pointer is valid for the whole lifetime of the program.
16+
///
17+
/// [HSA Platform System Architecture Specification]: https://hsafoundation.com/wp-content/uploads/2021/02/HSA-SysArch-1.2.pdf
18+
/// [hsa.h]: https://github.com/ROCm/rocm-systems/blob/rocm-7.1.0/projects/rocr-runtime/runtime/hsa-runtime/inc/hsa.h#L2959
19+
#[rustc_nounwind]
20+
#[rustc_intrinsic]
21+
#[cfg(target_arch = "amdgpu")]
22+
#[must_use = "returns a pointer that does nothing unless used"]
23+
pub fn amdgpu_dispatch_ptr() -> *const ();

library/core/src/intrinsics/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ use crate::{mem, ptr};
6060

6161
mod bounds;
6262
pub mod fallback;
63+
pub mod gpu;
6364
pub mod mir;
6465
pub mod simd;
6566

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Tests the amdgpu_dispatch_ptr intrinsic.
2+
3+
//@ compile-flags: --crate-type=rlib --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
4+
//@ needs-llvm-components: amdgpu
5+
//@ add-minicore
6+
#![feature(intrinsics, no_core, rustc_attrs)]
7+
#![no_core]
8+
9+
extern crate minicore;
10+
11+
pub struct DispatchPacket {
12+
pub header: u16,
13+
pub setup: u16,
14+
pub workgroup_size_x: u16, // and more
15+
}
16+
17+
#[rustc_intrinsic]
18+
#[rustc_nounwind]
19+
fn amdgpu_dispatch_ptr() -> *const ();
20+
21+
// CHECK: %[[ORIG_PTR:[^ ]+]] = tail call ptr addrspace(4) @llvm.amdgcn.dispatch.ptr()
22+
// CHECK: %[[PTR:[^ ]+]] = addrspacecast ptr addrspace(4) %[[ORIG_PTR]] to ptr
23+
// CHECK: ret ptr %[[PTR]]
24+
#[unsafe(no_mangle)]
25+
pub fn get_dispatch_data() -> &'static DispatchPacket {
26+
unsafe { &*(amdgpu_dispatch_ptr() as *const _) }
27+
}

0 commit comments

Comments
 (0)