'Function to perform bprop of ROIPooling.
Arguments:
I (Tensor): input errors (C, pooled_height, pooled_width, roi_count)
argmax (Tensor): max args from the fprp (C, pooled_height, pooled_width, roi_count)
rois (Tensor): (ROIs, 5)
O (Tensor): output deltas (C, H, W, N)'

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

    assert (I.size == argmax.size == (((C * pooled_height) * pooled_width) * roi_count)), 'ROIPooling    bprop    input    size    do    not    match'
    assert (O.size == (((C * H) * W) * self.bsz)), 'ROIPooling    bprop    output    size    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_E = I._tensor.reshape(C, pooled_height, pooled_width, roi_count)
    array_rois = rois._tensor
    array_delta = O._tensor.reshape(C, H, W, self.bsz)
    array_argmax = argmax._tensor.reshape(C, pooled_height, pooled_width, roi_count)
    array_delta[:] = 0
    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 w in range(xmin, (xmax + 1)):
            for h in range(ymin, (ymax + 1)):
                phstart = int(np.floor((float((h - ymin)) / stride_h)))
                phend = int(np.ceil((float(((h - ymin) + 1)) / stride_h)))
                pwstart = int(np.floor((float((w - xmin)) / stride_w)))
                pwend = int(np.ceil((float(((w - xmin) + 1)) / stride_w)))
                phstart = min(max(phstart, 0), pooled_height)
                phend = min(max(phend, 0), pooled_height)
                pwstart = min(max(pwstart, 0), pooled_width)
                pwend = min(max(pwend, 0), pooled_width)
                for ph in range(phstart, phend):
                    for pw in range(pwstart, pwend):
                        max_idx_tmp = array_argmax[:, ph, pw, b_id]
                        for c in range(C):
                            if (max_idx_tmp[c] == ((h * W) + w)):
                                array_delta[(c, h, w, int(idx))] += array_E[(c, ph, pw, b_id)]
