The priority loop in _resolve_auto recognises only 'torch', 'metal' and 'cuda_kernel' (hypyp/sync/base.py:433-439):
for backend in priority:
if backend == 'torch' and TORCH_AVAILABLE:
return cls._resolve_torch()
if backend == 'metal' and METAL_AVAILABLE:
return 'metal', 'mps'
if backend == 'cuda_kernel' and CUPY_AVAILABLE:
return 'cuda_kernel', 'cuda'
'numba' (and 'numpy') can never match. Yet 'numba' appears inside priority examples in three documented places:
hypyp/sync/__init__.py:112 — Example: ['metal', 'torch', 'numba']
hypyp/sync/__init__.py:128-129 — >>> pli = get_metric('pli', optimization='auto', priority=['numba', 'metal'])
hypyp/sync/README.md:112 (the priority-override section)
Measured on a CPU-only machine:
priority=['numba','metal'] -> backend=numba device=cpu
warnings=["No GPU available. optimization='auto' selects the best GPU backend..."]
The resulting numba comes from the CPU fallback at base.py:441-449, not from the priority list. On an Apple machine with Metal available, priority=['numba', 'metal'] yields metal — the opposite of the stated intent, since 'numba' is skipped and 'metal' matches.
tests/test_sync.py:958 test_auto_priority_override asserts _backend == 'numba' for priority=['numba'] and passes — but for the wrong reason, via the fallback path. It does not use pytest.warns, so the "No GPU backend available" warning that fires along the way is invisible. A completely broken priority loop would still pass this test.
Suggested fix: either honour CPU backends in the priority loop (so priority=['numba', 'metal'] really means "numba first"), or reject them with a clear ValueError and remove 'numba' from all three documented examples. Also make test_auto_priority_override assert the absence of the fallback warning, so it validates the path it claims to.
The
priorityloop in_resolve_autorecognises only'torch','metal'and'cuda_kernel'(hypyp/sync/base.py:433-439):'numba'(and'numpy') can never match. Yet'numba'appears insidepriorityexamples in three documented places:hypyp/sync/__init__.py:112—Example: ['metal', 'torch', 'numba']hypyp/sync/__init__.py:128-129—>>> pli = get_metric('pli', optimization='auto', priority=['numba', 'metal'])hypyp/sync/README.md:112(the priority-override section)Measured on a CPU-only machine:
The resulting
numbacomes from the CPU fallback atbase.py:441-449, not from the priority list. On an Apple machine with Metal available,priority=['numba', 'metal']yields metal — the opposite of the stated intent, since'numba'is skipped and'metal'matches.tests/test_sync.py:958test_auto_priority_overrideasserts_backend == 'numba'forpriority=['numba']and passes — but for the wrong reason, via the fallback path. It does not usepytest.warns, so the "No GPU backend available" warning that fires along the way is invisible. A completely broken priority loop would still pass this test.Suggested fix: either honour CPU backends in the priority loop (so
priority=['numba', 'metal']really means "numba first"), or reject them with a clearValueErrorand remove'numba'from all three documented examples. Also maketest_auto_priority_overrideassert the absence of the fallback warning, so it validates the path it claims to.