并行执行的问题

大家好,经过一段时间的蛰伏(冬眠),总算又有时间来玩太极了。
想请教一下如下的情况:

import taichi as ti

ti.init()
a = ti.field(ti.f32, shape = 100)

@ti.kernel
def print_number():
    # Initialization
    for i in a:
        a[i] = 0.0

    # Element value depends on previous element
    for i in range(1,100):
        a[i] = a[i-1] + 1
        print(a[i])

print_number()

即我想对一个数组的元素进行遍历,但是后面的元素的计算会依赖到前面的元素,此时太极给出的答案就是不正确的:比如上面的例子,我预计结果应该是打印出一串从1到100的数字,但是结果是打印出了三串从1到33的数字(我猜测是因为被并行了?)。(我知道上面的例子由于计算简单,实际上是可以直接推出每个元素关于i的计算公式,然后绕过执行顺序的,但是有时候当计算复杂的时候并不一定可以推出来)
想问:1. 太极的Kernel可以强迫其不并行执行某个代码块吗?2. 如上这种后面的元素依赖前面的元素的数组遍历,一般会用什么样的方法来处理呢?

谢谢!

  1. 太极的Kernel可以强迫其不并行执行某个代码块吗?

可以采用这个方法:

@ti.kernel
def print_number():
    for i in a:
        a[i] = 0.0

    # 最外层套一个大小只有1的并行for,从而相当于强制串行
    for _ in range(1):
        for i in range(1,100):  # 里面的for不会再并行了
            a[i] = a[i-1] + 1
            print(a[i])
  1. 如上这种后面的元素依赖前面的元素的数组遍历,一般会用什么样的方法来处理呢?

这个要具体情况具体分析了,比如你这里 a[i] = a[i-1] + 1 如果改成 a[i] = a[i-1] + b[i] 的话,这篇文章就给出了解决方案:https://developer.nvidia.com/gpugems/gpugems3/part-vi-gpu-computing/chapter-39-parallel-prefix-sum-scan-cuda 最坏的情况就是不得不放弃并行了。

1 Like