{"record":{"id":"6e98a06c85a70d6f","repo":"jax-ml/jax","slug":"one-input-must-be-smaller-than-the-other-in-every","errorCode":null,"errorMessage":"One input must be smaller than the other in every dimension.","messagePattern":"One input must be smaller than the other in every dimension\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/signal.py","lineNumber":174,"sourceCode":"  return lax.dynamic_slice(conv, start_indices, out_shape)\n\n\n# Note: we do not reuse the code from jax.numpy.convolve here, because the handling\n# of padding differs slightly between the two implementations (particularly for\n# mode='same').\ndef _convolve_nd(in1: Array, in2: Array, mode: ModeString, *, precision: PrecisionLike) -> Array:\n  if mode not in [\"full\", \"same\", \"valid\"]:\n    raise ValueError(\"mode must be one of ['full', 'same', 'valid']\")\n  if in1.ndim != in2.ndim:\n    raise ValueError(\"in1 and in2 must have the same number of dimensions\")\n  if in1.size == 0 or in2.size == 0:\n    raise ValueError(f\"zero-size arrays not supported in convolutions, got shapes {in1.shape} and {in2.shape}.\")\n  in1, in2 = promote_dtypes_inexact(in1, in2)\n\n  no_swap = all(s1 >= s2 for s1, s2 in zip(in1.shape, in2.shape))\n  swap = all(s1 <= s2 for s1, s2 in zip(in1.shape, in2.shape))\n  if not (no_swap or swap):\n    raise ValueError(\"One input must be smaller than the other in every dimension.\")\n\n  shape_o = in2.shape\n  if swap:\n    in1, in2 = in2, in1\n  shape = in2.shape\n  in2 = jnp.flip(in2)\n\n  if mode == 'valid':\n    padding = [(0, 0) for s in shape]\n  elif mode == 'same':\n    padding = [(s - 1 - (s_o - 1) // 2, s - s_o + (s_o - 1) // 2)\n               for (s, s_o) in zip(shape, shape_o)]\n  elif mode == 'full':\n    padding = [(s - 1, s - 1) for s in shape]\n  else:\n    raise ValueError(f'unsupported mode: {mode}')\n\n  strides = tuple(1 for s in shape)","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/signal.py#L156-L192","documentation":"Raised when neither input is uniformly >= the other across all dimensions, i.e. the shapes cross (in1 bigger in one dim, smaller in another). The implementation must order inputs as larger-then-smaller before handing off to lax.conv_general_dilated, which requires an unambiguous ordering; SciPy supports mixed cases but JAX does not.","triggerScenarios":"convolve(jnp.ones((5,3)), jnp.ones((4,4))) — 5>=4 in dim 0 but 3<4 in dim 1; any N-D convolution where shapes are not nested.","commonSituations":"Porting SciPy signal code that mixed kernel/data sizes; kernels sized per-dimension from unrelated config values.","solutions":["Pad the smaller array so one input dominates in every dimension, then crop the result","Redesign kernel dimensions so the kernel is <= the signal in all axes","Compute per-dimension separable convolutions if the kernel factorizes"],"exampleFix":"// before\ny = jax.scipy.signal.convolve(x, k)  # x:(5,3), k:(4,4)\n// after\nk_p = jnp.pad(k, ((0,1),(0,0)))  # (5,4)\ny = jax.scipy.signal.convolve(x, k_p)[: x.shape[0]+k.shape[0]-1, : x.shape[1]+k.shape[1]-1]","handlingStrategy":"validation","validationCode":"def shapes_nested(a, b):\n    return all(s1 >= s2 for s1, s2 in zip(a.shape, b.shape)) or \\\n           all(s1 <= s2 for s1, s2 in zip(a.shape, b.shape))\nassert shapes_nested(x, k), 'one input must dominate in every dim'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate dimension-wise dominance of the two shapes before calling","Pad kernels per-dimension when porting SciPy mixed-size convolutions"],"tags":["jax","scipy","convolution","shape-mismatch"],"backgroundTag":"incompatible-shape-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}