jax-ml/jax · error · ValueError

len(strides) = {len(strides)}; expected {mat.ndim}

Error message

len(strides) = {len(strides)}; expected {mat.ndim}

What it means

A secondary check in bcoo_slice that explicitly verifies len(strides) == mat.ndim after the earlier chained-comparison check. It fires when the strides sequence length doesn't match the array rank, typically when strides was passed explicitly with the wrong number of entries.

Source

Thrown at jax/experimental/sparse/bcoo.py:1986

      indices of each slice
    strides: (not implemented) sequence of integers of length `mat.ndim` specifying
      the stride for each slice

  Returns:
    out: BCOO array containing the slice.
  """
  if not isinstance(mat, BCOO):
    raise TypeError(f"bcoo_slice: input should be BCOO array, got type(mat)={type(mat)}")
  start_indices = [operator.index(i) for i in start_indices]
  limit_indices = [operator.index(i) for i in limit_indices]
  if strides is not None:
    strides = [operator.index(i) for i in strides]
  else:
    strides = [1] * mat.ndim
  if len(start_indices) != len(limit_indices) != len(strides) != mat.ndim:
    raise ValueError(f"bcoo_slice: indices must have size mat.ndim={mat.ndim}")
  if len(strides) != mat.ndim:
    raise ValueError(f"len(strides) = {len(strides)}; expected {mat.ndim}")
  if any(s <= 0 for s in strides):
    raise ValueError(f"strides must be a sequence of positive integers; got {strides}")

  if not all(0 <= start <= end <= size
             for start, end, size in safe_zip(start_indices, limit_indices, mat.shape)):
    raise ValueError(f"bcoo_slice: invalid indices. Got {start_indices=}, "
                     f"{limit_indices=} and shape={mat.shape}")

  start_batch, start_sparse, start_dense = split_list(start_indices, [mat.n_batch, mat.n_sparse])
  end_batch, end_sparse, end_dense = split_list(limit_indices, [mat.n_batch, mat.n_sparse])
  stride_batch, stride_sparse, stride_dense = split_list(strides, [mat.n_batch, mat.n_sparse])

  data_slices = []
  index_slices = []
  for i, (start, end, stride) in enumerate(zip(start_batch, end_batch, stride_batch)):
    data_slices.append(slice(None) if mat.data.shape[i] != mat.shape[i] else slice(start, end, stride))
    index_slices.append(slice(None) if mat.indices.shape[i] != mat.shape[i] else slice(start, end, stride))
  data_slices.append(slice(None))

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Supply a strides sequence with exactly mat.ndim entries
  2. Omit strides entirely (pass None) to use unit strides everywhere
  3. Generate strides as [1] * mat.ndim or tuple(s if i in stride_dims else 1 for ...)

Example fix

# before
bcoo_slice(mat, (0, 0), (8, 8), strides=(2,))
# after
bcoo_slice(mat, (0, 0), (8, 8), strides=(2, 1))
Defensive patterns

Strategy: validation

Validate before calling

if strides is not None and len(strides) != mat.ndim:
    raise ValueError(f'strides rank {len(strides)} != mat.ndim {mat.ndim}')

Prevention

When it happens

Trigger: Passing strides=[1] (or any list) whose length differs from mat.ndim to bcoo_slice, e.g. strides=(2,) for a 2-D BCOO array.

Common situations: Copying strides from code written for a different-rank array; assuming strides apply only to dense dimensions; off-by-one when constructing strides tuples.

Related errors


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