[Lang] variable definition, static-typed taichi vs dynamic-typed python
#939 opened on May 10, 2020
Description
Concisely describe the proposed feature Consider the following codes:
x = ti.var(ti.f32, 4)
x = [0.1, 0.2, 0.3, 0.4] # all below 1.0
@ti.kernel
def hello() -> ti.f32:
ret = 0 # ret is ti.i32
for i in x:
ret += x[i] # ti.i32 + ti.f32, but still stored in ti.i32!!
return ret
print(hello()) # user confused: why I got 0.0?
The key reason is that: taichi is statically typed, python is dynamically typed. And the user cost a huge time on debug to realize the problem, then blame us for the inconsistent behavior between python and taichi.
Also consider:
x = ti.var(ti.f64, 4)
@ti.kernel
def hello() -> ti.f64:
ret = 0.0 # you didn't change default_fp, so it's ti.f32!!
for i in x:
ret += x[i] # ti.f32 + ti.f64, but still stored in ti.f32!!
return ret # we are losing precision now
Currently we have to depend ti.cast to ensure everything typed correct.
So I may suggest:
- use
x = ti.var(ti.i32)to initialize local variables instead ofx = 0. - use
x = ti.var(ti.f32)to initialize local variables instead ofx = 0.0. - use
x = ti.Vector(2, dt=ti.f32)to initialize local vectors instead ofx = ti.Vector([0.0, 0.0]).
Then, we can change the previous code into:
x = ti.var(ti.f32, 4)
x = [0.1, 0.2, 0.3, 0.4] # all below 1.0
@ti.kernel
def hello() -> x.dtype:
ret = ti.var(x.dtype) # also helps meta programming, right?
for i in x:
ret += x[i]
return ret
print(hello()) # got 1.0, user happy
Also consider I want to initialize a vector y, whose dimension and type are same with x (meta programming).
Currently, we can only:
y = ti.Vector([(0.0 if ti.core.is_real(x.dtype) else 0) for i in range(x.shape[0])])
Or use a dirty hack:
y = x
y *= 0
But after this issue, we can:
y = ti.Vector(x.shape[0], dt=x.dtype)`
more clear, more easy, right?
Describe the solution you'd like (if any) Not yet have a sol.
Additional comments
What will ti.Vector([0.0, 0]) do?