{"record":{"id":"c3d53395ca9e3b8e","repo":"jax-ml/jax","slug":"invalid-csr-buffer-sizes-data-shape-indices-s","errorCode":null,"errorMessage":"Invalid CSR buffer sizes: {data.shape=} {indices.shape=} {indptr.shape=}","messagePattern":"Invalid CSR buffer sizes: (.+?) (.+?) (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/sparse/linalg.py","lineNumber":531,"sourceCode":"      [jnp.eye(m, dtype=X.dtype),\n       jnp.zeros((n - k - m, m), dtype=X.dtype)], axis=0)\n  w = _mm(y, vt.T * ((2 * (1 + s)) ** (-1/2))[jnp.newaxis, :])\n  h = -2 * jnp.linalg.multi_dot(\n      [w, w[k:, :].T, other], precision=jax.lax.Precision.HIGHEST)\n  return h.at[k:].add(other)\n\n\n# Sparse direct solve via QR factorization\ndef _spsolve_abstract_eval(data, indices, indptr, b, *, tol, reorder):\n  if data.dtype != b.dtype:\n    raise ValueError(f\"data types do not match: {data.dtype=} {b.dtype=}\")\n  if not (jnp.issubdtype(indices.dtype, jnp.integer) and jnp.issubdtype(indptr.dtype, jnp.integer)):\n    raise ValueError(f\"index arrays must be integer typed; got {indices.dtype=} {indptr.dtype=}\")\n  if not data.ndim == indices.ndim == indptr.ndim == b.ndim == 1:\n    raise ValueError(\"Arrays must be one-dimensional. \"\n                     f\"Got {data.shape=} {indices.shape=} {indptr.shape=} {b.shape=}\")\n  if indptr.size != b.size + 1 or  data.shape != indices.shape:\n    raise ValueError(f\"Invalid CSR buffer sizes: {data.shape=} {indices.shape=} {indptr.shape=}\")\n  if reorder not in [0, 1, 2, 3]:\n    raise ValueError(f\"{reorder=} not valid, must be one of [1, 2, 3, 4]\")\n  tol = float(tol)\n  return b\n\n\ndef _spsolve_gpu_lowering(ctx, data, indices, indptr, b, *, tol, reorder):\n  return ffi.ffi_lowering(\"cusolver_csrlsvqr_ffi\")(\n      ctx, data, indices, indptr, b, tol=np.float64(tol),\n      reorder=np.int32(reorder))\n\ndef _spsolve_cpu_lowering(ctx, data, indices, indptr, b, tol, reorder):\n  del tol, reorder\n  args = [data, indices, indptr, b]\n\n  def _callback(data, indices, indptr, b, **kwargs):\n    A = scipy.sparse.csr_matrix((data, indices, indptr), shape=(b.size, b.size))\n    return (scipy.sparse.linalg.spsolve(A, b).astype(b.dtype),)","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/sparse/linalg.py#L513-L549","documentation":"spsolve validates CSR buffer consistency: indptr must have exactly b.size + 1 entries (one per row plus sentinel) and data.shape must equal indices.shape. Violations indicate a malformed CSR structure.","triggerScenarios":"Passing indptr of the wrong length (e.g. built for a different number of rows) or data/indices arrays of differing lengths (nse mismatch).","commonSituations":"Hand-assembling CSR buffers from mismatched arrays; slicing the matrix rows without adjusting indptr; converting from scipy with an off-by-one in indptr.","solutions":["Rebuild the CSR from a dense array or a valid scipy CSR to guarantee consistent buffers","Check indptr has length nrows+1 and len(data) == len(indices) == indptr[-1]","Use sparse.CSR / sparse.bcoo_tocsr helpers instead of manual buffers"],"exampleFix":"// before\nA = sparse.CSR((data, indices, indptr))  # indptr from another matrix\n// after\nA = sparse.CSR.fromdense(M_dense)  # or sparse.bcoo_tocsr(bcoo)","handlingStrategy":"validation","validationCode":"assert indptr.size == b.size + 1, f'{indptr.size} != {b.size + 1}'\nassert data.shape == indices.shape","typeGuard":"def is_valid_csr(data, indices, indptr, b) -> bool:\n    return (indptr.size == b.size + 1\n            and data.shape == indices.shape\n            and int(indptr[-1]) == data.size)","tryCatchPattern":null,"preventionTips":["Build CSR via sparse.CSR.fromdense / sparse.bcoo_tocsr instead of manual buffers","Validate the CSR invariant indptr[-1] == nse before use"],"tags":["jax","sparse","spsolve","csr","buffer-sizes"],"backgroundTag":"malformed-csr-buffers","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}