jax-ml/jax · error · NotImplementedError
QDWH implementation is only supported on TPU
Error message
QDWH implementation is only supported on TPU
What it means
jax/_src/lax/linalg.py:1293 in _eigh_cpu_gpu_lowering. EighImplementation.QDWH (a QR-based Dynamically Weighted Halley iteration used on TPU) has no CPU/GPU implementation. Explicitly selecting algorithm=EighImplementation.QDWH while executing on CPU or GPU raises NotImplementedError.
Source
Thrown at jax/_src/lax/linalg.py:1293
return (n, d), (d,)
def _eigh_dtype_rule(dtype, **_):
return dtype, lax._complex_basetype(dtype)
def _eigh_cpu_gpu_lowering(
ctx, operand, *, lower, sort_eigenvalues, subset_by_index, algorithm,
target_name_prefix: str
):
del sort_eigenvalues # The CPU/GPU implementations always sort.
operand_aval, = ctx.avals_in
v_aval, w_aval = ctx.avals_out
n = operand_aval.shape[-1]
if not (subset_by_index is None or subset_by_index == (0, n)):
raise NotImplementedError("subset_by_index not supported on CPU and GPU")
batch_dims = operand_aval.shape[:-2]
if algorithm == EighImplementation.QDWH:
raise NotImplementedError("QDWH implementation is only supported on TPU")
if algorithm == EighImplementation.JACOBI and target_name_prefix == "cpu":
raise NotImplementedError("Jacobi implementation is not supported on CPU")
if target_name_prefix == "cpu":
dtype = operand_aval.dtype
prefix = "he" if dtypes.issubdtype(dtype, np.complexfloating) else "sy"
target_name = lapack.prepare_lapack_call(f"{prefix}evd_ffi",
operand_aval.dtype)
kwargs = {
"mode": np.uint8(ord("V")),
"uplo": np.uint8(ord("L" if lower else "U")),
}
else:
target_name = f"{target_name_prefix}solver_syevd_ffi"
# Use Jacobi (algorithm=2) if requested, otherwise use QR (algorithm=1)
if algorithm is None:
algo_int = 0
else:View on GitHub (pinned to 1e1c6a8fc0)
Solutions
- Drop the explicit algorithm and use the default per-backend implementation
- Select a supported algorithm for CPU/GPU (e.g. EighImplementation.LAPACK-ish default, or JACOBI on GPU)
- Run that section on TPU via jax.device_put with tpu backend if QDWH semantics are required
Example fix
// before evals, evecs = jax.lax.linalg.eigh(a, algorithm=lax.linalg.EighImplementation.QDWH) // after (on CPU/GPU) evals, evecs = jax.lax.linalg.eigh(a)
Defensive patterns
Strategy: validation
Validate before calling
if jax.default_backend() != 'tpu':
algorithm = None # never force QDWH off-TPU Prevention
- Don't hardcode QDWH; auto-select per backend
When it happens
Trigger: Calling jax.lax.linalg.eigh(a, algorithm=EighImplementation.QDWH) with backend cpu or gpu. Auto selection (algorithm=None) never picks QDWH off-TPU, so this only occurs with explicit configuration.
Common situations: Config copied from a TPU training pipeline to a local GPU/CPU dev machine; experimenting with algorithms for numerical accuracy; library code that hardcodes QDWH for determinism across TPU replicas.
Related errors
- Jacobi implementation is not supported on CPU
- `buffer_callback` not supported on {platform} backend.
- subset_by_index not supported on CPU and GPU
- psend is currently only implemented on GPU
- precv is currently only implemented on GPU
AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27).
Data as JSON: /api/errors/4e9b1faa81dee4a5.
Report an issue: GitHub.