TypeError: loop of ufunc does not support argument 0 of type Expr which has no callable cos method

代码片断如下:

@ti.kernel
def init_particles():
    _boundary = (boundary[0] * screen_to_world_ratio, boundary[1] * screen_to_world_ratio)
    center = ti.Vector([_boundary[0]/2, _boundary[1]/2])
    radius = np.min(_boundary) *0.5
    num_angle = 30
    num_p_in_radius = num_particles // num_angle
    p_idx = 0
    for i in range(num_angle):
        theta = 2*np.pi*i/num_angle
        for j in range(num_p_in_radius):
            ri = j/num_p_in_radius * radius
            x = ri * np.cos(theta)
            y = ri * np.sin(theta)
            positions[p_idx] = ti.Vector([x, y]) + center
            for c in ti.static(range(dim)):
                velocities[p_idx][c] = (ti.random() - 0.5) * 4
            p_idx += 1

报错如下:

Traceback (most recent call last):
  File "pbf2d.py", line 327, in <module>
    main()
  File "pbf2d.py", line 315, in main
    init_particles()
  File "/home/syguan/miniconda3/envs/taichi-env/lib/python3.7/site-packages/taichi/lang/kernel_impl.py", line 795, in wrapped
    return primal(*args, **kwargs)
  File "/home/syguan/miniconda3/envs/taichi-env/lib/python3.7/site-packages/taichi/lang/kernel_impl.py", line 722, in __call__
    key = self.ensure_compiled(*args)
  File "/home/syguan/miniconda3/envs/taichi-env/lib/python3.7/site-packages/taichi/lang/kernel_impl.py", line 713, in ensure_compiled
    self.materialize(key=key, args=args, arg_features=arg_features)
  File "/home/syguan/miniconda3/envs/taichi-env/lib/python3.7/site-packages/taichi/lang/kernel_impl.py", line 518, in materialize
    kernel_name, self.is_grad)
  File "/home/syguan/miniconda3/envs/taichi-env/lib/python3.7/site-packages/taichi/lang/kernel_impl.py", line 512, in taichi_ast_generator
    compiled()
  File "pbf2d.py", line 284, in init_particles
    x = ri * np.cos(theta)
TypeError: loop of ufunc does not support argument 0 of type Expr which has no callable cos method

我感觉是这个变量在编译时还没赋值? 请问我该怎么改呢?

Hi @shanyan, 请不要在Taichi Scope使用numpy库函数。

可以使用 ti.cos, ti.sin代替 np.cosnp.sin

谢谢禹同学的解答! 可以麻烦你再解释一下为什么不能用numpy库函数吗?其他的比如说cv2可以用吗?

如果我写成这样是可以跑的

_boundary = boundary
center = ti.Vector([_boundary[0]/2, _boundary[1]/2])
radius = np.min(_boundary)*100
num_angle = 30
num_p_in_radius = num_particles // num_angle
thetas = [2*np.pi*i/num_angle for i in range(num_angle)]
@ti.kernel
def init_particles():
    p_idx = 0
    delta = h * 0.8
    for i in ti.static(range(num_angle)):
        for j in range(num_p_in_radius):
            ri = j/num_p_in_radius * radius
            x = ri * np.cos(thetas[i])
            y = ri * np.sin(thetas[i])
            positions[p_idx] = ti.Vector([x, y])* delta + center
            for c in ti.static(range(dim)):
                velocities[p_idx][c] = (ti.random() - 0.5) * 0
            p_idx += 1

在加了ti.kernel或者ti.func之后的内容就会被Taichi 的compiler来解析和处理,Taichi处理Numpy一般就是通过ti.ext_arr()参数来传递进来的。如果直接使用numpy的数组或者函数可能就会出现类似的问题。

记住Taichi是另一种语言,可能对你有些帮助。

了解了,茅塞顿开,谢谢!