code: def backward_gpu(self, inputs, gy):
      _, bottom_rois, bottom_roi_indices = inputs
      channels, height, width = self._bottom_data_shape[1:]
      out_c, out_h, out_w = gy[0].shape[1:]
      bottom_diff = cuda.cupy.zeros(self._bottom_data_shape, np.float32)
      cuda.elementwise(
          """
              raw T top_diff, raw int32 argmax_data,
              raw T bottom_rois, raw int32 bottom_roi_indices,
              T spatial_scale, int32 channels, int32 height, int32 width,
              int32 pooled_dim, int32 pooled_height, int32 pooled_width,
              int32 group_size
              """,
          "raw T bottom_diff",
          """
              int ph = (i / pooled_width) % pooled_height;
              int pw = i % pooled_width;
              int ctop = (i / pooled_width / pooled_height) % pooled_dim;
              int n = i / pooled_width / pooled_height / pooled_dim;
  
              // [start, end) interval for spatial sampling
              int roi_batch_ind = bottom_roi_indices[n];
              T roi_start_h = bottom_rois[n * 4 + 0] * spatial_scale;
              T roi_start_w = bottom_rois[n * 4 + 1] * spatial_scale;
              T roi_end_h = bottom_rois[n * 4 + 2] * spatial_scale;
              T roi_end_w = bottom_rois[n * 4 + 3] * spatial_scale;
  
              // Force too small ROIs to be 1x1
              T roi_height = max(roi_end_h - roi_start_h, 0.1);
              T roi_width = max(roi_end_w - roi_start_w, 0.1); // avoid 0
  
              // Compute w and h at bottom
              T bin_size_h = roi_height / static_cast<T>(pooled_height);
              T bin_size_w = roi_width / static_cast<T>(pooled_width);
  
              int hstart = floor(
                  static_cast<T>(ph) * bin_size_h + roi_start_h);
              int wstart = floor(
                  static_cast<T>(pw) * bin_size_w + roi_start_w);
              int hend = ceil(
                  static_cast<T>(ph + 1.0) * bin_size_h + roi_start_h);
              int wend = ceil(
                  static_cast<T>(pw + 1.0) * bin_size_w + roi_start_w);
  
              // Add roi offsets and clip to input boundaries
              hstart = min(max(hstart, 0), height);
              wstart = min(max(wstart, 0), width);
              hend = min(max(hend, 0), height);
              wend = min(max(wend, 0), width);
  
              // Compute c at bottom
              int gh = floor(
                  static_cast<T>(ph) * group_size / pooled_height);
              int gw = floor(
                  static_cast<T>(pw) * group_size / pooled_width);
              gh = min(max(gh, 0), group_size - 1);
              gw = min(max(gw, 0), group_size - 1);
              int c = (ctop * group_size + gh) * group_size + gw;
  
              int bottom_diff_offset = (roi_batch_ind * channels + c);
              bottom_diff_offset = bottom_diff_offset * height * width;
              int top_diff_offset =
                  (n * pooled_dim + ctop) * pooled_height * pooled_width;
  
              int maxidx =
                  argmax_data[top_diff_offset + ph * pooled_width + pw];
              if (maxidx != -1) {
                  atomicAdd(
                      &bottom_diff[bottom_diff_offset + maxidx],
                      top_diff[top_diff_offset + ph * pooled_width + pw]);
              }
              """,
          "ps_roi_max_pooling_2d_bwd",
      )(
          gy[0],
          self.argmax_data,
          bottom_rois,
          bottom_roi_indices,
          self.spatial_scale,
          channels,
          height,
          width,
          out_c,
          out_h,
          out_w,
          self.group_size,
          bottom_diff,
          size=gy[0].size,
      )
  
      return bottom_diff, None, None
  
file_path: chainercv/chainercv/functions/ps_roi_max_pooling_2d.py
imports: from __future__ import division
  import numbers
  import numpy
  import six
  from chainer.backends import cuda
  from chainer import function
  from chainer.utils import type_check
  from chainercv.functions.ps_roi_average_pooling_2d import _outsize
label_desc: Use image node_id 6 for calling the PSROIMaxPooling2D obj's underlying member method code with example usage: obj.backward_gpu(inputs, gy) and returns: bottom_diff,  None,  None