def METHOD_NAME(self):
    def check(dim, size, backward=False):
        n = 64
        a = jt.random((n,n,n,n))
        a.sync()
        m = n // size
        arr = []
        for i in range(m):
            arr.append(a.getitem((slice(None),)*dim + (slice(i*size,i*size+size),)))
        b = concat2(arr, dim)
        if backward:
            loss = b * a
            b = jt.grad(loss, a)
        with jt.profile_scope(1, 0) as rep:
            b.sync()
        # print(rep)
        i = rep[0].index("TotalTime")
        stime = 0
        for r in rep[1:]:
            stime += float(r[i])
        bw = 4*64**4*2*2 / stime
        # sizeof(float) * numel * (split and concat) * (read and write)
        print(f"{dim} {size} {stime/1e6}ms, {bw}GB/s")
        return bw
    ndim = 4
    splits = [1, 2, 4, 8, 16, 32, 64]
    m = len(splits)
    result = np.zeros((4, m))
    result_back = np.zeros((4, m))
    for i in range(ndim):
        for j in range(m):
            result[i,j] = check(i, splits[j])
            result_back[i,j] = check(i, splits[j], True)
    print(result.T)
    print(result_back.T)
    '''