Launching refreshed version of LLM Engineering weeks 1-4 - see README
This commit is contained in:
359
week4/system_info.py
Normal file
359
week4/system_info.py
Normal file
@@ -0,0 +1,359 @@
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
# ------------------------- helpers -------------------------
|
||||
|
||||
|
||||
def _run(cmd, timeout=3):
|
||||
"""Run a command safely. Returns stdout text or ''.
|
||||
Accepts either a string (shell) or list (no shell)."""
|
||||
try:
|
||||
if isinstance(cmd, str):
|
||||
return subprocess.check_output(
|
||||
cmd, shell=True, text=True, stderr=subprocess.DEVNULL, timeout=timeout
|
||||
).strip()
|
||||
else:
|
||||
return subprocess.check_output(
|
||||
cmd, shell=False, text=True, stderr=subprocess.DEVNULL, timeout=timeout
|
||||
).strip()
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
|
||||
def _first_line(s: str) -> str:
|
||||
s = (s or "").strip()
|
||||
return s.splitlines()[0].strip() if s else ""
|
||||
|
||||
|
||||
def _which(name: str) -> str:
|
||||
return shutil.which(name) or ""
|
||||
|
||||
|
||||
def _bool_from_output(s: str) -> bool:
|
||||
return s.strip() in {"1", "true", "True", "YES", "Yes", "yes"}
|
||||
|
||||
|
||||
# ------------------------- OS & env -------------------------
|
||||
|
||||
|
||||
def _os_block():
|
||||
sysname = platform.system() # 'Windows', 'Darwin', 'Linux'
|
||||
machine = platform.machine() or ""
|
||||
release = platform.release() or ""
|
||||
version = platform.version() or ""
|
||||
kernel = release if sysname == "Windows" else (_run(["uname", "-r"]) or release)
|
||||
|
||||
distro = {"name": "", "version": ""}
|
||||
if sysname == "Linux":
|
||||
# Best-effort parse of /etc/os-release
|
||||
try:
|
||||
with open("/etc/os-release", "r") as f:
|
||||
data = {}
|
||||
for line in f:
|
||||
if "=" in line:
|
||||
k, v = line.rstrip().split("=", 1)
|
||||
data[k] = v.strip('"')
|
||||
distro["name"] = data.get("PRETTY_NAME") or data.get("NAME", "")
|
||||
distro["version"] = data.get("VERSION_ID") or data.get("VERSION", "")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# WSL / Rosetta detection (harmless if not present)
|
||||
wsl = False
|
||||
if sysname != "Windows":
|
||||
try:
|
||||
with open("/proc/version", "r") as f:
|
||||
v = f.read().lower()
|
||||
wsl = ("microsoft" in v) or ("wsl" in v)
|
||||
except Exception:
|
||||
wsl = False
|
||||
|
||||
rosetta = False
|
||||
if sysname == "Darwin":
|
||||
rosetta = _bool_from_output(_run(["sysctl", "-in", "sysctl.proc_translated"]))
|
||||
|
||||
# Target triple (best effort)
|
||||
target = ""
|
||||
for cc in ("clang", "gcc"):
|
||||
if _which(cc):
|
||||
out = _run([cc, "-dumpmachine"])
|
||||
if out:
|
||||
target = _first_line(out)
|
||||
break
|
||||
|
||||
return {
|
||||
"system": sysname,
|
||||
"arch": machine,
|
||||
"release": release,
|
||||
"version": version,
|
||||
"kernel": kernel,
|
||||
"distro": distro if sysname == "Linux" else None,
|
||||
"wsl": wsl,
|
||||
"rosetta2_translated": rosetta,
|
||||
"target_triple": target,
|
||||
}
|
||||
|
||||
|
||||
# ------------------------- package managers -------------------------
|
||||
|
||||
|
||||
def _package_managers():
|
||||
sysname = platform.system()
|
||||
pms = []
|
||||
if sysname == "Windows":
|
||||
for pm in ("winget", "choco", "scoop"):
|
||||
if _which(pm):
|
||||
pms.append(pm)
|
||||
elif sysname == "Darwin":
|
||||
if _run(["xcode-select", "-p"]):
|
||||
pms.append("xcode-select (CLT)")
|
||||
for pm in ("brew", "port"):
|
||||
if _which(pm):
|
||||
pms.append(pm)
|
||||
else:
|
||||
for pm in ("apt", "dnf", "yum", "pacman", "zypper", "apk", "emerge"):
|
||||
if _which(pm):
|
||||
pms.append(pm)
|
||||
return pms
|
||||
|
||||
|
||||
# ------------------------- CPU (minimal) -------------------------
|
||||
|
||||
|
||||
def _cpu_block():
|
||||
sysname = platform.system()
|
||||
brand = ""
|
||||
# A simple brand/model read per OS; ignore failures
|
||||
if sysname == "Linux":
|
||||
brand = _run("grep -m1 'model name' /proc/cpuinfo | cut -d: -f2").strip()
|
||||
elif sysname == "Darwin":
|
||||
brand = _run(["sysctl", "-n", "machdep.cpu.brand_string"])
|
||||
elif sysname == "Windows":
|
||||
brand = _run('powershell -NoProfile -Command "(Get-CimInstance Win32_Processor).Name"')
|
||||
if not brand:
|
||||
brand = _run("wmic cpu get Name /value").replace("Name=", "").strip()
|
||||
|
||||
# Logical cores always available; physical is best-effort
|
||||
cores_logical = os.cpu_count() or 0
|
||||
cores_physical = 0
|
||||
if sysname == "Darwin":
|
||||
cores_physical = int(_run(["sysctl", "-n", "hw.physicalcpu"]) or "0")
|
||||
elif sysname == "Windows":
|
||||
cores_physical = int(
|
||||
_run('powershell -NoProfile -Command "(Get-CimInstance Win32_Processor).NumberOfCores"')
|
||||
or "0"
|
||||
)
|
||||
elif sysname == "Linux":
|
||||
# This is a quick approximation; fine for our use (parallel -j suggestions)
|
||||
try:
|
||||
# Count unique "core id" per physical id
|
||||
mapping = _run("LC_ALL=C lscpu -p=CORE,SOCKET | grep -v '^#'").splitlines()
|
||||
unique = set(tuple(line.split(",")) for line in mapping if "," in line)
|
||||
cores_physical = len(unique) or 0
|
||||
except Exception:
|
||||
cores_physical = 0
|
||||
|
||||
# A tiny SIMD hint set (best-effort, optional)
|
||||
simd = []
|
||||
if sysname == "Linux":
|
||||
flags = _run("grep -m1 'flags' /proc/cpuinfo | cut -d: -f2")
|
||||
if flags:
|
||||
fset = set(flags.upper().split())
|
||||
for x in ("AVX512F", "AVX2", "AVX", "FMA", "SSE4_2", "NEON", "SVE"):
|
||||
if x in fset:
|
||||
simd.append(x)
|
||||
elif sysname == "Darwin":
|
||||
feats = (
|
||||
(
|
||||
_run(["sysctl", "-n", "machdep.cpu.features"])
|
||||
+ " "
|
||||
+ _run(["sysctl", "-n", "machdep.cpu.leaf7_features"])
|
||||
)
|
||||
.upper()
|
||||
.split()
|
||||
)
|
||||
for x in ("AVX512F", "AVX2", "AVX", "FMA", "SSE4_2", "NEON", "SVE"):
|
||||
if x in feats:
|
||||
simd.append(x)
|
||||
# On Windows, skip flags — brand typically suffices for MSVC /arch choice.
|
||||
|
||||
return {
|
||||
"brand": brand.strip(),
|
||||
"cores_logical": cores_logical,
|
||||
"cores_physical": cores_physical,
|
||||
"simd": sorted(set(simd)),
|
||||
}
|
||||
|
||||
|
||||
# ------------------------- toolchain presence -------------------------
|
||||
|
||||
|
||||
def _toolchain_block():
|
||||
def ver_line(exe, args=("--version",)):
|
||||
p = _which(exe)
|
||||
if not p:
|
||||
return ""
|
||||
out = _run([p, *args])
|
||||
return _first_line(out)
|
||||
|
||||
gcc = ver_line("gcc")
|
||||
gpp = ver_line("g++")
|
||||
clang = ver_line("clang")
|
||||
|
||||
# MSVC cl (only available inside proper dev shell; handle gracefully)
|
||||
msvc_cl = ""
|
||||
cl_path = _which("cl")
|
||||
if cl_path:
|
||||
msvc_cl = _first_line(_run("cl 2>&1"))
|
||||
|
||||
# Build tools (presence + short version line)
|
||||
cmake = ver_line("cmake")
|
||||
ninja = _first_line(_run([_which("ninja"), "--version"])) if _which("ninja") else ""
|
||||
make = ver_line("make")
|
||||
|
||||
# Linker (we only care if lld is available)
|
||||
lld = ver_line("ld.lld")
|
||||
return {
|
||||
"compilers": {"gcc": gcc, "g++": gpp, "clang": clang, "msvc_cl": msvc_cl},
|
||||
"build_tools": {"cmake": cmake, "ninja": ninja, "make": make},
|
||||
"linkers": {"ld_lld": lld},
|
||||
}
|
||||
|
||||
|
||||
# ------------------------- public API -------------------------
|
||||
|
||||
|
||||
def retrieve_system_info():
|
||||
"""
|
||||
Returns a compact dict with enough info for an LLM to:
|
||||
- Pick an install path (winget/choco/scoop, Homebrew/Xcode CLT, apt/dnf/...),
|
||||
- Choose a compiler family (MSVC/clang/gcc),
|
||||
- Suggest safe optimization flags (e.g., -O3/-march=native or MSVC /O2),
|
||||
- Decide on a build system (cmake+ninja) and parallel -j value.
|
||||
"""
|
||||
return {
|
||||
"os": _os_block(),
|
||||
"package_managers": _package_managers(),
|
||||
"cpu": _cpu_block(),
|
||||
"toolchain": _toolchain_block(),
|
||||
}
|
||||
|
||||
|
||||
def rust_toolchain_info():
|
||||
"""
|
||||
Return a dict with Rust-related settings:
|
||||
- presence and paths for rustc / cargo / rustup / rust-analyzer
|
||||
- versions
|
||||
- active/default toolchain (if rustup is present)
|
||||
- installed targets
|
||||
- common env vars (CARGO_HOME, RUSTUP_HOME, RUSTFLAGS, CARGO_BUILD_TARGET)
|
||||
- simple execution examples
|
||||
Works on Windows, macOS, and Linux. Uses the existing helpers: _run, _which, _first_line.
|
||||
"""
|
||||
info = {
|
||||
"installed": False,
|
||||
"rustc": {"path": "", "version": "", "host_triple": "", "release": "", "commit_hash": ""},
|
||||
"cargo": {"path": "", "version": ""},
|
||||
"rustup": {
|
||||
"path": "",
|
||||
"version": "",
|
||||
"active_toolchain": "",
|
||||
"default_toolchain": "",
|
||||
"toolchains": [],
|
||||
"targets_installed": [],
|
||||
},
|
||||
"rust_analyzer": {"path": ""},
|
||||
"env": {
|
||||
"CARGO_HOME": os.environ.get("CARGO_HOME", ""),
|
||||
"RUSTUP_HOME": os.environ.get("RUSTUP_HOME", ""),
|
||||
"RUSTFLAGS": os.environ.get("RUSTFLAGS", ""),
|
||||
"CARGO_BUILD_TARGET": os.environ.get("CARGO_BUILD_TARGET", ""),
|
||||
},
|
||||
"execution_examples": [],
|
||||
}
|
||||
|
||||
# Paths
|
||||
rustc_path = _which("rustc")
|
||||
cargo_path = _which("cargo")
|
||||
rustup_path = _which("rustup")
|
||||
ra_path = _which("rust-analyzer")
|
||||
|
||||
info["rustc"]["path"] = rustc_path or ""
|
||||
info["cargo"]["path"] = cargo_path or ""
|
||||
info["rustup"]["path"] = rustup_path or ""
|
||||
info["rust_analyzer"]["path"] = ra_path or ""
|
||||
|
||||
# Versions & verbose details
|
||||
if rustc_path:
|
||||
ver_line = _first_line(_run([rustc_path, "--version"]))
|
||||
info["rustc"]["version"] = ver_line
|
||||
verbose = _run([rustc_path, "--version", "--verbose"])
|
||||
host = release = commit = ""
|
||||
for line in verbose.splitlines():
|
||||
if line.startswith("host:"):
|
||||
host = line.split(":", 1)[1].strip()
|
||||
elif line.startswith("release:"):
|
||||
release = line.split(":", 1)[1].strip()
|
||||
elif line.startswith("commit-hash:"):
|
||||
commit = line.split(":", 1)[1].strip()
|
||||
info["rustc"]["host_triple"] = host
|
||||
info["rustc"]["release"] = release
|
||||
info["rustc"]["commit_hash"] = commit
|
||||
|
||||
if cargo_path:
|
||||
info["cargo"]["version"] = _first_line(_run([cargo_path, "--version"]))
|
||||
|
||||
if rustup_path:
|
||||
info["rustup"]["version"] = _first_line(_run([rustup_path, "--version"]))
|
||||
# Active toolchain
|
||||
active = _first_line(_run([rustup_path, "show", "active-toolchain"]))
|
||||
info["rustup"]["active_toolchain"] = active
|
||||
|
||||
# Default toolchain (best effort)
|
||||
# Try parsing `rustup toolchain list` and pick the line with "(default)"
|
||||
tlist = _run([rustup_path, "toolchain", "list"]).splitlines()
|
||||
info["rustup"]["toolchains"] = [t.strip() for t in tlist if t.strip()]
|
||||
default_tc = ""
|
||||
for line in tlist:
|
||||
if "(default)" in line:
|
||||
default_tc = line.strip()
|
||||
break
|
||||
if not default_tc:
|
||||
# Fallback: sometimes `rustup show` includes "default toolchain: ..."
|
||||
for line in _run([rustup_path, "show"]).splitlines():
|
||||
if "default toolchain:" in line:
|
||||
default_tc = line.split(":", 1)[1].strip()
|
||||
break
|
||||
info["rustup"]["default_toolchain"] = default_tc
|
||||
|
||||
# Installed targets
|
||||
targets = _run([rustup_path, "target", "list", "--installed"]).split()
|
||||
info["rustup"]["targets_installed"] = targets
|
||||
|
||||
# Execution examples (only include what will work on this system)
|
||||
exec_examples = []
|
||||
if cargo_path:
|
||||
exec_examples.append(f'"{cargo_path}" build')
|
||||
exec_examples.append(f'"{cargo_path}" run')
|
||||
exec_examples.append(f'"{cargo_path}" test')
|
||||
if rustc_path:
|
||||
exec_examples.append(f'"{rustc_path}" hello.rs -o hello')
|
||||
info["execution_examples"] = exec_examples
|
||||
|
||||
# Installed?
|
||||
info["installed"] = bool(rustc_path or cargo_path or rustup_path)
|
||||
|
||||
# Fill in default homes if env vars are empty but typical locations exist
|
||||
def _maybe_default_home(env_val, default_basename):
|
||||
if env_val:
|
||||
return env_val
|
||||
home = os.path.expanduser("~") or ""
|
||||
candidate = os.path.join(home, default_basename) if home else ""
|
||||
return candidate if candidate and os.path.isdir(candidate) else ""
|
||||
|
||||
info["env"]["CARGO_HOME"] = _maybe_default_home(info["env"]["CARGO_HOME"], ".cargo")
|
||||
info["env"]["RUSTUP_HOME"] = _maybe_default_home(info["env"]["RUSTUP_HOME"], ".rustup")
|
||||
|
||||
return info
|
||||
Reference in New Issue
Block a user