| 71 | /// **Calling this function multiple times will yield the same pointer**. |
| 72 | #[gpu_only] |
| 73 | pub fn dynamic_shared_mem<T>() -> *mut T { |
| 74 | // it is unclear whether an alignment of 16 is actually required for correctness, however, |
| 75 | // it seems like nvcc always generates the global with .align 16 no matter the type, so we just copy |
| 76 | // nvcc's behavior for now. |
| 77 | extern "C" { |
| 78 | // need to use nvvm_internal and not address_space because address_space only parses |
| 79 | // static definitions, not extern static definitions. |
| 80 | #[nvvm_internal(addrspace(3))] |
| 81 | #[allow(improper_ctypes)] |
| 82 | // mangle it a bit to make sure nobody makes the same thing |
| 83 | #[link_name = "_Zcuda_std_dyn_shared"] |
| 84 | static DYN_SHARED: ::core::cell::UnsafeCell<u128>; |
| 85 | } |
| 86 | |
| 87 | // SAFETY: extern statics is how dynamic shared mem is done in CUDA. This will turn into |
| 88 | // an extern variable decl in ptx, which is the same thing nvcc does if you dump the ptx from a cuda file. |
| 89 | unsafe { DYN_SHARED.get() as *mut T } |
| 90 | } |