def METHOD_NAME(test_case, placement, rois_sbp):
    dims = [8, 8, 64, 64]
    x = random_tensor(4, *dims).to_global(
        placement=placement,
        sbp=[flow.sbp.broadcast for _ in range(len(placement.ranks.shape))],
    )
    x.oneflow = x.oneflow.detach().requires_grad_()
    x.pytorch = x.pytorch.detach().requires_grad_()
    def get_h_w(idx1, idx2):
        if idx1 > idx2:
            idx1, idx2 = idx2, idx1
        h1 = idx1 // 64
        w1 = idx1 % 64
        h2 = idx2 // 64
        w2 = idx2 % 64
        return [x / 2 for x in [h1, w1, h2, w2]]
    np_rois = _get_np_rois()
    of_rois = (
        flow.tensor(np_rois, dtype=flow.float)
        .to_global(placement=flow.placement.all("cpu"), sbp=[flow.sbp.broadcast,])
        .to_global(placement, rois_sbp)
    )
    torch_rois = pytorch.tensor(np_rois)
    of_out = flow.roi_align(x.oneflow, of_rois, 2.0, 14, 14, 2, True)
    torch_out = torchvision.ops.roi_align(
        x.pytorch,
        torch_rois,
        spatial_scale=2.0,
        output_size=[14, 14],
        sampling_ratio=2,
        aligned=True,
    )
    # compare output
    of_local = of_out.to_global(
        placement=flow.placement.all("cpu"), sbp=[flow.sbp.broadcast,]
    ).to_local()
    test_case.assertTrue(
        np.allclose(
            of_local.numpy(), torch_out.detach().cpu().numpy(), rtol=1e-04, atol=1e-4
        )
    )
    # compare backward
    of_out.sum().backward()
    torch_out.sum().backward()
    of_input_grad = x.oneflow.grad.to_global(
        placement=flow.placement.all("cpu"), sbp=[flow.sbp.broadcast,]
    ).to_local()
    torch_input_grad = x.pytorch.grad.detach().cpu()
    test_case.assertTrue(
        np.allclose(
            of_input_grad.numpy(), torch_input_grad.numpy(), rtol=1e-04, atol=1e-4
        )
    )