'Function to perform fprop of ROIPooling
Arguments:
I (Tensor): (C, H, W, N)
rois (Tensor): (ROIs, 5)
O (Tensor): (C, pooled_height, pooled_width, roi_count)
argmax (Tensor): (C, pooled_height, pooled_width, roi_count)'

def roipooling_fprop(self, I, rois, O, argmax, roi_count, C, H, W, pooled_height, pooled_width, spatial_scale):

    assert (I.size == (((C * H) * W) * self.bsz)), 'ROIPooling    input    feature    map    size    do    not    match'
    assert (O.size == argmax.size == (((C * pooled_height) * pooled_width) * roi_count)), 'ROIPooling    output    shape    do    not    match'
    assert (rois.shape[1] == 5), 'ROIs    should    be    on    the    row    dimension'
    assert (rois.shape[0] == roi_count), 'ROIs    do    not    match    with    roi    count'
    array_fm = I._tensor.reshape(C, H, W, self.bsz)
    array_rois = rois._tensor
    array_O = O._tensor.reshape(C, pooled_height, pooled_width, roi_count)
    array_argmax = argmax._tensor.reshape(C, pooled_height, pooled_width, roi_count)
    array_O[:] = 0
    array_argmax[:] = (-1)
    for b_id in xrange(roi_count):
        [idx, xmin, ymin, xmax, ymax] = array_rois[b_id]
        xmin = int(round((xmin * spatial_scale)))
        xmax = int(round((xmax * spatial_scale)))
        ymin = int(round((ymin * spatial_scale)))
        ymax = int(round((ymax * spatial_scale)))
        roi_width = max(((xmax - xmin) + 1), 1)
        roi_height = max(((ymax - ymin) + 1), 1)
        stride_h = (float(roi_height) / float(pooled_height))
        stride_w = (float(roi_width) / float(pooled_width))
        for h_out in xrange(pooled_height):
            (sliceh, lenh) = self._roipooling_slice(h_out, stride_h, H, ymin)
            if (sliceh.stop <= sliceh.start):
                continue
            for w_out in xrange(pooled_width):
                (slicew, lenw) = self._roipooling_slice(w_out, stride_w, W, xmin)
                if (slicew.stop <= slicew.start):
                    continue
                else:
                    array_I = array_fm[:, sliceh, slicew, int(idx)].reshape(C, (-1))
                    array_O[:, h_out, w_out, b_id] = np.max(array_I, axis=1)
                    max_idx_slice = np.unravel_index(np.argmax(array_I, axis=1), (lenh, lenw))
                    max_idx_slice_h = (max_idx_slice[0] + sliceh.start)
                    max_idx_slice_w = (max_idx_slice[1] + slicew.start)
                    max_idx_slice = ((max_idx_slice_h * W) + max_idx_slice_w)
                    array_argmax[:, h_out, w_out, b_id] = max_idx_slice
