Tachi compiler bug?

Hello everyone,

I’m new to Taichi and I wrote this dummy code for getting experience with taichi:

import taichi as ti

ti.init(arch=ti.gpu)

n = 640
pixels = ti.field(dtype=float, shape=(n * 2, n))

d = 0.001
goback = False

@ti.kernel
def paint(t: float):
    if((not goback) and pixels[0, 0] >= 1):
        goback = True
    elif(goback and pixels[0, 0] <= 0):
        goback = False
    for i, j in pixels:  # Parallelized over all pixels
        if(goback):
            pixels[i, j] = pixels[i, j] - d
        else:
            pixels[i, j] = pixels[i, j] + d

gui = ti.GUI("Test", res=(n * 2, n))

for i in range(1000000):
    paint(i * 0.03)
    gui.set_image(pixels)
    gui.show()

and I got a “local variable ‘goback’ referenced before assignment” for goback, but if I remove the goback and keep d I don’t get any exception. n and pixels also don’t cause any problem. So am I doing something wrong?

Thank you for reading,
Have a nice day!

Edit: looks like the code part is unreadable, is there a way to render it as python code?

Hi,

This is because you are using an assignment on a global variable goback inside of the paint function. Python interpreter for some reasons will decide not to use the global goback. So that’s the reason why you get unboundedLocalError when you reference the goback before it is locally assigned.

Check this out for detailed explanation.

Solution

If it’s a normal Python function, you can use nonlocal or global at the first line of the function (nonlocal goback).

But in Taichi, there is no binding for these nonlocal or global in Taichi scope. So in this case, if you still want to modify a global variable in Taichi scope and use it as a non-static flag, you can define a new local variable and return it in @ti.kernel.

import taichi as ti

ti.init(arch=ti.gpu)

n = 640
pixels = ti.field(dtype=float, shape=(n * 2, n))

d = 0.001

goback = 0

@ti.kernel
def paint(t: float) -> ti.int32:
    ret_flag = 0
    if (not goback) and pixels[0, 0] >= 1:
        ret_flag = 1
    elif goback and pixels[0, 0] <= 0:
        ret_flag = 0
    for i, j in pixels:  # Parallelized over all pixels
        if ret_flag:
            pixels[i, j] = pixels[i, j] - d
        else:
            pixels[i, j] = pixels[i, j] + d
    return ret_flag


gui = ti.GUI("Test", res=(n * 2, n))


for i in range(1000000):
    goback = paint(i * 0.03)
    gui.set_image(pixels)
    gui.show()

The forum support Markdown. You can render the code by the code fences.

2 个赞