public void Update()
        {
            NvGPUThermalSettings settings = GetThermalSettings();

            foreach (Sensor sensor in temperatures)
            {
                sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
            }
        }
Example #2
0
        public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle)
        {
            try {
                string gpuName;
                if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK)
                {
                    this.name = "NVIDIA " + gpuName.Trim();
                }
                else
                {
                    this.name = "NVIDIA";
                }
                this.icon         = Utilities.EmbeddedResources.GetImage("nvidia.png");
                this.adapterIndex = adapterIndex;
                this.handle       = handle;

                NvGPUThermalSettings settings = GetThermalSettings();
                temperatures = new Sensor[settings.Count];
                for (int i = 0; i < temperatures.Length; i++)
                {
                    NvSensor sensor = settings.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, sensor.DefaultMaxTemp,
                                                 SensorType.Temperature, this);
                    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);
                        ActivateSensor(fan);
                    }
                }

                available = temperatures.Length > 0 || fan != null;
            } catch (Exception e) {
                System.Windows.Forms.MessageBox.Show(e.Message + "\n" + e.StackTrace);
            }
        }
        private NvGPUThermalSettings GetThermalSettings()
        {
            NvGPUThermalSettings settings = new NvGPUThermalSettings();

            settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
            settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
            settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
            NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
                                               ref settings);
            return(settings);
        }
Example #4
0
        private NvGPUThermalSettings GetThermalSettings()
        {
            var settings = new NvGPUThermalSettings();

            settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
            settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
            settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
            if (!(NVAPI.NvAPI_GPU_GetThermalSettings != null &&
                  NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
                                                     ref settings) == NvStatus.OK))
            {
                settings.Count = 0;
            }
            return(settings);
        }
        public override void Update()
        {
            NvGPUThermalSettings settings = GetThermalSettings();

            foreach (Sensor sensor in temperatures)
            {
                sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
            }

            if (fan != null)
            {
                int value = 0;
                NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
                fan.Value = value;
            }
        }
Example #6
0
        private NvGPUThermalSettings GetThermalSettings()
        {
            // HACK: For some reason, it needs this
            NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();

            driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
            NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value, ref driverVersion);

            NvGPUThermalSettings settings = new NvGPUThermalSettings();

            settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
            settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
            settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];
            if (!(NVAPI.NvAPI_GPU_GetThermalSettings != null &&
                  NVAPI.NvAPI_GPU_GetThermalSettings(handle, (int)NvThermalTarget.ALL,
                                                     ref settings) == NvStatus.OK))
            {
                settings.Count = 0;
            }
            return(settings);
        }
        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);
                }
            }
        }
Example #8
0
        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]);
            }

            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);

            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;
            }
            Update();
        }
Example #9
0
        public override void Update()
        {
            NvGPUThermalSettings settings = GetThermalSettings();

            foreach (Sensor sensor in temperatures)
            {
                sensor.Value = settings.Sensor[sensor.Index].CurrentTemp;
            }

            if (fan != null)
            {
                int value = 0;
                NVAPI.NvAPI_GPU_GetTachReading(handle, out value);
                fan.Value = value;
            }

            uint[] values = GetClocks();
            if (values != null)
            {
                clocks[0].Value = 0.001f * values[0];
                clocks[1].Value = 0.001f * values[8];
                clocks[2].Value = 0.001f * values[14];
                if (values[30] != 0)
                {
                    clocks[0].Value = 0.0005f * values[30];
                    clocks[2].Value = 0.001f * values[30];
                }
            }

            NvPStates states = new NvPStates();

            states.Version = NVAPI.GPU_PSTATES_VER;
            states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
            if (NVAPI.NvAPI_GPU_GetPStates != null &&
                NVAPI.NvAPI_GPU_GetPStates(handle, ref states) == NvStatus.OK)
            {
                for (int i = 0; i < 3; i++)
                {
                    if (states.PStates[i].Present)
                    {
                        loads[i].Value = states.PStates[i].Percentage;
                        ActivateSensor(loads[i]);
                    }
                }
            }
            else
            {
                NvUsages usages = new NvUsages();
                usages.Version = NVAPI.GPU_USAGES_VER;
                usages.Usage   = new uint[NVAPI.MAX_USAGES_PER_GPU];
                if (NVAPI.NvAPI_GPU_GetUsages != null &&
                    NVAPI.NvAPI_GPU_GetUsages(handle, ref usages) == NvStatus.OK)
                {
                    loads[0].Value = usages.Usage[2];
                    loads[1].Value = usages.Usage[6];
                    loads[2].Value = usages.Usage[10];
                    for (int i = 0; i < 3; i++)
                    {
                        ActivateSensor(loads[i]);
                    }
                }
            }


            NvGPUCoolerSettings coolerSettings = GetCoolerSettings();

            if (coolerSettings.Count > 0)
            {
                control.Value = coolerSettings.Cooler[0].CurrentLevel;
                ActivateSensor(control);
            }

            NvMemoryInfo memoryInfo = new NvMemoryInfo();

            memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
            memoryInfo.Values  = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
            if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue &&
                NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value, ref memoryInfo) ==
                NvStatus.OK)
            {
                uint  totalMemory = memoryInfo.Values[0];
                uint  freeMemory  = memoryInfo.Values[4];
                float usedMemory  = Math.Max(totalMemory - freeMemory, 0);
                memoryLoad.Value = 100f * usedMemory / totalMemory;
                ActivateSensor(memoryLoad);
            }
        }
