{"record":{"id":"bdc7ed142ca21b83","repo":"jax-ml/jax","slug":"convolution-requires-lhs-and-rhs-ndim-to-be-equal","errorCode":null,"errorMessage":"convolution requires lhs and rhs ndim to be equal, got {} and {}.","messagePattern":"convolution requires lhs and rhs ndim to be equal, got (.+?) and (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"jax/_src/lax/convolution.py","lineNumber":966,"sourceCode":"def conv_dimension_numbers(lhs_shape, rhs_shape, dimension_numbers\n                           ) -> ConvDimensionNumbers:\n  \"\"\"Converts convolution `dimension_numbers` to a `ConvDimensionNumbers`.\n\n  Args:\n    lhs_shape: tuple of nonnegative integers, shape of the convolution input.\n    rhs_shape: tuple of nonnegative integers, shape of the convolution kernel.\n    dimension_numbers: None or a tuple/list of strings or a ConvDimensionNumbers\n      object.\n\n  Returns:\n    A `ConvDimensionNumbers` object that represents `dimension_numbers` in the\n    canonical form used by lax functions.\n  \"\"\"\n  if isinstance(dimension_numbers, ConvDimensionNumbers):\n    return dimension_numbers\n  if len(lhs_shape) != len(rhs_shape):\n    msg = \"convolution requires lhs and rhs ndim to be equal, got {} and {}.\"\n    raise TypeError(msg.format(len(lhs_shape), len(rhs_shape)))\n\n  if dimension_numbers is None:\n    iota = tuple(range(len(lhs_shape)))\n    return ConvDimensionNumbers(iota, iota, iota)\n  elif isinstance(dimension_numbers, (list, tuple)):\n    if len(dimension_numbers) != 3:\n      msg = \"convolution dimension_numbers list/tuple must be length 3, got {}.\"\n      raise TypeError(msg.format(len(dimension_numbers)))\n    if not all(isinstance(elt, str) for elt in dimension_numbers):\n      msg = \"convolution dimension_numbers elements must be strings, got {}.\"\n      raise TypeError(msg.format(tuple(map(type, dimension_numbers))))\n    msg = (\"convolution dimension_numbers[{}] must have len equal to the ndim \"\n           \"of lhs and rhs, got {} for lhs and rhs shapes {} and {}.\")\n    for i, elt in enumerate(dimension_numbers):\n      if len(elt) != len(lhs_shape):\n        raise TypeError(msg.format(i, len(elt), lhs_shape, rhs_shape))\n\n    lhs_spec, rhs_spec, out_spec = conv_general_permutations(dimension_numbers)","sourceCodeStart":948,"sourceCodeEnd":984,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lax/convolution.py#L948-L984","documentation":"lax.conv_dimension_numbers validates that lhs and rhs have the same rank; a convolution needs matching ndim for its input and kernel. The counts are reported in the message.","triggerScenarios":"Calling lax.conv, lax.conv_general_dilated, etc. with a 4D lhs and a 3D rhs (e.g. forgetting the in/out channel dims on the kernel), or rank-mismatched dimension_numbers strings.","commonSituations":"Using a 1D kernel (out_channels,) instead of (out_channels, in_channels) with lax.conv_general_dilated; mixing 1D and 2D data layouts; bugs in preprocessing that drop a dimension.","solutions":["Reshape/broadcast the kernel so lhs.ndim == rhs.ndim (e.g. kernel shape (k,1,in,out) for 1D conv)","Verify your data pipeline preserves the channel dims on both tensors","Build dimension_numbers with lax.conv_dimension_numbers, which surfaces the mismatch early with clear shapes"],"exampleFix":"# before\nx = jnp.zeros((8, 16, 16, 3)); w = jnp.zeros((3, 3, 3))  # missing out-channel dim\nout = lax.conv_general_dilated(x, w, (1,1), 'SAME')\n# after\nw = jnp.zeros((3, 3, 3, 8))  # (H, W, Cin, Cout)\nout = lax.conv_general_dilated(x, w, (1,1), 'SAME')","handlingStrategy":"type-guard","validationCode":"assert lhs.ndim == rhs.ndim, f'rank mismatch: {lhs.ndim} vs {rhs.ndim}'","typeGuard":"def same_rank(a, b) -> bool:\n    return a.ndim == b.ndim","tryCatchPattern":null,"preventionTips":["Check ndim at data-loading time for both activations and kernels","Prefer lax.conv / flax layers which enforce kernel shape conventions"],"tags":["jax","convolution","shape-validation","rank-mismatch"],"backgroundTag":"shape-mismatch","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}