Coverage for cuda / core / system / _field_values.pxi: 64.86%
37 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-08 01:07 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-08 01:07 +0000
1# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
6FieldId = nvml.FieldId
9cdef class FieldValue:
10 """
11 Represents the data from a single field value.
13 Use :meth:`Device.get_field_values` to get multiple field values at once.
14 """
15 cdef object _field_value
17 def __init__(self, field_value: nvml.FieldValue):
18 assert len(field_value) == 1 1a
19 self._field_value = field_value 1a
21 @property
22 def field_id(self) -> FieldId:
23 """
24 The field ID.
25 """
26 return FieldId(self._field_value.field_id) 1a
28 @property
29 def scope_id(self) -> int:
30 """
31 The scope ID.
32 """
33 # Explicit int() cast required because this is a Numpy type
34 return int(self._field_value.scope_id)
36 @property
37 def timestamp(self) -> int:
38 """
39 The CPU timestamp (in microseconds since 1970) at which the value was
40 sampled.
41 """
42 # Explicit int() cast required because this is a Numpy type
43 return int(self._field_value.timestamp) 1a
45 @property
46 def latency_usec(self) -> int:
47 """
48 How long this field value took to update (in usec) within NVML. This may
49 be averaged across several fields that are serviced by the same driver
50 call.
51 """
52 # Explicit int() cast required because this is a Numpy type
53 return int(self._field_value.latency_usec) 1a
55 @property
56 def value(self) -> int | float:
57 """
58 The field value.
60 Raises
61 ------
62 :class:`cuda.core.system.NvmlError`
63 If there was an error retrieving the field value.
64 """
65 nvml.check_status(self._field_value.nvml_return) 1a
67 cdef int value_type = self._field_value.value_type 1a
68 value = self._field_value.value 1a
70 ValueType = nvml.ValueType 1a
72 if value_type == ValueType.DOUBLE: 1a
73 return float(value.d_val[0])
74 elif value_type == ValueType.UNSIGNED_INT: 1a
75 return int(value.ui_val[0]) 1a
76 elif value_type == ValueType.UNSIGNED_LONG: 1a
77 return int(value.ul_val[0])
78 elif value_type == ValueType.UNSIGNED_LONG_LONG: 1a
79 return int(value.ull_val[0]) 1a
80 elif value_type == ValueType.SIGNED_LONG_LONG:
81 return int(value.ll_val[0])
82 elif value_type == ValueType.SIGNED_INT:
83 return int(value.si_val[0])
84 elif value_type == ValueType.UNSIGNED_SHORT:
85 return int(value.us_val[0])
86 else:
87 raise AssertionError("Unexpected value type")
90cdef class FieldValues:
91 """
92 Container of multiple field values.
93 """
94 cdef object _field_values
96 def __init__(self, field_values: nvml.FieldValue):
97 self._field_values = field_values 1a
99 def __getitem__(self, idx: int) -> FieldValue:
100 return FieldValue(self._field_values[idx]) 1a
102 def __len__(self) -> int:
103 return len(self._field_values) 1a
105 def validate(self) -> None:
106 """
107 Validate that there are no issues in any of the contained field values.
109 Raises an exception for the first issue found, if any.
111 Raises
112 ------
113 :class:`cuda.core.system.NvmlError`
114 If any of the contained field values has an associated exception.
115 """
116 # TODO: This is a classic use case for an `ExceptionGroup`, but those
117 # are only available in Python 3.11+.
118 return_values = self._field_values.nvml_return 1a
119 if len(self._field_values) == 1: 1a
120 return_values = [return_values] 1a
121 for return_value in return_values: 1a
122 nvml.check_status(return_value) 1a
124 def get_all_values(self) -> list[int | float]:
125 """
126 Get all field values as a list.
128 This will validate each of the values and include just the core value in
129 the list.
131 Returns
132 -------
133 list[int | float]
134 List of all field values.
136 Raises
137 ------
138 :class:`cuda.core.system.NvmlError`
139 If any of the contained field values has an associated exception.
140 """
141 return [x.value for x in self] 1a