AttributeError: 'Expr' object has no attribute 'norm'

import taichi as ti
ti.init(arch=ti.gpu,default_fp=ti.f64)
res_x=1024
res_y=1024
pixels=ti.Vector.field(3,ti.f64,shape=(res_x,res_y))
G=6.674*10**-11
M_sun=3
m_earth=1
color_sun = ti.Vector([255, 255, 0])
r_sun = 32
color_earth = ti.Vector([255, 255, 255])
r_earth = 10
pos_sun = ti.Vector([512.0, 512.0])
pos_earth = ti.Vector([100.0, 100.0])
v_sun = ti.Vector([0.0, 0.0])
a_sun = ti.Vector([0.0, 0.0])
v_earth = ti.Vector([100.0, 200.0])
a_earth = ti.Vector([0.0, 0.0])
@ti.func
def draw_global(pixels,color,pos,r,i,j):
    pos_now = ti.Vector([i, j])
    c=ti.random(ti.f64)
    if((pos_now-pos).norm()<r and c<0.995):
        pixels[i, j] =color
@ti.func
def cal_pos(a_sun,a_earth,v_sun,v_earth,pos_sun,pos_earth):
    r = (pos_sun - pos_earth).norm()
    force = G * M_sun * m_earth / (r ** 2)
    x = pos_sun[0] - pos_earth[0]
    y = pos_sun[1] - pos_earth[1]
    forced_sun = ti.Vector([force * ti.sin(ti.atan2(x, y)), force * ti.cos(ti.atan2(x, y))])
    forced_earth = ti.Vector([force * ti.sin(ti.atan2(y, x)), force * ti.cos(ti.atan2(y, x))])
    asun = a_sun + forced_sun / M_sun
    aearth = a_earth + forced_earth / m_earth
    vsun=v_sun+asun
    vearth=v_earth+aearth
    pos_sun=pos_sun+vsun
    pos_earth=pos_earth+vearth
    return asun,aearth,vsun,vearth,pos_sun,pos_earth
@ti.func
def render(pos_sun:ti.f64,pos_earth:ti.f64):
    for i, j in pixels:
        pixels[i,j]=ti.Vector([0,0,0])
        draw_global(pixels,color_sun,pos_sun,r_sun,i,j)
        draw_global(pixels,color_earth,pos_earth,r_earth,i,j)
@ti.kernel
def ti_main(a_sun:ti.f64,a_earth:ti.f64,v_sun:ti.f64,v_earth:ti.f64,pos_sun:ti.f64,pos_earth:ti.f64):
    a_sun,a_earth,v_sun,v_earth,pos_sun,pos_earth=cal_pos(a_sun,a_earth,v_sun,v_earth,pos_sun,pos_earth)
    render(pos_sun,pos_earth)
if __name__ == '__main__':
    print("starting")
    gui = ti.GUI("gui", res=(res_x, res_y))
    while gui.running:
        ti_main(a_sun,a_earth,v_sun,v_earth,pos_sun,pos_earth)
        gui.set_image(pixels)
        gui.show()

想问下这不知道为什么不能调用norm()函数,明明单独用都可行

您好,

Taichi kernel 是静态类型的,其参数由 kernel 定义里的 type hint 决定。ti_main 中定义了 pos_sun:ti.f64,pos_earth:ti.f64 两个参数为浮点数类型,所以 (pos_sun - pos_earth).norm() 会在编译时会试图获取浮点数的 norm() 方法,所以报错。

想问下这具体应该这么改呢?我这怎么改都不对 :disappointed:

a_sun等参数是ti.Vector,你Kernel的type hints是不对的。可以用ti.template(), 比如:

import taichi as ti

ti.init()

@ti.kernel
def init(a: ti.template()):
    b = a
    print(b)


a = ti.Vector([1.0,1.0])
init(a)