| name | library-amd-smi |
| description | AMD SMI C++ library for GPU/CPU/NIC monitoring and management. Use when working with AMD hardware monitoring, GPU temperature, power, memory, clocks, PCIe, XGMI, SDMA (System DMA), AINIC (AI NIC) network interfaces, or any amdsmi.h functions. |
AMD SMI C++ Library
AMD System Management Interface library for monitoring and managing AMD GPUs, CPUs, and AI NICs.
Header and Linking
#include "amd_smi/amdsmi.h"
g++ -I/opt/rocm/include source.cc -L/opt/rocm/lib -lamd_smi -o output
g++ -DENABLE_ESMI_LIB -I/opt/rocm/include source.cc -L/opt/rocm/lib -lamd_smi -o output
export LD_LIBRARY_PATH=/opt/rocm/lib:$LD_LIBRARY_PATH
AMDSMI_FAKE_AINIC=1 ./output
Initialization Pattern
Every AMD SMI application must initialize and shut down properly:
amdsmi_status_t ret;
ret = amdsmi_init(AMDSMI_INIT_AMD_GPUS);
ret = amdsmi_init(AMDSMI_INIT_AMD_CPUS);
ret = amdsmi_init(AMDSMI_INIT_AMD_NICS);
ret = amdsmi_init(AMDSMI_INIT_ALL_PROCESSORS);
ret = amdsmi_shut_down();
Core Concepts
Handles Hierarchy
Socket → Processor (GPU/CPU/NIC) → Core (for CPUs)
- Socket handle: Physical hardware socket
- Processor handle: GPU, CPU, or NIC within a socket (may change between app restarts)
- Device handles are NOT persistent across processes
Getting Handles
uint32_t socket_count = 0;
amdsmi_get_socket_handles(&socket_count, nullptr);
std::vector<amdsmi_socket_handle> sockets(socket_count);
amdsmi_get_socket_handles(&socket_count, sockets.data());
uint32_t device_count = 0;
amdsmi_get_processor_handles(sockets[0], &device_count, nullptr);
std::vector<amdsmi_processor_handle> processors(device_count);
amdsmi_get_processor_handles(sockets[0], &device_count, processors.data());
processor_type_t type = AMDSMI_PROCESSOR_TYPE_AMD_GPU;
amdsmi_get_processor_handles_by_type(socket, type, nullptr, &count);
Processor Handle Functions Comparison
| Function | Returns | Use Case |
|---|
amdsmi_get_processor_handles() | GPUs only | Legacy GPU-only code |
amdsmi_get_processor_handles_by_type() | GPUs, NICs, CPUs, APUs | Recommended - supports all processor types |
CRITICAL: amdsmi_get_processor_handles() only returns GPU processors. It will NOT return NICs, CPUs, or other processor types even if they exist in the system. For NICs, CPUs, or mixed workloads, you MUST use amdsmi_get_processor_handles_by_type() with the appropriate processor type constant.
auto handles = amdsmi_get_processor_handles(socket, &count, nullptr);
amdsmi_get_processor_handles_by_type(socket, AMDSMI_PROCESSOR_TYPE_AMD_NIC, nullptr, &count);
amdsmi_get_processor_handles_by_type(socket, AMDSMI_PROCESSOR_TYPE_AMD_GPU, nullptr, &count);
Processor Types
AMDSMI_PROCESSOR_TYPE_AMD_GPU - AMD GPU
AMDSMI_PROCESSOR_TYPE_AMD_CPU - AMD CPU
AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE - CPU core
AMDSMI_PROCESSOR_TYPE_AMD_APU - AMD APU
AMDSMI_PROCESSOR_TYPE_AMD_NIC - AI Network Interface Card
Common GPU Queries
Temperature
int64_t temp;
amdsmi_get_temp_metric(processor, AMDSMI_TEMPERATURE_TYPE_EDGE,
AMDSMI_TEMP_CURRENT, &temp);
Power
amdsmi_power_info_t power_info;
amdsmi_get_power_info(processor, &power_info);
amdsmi_power_cap_info_t cap_info;
amdsmi_get_power_cap_info(processor, 0, &cap_info);
Memory
uint64_t total;
amdsmi_get_gpu_memory_total(processor, AMDSMI_MEM_TYPE_VRAM, &total);
uint64_t used;
amdsmi_get_gpu_memory_usage(processor, AMDSMI_MEM_TYPE_VRAM, &used);
Clocks
amdsmi_clk_info_t clk_info;
amdsmi_get_clock_info(processor, AMDSMI_CLK_TYPE_GFX, &clk_info);
GPU Activity/Utilization
amdsmi_engine_usage_t usage;
amdsmi_get_gpu_activity(processor, &usage);
uint32_t busy_percent;
amdsmi_get_gpu_busy_percent(processor, &busy_percent);
Process List with Resource Usage
uint32_t num_processes = 0;
amdsmi_get_gpu_process_list(processor, &num_processes, nullptr);
std::vector<amdsmi_proc_info_t> proc_list(num_processes);
amdsmi_get_gpu_process_list(processor, &num_processes, proc_list.data());
for (const auto& proc : proc_list) {
std::cout << "PID: " << proc.pid << " Name: " << proc.name << std::endl;
std::cout << " Memory: " << proc.mem / 1024 << " KB" << std::endl;
std::cout << " GTT: " << proc.memory_usage.gtt_mem / 1024 << " KB" << std::endl;
std::cout << " VRAM: " << proc.memory_usage.vram_mem / 1024 << " KB" << std::endl;
std::cout << " CPU: " << proc.memory_usage.cpu_mem / 1024 << " KB" << std::endl;
std::cout << " GFX engine: " << proc.engine_usage.gfx << " ns" << std::endl;
std::cout << " ENC engine: " << proc.engine_usage.enc << " ns" << std::endl;
std::cout << " SDMA usage: " << proc.sdma_usage << " us" << std::endl;
std::cout << " CU occupancy: " << proc.cu_occupancy << std::endl;
std::cout << " Evicted time: " << proc.evicted_time << " ms" << std::endl;
}
amdsmi_proc_info_t Structure
typedef struct {
uint32_t pid;
char name[AMDSMI_MAX_STRING_LENGTH];
uint64_t mem;
struct {
uint64_t gtt_mem;
uint64_t cpu_mem;
uint64_t vram_mem;
} memory_usage;
struct {
uint64_t gfx;
uint64_t enc;
} engine_usage;
char container_name[AMDSMI_MAX_STRING_LENGTH];
uint32_t cu_occupancy;
uint32_t evicted_time;
uint64_t sdma_usage;
} amdsmi_proc_info_t;
Device Info
amdsmi_board_info_t board_info;
amdsmi_get_gpu_board_info(processor, &board_info);
amdsmi_asic_info_t asic_info;
amdsmi_get_gpu_asic_info(processor, &asic_info);
amdsmi_vram_info_t vram_info;
amdsmi_get_gpu_vram_info(processor, &vram_info);
char uuid[AMDSMI_GPU_UUID_SIZE];
amdsmi_get_gpu_device_uuid(processor, nullptr, uuid);
amdsmi_bdf_t bdf;
amdsmi_get_gpu_device_bdf(processor, &bdf);
PCIe Info
amdsmi_pcie_info_t pcie_info;
amdsmi_get_pcie_info(processor, &pcie_info);
uint64_t sent, received, max_pkt_sz;
amdsmi_get_gpu_pci_throughput(processor, &sent, &received, &max_pkt_sz);
Fan Speed
int64_t speed;
amdsmi_get_gpu_fan_speed(processor, 0, &speed);
int64_t max_speed;
amdsmi_get_gpu_fan_speed_max(processor, 0, &max_speed);
int64_t rpm;
amdsmi_get_gpu_fan_rpms(processor, 0, &rpm);
Firmware Info
amdsmi_fw_info_t fw_info;
amdsmi_get_fw_info(processor, &fw_info);
Common CPU Queries
uint32_t power;
amdsmi_get_cpu_socket_power(processor, &power);
uint32_t temp;
amdsmi_get_cpu_socket_temperature(processor, &temp);
uint64_t energy;
amdsmi_get_cpu_socket_energy(processor, &energy);
uint32_t boost;
amdsmi_get_cpu_core_boostlimit(core_processor, &boost);
AI NIC (Network Interface Card) Functions
Build Requirements for NIC Support
g++ -DENABLE_ESMI_LIB -I/opt/rocm/include source.cc -L/opt/rocm/lib -lamd_smi -o output
AMDSMI_FAKE_AINIC=1 ./output
NIC Discovery
IMPORTANT: amdsmi_get_processor_handles() does NOT return NIC processors. You MUST use amdsmi_get_processor_handles_by_type() with AMDSMI_PROCESSOR_TYPE_AMD_NIC.
amdsmi_init(AMDSMI_INIT_AMD_NICS);
uint32_t socket_count = 0;
amdsmi_get_socket_handles(&socket_count, nullptr);
std::vector<amdsmi_socket_handle> sockets(socket_count);
amdsmi_get_socket_handles(&socket_count, sockets.data());
uint32_t nic_count = 0;
amdsmi_get_processor_handles_by_type(sockets[0],
AMDSMI_PROCESSOR_TYPE_AMD_NIC,
nullptr, &nic_count);
std::vector<amdsmi_processor_handle> nics(nic_count);
amdsmi_get_processor_handles_by_type(sockets[0],
AMDSMI_PROCESSOR_TYPE_AMD_NIC,
nics.data(), &nic_count);
NIC Data Structures