Coverage for /opt/cloud/slavespace/usr1/096471637100f3de0fcfc01072822a80/ut/src/asys/info/asys_info.py: 94%

254 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-14 17:42 +0800

1#!/usr/bin/env python3 

2# -*- coding: utf-8 -*- 

3# ---------------------------------------------------------------------------- 

4# Copyright (c) 2025 Huawei Technologies Co., Ltd. 

5# 

6# Licensed under the Apache License, Version 2.0 (the "License"); 

7# you may not use this file except in compliance with the License. 

8# You may obtain a copy of the License at 

9# 

10# http://www.apache.org/licenses/LICENSE-2.0 

11# 

12# Unless required by applicable law or agreed to in writing, software 

13# distributed under the License is distributed on an "AS IS" BASIS, 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

15# See the License for the specific language governing permissions and 

16# limitations under the License. 

17# ---------------------------------------------------------------------------- 

18 

19import os 

20import re 

21import sys 

22 

23from common import run_command 

24from common import get_project_conf, get_ascend_home 

25from common import get_device 

26from common import FileOperate as f 

27from common import timeout_decorator 

28from common import log_error 

29from common.const import UNKNOWN, NONE, MEMORY_FREQUENCY, HBM_FREQUENCY, CONTROL_CPU_FREQUENCY, CannPkg 

30from common.const import AI_CORE_USE, AI_CPU_USE, CONTROL_CPU_USE, MEM_BANDWIDTH_USE, NOT_SUPPORT, MAX_CHAR_LINE 

31from common.const import ConfigOperateType, ConfigOptionName, ALL_NOT_SUPPORTED_CHIP_TYPE, ALL_SUPPORTED_CHIP_TYPE 

32from common.const import GET_DEVICES_INFO_TIMEOUT 

33from params import ParamDict 

34from view import generate_report 

35 

36CPU_TABLE_TITLE = ' CPU Information ' 

37AIC_TABLE_TITLE = ' AI Core Information ' 

38BUS_TABLE_TITLE = ' Bus Information ' 

39MEM_TABLE_TITLE = ' Memory Information ' 

40 

41HOST_VERSION = ' Host Version ' 

42DEVICE_VERSION = ' Device Version ' 

43 

44PCIE_INFO = ' PCIe Info ' 

45 

46LSPCI_GREP_VERSION = "lspci | grep -E 'd100|d500|d801|d802|d803|d806'" 

47GET_COUNT = 'wc -l' 

48 

49 

50class AsysInfo: 

51 def __init__(self): 

52 self.device_info = get_device() 

53 self.device_num = self.device_info.get_device_count() 

54 self.output_root_path = ParamDict().asys_output_timestamp_dir 

55 self.config_table = f().read_config() 

56 self._chip_info = "" 

57 

58 @staticmethod 

59 def __get_pcie_info(table_data): 

60 pcie_info_query_cmds = { 

61 "PCIe Dev Count": f"{LSPCI_GREP_VERSION} | {GET_COUNT}", 

62 "PCIe Dev Count(normal)": f"{LSPCI_GREP_VERSION} | {GET_COUNT}", 

63 "PCIe Dev Count(abnormal)": f"{LSPCI_GREP_VERSION} | grep 'rev ff' | {GET_COUNT}", 

64 } 

65 for query_name, query_cmds in pcie_info_query_cmds.items(): 

66 count = run_command(query_cmds) 

67 if not count.isdigit() or (query_name == "PCIe Dev Count" and count == "0"): 

68 table_data[PCIE_INFO] = [] 

69 break 

70 table_data[PCIE_INFO].append([query_name, count]) 

71 if table_data[PCIE_INFO]: 

72 table_data[PCIE_INFO][1][1] = int(table_data[PCIE_INFO][0][1]) \ 

73 - int(table_data[PCIE_INFO][2][1]) 

74 else: 

75 del table_data[PCIE_INFO] 

76 

77 @staticmethod 

78 def __get_host_info(table_data): 

79 host_info_query_cmds = { 

80 "Cpu Info": "lscpu | grep -oP '^\\s*(BIOS Model name|Model name):\\s+\\K.*' | grep -v '^-$' | head -n1", 

81 "Cpu Physical Count": "lscpu | grep 'Socket(s):' | cut -f2 -d: | uniq", # arm cpuinfo no 'physical id' 

82 "Cpu Logical Count": "cat /proc/cpuinfo| grep 'processor' | wc -l", 

83 "Memory Total Size": "cat /proc/meminfo | sed -n '1p' | awk 'NR=2{print $2, $3}'", 

84 "Disk Total Size": """df -k / |sed -n '2p' | awk 'NR=2{printf $2}END{print " kB"}'""", 

85 } 

