1#![allow(
2 non_upper_case_globals,
3 non_snake_case,
4 non_camel_case_types,
5 unused_comparisons,
6 clippy::too_many_arguments,
7 clippy::missing_safety_doc,
8 clippy::ptr_offset_with_cast,
9 clippy::manual_div_ceil,
10 clippy::useless_transmute
11)]
12#![cfg_attr(not(feature = "dynamic-loading"), no_std)]
13
14#[allow(unused_macros)]
15macro_rules! link {
16 (
17 $lib:ident : [$($version:literal),*$(,)?] : $cfg_ver:ident;
18
19 $(
20 $(
21 #[private($cfg_priv:ident)]
22 )?
23 $(
24 #[doc = $docs:literal]
25 )*
26 $(#[deprecated = $note:literal$(, $cfg_strong:ident)?])?
27 $(#[since = $major_version:literal.$minor_version:literal,
28 $version_string:literal])?
29 $vis:vis fn $name:ident($($arg:ident: $arg_ty:ty),*$(,)?) $(-> $ret:ty)?;
30 )*
31 ) => {
32 #[cfg(feature = "dynamic-loading")]
33 static $lib: ::std::sync::LazyLock<libloading::Library> = {
34 const LIBRARIES: &[&str] = {
35 #[cfg(target_os = "linux")]
36 {
37 &[
38 concat!("lib", stringify!($lib), ".so"),
39 $(
40 concat!("lib", stringify!($lib), ".so.", stringify!($version)),
41 )*
42 ]
43 }
44
45 #[cfg(target_os = "windows")]
46 {
47 &[
48 concat!(stringify!($lib), ".dll"),
49 $(
50 concat!(stringify!($lib), "-", stringify!($version), ".dll"),
51 )*
52 ]
53 }
54
55 #[cfg(not(any(target_os = "windows", target_os = "linux")))]
56 {
57 &[]
58 }
59 };
60
61 ::std::sync::LazyLock::new(|| {
62 let roots = [
63 std::env::var_os("ROCM_PATH"),
64 Some("/opt/rocm".into()),
65 Some("/usr/local/rocm".into()),
66 ];
67
68 for root in roots.into_iter().flatten() {
69 let lib_dir = std::path::Path::new(&root).join("lib");
70
71 for choice in LIBRARIES {
72 let path = lib_dir.join(choice);
73
74 if let Ok(lib) = unsafe {
75 libloading::Library::new(&path)
76 } {
77 return lib;
78 }
79 }
80 }
81
82 panic!("Unable to dynamically load the {:?} shared library - searched for library names: {:?}. \
83If the shared library is present on the system under a different name than one of those listed above, please open a GitHub issue.", stringify!($lib), LIBRARIES);
84 })
85 };
86
87 $(
88 $(
89 #[$cfg_priv(feature = "private")]
90 )?
91 $(
92 #[doc = $docs]
93 )*
94 $(
95 $(#[$cfg_strong(feature = "deprecated")])?
96 #[deprecated = $note]
97 )?
98 #[cfg(feature = "dynamic-loading")]
99 $vis unsafe fn $name(
100 $($arg: $arg_ty),*
101 ) $(-> $ret)? {
102 type F = unsafe extern "C" fn(
103 $($arg_ty),*
104 ) $(-> $ret)?;
105
106 static SYMBOL: ::std::sync::OnceLock<F> = ::std::sync::OnceLock::new();
107
108 let f = SYMBOL.get_or_init(|| unsafe {
109 $(
110 let major = *MAJOR;
111 let minor = *MINOR;
112
113 assert!(major >= $major_version && minor >= $minor_version, "{} requires ROCm version ^{major}.{minor}", stringify!($name));
114 )?
115
116 *$lib.get::<F>(concat!(stringify!($name), "\0")).unwrap()
117 });
118
119 unsafe {
120 f($($arg),*)
121 }
122 }
123
124 $(
125 #[$cfg_priv(feature = "private")]
126 )?
127 $(
128 #[doc = $docs]
129 )*
130 $(
131 $(#[$cfg_strong(feature = "deprecated")])?
132 #[deprecated = $note]
133 )?
134 #[inline]
135 #[cfg(all(
136 not(feature = "dynamic-loading"),
137 $(
138 $cfg_ver = $version_string
139 )?
140 ))]
141 $vis unsafe fn $name(
142 $($arg: $arg_ty),*
143 ) $(-> $ret)? {
144 unsafe extern "C" {
145 #[link_name = stringify!($name)]
146 unsafe fn inner(
147 $($arg: $arg_ty),*
148 ) $(-> $ret)?;
149 }
150
151 unsafe {
152 inner($($arg),*)
153 }
154 }
155 )*
156 };
157}
158
159#[cfg(all(feature = "hip", any(feature = "dynamic-loading", hip)))]
160pub mod hip;
161
162#[cfg(all(feature = "hipblas", any(feature = "dynamic-loading", hipblas)))]
163pub mod hipblas;
164
165#[cfg(all(feature = "hipblaslt", any(feature = "dynamic-loading", hipblaslt)))]
166pub mod hipblaslt;
167
168#[cfg(all(feature = "hiprtc", any(feature = "dynamic-loading", hiprtc)))]
169pub mod hiprtc;
170
171#[cfg(all(feature = "rocblas", any(feature = "dynamic-loading", rocblas)))]
172pub mod rocblas;
173
174#[cfg(all(feature = "rocfft", any(feature = "dynamic-loading", rocfft)))]
175pub mod rocfft;
176
177mod version;