master
go 374 lines 11.4 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package nvidia_smi
4
5 import (
6 "fmt"
7 "strconv"
8 "strings"
9
10 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
11 )
12
13 const (
14 prioGPUPCIBandwidthUsage = collectorapi.Priority + iota
15 prioGPUPCIBandwidthUtilization
16 prioGPUFanSpeed
17 prioGPUUtilization
18 prioGPUMemUtilization
19 prioGPUDecoderUtilization
20 prioGPUEncoderUtilization
21 prioGPUMIGModeStatus
22 prioGPUMIGDevicesCount
23 prioGPUFBMemoryUsage
24 prioGPUMIGFBMemoryUsage
25 prioGPUBAR1MemoryUsage
26 prioGPUMIGBAR1MemoryUsage
27 prioGPUTemperatureChart
28 prioGPUVoltageChart
29 prioGPUClockFreq
30 prioGPUPowerDraw
31 prioGPUPerformanceState
32 )
33
34 var (
35 gpuXMLCharts = collectorapi.Charts{
36 gpuPCIBandwidthUsageChartTmpl.Copy(),
37 gpuPCIBandwidthUtilizationChartTmpl.Copy(),
38 gpuFanSpeedPercChartTmpl.Copy(),
39 gpuUtilizationChartTmpl.Copy(),
40 gpuMemUtilizationChartTmpl.Copy(),
41 gpuDecoderUtilizationChartTmpl.Copy(),
42 gpuEncoderUtilizationChartTmpl.Copy(),
43 gpuMIGModeCurrentStatusChartTmpl.Copy(),
44 gpuMIGDevicesCountChartTmpl.Copy(),
45 gpuFrameBufferMemoryUsageChartTmpl.Copy(),
46 gpuBAR1MemoryUsageChartTmpl.Copy(),
47 gpuVoltageChartTmpl.Copy(),
48 gpuTemperatureChartTmpl.Copy(),
49 gpuClockFreqChartTmpl.Copy(),
50 gpuPowerDrawChartTmpl.Copy(),
51 gpuPerformanceStateChartTmpl.Copy(),
52 }
53 migDeviceXMLCharts = collectorapi.Charts{
54 migDeviceFrameBufferMemoryUsageChartTmpl.Copy(),
55 migDeviceBAR1MemoryUsageChartTmpl.Copy(),
56 }
57 )
58
59 var (
60 gpuPCIBandwidthUsageChartTmpl = collectorapi.Chart{
61 ID: "gpu_%s_pcie_bandwidth_usage",
62 Title: "PCI Express Bandwidth Usage",
63 Units: "B/s",
64 Fam: "pcie bandwidth",
65 Ctx: "nvidia_smi.gpu_pcie_bandwidth_usage",
66 Type: collectorapi.Area,
67 Priority: prioGPUPCIBandwidthUsage,
68 Dims: collectorapi.Dims{
69 {ID: "gpu_%s_pcie_bandwidth_usage_rx", Name: "rx"},
70 {ID: "gpu_%s_pcie_bandwidth_usage_tx", Name: "tx", Mul: -1},
71 },
72 }
73 gpuPCIBandwidthUtilizationChartTmpl = collectorapi.Chart{
74 ID: "gpu_%s_pcie_bandwidth_utilization",
75 Title: "PCI Express Bandwidth Utilization",
76 Units: "percentage",
77 Fam: "pcie bandwidth",
78 Ctx: "nvidia_smi.gpu_pcie_bandwidth_utilization",
79 Priority: prioGPUPCIBandwidthUtilization,
80 Dims: collectorapi.Dims{
81 {ID: "gpu_%s_pcie_bandwidth_utilization_rx", Name: "rx", Div: 100},
82 {ID: "gpu_%s_pcie_bandwidth_utilization_tx", Name: "tx", Div: 100},
83 },
84 }
85 gpuFanSpeedPercChartTmpl = collectorapi.Chart{
86 ID: "gpu_%s_fan_speed_perc",
87 Title: "Fan speed",
88 Units: "%",
89 Fam: "fan speed",
90 Ctx: "nvidia_smi.gpu_fan_speed_perc",
91 Priority: prioGPUFanSpeed,
92 Dims: collectorapi.Dims{
93 {ID: "gpu_%s_fan_speed_perc", Name: "fan_speed"},
94 },
95 }
96 gpuUtilizationChartTmpl = collectorapi.Chart{
97 ID: "gpu_%s_gpu_utilization",
98 Title: "GPU utilization",
99 Units: "%",
100 Fam: "gpu utilization",
101 Ctx: "nvidia_smi.gpu_utilization",
102 Priority: prioGPUUtilization,
103 Dims: collectorapi.Dims{
104 {ID: "gpu_%s_gpu_utilization", Name: "gpu"},
105 },
106 }
107 gpuMemUtilizationChartTmpl = collectorapi.Chart{
108 ID: "gpu_%s_memory_utilization",
109 Title: "Memory utilization",
110 Units: "%",
111 Fam: "mem utilization",
112 Ctx: "nvidia_smi.gpu_memory_utilization",
113 Priority: prioGPUMemUtilization,
114 Dims: collectorapi.Dims{
115 {ID: "gpu_%s_mem_utilization", Name: "memory"},
116 },
117 }
118 gpuDecoderUtilizationChartTmpl = collectorapi.Chart{
119 ID: "gpu_%s_decoder_utilization",
120 Title: "Decoder utilization",
121 Units: "%",
122 Fam: "dec utilization",
123 Ctx: "nvidia_smi.gpu_decoder_utilization",
124 Priority: prioGPUDecoderUtilization,
125 Dims: collectorapi.Dims{
126 {ID: "gpu_%s_decoder_utilization", Name: "decoder"},
127 },
128 }
129 gpuEncoderUtilizationChartTmpl = collectorapi.Chart{
130 ID: "gpu_%s_encoder_utilization",
131 Title: "Encoder utilization",
132 Units: "%",
133 Fam: "enc utilization",
134 Ctx: "nvidia_smi.gpu_encoder_utilization",
135 Priority: prioGPUEncoderUtilization,
136 Dims: collectorapi.Dims{
137 {ID: "gpu_%s_encoder_utilization", Name: "encoder"},
138 },
139 }
140 gpuMIGModeCurrentStatusChartTmpl = collectorapi.Chart{
141 ID: "gpu_%s_mig_mode_current_status",
142 Title: "MIG current mode",
143 Units: "status",
144 Fam: "mig",
145 Ctx: "nvidia_smi.gpu_mig_mode_current_status",
146 Priority: prioGPUMIGModeStatus,
147 Dims: collectorapi.Dims{
148 {ID: "gpu_%s_mig_current_mode_enabled", Name: "enabled"},
149 {ID: "gpu_%s_mig_current_mode_disabled", Name: "disabled"},
150 },
151 }
152 gpuMIGDevicesCountChartTmpl = collectorapi.Chart{
153 ID: "gpu_%s_mig_devices_count",
154 Title: "MIG devices",
155 Units: "devices",
156 Fam: "mig",
157 Ctx: "nvidia_smi.gpu_mig_devices_count",
158 Priority: prioGPUMIGDevicesCount,
159 Dims: collectorapi.Dims{
160 {ID: "gpu_%s_mig_devices_count", Name: "mig"},
161 },
162 }
163 gpuFrameBufferMemoryUsageChartTmpl = collectorapi.Chart{
164 ID: "gpu_%s_frame_buffer_memory_usage",
165 Title: "Frame buffer memory usage",
166 Units: "B",
167 Fam: "fb mem usage",
168 Ctx: "nvidia_smi.gpu_frame_buffer_memory_usage",
169 Type: collectorapi.Stacked,
170 Priority: prioGPUFBMemoryUsage,
171 Dims: collectorapi.Dims{
172 {ID: "gpu_%s_frame_buffer_memory_usage_free", Name: "free"},
173 {ID: "gpu_%s_frame_buffer_memory_usage_used", Name: "used"},
174 {ID: "gpu_%s_frame_buffer_memory_usage_reserved", Name: "reserved"},
175 },
176 }
177 gpuBAR1MemoryUsageChartTmpl = collectorapi.Chart{
178 ID: "gpu_%s_bar1_memory_usage",
179 Title: "BAR1 memory usage",
180 Units: "B",
181 Fam: "bar1 mem usage",
182 Ctx: "nvidia_smi.gpu_bar1_memory_usage",
183 Type: collectorapi.Stacked,
184 Priority: prioGPUBAR1MemoryUsage,
185 Dims: collectorapi.Dims{
186 {ID: "gpu_%s_bar1_memory_usage_free", Name: "free"},
187 {ID: "gpu_%s_bar1_memory_usage_used", Name: "used"},
188 },
189 }
190 gpuTemperatureChartTmpl = collectorapi.Chart{
191 ID: "gpu_%s_temperature",
192 Title: "Temperature",
193 Units: "Celsius",
194 Fam: "temperature",
195 Ctx: "nvidia_smi.gpu_temperature",
196 Priority: prioGPUTemperatureChart,
197 Dims: collectorapi.Dims{
198 {ID: "gpu_%s_temperature", Name: "temperature"},
199 },
200 }
201 gpuVoltageChartTmpl = collectorapi.Chart{
202 ID: "gpu_%s_voltage",
203 Title: "Voltage",
204 Units: "V",
205 Fam: "voltage",
206 Ctx: "nvidia_smi.gpu_voltage",
207 Priority: prioGPUVoltageChart,
208 Dims: collectorapi.Dims{
209 {ID: "gpu_%s_voltage", Name: "voltage", Div: 1000}, // mV => V
210 },
211 }
212 gpuClockFreqChartTmpl = collectorapi.Chart{
213 ID: "gpu_%s_clock_freq",
214 Title: "Clock current frequency",
215 Units: "MHz",
216 Fam: "clocks",
217 Ctx: "nvidia_smi.gpu_clock_freq",
218 Priority: prioGPUClockFreq,
219 Dims: collectorapi.Dims{
220 {ID: "gpu_%s_graphics_clock", Name: "graphics"},
221 {ID: "gpu_%s_video_clock", Name: "video"},
222 {ID: "gpu_%s_sm_clock", Name: "sm"},
223 {ID: "gpu_%s_mem_clock", Name: "mem"},
224 },
225 }
226 gpuPowerDrawChartTmpl = collectorapi.Chart{
227 ID: "gpu_%s_power_draw",
228 Title: "Power draw",
229 Units: "Watts",
230 Fam: "power draw",
231 Ctx: "nvidia_smi.gpu_power_draw",
232 Priority: prioGPUPowerDraw,
233 Dims: collectorapi.Dims{
234 {ID: "gpu_%s_power_draw", Name: "power_draw"},
235 },
236 }
237 gpuPerformanceStateChartTmpl = collectorapi.Chart{
238 ID: "gpu_%s_performance_state",
239 Title: "Performance state",
240 Units: "state",
241 Fam: "performance state",
242 Ctx: "nvidia_smi.gpu_performance_state",
243 Priority: prioGPUPerformanceState,
244 Dims: collectorapi.Dims{
245 {ID: "gpu_%s_performance_state_P0", Name: "P0"},
246 {ID: "gpu_%s_performance_state_P1", Name: "P1"},
247 {ID: "gpu_%s_performance_state_P2", Name: "P2"},
248 {ID: "gpu_%s_performance_state_P3", Name: "P3"},
249 {ID: "gpu_%s_performance_state_P4", Name: "P4"},
250 {ID: "gpu_%s_performance_state_P5", Name: "P5"},
251 {ID: "gpu_%s_performance_state_P6", Name: "P6"},
252 {ID: "gpu_%s_performance_state_P7", Name: "P7"},
253 {ID: "gpu_%s_performance_state_P8", Name: "P8"},
254 {ID: "gpu_%s_performance_state_P9", Name: "P9"},
255 {ID: "gpu_%s_performance_state_P10", Name: "P10"},
256 {ID: "gpu_%s_performance_state_P11", Name: "P11"},
257 {ID: "gpu_%s_performance_state_P12", Name: "P12"},
258 {ID: "gpu_%s_performance_state_P13", Name: "P13"},
259 {ID: "gpu_%s_performance_state_P14", Name: "P14"},
260 {ID: "gpu_%s_performance_state_P15", Name: "P15"},
261 },
262 }
263 )
264
265 func (c *Collector) addGpuCharts(gpu gpuInfo, index int) {
266 charts := gpuXMLCharts.Copy()
267
268 if !isValidValue(gpu.Utilization.GpuUtil) {
269 _ = charts.Remove(gpuUtilizationChartTmpl.ID)
270 }
271 if !isValidValue(gpu.Utilization.MemoryUtil) {
272 _ = charts.Remove(gpuMemUtilizationChartTmpl.ID)
273 }
274 if !isValidValue(gpu.Utilization.DecoderUtil) {
275 _ = charts.Remove(gpuDecoderUtilizationChartTmpl.ID)
276 }
277 if !isValidValue(gpu.Utilization.EncoderUtil) {
278 _ = charts.Remove(gpuEncoderUtilizationChartTmpl.ID)
279 }
280 if !isValidValue(gpu.MIGMode.CurrentMIG) {
281 _ = charts.Remove(gpuMIGModeCurrentStatusChartTmpl.ID)
282 _ = charts.Remove(gpuMIGDevicesCountChartTmpl.ID)
283 }
284 if !isValidValue(gpu.FanSpeed) {
285 _ = charts.Remove(gpuFanSpeedPercChartTmpl.ID)
286 }
287
288 mx := make(map[string]int64)
289 addGPUPowerMetricsSwitch(mx, "", gpu)
290
291 if len(mx) == 0 {
292 _ = charts.Remove(gpuPowerDrawChartTmpl.ID)
293 }
294 if !isValidValue(gpu.Voltage.GraphicsVolt) {
295 _ = charts.Remove(gpuVoltageChartTmpl.ID)
296 }
297
298 for _, c := range *charts {
299 c.ID = fmt.Sprintf(c.ID, strings.ToLower(gpu.UUID))
300 c.Labels = []collectorapi.Label{
301 {Key: "index", Value: strconv.Itoa(index)},
302 {Key: "uuid", Value: gpu.UUID},
303 {Key: "product_name", Value: gpu.ProductName},
304 }
305 for _, d := range c.Dims {
306 d.ID = fmt.Sprintf(d.ID, gpu.UUID)
307 }
308 }
309
310 if err := c.Charts().Add(*charts...); err != nil {
311 c.Warning(err)
312 }
313 }
314
315 var (
316 migDeviceFrameBufferMemoryUsageChartTmpl = collectorapi.Chart{
317 ID: "mig_instance_%s_gpu_%s_frame_buffer_memory_usage",
318 Title: "MIG Frame buffer memory usage",
319 Units: "B",
320 Fam: "fb mem usage",
321 Ctx: "nvidia_smi.gpu_mig_frame_buffer_memory_usage",
322 Type: collectorapi.Stacked,
323 Priority: prioGPUMIGFBMemoryUsage,
324 Dims: collectorapi.Dims{
325 {ID: "mig_instance_%s_gpu_%s_frame_buffer_memory_usage_free", Name: "free"},
326 {ID: "mig_instance_%s_gpu_%s_frame_buffer_memory_usage_used", Name: "used"},
327 {ID: "mig_instance_%s_gpu_%s_frame_buffer_memory_usage_reserved", Name: "reserved"},
328 },
329 }
330 migDeviceBAR1MemoryUsageChartTmpl = collectorapi.Chart{
331 ID: "mig_instance_%s_gpu_%s_bar1_memory_usage",
332 Title: "MIG BAR1 memory usage",
333 Units: "B",
334 Fam: "bar1 mem usage",
335 Ctx: "nvidia_smi.gpu_mig_bar1_memory_usage",
336 Type: collectorapi.Stacked,
337 Priority: prioGPUMIGBAR1MemoryUsage,
338 Dims: collectorapi.Dims{
339 {ID: "mig_instance_%s_gpu_%s_bar1_memory_usage_free", Name: "free"},
340 {ID: "mig_instance_%s_gpu_%s_bar1_memory_usage_used", Name: "used"},
341 },
342 }
343 )
344
345 func (c *Collector) addMIGDeviceCharts(gpu gpuInfo, mig gpuMIGDeviceInfo) {
346 charts := migDeviceXMLCharts.Copy()
347
348 for _, c := range *charts {
349 c.ID = fmt.Sprintf(c.ID, strings.ToLower(mig.GPUInstanceID), strings.ToLower(gpu.UUID))
350 c.Labels = []collectorapi.Label{
351 {Key: "gpu_uuid", Value: gpu.UUID},
352 {Key: "gpu_product_name", Value: gpu.ProductName},
353 {Key: "gpu_instance_id", Value: mig.GPUInstanceID},
354 }
355 for _, d := range c.Dims {
356 d.ID = fmt.Sprintf(d.ID, mig.GPUInstanceID, gpu.UUID)
357 }
358 }
359
360 if err := c.Charts().Add(*charts...); err != nil {
361 c.Warning(err)
362 }
363 }
364
365 func (c *Collector) removeCharts(prefix string) {
366 prefix = strings.ToLower(prefix)
367
368 for _, c := range *c.Charts() {
369 if strings.HasPrefix(c.ID, prefix) {
370 c.MarkRemove()
371 c.MarkNotCreated()
372 }
373 }
374 }