86 for query_name, query_cmds in host_info_query_cmds.items(): 

87 host_info = run_command(query_cmds) 

88 if not host_info: 

89 continue 

90 table_data[" Host Info "].append([query_name, host_info]) 

91 

92 def __get_device_info(self, table_data): 

93 ccpu_count = self.device_info.get_device_info_loop( 

94 self.device_num, self.device_info.get_ccpu_count, NOT_SUPPORT 

95 ) 

96 aicpu_count = self.device_info.get_device_info_loop( 

97 self.device_num, self.device_info.get_aicpu_count, NOT_SUPPORT 

98 ) 

99 aicore_count = self.device_info.get_device_info_loop( 

100 self.device_num, self.device_info.get_aicore_count, NOT_SUPPORT 

101 ) 

102 vector_count = self.device_info.get_device_info_loop( 

103 self.device_num, self.device_info.get_veccore_count, NOT_SUPPORT 

104 ) 

105 device_info_query_cmds = { 

106 "NPU Count": self.device_num, 

107 "Chip Info": self.device_info.get_device_info_loop( 

108 self.device_num, self.device_info.get_chip_info, UNKNOWN 

109 ), 

110 "Arch Info": self.device_info.get_device_info_loop( 

111 self.device_num, self.device_info.get_npu_arch, UNKNOWN 

112 ), 

113 "Control CPU Count": str(ccpu_count * self.device_num) + f" ({ccpu_count} * {self.device_num})", 

114 "AI CPU Count": str(aicpu_count * self.device_num) + f" ({aicpu_count} * {self.device_num})", 

115 "AI Core Count": str(aicore_count * self.device_num) + f" ({aicore_count} * {self.device_num})", 

116 "AI Vector Count": str(vector_count * self.device_num) + f" ({vector_count} * {self.device_num})", 

117 } 

118 for query_name, query_cmds in device_info_query_cmds.items(): 

119 table_data[" Device Info "].append([query_name, query_cmds]) 

120 

121 def get_hardware_info(self, write_file=False): 

122 """ 

123 return hardware info report 

124 """ 

125 table_data = { 

126 " Host Info ": [], 

127 " Device Info ": [], 

128 PCIE_INFO: [] 

129 } 

130 # Host Info 

131 self.__get_host_info(table_data) 

132 # Device Info 

133 self.__get_device_info(table_data) 

134 # PCIe Info 

135 self.__get_pcie_info(table_data) 

136 table_header = [[f"Group of {self.device_num} Device", "INFORMATION"]] 

137 table_string = generate_report(table_header, table_data) 

138 if write_file: 

139 hardware_file = os.path.join(self.output_root_path, "hardware_info.txt") 

140 f.write_file(hardware_file, table_string) 

141 else: 

142 sys.stdout.write(table_string) 

143 

144 @staticmethod 

145 def __software_set_env(table_data): 

146 env_info = [] 

147 envs = os.environ 

148 for env_name, env_value in envs.items(): 

149 if env_name == "LS_COLORS" or env_value == "": 

150 continue 

151 if len(env_value) > MAX_CHAR_LINE: 

152 env_info.append([env_name, env_value[:MAX_CHAR_LINE]]) 

153 for i in range(MAX_CHAR_LINE, len(env_value), MAX_CHAR_LINE): 

154 env_info.append(["", env_value[i:i + MAX_CHAR_LINE]]) 

155 else: 

156 env_info.append([env_name, env_value]) 

157 if env_info: 

158 table_data[" Env Information "] = env_info 

159 

160 @staticmethod 

161 def __software_set_dep(table_data): 

162 dependent_packet = [] 

163 dep_info = f.read_file(os.path.join(get_project_conf(), "dependent_package.csv")) 

164 for item in dep_info: 

165 info = run_command(item[1]) 

166 if info == "NONE": 

167 continue 

168 dependent_packet.append([item[0], info]) 

169 if dependent_packet: 

170 table_data[" Dependent Packet "] = dependent_packet 

171 

172 def __check_support_read_option(self, option): 

173 if option not in self.config_table or self._chip_info == UNKNOWN: 

174 return True 

175 supported_chips = self.config_table[option][ConfigOperateType.GET.value] 

176 if ALL_NOT_SUPPORTED_CHIP_TYPE in supported_chips: 

177 return False 

178 if ( 

179 ALL_SUPPORTED_CHIP_TYPE in supported_chips or 

180 any(re.search(rf"{i}", self._chip_info) for i in supported_chips) 

181 ): 

