static NVML() { if (instance == null) { instance = new NVML(); } }
public override string GetReport() { StringBuilder r = new StringBuilder(); r.AppendLine("Nvidia GPU"); r.AppendLine(); r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); NVML.NvmlDeviceGetIndex(handle, out uint index); r.AppendFormat("Index: {0}{1}", index, Environment.NewLine); if (NVML.GetDriverVersionString(out string drvVer) == NvmlReturn.SUCCESS) { r.AppendLine("Driver Version: " + drvVer); } r.AppendLine(); NvmlPciInfo pciInfo = new NvmlPciInfo(); if (NVML.NvmlDeviceGetPciInfo(handle, ref pciInfo) == NvmlReturn.SUCCESS) { r.AppendLine("PCIBus: " + pciInfo.busId); r.Append("PCIBusId: 0x"); r.AppendLine(pciInfo.bus.ToString("X", CultureInfo.InvariantCulture)); r.Append("PCISubSystemID: 0x"); r.AppendLine(pciInfo.pciSubSystemId.ToString("X", CultureInfo.InvariantCulture)); r.Append("DeviceID: 0x"); r.AppendLine(pciInfo.pciDeviceId.ToString("X", CultureInfo.InvariantCulture)); r.AppendLine(); } if (NVML.NvmlDeviceGetCurrPcieLinkGeneration(handle, out uint linkGen) == NvmlReturn.SUCCESS) { r.AppendLine("PCIE Generation: " + linkGen); } if (NVML.NvmlDeviceGetCurrPcieLinkWidth(handle, out uint linkWidth) == NvmlReturn.SUCCESS) { r.AppendLine("PCIE Width: x" + linkWidth); } r.AppendLine(); if (NVML.GetDeviceUUID(handle, out string uuid) == NvmlReturn.SUCCESS) { r.AppendLine("Device UUID: " + uuid); } if (NVML.GetDeviceVbiosVersionString(handle, out string vbios) == NvmlReturn.SUCCESS) { r.AppendLine("VBIOS Version: " + vbios); } r.AppendLine(); r.AppendLine(); return(r.ToString()); }
public NvidiaGPU(uint deviceIndex, ISettings settings) : base(GetName(deviceIndex), new Identifier("nvidiagpu", deviceIndex.ToString(CultureInfo.InvariantCulture)), settings) { if (NVML.NvmlDeviceGetHandleByIndex(deviceIndex, ref handle) != NvmlReturn.SUCCESS) { return; } clocks = new Sensor[3]; clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings); clocks[1] = new Sensor("GPU Memory", 2, SensorType.Clock, this, settings); clocks[2] = new Sensor("GPU Shader", 3, SensorType.Clock, this, settings); foreach (var clock in clocks) { ActivateSensor(clock); } thermal = new Sensor("GPU Core", 0, SensorType.Temperature, this, settings); ActivateSensor(thermal); // Shows % instead of RPM //fan = new Sensor("GPU Fan", 0, SensorType.Fan, this, settings); fan = new Sensor("GPU Fan", 0, SensorType.Level, this, settings); ActivateSensor(fan); powers = new Sensor[2]; powers[0] = new Sensor("GPU Power", 0, SensorType.Power, this, settings); powers[1] = new Sensor("GPU TDP", 1, SensorType.Level, this, settings); foreach (var power in powers) { ActivateSensor(power); } loads = new Sensor[3]; loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings); loads[1] = new Sensor("GPU Memory Controller", 1, SensorType.Load, this, settings); loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings); foreach (var load in loads) { ActivateSensor(load); } memory = new Sensor[4]; memory[0] = new Sensor("GPU Memory", 3, SensorType.Load, this, settings); memory[1] = new Sensor("GPU Memory Total", 0, SensorType.SmallData, this, settings); memory[2] = new Sensor("GPU Memory Used", 1, SensorType.SmallData, this, settings); memory[3] = new Sensor("GPU Memory Free", 2, SensorType.SmallData, this, settings); foreach (var mem in memory) { ActivateSensor(mem); } }
public void Close() { foreach (Hardware gpu in hardware) { gpu.Close(); } if (NVML.IsInitialized) { NVML.NvmlShutdown(); } }
public NvidiaNVMLGPU(int adapterIndex, NvPhysicalGpuHandle handle, NvDisplayHandle?displayHandle, ISettings settings, NVML nvml) : base(adapterIndex, handle, displayHandle, settings) { if (nvml == null) { throw new ArgumentNullException(nameof(nvml)); } this.nvml = nvml; if (nvml.Initialised) { device = nvml.NvmlDeviceGetHandleByIndex(adapterIndex); if (device.HasValue) { powerUsage = new Sensor("GPU Package", 0, SensorType.Power, this, settings); } } }
public override void Update() { foreach (var clock in clocks) { NVML.NvmlDeviceGetClockInfo(handle, (NvmlClockType)clock.Index, out uint clockMhz); clock.Value = clockMhz; } NVML.NvmlDeviceGetTemperature(handle, NvmlTemperatureSensors.GPU, out uint temp); thermal.Value = temp; NVML.NvmlDeviceGetFanSpeed(handle, out uint fanSpeed); fan.Value = fanSpeed; NVML.NvmlDeviceGetPowerUsage(handle, out uint powerUsage); powers[0].Value = powerUsage / 1000.0f; NVML.NvmlDeviceGetPowerManagementDefaultLimit(handle, out uint tdp); powers[1].Value = powerUsage * 100.0f / tdp; NvmlUtilization util = new NvmlUtilization(); NVML.NvmlDeviceGetUtilizationRates(handle, ref util); loads[0].Value = util.gpu; loads[1].Value = util.memory; NVML.NvmlDeviceGetDecoderUtilization(handle, out uint videoUtil, out uint vidSamPer); loads[2].Value = videoUtil; NvmlMemory memInfo = new NvmlMemory(); NVML.NvmlDeviceGetMemoryInfo(handle, ref memInfo); memory[0].Value = 100.0f * memInfo.used / memInfo.total; memory[1].Value = (float)(memInfo.total / byteConv); memory[2].Value = (float)(memInfo.used / byteConv); memory[3].Value = (float)(memInfo.free / byteConv); }
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle, NvDisplayHandle?displayHandle, ISettings settings) : base(GetName(handle), new Identifier("nvidiagpu", adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) { this.adapterIndex = adapterIndex; this.handle = handle; this.displayHandle = displayHandle; NvGPUThermalSettings thermalSettings = GetThermalSettings(); temperatures = new Sensor[thermalSettings.Count]; for (int i = 0; i < temperatures.Length; i++) { NvSensor sensor = thermalSettings.Sensor[i]; string name; switch (sensor.Target) { case NvThermalTarget.BOARD: name = "GPU Board"; break; case NvThermalTarget.GPU: name = "GPU Core"; break; case NvThermalTarget.MEMORY: name = "GPU Memory"; break; case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break; case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break; default: name = "GPU"; break; } temperatures[i] = new Sensor(name, i, SensorType.Temperature, this, new ParameterDescription[0], settings); ActivateSensor(temperatures[i]); } fan = new Sensor("GPU", 0, SensorType.Fan, this, settings); clocks = new Sensor[3]; clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings); clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings); clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this, settings); for (int i = 0; i < clocks.Length; i++) { ActivateSensor(clocks[i]); } loads = new Sensor[4]; loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings); loads[1] = new Sensor("GPU Frame Buffer", 1, SensorType.Load, this, settings); loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings); loads[3] = new Sensor("GPU Bus Interface", 3, SensorType.Load, this, settings); memoryLoad = new Sensor("GPU Memory", 4, SensorType.Load, this, settings); memoryFree = new Sensor("GPU Memory Free", 1, SensorType.SmallData, this, settings); memoryUsed = new Sensor("GPU Memory Used", 2, SensorType.SmallData, this, settings); memoryAvail = new Sensor("GPU Memory Total", 3, SensorType.SmallData, this, settings); control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings); NvGPUCoolerSettings coolerSettings = GetCoolerSettings(); if (coolerSettings.Count > 0) { fanControl = new Control(control, settings, coolerSettings.Cooler[0].DefaultMin, coolerSettings.Cooler[0].DefaultMax); fanControl.ControlModeChanged += ControlModeChanged; fanControl.SoftwareControlValueChanged += SoftwareControlValueChanged; ControlModeChanged(fanControl); control.Control = fanControl; } if (NVML.IsInitialized) { if (NVAPI.NvAPI_GPU_GetBusId != null && NVAPI.NvAPI_GPU_GetBusId(handle, out uint busId) == NvStatus.OK) { if (NVML.NvmlDeviceGetHandleByPciBusId != null && NVML.NvmlDeviceGetHandleByPciBusId( "0000:" + busId.ToString("X2") + ":00.0", out var result) == NVML.NvmlReturn.Success) { device = result; power = new Sensor("GPU Power", 0, SensorType.Power, this, settings); pcieThroughputRx = new Sensor("GPU PCIE Rx", 0, SensorType.Throughput, this, settings); pcieThroughputTx = new Sensor("GPU PCIE Tx", 1, SensorType.Throughput, this, settings); } } } Update(); }
public override void Update() { NvGPUThermalSettings settings = GetThermalSettings(); foreach (Sensor sensor in temperatures) { sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; } bool tachReadingOk = false; if (NVAPI.NvAPI_GPU_GetTachReading != null && NVAPI.NvAPI_GPU_GetTachReading(handle, out int fanValue) == NvStatus.OK) { fan.Value = fanValue; ActivateSensor(fan); tachReadingOk = true; } uint[] values = GetClocks(); if (values != null) { clocks[1].Value = 0.001f * values[8]; if (values[30] != 0) { clocks[0].Value = 0.0005f * values[30]; clocks[2].Value = 0.001f * values[30]; } else { clocks[0].Value = 0.001f * values[0]; clocks[2].Value = 0.001f * values[14]; } } var infoEx = new NvDynamicPstatesInfoEx(); infoEx.Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_EX_VER; infoEx.UtilizationDomains = new NvUtilizationDomainEx[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS]; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx(handle, ref infoEx) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (infoEx.UtilizationDomains[i].Present) { loads[i].Value = infoEx.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } else { var info = new NvDynamicPstatesInfo(); info.Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_VER; info.UtilizationDomains = new NvUtilizationDomain[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS]; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfo != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfo(handle, ref info) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (info.UtilizationDomains[i].Present) { loads[i].Value = info.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } } var coolerSettings = GetCoolerSettings(); var coolerSettingsOk = false; if (coolerSettings.Count > 0) { control.Value = coolerSettings.Cooler[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk || !coolerSettingsOk) { var coolersStatus = GetFanCoolersStatus(); if (coolersStatus.Count > 0) { if (!coolerSettingsOk) { control.Value = coolersStatus.Items[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk) { fan.Value = coolersStatus.Items[0].CurrentRpm; ActivateSensor(fan); tachReadingOk = true; } } } NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo(); memoryInfo.Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER; memoryInfo.Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU]; if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null && displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverMemoryInfo(displayHandle.Value, ref memoryInfo) == NvStatus.OK) { uint totalMemory = memoryInfo.Values[0]; uint freeMemory = memoryInfo.Values[4]; float usedMemory = Math.Max(totalMemory - freeMemory, 0); memoryFree.Value = freeMemory / 1024; memoryAvail.Value = totalMemory / 1024; memoryUsed.Value = usedMemory / 1024; memoryLoad.Value = 100f * usedMemory / totalMemory; ActivateSensor(memoryAvail); ActivateSensor(memoryUsed); ActivateSensor(memoryFree); ActivateSensor(memoryLoad); } if (power != null) { if (NVML.NvmlDeviceGetPowerUsage(device.Value, out int powerValue) == NVML.NvmlReturn.Success) { power.Value = powerValue * 0.001f; ActivateSensor(power); } } if (pcieThroughputRx != null) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.RxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputRx.Value = value * (1.0f / 0x400); ActivateSensor(pcieThroughputRx); } } if (pcieThroughputTx != null) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.TxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputTx.Value = value * (1.0f / 0x400); ActivateSensor(pcieThroughputTx); } } }
private static string GetName(uint deviceIndex) { NVML.GetDeviceName(deviceIndex, out string name); return(name); }
public override void Close() { NVML.Close(); base.Close(); }
public NvidiaGroup(ISettings settings) { if (!NVAPI.IsAvailable) { return; } report.AppendLine("NVAPI"); report.AppendLine(); string version; if (NVAPI.NvAPI_GetInterfaceVersionString(out version) == NvStatus.OK) { report.Append(" Version: "); report.AppendLine(version); } NvPhysicalGpuHandle[] handles = new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS]; int count; if (NVAPI.NvAPI_EnumPhysicalGPUs == null) { report.AppendLine(" Error: NvAPI_EnumPhysicalGPUs not available"); report.AppendLine(); return; } else { NvStatus status = NVAPI.NvAPI_EnumPhysicalGPUs(handles, out count); if (status != NvStatus.OK) { report.AppendLine(" Status: " + status); report.AppendLine(); return; } } var result = NVML.NvmlInit(); report.AppendLine(); report.AppendLine("NVML"); report.AppendLine(); report.AppendLine(" Status: " + result); report.AppendLine(); IDictionary <NvPhysicalGpuHandle, NvDisplayHandle> displayHandles = new Dictionary <NvPhysicalGpuHandle, NvDisplayHandle>(); if (NVAPI.NvAPI_EnumNvidiaDisplayHandle != null && NVAPI.NvAPI_GetPhysicalGPUsFromDisplay != null) { NvStatus status = NvStatus.OK; int i = 0; while (status == NvStatus.OK) { NvDisplayHandle displayHandle = new NvDisplayHandle(); status = NVAPI.NvAPI_EnumNvidiaDisplayHandle(i, ref displayHandle); i++; if (status == NvStatus.OK) { NvPhysicalGpuHandle[] handlesFromDisplay = new NvPhysicalGpuHandle[NVAPI.MAX_PHYSICAL_GPUS]; uint countFromDisplay; if (NVAPI.NvAPI_GetPhysicalGPUsFromDisplay(displayHandle, handlesFromDisplay, out countFromDisplay) == NvStatus.OK) { for (int j = 0; j < countFromDisplay; j++) { if (!displayHandles.ContainsKey(handlesFromDisplay[j])) { displayHandles.Add(handlesFromDisplay[j], displayHandle); } } } } } } report.Append("Number of GPUs: "); report.AppendLine(count.ToString(CultureInfo.InvariantCulture)); for (int i = 0; i < count; i++) { NvDisplayHandle displayHandle; displayHandles.TryGetValue(handles[i], out displayHandle); hardware.Add(new NvidiaGPU(i, handles[i], displayHandle, settings)); } report.AppendLine(); }
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle, NvDisplayHandle?displayHandle, ISettings settings, PhysicalGPU physicalGPU = null) : base(GetName(handle), new Identifier("nvidiagpu", adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) { this.adapterIndex = adapterIndex; this.handle = handle; this.displayHandle = displayHandle; this.physicalGPU = physicalGPU; NvGPUThermalSettings thermalSettings = GetThermalSettings(); temperatures = new Sensor[thermalSettings.Count]; for (int i = 0; i < temperatures.Length; i++) { NvSensor sensor = thermalSettings.Sensor[i]; string name; switch (sensor.Target) { case NvThermalTarget.BOARD: name = "GPU Board"; break; case NvThermalTarget.GPU: name = "GPU Core"; break; case NvThermalTarget.MEMORY: name = "GPU Memory"; break; case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break; case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break; default: name = "GPU"; break; } temperatures[i] = new Sensor(name, i, SensorType.Temperature, this, new ParameterDescription[0], settings); ActivateSensor(temperatures[i]); } clocks = new Sensor[3]; clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings); clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings); clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this, settings); for (int i = 0; i < clocks.Length; i++) { ActivateSensor(clocks[i]); } loads = new Sensor[4]; loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings); loads[1] = new Sensor("GPU Frame Buffer", 1, SensorType.Load, this, settings); loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings); loads[3] = new Sensor("GPU Bus Interface", 3, SensorType.Load, this, settings); memoryLoad = new Sensor("GPU Memory", 4, SensorType.Load, this, settings); memoryFree = new Sensor("GPU Memory Free", 1, SensorType.SmallData, this, settings); memoryUsed = new Sensor("GPU Memory Used", 2, SensorType.SmallData, this, settings); memoryAvail = new Sensor("GPU Memory Total", 3, SensorType.SmallData, this, settings); memoryUsageDedicated = new Sensor("GPU Memory Dedicated", 4, SensorType.SmallData, this, settings); memoryUsageShared = new Sensor("GPU Memory Shared", 5, SensorType.SmallData, this, settings); fan = new Sensor("GPU Fan", 0, SensorType.Fan, this, settings); control = new Sensor("GPU Fan", 1, SensorType.Control, this, settings); voltage = new Sensor("GPU Voltage", 0, SensorType.Voltage, this, settings); powerLimit = new Sensor("GPU Power Limit", 0, SensorType.Factor, this, settings); temperatureLimit = new Sensor("GPU Thermal Limit", 1, SensorType.Factor, this, settings); voltageLimit = new Sensor("GPU Voltage Limit", 2, SensorType.Factor, this, settings); power = new Sensor("GPU Power", 0, SensorType.Power, this, settings); NvGPUCoolerSettings coolerSettings = GetCoolerSettings(); if (coolerSettings.Count > 0) { fanControl = new Control(control, settings, coolerSettings.Cooler[0].DefaultMin, coolerSettings.Cooler[0].DefaultMax); fanControl.ControlModeChanged += ControlModeChanged; fanControl.SoftwareControlValueChanged += SoftwareControlValueChanged; ControlModeChanged(fanControl); control.Control = fanControl; } try { if (PerformanceCounterCategory.Exists("GPU Adapter Memory")) { var category = new PerformanceCounterCategory("GPU Adapter Memory"); var instances = category.GetInstanceNames(); if (instances.Any()) { long maxRawValue = 0; int maxIndex = 0; for (int i = 0; i < instances.Length; i++) { try { var currentPerfCounter = new PerformanceCounter("GPU Adapter Memory", "Dedicated Usage", instances[i]); if (currentPerfCounter.RawValue > maxRawValue) { maxRawValue = currentPerfCounter.RawValue; maxIndex = i; } } catch (Exception ex) { Log.Logger.Error(ex, $"Error while creating performance counter with instance {i}."); } } dedicatedVramUsagePerformCounter = new PerformanceCounter("GPU Adapter Memory", "Dedicated Usage", instances[maxIndex]); sharedVramUsagePerformCounter = new PerformanceCounter("GPU Adapter Memory", "Shared Usage", instances[maxIndex]); } } } catch (Exception ex) { Log.Logger.Error(ex, "Error while creating GPU memory performance counter."); } if (NVML.IsInitialized) { if (NVAPI.NvAPI_GPU_GetBusId != null && NVAPI.NvAPI_GPU_GetBusId(handle, out uint busId) == NvStatus.OK) { if (NVML.NvmlDeviceGetHandleByPciBusId != null && NVML.NvmlDeviceGetHandleByPciBusId( "0000:" + busId.ToString("X2") + ":00.0", out var result) == NVML.NvmlReturn.Success) { device = result; pcieThroughputRx = new Sensor("GPU PCIE Rx", 0, SensorType.Throughput, this, settings); pcieThroughputTx = new Sensor("GPU PCIE Tx", 1, SensorType.Throughput, this, settings); } } } Update(); }
public override void Update() { NvGPUThermalSettings settings = GetThermalSettings(); foreach (Sensor sensor in temperatures) { sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; } bool tachReadingOk = false; if (NVAPI.NvAPI_GPU_GetTachReading != null && NVAPI.NvAPI_GPU_GetTachReading(handle, out int fanValue) == NvStatus.OK) { fan.Value = fanValue; ActivateSensor(fan); tachReadingOk = true; } uint[] values = GetClocks(); if (values != null) { clocks[1].Value = 0.001f * values[8]; if (values[30] != 0) { clocks[0].Value = 0.0005f * values[30]; clocks[2].Value = 0.001f * values[30]; } else { clocks[0].Value = 0.001f * values[0]; clocks[2].Value = 0.001f * values[14]; } } // set extra sensors from external NvAPI wrapper if (physicalGPU != null) { try { voltage.Value = GPUApi.GetCurrentVoltage(physicalGPU.Handle).ValueInMicroVolt / 1E06f; ActivateSensor(voltage); var currentActiveLimit = physicalGPU.PerformanceControl.CurrentActiveLimit; powerLimit.Value = ((currentActiveLimit & PerformanceLimit.PowerLimit) == PerformanceLimit.PowerLimit) ? 1 : 0; ActivateSensor(powerLimit); temperatureLimit.Value = ((currentActiveLimit & PerformanceLimit.TemperatureLimit) == PerformanceLimit.TemperatureLimit) ? 1 : 0; ActivateSensor(temperatureLimit); voltageLimit.Value = ((currentActiveLimit & PerformanceLimit.VoltageLimit) == PerformanceLimit.VoltageLimit) ? 1 : 0; ActivateSensor(voltageLimit); } catch { voltage.Value = float.NaN; powerLimit.Value = float.NaN; temperatureLimit.Value = float.NaN; voltageLimit.Value = float.NaN; } } var infoEx = new NvDynamicPstatesInfoEx(); infoEx.Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_EX_VER; infoEx.UtilizationDomains = new NvUtilizationDomainEx[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS]; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx(handle, ref infoEx) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (infoEx.UtilizationDomains[i].Present) { loads[i].Value = infoEx.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } else { var info = new NvDynamicPstatesInfo { Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_VER, UtilizationDomains = new NvUtilizationDomain[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS] }; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfo != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfo(handle, ref info) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (info.UtilizationDomains[i].Present) { loads[i].Value = info.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } } var coolerSettings = GetCoolerSettings(); var coolerSettingsOk = false; if (coolerSettings.Count > 0) { control.Value = coolerSettings.Cooler[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk || !coolerSettingsOk) { var coolersStatus = GetFanCoolersStatus(); if (coolersStatus.Count > 0) { if (!coolerSettingsOk) { control.Value = coolersStatus.Items[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk) { fan.Value = coolersStatus.Items[0].CurrentRpm; ActivateSensor(fan); tachReadingOk = true; } } } NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo { Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER, Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU] }; if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null && displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverMemoryInfo(displayHandle.Value, ref memoryInfo) == NvStatus.OK) { uint totalMemory = memoryInfo.Values[0]; uint freeMemory = memoryInfo.Values[4]; float usedMemory = Math.Max(totalMemory - freeMemory, 0); memoryFree.Value = (float)freeMemory / 1024; memoryAvail.Value = (float)totalMemory / 1024; memoryUsed.Value = usedMemory / 1024; memoryLoad.Value = 100f * usedMemory / totalMemory; ActivateSensor(memoryAvail); ActivateSensor(memoryUsed); ActivateSensor(memoryFree); ActivateSensor(memoryLoad); } if (power != null) { var channels = new NvGpuPowerMonitorPowerChannelStatus[NVAPI.POWER_STATUS_CHANNEL_COUNT]; for (int i = 0; i < channels.Length; i++) { channels[i].Rsvd = new byte[NVAPI.POWER_STATUS_RSVD_SIZE]; } var powerStatus = new NvGpuPowerStatus { Version = NVAPI.GPU_POWER_MONITOR_STATUS_VER, Rsvd = new byte[NVAPI.POWER_STATUS_RSVD_SIZE], Channels = channels }; if (NVAPI.NvAPI_GPU_PowerMonitorGetStatus != null && NVAPI.NvAPI_GPU_PowerMonitorGetStatus(handle, ref powerStatus) == NvStatus.OK) { power.Value = powerStatus.TotalGpuPowermW * 1E-03f; ActivateSensor(power); //// Grap all other sensors/channels //var powerSensors = powerStatus.Channels.Where(ch => ch.PwrAvgmW != 0).Select(ch => ch.PwrAvgmW * 1E-03).ToArray(); //for (int i = 0; i < powerSensors.Length; i++) //{ // Console.WriteLine($"Sensor {i}: {powerSensors[i]}W"); //} //Console.WriteLine("------------------------------------------"); } } // update VRAM usage if (dedicatedVramUsagePerformCounter != null) { try { memoryUsageDedicated.Value = dedicatedVramUsagePerformCounter.NextValue() / 1024f / 1024f; ActivateSensor(memoryUsageDedicated); } catch { } } if (sharedVramUsagePerformCounter != null) { try { memoryUsageShared.Value = (float)sharedVramUsagePerformCounter.NextValue() / 1024f / 1024f; ActivateSensor(memoryUsageShared); } catch { } } if (pcieThroughputRx != null) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.RxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputRx.Value = value / 1024f; ActivateSensor(pcieThroughputRx); } } if (pcieThroughputTx != null) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.TxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputTx.Value = value / 1024f; ActivateSensor(pcieThroughputTx); } } }
public override void Update() { if (temperatures.Any(sensor => sensorConfig.GetSensorEvaluate(sensor.IdentifierString))) { NvGPUThermalSettings settings = GetThermalSettings(); foreach (Sensor sensor in temperatures) { sensor.Value = settings.Sensor[sensor.Index].CurrentTemp; } } else { foreach (Sensor sensor in temperatures) { sensor.Value = null; } } bool tachReadingOk = false; if (sensorConfig.GetSensorEvaluate(fan.IdentifierString)) { if (NVAPI.NvAPI_GPU_GetTachReading != null && NVAPI.NvAPI_GPU_GetTachReading(handle, out int fanValue) == NvStatus.OK) { fan.Value = fanValue; ActivateSensor(fan); tachReadingOk = true; } } else { fan.Value = null; } if (clocks.Any(sensor => sensorConfig.GetSensorEvaluate(sensor.IdentifierString))) { uint[] values = GetClocks(); if (values != null) { clocks[1].Value = 0.001f * values[8]; if (values[30] != 0) { clocks[0].Value = 0.0005f * values[30]; clocks[2].Value = 0.001f * values[30]; } else { clocks[0].Value = 0.001f * values[0]; clocks[2].Value = 0.001f * values[14]; } } } else { for (int i = 0; i < clocks.Length; i++) { clocks[i].Value = null; } } if (sensorConfig.GetSensorEvaluate(voltage.IdentifierString)) { var gpuVoltageStatus = new NvGpuVoltageStatus { Version = NVAPI.GPU_VOLTAGE_STATUS_VER, Unknown2 = new uint[8], Unknown3 = new uint[8] }; if (NVAPI.NvAPI_GPU_GetCurrentVoltage != null && NVAPI.NvAPI_GPU_GetCurrentVoltage(handle, ref gpuVoltageStatus) == NvStatus.OK) { voltage.Value = gpuVoltageStatus.ValueInuV / 1E06f; ActivateSensor(voltage); } } else { voltage.Value = null; } if (loads.Any(sensor => sensorConfig.GetSensorEvaluate(sensor.IdentifierString))) { var infoEx = new NvDynamicPstatesInfoEx { Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_EX_VER, UtilizationDomains = new NvUtilizationDomainEx[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS] }; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx(handle, ref infoEx) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (infoEx.UtilizationDomains[i].Present) { loads[i].Value = infoEx.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } else { var info = new NvDynamicPstatesInfo { Version = NVAPI.GPU_DYNAMIC_PSTATES_INFO_VER, UtilizationDomains = new NvUtilizationDomain[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS] }; if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfo != null && NVAPI.NvAPI_GPU_GetDynamicPstatesInfo(handle, ref info) == NvStatus.OK) { for (int i = 0; i < loads.Length; i++) { if (info.UtilizationDomains[i].Present) { loads[i].Value = info.UtilizationDomains[i].Percentage; ActivateSensor(loads[i]); } } } } } else { for (int i = 0; i < loads.Length; i++) { loads[i].Value = null; } } if (sensorConfig.GetSensorEvaluate(control.IdentifierString) || sensorConfig.GetSensorEvaluate(fan.IdentifierString)) { var coolerSettings = GetCoolerSettings(); var coolerSettingsOk = false; if (coolerSettings.Count > 0) { control.Value = coolerSettings.Cooler[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk || !coolerSettingsOk) { var coolersStatus = GetFanCoolersStatus(); if (coolersStatus.Count > 0) { if (!coolerSettingsOk) { control.Value = coolersStatus.Items[0].CurrentLevel; ActivateSensor(control); coolerSettingsOk = true; } if (!tachReadingOk) { fan.Value = coolersStatus.Items[0].CurrentRpm; ActivateSensor(fan); tachReadingOk = true; } } } } else { control.Value = null; fan.Value = null; } if (!(!sensorConfig.GetSensorEvaluate(memoryAvail.IdentifierString) && !sensorConfig.GetSensorEvaluate(memoryUsed.IdentifierString) && !sensorConfig.GetSensorEvaluate(memoryFree.IdentifierString) && !sensorConfig.GetSensorEvaluate(memoryLoad.IdentifierString))) { NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo { Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER, Values = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU] }; if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null && displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverMemoryInfo(displayHandle.Value, ref memoryInfo) == NvStatus.OK) { uint totalMemory = memoryInfo.Values[0]; uint freeMemory = memoryInfo.Values[4]; float usedMemory = Math.Max(totalMemory - freeMemory, 0); memoryFree.Value = (float)freeMemory / 1024 / 1024; memoryAvail.Value = (float)totalMemory / 1024 / 1024; memoryUsed.Value = usedMemory / 1024 / 1024; memoryLoad.Value = 100f * usedMemory / totalMemory; ActivateSensor(memoryAvail); ActivateSensor(memoryUsed); ActivateSensor(memoryFree); ActivateSensor(memoryLoad); } } else { memoryAvail.Value = null; memoryUsed.Value = null; memoryFree.Value = null; memoryLoad.Value = null; } if (power != null) { if (sensorConfig.GetSensorEvaluate(power.IdentifierString)) { var channels = new NvGpuPowerMonitorPowerChannelStatus[NVAPI.POWER_STATUS_CHANNEL_COUNT]; for (int i = 0; i < channels.Length; i++) { channels[i].Rsvd = new byte[NVAPI.POWER_STATUS_RSVD_SIZE]; } var powerStatus = new NvGpuPowerStatus { Version = NVAPI.GPU_POWER_MONITOR_STATUS_VER, Rsvd = new byte[NVAPI.POWER_STATUS_RSVD_SIZE], Channels = channels }; if (NVAPI.NvAPI_GPU_PowerMonitorGetStatus != null && NVAPI.NvAPI_GPU_PowerMonitorGetStatus(handle, ref powerStatus) == NvStatus.OK) { power.Value = powerStatus.TotalGpuPowermW * 1E-03f; ActivateSensor(power); } } else { power.Value = null; } } // update VRAM usage if (dedicatedVramUsagePerformCounter != null) { try { if (sensorConfig.GetSensorEvaluate(memoryUsageDedicated.IdentifierString)) { memoryUsageDedicated.Value = dedicatedVramUsagePerformCounter.NextValue() / SCALE; ActivateSensor(memoryUsageDedicated); } else { memoryUsageDedicated.Value = null; } } catch { memoryUsageDedicated.Value = null; } } if (sharedVramUsagePerformCounter != null) { try { if (sensorConfig.GetSensorEvaluate(memoryUsageShared.IdentifierString)) { memoryUsageShared.Value = (float)sharedVramUsagePerformCounter.NextValue() / SCALE; ActivateSensor(memoryUsageShared); } else { memoryUsageShared.Value = null; } } catch { memoryUsageShared.Value = null; } } try { if (sensorConfig.GetSensorEvaluate(processMemoryUsageDedicated.IdentifierString)) { lock (_performanceCounterLock) { processMemoryUsageDedicated.Value = dedicatedVramUsageProcessPerformCounter == null ? 0f : (float)dedicatedVramUsageProcessPerformCounter.NextValue() / SCALE; } ActivateSensor(processMemoryUsageDedicated); } else { processMemoryUsageDedicated.Value = null; } } catch { processMemoryUsageDedicated.Value = null; } try { if (sensorConfig.GetSensorEvaluate(processMemoryUsageShared.IdentifierString)) { lock (_performanceCounterLock) { processMemoryUsageShared.Value = sharedVramUsageProcessPerformCounter == null ? 0f : (float)sharedVramUsageProcessPerformCounter.NextValue() / SCALE; } ActivateSensor(processMemoryUsageShared); } else { processMemoryUsageShared.Value = null; } } catch { processMemoryUsageShared.Value = null; } if (pcieThroughputRx != null) { if (sensorConfig.GetSensorEvaluate(pcieThroughputRx.IdentifierString)) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.RxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputRx.Value = value / 1024f; ActivateSensor(pcieThroughputRx); } } else { pcieThroughputRx.Value = null; } } if (pcieThroughputTx != null) { if (sensorConfig.GetSensorEvaluate(pcieThroughputTx.IdentifierString)) { if (NVML.NvmlDeviceGetPcieThroughput(device.Value, NVML.NvmlPcieUtilCounter.TxBytes, out uint value) == NVML.NvmlReturn.Success) { pcieThroughputTx.Value = value / 1024f; ActivateSensor(pcieThroughputTx); } } else { pcieThroughputTx.Value = null; } } if (sensorConfig.GetSensorEvaluate(monitorRefreshRate.IdentifierString)) { if (NVAPI.NvAPI_GetVBlankCounter(displayHandle.Value, out uint pCounter) == NvStatus.OK) { var deltaTicks = stopwatch.ElapsedTicks; stopwatch.Restart(); lock (_displayLock) { var currentRefreshRate = (float)(pCounter - lastpCounter) / deltaTicks * Stopwatch.Frequency; refreshRateBuffer.Add(currentRefreshRate); var refreshRateFiltered = (float)Math.Ceiling(refreshRateBuffer.RefreshRates.Average()); monitorRefreshRate.Value = refreshRateFiltered > refreshRateCurrentWindowHandle ? refreshRateCurrentWindowHandle : refreshRateFiltered; } lastpCounter = pCounter; ActivateSensor(monitorRefreshRate); } } else { monitorRefreshRate.Value = null; } }
public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle, NvDisplayHandle?displayHandle, ISettings settings, NVML nvml) : base(GetName(handle), new Identifier("nvidiagpu", adapterIndex.ToString(CultureInfo.InvariantCulture)), settings) { this.adapterIndex = adapterIndex; this.handle = handle; this.displayHandle = displayHandle; this.nvml = nvml; NvGPUThermalSettings thermalSettings = GetThermalSettings(); temperatures = new Sensor[thermalSettings.Count]; for (int i = 0; i < temperatures.Length; i++) { NvSensor sensor = thermalSettings.Sensor[i]; string name; switch (sensor.Target) { case NvThermalTarget.BOARD: name = "GPU Board"; break; case NvThermalTarget.GPU: name = "GPU Core"; break; case NvThermalTarget.MEMORY: name = "GPU Memory"; break; case NvThermalTarget.POWER_SUPPLY: name = "GPU Power Supply"; break; case NvThermalTarget.UNKNOWN: name = "GPU Unknown"; break; default: name = "GPU"; break; } temperatures[i] = new Sensor(name, i, SensorType.Temperature, this, new ParameterDescription[0], settings); ActivateSensor(temperatures[i]); } int value; if (NVAPI.NvAPI_GPU_GetTachReading != null && NVAPI.NvAPI_GPU_GetTachReading(handle, out value) == NvStatus.OK) { if (value >= 0) { fan = new Sensor("GPU", 0, SensorType.Fan, this, settings); ActivateSensor(fan); } } clocks = new Sensor[3]; clocks[0] = new Sensor("GPU Core", 0, SensorType.Clock, this, settings); clocks[1] = new Sensor("GPU Memory", 1, SensorType.Clock, this, settings); clocks[2] = new Sensor("GPU Shader", 2, SensorType.Clock, this, settings); for (int i = 0; i < clocks.Length; i++) { ActivateSensor(clocks[i]); } loads = new Sensor[3]; loads[0] = new Sensor("GPU Core", 0, SensorType.Load, this, settings); loads[1] = new Sensor("GPU Memory Controller", 1, SensorType.Load, this, settings); loads[2] = new Sensor("GPU Video Engine", 2, SensorType.Load, this, settings); memoryLoad = new Sensor("GPU Memory", 3, SensorType.Load, this, settings); memoryFree = new Sensor("GPU Memory Free", 1, SensorType.SmallData, this, settings); memoryUsed = new Sensor("GPU Memory Used", 2, SensorType.SmallData, this, settings); memoryAvail = new Sensor("GPU Memory Total", 3, SensorType.SmallData, this, settings); control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings); NvGPUCoolerSettings coolerSettings = GetCoolerSettings(); if (coolerSettings.Count > 0) { fanControl = new Control(control, settings, coolerSettings.Cooler[0].DefaultMin, coolerSettings.Cooler[0].DefaultMax); fanControl.ControlModeChanged += ControlModeChanged; fanControl.SoftwareControlValueChanged += SoftwareControlValueChanged; ControlModeChanged(fanControl); control.Control = fanControl; } if (nvml.Initialised) { nvmlDevice = nvml.NvmlDeviceGetHandleByIndex(adapterIndex); if (nvmlDevice.HasValue) { powerUsage = new Sensor("GPU Package", 0, SensorType.Power, this, settings); } } Update(); }