File: NvidiaGpu.cpp

package info (click to toggle)
ksystemstats 6.5.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,528 kB
  • sloc: cpp: 4,881; makefile: 6; sh: 1
file content (91 lines) | stat: -rw-r--r-- 2,994 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
 *
 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
 */

#include "NvidiaGpu.h"

#include "debug.h"

NvidiaSmiProcess *NvidiaGpu::s_smiProcess = nullptr;

constexpr quint64 mbToBytes(quint64 mb) {
    return mb * 1024 * 1024;
}

NvidiaGpu::NvidiaGpu(const QString &id, const QString &name, const QString& pci_path)
    : GpuDevice(id, name),
    m_pciPath(pci_path)
{
    if (!s_smiProcess) {
        s_smiProcess = new NvidiaSmiProcess();
    }

    connect(s_smiProcess, &NvidiaSmiProcess::dataReceived, this, &NvidiaGpu::onDataReceived);
}

NvidiaGpu::~NvidiaGpu()
{
    for (auto sensor : {m_usageProperty, m_totalVramProperty, m_usedVramProperty, m_temperatureProperty, m_coreFrequencyProperty, m_memoryFrequencyProperty}) {
        if (sensor->isSubscribed()) {
            NvidiaGpu::s_smiProcess->unref();
        }
    }
}

void NvidiaGpu::initialize()
{
    GpuDevice::initialize();

    for (auto sensor : {m_usageProperty,
                        m_totalVramProperty,
                        m_usedVramProperty,
                        m_temperatureProperty,
                        m_coreFrequencyProperty,
                        m_memoryFrequencyProperty,
                        m_powerProperty}) {
        connect(sensor, &KSysGuard::SensorProperty::subscribedChanged, sensor, [sensor]() {
            if (sensor->isSubscribed()) {
                NvidiaGpu::s_smiProcess->ref();
            } else {
                NvidiaGpu::s_smiProcess->unref();
            }
        });
    }

    const auto queryResult = s_smiProcess->query();
    auto it = std::find_if(queryResult.cbegin(), queryResult.cend(), [this] (const NvidiaSmiProcess::GpuQueryResult &result) {
        return result.pciPath == m_pciPath;
    });
    if (it == queryResult.cend()) {
        qCWarning(KSYSTEMSTATS_GPU) << "Could not retrieve information for NVidia GPU" << m_pciPath;
    } else {
        m_index = it - queryResult.cbegin();
        m_nameProperty->setValue(it->name);
        m_totalVramProperty->setValue(mbToBytes(it->totalMemory));
        m_usedVramProperty->setMax(mbToBytes(it->totalMemory));
        m_coreFrequencyProperty->setMax(it->maxCoreFrequency);
        m_memoryFrequencyProperty->setMax(it->maxMemoryFrequency);
        m_temperatureProperty->setMax(it->maxTemperature);
        m_powerProperty->setMax(it->maxPower);
    }

    m_powerProperty->setUnit(KSysGuard::UnitWatt);
}

void NvidiaGpu::onDataReceived(const NvidiaSmiProcess::GpuData &data)
{
    if (data.index != m_index) {
        return;
    }

    m_usageProperty->setValue(data.usage);
    m_usedVramProperty->setValue(mbToBytes(data.memoryUsed));
    m_coreFrequencyProperty->setValue(data.coreFrequency);
    m_memoryFrequencyProperty->setValue(data.memoryFrequency);
    m_temperatureProperty->setValue(data.temperature);
    m_powerProperty->setValue(data.power);
}

#include "moc_NvidiaGpu.cpp"