Taichi: Invalid input for autodiff, Kernel Simplicity Rule

Created on 9 Mar 2020  路  5Comments  路  Source: taichi-dev/taichi

Hi! I am trying to create a compute_loss function, where along the path of the object I calculate the closest distance, making that my loss. I am using this code:

@ti.kernel
def compute_loss(t: ti.i32):
    for i in range(1024):
        d=ti.sqrt(ti.sqr(help[1, 0][0] - path[i, 0][0]) + ti.sqr(help[1, 0][1] - path[i, 0][1]))
        if dist[0] > d:
            dist[0] = d
    dist[1] = 0.01
    loss[None] = ti.sqr(dist[1] - dist[0])

The error:
Traceback (most recent call last):
File "C:/Users/User/PycharmProjects/Try/Throwing.py", line 166, in
main()
File "C:/Users/User/PycharmProjects/Try/Throwing.py", line 140, in main
forward()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\taichi\lang\tape.py", line 19, in __exit__
self.grad()
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\taichi\lang\tape.py", line 28, in grad
func.grad(*args)
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\taichi\lang\kernel.py", line 400, in __call__
return self.compiled_functionskey
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\taichi\lang\kernel.py", line 374, in func__
t_kernel()
RuntimeError: [reverse_segments.cpp:taichi::lang::irpass::reverse_segments@64] Invalid program input for autodiff. Please check the documentation for the "Kernel Simplicity Rule".
[E 03/09/20 17:10:42.325] [reverse_segments.cpp:taichi::lang::irpass::reverse_segments@64] Invalid program input for autodiff. Please check the documentation for the "Kernel Simplicity Rule".

Process finished with exit code 1

I don't see why to loop makes it invalid, without it, it runs fine. Can somebody point out the mistake for me?

Most helpful comment

Maybe you want to use dist[0] = min(dist[0], d) instead of if, which is not supported by adjoint grad as far as I can see.

All 5 comments

You can use ti.static(range(1024)) instead. Non-static for loops are not allowed with other statements.

Kernel Simplicity Rule: Kernel body consists of multiple simply nested for-loops. I.e., each for-loop can either contain exactly one (nested) for-loop (and no other statements), or a group of statements without loops.

Thank you, it solved that problem, but now it keeps crashing, I put it in a separate function to make it more readable.

@ti.kernel
def min_dis():
    for i in ti.static(range(1024)):
        d=ti.sqrt(ti.sqr(help[1, 0][0] - path[i, 0][0]) + ti.sqr(help[1, 0][1] - path[i, 0][1]))
        if dist[0] > d:
            dist[0] = ti.cast(d, real)

No error on the console, it just says on the cv2 image that loads up that it is not responding. In debug it crashes somewhere between

  min_dis()
  compute_loss(steps-1)

Maybe you can change the for loop in min_dis() here back to the non-static one. One loop without other statements is OK. ti.static(range(1024)) in fact unrolls the loop and I'm not sure if the number 1024 is too large...

Maybe you want to use dist[0] = min(dist[0], d) instead of if, which is not supported by adjoint grad as far as I can see.

Thank you, changing it to non-static, and applying ti.min solved it.

Was this page helpful?
0 / 5 - 0 ratings