Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion comfy_cli/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,29 @@ def _detect_gpu_amd() -> dict | None:
}


def _is_apple_silicon(machine: str) -> bool:
"""True when the underlying CPU is Apple Silicon (Darwin already assumed).

A native arm64 process reports ``machine == 'arm64'`` directly. An x86_64
Python running under Rosetta 2 on an Apple Silicon Mac reports
``machine == 'x86_64'``, so fall back to ``sysctl.proc_translated`` — a value
of ``'1'`` means the process is translated, which only happens on Apple
Silicon. Genuine Intel Macs lack that sysctl key, so ``_run`` returns
``None`` and this stays False.
"""
if machine == "arm64":
return True
return _run(["sysctl", "-n", "sysctl.proc_translated"]) == "1"


def _detect_gpu(system: str, machine: str, cpu: str | None) -> dict | None:
"""Resolve the GPU block, or ``None`` if no GPU is detected.

Apple Silicon is unified-memory (the RAM figure IS the GPU budget). Every
other path tries NVIDIA (nvidia-smi then ctypes), then AMD.
"""
try:
if system == "Darwin" and machine == "arm64":
if system == "Darwin" and _is_apple_silicon(machine):
return {
"vendor": "apple",
"model": cpu,
Expand Down
30 changes: 30 additions & 0 deletions tests/comfy_cli/test_hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,36 @@ def test_intel_mac_has_no_apple_gpu(self):
assert hw["gpu"] is None
assert hw["ram_bytes"] == 17179869184

def test_apple_silicon_under_rosetta_unified_block(self):
"""An x86_64 Python under Rosetta 2 reports machine == 'x86_64', but
sysctl.proc_translated == '1' reveals the underlying Apple Silicon, so
the unified-memory block is still reported (not gpu null)."""

def fake_run(cmd):
if cmd == ["sysctl", "-n", "sysctl.proc_translated"]:
return "1"
if cmd == ["sysctl", "-n", "machdep.cpu.brand_string"]:
return "Apple M4 Max"
return None

with (
patch.object(hardware.platform, "system", return_value="Darwin"),
patch.object(hardware.platform, "machine", return_value="x86_64"),
patch.object(hardware.platform, "release", return_value="25.4.0"),
patch.object(hardware, "_run", side_effect=fake_run),
patch.object(hardware, "_detect_ram_bytes", return_value=68719476736),
):
hw = hardware.detect_hardware()

assert hw["arch"] == "x86_64"
assert hw["cpu"] == "Apple M4 Max"
assert hw["gpu"] == {
"vendor": "apple",
"model": "Apple M4 Max",
"vram_bytes": None,
"unified_memory": True,
}


class TestDetectHardwareNvidiaSmi:
def test_nvidia_smi_happy_path(self):
Expand Down
Loading