检查dense后pointer snode的activity时,提示SNode只有1维
[$38] S3 has 1 indices. Indexed with 2.
无法求dense[i] => pointer[i,j]
这个SNode的activity。。
可能是bug?还是我哪里的理解有问题…
pointer()
SNode 和 dens().pointer().pointer()
SNode都正常
ti.init(arch=ti.gpu)
pf = ti.field(ti.f64)
dpf = ti.field(ti.f64)
dppf = ti.field(ti.f64)
# pointer case
p = ti.root.pointer(ti.i, 2)
p.place(pf)
# dense => pointer case
d = ti.root.dense(ti.i, 2)
dp = d.pointer(ti.j, 2)
dp.place(dpf)
# dense => pointer => pointer case
dpp = dp.pointer(ti.j, 2)
dpp.place(dppf)
@ti.kernel
def test_pf():
for i in pf:
if ti.is_active(p, i):
print(i, "active")
@ti.kernel
def test_dpf():
for i, j in dpf:
if ti.is_active(dp, [i,j]):
print(i,j, "active")
@ti.kernel
def test_dppf():
for i, j in dppf:
if ti.is_active(dpp, [i,j]):
print(i,j, "active")
test_pf()
# test_dpf() # RuntimeError
test_dppf()
mzhang
2022 年9 月 28 日 02:22
#2
ti.is_active
只能检查pointer/bitmask这类snodes,访问dpf虽然要两个index,但是只有第二层是pointer,因此test_dpf
里给ti.is_active
的index应该只包含第二层的
1 个赞
好像还是不对…
如果这个pointer是多维(>=2),报错还是说SNode只有1维,无法判断这个多维pointer SNode的activity。
将上面的代码pointer维度加一维
ti.init(arch=ti.gpu)
pf = ti.field(ti.f64)
dpf = ti.field(ti.f64)
dppf = ti.field(ti.f64)
# pointer case
p = ti.root.pointer(ti.ij, (2,2))
p.place(pf)
# dense => pointer case
d = ti.root.dense(ti.i, 2)
dp = d.pointer(ti.jk, (2,2))
dp.place(dpf)
# dense => pointer => pointer case
dpp = dp.pointer(ti.jk, (2,2))
dpp.place(dppf)
@ti.kernel
def test_pf():
for i,j in pf:
if ti.is_active(p, [i,j]):
print(i,j, "active")
@ti.kernel
def test_dpf():
for i, j, k in dpf:
if ti.is_active(dp, [j,k]): # no i since dense???? still error.
print(i,j,k, "active")
@ti.kernel
def test_dppf():
for i, j, k in dppf:
if ti.is_active(dpp, [i,j,k]):
print(i,j,k, "active")
test_pf()
test_dpf() # RuntimeError
test_dppf()
一个更清楚的例子
ti.init(arch=ti.gpu)
dpf = ti.field(ti.f64)
d = ti.root.dense(ti.i, 2)
dp = d.pointer(ti.jk, (2,2))
dp.place(dpf)
# inactive dpf[0,0,0]
dpf[0, 0, 1] = 1.0
dpf[0, 1, 0] = 2.0
dpf[0, 1, 1] = 3.0
# inactive dpf[1,0,0]
dpf[1, 0, 1] = 11.0
dpf[1, 1, 0] = 12.0
dpf[1, 1, 1] = 13.0
@ti.kernel
def is_active_1d(snode: ti.template(), i: ti.i32) -> ti.i32:
return ti.is_active(snode, i)
def test_dpf():
for i in range(2):
if is_active_1d(dp, i):
print(i, "active")
else:
print(i, "inactive")
test_dpf()
print(dpf)
'''
0 inactive
1 inactive
[[[ 0. 1.]
[ 2. 3.]]
[[ 0. 11.]
[12. 13.]]]
'''
主要问题在于:
跟在dense后的pointer snode (dp
),比如是n维,在使用ti.is_active
时,提示只有一维,其实应该是(1+n)维。导致无法查询dp
中元素的activity。
ti.is_active
似乎只检查了dp
中的首个元素的activity。
一种丑陋的hack解决方式是,再加一层ugly pointer with shape (1,1)。。
dupf = ti.field(ti.f64)
d = ti.root.dense(ti.i, 2)
du = d.pointer(ti.jk, (1,1)) # ugly pointer of shape (1,1)
dup = du.pointer(ti.jk, (2,2))
dup.place(dupf)
@ti.kernel
def test_dupf():
for i, j, k in dupf:
if ti.is_active(dup, [i,j,k]):
print(i, j, k, "active")
else:
print(i, j, k, "inactive")
test_dupf() # working...
我觉得算是一个小bug
@identxxy 感谢报告,这的确是个 bug。我已经在 GitHub 上提了 issue 和相应的解决 PR ,在下个版本中你应该就不需要 hack 了
3 个赞