Average rank of a matrix

我想求一个大矩阵的binary rank 并取平均。但是没有办法并行的求
代码如下

import taichi as ti

ti.init(arch=ti.cpu)

num_site = 1024
num_copy = 128

mat = ti.field(dtype=ti.u8, shape=(num_site, num_site))
mat_copy = ti.field(dtype=ti.u8, shape=(num_copy, num_site, num_site))

rank_lis = ti.field(dtype=ti.u8, shape=num_copy)


@ti.kernel
def average_rank():
    mat_eval()
    for i in range(num_copy):
        rank_sum(i)


@ti.func
def mat_eval():
    for i, j in mat:
        mat[i, j] = ti.random(dtype=ti.i32) % 2

    for i, j, k in mat_copy:
        mat_copy[i, j, k] = mat[j, k]

    for i in rank_lis:
        rank_lis[i] = 0


@ti.func
def rank_sum(copy_idx: ti.i32):
    ti.loop_config(serialize=True)
    for i in range(num_site):
        piv_j = -1
        for j in range(num_site):
            if mat_copy[copy_idx, i, j] == 1:
                piv_j = j
                rank_lis[copy_idx] += 1
                break
        if piv_j >= 0:
            for ii in range(num_site):
                if i == ii or mat_copy[copy_idx, ii, piv_j] == 0:
                    continue
                for jj in range(num_site):
                    mat_copy[copy_idx, ii, jj] ^= mat_copy[copy_idx, i, jj]


average_rank()
print(rank_lis)

在average_rank kernel的第一个for似乎不是parallel for.

如何让最外面的for 变成parallel的呢

Hi @HCPhy , 非常欢迎来到Taichi论坛。

average_rank中最外层for应该是并行的。你可以写个print(i)来看一下打印顺序。

除此之外,为了设置CPU上多线程的个数,你可是可以在最外层for前面加上ti.loop_config,具体可以参考:taichi.lang.misc — taichi-api-docstring documentation

我尝试打印了loop里面 i 的取值, 最外层的for 似乎并没有parallelize。

这个可能是你的 num_copy 设置的比较小。如果增大 num_copy=1000 你可以再看看结果。我这里看到是乱序的。

这里有个比较尴尬的地方,当num_copy 比较大的时候,如果num_site 也很大,有可能会超过i32的snode index的限制。有没有办法让num_copy 较小的时候仍然并行呢?

我的意思是,num_copy即使比较小也是并行的。只不过你print的时候看起来是串行的而已。

你可以通过htop看一下这个进程下面有多少线程:htop -p pid

Htop的配置参考:https://www.ktanx.com/blog/p/3025

下面图片是我跑你的程序时,线程图