182 return True 

183 return False 

184 

185 def __table_data_append(self, table, value, option): 

186 if value[1] != NOT_SUPPORT and self.__check_support_read_option(option): 

187 table.append(value) 

188 

189 @staticmethod 

190 def __software_set_pkg(table_data): 

191 grep_version = "| grep Version | awk -v FS='=' '{print $2}'" 

192 if ParamDict().get_env_type() == "EP": 

193 install_path = get_ascend_home() 

194 for pag_name in CannPkg.get_all_pkg_list(): 

195 if pag_name in [CannPkg.firmware, CannPkg.driver]: 

196 version = run_command('cat {}/{}/version.info {}'.format(install_path, pag_name, grep_version)) 

197 else: 

198 version = run_command('cat {}/cann/share/info/{}/version.info {}'.format(install_path, pag_name, 

199 grep_version)) 

200 if version == "": 

201 version = "None" 

202 table_data[DEVICE_VERSION].append([pag_name, version]) 

203 else: 

204 driver_version = run_command(f"cat /var/davinci/driver/version.info {grep_version}") 

205 table_data[DEVICE_VERSION].append([CannPkg.driver, driver_version]) 

206 firmware_version = run_command(f"cat /fw/version.info {grep_version}") 

207 table_data[DEVICE_VERSION].append([CannPkg.firmware, firmware_version]) 

208 runtime_version = run_command(f"cat /usr/local/Ascend/latest/runtime/version.info {grep_version}") 

209 if not runtime_version or runtime_version == "NONE": 

210 runtime_version = run_command(f"cat /usr/local/Ascend/runtime/version.info {grep_version}") 

211 table_data[DEVICE_VERSION].append(["runtime", runtime_version]) 

212 

213 def get_software_info(self, write_file=False): 

214 """ 

215 return software info report 

216 """ 

217 table_data = { 

218 HOST_VERSION: [], 

219 DEVICE_VERSION: [] 

220 } 

221 os_version_path = os.sep + "etc/*release" 

222 table_data[HOST_VERSION].append(["Kernel", run_command('uname -r')]) 

223 os_version = run_command("cat " + os_version_path + """ | grep PRETTY_NAME | awk -v FS='"' '{print $2}'""") 

224 table_data[HOST_VERSION].append(["OS", os_version]) 

225 

226 self.__software_set_pkg(table_data) 

227 table_header = [[f"Group of {self.device_num} Device", "INFORMATION"]] 

228 if write_file: 

229 self.__software_set_dep(table_data) 

230 self.__software_set_env(table_data) 

231 table_string = generate_report(table_header, table_data) 

232 software_file = os.path.join(self.output_root_path, "software_info.txt") 

233 f.write_file(software_file, table_string) 

234 else: 

235 table_string = generate_report(table_header, table_data) 

236 sys.stdout.write(table_string) 

237 

238 def __add_status_cpu_info(self, table_data, device_id): 

239 cpu_info = self.device_info.get_device_cpu_info(device_id) 

240 if NOT_SUPPORT in cpu_info: 

241 ai_cpu_c = self.device_info.get_aicpu_count(device_id) 

242 c_cpu_c = self.device_info.get_ccpu_count(device_id) 

243 c_cpu_v = NOT_SUPPORT 

244 c_cpu_f = self.device_info.get_device_frequency(device_id, CONTROL_CPU_FREQUENCY) 

245 else: 

246 ai_cpu_c, c_cpu_c, c_cpu_v, c_cpu_f = cpu_info 

247 

248 cpu_info_list = [] 

249 self.__table_data_append(cpu_info_list, ["AI CPU Count", ai_cpu_c], ConfigOptionName.ACPU_CNT.value) 

250 self.__table_data_append( 

251 cpu_info_list, 

252 ["AI CPU Usage (%)", self.device_info.get_device_utilization_rate(device_id, AI_CPU_USE)], 

253 ConfigOptionName.ACPU_USAGE.value, 

254 ) 

255 self.__table_data_append(cpu_info_list, ["Control CPU Count", c_cpu_c], ConfigOptionName.CCPU_CNT.value) 

256 self.__table_data_append( 

257 cpu_info_list, 

258 ["Control CPU Usage (%)", self.device_info.get_device_utilization_rate(device_id, CONTROL_CPU_USE)], 

259 ConfigOptionName.CCPU_USAGE.value, 

260 ) 

261 self.__table_data_append( 

262 cpu_info_list, ["Control CPU Frequency (MHZ)", c_cpu_f], ConfigOptionName.CCPU_FREQUENCY.value 

263 ) 