Example #10
0
        public override string GetReport()
        {
            StringBuilder r = new StringBuilder();

            r.AppendLine("Nvidia GPU");
            r.AppendLine();

            r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
            r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);

            if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null)
            {
                NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
                driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
                if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
                                                        ref driverVersion) == NvStatus.OK)
                {
                    r.Append("Driver Version: ");
                    r.Append(driverVersion.DriverVersion / 100);
                    r.Append(".");
                    r.Append((driverVersion.DriverVersion % 100).ToString("00",
                                                                          CultureInfo.InvariantCulture));
                    r.AppendLine();
                    r.Append("Driver Branch: ");
                    r.AppendLine(driverVersion.BuildBranch);
                }
            }
            r.AppendLine();

            if (NVAPI.NvAPI_GPU_GetThermalSettings != null)
            {
                NvGPUThermalSettings settings = new NvGPUThermalSettings();
                settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
                settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
                settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];

                NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
                                                                     (int)NvThermalTarget.ALL, ref settings);

                r.AppendLine("Thermal Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
                                       settings.Sensor[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
                                       settings.Sensor[i].CurrentTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
                                       settings.Sensor[i].Target, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetAllClocks != null)
            {
                NvClocks allClocks = new NvClocks();
                allClocks.Version = NVAPI.GPU_CLOCKS_VER;
                allClocks.Clock   = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks);

                r.AppendLine("Clocks");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < allClocks.Clock.Length; i++)
                    {
                        if (allClocks.Clock[i] > 0)
                        {
                            r.AppendFormat(" Clock[{0}]: {1}{2}", i, allClocks.Clock[i],
                                           Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetTachReading != null)
            {
                int      tachValue;
                NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);

                r.AppendLine("Tachometer");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetPStates != null)
            {
                NvPStates states = new NvPStates();
                states.Version = NVAPI.GPU_PSTATES_VER;
                states.PStates = new NvPState[NVAPI.MAX_PSTATES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetPStates(handle, ref states);

                r.AppendLine("P-States");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < states.PStates.Length; i++)
                    {
                        if (states.PStates[i].Present)
                        {
                            r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
                                           states.PStates[i].Percentage, Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetUsages != null)
            {
                NvUsages usages = new NvUsages();
                usages.Version = NVAPI.GPU_USAGES_VER;
                usages.Usage   = new uint[NVAPI.MAX_USAGES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetUsages(handle, ref usages);

                r.AppendLine("Usages");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < usages.Usage.Length; i++)
                    {
                        if (usages.Usage[i] > 0)
                        {
                            r.AppendFormat(" Usage[{0}]: {1}{2}", i,
                                           usages.Usage[i], Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetCoolerSettings != null)
            {
                NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
                settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
                settings.Cooler  = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
                NvStatus status =
                    NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);

                r.AppendLine("Cooler Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
                                       settings.Cooler[i].Type, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
                                       settings.Cooler[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
                                       settings.Cooler[i].DefaultMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
                                       settings.Cooler[i].DefaultMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
                                       settings.Cooler[i].CurrentMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
                                       settings.Cooler[i].CurrentMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
                                       settings.Cooler[i].CurrentLevel, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
                                       settings.Cooler[i].DefaultPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
                                       settings.Cooler[i].CurrentPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
                                       settings.Cooler[i].Target, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
                                       settings.Cooler[i].ControlType, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
                                       settings.Cooler[i].Active, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetMemoryInfo != null && displayHandle.HasValue)
            {
                NvMemoryInfo memoryInfo = new NvMemoryInfo();
                memoryInfo.Version = NVAPI.GPU_MEMORY_INFO_VER;
                memoryInfo.Values  = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetMemoryInfo(displayHandle.Value,
                                                                ref memoryInfo);

                r.AppendLine("Memory Info");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < memoryInfo.Values.Length; i++)
                    {
                        r.AppendFormat(" Value[{0}]: {1}{2}", i,
                                       memoryInfo.Values[i], Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            return(r.ToString());
        }
Example #11
0
        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 string GetReport()
        {
            NVidiaGpu nVidiaGpu = new NVidiaGpu();

            nVidiaGpu.Name = name;

            if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null)
            {
                NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
                driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
                if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
                                                        ref driverVersion) == NvStatus.OK)
                {
                    nVidiaGpu.DriverVersion = (driverVersion.DriverVersion / 100).ToString() + "." + (driverVersion.DriverVersion % 100).ToString("00", CultureInfo.InvariantCulture);
                    nVidiaGpu.DriverBranch  = driverVersion.BuildBranch;
                }
            }
            if (NVAPI.NvAPI_GPU_GetPCIIdentifiers != null)
            {
                uint deviceId, subSystemId, revisionId, extDeviceId;

                NvStatus status = NVAPI.NvAPI_GPU_GetPCIIdentifiers(handle,
                                                                    out deviceId, out subSystemId, out revisionId, out extDeviceId);

                if (status == NvStatus.OK)
                {
                    nVidiaGpu.DeviceID   = deviceId.ToString("X", CultureInfo.InvariantCulture);
                    nVidiaGpu.RevisionID = revisionId.ToString("X", CultureInfo.InvariantCulture);
                }
            }

            if (NVAPI.NvAPI_GPU_GetThermalSettings != null)
            {
                NvGPUThermalSettings settings = new NvGPUThermalSettings();
                settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
                settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
                settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];

                NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
                                                                     (int)NvThermalTarget.ALL, ref settings);


                if (status == NvStatus.OK)
                {
                    nVidiaGpu.CurrentTemp = (long)settings.Sensor[0].CurrentTemp;
                }
            }
            else
            {
                nVidiaGpu.CurrentTemp = 0;
            }

            if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null &&
                displayHandle.HasValue)
            {
                NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo();
                memoryInfo.Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER;
                memoryInfo.Values  = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GetDisplayDriverMemoryInfo(
                    displayHandle.Value, ref memoryInfo);


                if (status == NvStatus.OK)
                {
                    nVidiaGpu.TotalMemory     = memoryInfo.Values[0];
                    nVidiaGpu.AvailableMemory = memoryInfo.Values[1];
                }
                else
                {
                    nVidiaGpu.TotalMemory     = 21;
                    nVidiaGpu.AvailableMemory = 37;
                }
            }
            return(JsonSerializer.Serialize(nVidiaGpu));
        }
Example #13
0
        public NvidiaGPU(int adapterIndex, NvPhysicalGpuHandle handle,
                         NvDisplayHandle?displayHandle, ISettings settings)
        {
            string gpuName;

            if (NVAPI.NvAPI_GPU_GetFullName(handle, out gpuName) == NvStatus.OK)
            {
                this.name = "NVIDIA " + gpuName.Trim();
            }
            else
            {
                this.name = "NVIDIA";
            }
            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]);
            }

            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);

            control = new Sensor("GPU Fan", 0, SensorType.Control, this, settings);
        }
