Question about updating temporary global variable
Env
in case
[Taichi] mode=release
[Taichi] version 0.6.37, llvm 10.0.0, commit e0ac1d86, osx, python 3.8.3
[Taichi] Starting on arch=x64
In short
I want to access temporary variable(say init by ti.Vector() ) in taichi scope. However, the results turns out that in taichi scope , program could only capture the initial value of the temporary variable if the variable is not the input of this taichi scope function, but in py scope it could.
To be clear, here we have this script:
import taichi as ti
import math
ti.init(ti.cpu, debug=True)
@ti.data_oriented
class trsfrm:
def __init__(self, translation=ti.Vector([0.0, 0.0]), orientation=0.0, localscale=1.0):
'''
class variable init by ti.Vector
:param translation:
:param orientation:
:param localscale:
'''
self.translation = translation
self.orientation = orientation % (2 * math.pi)
self.localScale = localscale
def __repr__(self):
return '{} ( Trsln : {}, Ornttn: {}, lclScl: {})'.format(
self.__class__.__name__,
self.translation,
self.orientation,
self.localScale)
@ti.data_oriented
class trsfrm_field:
def __init__(self):
'''
class member init by ti.Vector.field
'''
self.translation = ti.Vector.field(2, dtype=ti.f32, shape=[1])
# self.orientation = orientation % (2 * math.pi)
# self.localScale = localscale
def __repr__(self):
return '{} ( Trsln : {})'.format(
self.__class__.__name__,
self.translation,
)
@ti.kernel
def kern_test_with_input(t_1 : ti.template(), t_2 : ti.template()):
print("kern with input t1: ", t_1)
print("kern with input t2: ", t_2[0])
@ti.kernel
def kern_test_without_input():
print("kern without input t1: ", t1.translation)
print("kern without input t2: ", t2.translation[0])
@ti.kernel
def kern_add(t:ti.template()):
t[0] += ti.Vector([2.0, 2.0])
# print("kern add field", t[0])
t1 = trsfrm()
t2 = trsfrm_field()
while (True):
t1.translation = t1.translation + ti.Vector([2.0, 2.0])
print(t1)
print("py scope print t1: ",t1.translation)
# increment t2
kern_add(t2.translation)
kern_test_without_input()
# can not capture the incremented t1
kern_test_with_input(t1.translation, t2.translation)
print(" ")
What’s the program?
Bascially, the program has two forms of class trsfm, one(trsfm) init with ti.Vector, another(trsfrm_field) with ti.Vector.field().
My current implementation is class trsfrm, what I wanna do is to increment the translation member of class trsfrm and capture the incremented class trsfrm in taichi scope.
However, in kern_test_without_input it could only capture the initial value( keep printing [2.0, 2.0] instead of incrementing itself ). The funny thing to me is that: in py scope the t1 still updates itself . While in kern_test_input, with t1 as input it can capture the increasing value.
The truth is, the trsfrm_field no matter without or with input, the taichi scope could always capture the increasement.
The program output is :
trsfrm ( Trsln : [2. 2.], Ornttn: 0.0, lclScl: 1.0)
py scope print t1: [2. 2.]
[Taichi] materializing...
kern without input t1: [2.000000, 2.000000]
kern without input t2: [2.000000, 2.000000]
kern with input t1: [2.000000, 2.000000]
kern with input t2: [2.000000, 2.000000]
trsfrm ( Trsln : [4. 4.], Ornttn: 0.0, lclScl: 1.0)
py scope print t1: [4. 4.]
kern without input t1: [2.000000, 2.000000]
kern without input t2: [4.000000, 4.000000]
kern with input t1: [4.000000, 4.000000]
kern with input t2: [4.000000, 4.000000]
trsfrm ( Trsln : [6. 6.], Ornttn: 0.0, lclScl: 1.0)
py scope print t1: [6. 6.]
kern without input t1: [2.000000, 2.000000]
kern without input t2: [6.000000, 6.000000]
kern with input t1: [6.000000, 6.000000]
kern with input t2: [6.000000, 6.000000]
The kern without input t1 is always the same. Due to some resons I expect it to increase as well.
Sry about the wording
So The Question:
-
Is there an elegant way to capture the ti.Vector change in taichi global scope?
-
p.s. why the kern without input t1 can not capture the t1 increasement? Is this a bug or meant to be like this ?
-
Take as input would cause performance to drop. This phenomenon can not be easily captured here in my repo, take the transform as input would cause fps to drop from 15 fps to 8fps, with the same amout of calculation I think.
So why?
Why asking this?
I want to implement a transform class for collider in euler based fluid simulation in order to make the collider rotate or translate. Here is the repo link.
The circle(collider) stands still if I do not make the transform.rotation as the function input in rendering function. (currently I access the )
Currently my walkaround is either
- take as kernel function(render) input
- init with ti.field
But personally, I am not a big fan of capturing the increasement by adding t1 as input because in that way it may take undefined multiple number of colliders as input. And probably due to this, although the ball can rotate, the fps drops drastically(from 15fps → 8fps). From the experience, it should not happen since the function did not change that much whether with or without the input.
Also init the transform member with ti.field is not that feasible to me because ti.field cannot be init after materialize or start an kernel function. In this way we somehow cannot trivially add new collider with transform as member to the scene.
So is there any walkaround for this ?
Hope my statement is clear and clean…