{"record":{"id":"8a3992bb8e6fce55","repo":"jax-ml/jax","slug":"preferred-element-type-must-have-the-same-signed","errorCode":null,"errorMessage":"`preferred_element_type` must have the same signedness as the original type.","messagePattern":"`preferred_element_type` must have the same signedness as the original type\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/lax.py","lineNumber":5674,"sourceCode":"\ndef _validate_preferred_element_type(input_dtype, preferred_element_type):\n  if (dtypes.issubdtype(input_dtype, np.integer) and\n      dtypes.issubdtype(preferred_element_type, np.floating)):\n    # Special-case integer->float multiply. This is allowed, and also allows\n    # different signedness between input and output.\n    pass\n  else:\n    allowed_types = (np.integer, np.floating, np.complexfloating)\n    if any(dtypes.issubdtype(input_dtype, t) and not\n           dtypes.issubdtype(preferred_element_type, t) for t in allowed_types):\n      raise TypeError(\"Input type is incompatible with \"\n                      \"`preferred_element_type`. The compatible combinations \"\n                      \"of (input_type, preferred_element_type) are \"\n                      \"(integral, integral), (integral, floating), \"\n                      \"(floating, floating), (complex, complex.\")\n    if (dtypes.issubdtype(input_dtype, np.signedinteger) and\n        not dtypes.issubdtype(preferred_element_type, np.signedinteger)):\n      raise TypeError(\"`preferred_element_type` must have the same signedness \"\n                      \"as the original type.\")\n  input_bitwidth = np.dtype(input_dtype).itemsize\n  preferred_bitwidth = np.dtype(preferred_element_type).itemsize\n  if preferred_bitwidth < input_bitwidth:\n    raise TypeError(\"`preferred_element_type` must not be narrower than the \"\n                    \"original type.\")\n\n\ndef _dot_general_shape_rule(lhs, rhs, *, dimension_numbers, precision,\n                            preferred_element_type: DTypeLike | None,\n                            out_sharding):\n  if out_sharding is not None and not isinstance(out_sharding, NamedSharding):\n    raise NotImplementedError\n  (lhs_contracting, rhs_contracting), (lhs_batch, rhs_batch) = _from_maybe_ragged(dimension_numbers)\n  if not all(np.all(np.greater_equal(d, 0)) and np.all(np.less(d, lhs.ndim))\n             for d in (lhs_contracting, lhs_batch)):\n    msg = (\"dot_general requires lhs dimension numbers to be nonnegative and \"\n           \"less than the number of axes of the lhs value, got \"","sourceCodeStart":5656,"sourceCodeEnd":5692,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/lax.py#L5656-L5692","documentation":"For integral inputs, dot_general's preferred_element_type must preserve signedness: a signed input cannot prefer an unsigned accumulation type and vice versa. Mixing signed and unsigned in the accumulation would silently change semantics, so TypeError is raised.","triggerScenarios":"lax.dot_general with int32 (signed) inputs and preferred_element_type=jnp.uint32, or uint8 inputs with int16 preferred.","commonSituations":"Trying to use unsigned accumulators to gain range; guessing dtype names (uint32 vs int32); porting C-style unsigned accumulation habits.","solutions":["Match signedness: signed input -> signed preferred type, unsigned -> unsigned","If extra range is needed, widen within the same signedness (int32 -> int64)","Cast the inputs to the desired signedness before the dot if overflow semantics are understood","Double-check dtype spelling: jnp.uint32 vs jnp.int32"],"exampleFix":"// before\nout = lax.dot_general(a_i32, b_i32, ..., preferred_element_type=jnp.uint32)\n\n// after\nout = lax.dot_general(a_i32, b_i32, ..., preferred_element_type=jnp.int64)","handlingStrategy":"validation","validationCode":"import numpy as np\nassert not (np.issubdtype(input_dtype, np.signedinteger) and\n           not np.issubdtype(pref, np.signedinteger)), 'signedness mismatch'","typeGuard":"def same_signedness(input_dtype, pref) -> bool:\n    return np.issubdtype(input_dtype, np.signedinteger) == np.issubdtype(pref, np.signedinteger) or not np.issubdtype(input_dtype, np.integer)","tryCatchPattern":"try:\n    out = lax.dot_general(a, b, dn, preferred_element_type=pref)\nexcept TypeError:\n    out = lax.dot_general(a, b, dn, preferred_element_type=np.promote_types(a.dtype, pref))","preventionTips":["Match signedness between inputs and preferred accumulation type","Widen within the same signedness for range (int32 -> int64)","Add dtype-signature asserts in integer matmul helpers"],"tags":["jax","dot-general","signedness","dtype-validation"],"backgroundTag":"dtype-signedness-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}