init commit
This commit is contained in:
90
ultralytics/utils/cpu.py
Normal file
90
ultralytics/utils/cpu.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class CPUInfo:
|
||||
"""
|
||||
Provide cross-platform CPU brand and model information.
|
||||
|
||||
Query platform-specific sources to retrieve a human-readable CPU descriptor and normalize it for consistent
|
||||
presentation across macOS, Linux, and Windows. If platform-specific probing fails, generic platform identifiers are
|
||||
used to ensure a stable string is always returned.
|
||||
|
||||
Methods:
|
||||
name: Return the normalized CPU name using platform-specific sources with robust fallbacks.
|
||||
_clean: Normalize and prettify common vendor brand strings and frequency patterns.
|
||||
__str__: Return the normalized CPU name for string contexts.
|
||||
|
||||
Examples:
|
||||
>>> CPUInfo.name()
|
||||
'Apple M4 Pro'
|
||||
>>> str(CPUInfo())
|
||||
'Intel Core i7-9750H 2.60GHz'
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def name() -> str:
|
||||
"""Return a normalized CPU model string from platform-specific sources."""
|
||||
try:
|
||||
if sys.platform == "darwin":
|
||||
# Query macOS sysctl for the CPU brand string
|
||||
s = subprocess.run(
|
||||
["sysctl", "-n", "machdep.cpu.brand_string"], capture_output=True, text=True
|
||||
).stdout.strip()
|
||||
if s:
|
||||
return CPUInfo._clean(s)
|
||||
elif sys.platform.startswith("linux"):
|
||||
# Parse /proc/cpuinfo for the first "model name" entry
|
||||
p = Path("/proc/cpuinfo")
|
||||
if p.exists():
|
||||
for line in p.read_text(errors="ignore").splitlines():
|
||||
if "model name" in line:
|
||||
return CPUInfo._clean(line.split(":", 1)[1])
|
||||
elif sys.platform.startswith("win"):
|
||||
try:
|
||||
import winreg as wr
|
||||
|
||||
with wr.OpenKey(wr.HKEY_LOCAL_MACHINE, r"HARDWARE\DESCRIPTION\System\CentralProcessor\0") as k:
|
||||
val, _ = wr.QueryValueEx(k, "ProcessorNameString")
|
||||
if val:
|
||||
return CPUInfo._clean(val)
|
||||
except Exception:
|
||||
# Fall through to generic platform fallbacks on Windows registry access failure
|
||||
pass
|
||||
# Generic platform fallbacks
|
||||
s = platform.processor() or getattr(platform.uname(), "processor", "") or platform.machine()
|
||||
return CPUInfo._clean(s or "Unknown CPU")
|
||||
except Exception:
|
||||
# Ensure a string is always returned even on unexpected failures
|
||||
s = platform.processor() or platform.machine() or ""
|
||||
return CPUInfo._clean(s or "Unknown CPU")
|
||||
|
||||
@staticmethod
|
||||
def _clean(s: str) -> str:
|
||||
"""Normalize and prettify a raw CPU descriptor string."""
|
||||
s = re.sub(r"\s+", " ", s.strip())
|
||||
s = s.replace("(TM)", "").replace("(tm)", "").replace("(R)", "").replace("(r)", "").strip()
|
||||
# Normalize common Intel pattern to 'Model Freq'
|
||||
m = re.search(r"(Intel.*?i\d[\w-]*) CPU @ ([\d.]+GHz)", s, re.I)
|
||||
if m:
|
||||
return f"{m.group(1)} {m.group(2)}"
|
||||
# Normalize common AMD Ryzen pattern to 'Model Freq'
|
||||
m = re.search(r"(AMD.*?Ryzen.*?[\w-]*) CPU @ ([\d.]+GHz)", s, re.I)
|
||||
if m:
|
||||
return f"{m.group(1)} {m.group(2)}"
|
||||
return s
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Return the normalized CPU name."""
|
||||
return self.name()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(CPUInfo.name())
|
||||
Reference in New Issue
Block a user