jax-ml/jax · error · ValueError

BCSR from_scipy_sparse requires 2D array; {mat.ndim}D is giv

Error message

BCSR from_scipy_sparse requires 2D array; {mat.ndim}D is given.

What it means

scipy.sparse matrices are inherently 2D, and the BCSR format maps 1:1 onto a 2D (rows x cols) layout. from_scipy_sparse validates mat.ndim == 2 and raises ValueError otherwise. Non-2D inputs almost always indicate a wrong object was passed (e.g. a dense numpy array or a 1D vector).

Source

Thrown at jax/experimental/sparse/bcsr.py:995

  @classmethod
  def from_bcoo(cls, arr: bcoo.BCOO) -> BCSR:
    if arr.n_sparse != 2:
      raise NotImplementedError(f"BSCR.from_bcoo requires n_sparse=2; got {arr.n_sparse=}")
    if not arr.indices_sorted:
      arr = arr.sort_indices()
    indices, indptr = _bcoo_to_bcsr(
        arr.indices, shape=arr.shape, index_dtype=arr.indices.dtype
    )
    return cls((arr.data, indices, indptr), shape=arr.shape)

  @classmethod
  def from_scipy_sparse(cls, mat, *, index_dtype=None, n_dense=0, n_batch=0):
    """Create a BCSR array from a :mod:`scipy.sparse` array."""
    if n_dense != 0 or n_batch != 0:
      raise NotImplementedError("BCSR from_scipy_sparse with nonzero n_dense/n_batch.")

    if mat.ndim != 2:
      raise ValueError(f"BCSR from_scipy_sparse requires 2D array; {mat.ndim}D is given.")

    mat = mat.tocsr()
    data = jnp.asarray(mat.data)
    indices = jnp.asarray(mat.indices).astype(index_dtype or jnp.int32)
    indptr = jnp.asarray(mat.indptr).astype(index_dtype or jnp.int32)
    return cls((data, indices, indptr), shape=mat.shape)

#--------------------------------------------------------------------
# vmappable handlers
def _bcsr_to_elt(cont, _, val, axis):
  if axis is None:
    return val
  if axis >= val.n_batch:
    raise ValueError(f"Cannot map in_axis={axis} for BCSR array with n_batch="
                     f"{val.n_batch}. in_axes for batched BCSR operations must "
                     "correspond to a batched dimension.")
  return BCSR((cont(val.data, axis),
               cont(val.indices, axis),

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Verify the input is a scipy.sparse matrix (scipy.sparse.issparse) before calling
  2. If you have a dense array, use BCSR.from_bcoo(bcoo.bcoo_fromdense(x)) or sparse.BCSR.fromdense-style paths instead
  3. For 1D vectors, reshape to (1, N) or (N, 1) first if a matrix is semantically correct
  4. Add an assert/issparse check in loaders that accept polymorphic input

Example fix

# before
m = BCSR.from_scipy_sparse(dense_np_array)  # ValueError

# after
assert scipy.sparse.issparse(sp_mat) and sp_mat.ndim == 2
m = BCSR.from_scipy_sparse(sp_mat)
Defensive patterns

Strategy: type-guard

Validate before calling

import scipy.sparse
assert scipy.sparse.issparse(mat), 'expected scipy.sparse matrix'
assert mat.ndim == 2

Type guard

def is_valid_scipy_input(mat) -> bool:
    import scipy.sparse
    return scipy.sparse.issparse(mat) and mat.ndim == 2

Try / catch

try:
    m = BCSR.from_scipy_sparse(mat)
except ValueError as e:
    m = BCSR.from_bcoo(bcoo.bcoo_fromdense(jnp.asarray(mat)))

Prevention

When it happens

Trigger: Calling BCSR.from_scipy_sparse(mat) where mat.ndim != 2 — most commonly passing a numpy ndarray, a 1D scipy-like vector, or a higher-dimensional array instead of a scipy.sparse matrix.

Common situations: Refactoring a pipeline that previously accepted dense arrays; passing np.asarray(sp_mat) (which yields a 2D sparse-backed ndarray in new scipy and may behave unexpectedly) or a plain numpy array by mistake.

Related errors


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