def METHOD_NAME(
    dev,
    target,
    op_name: str = "cumsum",
    gt_func: Callable[..., np.array] = np.cumsum,
):
    def check_scan(np_ref, data, axis=None, dtype=None, exclusive=False):
        implementations = get_implementations(op_name, axis, dtype, exclusive)
        fcompute, fschedule = tvm.topi.testing.dispatch(target, implementations)
        tvm.topi.testing.compare_numpy_tvm([data], np_ref, target, dev, fcompute, fschedule)
    data = np.array([2, 3, 0])
    check_scan(gt_func(data), data)
    data = np.random.rand(10) > 0.5
    data = data.astype(np.int32)
    check_scan(gt_func(data, dtype=np.int32), data)
    check_scan(gt_func(data), data, dtype="int64")
    data = np.random.rand(10) > 0.5
    check_scan(gt_func(data, dtype=np.int32), data, dtype="int32")
    for in_dtype in ["float32", "float64"]:
        if target == "metal" and in_dtype == "float64":
            # float64 is not supported in metal
            continue
        data = np.random.randn(10, 10).astype(in_dtype)
        check_scan(gt_func(data), data)
        check_scan(gt_func(data, axis=0), data, axis=0)
        check_scan(gt_func(data, axis=1), data, axis=1)
        data = np.random.randn(10, 5, 10).astype(in_dtype)
        check_scan(gt_func(data), data)
        check_scan(gt_func(data, axis=0), data, axis=0)
        check_scan(gt_func(data, axis=1), data, axis=1)
        check_scan(gt_func(data, axis=-1), data, axis=-1)
    for in_dtype in ["int32", "int64"]:
        data = np.random.randint(-100, 100, size=(100, 100)).astype(in_dtype)
        check_scan(gt_func(data, dtype=in_dtype), data)
        check_scan(gt_func(data), data, dtype="int64")
        check_scan(gt_func(data, axis=0, dtype=in_dtype), data, axis=0)
        check_scan(gt_func(data, axis=1, dtype=in_dtype), data, axis=1)
        data = np.random.randint(1 << 30, (1 << 31) - 1, size=(100)).astype(in_dtype)
        check_scan(gt_func(data), data, dtype="int64")
    data = np.random.randint(-100, 100, size=(100, 100)).astype("int64")
    expected_result = np.roll(gt_func(data), 1)
    expected_result[0] = identity_value[op_name]
    check_scan(expected_result, data, dtype="int64", exclusive=True)
    expected_result = np.roll(gt_func(data, axis=0, dtype=in_dtype), 1, axis=0)
    expected_result[0, :] = identity_value[op_name]
    check_scan(expected_result, data, axis=0, exclusive=True)
    expected_result = np.roll(gt_func(data, axis=1, dtype=in_dtype), 1, axis=1)
    expected_result[:, 0] = identity_value[op_name]
    check_scan(gt_func(data, axis=1, dtype=in_dtype), data, axis=1)