class_docstr: RoI average pooling over a set of 2d planes.
class_docstr_tok: ["RoI","average","pooling","over","a","set","of","2d","planes","."]
code: def forward_gpu(self, inputs):
      self.retain_inputs((1, 2))
      self._bottom_data_shape = inputs[0].shape
  
      bottom_data, bottom_rois, bottom_roi_indices = inputs
      channels, height, width = bottom_data.shape[1:]
      n_rois = bottom_rois.shape[0]
      top_data = cuda.cupy.empty(
          (n_rois, channels, self.outh, self.outw),
          dtype=bottom_data.dtype,
      )
      cuda.elementwise(
          """
              raw T bottom_data, raw T bottom_rois, raw int32 bottom_roi_indices,
              T spatial_scale, int32 channels, int32 height, int32 width,
              int32 pooled_height, int32 pooled_width
              """,
          "T top_data",
          """
              // pos in output filter
              int pw = i % pooled_width;
              int ph = (i / pooled_width) % pooled_height;
              int c = (i / pooled_width / pooled_height) % channels;
              int n = i / pooled_width / pooled_height / channels;
  
              int roi_batch_ind = bottom_roi_indices[n];
              int roi_start_h = round(bottom_rois[n * 4 + 0] * spatial_scale);
              int roi_start_w = round(bottom_rois[n * 4 + 1] * spatial_scale);
              int roi_end_h = round(bottom_rois[n * 4 + 2] * spatial_scale);
              int roi_end_w = round(bottom_rois[n * 4 + 3] * spatial_scale);
  
              // Force malformed ROIs to be 1x1
              int roi_height = max(roi_end_h - roi_start_h, 1);
              int roi_width = max(roi_end_w - roi_start_w, 1);
              T bin_size_h = static_cast<T>(roi_height)
                             / static_cast<T>(pooled_height);
              T bin_size_w = static_cast<T>(roi_width)
                             / static_cast<T>(pooled_width);
  
              int hstart = static_cast<int>(floor(static_cast<T>(ph)
                                            * bin_size_h));
              int wstart = static_cast<int>(floor(static_cast<T>(pw)
                                            * bin_size_w));
              int hend = static_cast<int>(ceil(static_cast<T>(ph + 1)
                                          * bin_size_h));
              int wend = static_cast<int>(ceil(static_cast<T>(pw + 1)
                                          * bin_size_w));
  
              // Add roi offsets and clip to input boundaries
              hstart = min(max(hstart + roi_start_h, 0), height);
              hend = min(max(hend + roi_start_h, 0), height);
              wstart = min(max(wstart + roi_start_w, 0), width);
              wend = min(max(wend + roi_start_w, 0), width);
              bool is_empty = (hend <= hstart) || (wend <= wstart);
  
              // Define an empty pooling region to be zero
              T sumval = 0.;
              T count = (hend - hstart) * (wend - wstart);
              int data_offset = (roi_batch_ind * channels + c) * height * width;
              for (int h = hstart; h < hend; ++h) {
                  for (int w = wstart; w < wend; ++w) {
                      int bottom_index = h * width + w;
                      sumval += bottom_data[data_offset + bottom_index];
                  }
              }
              top_data = is_empty ? 0. : sumval / count;
              """,
          "roi_average_pooling_2d_fwd",
      )(
          bottom_data,
          bottom_rois,
          bottom_roi_indices,
          self.spatial_scale,
          channels,
          height,
          width,
          self.outh,
          self.outw,
          top_data,
      )
  
      return (top_data,)
  
file_path: chainer/chainer/functions/pooling/roi_average_pooling_2d.py
imports: import numbers
  import numpy
  import six
  from chainer.backends import cuda
  from chainer import function
  from chainer.functions.pooling.roi_pooling_2d import _roi_pooling_slice
  from chainer import utils
  from chainer.utils import collections_abc
  from chainer.utils import type_check
label_desc: Use image node_id 4 for calling the ROIAveragePooling2D obj's underlying member method code with example usage: obj.forward_gpu(inputs) and returns: top_data