Example #14
0
        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)
            : 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 string GetReport()
        {
            StringBuilder r = new StringBuilder();

            r.AppendLine("Nvidia GPU");
            r.AppendLine();

            r.AppendFormat("Name: {0}{1}", name, Environment.NewLine);
            r.AppendFormat("Index: {0}{1}", adapterIndex, Environment.NewLine);

            if (displayHandle.HasValue && NVAPI.NvAPI_GetDisplayDriverVersion != null)
            {
                NvDisplayDriverVersion driverVersion = new NvDisplayDriverVersion();
                driverVersion.Version = NVAPI.DISPLAY_DRIVER_VERSION_VER;
                if (NVAPI.NvAPI_GetDisplayDriverVersion(displayHandle.Value,
                                                        ref driverVersion) == NvStatus.OK)
                {
                    r.Append("Driver Version: ");
                    r.Append(driverVersion.DriverVersion / 100);
                    r.Append(".");
                    r.Append((driverVersion.DriverVersion % 100).ToString("00",
                                                                          CultureInfo.InvariantCulture));
                    r.AppendLine();
                    r.Append("Driver Branch: ");
                    r.AppendLine(driverVersion.BuildBranch);
                }
            }
            r.AppendLine();

            if (NVAPI.NvAPI_GPU_GetPCIIdentifiers != null)
            {
                uint deviceId, subSystemId, revisionId, extDeviceId;

                NvStatus status = NVAPI.NvAPI_GPU_GetPCIIdentifiers(handle,
                                                                    out deviceId, out subSystemId, out revisionId, out extDeviceId);

                if (status == NvStatus.OK)
                {
                    r.Append("DeviceID: 0x");
                    r.AppendLine(deviceId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("SubSystemID: 0x");
                    r.AppendLine(subSystemId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("RevisionID: 0x");
                    r.AppendLine(revisionId.ToString("X", CultureInfo.InvariantCulture));
                    r.Append("ExtDeviceID: 0x");
                    r.AppendLine(extDeviceId.ToString("X", CultureInfo.InvariantCulture));
                    r.AppendLine();
                }
            }

            if (NVAPI.NvAPI_GPU_GetThermalSettings != null)
            {
                NvGPUThermalSettings settings = new NvGPUThermalSettings();
                settings.Version = NVAPI.GPU_THERMAL_SETTINGS_VER;
                settings.Count   = NVAPI.MAX_THERMAL_SENSORS_PER_GPU;
                settings.Sensor  = new NvSensor[NVAPI.MAX_THERMAL_SENSORS_PER_GPU];

                NvStatus status = NVAPI.NvAPI_GPU_GetThermalSettings(handle,
                                                                     (int)NvThermalTarget.ALL, ref settings);

                r.AppendLine("Thermal Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Sensor[{0}].Controller: {1}{2}", i,
                                       settings.Sensor[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMinTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMinTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].DefaultMaxTemp: {1}{2}", i,
                                       settings.Sensor[i].DefaultMaxTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].CurrentTemp: {1}{2}", i,
                                       settings.Sensor[i].CurrentTemp, Environment.NewLine);
                        r.AppendFormat(" Sensor[{0}].Target: {1}{2}", i,
                                       settings.Sensor[i].Target, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetAllClocks != null)
            {
                NvClocks allClocks = new NvClocks();
                allClocks.Version = NVAPI.GPU_CLOCKS_VER;
                allClocks.Clock   = new uint[NVAPI.MAX_CLOCKS_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GPU_GetAllClocks(handle, ref allClocks);

                r.AppendLine("Clocks");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < allClocks.Clock.Length; i++)
                    {
                        if (allClocks.Clock[i] > 0)
                        {
                            r.AppendFormat(" Clock[{0}]: {1}{2}", i, allClocks.Clock[i],
                                           Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetTachReading != null)
            {
                int      tachValue;
                NvStatus status = NVAPI.NvAPI_GPU_GetTachReading(handle, out tachValue);

                r.AppendLine("Tachometer");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    r.AppendFormat(" Value: {0}{1}", tachValue, Environment.NewLine);
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx != null)
            {
                var info = new NvDynamicPstatesInfoEx();
                info.Version            = NVAPI.GPU_DYNAMIC_PSTATES_INFO_EX_VER;
                info.UtilizationDomains =
                    new NvUtilizationDomainEx[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS];
                var status = NVAPI.NvAPI_GPU_GetDynamicPstatesInfoEx(handle, ref info);

                r.AppendLine("Utilization Domains Ex");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < info.UtilizationDomains.Length; i++)
                    {
                        if (info.UtilizationDomains[i].Present)
                        {
                            r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
                                           info.UtilizationDomains[i].Percentage, Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetDynamicPstatesInfo != null)
            {
                var info = new NvDynamicPstatesInfo();
                info.Version            = NVAPI.GPU_DYNAMIC_PSTATES_INFO_VER;
                info.UtilizationDomains =
                    new NvUtilizationDomain[NVAPI.NVAPI_MAX_GPU_UTILIZATIONS];
                var status = NVAPI.NvAPI_GPU_GetDynamicPstatesInfo(handle, ref info);

                r.AppendLine("Utilization Domains");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < info.UtilizationDomains.Length; i++)
                    {
                        if (info.UtilizationDomains[i].Present)
                        {
                            r.AppendFormat(" Percentage[{0}]: {1}{2}", i,
                                           info.UtilizationDomains[i].Percentage, Environment.NewLine);
                        }
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_GetCoolerSettings != null)
            {
                NvGPUCoolerSettings settings = new NvGPUCoolerSettings();
                settings.Version = NVAPI.GPU_COOLER_SETTINGS_VER;
                settings.Cooler  = new NvCooler[NVAPI.MAX_COOLER_PER_GPU];
                NvStatus status =
                    NVAPI.NvAPI_GPU_GetCoolerSettings(handle, 0, ref settings);

                r.AppendLine("Cooler Settings");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < settings.Count; i++)
                    {
                        r.AppendFormat(" Cooler[{0}].Type: {1}{2}", i,
                                       settings.Cooler[i].Type, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Controller: {1}{2}", i,
                                       settings.Cooler[i].Controller, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMin: {1}{2}", i,
                                       settings.Cooler[i].DefaultMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultMax: {1}{2}", i,
                                       settings.Cooler[i].DefaultMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMin: {1}{2}", i,
                                       settings.Cooler[i].CurrentMin, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentMax: {1}{2}", i,
                                       settings.Cooler[i].CurrentMax, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentLevel: {1}{2}", i,
                                       settings.Cooler[i].CurrentLevel, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].DefaultPolicy: {1}{2}", i,
                                       settings.Cooler[i].DefaultPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].CurrentPolicy: {1}{2}", i,
                                       settings.Cooler[i].CurrentPolicy, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Target: {1}{2}", i,
                                       settings.Cooler[i].Target, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].ControlType: {1}{2}", i,
                                       settings.Cooler[i].ControlType, Environment.NewLine);
                        r.AppendFormat(" Cooler[{0}].Active: {1}{2}", i,
                                       settings.Cooler[i].Active, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GetDisplayDriverMemoryInfo != null &&
                displayHandle.HasValue)
            {
                NvDisplayDriverMemoryInfo memoryInfo = new NvDisplayDriverMemoryInfo();
                memoryInfo.Version = NVAPI.DISPLAY_DRIVER_MEMORY_INFO_VER;
                memoryInfo.Values  = new uint[NVAPI.MAX_MEMORY_VALUES_PER_GPU];
                NvStatus status = NVAPI.NvAPI_GetDisplayDriverMemoryInfo(
                    displayHandle.Value, ref memoryInfo);

                r.AppendLine("Memory Info");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < memoryInfo.Values.Length; i++)
                    {
                        r.AppendFormat(" Value[{0}]: {1}{2}", i,
                                       memoryInfo.Values[i], Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            if (NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus != null)
            {
                var coolers = new NvFanCoolersStatus();
                coolers.Version = NVAPI.GPU_FAN_COOLERS_STATUS_VER;
                coolers.Items   =
                    new NvFanCoolersStatusItem[NVAPI.MAX_FAN_COOLERS_STATUS_ITEMS];

                var status = NVAPI.NvAPI_GPU_ClientFanCoolersGetStatus(handle, ref coolers);

                r.AppendLine("Fan Coolers Status");
                r.AppendLine();
                if (status == NvStatus.OK)
                {
                    for (int i = 0; i < coolers.Count; i++)
                    {
                        r.AppendFormat(" Items[{0}].Type: {1}{2}", i,
                                       coolers.Items[i].Type, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentRpm: {1}{2}", i,
                                       coolers.Items[i].CurrentRpm, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentMinLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentMinLevel, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentMaxLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentMaxLevel, Environment.NewLine);
                        r.AppendFormat(" Items[{0}].CurrentLevel: {1}{2}", i,
                                       coolers.Items[i].CurrentLevel, Environment.NewLine);
                    }
                }
                else
                {
                    r.Append(" Status: ");
                    r.AppendLine(status.ToString());
                }
                r.AppendLine();
            }

            return(r.ToString());
        }
Example #17
0
        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);
                }
            }
        }