code: def _convolve2d_gpu(
      inp,
      out,
      ker,
      mode,
      boundary,
      use_convolve,
      fillvalue,
  ):
      if (
          (boundary != PAD)
          and (boundary != REFLECT)
          and (boundary != CIRCULAR)
      ):
          raise Exception("Invalid boundary flag")
  
      S = np.zeros(2, dtype=int)
  
      # If kernel is square and odd
      if ker.shape[0] == ker.shape[1]:  # square
          if ker.shape[0] % 2 == 1:  # odd
              pick = 1
              S[0] = (ker.shape[0] - 1) // 2
              if mode == 2:  # full
                  P1 = P2 = P3 = P4 = S[0] * 2
              else:  # same/valid
                  P1 = P2 = P3 = P4 = S[0]
          else:  # even
              pick = 2
              S[0] = ker.shape[0] // 2
              if mode == 2:  # full
                  P1 = P2 = P3 = P4 = S[0] * 2 - 1
              else:  # same/valid
                  if use_convolve:
                      P1 = P2 = P3 = P4 = S[0]
                  else:
                      P1 = P3 = S[0] - 1
                      P2 = P4 = S[0]
      else:  # Non-square
          pick = 3
          S[0] = ker.shape[0]
          S[1] = ker.shape[1]
          if mode == 2:  # full
              P1 = S[0] - 1
              P2 = S[0] - 1
              P3 = S[1] - 1
              P4 = S[1] - 1
          else:  # same/valid
              if use_convolve:
                  P1 = S[0] // 2
                  P2 = S[0] // 2 if (S[0] % 2) else S[0] // 2 - 1
                  P3 = S[1] // 2
                  P4 = S[1] // 2 if (S[1] % 2) else S[1] // 2 - 1
              else:
                  P1 = S[0] // 2 if (S[0] % 2) else S[0] // 2 - 1
                  P2 = S[0] // 2
                  P3 = S[1] // 2 if (S[1] % 2) else S[1] // 2 - 1
                  P4 = S[1] // 2
  
      if mode == 1:  # SAME
          pad = ((P1, P2), (P3, P4))  # 4x5
          if boundary == REFLECT:
              inp = cp.pad(inp, pad, "symmetric")
          if boundary == CIRCULAR:
              inp = cp.pad(inp, pad, "wrap")
          if boundary == PAD:
              inp = cp.pad(
                  inp, pad, "constant", constant_values=(fillvalue)
              )
  
      if mode == 2:  # FULL
          pad = ((P1, P2), (P3, P4))
          if boundary == REFLECT:
              inp = cp.pad(inp, pad, "symmetric")
          if boundary == CIRCULAR:
              inp = cp.pad(inp, pad, "wrap")
          if boundary == PAD:
              inp = cp.pad(
                  inp, pad, "constant", constant_values=(fillvalue)
              )
  
      paddedW = inp.shape[1]
      paddedH = inp.shape[0]
  
      outW = out.shape[1]
      outH = out.shape[0]
  
      d_inp = cp.asarray(inp)
      d_kernel = cp.asarray(ker)
  
      threadsperblock = (16, 16)
      blockspergrid = (
          _iDivUp(out.shape[1], threadsperblock[0]),
          _iDivUp(out.shape[0], threadsperblock[1]),
      )
  
      if use_convolve:
          k_type = "convolve2D"
  
          _populate_kernel_cache(out.dtype, k_type)
  
          kernel = _get_backend_kernel(
              out.dtype,
              blockspergrid,
              threadsperblock,
              k_type,
          )
      else:
          k_type = "correlate2D"
  
          _populate_kernel_cache(out.dtype, k_type)
  
          kernel = _get_backend_kernel(
              out.dtype,
              blockspergrid,
              threadsperblock,
              k_type,
          )
  
      kernel(
          d_inp,
          paddedW,
          paddedH,
          d_kernel,
          S[0],
          S[1],
          out,
          outW,
          outH,
          pick,
      )
  
      _print_atts(kernel)
  
      return out
  
imports: import cupy
  import numpy
  from ..utils._caches import _cupy_kernel_cache
  from ..utils.helper_tools import _get_function, _get_tpb_bpg, _print_atts
  from .convolution_utils import CIRCULAR, FULL, PAD, REFLECT, SAME, VALID, _bvalfromboundary, _iDivUp, _valfrommode
label_desc: Use image node_id 4 for calling a global function with example usage: _convolve2d_gpu(inp, out, ker, mode, boundary, use_convolve, fillvalue) and returns: out