AMD System Management Interface (AMD SMI) Go library for unified GPU and CPU management and monitoring
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Core system initialization, device enumeration, and handle management for AMD processors. These functions must be called before using any other AMD SMI functionality.
Initialize the AMD SMI library and specify which processor types to manage.
amdsmi_status_t amdsmi_init(uint64_t init_flags);Parameters:
init_flags: Bitwise combination of initialization flagsInitialization Flags:
typedef enum {
AMDSMI_INIT_ALL_PROCESSORS = 0xFFFFFFFF,
AMDSMI_INIT_AMD_CPUS = (1 << 0),
AMDSMI_INIT_AMD_GPUS = (1 << 1),
AMDSMI_INIT_NON_AMD_CPUS = (1 << 2),
AMDSMI_INIT_NON_AMD_GPUS = (1 << 3),
AMDSMI_INIT_AMD_APUS = (AMDSMI_INIT_AMD_CPUS | AMDSMI_INIT_AMD_GPUS)
} amdsmi_init_flags_t;Usage Example:
// Initialize for AMD GPUs only
amdsmi_status_t status = amdsmi_init(AMDSMI_INIT_AMD_GPUS);
if (status != AMDSMI_STATUS_SUCCESS) {
// Handle initialization failure
}
// Initialize for both AMD CPUs and GPUs
status = amdsmi_init(AMDSMI_INIT_AMD_APUS);Clean up resources and shut down the AMD SMI library.
amdsmi_status_t amdsmi_shut_down(void);Returns: Status code indicating success or failure
Usage Example:
// Always call shutdown to clean up resources
amdsmi_shut_down();Get handles to available processors for subsequent API calls.
amdsmi_status_t amdsmi_get_processor_handles(amdsmi_processor_type_t processor_type,
amdsmi_processor_handle* processor_handles,
uint32_t* num_devices);Parameters:
processor_type: Type of processors to enumerateprocessor_handles: Array to store processor handles (can be NULL to query count)num_devices: Input: array size, Output: actual number of devicesProcessor Types:
typedef enum {
AMDSMI_PROCESSOR_TYPE_AMD_GPU,
AMDSMI_PROCESSOR_TYPE_AMD_CPU,
AMDSMI_PROCESSOR_TYPE_NON_AMD_GPU,
AMDSMI_PROCESSOR_TYPE_NON_AMD_CPU
} amdsmi_processor_type_t;Usage Example:
// First, get the number of AMD GPUs
uint32_t num_gpus = 0;
amdsmi_status_t status = amdsmi_get_processor_handles(AMDSMI_PROCESSOR_TYPE_AMD_GPU,
nullptr, &num_gpus);
if (status == AMDSMI_STATUS_SUCCESS && num_gpus > 0) {
// Allocate array for handles
std::vector<amdsmi_processor_handle> gpu_handles(num_gpus);
// Get the actual handles
status = amdsmi_get_processor_handles(AMDSMI_PROCESSOR_TYPE_AMD_GPU,
gpu_handles.data(), &num_gpus);
// Use the handles for subsequent API calls
for (const auto& handle : gpu_handles) {
// Perform operations on each GPU
}
}Determine the type of a given processor handle.
amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle,
amdsmi_processor_type_t* processor_type);Parameters:
processor_handle: Handle to queryprocessor_type: Output pointer to store processor typeUsage Example:
amdsmi_processor_type_t type;
amdsmi_status_t status = amdsmi_get_processor_type(processor_handle, &type);
if (status == AMDSMI_STATUS_SUCCESS) {
switch (type) {
case AMDSMI_PROCESSOR_TYPE_AMD_GPU:
// Handle AMD GPU specific operations
break;
case AMDSMI_PROCESSOR_TYPE_AMD_CPU:
// Handle AMD CPU specific operations
break;
default:
// Handle other processor types
break;
}
}Get socket-level handles for CPU management.
amdsmi_status_t amdsmi_get_socket_handles(uint32_t* num_sockets,
amdsmi_socket_handle* socket_handles);Parameters:
num_sockets: Input: array size, Output: actual number of socketssocket_handles: Array to store socket handles (can be NULL to query count)amdsmi_status_t amdsmi_get_socket_info(amdsmi_socket_handle socket_handle,
amdsmi_socket_info_t* socket_info);Socket Information Structure:
typedef struct {
uint32_t socket_id;
uint32_t num_cpu_cores;
uint32_t num_gpus;
} amdsmi_socket_info_t;import amdsmi
# Initialize library
amdsmi.amdsmi_init(amdsmi.AmdSmiInitFlag.AMD_GPUS)
# Get GPU handles
gpu_handles = amdsmi.amdsmi_get_processor_handles(amdsmi.AmdSmiProcessorType.AMD_GPU)
print(f"Found {len(gpu_handles)} AMD GPU(s)")
# Get socket handles for CPU management
socket_handles = amdsmi.amdsmi_get_socket_handles()
print(f"Found {len(socket_handles)} CPU socket(s)")
# Cleanup
amdsmi.amdsmi_shut_down()The Go interface provides direct initialization functions for GPU and CPU monitoring:
func GO_gpu_init() bool
func GO_gpu_shutdown() bool
func GO_gpu_num_monitor_devices() uint
func GO_cpu_init() bool
func GO_cpu_number_of_sockets_get() uint
func GO_cpu_number_of_threads_get() uint
func GO_cpu_threads_per_core_get() uintUsage Example:
package main
import (
"fmt"
"log"
)
func main() {
// Initialize for GPU monitoring
if !goamdsmi.GO_gpu_init() {
log.Fatal("Failed to initialize AMD SMI for GPUs")
}
defer func() {
if !goamdsmi.GO_gpu_shutdown() {
log.Println("Warning: Failed to shutdown GPU monitoring")
}
}()
// Get number of monitor devices
numGPUs := goamdsmi.GO_gpu_num_monitor_devices()
fmt.Printf("Found %d GPU(s) available for monitoring\n", numGPUs)
// Initialize CPU monitoring separately if needed
if goamdsmi.GO_cpu_init() {
numSockets := goamdsmi.GO_cpu_number_of_sockets_get()
numThreads := goamdsmi.GO_cpu_number_of_threads_get()
threadsPerCore := goamdsmi.GO_cpu_threads_per_core_get()
fmt.Printf("CPU Info: %d sockets, %d threads, %d threads per core\n",
numSockets, numThreads, threadsPerCore)
}
}use amdsmi::{init, shut_down, get_processor_handles, ProcessorType, InitFlag};
// Initialize library
init(InitFlag::AMD_GPUS)?;
// Get GPU handles
let gpu_handles = get_processor_handles(ProcessorType::AmdGpu)?;
println!("Found {} GPU(s)", gpu_handles.len());
// Cleanup
shut_down();All initialization functions return status codes that should be checked:
typedef enum {
AMDSMI_STATUS_SUCCESS = 0,
AMDSMI_STATUS_INVAL,
AMDSMI_STATUS_NOT_SUPPORTED,
AMDSMI_STATUS_FILE_ERROR,
AMDSMI_STATUS_PERMISSION,
AMDSMI_STATUS_OUT_OF_RESOURCES,
AMDSMI_STATUS_INTERNAL_EXCEPTION,
AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS,
AMDSMI_STATUS_INIT_ERROR,
AMDSMI_STATUS_NOT_YET_IMPLEMENTED,
AMDSMI_STATUS_NOT_FOUND,
AMDSMI_STATUS_INSUFFICIENT_SIZE,
AMDSMI_STATUS_INTERRUPT,
AMDSMI_STATUS_UNEXPECTED_SIZE,
AMDSMI_STATUS_NO_DATA,
AMDSMI_STATUS_UNEXPECTED_DATA,
AMDSMI_STATUS_BUSY,
AMDSMI_STATUS_REFCOUNT_OVERFLOW,
AMDSMI_STATUS_UNKNOWN_ERROR
} amdsmi_status_t;Common Error Conditions:
AMDSMI_STATUS_INIT_ERROR: Library not initialized or initialization failedAMDSMI_STATUS_PERMISSION: Insufficient permissions (especially for control operations)AMDSMI_STATUS_NOT_SUPPORTED: Feature not supported on current hardwareAMDSMI_STATUS_FILE_ERROR: Driver files not accessibleInstall with Tessl CLI
npx tessl i tessl/go-amdsmi