264 self.__table_data_append( 

265 cpu_info_list, ["Control CPU Voltage (MV)", c_cpu_v], ConfigOptionName.CCPU_VOLTAGE.value 

266 ) 

267 if cpu_info_list: 

268 table_data[CPU_TABLE_TITLE] = cpu_info_list 

269 else: 

270 table_data.pop(CPU_TABLE_TITLE) 

271 

272 def __add_status_aic_info(self, table_data, device_id): 

273 accuracy_device = get_device(device_id) 

274 aic_info = accuracy_device.get_device_aic_info(device_id) 

275 if any(i in aic_info for i in accuracy_device.UNSUPPORTED_KEY_WORDS): 

276 aic_c = self.device_info.get_aicore_count(device_id) 

277 aic_v = accuracy_device.get_device_voltage(device_id) 

278 aic_f = accuracy_device.get_device_aicore_frequency(device_id) 

279 else: 

280 aic_c, aic_v, aic_f = aic_info 

281 aic_info_list = [] 

282 self.__table_data_append(aic_info_list, ["AI Core Count", aic_c], ConfigOptionName.AIC_CNT.value) 

283 self.__table_data_append( 

284 aic_info_list, 

285 ["AI Core Usage (%)", self.device_info.get_device_utilization_rate(device_id, AI_CORE_USE)], 

286 ConfigOptionName.AIC_USAGE.value, 

287 ) 

288 self.__table_data_append( 

289 aic_info_list, ["AI Core Frequency (MHZ)", aic_f], ConfigOptionName.AIC_FREQUENCY.value 

290 ) 

291 self.__table_data_append(aic_info_list, ["AI Core Voltage (MV)", aic_v], ConfigOptionName.AIC_VOLTAGE.value) 

292 if aic_info_list: 

293 table_data[AIC_TABLE_TITLE] = aic_info_list 

294 else: 

295 table_data.pop(AIC_TABLE_TITLE) 

296 

297 def __add_status_bus_info(self, table_data, device_id): 

298 accuracy_device = get_device(device_id) 

299 bus_v, ring_f, cpu_f, mate_f, l2_buf_f = accuracy_device.get_device_bus_info(device_id) 

300 bus_info_list = [] 

301 self.__table_data_append(bus_info_list, ["Bus Voltage (MV)", bus_v], ConfigOptionName.BUS_VOLTAGE.value) 

302 self.__table_data_append(bus_info_list, ["Ring Frequency (MHZ)", ring_f], ConfigOptionName.RING_FREQUENCY.value) 

303 self.__table_data_append(bus_info_list, ["CPU Frequency (MHZ)", cpu_f], ConfigOptionName.CPU_FREQUENCY.value) 

304 self.__table_data_append(bus_info_list, ["Mata Frequency (MHZ)", mate_f], ConfigOptionName.MATA_FREQUENCY.value) 

305 self.__table_data_append( 

306 bus_info_list, ["L2buffer Frequency (MHZ)", l2_buf_f], ConfigOptionName.L2BUFFER_FREQUENCY.value 

307 ) 

308 if bus_info_list: 

309 table_data[BUS_TABLE_TITLE] = bus_info_list 

310 else: 

311 table_data.pop(BUS_TABLE_TITLE) 

312 

313 def __add_status_memory_info(self, table_data, device_id): 

314 ddr_total, ddr_use = self.device_info.get_device_memory_info(device_id) 

315 hbm_total, hbm_use, _, hbm_bandwidth = get_device(device_id).get_device_hbm_info(device_id) 

316 

317 memory_info_list = [] 

318 if ddr_total != NOT_SUPPORT: 

319 ddr_bandwidth = self.device_info.get_device_utilization_rate(device_id, MEM_BANDWIDTH_USE) 

320 ddr_frequency = self.device_info.get_device_frequency(device_id, MEMORY_FREQUENCY) 

321 self.__table_data_append(memory_info_list, ["DDR Total (MB)", ddr_total], ConfigOptionName.DDR_TOTAL.value) 

322 self.__table_data_append(memory_info_list, ["DDR Used (MB)", ddr_use], ConfigOptionName.DDR_USED.value) 

323 self.__table_data_append( 

324 memory_info_list, ["DDR Bandwidth Usage (%)", ddr_bandwidth], ConfigOptionName.DDR_BANDWIDTH.value 

325 ) 

326 self.__table_data_append( 

327 memory_info_list, ["DDR Frequency (MHZ)", ddr_frequency], ConfigOptionName.DDR_FREQUENCY.value 

328 ) 

