{"record":{"id":"7fb8cdc4535f2872","repo":"jax-ml/jax","slug":"bcoo-multiply-sparse-arrays-must-have-same-number","errorCode":null,"errorMessage":"bcoo_multiply_sparse: arrays must have same number of dimensions, got {lhs_shape}, {rhs_shape}","messagePattern":"bcoo_multiply_sparse: arrays must have same number of dimensions, got (.+?), (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/experimental/sparse/bcoo.py","lineNumber":2216,"sourceCode":"\n  Returns:\n    An BCOO-format array containing the result.\n  \"\"\"\n  out_data, out_indices, out_shape = _bcoo_multiply_sparse(\n      lhs.data, lhs.indices, rhs.data, rhs.indices, lhs_spinfo=lhs._info,\n      rhs_spinfo=rhs._info)\n  return BCOO((out_data, out_indices), shape=out_shape)\n\ndef _bcoo_multiply_sparse(lhs_data: Array, lhs_indices: Array, rhs_data: Array, rhs_indices: Array, *,\n                          lhs_spinfo: SparseInfo, rhs_spinfo: SparseInfo) -> tuple[Array, Array, Shape]:\n  lhs_shape = lhs_spinfo.shape\n  rhs_shape = rhs_spinfo.shape\n\n  lhs = _validate_bcoo(lhs_data, lhs_indices, lhs_shape)\n  rhs = _validate_bcoo(rhs_data, rhs_indices, rhs_shape)\n  if len(lhs_shape) != len(rhs_shape):\n    # Similar requirement as lax.mul:\n    raise TypeError(\"bcoo_multiply_sparse: arrays must have same number of dimensions, \"\n                    f\"got {lhs_shape}, {rhs_shape}\")\n  if lhs.n_dense != rhs.n_dense:\n    raise NotImplementedError(\"bcoo_multiply_sparse: arrays with differing numbers of \"\n                              f\"dense dimensions: {lhs}, {rhs}\")\n  n_batch = min(lhs.n_batch, rhs.n_batch)\n  _mul = functools.partial(_bcoo_multiply_sparse_unbatched,\n                           lhs_shape=lhs_shape[n_batch:],\n                           rhs_shape=rhs_shape[n_batch:])\n  _mul = nfold_vmap(_mul, n_batch)\n  data, indices = _mul(lhs_data, lhs_indices, rhs_data, rhs_indices)\n  return data, indices, jnp.broadcast_shapes(lhs_shape, rhs_shape)\n\ndef _bcoo_multiply_sparse_unbatched(lhs_data, lhs_indices, rhs_data, rhs_indices, *, lhs_shape, rhs_shape):\n  lhs = _validate_bcoo(lhs_data, lhs_indices, lhs_shape)\n  rhs = _validate_bcoo(rhs_data, rhs_indices, rhs_shape)\n  assert (lhs.n_batch == 0) or (rhs.n_batch == 0)  # Ensured at call site above\n\n  # TODO(jakevdp): this can be made more efficient by utilizing batch structure.","sourceCodeStart":2198,"sourceCodeEnd":2234,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/sparse/bcoo.py#L2198-L2234","documentation":"bcoo_multiply_sparse (element-wise sparse product used by BCOO multiplication) requires both operands to have the same number of dimensions, mirroring lax.mul's no-broadcasting-on-rank rule. A rank mismatch raises TypeError with both shapes.","triggerScenarios":"Calling bcoo_multiply_sparse (or BCOO * BCOO / sparse multiply paths) where lhs is e.g. 2-D and rhs is 1-D, so len(lhs_shape) != len(rhs_shape).","commonSituations":"Multiplying a sparse matrix by a vector without reshaping; operands built from different pipelines with different rank; assuming NumPy broadcasting across ranks works here.","solutions":["Reshape the lower-rank operand to match ranks, e.g. vec[None, :] or jnp.reshape before building BCOO","For matrix-vector products use bcoo_matvec / mat.dot(vec) instead of element-wise multiply","Rebuild both BCOO operands with consistent ndim and shape metadata"],"exampleFix":"# before\nresult = bcoo_multiply_sparse(mat_2d, vec_1d.data, vec_1d.indices, ..., shapes)\n# after\nvec = sparse.BCOO((v_data, v_indices), shape=(1, n))  # match 2-D rank\nresult = mat * vec  # or reshape appropriately","handlingStrategy":"validation","validationCode":"if lhs.ndim != rhs.ndim:\n    raise ValueError(f'rank mismatch: {lhs.ndim} vs {rhs.ndim}; reshape first')","typeGuard":"from jax.experimental.sparse import BCOO\ndef same_rank(a: BCOO, b: BCOO) -> bool:\n    return len(a.spinfo.shape) == len(b.spinfo.shape)","tryCatchPattern":null,"preventionTips":["No cross-rank broadcasting in sparse elementwise multiply — reshape first","Use bcoo_matvec / dot for matrix-vector semantics"],"tags":["jax","sparse","bcoo","shape-mismatch","elementwise-multiply"],"backgroundTag":"rank-mismatch-in-elementwise-op","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}