def METHOD_NAME(test_case, src_nd_sbp, dst_nd_sbp):
    # can not process p in dst
    if flow.sbp.partial_sum() in dst_nd_sbp:
        return
    # skip src == dst
    if src_nd_sbp == dst_nd_sbp:
        return
    # in this case, use intra group boxing
    if src_nd_sbp[0] == dst_nd_sbp[0]:
        return
    # in this case, use inter group boxing
    if (
        src_nd_sbp[1] == dst_nd_sbp[1]
        and src_nd_sbp[0] != src_nd_sbp[1]
        and dst_nd_sbp[0] != dst_nd_sbp[1]
    ):
        return
    # input
    placement = flow.placement("cuda", ranks=[[0, 1], [2, 3]])
    local_np = np.arange(4 * 4 * 4).reshape(4, 4, 4)
    x = flow.tensor(local_np, sbp=src_nd_sbp, placement=placement)
    # check eager boxing
    eager_out = x.to_global(sbp=dst_nd_sbp, placement=placement)
    test_case.assertTrue(np.array_equal(eager_out.numpy(), x.numpy()))
    # check graph boxing
    flow.boxing.nccl.enable_use_compute_stream(True)
    class TestNcclLogicalSendRecv2DGraph(flow.nn.Graph):
        def __init__(self):
            super().__init__()
        def build(self, x):
            y = x.to_global(sbp=dst_nd_sbp, placement=placement)
            return y
    graph = TestNcclLogicalSendRecv2DGraph()
    # graph.debug()
    y = graph(x)
    out_np = y.numpy()
    in_np = x.numpy()
    # if flow.env.get_rank() == 0:
    #    print("src sbp ", src_nd_sbp, ", dst sbp ", dst_nd_sbp)
    #    equal = np.array_equal(out_np, in_np)
    #    if not equal:
    #        print("in ", in_np)
    #        print("out ", out_np)
    test_case.assertTrue(np.array_equal(out_np, in_np))
    flow.boxing.nccl.enable_use_compute_stream(False)