jax-ml/jax · error · RuntimeError

Nonsymmetric eigendecomposition requires cusolver 11.7.1 or

Error message

Nonsymmetric eigendecomposition requires cusolver 11.7.1 or newer

What it means

jax/_src/lax/linalg.py:1111 in _eig_gpu_lowering. JAX routes nonsymmetric eigendecomposition on GPU to cusolver's geev only when cusolver_get_version() >= 11701 (cusolver 11.7.1, shipped with CUDA 11.8+). If you explicitly select implementation=EigImplementation.CUSOLVER (or auto-select it) on an older cusolver, this RuntimeError fires because the geev kernel simply does not exist there.

Source

Thrown at jax/_src/lax/linalg.py:1111

  if dtype in (np.float32, np.float64):
    is_real = True
  elif dtype in (np.complex64, np.complex128):
    is_real = False
  else:
    raise ValueError(f"Unsupported dtype: {dtype}")

  have_cusolver_geev = (
      target_name_prefix == "cu"
      and cuda_versions
      and cuda_versions.cusolver_get_version() >= 11701
  )

  if (
      implementation is None and have_cusolver_geev
      and not compute_left_eigenvectors
  ) or implementation == EigImplementation.CUSOLVER:
    if not have_cusolver_geev:
      raise RuntimeError(
          "Nonsymmetric eigendecomposition requires cusolver 11.7.1 or newer"
      )
    if compute_left_eigenvectors:
      raise NotImplementedError(
          "Left eigenvectors are not supported by cusolver")
    target_name = f"{target_name_prefix}solver_geev_ffi"
    avals_out = [
        ShapedArray(batch_dims + (n, n), dtype),
        ShapedArray(batch_dims + (n,), complex_dtype),
        ShapedArray(batch_dims + (n, n), dtype),
        ShapedArray(batch_dims + (n, n), dtype),
        ShapedArray(batch_dims, np.int32),
    ]

    rule = _linalg_ffi_lowering(target_name, avals_out=avals_out)
    _, w, vl, vr, info = rule(ctx, operand, left=compute_left_eigenvectors,
                              right=compute_right_eigenvectors)
    if is_real:

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Upgrade CUDA/cusolver to 11.7.1+ (CUDA 11.8 or newer toolkit / cuDNN-bundled pip wheels jax[cuda])
  2. Let JAX choose the fallback implementation: pass implementation=None on old cusolver (auto path avoids cusolver when unavailable, e.g. uses CPU or alternative path)
  3. Move the eig computation to CPU backend if upgrading the GPU stack is not feasible

Example fix

// before
w, v = jax.lax.linalg.eig(a, implementation=lax.linalg.EigImplementation.CUSOLVER)
// after (old cusolver)
w, v = jax.lax.linalg.eig(a)  # let JAX pick an available implementation
Defensive patterns

Strategy: fallback

Validate before calling

import jax
v_ok = (jax.default_backend() != 'gpu') or (cusolver_version() >= 11701)
if not v_ok:
    eig = jax.jit(jnp.linalg.eig, backend='cpu')

Try / catch

try:
    w, v = jax.lax.linalg.eig(a, implementation=lax.linalg.EigImplementation.CUSOLVER)
except RuntimeError:
    w, v = jax.jit(jnp.linalg.eig, backend='cpu')(a)

Prevention

When it happens

Trigger: Passing implementation=jax.lax.linalg.EigImplementation.CUSOLVER to jax.lax.linalg.eig on a GPU whose cusolver version < 11.7.1; or relying on auto-selection (implementation=None, no left eigenvectors) on an old CUDA toolkit install.

Common situations: Old CUDA 11.x installs (cusolver < 11.7.1), docker images pinned to old CUDA runtime, clusters with stale GPU driver/toolkit stacks, after a JAX upgrade that started using the FFI geev path.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/50b7f20c12f03fa2. Report an issue: GitHub.