{"record":{"id":"b33512cec5882e4a","repo":"jax-ml/jax","slug":"convolution-dimension-numbers-elements-must-each-h","errorCode":null,"errorMessage":"convolution dimension_numbers elements must each have the same set of spatial characters, got {}.","messagePattern":"convolution dimension_numbers elements must each have the same set of spatial characters, got (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/convolution.py","lineNumber":1008,"sourceCode":"\ndef conv_general_permutations(dimension_numbers):\n  \"\"\"Utility for convolution dimension permutations relative to Conv HLO.\"\"\"\n  lhs_spec, rhs_spec, out_spec = dimension_numbers\n  lhs_char, rhs_char, out_char = charpairs = (\"N\", \"C\"), (\"O\", \"I\"), (\"N\", \"C\")\n  for i, (a, b) in enumerate(charpairs):\n    if not dimension_numbers[i].count(a) == dimension_numbers[i].count(b) == 1:\n      msg = (\"convolution dimension_numbers[{}] must contain the characters \"\n             \"'{}' and '{}' exactly once, got {}.\")\n      raise TypeError(msg.format(i, a, b, dimension_numbers[i]))\n    if len(dimension_numbers[i]) != len(set(dimension_numbers[i])):\n      msg = (\"convolution dimension_numbers[{}] cannot have duplicate \"\n             \"characters, got {}.\")\n      raise TypeError(msg.format(i, dimension_numbers[i]))\n  if not (set(lhs_spec) - set(lhs_char) == set(rhs_spec) - set(rhs_char) ==\n          set(out_spec) - set(out_char)):\n    msg = (\"convolution dimension_numbers elements must each have the same \"\n           \"set of spatial characters, got {}.\")\n    raise TypeError(msg.format(dimension_numbers))\n\n  def getperm(spec, charpair):\n    spatial = (i for i, c in enumerate(spec) if c not in charpair)\n    if spec is not rhs_spec:\n      spatial = sorted(spatial, key=lambda i: rhs_spec.index(spec[i]))\n    return (spec.index(charpair[0]), spec.index(charpair[1])) + tuple(spatial)\n\n  lhs_perm, rhs_perm, out_perm = map(getperm, dimension_numbers, charpairs)\n  return lhs_perm, rhs_perm, out_perm\n\n\ndef _conv_general_vjp_lhs_padding(\n    in_shape, window_dimensions, window_strides, out_shape, padding,\n    lhs_dilation, rhs_dilation) -> list[tuple[int, int]]:\n  lhs_dilated_shape = lax._dilate_shape(in_shape, lhs_dilation)\n  rhs_dilated_shape = lax._dilate_shape(window_dimensions, rhs_dilation)\n  out_dilated_shape = lax._dilate_shape(out_shape, window_strides)\n  pad_before = np.subtract(rhs_dilated_shape, [lo for lo, _ in padding]) - 1","sourceCodeStart":990,"sourceCodeEnd":1026,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/convolution.py#L990-L1026","documentation":"After removing the batch/channel characters, the remaining (spatial) character sets of the three layout strings must be identical — lhs, rhs, and out must agree on which spatial axes exist. Mismatched spatial sets raise this TypeError showing the whole dimension_numbers.","triggerScenarios":"Passing ('NCHW','OIHD','NCHW') — rhs uses 'D' where others use 'W'; or 1D lhs/out layouts with a 2D kernel layout.","commonSituations":"Editing only one of the three strings during a layout refactor (NHWC→NCHW); using different spatial letters per string in 3D convs.","solutions":["Use the same spatial characters (same set) in all three layout strings, only N/C vs O/I may differ","Regenerate all three strings together from one rank/layout decision","For transposed convs remember out layout spatial chars must still match lhs/rhs"],"exampleFix":"# before\ndn = lax.conv_dimension_numbers(x.shape, w.shape, ('NCHW', 'OIHD', 'NCHW'))\n# after\ndn = lax.conv_dimension_numbers(x.shape, w.shape, ('NCHW', 'OIHW', 'NCHW'))","handlingStrategy":"validation","validationCode":"spatial = [set(s) - set(sc) for s, sc in zip(dn, [('NC','C'),('OI','I'),('NC','C')])]\nassert spatial[0] == spatial[1] == spatial[2], 'spatial chars must match'","typeGuard":"def matching_spatial_sets(dn) -> bool:\n    sets = [set(dn[0]) - {'N','C'}, set(dn[1]) - {'O','I'}, set(dn[2]) - {'N','C'}]\n    return sets[0] == sets[1] == sets[2]","tryCatchPattern":null,"preventionTips":["Edit all three layout strings together; keep spatial letters identical across them"],"tags":["jax","convolution","dimension-numbers","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}