Skip to content
45 changes: 45 additions & 0 deletions nodescraper/plugins/inband/amdsmi/amdsmi_collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@
AmdSmiStatic,
AmdSmiVersion,
BadPages,
CoreMetric,
CpuMetric,
EccState,
Fabric,
Fw,
FwListItem,
NodeInfo,
Partition,
PartitionCompute,
PartitionMemory,
Expand Down Expand Up @@ -110,6 +113,9 @@ class AmdSmiCollector(InBandDataCollector[AmdSmiDataModel, AmdSmiCollectorArgs])
CMD_RAS = "ras --cper --folder={folder}"
CMD_RAS_AFID = "ras --afid --cper-file {cper_file}"
CMD_FABRIC = "fabric"
CMD_NODE = "node"
CMD_METRIC_CPU = "metric --cpu all"
CMD_METRIC_CORE = "metric --core all"

def _check_amdsmi_installed(self) -> bool:
"""Check if amd-smi is installed
Expand Down Expand Up @@ -499,6 +505,39 @@ def get_fabric(self) -> List[Fabric]:
built = self._build_amdsmi_sub_data(Fabric, fabric_entries)
return built if isinstance(built, list) else ([built] if built else [])

def get_node(self) -> List[NodeInfo]:
"""Get node-level data from amd-smi node --json."""
ret = self._run_amd_smi_dict(self.CMD_NODE)
if ret is None:
return []
if isinstance(ret, dict) and "node_data" in ret:
ret = ret["node_data"]
data = ret if isinstance(ret, list) else [ret]
built = self._build_amdsmi_sub_data(NodeInfo, data)
return built if isinstance(built, list) else ([built] if built else [])

def get_cpu_metric(self) -> List[CpuMetric]:
"""Get per-CPU-socket metrics from amd-smi metric --cpu all --json."""
ret = self._run_amd_smi_dict(self.CMD_METRIC_CPU)
if ret is None:
return []
if isinstance(ret, dict) and "cpu_data" in ret:
ret = ret["cpu_data"]
data = ret if isinstance(ret, list) else [ret]
built = self._build_amdsmi_sub_data(CpuMetric, data)
return built if isinstance(built, list) else ([built] if built else [])

def get_core_metric(self) -> List[CoreMetric]:
"""Get per-core metrics from amd-smi metric --core all --json."""
ret = self._run_amd_smi_dict(self.CMD_METRIC_CORE)
if ret is None:
return []
if isinstance(ret, dict) and "core_data" in ret:
ret = ret["core_data"]
data = ret if isinstance(ret, list) else [ret]
built = self._build_amdsmi_sub_data(CoreMetric, data)
return built if isinstance(built, list) else ([built] if built else [])

def _get_amdsmi_data(
self, args: Optional[AmdSmiCollectorArgs] = None
) -> Optional[AmdSmiDataModel]:
Expand All @@ -519,6 +558,9 @@ def _get_amdsmi_data(
bad_pages = self.get_bad_pages()
xgmi_metric, xgmi_link = self.get_xgmi_data()
fabric = self.get_fabric()
node = self.get_node()
cpu_metric = self.get_cpu_metric()
core_metric = self.get_core_metric()
cper_data, cper_afids = self.get_cper_data()
except Exception as e:
self._log_event(
Expand Down Expand Up @@ -546,6 +588,9 @@ def _get_amdsmi_data(
xgmi_metric=xgmi_metric or [],
xgmi_link=xgmi_link or [],
fabric=fabric or [],
node=node or [],
cpu_metric=cpu_metric or [],
core_metric=core_metric or [],
cper_data=cper_data,
cper_afids=cper_afids,
analysis_firmware_ids=fw_ids,
Expand Down
Loading
Loading