go.d nvidia_smi remove "csv" mode (#18311)
Ilya Mashchenko committed
Aug 12, 2024 at 11:44 UTC
80c0093d11f798e885b8a83c284c7e43f84a857a
15 files changed
+356
-1253
src/go/plugin/go.d/modules/nvidia_smi/charts.go
+3
-44
@@ -53,16 +53,6 @@ var (
53
migDeviceFrameBufferMemoryUsageChartTmpl.Copy(),
54
migDeviceBAR1MemoryUsageChartTmpl.Copy(),
55
}
56
- gpuCSVCharts = module.Charts{
57
- gpuFanSpeedPercChartTmpl.Copy(),
58
- gpuUtilizationChartTmpl.Copy(),
59
- gpuMemUtilizationChartTmpl.Copy(),
60
- gpuFrameBufferMemoryUsageChartTmpl.Copy(),
61
- gpuTemperatureChartTmpl.Copy(),
62
- gpuClockFreqChartTmpl.Copy(),
63
- gpuPowerDrawChartTmpl.Copy(),
64
- gpuPerformanceStateChartTmpl.Copy(),
65
- }
56
)
57
58
var (
@@ -271,7 +261,7 @@ var (
261
}
262
)
263
274
-func (nv *NvidiaSMI) addGPUXMLCharts(gpu xmlGPUInfo) {
264
+func (nv *NvidiaSmi) addGPUXMLCharts(gpu gpuInfo) {
265
charts := gpuXMLCharts.Copy()
266
267
if !isValidValue(gpu.Utilization.GpuUtil) {
@@ -318,37 +308,6 @@ func (nv *NvidiaSMI) addGPUXMLCharts(gpu xmlGPUInfo) {
308
}
309
}
310
321
-func (nv *NvidiaSMI) addGPUCSVCharts(gpu csvGPUInfo) {
322
- charts := gpuCSVCharts.Copy()
323
-
324
- if !isValidValue(gpu.utilizationGPU) {
325
- _ = charts.Remove(gpuUtilizationChartTmpl.ID)
326
- }
327
- if !isValidValue(gpu.utilizationMemory) {
328
- _ = charts.Remove(gpuMemUtilizationChartTmpl.ID)
329
- }
330
- if !isValidValue(gpu.fanSpeed) {
331
- _ = charts.Remove(gpuFanSpeedPercChartTmpl.ID)
332
- }
333
- if !isValidValue(gpu.powerDraw) {
334
- _ = charts.Remove(gpuPowerDrawChartTmpl.ID)
335
- }
336
-
337
- for _, c := range *charts {
338
- c.ID = fmt.Sprintf(c.ID, strings.ToLower(gpu.uuid))
339
- c.Labels = []module.Label{
340
- {Key: "product_name", Value: gpu.name},
341
- }
342
- for _, d := range c.Dims {
343
- d.ID = fmt.Sprintf(d.ID, gpu.uuid)
344
- }
345
- }
346
-
347
- if err := nv.Charts().Add(*charts...); err != nil {
348
- nv.Warning(err)
349
- }
350
-}
351
-
311
var (
312
migDeviceFrameBufferMemoryUsageChartTmpl = module.Chart{
313
ID: "mig_instance_%s_gpu_%s_frame_buffer_memory_usage",
@@ -379,7 +338,7 @@ var (
338
}
339
)
340
382
-func (nv *NvidiaSMI) addMIGDeviceXMLCharts(gpu xmlGPUInfo, mig xmlMIGDeviceInfo) {
341
+func (nv *NvidiaSmi) addMIGDeviceCharts(gpu gpuInfo, mig gpuMIGDeviceInfo) {
342
charts := migDeviceXMLCharts.Copy()
343
344
for _, c := range *charts {
@@ -399,7 +358,7 @@ func (nv *NvidiaSMI) addMIGDeviceXMLCharts(gpu xmlGPUInfo, mig xmlMIGDeviceInfo)
358
}
359
}
360
402
-func (nv *NvidiaSMI) removeCharts(prefix string) {
361
+func (nv *NvidiaSmi) removeCharts(prefix string) {
362
prefix = strings.ToLower(prefix)
363
364
for _, c := range *nv.Charts() {
src/go/plugin/go.d/modules/nvidia_smi/collect.go
+137
-5
@@ -3,12 +3,14 @@
3
package nvidia_smi
4
5
import (
6
+ "encoding/xml"
7
"errors"
8
+ "fmt"
9
"strconv"
10
"strings"
11
)
12
11
-func (nv *NvidiaSMI) collect() (map[string]int64, error) {
13
+func (nv *NvidiaSmi) collect() (map[string]int64, error) {
14
if nv.exec == nil {
15
return nil, errors.New("nvidia-smi exec is not initialized")
16
}
@@ -22,11 +24,141 @@ func (nv *NvidiaSMI) collect() (map[string]int64, error) {
24
return mx, nil
25
}
26
25
-func (nv *NvidiaSMI) collectGPUInfo(mx map[string]int64) error {
26
- if nv.UseCSVFormat {
27
- return nv.collectGPUInfoCSV(mx)
27
+func (nv *NvidiaSmi) collectGPUInfo(mx map[string]int64) error {
28
+ bs, err := nv.exec.queryGPUInfo()
29
+ if err != nil {
30
+ return fmt.Errorf("error on quering XML GPU info: %v", err)
31
+ }
32
+
33
+ info := &gpusInfo{}
34
+ if err := xml.Unmarshal(bs, info); err != nil {
35
+ return fmt.Errorf("error on unmarshaling XML GPU info response: %v", err)
36
+ }
37
+
38
+ seenGPU := make(map[string]bool)
39
+ seenMIG := make(map[string]bool)
40
+
41
+ for _, gpu := range info.GPUs {
42
+ if !isValidValue(gpu.UUID) {
43
+ continue
44
+ }
45
+
46
+ px := "gpu_" + gpu.UUID + "_"
47
+
48
+ seenGPU[px] = true
49
+
50
+ if !nv.gpus[px] {
51
+ nv.gpus[px] = true
52
+ nv.addGPUXMLCharts(gpu)
53
+ }
54
+
55
+ addMetric(mx, px+"pcie_bandwidth_usage_rx", gpu.PCI.RxUtil, 1024) // KB => bytes
56
+ addMetric(mx, px+"pcie_bandwidth_usage_tx", gpu.PCI.TxUtil, 1024) // KB => bytes
57
+ if maxBw := calcMaxPCIEBandwidth(gpu); maxBw > 0 {
58
+ rx := parseFloat(gpu.PCI.RxUtil) * 1024 // KB => bytes
59
+ tx := parseFloat(gpu.PCI.TxUtil) * 1024 // KB => bytes
60
+ mx[px+"pcie_bandwidth_utilization_rx"] = int64((rx * 100 / maxBw) * 100)
61
+ mx[px+"pcie_bandwidth_utilization_tx"] = int64((tx * 100 / maxBw) * 100)
62
+ }
63
+ addMetric(mx, px+"fan_speed_perc", gpu.FanSpeed, 0)
64
+ addMetric(mx, px+"gpu_utilization", gpu.Utilization.GpuUtil, 0)
65
+ addMetric(mx, px+"mem_utilization", gpu.Utilization.MemoryUtil, 0)
66
+ addMetric(mx, px+"decoder_utilization", gpu.Utilization.DecoderUtil, 0)
67
+ addMetric(mx, px+"encoder_utilization", gpu.Utilization.EncoderUtil, 0)
68
+ addMetric(mx, px+"frame_buffer_memory_usage_free", gpu.FBMemoryUsage.Free, 1024*1024) // MiB => bytes
69
+ addMetric(mx, px+"frame_buffer_memory_usage_used", gpu.FBMemoryUsage.Used, 1024*1024) // MiB => bytes
70
+ addMetric(mx, px+"frame_buffer_memory_usage_reserved", gpu.FBMemoryUsage.Reserved, 1024*1024) // MiB => bytes
71
+ addMetric(mx, px+"bar1_memory_usage_free", gpu.Bar1MemoryUsage.Free, 1024*1024) // MiB => bytes
72
+ addMetric(mx, px+"bar1_memory_usage_used", gpu.Bar1MemoryUsage.Used, 1024*1024) // MiB => bytes
73
+ addMetric(mx, px+"temperature", gpu.Temperature.GpuTemp, 0)
74
+ addMetric(mx, px+"graphics_clock", gpu.Clocks.GraphicsClock, 0)
75
+ addMetric(mx, px+"video_clock", gpu.Clocks.VideoClock, 0)
76
+ addMetric(mx, px+"sm_clock", gpu.Clocks.SmClock, 0)
77
+ addMetric(mx, px+"mem_clock", gpu.Clocks.MemClock, 0)
78
+ if gpu.PowerReadings != nil {
79
+ addMetric(mx, px+"power_draw", gpu.PowerReadings.PowerDraw, 0)
80
+ } else if gpu.GPUPowerReadings != nil {
81
+ addMetric(mx, px+"power_draw", gpu.GPUPowerReadings.PowerDraw, 0)
82
+ }
83
+ addMetric(mx, px+"voltage", gpu.Voltage.GraphicsVolt, 0)
84
+ for i := 0; i < 16; i++ {
85
+ s := "P" + strconv.Itoa(i)
86
+ mx[px+"performance_state_"+s] = boolToInt(gpu.PerformanceState == s)
87
+ }
88
+ if isValidValue(gpu.MIGMode.CurrentMIG) {
89
+ mode := strings.ToLower(gpu.MIGMode.CurrentMIG)
90
+ mx[px+"mig_current_mode_enabled"] = boolToInt(mode == "enabled")
91
+ mx[px+"mig_current_mode_disabled"] = boolToInt(mode == "disabled")
92
+ mx[px+"mig_devices_count"] = int64(len(gpu.MIGDevices.MIGDevice))
93
+ }
94
+
95
+ for _, mig := range gpu.MIGDevices.MIGDevice {
96
+ if !isValidValue(mig.GPUInstanceID) {
97
+ continue
98
+ }
99
+
100
+ px := "mig_instance_" + mig.GPUInstanceID + "_" + px
101
+
102
+ seenMIG[px] = true
103
+
104
+ if !nv.migs[px] {
105
+ nv.migs[px] = true
106
+ nv.addMIGDeviceCharts(gpu, mig)
107
+ }
108
+
109
+ addMetric(mx, px+"ecc_error_sram_uncorrectable", mig.ECCErrorCount.VolatileCount.SRAMUncorrectable, 0)
110
+ addMetric(mx, px+"frame_buffer_memory_usage_free", mig.FBMemoryUsage.Free, 1024*1024) // MiB => bytes
111
+ addMetric(mx, px+"frame_buffer_memory_usage_used", mig.FBMemoryUsage.Used, 1024*1024) // MiB => bytes
112
+ addMetric(mx, px+"frame_buffer_memory_usage_reserved", mig.FBMemoryUsage.Reserved, 1024*1024) // MiB => bytes
113
+ addMetric(mx, px+"bar1_memory_usage_free", mig.BAR1MemoryUsage.Free, 1024*1024) // MiB => bytes
114
+ addMetric(mx, px+"bar1_memory_usage_used", mig.BAR1MemoryUsage.Used, 1024*1024) // MiB => bytes
115
+ }
116
+ }
117
+
118
+ for px := range nv.gpus {
119
+ if !seenGPU[px] {
120
+ delete(nv.gpus, px)
121
+ nv.removeCharts(px)
122
+ }
123
+ }
124
+
125
+ for px := range nv.migs {
126
+ if !seenMIG[px] {
127
+ delete(nv.migs, px)
128
+ nv.removeCharts(px)
129
+ }
130
}
29
- return nv.collectGPUInfoXML(mx)
131
+
132
+ return nil
133
+}
134
+
135
+func calcMaxPCIEBandwidth(gpu gpuInfo) float64 {
136
+ gen := gpu.PCI.PCIGPULinkInfo.PCIEGen.MaxLinkGen
137
+ width := strings.TrimSuffix(gpu.PCI.PCIGPULinkInfo.LinkWidths.MaxLinkWidth, "x")
138
+
139
+ if !isValidValue(gen) || !isValidValue(width) {
140
+ return 0
141
+ }
142
+
143
+ // https://enterprise-support.nvidia.com/s/article/understanding-pcie-configuration-for-maximum-performance
144
+ var speed, enc float64
145
+ switch gen {
146
+ case "1":
147
+ speed, enc = 2.5, 1.0/5.0
148
+ case "2":
149
+ speed, enc = 5, 1.0/5.0
150
+ case "3":
151
+ speed, enc = 8, 2.0/130.0
152
+ case "4":
153
+ speed, enc = 16, 2.0/130.0
154
+ case "5":
155
+ speed, enc = 32, 2.0/130.0
156
+ default:
157
+ return 0
158
+ }
159
+
160
+ // Maximum PCIe Bandwidth = SPEED * WIDTH * (1 - ENCODING) - 1Gb/s
161
+ return (speed*parseFloat(width)*(1-enc) - 1) * 1e9 / 8 // Gb/s => bytes
162
}
163
164
func addMetric(mx map[string]int64, key, value string, mul int) {
src/go/plugin/go.d/modules/nvidia_smi/collect_csv.go
deleted
-198
@@ -1,198 +0,0 @@
1
-// SPDX-License-Identifier: GPL-3.0-or-later
2
-
3
-package nvidia_smi
4
-
5
-import (
6
- "bufio"
7
- "bytes"
8
- "encoding/csv"
9
- "errors"
10
- "fmt"
11
- "io"
12
- "regexp"
13
- "strconv"
14
- "strings"
15
-)
16
-
17
-// use of property aliases is not implemented ('"<property>" or "<alias>"' in help-query-gpu)
18
-var knownProperties = map[string]bool{
19
- "uuid": true,
20
- "name": true,
21
- "fan.speed": true,
22
- "pstate": true,
23
- "utilization.gpu": true,
24
- "utilization.memory": true,
25
- "memory.used": true,
26
- "memory.free": true,
27
- "memory.reserved": true,
28
- "temperature.gpu": true,
29
- "clocks.current.graphics": true,
30
- "clocks.current.video": true,
31
- "clocks.current.sm": true,
32
- "clocks.current.memory": true,
33
- "power.draw": true,
34
-}
35
-
36
-var reHelpProperty = regexp.MustCompile(`"([a-zA-Z_.]+)"`)
37
-
38
-func (nv *NvidiaSMI) collectGPUInfoCSV(mx map[string]int64) error {
39
- if len(nv.gpuQueryProperties) == 0 {
40
- bs, err := nv.exec.queryHelpQueryGPU()
41
- if err != nil {
42
- return err
43
- }
44
-
45
- sc := bufio.NewScanner(bytes.NewBuffer(bs))
46
-
47
- for sc.Scan() {
48
- if !strings.HasPrefix(sc.Text(), "\"") {
49
- continue
50
- }
51
- matches := reHelpProperty.FindAllString(sc.Text(), -1)
52
- if len(matches) == 0 {
53
- continue
54
- }
55
- for _, v := range matches {
56
- if v = strings.Trim(v, "\""); knownProperties[v] {
57
- nv.gpuQueryProperties = append(nv.gpuQueryProperties, v)
58
- }
59
- }
60
- }
61
- nv.Debugf("found query GPU properties: %v", nv.gpuQueryProperties)
62
- }
63
-
64
- bs, err := nv.exec.queryGPUInfoCSV(nv.gpuQueryProperties)
65
- if err != nil {
66
- return err
67
- }
68
-
69
- nv.Debugf("GPU info:\n%s", bs)
70
-
71
- r := csv.NewReader(bytes.NewBuffer(bs))
72
- r.Comma = ','
73
- r.ReuseRecord = true
74
- r.TrimLeadingSpace = true
75
-
76
- // skip headers
77
- if _, err := r.Read(); err != nil && err != io.EOF {
78
- return err
79
- }
80
-
81
- var gpusInfo []csvGPUInfo
82
- for {
83
- record, err := r.Read()
84
- if err != nil {
85
- if errors.Is(err, io.EOF) {
86
- break
87
- }
88
- return err
89
- }
90
-
91
- if len(record) != len(nv.gpuQueryProperties) {
92
- return fmt.Errorf("record values (%d) != queried properties (%d)", len(record), len(nv.gpuQueryProperties))
93
- }
94
-
95
- var gpu csvGPUInfo
96
- for i, v := range record {
97
- switch nv.gpuQueryProperties[i] {
98
- case "uuid":
99
- gpu.uuid = v
100
- case "name":
101
- gpu.name = v
102
- case "fan.speed":
103
- gpu.fanSpeed = v
104
- case "pstate":
105
- gpu.pstate = v
106
- case "utilization.gpu":
107
- gpu.utilizationGPU = v
108
- case "utilization.memory":
109
- gpu.utilizationMemory = v
110
- case "memory.used":
111
- gpu.memoryUsed = v
112
- case "memory.free":
113
- gpu.memoryFree = v
114
- case "memory.reserved":
115
- gpu.memoryReserved = v
116
- case "temperature.gpu":
117
- gpu.temperatureGPU = v
118
- case "clocks.current.graphics":
119
- gpu.clocksCurrentGraphics = v
120
- case "clocks.current.video":
121
- gpu.clocksCurrentVideo = v
122
- case "clocks.current.sm":
123
- gpu.clocksCurrentSM = v
124
- case "clocks.current.memory":
125
- gpu.clocksCurrentMemory = v
126
- case "power.draw":
127
- gpu.powerDraw = v
128
- }
129
- }
130
- gpusInfo = append(gpusInfo, gpu)
131
- }
132
-
133
- seen := make(map[string]bool)
134
-
135
- for _, gpu := range gpusInfo {
136
- if !isValidValue(gpu.uuid) || !isValidValue(gpu.name) {
137
- continue
138
- }
139
-
140
- px := "gpu_" + gpu.uuid + "_"
141
-
142
- seen[px] = true
143
-
144
- if !nv.gpus[px] {
145
- nv.gpus[px] = true
146
- nv.addGPUCSVCharts(gpu)
147
- }
148
-
149
- addMetric(mx, px+"fan_speed_perc", gpu.fanSpeed, 0)
150
- addMetric(mx, px+"gpu_utilization", gpu.utilizationGPU, 0)
151
- addMetric(mx, px+"mem_utilization", gpu.utilizationMemory, 0)
152
- addMetric(mx, px+"frame_buffer_memory_usage_free", gpu.memoryFree, 1024*1024) // MiB => bytes
153
- addMetric(mx, px+"frame_buffer_memory_usage_used", gpu.memoryUsed, 1024*1024) // MiB => bytes
154
- addMetric(mx, px+"frame_buffer_memory_usage_reserved", gpu.memoryReserved, 1024*1024) // MiB => bytes
155
- addMetric(mx, px+"temperature", gpu.temperatureGPU, 0)
156
- addMetric(mx, px+"graphics_clock", gpu.clocksCurrentGraphics, 0)
157
- addMetric(mx, px+"video_clock", gpu.clocksCurrentVideo, 0)
158
- addMetric(mx, px+"sm_clock", gpu.clocksCurrentSM, 0)
159
- addMetric(mx, px+"mem_clock", gpu.clocksCurrentMemory, 0)
160
- addMetric(mx, px+"power_draw", gpu.powerDraw, 0)
161
- for i := 0; i < 16; i++ {
162
- if s := "P" + strconv.Itoa(i); gpu.pstate == s {
163
- mx[px+"performance_state_"+s] = 1
164
- } else {
165
- mx[px+"performance_state_"+s] = 0
166
- }
167
- }
168
- }
169
-
170
- for px := range nv.gpus {
171
- if !seen[px] {
172
- delete(nv.gpus, px)
173
- nv.removeCharts(px)
174
- }
175
- }
176
-
177
- return nil
178
-}
179
-
180
-type (
181
- csvGPUInfo struct {
182
- uuid string
183
- name string
184
- fanSpeed string
185
- pstate string
186
- utilizationGPU string
187
- utilizationMemory string
188
- memoryUsed string
189
- memoryFree string
190
- memoryReserved string
191
- temperatureGPU string
192
- clocksCurrentGraphics string
193
- clocksCurrentVideo string
194
- clocksCurrentSM string
195
- clocksCurrentMemory string
196
- powerDraw string
197
- }
198
-)
src/go/plugin/go.d/modules/nvidia_smi/collect_xml.go
deleted
-265
@@ -1,265 +0,0 @@
1
-// SPDX-License-Identifier: GPL-3.0-or-later
2
-
3
-package nvidia_smi
4
-
5
-import (
6
- "encoding/xml"
7
- "fmt"
8
- "strconv"
9
- "strings"
10
-)
11
-
12
-func (nv *NvidiaSMI) collectGPUInfoXML(mx map[string]int64) error {
13
- bs, err := nv.exec.queryGPUInfoXML()
14
- if err != nil {
15
- return fmt.Errorf("error on quering XML GPU info: %v", err)
16
- }
17
-
18
- info := &xmlInfo{}
19
- if err := xml.Unmarshal(bs, info); err != nil {
20
- return fmt.Errorf("error on unmarshaling XML GPU info response: %v", err)
21
- }
22
-
23
- seenGPU := make(map[string]bool)
24
- seenMIG := make(map[string]bool)
25
-
26
- for _, gpu := range info.GPUs {
27
- if !isValidValue(gpu.UUID) {
28
- continue
29
- }
30
-
31
- px := "gpu_" + gpu.UUID + "_"
32
-
33
- seenGPU[px] = true
34
-
35
- if !nv.gpus[px] {
36
- nv.gpus[px] = true
37
- nv.addGPUXMLCharts(gpu)
38
- }
39
-
40
- addMetric(mx, px+"pcie_bandwidth_usage_rx", gpu.PCI.RxUtil, 1024) // KB => bytes
41
- addMetric(mx, px+"pcie_bandwidth_usage_tx", gpu.PCI.TxUtil, 1024) // KB => bytes
42
- if max := calcMaxPCIEBandwidth(gpu); max > 0 {
43
- rx := parseFloat(gpu.PCI.RxUtil) * 1024 // KB => bytes
44
- tx := parseFloat(gpu.PCI.TxUtil) * 1024 // KB => bytes
45
- mx[px+"pcie_bandwidth_utilization_rx"] = int64((rx * 100 / max) * 100)
46
- mx[px+"pcie_bandwidth_utilization_tx"] = int64((tx * 100 / max) * 100)
47
- }
48
- addMetric(mx, px+"fan_speed_perc", gpu.FanSpeed, 0)
49
- addMetric(mx, px+"gpu_utilization", gpu.Utilization.GpuUtil, 0)
50
- addMetric(mx, px+"mem_utilization", gpu.Utilization.MemoryUtil, 0)
51
- addMetric(mx, px+"decoder_utilization", gpu.Utilization.DecoderUtil, 0)
52
- addMetric(mx, px+"encoder_utilization", gpu.Utilization.EncoderUtil, 0)
53
- addMetric(mx, px+"frame_buffer_memory_usage_free", gpu.FBMemoryUsage.Free, 1024*1024) // MiB => bytes
54
- addMetric(mx, px+"frame_buffer_memory_usage_used", gpu.FBMemoryUsage.Used, 1024*1024) // MiB => bytes
55
- addMetric(mx, px+"frame_buffer_memory_usage_reserved", gpu.FBMemoryUsage.Reserved, 1024*1024) // MiB => bytes
56
- addMetric(mx, px+"bar1_memory_usage_free", gpu.Bar1MemoryUsage.Free, 1024*1024) // MiB => bytes
57
- addMetric(mx, px+"bar1_memory_usage_used", gpu.Bar1MemoryUsage.Used, 1024*1024) // MiB => bytes
58
- addMetric(mx, px+"temperature", gpu.Temperature.GpuTemp, 0)
59
- addMetric(mx, px+"graphics_clock", gpu.Clocks.GraphicsClock, 0)
60
- addMetric(mx, px+"video_clock", gpu.Clocks.VideoClock, 0)
61
- addMetric(mx, px+"sm_clock", gpu.Clocks.SmClock, 0)
62
- addMetric(mx, px+"mem_clock", gpu.Clocks.MemClock, 0)
63
- if gpu.PowerReadings != nil {
64
- addMetric(mx, px+"power_draw", gpu.PowerReadings.PowerDraw, 0)
65
- } else if gpu.GPUPowerReadings != nil {
66
- addMetric(mx, px+"power_draw", gpu.GPUPowerReadings.PowerDraw, 0)
67
- }
68
- addMetric(mx, px+"voltage", gpu.Voltage.GraphicsVolt, 0)
69
- for i := 0; i < 16; i++ {
70
- s := "P" + strconv.Itoa(i)
71
- mx[px+"performance_state_"+s] = boolToInt(gpu.PerformanceState == s)
72
- }
73
- if isValidValue(gpu.MIGMode.CurrentMIG) {
74
- mode := strings.ToLower(gpu.MIGMode.CurrentMIG)
75
- mx[px+"mig_current_mode_enabled"] = boolToInt(mode == "enabled")
76
- mx[px+"mig_current_mode_disabled"] = boolToInt(mode == "disabled")
77
- mx[px+"mig_devices_count"] = int64(len(gpu.MIGDevices.MIGDevice))
78
- }
79
-
80
- for _, mig := range gpu.MIGDevices.MIGDevice {
81
- if !isValidValue(mig.GPUInstanceID) {
82
- continue
83
- }
84
-
85
- px := "mig_instance_" + mig.GPUInstanceID + "_" + px
86
-
87
- seenMIG[px] = true
88
-
89
- if !nv.migs[px] {
90
- nv.migs[px] = true
91
- nv.addMIGDeviceXMLCharts(gpu, mig)
92
- }
93
-
94
- addMetric(mx, px+"ecc_error_sram_uncorrectable", mig.ECCErrorCount.VolatileCount.SRAMUncorrectable, 0)
95
- addMetric(mx, px+"frame_buffer_memory_usage_free", mig.FBMemoryUsage.Free, 1024*1024) // MiB => bytes
96
- addMetric(mx, px+"frame_buffer_memory_usage_used", mig.FBMemoryUsage.Used, 1024*1024) // MiB => bytes
97
- addMetric(mx, px+"frame_buffer_memory_usage_reserved", mig.FBMemoryUsage.Reserved, 1024*1024) // MiB => bytes
98
- addMetric(mx, px+"bar1_memory_usage_free", mig.BAR1MemoryUsage.Free, 1024*1024) // MiB => bytes
99
- addMetric(mx, px+"bar1_memory_usage_used", mig.BAR1MemoryUsage.Used, 1024*1024) // MiB => bytes
100
- }
101
- }
102
-
103
- for px := range nv.gpus {
104
- if !seenGPU[px] {
105
- delete(nv.gpus, px)
106
- nv.removeCharts(px)
107
- }
108
- }
109
-
110
- for px := range nv.migs {
111
- if !seenMIG[px] {
112
- delete(nv.migs, px)
113
- nv.removeCharts(px)
114
- }
115
- }
116
-
117
- return nil
118
-}
119
-
120
-func calcMaxPCIEBandwidth(gpu xmlGPUInfo) float64 {
121
- gen := gpu.PCI.PCIGPULinkInfo.PCIEGen.MaxLinkGen
122
- width := strings.TrimSuffix(gpu.PCI.PCIGPULinkInfo.LinkWidths.MaxLinkWidth, "x")
123
-
124
- if !isValidValue(gen) || !isValidValue(width) {
125
- return 0
126
- }
127
-
128
- // https://enterprise-support.nvidia.com/s/article/understanding-pcie-configuration-for-maximum-performance
129
- var speed, enc float64
130
- switch gen {
131
- case "1":
132
- speed, enc = 2.5, 1.0/5.0
133
- case "2":
134
- speed, enc = 5, 1.0/5.0
135
- case "3":
136
- speed, enc = 8, 2.0/130.0
137
- case "4":
138
- speed, enc = 16, 2.0/130.0
139
- case "5":
140
- speed, enc = 32, 2.0/130.0
141
- default:
142
- return 0
143
- }
144
-
145
- // Maximum PCIe Bandwidth = SPEED * WIDTH * (1 - ENCODING) - 1Gb/s
146
- return (speed*parseFloat(width)*(1-enc) - 1) * 1e9 / 8 // Gb/s => bytes
147
-}
148
-
149
-type (
150
- xmlInfo struct {
151
- GPUs []xmlGPUInfo `xml:"gpu"`
152
- }
153
- xmlGPUInfo struct {
154
- ID string `xml:"id,attr"`
155
- ProductName string `xml:"product_name"`
156
- ProductBrand string `xml:"product_brand"`
157
- ProductArchitecture string `xml:"product_architecture"`
158
- UUID string `xml:"uuid"`
159
- FanSpeed string `xml:"fan_speed"`
160
- PerformanceState string `xml:"performance_state"`
161
- MIGMode struct {
162
- CurrentMIG string `xml:"current_mig"`
163
- } `xml:"mig_mode"`
164
- MIGDevices struct {
165
- MIGDevice []xmlMIGDeviceInfo `xml:"mig_device"`
166
- } `xml:"mig_devices"`
167
- PCI struct {
168
- TxUtil string `xml:"tx_util"`
169
- RxUtil string `xml:"rx_util"`
170
- PCIGPULinkInfo struct {
171
- PCIEGen struct {
172
- MaxLinkGen string `xml:"max_link_gen"`
173
- } `xml:"pcie_gen"`
174
- LinkWidths struct {
175
- MaxLinkWidth string `xml:"max_link_width"`
176
- } `xml:"link_widths"`
177
- } `xml:"pci_gpu_link_info"`
178
- } `xml:"pci"`
179
- Utilization struct {
180
- GpuUtil string `xml:"gpu_util"`
181
- MemoryUtil string `xml:"memory_util"`
182
- EncoderUtil string `xml:"encoder_util"`
183
- DecoderUtil string `xml:"decoder_util"`
184
- } `xml:"utilization"`
185
- FBMemoryUsage struct {
186
- Total string `xml:"total"`
187
- Reserved string `xml:"reserved"`
188
- Used string `xml:"used"`
189
- Free string `xml:"free"`
190
- } `xml:"fb_memory_usage"`
191
- Bar1MemoryUsage struct {
192
- Total string `xml:"total"`
193
- Used string `xml:"used"`
194
- Free string `xml:"free"`
195
- } `xml:"bar1_memory_usage"`
196
- Temperature struct {
197
- GpuTemp string `xml:"gpu_temp"`
198
- GpuTempMaxThreshold string `xml:"gpu_temp_max_threshold"`
199
- GpuTempSlowThreshold string `xml:"gpu_temp_slow_threshold"`
200
- GpuTempMaxGpuThreshold string `xml:"gpu_temp_max_gpu_threshold"`
201
- GpuTargetTemperature string `xml:"gpu_target_temperature"`
202
- MemoryTemp string `xml:"memory_temp"`
203
- GpuTempMaxMemThreshold string `xml:"gpu_temp_max_mem_threshold"`
204
- } `xml:"temperature"`
205
- Clocks struct {
206
- GraphicsClock string `xml:"graphics_clock"`
207
- SmClock string `xml:"sm_clock"`
208
- MemClock string `xml:"mem_clock"`
209
- VideoClock string `xml:"video_clock"`
210
- } `xml:"clocks"`
211
- PowerReadings *xmlPowerReadings `xml:"power_readings"`
212
- GPUPowerReadings *xmlPowerReadings `xml:"gpu_power_readings"`
213
- Voltage struct {
214
- GraphicsVolt string `xml:"graphics_volt"`
215
- } `xml:"voltage"`
216
- Processes struct {
217
- ProcessInfo []struct {
218
- PID string `xml:"pid"`
219
- ProcessName string `xml:"process_name"`
220
- UsedMemory string `xml:"used_memory"`
221
- } `sml:"process_info"`
222
- } `xml:"processes"`
223
- }
224
-
225
- xmlPowerReadings struct {
226
- //PowerState string `xml:"power_state"`
227
- //PowerManagement string `xml:"power_management"`
228
- PowerDraw string `xml:"power_draw"`
229
- //PowerLimit string `xml:"power_limit"`
230
- //DefaultPowerLimit string `xml:"default_power_limit"`
231
- //EnforcedPowerLimit string `xml:"enforced_power_limit"`
232
- //MinPowerLimit string `xml:"min_power_limit"`
233
- //MaxPowerLimit string `xml:"max_power_limit"`
234
- }
235
-
236
- xmlMIGDeviceInfo struct {
237
- Index string `xml:"index"`
238
- GPUInstanceID string `xml:"gpu_instance_id"`
239
- ComputeInstanceID string `xml:"compute_instance_id"`
240
- DeviceAttributes struct {
241
- Shared struct {
242
- MultiprocessorCount string `xml:"multiprocessor_count"`
243
- CopyEngineCount string `xml:"copy_engine_count"`
244
- EncoderCount string `xml:"encoder_count"`
245
- DecoderCount string `xml:"decoder_count"`
246
- OFACount string `xml:"ofa_count"`
247
- JPGCount string `xml:"jpg_count"`
248
- } `xml:"shared"`
249
- } `xml:"device_attributes"`
250
- ECCErrorCount struct {
251
- VolatileCount struct {
252
- SRAMUncorrectable string `xml:"sram_uncorrectable"`
253
- } `xml:"volatile_count"`
254
- } `xml:"ecc_error_count"`
255
- FBMemoryUsage struct {
256
- Free string `xml:"free"`
257
- Used string `xml:"used"`
258
- Reserved string `xml:"reserved"`
259
- } `xml:"fb_memory_usage"`
260
- BAR1MemoryUsage struct {
261
- Free string `xml:"free"`
262
- Used string `xml:"used"`
263
- } `xml:"bar1_memory_usage"`
264
- }
265
-)
src/go/plugin/go.d/modules/nvidia_smi/config_schema.json
-6
@@ -23,12 +23,6 @@
23
"type": "number",
24
"minimum": 0.5,
25
"default": 10
26
- },
27
- "use_csv_format": {
28
- "title": "Use CSV format",
29
- "description": "Determines the format used for requesting GPU information. If set, CSV format is used, otherwise XML.",
30
- "type": "boolean",
31
- "default": false
26
}
27
},
28
"required": [
src/go/plugin/go.d/modules/nvidia_smi/exec.go
+11
-43
@@ -4,30 +4,33 @@ package nvidia_smi
4
5
import (
6
"context"
7
- "errors"
7
"fmt"
8
"os/exec"
10
- "strings"
9
"time"
10
11
"github.com/netdata/netdata/go/plugins/logger"
12
)
13
16
-func newNvidiaSMIExec(path string, cfg Config, log *logger.Logger) (*nvidiaSMIExec, error) {
17
- return &nvidiaSMIExec{
14
+type nvidiaSmiBinary interface {
15
+ queryGPUInfo() ([]byte, error)
16
+}
17
+
18
+func newNvidiaSmiExec(path string, cfg Config, log *logger.Logger) (*nvidiaSmiExec, error) {
19
+ return &nvidiaSmiExec{
20
+ Logger: log,
21
binPath: path,
22
timeout: cfg.Timeout.Duration(),
20
- Logger: log,
23
}, nil
24
}
25
24
-type nvidiaSMIExec struct {
26
+type nvidiaSmiExec struct {
27
+ *logger.Logger
28
+
29
binPath string
30
timeout time.Duration
27
- *logger.Logger
31
}
32
30
-func (e *nvidiaSMIExec) queryGPUInfoXML() ([]byte, error) {
33
+func (e *nvidiaSmiExec) queryGPUInfo() ([]byte, error) {
34
ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
35
defer cancel()
36
@@ -41,38 +44,3 @@ func (e *nvidiaSMIExec) queryGPUInfoXML() ([]byte, error) {
44
45
return bs, nil
46
}
44
-
45
-func (e *nvidiaSMIExec) queryGPUInfoCSV(properties []string) ([]byte, error) {
46
- if len(properties) == 0 {
47
- return nil, errors.New("can not query CSV GPU Info without properties")
48
- }
49
-
50
- ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
51
- defer cancel()
52
-
53
- cmd := exec.CommandContext(ctx, e.binPath, "--query-gpu="+strings.Join(properties, ","), "--format=csv,nounits")
54
-
55
- e.Debugf("executing '%s'", cmd)
56
-
57
- bs, err := cmd.Output()
58
- if err != nil {
59
- return nil, fmt.Errorf("error on '%s': %v", cmd, err)
60
- }
61
-
62
- return bs, nil
63
-}
64
-
65
-func (e *nvidiaSMIExec) queryHelpQueryGPU() ([]byte, error) {
66
- ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
67
- defer cancel()
68
-
69
- cmd := exec.CommandContext(ctx, e.binPath, "--help-query-gpu")
70
-
71
- e.Debugf("executing '%s'", cmd)
72
- bs, err := cmd.Output()
73
- if err != nil {
74
- return nil, fmt.Errorf("error on '%s': %v", cmd, err)
75
- }
76
-
77
- return bs, err
78
-}
src/go/plugin/go.d/modules/nvidia_smi/gpu_info.go
new
+121
@@ -0,0 +1,121 @@
1
+// SPDX-License-Identifier: GPL-3.0-or-later
2
+
3
+package nvidia_smi
4
+
5
+type gpusInfo struct {
6
+ GPUs []gpuInfo `xml:"gpu"`
7
+}
8
+
9
+type (
10
+ gpuInfo struct {
11
+ ID string `xml:"id,attr"`
12
+ ProductName string `xml:"product_name"`
13
+ ProductBrand string `xml:"product_brand"`
14
+ ProductArchitecture string `xml:"product_architecture"`
15
+ UUID string `xml:"uuid"`
16
+ FanSpeed string `xml:"fan_speed"`
17
+ PerformanceState string `xml:"performance_state"`
18
+ MIGMode struct {
19
+ CurrentMIG string `xml:"current_mig"`
20
+ } `xml:"mig_mode"`
21
+ MIGDevices struct {
22
+ MIGDevice []gpuMIGDeviceInfo `xml:"mig_device"`
23
+ } `xml:"mig_devices"`
24
+ PCI struct {
25
+ TxUtil string `xml:"tx_util"`
26
+ RxUtil string `xml:"rx_util"`
27
+ PCIGPULinkInfo struct {
28
+ PCIEGen struct {
29
+ MaxLinkGen string `xml:"max_link_gen"`
30
+ } `xml:"pcie_gen"`
31
+ LinkWidths struct {
32
+ MaxLinkWidth string `xml:"max_link_width"`
33
+ } `xml:"link_widths"`
34
+ } `xml:"pci_gpu_link_info"`
35
+ } `xml:"pci"`
36
+ Utilization struct {
37
+ GpuUtil string `xml:"gpu_util"`
38
+ MemoryUtil string `xml:"memory_util"`
39
+ EncoderUtil string `xml:"encoder_util"`
40
+ DecoderUtil string `xml:"decoder_util"`
41
+ } `xml:"utilization"`
42
+ FBMemoryUsage struct {
43
+ Total string `xml:"total"`
44
+ Reserved string `xml:"reserved"`
45
+ Used string `xml:"used"`
46
+ Free string `xml:"free"`
47
+ } `xml:"fb_memory_usage"`
48
+ Bar1MemoryUsage struct {
49
+ Total string `xml:"total"`
50
+ Used string `xml:"used"`
51
+ Free string `xml:"free"`
52
+ } `xml:"bar1_memory_usage"`
53
+ Temperature struct {
54
+ GpuTemp string `xml:"gpu_temp"`
55
+ GpuTempMaxThreshold string `xml:"gpu_temp_max_threshold"`
56
+ GpuTempSlowThreshold string `xml:"gpu_temp_slow_threshold"`
57
+ GpuTempMaxGpuThreshold string `xml:"gpu_temp_max_gpu_threshold"`
58
+ GpuTargetTemperature string `xml:"gpu_target_temperature"`
59
+ MemoryTemp string `xml:"memory_temp"`
60
+ GpuTempMaxMemThreshold string `xml:"gpu_temp_max_mem_threshold"`
61
+ } `xml:"temperature"`
62
+ Clocks struct {
63
+ GraphicsClock string `xml:"graphics_clock"`
64
+ SmClock string `xml:"sm_clock"`
65
+ MemClock string `xml:"mem_clock"`
66
+ VideoClock string `xml:"video_clock"`
67
+ } `xml:"clocks"`
68
+ PowerReadings *gpuPowerReadings `xml:"power_readings"`
69
+ GPUPowerReadings *gpuPowerReadings `xml:"gpu_power_readings"`
70
+ Voltage struct {
71
+ GraphicsVolt string `xml:"graphics_volt"`
72
+ } `xml:"voltage"`
73
+ Processes struct {
74
+ ProcessInfo []struct {
75
+ PID string `xml:"pid"`
76
+ ProcessName string `xml:"process_name"`
77
+ UsedMemory string `xml:"used_memory"`
78
+ } `sml:"process_info"`
79
+ } `xml:"processes"`
80
+ }
81
+ gpuPowerReadings struct {
82
+ //PowerState string `xml:"power_state"`
83
+ //PowerManagement string `xml:"power_management"`
84
+ PowerDraw string `xml:"power_draw"`
85
+ //PowerLimit string `xml:"power_limit"`
86
+ //DefaultPowerLimit string `xml:"default_power_limit"`
87
+ //EnforcedPowerLimit string `xml:"enforced_power_limit"`
88
+ //MinPowerLimit string `xml:"min_power_limit"`
89
+ //MaxPowerLimit string `xml:"max_power_limit"`
90
+ }
91
+
92
+ gpuMIGDeviceInfo struct {
93
+ Index string `xml:"index"`
94
+ GPUInstanceID string `xml:"gpu_instance_id"`
95
+ ComputeInstanceID string `xml:"compute_instance_id"`
96
+ DeviceAttributes struct {
97
+ Shared struct {
98
+ MultiprocessorCount string `xml:"multiprocessor_count"`
99
+ CopyEngineCount string `xml:"copy_engine_count"`
100
+ EncoderCount string `xml:"encoder_count"`
101
+ DecoderCount string `xml:"decoder_count"`
102
+ OFACount string `xml:"ofa_count"`
103
+ JPGCount string `xml:"jpg_count"`
104
+ } `xml:"shared"`
105
+ } `xml:"device_attributes"`
106
+ ECCErrorCount struct {
107
+ VolatileCount struct {
108
+ SRAMUncorrectable string `xml:"sram_uncorrectable"`
109
+ } `xml:"volatile_count"`
110
+ } `xml:"ecc_error_count"`
111
+ FBMemoryUsage struct {
112
+ Free string `xml:"free"`
113
+ Used string `xml:"used"`
114
+ Reserved string `xml:"reserved"`
115
+ } `xml:"fb_memory_usage"`
116
+ BAR1MemoryUsage struct {
117
+ Free string `xml:"free"`
118
+ Used string `xml:"used"`
119
+ } `xml:"bar1_memory_usage"`
120
+ }
121
+)
src/go/plugin/go.d/modules/nvidia_smi/init.go
+2
-2
@@ -8,7 +8,7 @@ import (
8
"os/exec"
9
)
10
11
-func (nv *NvidiaSMI) initNvidiaSMIExec() (nvidiaSMI, error) {
11
+func (nv *NvidiaSmi) initNvidiaSmiExec() (nvidiaSmiBinary, error) {
12
binPath := nv.BinaryPath
13
if _, err := os.Stat(binPath); os.IsNotExist(err) {
14
path, err := exec.LookPath(nv.binName)
@@ -18,5 +18,5 @@ func (nv *NvidiaSMI) initNvidiaSMIExec() (nvidiaSMI, error) {
18
binPath = path
19
}
20
21
- return newNvidiaSMIExec(binPath, nv.Config, nv.Logger)
21
+ return newNvidiaSmiExec(binPath, nv.Config, nv.Logger)
22
}
src/go/plugin/go.d/modules/nvidia_smi/metadata.yaml
+1
-62
@@ -73,26 +73,11 @@ modules:
73
description: nvidia_smi binary execution timeout.
74
default_value: 2
75
required: false
76
- - name: use_csv_format
77
- description: Used format when requesting GPU information. XML is used if set to 'no'.
78
- default_value: false
79
- required: false
80
- details: |
81
- This module supports data collection in CSV and XML formats. The default is XML.
82
-
83
- - XML provides more metrics, but requesting GPU information consumes more CPU, especially if there are multiple GPUs in the system.
84
- - CSV provides fewer metrics, but is much lighter than XML in terms of CPU usage.
76
examples:
77
folding:
78
title: Config
79
enabled: true
80
list:
90
- - name: CSV format
91
- description: Use CSV format when requesting GPU information.
92
- config: |
93
- jobs:
94
- - name: nvidia_smi
95
- use_csv_format: yes
81
- name: Custom binary path
82
description: The executable is not in the directories specified in the PATH environment variable.
83
config: |
@@ -108,9 +93,7 @@ modules:
93
title: Metrics
94
enabled: false
95
description: ""
111
- availability:
112
- - XML
113
- - CSV
96
+ availability: []
97
scopes:
98
- name: gpu
99
description: These metrics refer to the GPU.
@@ -121,8 +104,6 @@ modules:
104
description: GPU product name (e.g. NVIDIA A100-SXM4-40GB)
105
metrics:
106
- name: nvidia_smi.gpu_pcie_bandwidth_usage
124
- availability:
125
- - XML
107
description: PCI Express Bandwidth Usage
108
unit: B/s
109
chart_type: line
@@ -130,8 +111,6 @@ modules:
111
- name: rx
112
- name: tx
113
- name: nvidia_smi.gpu_pcie_bandwidth_utilization
133
- availability:
134
- - XML
114
description: PCI Express Bandwidth Utilization
115
unit: '%'
116
chart_type: line
@@ -139,52 +118,36 @@ modules:
118
- name: rx
119
- name: tx
120
- name: nvidia_smi.gpu_fan_speed_perc
142
- availability:
143
- - XML
144
- - CSV
121
description: Fan speed
122
unit: '%'
123
chart_type: line
124
dimensions:
125
- name: fan_speed
126
- name: nvidia_smi.gpu_utilization
151
- availability:
152
- - XML
153
- - CSV
127
description: GPU utilization
128
unit: '%'
129
chart_type: line
130
dimensions:
131
- name: gpu
132
- name: nvidia_smi.gpu_memory_utilization
160
- availability:
161
- - XML
162
- - CSV
133
description: Memory utilization
134
unit: '%'
135
chart_type: line
136
dimensions:
137
- name: memory
138
- name: nvidia_smi.gpu_decoder_utilization
169
- availability:
170
- - XML
139
description: Decoder utilization
140
unit: '%'
141
chart_type: line
142
dimensions:
143
- name: decoder
144
- name: nvidia_smi.gpu_encoder_utilization
177
- availability:
178
- - XML
145
description: Encoder utilization
146
unit: '%'
147
chart_type: line
148
dimensions:
149
- name: encoder
150
- name: nvidia_smi.gpu_frame_buffer_memory_usage
185
- availability:
186
- - XML
187
- - CSV
151
description: Frame buffer memory usage
152
unit: B
153
chart_type: stacked
@@ -193,8 +156,6 @@ modules:
156
- name: used
157
- name: reserved
158
- name: nvidia_smi.gpu_bar1_memory_usage
196
- availability:
197
- - XML
159
description: BAR1 memory usage
160
unit: B
161
chart_type: stacked
@@ -202,26 +163,18 @@ modules:
163
- name: free
164
- name: used
165
- name: nvidia_smi.gpu_temperature
205
- availability:
206
- - XML
207
- - CSV
166
description: Temperature
167
unit: Celsius
168
chart_type: line
169
dimensions:
170
- name: temperature
171
- name: nvidia_smi.gpu_voltage
214
- availability:
215
- - XML
172
description: Voltage
173
unit: V
174
chart_type: line
175
dimensions:
176
- name: voltage
177
- name: nvidia_smi.gpu_clock_freq
222
- availability:
223
- - XML
224
- - CSV
178
description: Clock current frequency
179
unit: MHz
180
chart_type: line
@@ -231,26 +184,18 @@ modules:
184
- name: sm
185
- name: mem
186
- name: nvidia_smi.gpu_power_draw
234
- availability:
235
- - XML
236
- - CSV
187
description: Power draw
188
unit: Watts
189
chart_type: line
190
dimensions:
191
- name: power_draw
192
- name: nvidia_smi.gpu_performance_state
243
- availability:
244
- - XML
245
- - CSV
193
description: Performance state
194
unit: state
195
chart_type: line
196
dimensions:
197
- name: P0-P15
198
- name: nvidia_smi.gpu_mig_mode_current_status
252
- availability:
253
- - XML
199
description: MIG current mode
200
unit: status
201
chart_type: line
@@ -258,8 +203,6 @@ modules:
203
- name: enabled
204
- name: disabled
205
- name: nvidia_smi.gpu_mig_devices_count
261
- availability:
262
- - XML
206
description: MIG devices
207
unit: devices
208
chart_type: line
@@ -276,8 +219,6 @@ modules:
219
description: GPU instance id (e.g. 1)
220
metrics:
221
- name: nvidia_smi.gpu_mig_frame_buffer_memory_usage
279
- availability:
280
- - XML
222
description: Frame buffer memory usage
223
unit: B
224
chart_type: stacked
@@ -286,8 +227,6 @@ modules:
227
- name: used
228
- name: reserved
229
- name: nvidia_smi.gpu_mig_bar1_memory_usage
289
- availability:
290
- - XML
230
description: BAR1 memory usage
231
unit: B
232
chart_type: stacked
src/go/plugin/go.d/modules/nvidia_smi/nvidia_smi.go
+22
-33
@@ -26,11 +26,10 @@ func init() {
26
})
27
}
28
29
-func New() *NvidiaSMI {
30
- return &NvidiaSMI{
29
+func New() *NvidiaSmi {
30
+ return &NvidiaSmi{
31
Config: Config{
32
- Timeout: web.Duration(time.Second * 10),
33
- UseCSVFormat: false,
32
+ Timeout: web.Duration(time.Second * 10),
33
},
34
binName: "nvidia-smi",
35
charts: &module.Charts{},
@@ -41,41 +40,31 @@ func New() *NvidiaSMI {
40
}
41
42
type Config struct {
44
- UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
45
- Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
46
- BinaryPath string `yaml:"binary_path" json:"binary_path"`
47
- UseCSVFormat bool `yaml:"use_csv_format" json:"use_csv_format"`
43
+ UpdateEvery int `yaml:"update_every,omitempty" json:"update_every"`
44
+ Timeout web.Duration `yaml:"timeout,omitempty" json:"timeout"`
45
+ BinaryPath string `yaml:"binary_path" json:"binary_path"`
46
}
47
50
-type (
51
- NvidiaSMI struct {
52
- module.Base
53
- Config `yaml:",inline" json:""`
48
+type NvidiaSmi struct {
49
+ module.Base
50
+ Config `yaml:",inline" json:""`
51
55
- charts *module.Charts
52
+ charts *module.Charts
53
57
- exec nvidiaSMI
58
- binName string
54
+ exec nvidiaSmiBinary
55
+ binName string
56
60
- gpuQueryProperties []string
61
-
62
- gpus map[string]bool
63
- migs map[string]bool
64
- }
65
- nvidiaSMI interface {
66
- queryGPUInfoXML() ([]byte, error)
67
- queryGPUInfoCSV(properties []string) ([]byte, error)
68
- queryHelpQueryGPU() ([]byte, error)
69
- }
70
-)
57
+ gpus map[string]bool
58
+ migs map[string]bool
59
+}
60
72
-func (nv *NvidiaSMI) Configuration() any {
61
+func (nv *NvidiaSmi) Configuration() any {
62
return nv.Config
63
}
64
76
-func (nv *NvidiaSMI) Init() error {
65
+func (nv *NvidiaSmi) Init() error {
66
if nv.exec == nil {
78
- smi, err := nv.initNvidiaSMIExec()
67
+ smi, err := nv.initNvidiaSmiExec()
68
if err != nil {
69
nv.Error(err)
70
return err
@@ -86,7 +75,7 @@ func (nv *NvidiaSMI) Init() error {
75
return nil
76
}
77
89
-func (nv *NvidiaSMI) Check() error {
78
+func (nv *NvidiaSmi) Check() error {
79
mx, err := nv.collect()
80
if err != nil {
81
nv.Error(err)
@@ -98,11 +87,11 @@ func (nv *NvidiaSMI) Check() error {
87
return nil
88
}
89
101
-func (nv *NvidiaSMI) Charts() *module.Charts {
90
+func (nv *NvidiaSmi) Charts() *module.Charts {
91
return nv.charts
92
}
93
105
-func (nv *NvidiaSMI) Collect() map[string]int64 {
94
+func (nv *NvidiaSmi) Collect() map[string]int64 {
95
mx, err := nv.collect()
96
if err != nil {
97
nv.Error(err)
@@ -114,4 +103,4 @@ func (nv *NvidiaSMI) Collect() map[string]int64 {
103
return mx
104
}
105
117
-func (nv *NvidiaSMI) Cleanup() {}
106
+func (nv *NvidiaSmi) Cleanup() {}
src/go/plugin/go.d/modules/nvidia_smi/nvidia_smi_test.go
+58
-176
@@ -24,9 +24,6 @@ var (
24
dataXMLTeslaP100, _ = os.ReadFile("testdata/tesla-p100.xml")
25
26
dataXMLA100SXM4MIG, _ = os.ReadFile("testdata/a100-sxm4-mig.xml")
27
-
28
- dataHelpQueryGPU, _ = os.ReadFile("testdata/help-query-gpu.txt")
29
- dataCSVTeslaP100, _ = os.ReadFile("testdata/tesla-p100.csv")
27
)
28
29
func Test_testDataIsValid(t *testing.T) {
@@ -38,25 +35,23 @@ func Test_testDataIsValid(t *testing.T) {
35
"dataXMLRTX3060": dataXMLRTX3060,
36
"dataXMLTeslaP100": dataXMLTeslaP100,
37
"dataXMLA100SXM4MIG": dataXMLA100SXM4MIG,
41
- "dataHelpQueryGPU": dataHelpQueryGPU,
42
- "dataCSVTeslaP100": dataCSVTeslaP100,
38
} {
39
require.NotNil(t, data, name)
40
}
41
}
42
48
-func TestNvidiaSMI_ConfigurationSerialize(t *testing.T) {
49
- module.TestConfigurationSerialize(t, &NvidiaSMI{}, dataConfigJSON, dataConfigYAML)
43
+func TestNvidiaSmi_ConfigurationSerialize(t *testing.T) {
44
+ module.TestConfigurationSerialize(t, &NvidiaSmi{}, dataConfigJSON, dataConfigYAML)
45
}
46
52
-func TestNvidiaSMI_Init(t *testing.T) {
47
+func TestNvidiaSmi_Init(t *testing.T) {
48
tests := map[string]struct {
54
- prepare func(nv *NvidiaSMI)
49
+ prepare func(nv *NvidiaSmi)
50
wantFail bool
51
}{
52
"fails if can't local nvidia-smi": {
53
wantFail: true,
59
- prepare: func(nv *NvidiaSMI) {
54
+ prepare: func(nv *NvidiaSmi) {
55
nv.binName += "!!!"
56
},
57
},
@@ -77,46 +72,34 @@ func TestNvidiaSMI_Init(t *testing.T) {
72
}
73
}
74
80
-func TestNvidiaSMI_Charts(t *testing.T) {
75
+func TestNvidiaSmi_Charts(t *testing.T) {
76
assert.NotNil(t, New().Charts())
77
}
78
84
-func TestNvidiaSMI_Check(t *testing.T) {
79
+func TestNvidiaSmi_Check(t *testing.T) {
80
tests := map[string]struct {
86
- prepare func(nv *NvidiaSMI)
81
+ prepare func(nv *NvidiaSmi)
82
wantFail bool
83
}{
89
- "success A100-SXM4 MIG [XML]": {
90
- wantFail: false,
91
- prepare: prepareCaseMIGA100formatXML,
92
- },
93
- "success RTX 3060 [XML]": {
84
+ "success A100-SXM4 MIG": {
85
wantFail: false,
95
- prepare: prepareCaseRTX3060formatXML,
86
+ prepare: prepareCaseMIGA100,
87
},
97
- "success Tesla P100 [XML]": {
88
+ "success RTX 3060": {
89
wantFail: false,
99
- prepare: prepareCaseTeslaP100formatXML,
90
+ prepare: prepareCaseRTX3060,
91
},
101
- "success Tesla P100 [CSV]": {
92
+ "success Tesla P100": {
93
wantFail: false,
103
- prepare: prepareCaseTeslaP100formatCSV,
94
+ prepare: prepareCaseTeslaP100,
95
},
105
- "success RTX 2080 Win [XML]": {
96
+ "success RTX 2080 Win": {
97
wantFail: false,
107
- prepare: prepareCaseRTX2080WinFormatXML,
108
- },
109
- "fail on queryGPUInfoXML error": {
110
- wantFail: true,
111
- prepare: prepareCaseErrOnQueryGPUInfoXML,
112
- },
113
- "fail on queryGPUInfoCSV error": {
114
- wantFail: true,
115
- prepare: prepareCaseErrOnQueryGPUInfoCSV,
98
+ prepare: prepareCaseRTX2080Win,
99
},
117
- "fail on queryHelpQueryGPU error": {
100
+ "fail on queryGPUInfo error": {
101
wantFail: true,
119
- prepare: prepareCaseErrOnQueryHelpQueryGPU,
102
+ prepare: prepareCaseErrOnQueryGPUInfo,
103
},
104
}
105
@@ -135,16 +118,16 @@ func TestNvidiaSMI_Check(t *testing.T) {
118
}
119
}
120
138
-func TestNvidiaSMI_Collect(t *testing.T) {
121
+func TestNvidiaSmi_Collect(t *testing.T) {
122
type testCaseStep struct {
140
- prepare func(nv *NvidiaSMI)
141
- check func(t *testing.T, nv *NvidiaSMI)
123
+ prepare func(nv *NvidiaSmi)
124
+ check func(t *testing.T, nv *NvidiaSmi)
125
}
126
tests := map[string][]testCaseStep{
144
- "success A100-SXM4 MIG [XML]": {
127
+ "success A100-SXM4 MIG": {
128
{
146
- prepare: prepareCaseMIGA100formatXML,
147
- check: func(t *testing.T, nv *NvidiaSMI) {
129
+ prepare: prepareCaseMIGA100,
130
+ check: func(t *testing.T, nv *NvidiaSmi) {
131
mx := nv.Collect()
132
133
expected := map[string]int64{
@@ -201,10 +184,10 @@ func TestNvidiaSMI_Collect(t *testing.T) {
184
},
185
},
186
},
204
- "success RTX 4090 Driver 535 [XML]": {
187
+ "success RTX 4090 Driver 535": {
188
{
206
- prepare: prepareCaseRTX4090Driver535formatXML,
207
- check: func(t *testing.T, nv *NvidiaSMI) {
189
+ prepare: prepareCaseRTX4090Driver535,
190
+ check: func(t *testing.T, nv *NvidiaSmi) {
191
mx := nv.Collect()
192
193
expected := map[string]int64{
@@ -251,10 +234,10 @@ func TestNvidiaSMI_Collect(t *testing.T) {
234
},
235
},
236
},
254
- "success RTX 3060 [XML]": {
237
+ "success RTX 3060": {
238
{
256
- prepare: prepareCaseRTX3060formatXML,
257
- check: func(t *testing.T, nv *NvidiaSMI) {
239
+ prepare: prepareCaseRTX3060,
240
+ check: func(t *testing.T, nv *NvidiaSmi) {
241
mx := nv.Collect()
242
243
expected := map[string]int64{
@@ -300,10 +283,10 @@ func TestNvidiaSMI_Collect(t *testing.T) {
283
},
284
},
285
},
303
- "success Tesla P100 [XML]": {
286
+ "success Tesla P100": {
287
{
305
- prepare: prepareCaseTeslaP100formatXML,
306
- check: func(t *testing.T, nv *NvidiaSMI) {
288
+ prepare: prepareCaseTeslaP100,
289
+ check: func(t *testing.T, nv *NvidiaSmi) {
290
mx := nv.Collect()
291
292
expected := map[string]int64{
@@ -348,50 +331,10 @@ func TestNvidiaSMI_Collect(t *testing.T) {
331
},
332
},
333
},
351
- "success Tesla P100 [CSV]": {
334
+ "success RTX 2080 Win": {
335
{
353
- prepare: prepareCaseTeslaP100formatCSV,
354
- check: func(t *testing.T, nv *NvidiaSMI) {
355
- mx := nv.Collect()
356
-
357
- expected := map[string]int64{
358
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_free": 17070817280,
359
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_reserved": 108003328,
360
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_frame_buffer_memory_usage_used": 0,
361
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_gpu_utilization": 0,
362
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_graphics_clock": 405,
363
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_mem_clock": 715,
364
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_mem_utilization": 0,
365
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P0": 1,
366
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P1": 0,
367
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P10": 0,
368
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P11": 0,
369
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P12": 0,
370
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P13": 0,
371
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P14": 0,
372
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P15": 0,
373
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P2": 0,
374
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P3": 0,
375
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P4": 0,
376
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P5": 0,
377
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P6": 0,
378
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P7": 0,
379
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P8": 0,
380
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_performance_state_P9": 0,
381
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_power_draw": 28,
382
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_sm_clock": 405,
383
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_temperature": 37,
384
- "gpu_GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6_video_clock": 835,
385
- }
386
-
387
- assert.Equal(t, expected, mx)
388
- },
389
- },
390
- },
391
- "success RTX 2080 Win [XML]": {
392
- {
393
- prepare: prepareCaseRTX2080WinFormatXML,
394
- check: func(t *testing.T, nv *NvidiaSMI) {
336
+ prepare: prepareCaseRTX2080Win,
337
+ check: func(t *testing.T, nv *NvidiaSmi) {
338
mx := nv.Collect()
339
340
expected := map[string]int64{
@@ -437,30 +380,10 @@ func TestNvidiaSMI_Collect(t *testing.T) {
380
},
381
},
382
},
440
- "fail on queryGPUInfoXML error [XML]": {
383
+ "fails on queryGPUInfo error": {
384
{
442
- prepare: prepareCaseErrOnQueryGPUInfoXML,
443
- check: func(t *testing.T, nv *NvidiaSMI) {
444
- mx := nv.Collect()
445
-
446
- assert.Equal(t, map[string]int64(nil), mx)
447
- },
448
- },
449
- },
450
- "fail on queryGPUInfoCSV error [CSV]": {
451
- {
452
- prepare: prepareCaseErrOnQueryGPUInfoCSV,
453
- check: func(t *testing.T, nv *NvidiaSMI) {
454
- mx := nv.Collect()
455
-
456
- assert.Equal(t, map[string]int64(nil), mx)
457
- },
458
- },
459
- },
460
- "fail on queryHelpQueryGPU error": {
461
- {
462
- prepare: prepareCaseErrOnQueryHelpQueryGPU,
463
- check: func(t *testing.T, nv *NvidiaSMI) {
385
+ prepare: prepareCaseErrOnQueryGPUInfo,
386
+ check: func(t *testing.T, nv *NvidiaSmi) {
387
mx := nv.Collect()
388
389
assert.Equal(t, map[string]int64(nil), mx)
@@ -483,79 +406,38 @@ func TestNvidiaSMI_Collect(t *testing.T) {
406
}
407
}
408
486
-type mockNvidiaSMI struct {
487
- gpuInfoXML []byte
488
- errOnQueryGPUInfoXML bool
489
-
490
- gpuInfoCSV []byte
491
- errOnQueryGPUInfoCSV bool
492
-
493
- helpQueryGPU []byte
494
- errOnQueryHelpQueryGPU bool
495
-}
496
-
497
-func (m *mockNvidiaSMI) queryGPUInfoXML() ([]byte, error) {
498
- if m.errOnQueryGPUInfoXML {
499
- return nil, errors.New("error on mock.queryGPUInfoXML()")
500
- }
501
- return m.gpuInfoXML, nil
502
-}
503
-
504
-func (m *mockNvidiaSMI) queryGPUInfoCSV(_ []string) ([]byte, error) {
505
- if m.errOnQueryGPUInfoCSV {
506
- return nil, errors.New("error on mock.queryGPUInfoCSV()")
507
- }
508
- return m.gpuInfoCSV, nil
409
+type mockNvidiaSmi struct {
410
+ gpuInfo []byte
411
+ errOnQueryGPUInfo bool
412
}
413
511
-func (m *mockNvidiaSMI) queryHelpQueryGPU() ([]byte, error) {
512
- if m.errOnQueryHelpQueryGPU {
513
- return nil, errors.New("error on mock.queryHelpQueryGPU()")
414
+func (m *mockNvidiaSmi) queryGPUInfo() ([]byte, error) {
415
+ if m.errOnQueryGPUInfo {
416
+ return nil, errors.New("error on mock.queryGPUInfo()")
417
}
515
- return m.helpQueryGPU, nil
516
-}
517
-
518
-func prepareCaseMIGA100formatXML(nv *NvidiaSMI) {
519
- nv.UseCSVFormat = false
520
- nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLA100SXM4MIG}
521
-}
522
-
523
-func prepareCaseRTX3060formatXML(nv *NvidiaSMI) {
524
- nv.UseCSVFormat = false
525
- nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX3060}
526
-}
527
-
528
-func prepareCaseRTX4090Driver535formatXML(nv *NvidiaSMI) {
529
- nv.UseCSVFormat = false
530
- nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX4090Driver535}
418
+ return m.gpuInfo, nil
419
}
420
533
-func prepareCaseTeslaP100formatXML(nv *NvidiaSMI) {
534
- nv.UseCSVFormat = false
535
- nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLTeslaP100}
421
+func prepareCaseMIGA100(nv *NvidiaSmi) {
422
+ nv.exec = &mockNvidiaSmi{gpuInfo: dataXMLA100SXM4MIG}
423
}
424
538
-func prepareCaseRTX2080WinFormatXML(nv *NvidiaSMI) {
539
- nv.UseCSVFormat = false
540
- nv.exec = &mockNvidiaSMI{gpuInfoXML: dataXMLRTX2080Win}
425
+func prepareCaseRTX3060(nv *NvidiaSmi) {
426
+ nv.exec = &mockNvidiaSmi{gpuInfo: dataXMLRTX3060}
427
}
428
543
-func prepareCaseErrOnQueryGPUInfoXML(nv *NvidiaSMI) {
544
- nv.UseCSVFormat = false
545
- nv.exec = &mockNvidiaSMI{errOnQueryGPUInfoXML: true}
429
+func prepareCaseRTX4090Driver535(nv *NvidiaSmi) {
430
+ nv.exec = &mockNvidiaSmi{gpuInfo: dataXMLRTX4090Driver535}
431
}
432
548
-func prepareCaseTeslaP100formatCSV(nv *NvidiaSMI) {
549
- nv.UseCSVFormat = true
550
- nv.exec = &mockNvidiaSMI{helpQueryGPU: dataHelpQueryGPU, gpuInfoCSV: dataCSVTeslaP100}
433
+func prepareCaseTeslaP100(nv *NvidiaSmi) {
434
+ nv.exec = &mockNvidiaSmi{gpuInfo: dataXMLTeslaP100}
435
}
436
553
-func prepareCaseErrOnQueryHelpQueryGPU(nv *NvidiaSMI) {
554
- nv.UseCSVFormat = true
555
- nv.exec = &mockNvidiaSMI{errOnQueryHelpQueryGPU: true}
437
+func prepareCaseRTX2080Win(nv *NvidiaSmi) {
438
+ nv.exec = &mockNvidiaSmi{gpuInfo: dataXMLRTX2080Win}
439
}
440
558
-func prepareCaseErrOnQueryGPUInfoCSV(nv *NvidiaSMI) {
559
- nv.UseCSVFormat = true
560
- nv.exec = &mockNvidiaSMI{helpQueryGPU: dataHelpQueryGPU, errOnQueryGPUInfoCSV: true}
441
+func prepareCaseErrOnQueryGPUInfo(nv *NvidiaSmi) {
442
+ nv.exec = &mockNvidiaSmi{errOnQueryGPUInfo: true}
443
}
src/go/plugin/go.d/modules/nvidia_smi/testdata/config.json
+1
-2
@@ -1,6 +1,5 @@
1
{
2
"update_every": 123,
3
"timeout": 123.123,
4
- "binary_path": "ok",
5
- "use_csv_format": true
4
+ "binary_path": "ok"
5
}
src/go/plugin/go.d/modules/nvidia_smi/testdata/config.yaml
-1
@@ -1,4 +1,3 @@
1
update_every: 123
2
timeout: 123.123
3
binary_path: "ok"
4
-use_csv_format: yes
src/go/plugin/go.d/modules/nvidia_smi/testdata/help-query-gpu.txt
deleted
-414
@@ -1,414 +0,0 @@
1
-List of valid properties to query for the switch "--query-gpu=":
2
-
3
-"timestamp"
4
-The timestamp of when the query was made in format "YYYY/MM/DD HH:MM:SS.msec".
5
-
6
-"driver_version"
7
-The version of the installed NVIDIA display driver. This is an alphanumeric string.
8
-
9
-"count"
10
-The number of NVIDIA GPUs in the system.
11
-
12
-"name" or "gpu_name"
13
-The official product name of the GPU. This is an alphanumeric string. For all products.
14
-
15
-"serial" or "gpu_serial"
16
-This number matches the serial number physically printed on each board. It is a globally unique immutable alphanumeric value.
17
-
18
-"uuid" or "gpu_uuid"
19
-This value is the globally unique immutable alphanumeric identifier of the GPU. It does not correspond to any physical label on the board.
20
-
21
-"pci.bus_id" or "gpu_bus_id"
22
-PCI bus id as "domain:bus:device.function", in hex.
23
-
24
-"pci.domain"
25
-PCI domain number, in hex.
26
-
27
-"pci.bus"
28
-PCI bus number, in hex.
29
-
30
-"pci.device"
31
-PCI device number, in hex.
32
-
33
-"pci.device_id"
34
-PCI vendor device id, in hex
35
-
36
-"pci.sub_device_id"
37
-PCI Sub System id, in hex
38
-
39
-"pcie.link.gen.current"
40
-The current PCI-E link generation. These may be reduced when the GPU is not in use.
41
-
42
-"pcie.link.gen.max"
43
-The maximum PCI-E link generation possible with this GPU and system configuration. For example, if the GPU supports a higher PCIe generation than the system supports then this reports the system PCIe generation.
44
-
45
-"pcie.link.width.current"
46
-The current PCI-E link width. These may be reduced when the GPU is not in use.
47
-
48
-"pcie.link.width.max"
49
-The maximum PCI-E link width possible with this GPU and system configuration. For example, if the GPU supports a higher PCIe generation than the system supports then this reports the system PCIe generation.
50
-
51
-"index"
52
-Zero based index of the GPU. Can change at each boot.
53
-
54
-"display_mode"
55
-A flag that indicates whether a physical display (e.g. monitor) is currently connected to any of the GPU's connectors. "Enabled" indicates an attached display. "Disabled" indicates otherwise.
56
-
57
-"display_active"
58
-A flag that indicates whether a display is initialized on the GPU's (e.g. memory is allocated on the device for display). Display can be active even when no monitor is physically attached. "Enabled" indicates an active display. "Disabled" indicates otherwise.
59
-
60
-"persistence_mode"
61
-A flag that indicates whether persistence mode is enabled for the GPU. Value is either "Enabled" or "Disabled". When persistence mode is enabled the NVIDIA driver remains loaded even when no active clients, such as X11 or nvidia-smi, exist. This minimizes the driver load latency associated with running dependent apps, such as CUDA programs. Linux only.
62
-
63
-"accounting.mode"
64
-A flag that indicates whether accounting mode is enabled for the GPU. Value is either "Enabled" or "Disabled". When accounting is enabled statistics are calculated for each compute process running on the GPU.Statistics can be queried during the lifetime or after termination of the process.The execution time of process is reported as 0 while the process is in running state and updated to actualexecution time after the process has terminated. See --help-query-accounted-apps for more info.
65
-
66
-"accounting.buffer_size"
67
-The size of the circular buffer that holds list of processes that can be queried for accounting stats. This is the maximum number of processes that accounting information will be stored for before information about oldest processes will get overwritten by information about new processes.
68
-
69
-Section about driver_model properties
70
-On Windows, the TCC and WDDM driver models are supported. The driver model can be changed with the (-dm) or (-fdm) flags. The TCC driver model is optimized for compute applications. I.E. kernel launch times will be quicker with TCC. The WDDM driver model is designed for graphics applications and is not recommended for compute applications. Linux does not support multiple driver models, and will always have the value of "N/A". Only for selected products. Please see feature matrix in NVML documentation.
71
-
72
-"driver_model.current"
73
-The driver model currently in use. Always "N/A" on Linux.
74
-
75
-"driver_model.pending"
76
-The driver model that will be used on the next reboot. Always "N/A" on Linux.
77
-
78
-"vbios_version"
79
-The BIOS of the GPU board.
80
-
81
-Section about inforom properties
82
-Version numbers for each object in the GPU board's inforom storage. The inforom is a small, persistent store of configuration and state data for the GPU. All inforom version fields are numerical. It can be useful to know these version numbers because some GPU features are only available with inforoms of a certain version or higher.
83
-
84
-"inforom.img" or "inforom.image"
85
-Global version of the infoROM image. Image version just like VBIOS version uniquely describes the exact version of the infoROM flashed on the board in contrast to infoROM object version which is only an indicator of supported features.
86
-
87
-"inforom.oem"
88
-Version for the OEM configuration data.
89
-
90
-"inforom.ecc"
91
-Version for the ECC recording data.
92
-
93
-"inforom.pwr" or "inforom.power"
94
-Version for the power management data.
95
-
96
-Section about gom properties
97
-GOM allows to reduce power usage and optimize GPU throughput by disabling GPU features. Each GOM is designed to meet specific user needs.
98
-In "All On" mode everything is enabled and running at full speed.
99
-The "Compute" mode is designed for running only compute tasks. Graphics operations are not allowed.
100
-The "Low Double Precision" mode is designed for running graphics applications that don't require high bandwidth double precision.
101
-GOM can be changed with the (--gom) flag.
102
-
103
-"gom.current" or "gpu_operation_mode.current"
104
-The GOM currently in use.
105
-
106
-"gom.pending" or "gpu_operation_mode.pending"
107
-The GOM that will be used on the next reboot.
108
-
109
-"fan.speed"
110
-The fan speed value is the percent of the product's maximum noise tolerance fan speed that the device's fan is currently intended to run at. This value may exceed 100% in certain cases. Note: The reported speed is the intended fan speed. If the fan is physically blocked and unable to spin, this output will not match the actual fan speed. Many parts do not report fan speeds because they rely on cooling via fans in the surrounding enclosure.
111
-
112
-"pstate"
113
-The current performance state for the GPU. States range from P0 (maximum performance) to P12 (minimum performance).
114
-
115
-Section about clocks_throttle_reasons properties
116
-Retrieves information about factors that are reducing the frequency of clocks. If all throttle reasons are returned as "Not Active" it means that clocks are running as high as possible.
117
-
118
-"clocks_throttle_reasons.supported"
119
-Bitmask of supported clock throttle reasons. See nvml.h for more details.
120
-
121
-"clocks_throttle_reasons.active"
122
-Bitmask of active clock throttle reasons. See nvml.h for more details.
123
-
124
-"clocks_throttle_reasons.gpu_idle"
125
-Nothing is running on the GPU and the clocks are dropping to Idle state. This limiter may be removed in a later release.
126
-
127
-"clocks_throttle_reasons.applications_clocks_setting"
128
-GPU clocks are limited by applications clocks setting. E.g. can be changed by nvidia-smi --applications-clocks=
129
-
130
-"clocks_throttle_reasons.sw_power_cap"
131
-SW Power Scaling algorithm is reducing the clocks below requested clocks because the GPU is consuming too much power. E.g. SW power cap limit can be changed with nvidia-smi --power-limit=
132
-
133
-"clocks_throttle_reasons.hw_slowdown"
134
-HW Slowdown (reducing the core clocks by a factor of 2 or more) is engaged. This is an indicator of:
135
- HW Thermal Slowdown: temperature being too high
136
- HW Power Brake Slowdown: External Power Brake Assertion is triggered (e.g. by the system power supply)
137
- * Power draw is too high and Fast Trigger protection is reducing the clocks
138
- * May be also reported during PState or clock change
139
- * This behavior may be removed in a later release
140
-
141
-"clocks_throttle_reasons.hw_thermal_slowdown"
142
-HW Thermal Slowdown (reducing the core clocks by a factor of 2 or more) is engaged. This is an indicator of temperature being too high
143
-
144
-"clocks_throttle_reasons.hw_power_brake_slowdown"
145
-HW Power Brake Slowdown (reducing the core clocks by a factor of 2 or more) is engaged. This is an indicator of External Power Brake Assertion being triggered (e.g. by the system power supply)
146
-
147
-"clocks_throttle_reasons.sw_thermal_slowdown"
148
-SW Thermal capping algorithm is reducing clocks below requested clocks because GPU temperature is higher than Max Operating Temp.
149
-
150
-"clocks_throttle_reasons.sync_boost"
151
-Sync Boost This GPU has been added to a Sync boost group with nvidia-smi or DCGM in
152
- * order to maximize performance per watt. All GPUs in the sync boost group
153
- * will boost to the minimum possible clocks across the entire group. Look at
154
- * the throttle reasons for other GPUs in the system to see why those GPUs are
155
- * holding this one at lower clocks.
156
-
157
-Section about memory properties
158
-On-board memory information. Reported total memory is affected by ECC state. If ECC is enabled the total available memory is decreased by several percent, due to the requisite parity bits. The driver may also reserve a small amount of memory for internal use, even without active work on the GPU.
159
-
160
-"memory.total"
161
-Total installed GPU memory.
162
-
163
-"memory.reserved"
164
-Total memory reserved by the NVIDIA driver and firmware.
165
-
166
-"memory.used"
167
-Total memory allocated by active contexts.
168
-
169
-"memory.free"
170
-Total free memory.
171
-
172
-"compute_mode"
173
-The compute mode flag indicates whether individual or multiple compute applications may run on the GPU.
174
-"0: Default" means multiple contexts are allowed per device.
175
-"1: Exclusive_Thread", deprecated, use Exclusive_Process instead
176
-"2: Prohibited" means no contexts are allowed per device (no compute apps).
177
-"3: Exclusive_Process" means only one context is allowed per device, usable from multiple threads at a time.
178
-
179
-"compute_cap"
180
-The CUDA Compute Capability, represented as Major DOT Minor.
181
-
182
-Section about utilization properties
183
-Utilization rates report how busy each GPU is over time, and can be used to determine how much an application is using the GPUs in the system.
184
-
185
-"utilization.gpu"
186
-Percent of time over the past sample period during which one or more kernels was executing on the GPU.
187
-The sample period may be between 1 second and 1/6 second depending on the product.
188
-
189
-"utilization.memory"
190
-Percent of time over the past sample period during which global (device) memory was being read or written.
191
-The sample period may be between 1 second and 1/6 second depending on the product.
192
-
193
-Section about encoder.stats properties
194
-Encoder stats report number of encoder sessions, average FPS and average latency in us for given GPUs in the system.
195
-
196
-"encoder.stats.sessionCount"
197
-Number of encoder sessions running on the GPU.
198
-
199
-"encoder.stats.averageFps"
200
-Average FPS of all sessions running on the GPU.
201
-
202
-"encoder.stats.averageLatency"
203
-Average latency in microseconds of all sessions running on the GPU.
204
-
205
-Section about ecc.mode properties
206
-A flag that indicates whether ECC support is enabled. May be either "Enabled" or "Disabled". Changes to ECC mode require a reboot. Requires Inforom ECC object version 1.0 or higher.
207
-
208
-"ecc.mode.current"
209
-The ECC mode that the GPU is currently operating under.
210
-
211
-"ecc.mode.pending"
212
-The ECC mode that the GPU will operate under after the next reboot.
213
-
214
-Section about ecc.errors properties
215
-NVIDIA GPUs can provide error counts for various types of ECC errors. Some ECC errors are either single or double bit, where single bit errors are corrected and double bit errors are uncorrectable. Texture memory errors may be correctable via resend or uncorrectable if the resend fails. These errors are available across two timescales (volatile and aggregate). Single bit ECC errors are automatically corrected by the HW and do not result in data corruption. Double bit errors are detected but not corrected. Please see the ECC documents on the web for information on compute application behavior when double bit errors occur. Volatile error counters track the number of errors detected since the last driver load. Aggregate error counts persist indefinitely and thus act as a lifetime counter.
216
-
217
-"ecc.errors.corrected.volatile.device_memory"
218
-Errors detected in global device memory.
219
-
220
-"ecc.errors.corrected.volatile.dram"
221
-Errors detected in global device memory.
222
-
223
-"ecc.errors.corrected.volatile.register_file"
224
-Errors detected in register file memory.
225
-
226
-"ecc.errors.corrected.volatile.l1_cache"
227
-Errors detected in the L1 cache.
228
-
229
-"ecc.errors.corrected.volatile.l2_cache"
230
-Errors detected in the L2 cache.
231
-
232
-"ecc.errors.corrected.volatile.texture_memory"
233
-Parity errors detected in texture memory.
234
-
235
-"ecc.errors.corrected.volatile.cbu"
236
-Parity errors detected in CBU.
237
-
238
-"ecc.errors.corrected.volatile.sram"
239
-Errors detected in global SRAMs.
240
-
241
-"ecc.errors.corrected.volatile.total"
242
-Total errors detected across entire chip.
243
-
244
-"ecc.errors.corrected.aggregate.device_memory"
245
-Errors detected in global device memory.
246
-
247
-"ecc.errors.corrected.aggregate.dram"
248
-Errors detected in global device memory.
249
-
250
-"ecc.errors.corrected.aggregate.register_file"
251
-Errors detected in register file memory.
252
-
253
-"ecc.errors.corrected.aggregate.l1_cache"
254
-Errors detected in the L1 cache.
255
-
256
-"ecc.errors.corrected.aggregate.l2_cache"
257
-Errors detected in the L2 cache.
258
-
259
-"ecc.errors.corrected.aggregate.texture_memory"
260
-Parity errors detected in texture memory.
261
-
262
-"ecc.errors.corrected.aggregate.cbu"
263
-Parity errors detected in CBU.
264
-
265
-"ecc.errors.corrected.aggregate.sram"
266
-Errors detected in global SRAMs.
267
-
268
-"ecc.errors.corrected.aggregate.total"
269
-Total errors detected across entire chip.
270
-
271
-"ecc.errors.uncorrected.volatile.device_memory"
272
-Errors detected in global device memory.
273
-
274
-"ecc.errors.uncorrected.volatile.dram"
275
-Errors detected in global device memory.
276
-
277
-"ecc.errors.uncorrected.volatile.register_file"
278
-Errors detected in register file memory.
279
-
280
-"ecc.errors.uncorrected.volatile.l1_cache"
281
-Errors detected in the L1 cache.
282
-
283
-"ecc.errors.uncorrected.volatile.l2_cache"
284
-Errors detected in the L2 cache.
285
-
286
-"ecc.errors.uncorrected.volatile.texture_memory"
287
-Parity errors detected in texture memory.
288
-
289
-"ecc.errors.uncorrected.volatile.cbu"
290
-Parity errors detected in CBU.
291
-
292
-"ecc.errors.uncorrected.volatile.sram"
293
-Errors detected in global SRAMs.
294
-
295
-"ecc.errors.uncorrected.volatile.total"
296
-Total errors detected across entire chip.
297
-
298
-"ecc.errors.uncorrected.aggregate.device_memory"
299
-Errors detected in global device memory.
300
-
301
-"ecc.errors.uncorrected.aggregate.dram"
302
-Errors detected in global device memory.
303
-
304
-"ecc.errors.uncorrected.aggregate.register_file"
305
-Errors detected in register file memory.
306
-
307
-"ecc.errors.uncorrected.aggregate.l1_cache"
308
-Errors detected in the L1 cache.
309
-
310
-"ecc.errors.uncorrected.aggregate.l2_cache"
311
-Errors detected in the L2 cache.
312
-
313
-"ecc.errors.uncorrected.aggregate.texture_memory"
314
-Parity errors detected in texture memory.
315
-
316
-"ecc.errors.uncorrected.aggregate.cbu"
317
-Parity errors detected in CBU.
318
-
319
-"ecc.errors.uncorrected.aggregate.sram"
320
-Errors detected in global SRAMs.
321
-
322
-"ecc.errors.uncorrected.aggregate.total"
323
-Total errors detected across entire chip.
324
-
325
-Section about retired_pages properties
326
-NVIDIA GPUs can retire pages of GPU device memory when they become unreliable. This can happen when multiple single bit ECC errors occur for the same page, or on a double bit ECC error. When a page is retired, the NVIDIA driver will hide it such that no driver, or application memory allocations can access it.
327
-
328
-"retired_pages.single_bit_ecc.count" or "retired_pages.sbe"
329
-The number of GPU device memory pages that have been retired due to multiple single bit ECC errors.
330
-
331
-"retired_pages.double_bit.count" or "retired_pages.dbe"
332
-The number of GPU device memory pages that have been retired due to a double bit ECC error.
333
-
334
-"retired_pages.pending"
335
-Checks if any GPU device memory pages are pending retirement on the next reboot. Pages that are pending retirement can still be allocated, and may cause further reliability issues.
336
-
337
-"temperature.gpu"
338
- Core GPU temperature. in degrees C.
339
-
340
-"temperature.memory"
341
- HBM memory temperature. in degrees C.
342
-
343
-"power.management"
344
-A flag that indicates whether power management is enabled. Either "Supported" or "[Not Supported]". Requires Inforom PWR object version 3.0 or higher or Kepler device.
345
-
346
-"power.draw"
347
-The last measured power draw for the entire board, in watts. Only available if power management is supported. This reading is accurate to within +/- 5 watts.
348
-
349
-"power.limit"
350
-The software power limit in watts. Set by software like nvidia-smi. On Kepler devices Power Limit can be adjusted using [-pl | --power-limit=] switches.
351
-
352
-"enforced.power.limit"
353
-The power management algorithm's power ceiling, in watts. Total board power draw is manipulated by the power management algorithm such that it stays under this value. This value is the minimum of various power limiters.
354
-
355
-"power.default_limit"
356
-The default power management algorithm's power ceiling, in watts. Power Limit will be set back to Default Power Limit after driver unload.
357
-
358
-"power.min_limit"
359
-The minimum value in watts that power limit can be set to.
360
-
361
-"power.max_limit"
362
-The maximum value in watts that power limit can be set to.
363
-
364
-"clocks.current.graphics" or "clocks.gr"
365
-Current frequency of graphics (shader) clock.
366
-
367
-"clocks.current.sm" or "clocks.sm"
368
-Current frequency of SM (Streaming Multiprocessor) clock.
369
-
370
-"clocks.current.memory" or "clocks.mem"
371
-Current frequency of memory clock.
372
-
373
-"clocks.current.video" or "clocks.video"
374
-Current frequency of video encoder/decoder clock.
375
-
376
-Section about clocks.applications properties
377
-User specified frequency at which applications will be running at. Can be changed with [-ac | --applications-clocks] switches.
378
-
379
-"clocks.applications.graphics" or "clocks.applications.gr"
380
-User specified frequency of graphics (shader) clock.
381
-
382
-"clocks.applications.memory" or "clocks.applications.mem"
383
-User specified frequency of memory clock.
384
-
385
-Section about clocks.default_applications properties
386
-Default frequency at which applications will be running at. Application clocks can be changed with [-ac | --applications-clocks] switches. Application clocks can be set to default using [-rac | --reset-applications-clocks] switches.
387
-
388
-"clocks.default_applications.graphics" or "clocks.default_applications.gr"
389
-Default frequency of applications graphics (shader) clock.
390
-
391
-"clocks.default_applications.memory" or "clocks.default_applications.mem"
392
-Default frequency of applications memory clock.
393
-
394
-Section about clocks.max properties
395
-Maximum frequency at which parts of the GPU are design to run.
396
-
397
-"clocks.max.graphics" or "clocks.max.gr"
398
-Maximum frequency of graphics (shader) clock.
399
-
400
-"clocks.max.sm" or "clocks.max.sm"
401
-Maximum frequency of SM (Streaming Multiprocessor) clock.
402
-
403
-"clocks.max.memory" or "clocks.max.mem"
404
-Maximum frequency of memory clock.
405
-
406
-Section about mig.mode properties
407
-A flag that indicates whether MIG mode is enabled. May be either "Enabled" or "Disabled". Changes to MIG mode require a GPU reset.
408
-
409
-"mig.mode.current"
410
-The MIG mode that the GPU is currently operating under.
411
-
412
-"mig.mode.pending"
413
-The MIG mode that the GPU will operate under after reset.
414
-
src/go/plugin/go.d/modules/nvidia_smi/testdata/tesla-p100.csv
deleted
-2
@@ -1,2 +0,0 @@
1
-name, uuid, fan.speed [%], pstate, memory.reserved [MiB], memory.used [MiB], memory.free [MiB], utilization.gpu [%], utilization.memory [%], temperature.gpu, power.draw [W], clocks.current.graphics [MHz], clocks.current.sm [MHz], clocks.current.memory [MHz], clocks.current.video [MHz]
2
-Tesla P100-PCIE-16GB, GPU-ef1b2c9b-38d8-2090-2bd1-f567a3eb42a6, [N/A], P0, 103, 0, 16280, 0, 0, 37, 28.16, 405, 405, 715, 835
\ No newline at end of file