329 

330 if hbm_total != NOT_SUPPORT: 

331 hbm_v, hbm_f = self.device_info.get_device_hbm_volt_freq(device_id) 

332 if hbm_f == NOT_SUPPORT: 

333 hbm_f = self.device_info.get_device_frequency(device_id, HBM_FREQUENCY) 

334 self.__table_data_append(memory_info_list, ["HBM Total (MB)", hbm_total], ConfigOptionName.HBM_TOTAL.value) 

335 self.__table_data_append(memory_info_list, ["HBM Used (MB)", hbm_use], ConfigOptionName.HBM_USED.value) 

336 self.__table_data_append( 

337 memory_info_list, ["HBM Bandwidth Usage (%)", hbm_bandwidth], ConfigOptionName.HBM_BANDWIDTH_USE.value 

338 ) 

339 self.__table_data_append( 

340 memory_info_list, ["HBM Frequency (MHZ)", hbm_f], ConfigOptionName.HBM_FREQUENCY.value 

341 ) 

342 self.__table_data_append(memory_info_list, ["HBM Voltage (MV)", hbm_v], ConfigOptionName.HBM_VOLTAGE.value) 

343 

344 if memory_info_list: 

345 table_data[MEM_TABLE_TITLE] = memory_info_list 

346 else: 

347 table_data.pop(MEM_TABLE_TITLE) 

348 

349 def get_status_info(self, device_id, write_file=False): 

350 """ 

351 return status info report 

352 """ 

353 table_data = { 

354 NONE: [], 

355 CPU_TABLE_TITLE: [], 

356 AIC_TABLE_TITLE: [], 

357 BUS_TABLE_TITLE: [], 

358 MEM_TABLE_TITLE: [] 

359 } 

360 # add public information 

361 self._chip_info = self.device_info.get_chip_info(device_id) 

362 self.__table_data_append(table_data[NONE], ["Chip Name", self._chip_info], ConfigOptionName.CHIP_NAME.value) 

363 self.__table_data_append( 

364 table_data[NONE], ["Power (W)", self.device_info.get_device_power(device_id)], ConfigOptionName.POWER.value 

365 ) 

366 self.__table_data_append( 

367 table_data[NONE], 

368 ["Temperature (C)", get_device(device_id).get_device_temperature(device_id)], 

369 ConfigOptionName.TEMPERATURE.value 

370 ) 

371 self.__table_data_append( 

372 table_data[NONE], 

373 ["health", self.device_info.get_device_health(device_id)], 

374 ConfigOptionName.HEALTH.value 

375 ) 

376 

377 # add cpu information 

378 self.__add_status_cpu_info(table_data=table_data, device_id=device_id) 

379 

380 # add aicore information 

381 self.__add_status_aic_info(table_data=table_data, device_id=device_id) 

382 

383 # add bus information 

384 self.__add_status_bus_info(table_data=table_data, device_id=device_id) 

385 

386 # add memory information 

387 self.__add_status_memory_info(table_data=table_data, device_id=device_id) 

388 

389 # Delete the key whose value is empty. 

390 for key, value in table_data.items(): 

391 if not value: 

392 table_data.pop(key) 

393 

394 table_header = [[f"Device ID: {device_id}", "INFORMATION"]] 

395 table_string = generate_report(table_header, table_data) 

396 if write_file: 

397 status_file = os.path.join(self.output_root_path, "status_info.txt") 

398 f.append_write_file(status_file, table_string) 

399 else: 

400 sys.stdout.write(table_string) 

401 

402 @timeout_decorator(GET_DEVICES_INFO_TIMEOUT) 

403 def run_info(self, run_mode, device_id): 

404 if run_mode == "hardware": 

405 self.get_hardware_info() 

406 elif run_mode == "software": 

407 self.get_software_info() 

408 elif run_mode == "status": 

409 self.get_status_info(device_id) 

410 

411 def run(self): 

412 run_mode = ParamDict().get_arg('run_mode') 

413 device_id = ParamDict().get_arg('device_id') if ParamDict().get_arg('device_id') else 0 

414 try: 

415 self.run_info(run_mode, device_id) 

416 except TimeoutError: 

417 log_error(f"Timeout in retrieving the {device_id} chip status, Please check for malfunctions.") 

418 return False 

419 return True 

420 

421 def write_info(self): 

422 self.get_hardware_info(write_file=True) 

423 self.get_software_info(write_file=True) 

424 for device_id in range(self.device_num): 

425 self.get_status_info(device_id, write_file=True)