Regenerate Rust bindings against latest amdsmi.h header

- Regenerate Rust wrapper against latest amdsmi.h header
- Add libc dependency for proper C memory management
- Fix compilation errors caused by types removed from amdsmi.h
- Add FFI bindings regeneration documentation in README

This update ensures the Rust bindings are synchronized with the latest
C API and provides guidance for developers on regenerating
Bindings.

Signed-off-by: Tim Huang <tim.huang@amd.com>


[ROCm/amdsmi commit: 51a44bc0c4]
This commit is contained in:
Tim Huang
2025-08-06 18:03:34 +08:00
committato da Arif, Maisam
parent ed3e242202
commit c3f5771541
5 ha cambiato i file con 948 aggiunte e 168 eliminazioni
+4 -1
Vedi File
@@ -1,6 +1,6 @@
[package]
name = "amdsmi"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
description = "A rust binding for the AMD System Management Interface (AMD-SMI) library"
repository = "https://github.com/ROCm/amdsmi/rust-interface"
@@ -8,6 +8,9 @@ readme = "README.md"
keywords = ["amdsmi", "rust binding"]
license = "Copyright (c) 2019-2024 Advanced Micro Devices, Inc"
[dependencies]
libc = "0.2"
[build-dependencies]
bindgen = "0.70.1"
+22 -3
Vedi File
@@ -8,6 +8,7 @@ This rust crate provides Rust bindings for the AMD System Management Interface (
- [Hello World Example](#hello-world-example)
- [Directory Structure](#directory-structure)
- [Building](#building)
- [Regenerating FFI Bindings](#regenerating-ffi-bindings)
- [Running Tests](#running-tests)
- [Running Examples](#running-examples)
- [Generating Documentation](#generating-documentation)
@@ -140,6 +141,24 @@ cd rust-interface
cargo build
```
### Regenerating FFI Bindings
The `amdsmi_wrapper.rs` file contains automatically generated FFI (Foreign Function Interface) bindings from the AMD SMI C library. **Do not edit this file manually** as any changes will be overwritten during regeneration. Bindings are not automatically regenerated during normal builds unless the `AMDSMI_GENERATE_RUST_WRAPPER` environment variable is explicitly set.
To force regeneration of the bindings, you can:
```sh
# Using CMake
cd build
cmake -DBUILD_RUST_WRAPPER=ON -DREGENERATE_RUST_WRAPPER=ON ..
make
# Or using Cargo with environment variable (recommended)
cd rust-interface
AMDSMI_GENERATE_RUST_WRAPPER=1 cargo build
```
## Running Tests
To run the tests, use the following command:
@@ -158,10 +177,10 @@ To run the examples, use the following command:
cargo run --example example_name
```
Replace `example_name` with the name of the example you want to run. For example, if you have an example named `get_gpu_info`, you can run it as follows:
Replace `example_name` with the name of the example you want to run. For example, if you have an example named `amdsmi_get_gpu_info`, you can run it as follows:
```sh
cargo run --example get_gpu_info
cargo run --example amdsmi_get_gpu_info
```
## Generating Documentation
@@ -179,7 +198,7 @@ This will generate the documentation and open it in your default web browser.
### Adding New API
1. **Update Bindings**:
- Rebuilding this Rust library will automatically generate the bindings using `bindgen` according to the latest `amdsmi.h`.
- To regenerate the bindings using `bindgen` according to the latest `amdsmi.h`, set the `AMDSMI_GENERATE_RUST_WRAPPER` environment variable and rebuild (see [Regenerating FFI Bindings](#regenerating-ffi-bindings)).
2. **Define the API**:
- Add the new API function in the appropriate Rust file, e.g., `src/amdsmi.rs`.
+32 -16
Vedi File
@@ -20,6 +20,7 @@
use crate::amdsmi_wrapper;
use crate::utils::*;
use libc::free;
use std::mem::MaybeUninit;
use std::os::raw::c_void;
use std::ptr::null_mut;
@@ -1982,7 +1983,7 @@ pub fn amdsmi_set_gpu_fan_speed(
/// This function will return the error in [`AmdsmiStatusT`] if the underlying `amdsmi_wrapper::amdsmi_get_gpu_busy_percent` call fails.
pub fn amdsmi_get_gpu_busy_percent(
processor_handle: AmdsmiProcessorHandle
) -> AmdsmiResult<(u32)> {
) -> AmdsmiResult<u32> {
let mut gpu_busy_percent = 0;
call_unsafe!(amdsmi_wrapper::amdsmi_get_gpu_busy_percent(
processor_handle,
@@ -2597,7 +2598,9 @@ pub fn amdsmi_get_gpu_pm_metrics_info(
unsafe { std::slice::from_raw_parts(pm_metrics_ptr, num_of_metrics as usize) };
let pm_metrics = pm_metrics_slice.to_vec();
unsafe { amdsmi_wrapper::amdsmi_free_name_value_pairs(pm_metrics_ptr as *mut c_void) };
if !pm_metrics_ptr.is_null() {
unsafe { free(pm_metrics_ptr as *mut c_void) };
}
Ok(pm_metrics)
}
@@ -2668,7 +2671,9 @@ pub fn amdsmi_get_gpu_reg_table_info(
unsafe { std::slice::from_raw_parts(reg_metrics_ptr, num_of_metrics as usize) };
let reg_metrics = reg_metrics_slice.to_vec();
unsafe { amdsmi_wrapper::amdsmi_free_name_value_pairs(reg_metrics_ptr as *mut c_void) };
if !reg_metrics_ptr.is_null() {
unsafe { free(reg_metrics_ptr as *mut c_void) };
}
Ok(reg_metrics)
}
@@ -2973,18 +2978,29 @@ pub fn amdsmi_set_gpu_od_volt_info(
pub fn amdsmi_get_gpu_od_volt_curve_regions(
processor_handle: AmdsmiProcessorHandle,
) -> AmdsmiResult<Vec<AmdsmiFreqVoltRegionT>> {
let mut num_regions = MaybeUninit::<u32>::uninit();
let buffer_ptr: *mut AmdsmiFreqVoltRegionT = std::ptr::null_mut();
let mut num_regions: u32 = 0;
// First call to get the number of regions
call_unsafe!(amdsmi_wrapper::amdsmi_get_gpu_od_volt_curve_regions(
processor_handle,
num_regions.as_mut_ptr(),
buffer_ptr
&mut num_regions,
null_mut()
));
let num_regions = unsafe { num_regions.assume_init() };
let buffer_slice = unsafe { std::slice::from_raw_parts(buffer_ptr, num_regions as usize) };
let buffer = buffer_slice.to_vec();
if num_regions == 0 {
return Ok(Vec::new());
}
// Allocate buffer and make second call
let mut buffer = Vec::with_capacity(num_regions as usize);
unsafe {
buffer.set_len(num_regions as usize);
}
call_unsafe!(amdsmi_wrapper::amdsmi_get_gpu_od_volt_curve_regions(
processor_handle,
&mut num_regions,
buffer.as_mut_ptr()
));
Ok(buffer)
}
@@ -4628,7 +4644,7 @@ pub fn amdsmi_is_p2p_accessible(
///
/// # Returns
///
/// * `AmdsmiResult<(u64, AmdsmiIoLinkTypeT)>` - Returns a tuple containing the number of hops and the link type if successful, or an error if it fails.
/// * `AmdsmiResult<(u64, AmdsmiLinkTypeT)>` - Returns a tuple containing the number of hops and the link type if successful, or an error if it fails.
///
/// # Example
///
@@ -4660,9 +4676,9 @@ pub fn amdsmi_is_p2p_accessible(
pub fn amdsmi_topo_get_link_type(
processor_handle_src: AmdsmiProcessorHandle,
processor_handle_dst: AmdsmiProcessorHandle,
) -> AmdsmiResult<(u64, AmdsmiIoLinkTypeT)> {
) -> AmdsmiResult<(u64, AmdsmiLinkTypeT)> {
let mut hops: u64 = 0;
let mut link_type: AmdsmiIoLinkTypeT = AmdsmiIoLinkTypeT::AmdsmiIolinkTypeUndefined;
let mut link_type: AmdsmiLinkTypeT = AmdsmiLinkTypeT::AmdsmiLinkTypeUnknown;
call_unsafe!(amdsmi_wrapper::amdsmi_topo_get_link_type(
processor_handle_src,
@@ -4685,7 +4701,7 @@ pub fn amdsmi_topo_get_link_type(
///
/// # Returns
///
/// * `AmdsmiResult<(AmdsmiIoLinkTypeT, AmdsmiP2pCapabilityT)>` - Returns a tuple containing the link type and P2P capability if successful, or an error if it fails.
/// * `AmdsmiResult<(AmdsmiLinkTypeT, AmdsmiP2pCapabilityT)>` - Returns a tuple containing the link type and P2P capability if successful, or an error if it fails.
///
/// # Example
///
@@ -4717,8 +4733,8 @@ pub fn amdsmi_topo_get_link_type(
pub fn amdsmi_topo_get_p2p_status(
processor_handle_src: AmdsmiProcessorHandle,
processor_handle_dst: AmdsmiProcessorHandle,
) -> AmdsmiResult<(AmdsmiIoLinkTypeT, AmdsmiP2pCapabilityT)> {
let mut link_type: AmdsmiIoLinkTypeT = AmdsmiIoLinkTypeT::AmdsmiIolinkTypeUndefined;
) -> AmdsmiResult<(AmdsmiLinkTypeT, AmdsmiP2pCapabilityT)> {
let mut link_type: AmdsmiLinkTypeT = AmdsmiLinkTypeT::AmdsmiLinkTypeUnknown;
let mut p2p_capability = MaybeUninit::<AmdsmiP2pCapabilityT>::uninit();
call_unsafe!(amdsmi_wrapper::amdsmi_topo_get_p2p_status(
File diff soppresso perché troppo grande Carica Diff
@@ -27,8 +27,8 @@ pub use crate::amdsmi_wrapper::{
AmdsmiCachePropertyTypeT, AmdsmiCardFormFactorT, AmdsmiClkLimitTypeT, AmdsmiClkTypeT,
AmdsmiComputePartitionTypeT, AmdsmiCounterCommandT, AmdsmiDevPerfLevelT, AmdsmiEventGroupT,
AmdsmiEventTypeT, AmdsmiEvtNotificationTypeT, AmdsmiFreqIndT, AmdsmiFwBlockT, AmdsmiGpuBlockT,
AmdsmiInitFlagsT, AmdsmiIoLinkTypeT, AmdsmiMemoryPartitionTypeT, AmdsmiMemoryTypeT,
AmdsmiPowerProfilePresetMasksT, AmdsmiPowerTypeT, AmdsmiRasErrStateT, AmdsmiStatusT,
AmdsmiInitFlagsT, AmdsmiLinkTypeT, AmdsmiMemoryPartitionTypeT, AmdsmiMemoryTypeT,
AmdsmiPowerProfilePresetMasksT, AmdsmiRasErrStateT, AmdsmiStatusT,
AmdsmiTemperatureMetricT, AmdsmiTemperatureTypeT, AmdsmiUtilizationCounterTypeT,
AmdsmiVoltageMetricT, AmdsmiVoltageTypeT, AmdsmiXgmiStatusT, ProcessorTypeT, AmdsmiAcceleratorPartitionTypeT
};
@@ -40,7 +40,7 @@ pub use crate::amdsmi_wrapper::{
AmdsmiDriverInfoT, AmdsmiEngineUsageT, AmdsmiErrorCountT, AmdsmiEvtNotificationDataT,
AmdsmiFreqVoltRegionT, AmdsmiFrequenciesT, AmdsmiFrequencyRangeT, AmdsmiFwInfoT,
AmdsmiGpuCacheInfoT, AmdsmiGpuCacheInfoTCache, AmdsmiGpuMetricsT, AmdsmiKfdInfoT,
AmdsmiLinkMetricsT, AmdsmiLinkMetricsTLinks, AmdsmiLinkTypeT, AmdsmiNameValueT,
AmdsmiLinkMetricsT, AmdsmiLinkMetricsTLinks, AmdsmiNameValueT,
AmdsmiOdVoltFreqDataT, AmdsmiP2pCapabilityT, AmdsmiPcieBandwidthT, AmdsmiPcieInfoT,
AmdsmiPcieInfoTPcieMetric, AmdsmiPcieInfoTPcieStatic, AmdsmiPowerCapInfoT, AmdsmiPowerInfoT,
AmdsmiPowerProfileStatusT, AmdsmiProcInfoT, AmdsmiProcInfoTEngineUsage,