You can also get GPU/memory activity from the IGCL C++ API.
Download the files igcl_api.h and cApiWrapper.cpp to your source code. Below is a quick-and-dirty minimal example on how to get GPU/VRAM usage, VRAM bandwidth usage, clock speed, temperature and fan speed. For a more detailed example, look here.
string gpu_name; // GPU name
uint gpu_usage; // GPU usage in %
uint gpu_memory, gpu_memory_used, gpu_memory_max; // VRAM usage in % and MB
uint gpu_memory_bandwidth, gpu_memory_bandwidth_used, gpu_memory_bandwidth_max; // in % and MB/s
uint gpu_temp, gpu_fan; // in °C and RPM
uint gpu_clock_core; // GPU core clock in MHz
#include "cApiWrapper.cpp"
ctl_device_adapter_handle_t igcl_device;
uint64_t igcl_timestamp_last_activeTime = 0ull;
uint64_t igcl_timestamp_last_timestamp = 0ull;
uint64_t igcl_read_write_counter = 0ull;
uint64_t igcl_timestamp_last_bandwidth = 0ull;
void initialize_gpu_data() {
ctl_device_adapter_handle_t* igcl_devices = nullptr;
uint igcl_device_number = 0;
ctl_init_args_t init_args;
ctl_api_handle_t api_handle;
init_args.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION);
init_args.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO;
init_args.Size = sizeof(init_args);
init_args.Version = 0;
ZeroMemory(&init_args.ApplicationUID, sizeof(ctl_application_id_t));
do {
ctl_result_t igcl_device_exists = ctlInit(&init_args, &api_handle);
if(igcl_device_exists==CTL_RESULT_SUCCESS) {
igcl_device_exists = ctlEnumerateDevices(api_handle, &igcl_device_number, igcl_devices);
if(igcl_device_exists==CTL_RESULT_SUCCESS) {
igcl_devices = (ctl_device_adapter_handle_t*)malloc(sizeof(ctl_device_adapter_handle_t) * igcl_device_number);
igcl_device_exists = ctlEnumerateDevices(api_handle, &igcl_device_number, igcl_devices);
}
}
} while(igcl_device_number<1u);
igcl_device = igcl_devices[0];
{
ctl_device_adapter_properties_t deviceadapterproperties = { 0 };
deviceadapterproperties.Size = sizeof(ctl_device_adapter_properties_t);
deviceadapterproperties.pDeviceID = malloc(sizeof(LUID));
deviceadapterproperties.device_id_size = sizeof(LUID);
deviceadapterproperties.Version = 2;
ctlGetDeviceProperties(igcl_device, &deviceadapterproperties);
gpu_name = deviceadapterproperties.name;
}
}
void query_gpu_data() {
{
uint engine_count = 0u;
ctlEnumEngineGroups(igcl_device, &engine_count, nullptr);
ctl_engine_handle_t* engines = new ctl_engine_handle_t[engine_count];
ctlEnumEngineGroups(igcl_device, &engine_count, engines);
for(uint i=0u; i<engine_count; i++) {
ctl_engine_properties_t engine_properties = { 0 };
engine_properties.Size = sizeof(ctl_engine_properties_t);
ctlEngineGetProperties(engines[i], &engine_properties);
if(engine_properties.type==CTL_ENGINE_GROUP_RENDER) { // CTL_ENGINE_GROUP_MEDIA
ctl_engine_stats_t engine_stats = { 0 };
engine_stats.Size = sizeof(ctl_engine_stats_t);
ctlEngineGetActivity(engines[i], &engine_stats);
gpu_usage = to_uint(100.0f*(float)(engine_stats.activeTime-igcl_timestamp_last_activeTime)/(float)(engine_stats.timestamp-igcl_timestamp_last_timestamp));
igcl_timestamp_last_activeTime = engine_stats.activeTime;
igcl_timestamp_last_timestamp = engine_stats.timestamp;
}
}
delete[] engines;
} {
uint memory_count = 0u;
ctlEnumMemoryModules(igcl_device, &memory_count, nullptr);
ctl_mem_handle_t* memory_handle = new ctl_mem_handle_t[memory_count];
ctlEnumMemoryModules(igcl_device, &memory_count, memory_handle);
for(uint i=0u; i<min(memory_count, 1u); i++) {
ctl_mem_state_t state = { 0 };
state.Size = sizeof(ctl_mem_state_t);
ctlMemoryGetState(memory_handle[i], &state);
gpu_memory_used = (uint)((state.size-state.free)/1048576ull);
gpu_memory_max = (uint)(state.free/1048576ull);
gpu_memory = to_uint(100.0f*(float)(state.size-state.free)/(float)state.size);
ctl_mem_bandwidth_t bandwidth = { 0 };
bandwidth.Version = 1;
bandwidth.Size = sizeof(ctl_mem_bandwidth_t);
ctlMemoryGetBandwidth(memory_handle[i], &bandwidth);
gpu_memory_bandwidth_used = (uint)(((bandwidth.readCounter+bandwidth.writeCounter-igcl_read_write_counter))/(bandwidth.timestamp-igcl_timestamp_last_bandwidth)); // does not work
gpu_memory_bandwidth_max =(uint)(bandwidth.maxBandwidth/1000000ull);
gpu_memory_bandwidth = to_uint(100.0f*(float)gpu_memory_bandwidth_used/(float)gpu_memory_bandwidth_max);
igcl_read_write_counter = bandwidth.readCounter+bandwidth.writeCounter;
igcl_timestamp_last_bandwidth = bandwidth.timestamp;
}
delete[] memory_handle;
} {
ctl_power_telemetry_t power_telemetry = { 0 };
power_telemetry.Size = sizeof(ctl_power_telemetry_t);
ctlPowerTelemetryGet(igcl_device, &power_telemetry);
gpu_temp = to_uint(power_telemetry.gpuCurrentTemperature.value.datadouble);
gpu_fan = to_uint(power_telemetry.fanSpeed[0].value.datadouble);
gpu_clock_core = to_uint(power_telemetry.gpuCurrentClockFrequency.value.datadouble);
}
}