Skip to main content

core/stdarch/crates/core_arch/src/nvptx/
mod.rs

1//! NVPTX intrinsics (experimental)
2//!
3//! These intrinsics form the foundation of the CUDA
4//! programming model.
5//!
6//! The reference is the [CUDA C Programming Guide][cuda_c]. Relevant is also
7//! the [LLVM NVPTX Backend documentation][llvm_docs].
8//!
9//! [cuda_c]:
10//! http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html
11//! [llvm_docs]:
12//! https://llvm.org/docs/NVPTXUsage.html
13
14use crate::ffi::c_void;
15
16mod packed;
17
18#[unstable(feature = "stdarch_nvptx", issue = "111199")]
19pub use packed::*;
20
21#[allow(improper_ctypes)]
22unsafe extern "unadjusted" {
23    #[link_name = "llvm.nvvm.barrier.cta.sync.aligned.all"]
24    fn syncthreads(a: u32) -> ();
25    #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.x"]
26    fn block_dim_x() -> u32;
27    #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.y"]
28    fn block_dim_y() -> u32;
29    #[link_name = "llvm.nvvm.read.ptx.sreg.ntid.z"]
30    fn block_dim_z() -> u32;
31    #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.x"]
32    fn block_idx_x() -> u32;
33    #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.y"]
34    fn block_idx_y() -> u32;
35    #[link_name = "llvm.nvvm.read.ptx.sreg.ctaid.z"]
36    fn block_idx_z() -> u32;
37    #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.x"]
38    fn grid_dim_x() -> u32;
39    #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.y"]
40    fn grid_dim_y() -> u32;
41    #[link_name = "llvm.nvvm.read.ptx.sreg.nctaid.z"]
42    fn grid_dim_z() -> u32;
43    #[link_name = "llvm.nvvm.read.ptx.sreg.tid.x"]
44    fn thread_idx_x() -> u32;
45    #[link_name = "llvm.nvvm.read.ptx.sreg.tid.y"]
46    fn thread_idx_y() -> u32;
47    #[link_name = "llvm.nvvm.read.ptx.sreg.tid.z"]
48    fn thread_idx_z() -> u32;
49}
50
51/// Synchronizes all threads in the block.
52///
53#[doc = include_str!("../amdgpu/intrinsic_is_convergent.md")]
54#[inline]
55#[unstable(feature = "stdarch_nvptx", issue = "111199")]
56pub unsafe fn _syncthreads() -> () {
57    syncthreads(0)
58}
59
60/// x-th thread-block dimension.
61#[inline]
62#[unstable(feature = "stdarch_nvptx", issue = "111199")]
63pub unsafe fn _block_dim_x() -> u32 {
64    block_dim_x()
65}
66
67/// y-th thread-block dimension.
68#[inline]
69#[unstable(feature = "stdarch_nvptx", issue = "111199")]
70pub unsafe fn _block_dim_y() -> u32 {
71    block_dim_y()
72}
73
74/// z-th thread-block dimension.
75#[inline]
76#[unstable(feature = "stdarch_nvptx", issue = "111199")]
77pub unsafe fn _block_dim_z() -> u32 {
78    block_dim_z()
79}
80
81/// x-th thread-block index.
82#[inline]
83#[unstable(feature = "stdarch_nvptx", issue = "111199")]
84pub unsafe fn _block_idx_x() -> u32 {
85    block_idx_x()
86}
87
88/// y-th thread-block index.
89#[inline]
90#[unstable(feature = "stdarch_nvptx", issue = "111199")]
91pub unsafe fn _block_idx_y() -> u32 {
92    block_idx_y()
93}
94
95/// z-th thread-block index.
96#[inline]
97#[unstable(feature = "stdarch_nvptx", issue = "111199")]
98pub unsafe fn _block_idx_z() -> u32 {
99    block_idx_z()
100}
101
102/// x-th block-grid dimension.
103#[inline]
104#[unstable(feature = "stdarch_nvptx", issue = "111199")]
105pub unsafe fn _grid_dim_x() -> u32 {
106    grid_dim_x()
107}
108
109/// y-th block-grid dimension.
110#[inline]
111#[unstable(feature = "stdarch_nvptx", issue = "111199")]
112pub unsafe fn _grid_dim_y() -> u32 {
113    grid_dim_y()
114}
115
116/// z-th block-grid dimension.
117#[inline]
118#[unstable(feature = "stdarch_nvptx", issue = "111199")]
119pub unsafe fn _grid_dim_z() -> u32 {
120    grid_dim_z()
121}
122
123/// x-th thread index.
124#[inline]
125#[unstable(feature = "stdarch_nvptx", issue = "111199")]
126pub unsafe fn _thread_idx_x() -> u32 {
127    thread_idx_x()
128}
129
130/// y-th thread index.
131#[inline]
132#[unstable(feature = "stdarch_nvptx", issue = "111199")]
133pub unsafe fn _thread_idx_y() -> u32 {
134    thread_idx_y()
135}
136
137/// z-th thread index.
138#[inline]
139#[unstable(feature = "stdarch_nvptx", issue = "111199")]
140pub unsafe fn _thread_idx_z() -> u32 {
141    thread_idx_z()
142}
143
144/// Generates the trap instruction `TRAP`
145#[inline]
146#[unstable(feature = "stdarch_nvptx", issue = "111199")]
147pub unsafe fn trap() -> ! {
148    crate::intrinsics::abort()
149}
150
151// Basic CUDA syscall declarations.
152unsafe extern "C" {
153    /// Print formatted output from a kernel to a host-side output stream.
154    ///
155    /// Syscall arguments:
156    /// * `status`: The status value that is returned by `vprintf`.
157    /// * `format`: A pointer to the format specifier input (uses common `printf` format).
158    /// * `valist`: A pointer to the valist input.
159    ///
160    /// ```ignore (available only for nvptx)
161    /// # use std::mem::transmute;
162    /// #[repr(C)]
163    /// struct PrintArgs(f32, f32, f32, i32);
164    ///
165    /// let a = 0.1f32;
166    /// let b = 0.2f32;
167    /// vprintf(
168    ///     "int(%f + %f) = int(%f) = %d\n".as_ptr(),
169    ///     transmute(&PrintArgs(a, b, a + b, (a + b) as i32)),
170    /// );
171    /// ```
172    ///
173    /// Sources:
174    /// [Programming Guide](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#formatted-output),
175    /// [PTX Interoperability](https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#system-calls).
176    #[unstable(feature = "stdarch_nvptx", issue = "111199")]
177    pub fn vprintf(format: *const u8, valist: *const c_void) -> i32;
178
179    /// Allocate memory dynamically from a fixed-size heap in global memory.
180    ///
181    /// The CUDA in-kernel `malloc()` function allocates at least `size` bytes
182    /// from the device heap and returns a pointer to the allocated memory
183    /// or `NULL` if insufficient memory exists to fulfill the request.
184    ///
185    /// The returned pointer is guaranteed to be aligned to a 16-byte boundary.
186    ///
187    /// The memory allocated by a given CUDA thread via `malloc()` remains allocated
188    /// for the lifetime of the CUDA context, or until it is explicitly released
189    /// by a call to `free()`. It can be used by any other CUDA threads
190    /// even from subsequent kernel launches.
191    ///
192    /// Sources:
193    /// [Programming Guide](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#dynamic-global-memory-allocation-and-operations),
194    /// [PTX Interoperability](https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#system-calls).
195    // FIXME(denzp): assign `malloc` and `nothrow` attributes.
196    #[unstable(feature = "stdarch_nvptx", issue = "111199")]
197    pub fn malloc(size: usize) -> *mut c_void;
198
199    /// Free previously dynamically allocated memory.
200    ///
201    /// The CUDA in-kernel `free()` function deallocates the memory pointed to by `ptr`,
202    /// which must have been returned by a previous call to `malloc()`. If `ptr` is NULL,
203    /// the call to `free()` is ignored.
204    ///
205    /// Any CUDA thread may free memory allocated by another thread, but care should be taken
206    /// to ensure that the same pointer is not freed more than once. Repeated calls to `free()`
207    /// with the same `ptr` has undefined behavior.
208    ///
209    /// Sources:
210    /// [Programming Guide](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#dynamic-global-memory-allocation-and-operations),
211    /// [PTX Interoperability](https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#system-calls).
212    // FIXME(denzp): assign `nothrow` attribute.
213    #[unstable(feature = "stdarch_nvptx", issue = "111199")]
214    pub fn free(ptr: *mut c_void);
215
216    // Internal declaration of the syscall. Exported variant has
217    // the `char_size` parameter set to `1` (single char size in bytes).
218    fn __assertfail(
219        message: *const u8,
220        file: *const u8,
221        line: u32,
222        function: *const u8,
223        char_size: usize,
224    );
225}
226
227/// Syscall to be used whenever the *assert expression produces a `false` value*.
228///
229/// Syscall arguments:
230/// * `message`: The pointer to the string that should be output.
231/// * `file`: The pointer to the file name string associated with the assert.
232/// * `line`: The line number associated with the assert.
233/// * `function`: The pointer to the function name string associated with the assert.
234///
235/// Source:
236/// [PTX Interoperability](https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability/index.html#system-calls).
237#[inline]
238#[unstable(feature = "stdarch_nvptx", issue = "111199")]
239pub unsafe fn __assert_fail(message: *const u8, file: *const u8, line: u32, function: *const u8) {
240    __assertfail(message, file, line, function, 1)
241}