{"record":{"id":"feecd42bb8a5bcf9","repo":"jax-ml/jax","slug":"cannot-bitcast-a-shaped-array-to-a-dtype-with-a","errorCode":null,"errorMessage":"Cannot bitcast a ()-shaped array to a dtype with a different bitwidth: {old_bitwidth=} vs {new_bitwidth=}","messagePattern":"Cannot bitcast a \\(\\)-shaped array to a dtype with a different bitwidth: (.+?) vs (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/pallas/mosaic/sc_primitives.py","lineNumber":442,"sourceCode":"    raise ValueError(\"Indices must not be empty\")\n  ref, transforms = state_primitives.get_ref_and_transforms(\n      ref, None, \"addupdate_scatter\"\n  )\n  flat_args, tree = jax.tree.flatten((ref, transforms, indices, x, mask))\n  _ = scatter_p.bind(*flat_args, tree=tree, add=True)\n\n\nbitcast_p = jax_core.Primitive(\"bitcast\")\n\n\n@bitcast_p.def_abstract_eval\ndef _bitcast_abstract_eval(x, dtype):\n  old_bitwidth = dtypes.itemsize_bits(x.dtype)\n  new_bitwidth = dtypes.itemsize_bits(dtype)\n  if old_bitwidth == new_bitwidth:\n    return jax_core.ShapedArray(x.shape, dtype)\n  if x.ndim == 0:\n    raise ValueError(\n        \"Cannot bitcast a ()-shaped array to a dtype with a different bitwidth:\"\n        f\" {old_bitwidth=} vs {new_bitwidth=}\"\n    )\n  new_last_dim, rem = divmod(x.shape[-1] * old_bitwidth, new_bitwidth)\n  if rem:\n    raise ValueError(\n        f\"Cannot bitcast from {x.dtype} ({old_bitwidth} bits) to\"\n        f\" {dtype} ({new_bitwidth} bits), because {x.shape[-1]=} *\"\n        f\" {old_bitwidth} is not divisible by {new_bitwidth}\"\n    )\n  return jax_core.ShapedArray((*x.shape[:-1], new_last_dim), dtype)\n\n\n@sc_lowering.register_lowering_rule(bitcast_p)\ndef _bitcast_lowering_rule(ctx: sc_lowering.LoweringRuleContext, x, *, dtype):\n  del dtype  # Unused.\n  [out_aval] = ctx.avals_out\n  return vector.bitcast(ctx.aval_to_ir_type(out_aval), x)","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/pallas/mosaic/sc_primitives.py#L424-L460","documentation":"Bitcasting a scalar (ndim 0) array to a dtype with a different bitwidth is impossible because there is no trailing dimension to redistribute bits across, so the abstract eval raises.","triggerScenarios":"Calling the SC bitcast primitive on a 0-d array, e.g. bitcast(jnp.float32(1.0), jnp.int16) or to a wider dtype like float32->bfloat16 pairs on a scalar.","commonSituations":"Applying vectorized bitcast logic to scalars; converting constants/registers inside a kernel where a scalar slipped through.","solutions":["Reshape the scalar to shape (1,) before bitcasting (and reshape back after)","Use lax.convert_element_type if you want a value conversion, not a bit reinterpretation","Match bitwidths (e.g. f32<->u32) for scalar bitcasts"],"exampleFix":"// before\ny = bitcast(jnp.float32(1.0), jnp.int16)  # scalar, bitwidth differs\n\n// after\ny = bitcast(jnp.float32(1.0).reshape(1), jnp.int16).reshape(())","handlingStrategy":"validation","validationCode":"if x.ndim == 0 and dtypes.itemsize_bits(x.dtype) != dtypes.itemsize_bits(dtype):\n    x = x.reshape(1)","typeGuard":"def bitcast_ok(x, dtype) -> bool:\n    ob, nb = dtypes.itemsize_bits(x.dtype), dtypes.itemsize_bits(dtype)\n    return ob == nb or (x.ndim > 0 and (x.shape[-1] * ob) % nb == 0)","tryCatchPattern":null,"preventionTips":["Never bitcast scalars across bitwidths; reshape to (1,) first","Prefer same-width casts (f32<->u32) for scalars","Wrap bitcast in a helper that validates bitwidth divisibility"],"tags":["jax","pallas","sparsecore","bitcast","scalar"],"backgroundTag":"invalid-bitcast-shape","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}