{"record":{"id":"5cc58d49dc3d80d2","repo":"jax-ml/jax","slug":"correlate2d-only-supports-boundary-fill-fillv","errorCode":null,"errorMessage":"correlate2d() only supports boundary='fill', fillvalue=0","messagePattern":"correlate2d\\(\\) only supports boundary='fill', fillvalue=0","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"jax/_src/scipy/signal.py","lineNumber":454,"sourceCode":"           [12.,  7.,  7.,  2.]], dtype=float32)\n\n    Specifying ``mode = 'same'`` returns a centered 2D correlation of the same\n    size as the first input:\n\n    >>> jax.scipy.signal.correlate2d(x, y, mode='same')\n    Array([[15., 24.,  7.],\n           [28., 14.,  9.],\n           [ 7.,  7.,  2.]], dtype=float32)\n\n    Specifying ``mode = 'valid'`` returns only the portion of 2D correlation\n    where the two arrays fully overlap:\n\n    >>> jax.scipy.signal.correlate2d(x, y, mode='valid')\n    Array([[15., 24.],\n           [28., 14.]], dtype=float32)\n  \"\"\"\n  if boundary != 'fill' or fillvalue != 0:\n    raise NotImplementedError(\"correlate2d() only supports boundary='fill', fillvalue=0\")\n  if np.ndim(in1) != 2 or np.ndim(in2) != 2:\n    raise ValueError(\"correlate2d() only supports 2-dimensional inputs.\")\n\n  swap = all(s1 <= s2 for s1, s2 in zip(in1.shape, in2.shape))\n  same_shape =  all(s1 == s2 for s1, s2 in zip(in1.shape, in2.shape))\n\n  if mode == \"same\":\n    in1, in2 = jnp.flip(in1), in2.conj()\n    result = jnp.flip(_convolve_nd(in1, in2, mode, precision=precision))\n  elif mode == \"valid\":\n    if swap and not same_shape:\n      in1, in2 = jnp.flip(in2), in1.conj()\n      result = _convolve_nd(in1, in2, mode, precision=precision)\n    else:\n      in1, in2 = jnp.flip(in1), in2.conj()\n      result = jnp.flip(_convolve_nd(in1, in2, mode, precision=precision))\n  else:\n    if swap:","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/scipy/signal.py#L436-L472","documentation":"correlate2d in JAX only supports the default zero-fill boundary; 'wrap', 'symm', and nonzero fill values are not implemented (NotImplementedError, not ValueError — the feature is absent rather than invalid).","triggerScenarios":"jax.scipy.signal.correlate2d(x, template, boundary='wrap') or fillvalue != 0, typical in template matching with periodic images.","commonSituations":"Porting scipy.signal.correlate2d normalized cross-correlation pipelines that use reflecting boundaries.","solutions":["Pre-pad inputs with jnp.pad using the desired mode and use mode='valid'","Use jax.lax.conv_general_dilated directly for full padding control","Fall back to scipy on CPU for that op if exact boundary semantics are required"],"exampleFix":"// before\nr = jax.scipy.signal.correlate2d(img, tpl, mode='same', boundary='symm')\n// after\nph, pw = tpl.shape[0]//2, tpl.shape[1]//2\nimg_p = jnp.pad(img, ((ph,ph),(pw,pw)), mode='symmetric')\nr = jax.scipy.signal.correlate2d(img_p, tpl, mode='valid')","handlingStrategy":"fallback","validationCode":"def corr2d_symm(x, tpl):\n    ph, pw = tpl.shape[0] // 2, tpl.shape[1] // 2\n    xp = jnp.pad(x, ((ph, ph), (pw, pw)), mode='symmetric')\n    return jax.scipy.signal.correlate2d(xp, tpl, mode='valid')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check boundary/fillvalue against the defaults before calling","Pre-pad to reproduce scipy boundary semantics"],"tags":["jax","scipy","correlation","not-implemented","boundary"],"backgroundTag":"unsupported-feature-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}