taichi-dev/taichi

[Lang] variable definition, static-typed taichi vs dynamic-typed python

Open

#939 ouverte le 10 mai 2020

Voir sur GitHub
 (1 commentaire) (1 réaction) (1 assigné)C++ (2 384 forks)batch import
enhancementfeature requestgood first issuepython

Métriques du dépôt

Stars
 (28 195 stars)
Métriques de merge PR
 (Aucune PR mergée en 30 j)

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:

  1. use x = ti.var(ti.i32) to initialize local variables instead of x = 0.
  2. use x = ti.var(ti.f32) to initialize local variables instead of x = 0.0.
  3. use x = ti.Vector(2, dt=ti.f32) to initialize local vectors instead of x = 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?

Guide contributeur