spacr.accelerator¶
Select the torch compute device and report its vendor name and limitations.
About forty-five spaCR call sites ask torch.cuda.is_available(), and
most of them use it to decide whether any GPU is present. On non-NVIDIA
hardware those are two different questions, and treating them as one
reports a usable accelerator as “no GPU”:
ROCm answers
torch.cuda.is_available()True and wantsdevice="cuda". Code that then prints “CUDA” names the wrong vendor; code that prints “no NVIDIA GPU” hides a usable AMD device.Apple’s Metal answers it False and wants
device="mps". MPS is Metal, not an Apple-Silicon feature. On the Intel iMac this was written on it drives an AMD Radeon Pro 5300 – measured 16x on conv2d inference and 2.7x on a training step against the same machine’s CPU. ROCm has no macOS build, so Metal is the only route to an AMD card on a Mac.
This module therefore reports the vendor and the GPU decision separately, and also records what the selected device cannot do. Moving a tensor to MPS is not sufficient, because three operations fail rather than slow down (each was measured):
float64raisesTypeError. Computations that need double precision must stay on the CPU.autocast(device_type="mps")raisesRuntimeError. Mixed precision must be disabled on this device, not redirected to it.Some operators are missing (
aten::linalg_qr.outamong them).PYTORCH_ENABLE_MPS_FALLBACK=1makes those run on the CPU instead of raising, so this module sets it when it selects MPS.
Detected and usable hardware are reported separately. A setup screen that
lists an accelerator spaCR never dispatches to leads users to attribute CPU
run times to that hardware. Neural engines are the main case: the Apple
Neural Engine, Intel AI Boost and Qualcomm Hexagon have no portable torch
device and are never selected; neural_engines() currently reports
only the Apple Neural Engine, on arm64 macOS.
Device resolution does not raise. A half-installed ROCm, a broken driver, or a torch build without a backend it advertises all resolve to the CPU with an explanatory note, so an unusual accelerator cannot cause a traceback at import time.
Classes¶
Resolved compute device, its display names and its capabilities. |
Functions¶
|
The string for |
|
|
|
Return the value to pass Cellpose as |
|
Consistent device and weight precision for |
|
One line for a log or a console: what was found and whether it runs. |
|
The resolved device as a string, e.g. |
|
Release the backend's cached device memory and return the call made |
|
Resolve the accelerator for a given torch module, bypassing the cache. |
|
Whether the resolved accelerator is NVIDIA CUDA (not ROCm). |
|
Whether a usable accelerator of any vendor was selected. |
|
Names of detected neural-inference hardware that spaCR does not use. |
|
The accelerator spaCR will use. Cached; never raises. |
|
Whether a GPU is selected and |
|
Whether |
|
Whether double precision may be sent to the device. |
|
Module Contents¶
- class spacr.accelerator.Accelerator[source]¶
Resolved compute device, its display names and its capabilities.
- Parameters:
kind – one of
KINDS.rocmis reported distinctly fromcudaeven though both dispatch todevice="cuda", because the only thing a user can act on is the true vendor.device – the string to hand
torch.device.label – human text for the setup slide and the doctor.
name – undecorated hardware marketing name shown to users, without the backend or version suffix carried by
label; empty when no device name was discovered.detected – the hardware is present.
usable – spaCR dispatches work to it. Never true unless
detected; false for accelerators with no torch device.note – why it is not usable, when it is not. Empty otherwise.
float64 – the device accepts double precision.
autocast –
torch.autocastaccepts this device type.fallback – missing operators silently run on the CPU instead of raising, because this module set the backend’s fallback flag.
bfloat16 – the device accepts
torch.bfloat16. Probed rather than assumed from the backend name, because it is the one capability that moves with the torch version: Metal gained it after 2.2, and 2.2.2 is the last x86-64 macOS wheel, so the same backend answers differently on an Intel Mac and an Apple Silicon one. Cellpose’s cpsam loads its weights in bfloat16 by default, so a wrong answer here is a TypeError at model construction.
- property is_cuda: bool[source]¶
Whether this accelerator is NVIDIA CUDA (not ROCm).
Narrower than
is_gpu: anything readingnvidia-smi, a CUDA version, or NVIDIA-specific memory interfaces wants this one and would be wrong on ROCm.
- spacr.accelerator.autocast_device_type() str | None[source]¶
The string for
torch.autocast(device_type=...), or None.None means “do not use mixed precision here”, which is a different answer from “use it on the CPU” and has to stay distinguishable.
- spacr.accelerator.capabilities(found: Accelerator | None = None) Tuple[Tuple[str, bool, str], ...][source]¶
(task, accelerated, detail)rows stating which tasks are accelerated.The setup screen reports acceleration per task rather than a single “compatible GPU” flag, because backends differ by task: on Metal, segmentation and the classifier are accelerated while the cuML reductions run on the CPU.
Ordered by how much the acceleration is worth: segmentation on the CPU took 444 s for one 256x256 image on the machine this was written on, and 3.2 s on its Radeon.
- Parameters:
found – optional existing accelerator snapshot. Providing it avoids another resolution and any dtype-probe allocations, as required by the doctor’s metadata-only check.
- Returns:
task, accelerated flag and explanation for each capability.
- spacr.accelerator.cellpose_gpu() bool[source]¶
Return the value to pass Cellpose as
gpu=.Cellpose resolves the device itself and supports MPS –
assign_device(gpu=True)returnsmpson a Metal machine – but it uses a GPU only when called withgpu=True. Passingtorch.cuda.is_available()here pins a Mac to the CPU when no explicit device is supplied. An explicit Cellpose device takes precedence.
- spacr.accelerator.cellpose_kwargs() dict[source]¶
Consistent device and weight precision for
CellposeModelinference.The three arguments must agree, so they are produced together here rather than written out at six call sites:
gpu– controls Cellpose’s selection when no explicit device is supplied, including callers that deliberately dropdevicebelow.device– from the one resolver, so cellpose and spaCR cannot disagree about the same machine; an explicit device takes precedence.use_bfloat16– cpsam loads its weights in bfloat16 by default and Metal on torch 2.2 has no bfloat16, so the default is aTypeError: BFloat16 is not supported on MPSat construction. Measured on the reporting iMac; float32 weights work there at the cost of additional VRAM. CPU inference also uses float32: bfloat16 support does not imply native arithmetic, and emulation can be substantially slower. This matches Make Masks; float32 arithmetic need not produce identical predictions to bfloat16.
Callers that pass
device=Noneon purpose – letting cellpose resolve it – should takegpuanduse_bfloat16from here and dropdevice.
- spacr.accelerator.describe() str[source]¶
One line for a log or a console: what was found and whether it runs.
- spacr.accelerator.device_string() str[source]¶
The resolved device as a string, e.g.
"cuda:0","mps".
- spacr.accelerator.empty_cache(torch_module=None) str[source]¶
Release the backend’s cached device memory and return the call made (
""when none was made). Never raises.- Parameters:
torch_module – resolve the backend from this torch module instead of the cached result for the machine.
spacr.qt.resource_cleanupholds its own handle – it deliberately does not import torch just to free memory – and a cached global would send the call to the wrong backend when that handle is a stand-in.
- spacr.accelerator.inspect_torch(torch, *, device_names=True, include_cuda=True) Accelerator[source]¶
Resolve the accelerator for a given torch module, bypassing the cache.
For callers that already hold a torch handle and need the result for that handle –
spacr.doctor.check_gpu()imports torch through its own indirection so the diagnosis can be tested against a stand-in, and the cached result for the real machine would ignore that stand-in. Uses the same probes in the same order asresolve().- Parameters:
torch – torch module whose availability metadata should be inspected.
device_names – False avoids CUDA/XPU property queries that can initialize their runtime. Availability queries still run.
include_cuda – False skips CUDA/ROCm entirely, for a process whose environment deliberately hides those devices. Other backends remain eligible. This function does not allocate dtype-probe tensors.
- Returns:
accelerator described by the supplied torch module.
- spacr.accelerator.is_cuda() bool[source]¶
Whether the resolved accelerator is NVIDIA CUDA (not ROCm).
For the places that need CUDA specifically – memory interrogation,
nvidia-smiadvice, CUDA version reporting.
- spacr.accelerator.is_gpu() bool[source]¶
Whether a usable accelerator of any vendor was selected.
What a call site means when it writes
torch.cuda.is_available()to decide whether to use a GPU at all.
- spacr.accelerator.neural_engines() Tuple[str, ...][source]¶
Names of detected neural-inference hardware that spaCR does not use.
Reported so the setup slide can say “found, not used” for an idle Neural Engine. There is no portable torch device for any of these – the ANE is reachable only through CoreML, Intel’s AI Boost only through OpenVINO – so none of them is offered as a compute device.
- spacr.accelerator.resolve(refresh: bool = False) Accelerator[source]¶
The accelerator spaCR will use. Cached; never raises.
- Parameters:
refresh – probe again instead of answering from the cache. For tests, which fake the probes.
- spacr.accelerator.supports_autocast() bool[source]¶
Whether a GPU is selected and
torch.autocastaccepts its device type.
- spacr.accelerator.supports_bfloat16() bool[source]¶
Whether
torch.bfloat16tensors may be put on the device.
Nested helpers¶
- _keep_cellpose_flows_off_metal.on_the_cpu(masks, flows, threshold=0.4, device=None)¶
Run Cellpose flow-error filtering on the CPU for Metal.
- Parameters:
masks – label masks forwarded unchanged to Cellpose.
flows – flow field forwarded unchanged to Cellpose.
threshold – flow-error threshold forwarded to Cellpose.
device – ignored compatibility argument; the wrapped call always receives
torch.device("cpu").
- Returns:
the original
remove_bad_flow_masksreturn value.
spacr/accelerator.py:734
- _measure_dtypes.accepts(name: str) bool | None¶
Probe whether the resolved device accepts one named torch dtype.
- Parameters:
name – torch dtype attribute name, such as
"float64"or"bfloat16".- Returns:
Truewhen a two-element tensor allocates on the device,Falsefor the errors used by unsupported dtypes, orNonewhen torch lacks the dtype or the probe fails unexpectedly.
spacr/accelerator.py:464