{"record":{"id":"f98c5b69c449fe6b","repo":"jax-ml/jax","slug":"lax-bitcast-convert-type-does-not-support-bool-or","errorCode":null,"errorMessage":"lax.bitcast_convert_type does not support bool or complex values unless the operand and destination types match. Got operand dtype={old_dtype}, {new_dtype=}. Consider using the arr.view() method instead.","messagePattern":"lax\\.bitcast_convert_type does not support bool or complex values unless the operand and destination types match\\. Got operand dtype=(.+?), (.+?)\\. Consider using the arr\\.view\\(\\) method instead\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/lax.py","lineNumber":5634,"sourceCode":"\n  old_nbits = dtypes.itemsize_bits(old_dtype)\n  new_nbits = dtypes.itemsize_bits(new_dtype)\n\n  if old_nbits == new_nbits:\n    return operand.sharding\n  elif old_nbits > new_nbits:\n    return operand.sharding.update(spec=(*operand.sharding.spec, None))\n  else:\n    return operand.sharding.update(spec=operand.sharding.spec[:-1])\n\ndef _bitcast_convert_type_dtype_rule(operand, *, new_dtype):\n  old_dtype = operand.dtype\n  if (dtypes.issubdtype(old_dtype, np.bool_) or\n      dtypes.issubdtype(old_dtype, np.complexfloating) or\n      dtypes.issubdtype(new_dtype, np.bool_) or\n      dtypes.issubdtype(new_dtype, np.complexfloating)):\n    if old_dtype != new_dtype:\n      raise TypeError(\"lax.bitcast_convert_type does not support bool or complex values \"\n                      \"unless the operand and destination types match. \"\n                      f\"Got operand dtype={old_dtype}, {new_dtype=}. \"\n                      \"Consider using the arr.view() method instead.\")\n  return new_dtype\n\nbitcast_convert_type_p = standard_primitive(\n    _bitcast_convert_type_shape_rule, _bitcast_convert_type_dtype_rule,\n    'bitcast_convert_type', weak_type_rule=_strip_weak_type,\n    sharding_rule=_bitcast_convert_type_sharding_rule,\n    vma_rule=partial(core.standard_vma_rule, 'bitcast_convert_type'))\nad.defjvp_zero(bitcast_convert_type_p)\nbatching.defvectorized(bitcast_convert_type_p)\n\ndef _bitcast_convert_type_lower(ctx, operand, *, new_dtype):\n  aval_out, = ctx.avals_out\n  out_type = mlir.aval_to_ir_type(ctx.module_context, aval_out)\n  out = hlo.bitcast_convert(out_type, operand)\n  return [mlir.lower_with_sharding_in_types(ctx, out, aval_out)]","sourceCodeStart":5616,"sourceCodeEnd":5652,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/lax.py#L5616-L5652","documentation":"bitcast_convert_type cannot reinterpret bool or complex values unless the operand and destination types are identical, because bool/complex bit layouts make cross-type reinterpretation ambiguous in XLA. Any bool/complex involved with a different target dtype raises TypeError.","triggerScenarios":"lax.bitcast_convert_type(jnp.complex64_arr, jnp.float32); bitcasting bool to uint8; bitcasting float32 to complex64 — all with differing types.","commonSituations":"Trying to inspect raw bits of complex numbers; extracting bool bit patterns; porting numpy view()-based code to JAX.","solutions":["Use identical operand and destination dtypes where bool/complex are involved","Bitcast via an intermediate non-bool, non-complex dtype is not allowed — instead split complex into real/imag with jnp.real/jnp.imag then reinterpret each","Use arr.view() (jnp arrays) which supports the needed reinterpretation as the message suggests","Convert bool to uint8 with astype (value cast) if bit-exactness is not required"],"exampleFix":"// before\nbits = lax.bitcast_convert_type(z_c64, jnp.float32)\n\n// after\nbits_re = lax.bitcast_convert_type(jnp.real(z_c64), jnp.float32)  # value-preserving cast not bitcast; better:\nflat = z_c64.view(jnp.float32)  # arr.view method","handlingStrategy":"type-guard","validationCode":"def bitcast_ok(old, new):\n    bad = lambda d: np.issubdtype(d, np.bool_) or np.issubdtype(d, np.complexfloating)\n    return old == new or not (bad(old) or bad(new))","typeGuard":"def is_bitcastable_pair(old_dt, new_dt) -> bool:\n    bad = lambda d: np.issubdtype(d, np.bool_) or np.issubdtype(d, np.complexfloating)\n    return old_dt == new_dt or not (bad(old_dt) or bad(new_dt))","tryCatchPattern":"try:\n    bits = lax.bitcast_convert_type(x, dt)\nexcept TypeError:\n    bits = x.view(dt)  # arr.view supports the reinterpretation","preventionTips":["Use arr.view(dtype) for bool/complex reinterpretation","Split complex arrays into real/imag before bit tricks","Keep bitcasts between same-category non-bool dtypes"],"tags":["jax","bitcast","complex","bool","typeerror"],"backgroundTag":"unsupported-bitcast-conversion","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}