code: def _conv2d_hw(apad, w_np_fc):
      """2d convolution operator in HW layout.
  
      This is intended to be used as a subroutine from
      _conv2d_nchw_python.  Using scipy.signal.convolve2d directly does
      not work for all dtypes (e.g. float16).  Where possible, this
      function uses scipy.signal.convolve2d to take advantage of
      compiled scipy routines, falling back to an explicit loop only
      where needed
  
      Parameters
      ----------
      a_np : numpy.ndarray
          2-D with shape [in_height, in_width]
  
      w_np : numpy.ndarray
          2-D with shape [filter_height, filter_width].
  
      Returns
      -------
      b_np : np.ndarray
          2-D with shape [out_height, out_width]
      """
  
      try:
          return scipy.signal.convolve2d(
              apad, np.rot90(np.rot90(w_np_fc)), mode="valid"
          )
      except ValueError:
          pass
  
      assert len(apad.shape) == len(w_np_fc.shape) == 2
  
      dtype = apad.dtype
      in_height, in_width = apad.shape
      kernel_h, kernel_w = w_np_fc.shape
  
      output_shape = [
          a_dim - w_dim + 1
          for a_dim, w_dim in zip(apad.shape, w_np_fc.shape)
      ]
      output = np.zeros(output_shape, dtype=apad.dtype)
  
      for y in range(output_shape[0]):
          for x in range(output_shape[1]):
              output[y][x] = np.sum(
                  apad[y : y + kernel_h, x : x + kernel_w] * w_np_fc
              )
  
      return output
  
imports: import numpy
  import scipy
  from tvm.topi.nn.utils import get_pad_tuple
label_desc: Use image node_id 2 for calling a global function with example usage: _conv2d_hw(apad, w_np_fc) and returns: output, scipy