code: def forward_cpu(self, inputs):
      self.retain_inputs((1, 2))
      self._bottom_data_shape = inputs[0].shape
  
      bottom_data, bottom_rois, bottom_roi_indices = inputs
      channel, height, width = bottom_data.shape[1:]
      if self.out_c is None:
          if channel % (self.group_size * self.group_size) != 0:
              raise ValueError(
                  "input channel must be divided by group_size * group_size:"
                  "{} % {} != 0".format(
                      channel, self.group_size * self.group_size
                  )
              )
          out_c = channel // (self.group_size * self.group_size)
      else:
          if channel != self.out_c * self.group_size * self.group_size:
              raise ValueError(
                  "input channel must be equal to "
                  "outsize[0] * group_size * group_size: {} != {}".format(
                      channel,
                      self.out_c * self.group_size * self.group_size,
                  )
              )
          out_c = self.out_c
      n_roi = bottom_rois.shape[0]
      top_data = np.empty(
          (n_roi, out_c, self.out_h, self.out_w), dtype=np.float32
      )
  
      spatial_scale = self.spatial_scale
      pooled_height = self.out_h
      pooled_width = self.out_w
      group_size = self.group_size
  
      for i in six.moves.range(top_data.size):
          n, ctop, ph, pw = np.unravel_index(i, top_data.shape)
  
          roi_batch_ind = bottom_roi_indices[n]
          roi_start_h = bottom_rois[n, 0] * spatial_scale
          roi_start_w = bottom_rois[n, 1] * spatial_scale
          roi_end_h = bottom_rois[n, 2] * spatial_scale
          roi_end_w = bottom_rois[n, 3] * spatial_scale
  
          roi_height = max(roi_end_h - roi_start_h, 0.1)
          roi_width = max(roi_end_w - roi_start_w, 0.1)
          bin_size_h = roi_height / pooled_height
          bin_size_w = roi_width / pooled_width
  
          hstart = int(np.floor(ph * bin_size_h + roi_start_h))
          wstart = int(np.floor(pw * bin_size_w + roi_start_w))
          hend = int(np.ceil((ph + 1) * bin_size_h + roi_start_h))
          wend = int(np.ceil((pw + 1) * bin_size_w + roi_start_w))
          hstart = min(max(hstart, 0), height)
          wstart = min(max(wstart, 0), width)
          hend = min(max(hend, 0), height)
          wend = min(max(wend, 0), width)
  
          gh = int(np.floor(ph * group_size / pooled_height))
          gw = int(np.floor(pw * group_size / pooled_width))
          gh = min(max(gh, 0), group_size - 1)
          gw = min(max(gw, 0), group_size - 1)
          c = (ctop * group_size + gh) * group_size + gw
  
          if hstart >= hend or wstart >= wend:
              top_data[n, ctop, ph, pw] = 0
              continue
  
          top_data[n, ctop, ph, pw] = np.mean(
              bottom_data[roi_batch_ind, c, hstart:hend, wstart:wend]
          )
  
      return (top_data,)
  
file_path: chainercv/chainercv/functions/ps_roi_average_pooling_2d.py
imports: from __future__ import division
  import numbers
  import numpy
  import six
  import chainer
  from chainer.backends import cuda
  from chainer import function
  from chainer.utils import type_check
label_desc: Use image node_id 3 for calling the PSROIAveragePooling2D obj's underlying member method code with example usage: obj.forward_cpu(inputs) and returns: top_data