Skip to content

Instantly share code, notes, and snippets.

@nandhu-44
Last active January 30, 2026 10:01
Show Gist options
  • Select an option

  • Save nandhu-44/fe9bf4c512cfd158a8d09e9cc22021ee to your computer and use it in GitHub Desktop.

Select an option

Save nandhu-44/fe9bf4c512cfd158a8d09e9cc22021ee to your computer and use it in GitHub Desktop.
List specs
#!/usr/bin/env python3
"""
Tejaswi HPC Node Hardware Specs Collector
Lists detailed CPU and GPU information for the current node.
Run this script as a regular user (or with sudo for more details like dmidecode).
"""
import subprocess
import sys
from datetime import datetime
def run_command(cmd, check=True, capture_output=True, text=True):
"""Helper to run shell commands safely."""
try:
result = subprocess.run(
cmd, shell=True, check=check,
capture_output=capture_output, text=text
)
return result.stdout.strip() if capture_output else result
except subprocess.CalledProcessError as e:
print(f"Command failed: {cmd}\nError: {e.stderr.strip()}", file=sys.stderr)
return None
def get_cpu_info():
"""Gather and print detailed CPU information — nothing omitted."""
info = {}
# lscpu full output parsed
lscpu = run_command("lscpu")
if lscpu:
for line in lscpu.splitlines():
if ':' in line:
key, val = line.split(':', 1)
info[key.strip()] = val.strip()
# Model name from /proc/cpuinfo
model = run_command("cat /proc/cpuinfo | grep 'model name' | head -1 | cut -d':' -f2-")
if model:
info["Model Name"] = model.strip()
sockets = info.get("Socket(s)", "N/A")
cores_per_socket = info.get("Core(s) per socket", "N/A")
threads_per_core = info.get("Thread(s) per core", "N/A")
total_cpus = info.get("CPU(s)", "N/A")
print("\n=== CPU / Processor Summary (full details) ===")
print(f"Architecture: {info.get('Architecture', 'N/A')}")
print(f"Model Name: {info.get('Model Name', 'N/A')}")
print(f"CPU op-mode(s): {info.get('CPU op-mode(s)', 'N/A')}")
print(f"Byte Order: {info.get('Byte Order', 'N/A')}")
print(f"Address sizes: {info.get('Address sizes', 'N/A')}")
print(f"CPU(s): {total_cpus}")
print(f"On-line CPU(s) list: {info.get('On-line CPU(s) list', 'N/A')}")
print(f"Thread(s) per core: {threads_per_core}")
print(f"Core(s) per socket: {cores_per_socket}")
print(f"Socket(s): {sockets}")
print(f"NUMA node(s): {info.get('NUMA node(s)', 'N/A')}")
print(f"Vendor ID: {info.get('Vendor ID', 'N/A')}")
print(f"CPU family: {info.get('CPU family', 'N/A')}")
print(f"Model: {info.get('Model', 'N/A')}")
print(f"Model name: {info.get('Model name', 'N/A')}")
print(f"Stepping: {info.get('Stepping', 'N/A')}")
print(f"CPU MHz: {info.get('CPU MHz', 'N/A')}")
print(f"CPU max MHz: {info.get('CPU max MHz', 'N/A')}")
print(f"CPU min MHz: {info.get('CPU min MHz', 'N/A')}")
print(f"BogoMIPS: {info.get('BogoMIPS', 'N/A')}")
print(f"Virtualization: {info.get('Virtualization', 'N/A')}")
print(f"L1d cache: {info.get('L1d cache', 'N/A')}")
print(f"L1i cache: {info.get('L1i cache', 'N/A')}")
print(f"L2 cache: {info.get('L2 cache', 'N/A')}")
print(f"L3 cache: {info.get('L3 cache', 'N/A')}")
print(f"NUMA node0 CPU(s): {info.get('NUMA node0 CPU(s)', 'N/A')}")
# Print ALL NUMA mappings fully — no omission
print("\nFull NUMA Node → CPU Mappings:")
numa_lines = run_command("lscpu | grep 'NUMA node.*CPU(s)'")
if numa_lines:
for line in numa_lines.splitlines():
if line.strip():
print(" " + line.strip())
else:
print(" (No NUMA mapping details found)")
def get_gpu_info():
"""Gather NVIDIA GPU information using nvidia-smi."""
print("\n=== GPU Summary (via nvidia-smi) ===")
smi_summary = run_command("nvidia-smi --query-gpu=index,name,memory.total,memory.used,utilization.gpu,power.draw,power.limit,temperature.gpu --format=csv,noheader,nounits")
if not smi_summary:
print("nvidia-smi not found or failed.")
return
print("GPU | Name | Mem Total/Used (MiB) | Util (%) | Power (W) | Temp (°C)")
print("-" * 85)
for line in smi_summary.splitlines():
fields = [f.strip() for f in line.split(',')]
if len(fields) >= 7:
idx, name, mem_total, mem_used, util, pwr, temp = fields[0], fields[1], fields[2], fields[3], fields[4], fields[5], fields[6]
pwr_limit = fields[6] if len(fields) > 6 else "N/A"
print(f"{idx:>3} | {name:<21} | {mem_total:>6} / {mem_used:>6} | {util:>7} | {pwr:>4}/{pwr_limit:>4} | {temp:>4}")
# Driver & CUDA
driver_line = run_command("nvidia-smi | head -n 1 | grep -o 'Driver Version:.*CUDA Version:.*'")
if driver_line:
print(f"\n{driver_line}")
# Topology
topo = run_command("nvidia-smi topo -m")
if topo:
print("\nGPU Interconnect Topology (full):")
print(topo)
def main():
print(f"Tejaswi HPC Node Hardware Specs Report")
print(f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S IST')}")
print(f"Hostname: {run_command('hostname -f') or 'N/A'}")
print("=" * 70)
get_cpu_info()
get_gpu_info()
print("\nNote: For even more hardware details (DIMM layout, BIOS, etc.), run with sudo:")
print(" sudo dmidecode --type memory | grep -E 'Size|Locator|Speed|Manufacturer|Part'")
print(" sudo dmidecode --type processor | grep -E 'Version|Core|Thread|Family| stepping'")
print("\nDone. This shows specs of THIS node only.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment