|
72 | 72 | "23.1": "2.0", |
73 | 73 | } |
74 | 74 |
|
| 75 | +# source: https://developer.nvidia.com/embedded/jetson-modules |
| 76 | +BOARD_MEMORY_BITRATE: dict[str, int] = { |
| 77 | + # Orin series |
| 78 | + "Orin AGX 64Gb": 256, |
| 79 | + "Orin AGX 32Gb": 256, |
| 80 | + "Orin NX 16Gb": 128, |
| 81 | + "Orin NX 8Gb": 128, |
| 82 | + "Orin Nano 8Gb": 128, |
| 83 | + "Orin Nano 4Gb": 64, |
| 84 | + # Xavier series |
| 85 | + "Xavier AGX 64Gb": 256, |
| 86 | + "Xavier AGX 32Gb": 256, |
| 87 | + "Xavier NX 16Gb": 128, |
| 88 | + "Xavier NX 8Gb": 128, |
| 89 | + # Others |
| 90 | + "TX2i": 128, |
| 91 | + "TX2 8Gb": 128, |
| 92 | + "TX2 4Gb": 128, |
| 93 | + "TX2 NX": 128, |
| 94 | + "Jetson Nano": 64, |
| 95 | + # add backup for unknown |
| 96 | + "UNKNOWN": 0, |
| 97 | +} |
| 98 | + |
75 | 99 |
|
76 | 100 | def _run(cmd: list[str], *, strip: bool = True) -> str: |
77 | 101 | try: |
@@ -179,6 +203,23 @@ def _jetson_boardids() -> str: |
179 | 203 | return _read("/proc/device-tree/nvidia,boardids") |
180 | 204 |
|
181 | 205 |
|
| 206 | +def _memory_size() -> str: |
| 207 | + meminfo = _read("/proc/meminfo") |
| 208 | + if not meminfo: |
| 209 | + return "UNKNOWN" |
| 210 | + |
| 211 | + for line in meminfo.splitlines(): |
| 212 | + if line.startswith("MemTotal:"): |
| 213 | + mem_kb = int(line.split()[1]) |
| 214 | + mem_gb = mem_kb / (1024 * 1024) |
| 215 | + |
| 216 | + # round to closest size |
| 217 | + standard_sizes = [64, 32, 16, 8, 4] |
| 218 | + closest_size = min(standard_sizes, key=lambda x: abs(x - mem_gb)) |
| 219 | + return f"{closest_size}GB" |
| 220 | + return "UNKNOWN" |
| 221 | + |
| 222 | + |
182 | 223 | def _codename_dts_module_carrier() -> tuple[str, str, str]: |
183 | 224 | dtsfile = _read("/proc/device-tree/nvidia,dtsfilename") |
184 | 225 | if not dtsfile: |
@@ -248,16 +289,67 @@ def _jetson_jetpack(l4t: str) -> str: |
248 | 289 | return L4T_TO_JETPACK.get(l4t, "UNKNOWN") |
249 | 290 |
|
250 | 291 |
|
| 292 | +def _get_board_name(model: str, memory_size: str) -> str: |
| 293 | + model = model.upper() |
| 294 | + memory_size = memory_size.replace("GB", "Gb") |
| 295 | + |
| 296 | + # Identify the series |
| 297 | + if "ORIN" in model: |
| 298 | + series = "Orin" |
| 299 | + elif "XAVIER" in model: |
| 300 | + series = "Xavier" |
| 301 | + elif "TX2" in model: |
| 302 | + series = "TX2" |
| 303 | + elif "NANO" in model: |
| 304 | + # handle Jetson nano special |
| 305 | + return "Jetson Nano" |
| 306 | + else: |
| 307 | + return "UNKNOWN" |
| 308 | + |
| 309 | + # Identify form factor for Orin and Xavier |
| 310 | + if series in ["Orin", "Xavier"]: |
| 311 | + if "AGX" in model: |
| 312 | + form_factor = "AGX" |
| 313 | + elif "NX" in model: |
| 314 | + form_factor = "NX" |
| 315 | + elif "NANO" in model: |
| 316 | + form_factor = "Nano" |
| 317 | + else: |
| 318 | + return "UNKNOWN" |
| 319 | + |
| 320 | + return f"{series} {form_factor} {memory_size}" |
| 321 | + if series == "TX2": |
| 322 | + if "NX" in model: |
| 323 | + return "TX2 NX" |
| 324 | + if "4GB" in memory_size or "4Gb" in memory_size: |
| 325 | + return "TX2 4Gb" |
| 326 | + if "8GB" in memory_size or "8Gb" in memory_size: |
| 327 | + return "TX2 8Gb" |
| 328 | + if "TX2I" in model: |
| 329 | + return "TX2i" |
| 330 | + return f"TX2 {memory_size}" |
| 331 | + return "UNKNOWN" |
| 332 | + |
| 333 | + |
| 334 | +def _get_mem_bitrate(name: str) -> int: |
| 335 | + return BOARD_MEMORY_BITRATE.get(name, 0) |
| 336 | + |
| 337 | + |
251 | 338 | @dataclass |
252 | 339 | class JetsonInfo: |
253 | 340 | """Class to store information about the Jetson device.""" |
254 | 341 |
|
255 | 342 | # core hardware info |
| 343 | + name: str = field(repr=True) |
256 | 344 | model: str = field(repr=True) |
257 | 345 | jetpack: str = field(repr=True) |
258 | 346 | l4t: str = field(repr=True) |
259 | 347 | cuda_arch: str = field(repr=True) |
260 | 348 |
|
| 349 | + # additional hardware info |
| 350 | + memory_size: str = field(repr=True) |
| 351 | + memory_bitrate: int = field(repr=True) |
| 352 | + |
261 | 353 | # software info |
262 | 354 | cuda: str = field(repr=True) |
263 | 355 | cudnn: str = field(repr=True) |
@@ -293,16 +385,22 @@ def _get_info() -> JetsonInfo: |
293 | 385 | jetson_boardids = _jetson_boardids() |
294 | 386 | codename, module, carrier = _codename_dts_module_carrier() |
295 | 387 | cuda_arch = _cuda_arch_bin(jetson_model) |
| 388 | + memory_size = _memory_size() |
296 | 389 | serial_number = _serial_number() |
297 | 390 | _, _, l4t = _jetson_l4t() |
298 | 391 | jetpack = _jetson_jetpack(l4t) |
| 392 | + name = _get_board_name(jetson_model, memory_size) |
| 393 | + memory_bitrate = _get_mem_bitrate(name) |
299 | 394 |
|
300 | 395 | return JetsonInfo( |
| 396 | + name=name, |
301 | 397 | model=jetson_model, |
302 | 398 | jetpack=jetpack, |
303 | 399 | l4t=l4t, |
304 | 400 | cuda=cuda_version, |
305 | 401 | cuda_arch=cuda_arch, |
| 402 | + memory_size=memory_size, |
| 403 | + memory_bitrate=memory_bitrate, |
306 | 404 | cudnn=cudnn_version, |
307 | 405 | tensorrt=tensorrt_version, |
308 | 406 | visionworks=visionworks_version, |
@@ -343,11 +441,14 @@ def get_info(*, verbose: bool | None = None) -> JetsonInfo: |
343 | 441 | jetson_info = _get_info() |
344 | 442 |
|
345 | 443 | if verbose: |
| 444 | + LOG.info(f"Board name: {jetson_info.name}") |
346 | 445 | LOG.info(f"Jetson model: {jetson_info.model}") |
347 | 446 | LOG.info(f"Jetpack: {jetson_info.jetpack}") |
348 | 447 | LOG.info(f"L4T: {jetson_info.l4t}") |
349 | 448 | LOG.info(f"CUDA: {jetson_info.cuda}") |
350 | 449 | LOG.info(f"CUDA arch: {jetson_info.cuda_arch}") |
| 450 | + LOG.info(f"Memory size: {jetson_info.memory_size}") |
| 451 | + LOG.info(f"Memory bitrate: {jetson_info.memory_bitrate}") |
351 | 452 | LOG.info(f"CUDNN: {jetson_info.cudnn}") |
352 | 453 | LOG.info(f"TensorRT: {jetson_info.tensorrt}") |
353 | 454 | LOG.info(f"VisionWorks: {jetson_info.visionworks}") |
|
0 commit comments