Work around broken AMD Adrenalin 25.5.1 driver (#366)

For reasons unknown AMD Adrenalin 25.5.1 ships with comgr that presents itself as version 2, but expects ABI for veersion 3. Add a workaround
This commit is contained in:
Andrzej Janik 2025-05-13 02:20:23 +02:00 committed by GitHub
commit 5935cfec78
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 50 additions and 5 deletions

View file

@ -245,14 +245,37 @@ impl Comgr {
})
.or_else(|_| {
unsafe { libloading::Library::new(os::COMGR2) }.and_then(|lib| {
Ok(Comgr::V2(unsafe {
amd_comgr_sys::comgr2::Comgr2::from_library(lib)?
}))
Ok(if Self::is_broken_v2(&lib) {
Comgr::V3(unsafe { amd_comgr_sys::comgr3::Comgr3::from_library(lib)? })
} else {
Comgr::V2(unsafe { amd_comgr_sys::comgr2::Comgr2::from_library(lib)? })
})
})
})
.map_err(Into::into)
}
// For reasons unknown, on AMD Adrenalin 25.5.1, AMD ships amd_comgr_2.dll that shows up as
// version 2.9.0, but actually uses the 3.X ABI. This is our best effort to detect it.
// Version 25.3.1 returns 2.8.0, which seem to be the last version that actually uses the 2 ABI
fn is_broken_v2(lib: &libloading::Library) -> bool {
if cfg!(not(windows)) {
return false;
}
let amd_comgr_get_version = match unsafe {
lib.get::<unsafe extern "C" fn(major: *mut usize, minor: *mut usize)>(
b"amd_comgr_get_version\0",
)
} {
Ok(symbol) => symbol,
Err(_) => return false,
};
let mut major = 0;
let mut minor = 0;
unsafe { (amd_comgr_get_version)(&mut major, &mut minor) };
(major, minor) >= (2, 9)
}
fn do_action(
&self,
kind: ActionKind,

View file

@ -1,4 +1,4 @@
# On ROCm 6.3 and lower
bindgen --rust-target 1.77 /opt/rocm-6.3.4/include/amd_comgr/amd_comgr.h -o src/comgr2.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --must-use-type amd_comgr_status_t --allowlist-var "^AMD_COMGR.*$" --dynamic-loading Comgr2 --allowlist-function amd_comgr_do_action --allowlist-function amd_comgr_action_data_get_data --allowlist-function amd_comgr_action_info_set_isa_name --allowlist-function amd_comgr_action_info_set_language --allowlist-function amd_comgr_create_action_info --allowlist-function amd_comgr_create_data --allowlist-function amd_comgr_create_data_set --allowlist-function amd_comgr_data_set_add --allowlist-function amd_comgr_destroy_action_info --allowlist-function amd_comgr_destroy_data_set --allowlist-function amd_comgr_get_data --allowlist-function amd_comgr_set_data --allowlist-function amd_comgr_set_data_name --allowlist-function amd_comgr_action_info_set_option_list
bindgen --rust-target 1.77 /opt/rocm-6.3.4/include/amd_comgr/amd_comgr.h -o src/comgr2.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --must-use-type amd_comgr_status_t --allowlist-var "^AMD_COMGR.*$" --dynamic-loading Comgr2 --allowlist-function amd_comgr_do_action --allowlist-function amd_comgr_action_data_get_data --allowlist-function amd_comgr_action_info_set_isa_name --allowlist-function amd_comgr_action_info_set_language --allowlist-function amd_comgr_create_action_info --allowlist-function amd_comgr_create_data --allowlist-function amd_comgr_create_data_set --allowlist-function amd_comgr_data_set_add --allowlist-function amd_comgr_destroy_action_info --allowlist-function amd_comgr_destroy_data_set --allowlist-function amd_comgr_get_data --allowlist-function amd_comgr_set_data --allowlist-function amd_comgr_set_data_name --allowlist-function amd_comgr_action_info_set_option_list --allowlist-function amd_comgr_get_version
# On ROCm 6.4 and higher
bindgen --rust-target 1.77 /opt/rocm/include/amd_comgr/amd_comgr.h -o src/comgr3.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --must-use-type amd_comgr_status_t --allowlist-var "^AMD_COMGR.*$" --dynamic-loading Comgr3 --allowlist-function amd_comgr_do_action --allowlist-function amd_comgr_action_data_get_data --allowlist-function amd_comgr_action_info_set_isa_name --allowlist-function amd_comgr_action_info_set_language --allowlist-function amd_comgr_create_action_info --allowlist-function amd_comgr_create_data --allowlist-function amd_comgr_create_data_set --allowlist-function amd_comgr_data_set_add --allowlist-function amd_comgr_destroy_action_info --allowlist-function amd_comgr_destroy_data_set --allowlist-function amd_comgr_get_data --allowlist-function amd_comgr_set_data --allowlist-function amd_comgr_set_data_name --allowlist-function amd_comgr_action_info_set_option_list
bindgen --rust-target 1.77 /opt/rocm/include/amd_comgr/amd_comgr.h -o src/comgr3.rs --no-layout-tests --default-enum-style=newtype --no-derive-debug --must-use-type amd_comgr_status_t --allowlist-var "^AMD_COMGR.*$" --dynamic-loading Comgr3 --allowlist-function amd_comgr_do_action --allowlist-function amd_comgr_action_data_get_data --allowlist-function amd_comgr_action_info_set_isa_name --allowlist-function amd_comgr_action_info_set_language --allowlist-function amd_comgr_create_action_info --allowlist-function amd_comgr_create_data --allowlist-function amd_comgr_create_data_set --allowlist-function amd_comgr_data_set_add --allowlist-function amd_comgr_destroy_action_info --allowlist-function amd_comgr_destroy_data_set --allowlist-function amd_comgr_get_data --allowlist-function amd_comgr_set_data --allowlist-function amd_comgr_set_data_name --allowlist-function amd_comgr_action_info_set_option_list --allowlist-function amd_comgr_get_version

View file

@ -256,6 +256,8 @@ pub struct amd_comgr_action_kind_s(pub ::std::os::raw::c_uint);
pub use self::amd_comgr_action_kind_s as amd_comgr_action_kind_t;
pub struct Comgr2 {
__library: ::libloading::Library,
pub amd_comgr_get_version:
Result<unsafe extern "C" fn(major: *mut usize, minor: *mut usize), ::libloading::Error>,
pub amd_comgr_create_data: Result<
unsafe extern "C" fn(
kind: amd_comgr_data_kind_t,
@ -363,6 +365,7 @@ impl Comgr2 {
L: Into<::libloading::Library>,
{
let __library = library.into();
let amd_comgr_get_version = __library.get(b"amd_comgr_get_version\0").map(|sym| *sym);
let amd_comgr_create_data = __library.get(b"amd_comgr_create_data\0").map(|sym| *sym);
let amd_comgr_set_data = __library.get(b"amd_comgr_set_data\0").map(|sym| *sym);
let amd_comgr_set_data_name = __library.get(b"amd_comgr_set_data_name\0").map(|sym| *sym);
@ -395,6 +398,7 @@ impl Comgr2 {
let amd_comgr_do_action = __library.get(b"amd_comgr_do_action\0").map(|sym| *sym);
Ok(Comgr2 {
__library,
amd_comgr_get_version,
amd_comgr_create_data,
amd_comgr_set_data,
amd_comgr_set_data_name,
@ -411,6 +415,13 @@ impl Comgr2 {
amd_comgr_do_action,
})
}
#[doc = " @brief Get the version of the code object manager interface\n supported.\n\n An interface is backwards compatible with an implementation with an\n equal major version, and a greater than or equal minor version.\n\n @param[out] major Major version number.\n\n @param[out] minor Minor version number."]
pub unsafe fn amd_comgr_get_version(&self, major: *mut usize, minor: *mut usize) {
(self
.amd_comgr_get_version
.as_ref()
.expect("Expected function, got error."))(major, minor)
}
#[must_use]
#[doc = " @brief Create a data object that can hold data of a specified kind.\n\n Data objects are reference counted and are destroyed when the\n reference count reaches 0. When a data object is created its\n reference count is 1, it has 0 bytes of data, it has an empty name,\n and it has no metadata.\n\n @param[in] kind The kind of data the object is intended to hold.\n\n @param[out] data A handle to the data object created. Its reference\n count is set to 1.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n kind is an invalid data kind, or @p\n AMD_COMGR_DATA_KIND_UNDEF. @p data is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the data object as out of resources."]
pub unsafe fn amd_comgr_create_data(

View file

@ -246,6 +246,8 @@ pub struct amd_comgr_action_kind_s(pub ::std::os::raw::c_uint);
pub use self::amd_comgr_action_kind_s as amd_comgr_action_kind_t;
pub struct Comgr3 {
__library: ::libloading::Library,
pub amd_comgr_get_version:
Result<unsafe extern "C" fn(major: *mut usize, minor: *mut usize), ::libloading::Error>,
pub amd_comgr_create_data: Result<
unsafe extern "C" fn(
kind: amd_comgr_data_kind_t,
@ -353,6 +355,7 @@ impl Comgr3 {
L: Into<::libloading::Library>,
{
let __library = library.into();
let amd_comgr_get_version = __library.get(b"amd_comgr_get_version\0").map(|sym| *sym);
let amd_comgr_create_data = __library.get(b"amd_comgr_create_data\0").map(|sym| *sym);
let amd_comgr_set_data = __library.get(b"amd_comgr_set_data\0").map(|sym| *sym);
let amd_comgr_set_data_name = __library.get(b"amd_comgr_set_data_name\0").map(|sym| *sym);
@ -385,6 +388,7 @@ impl Comgr3 {
let amd_comgr_do_action = __library.get(b"amd_comgr_do_action\0").map(|sym| *sym);
Ok(Comgr3 {
__library,
amd_comgr_get_version,
amd_comgr_create_data,
amd_comgr_set_data,
amd_comgr_set_data_name,
@ -401,6 +405,13 @@ impl Comgr3 {
amd_comgr_do_action,
})
}
#[doc = " @brief Get the version of the code object manager interface\n supported.\n\n An interface is backwards compatible with an implementation with an\n equal major version, and a greater than or equal minor version.\n\n @param[out] major Major version number.\n\n @param[out] minor Minor version number."]
pub unsafe fn amd_comgr_get_version(&self, major: *mut usize, minor: *mut usize) {
(self
.amd_comgr_get_version
.as_ref()
.expect("Expected function, got error."))(major, minor)
}
#[must_use]
#[doc = " @brief Create a data object that can hold data of a specified kind.\n\n Data objects are reference counted and are destroyed when the\n reference count reaches 0. When a data object is created its\n reference count is 1, it has 0 bytes of data, it has an empty name,\n and it has no metadata.\n\n @param[in] kind The kind of data the object is intended to hold.\n\n @param[out] data A handle to the data object created. Its reference\n count is set to 1.\n\n @retval ::AMD_COMGR_STATUS_SUCCESS The function has\n been executed successfully.\n\n @retval ::AMD_COMGR_STATUS_ERROR_INVALID_ARGUMENT @p\n kind is an invalid data kind, or @p\n AMD_COMGR_DATA_KIND_UNDEF. @p data is NULL.\n\n @retval ::AMD_COMGR_STATUS_ERROR_OUT_OF_RESOURCES\n Unable to create the data object as out of resources."]
pub unsafe fn amd_comgr_create_data(