- 问题不只是出现在函数调用的地方, 赋值也会先转换为 i32, 如下:
import taichi as ti
ti.init(arch=ti.gpu, print_ir=True)
@ti.kernel
def kernel():
a = ti.Vector([0x7fff_ffff], ti.u32) # work
# b = ti.Vector([0x8000_0000], ti.u32)
"""
Constant 2147483648 has exceeded the range of i32: [-2147483648, 2147483647]
"""
b = ti.Vector([ti.u32(0x8000_0000)], ti.u32) # work
kernel()
就 b = ti.Vector([0x8000_0000], ti.u32)
而言, 无论哪一门语言的用户都无法理解, 为什么会涉及到 i32 的范围的错误.
- 有些情况直接引用全局常量, 而非参数传递是更合理的写法.
import taichi as ti
import numpy as np
ti.init(arch=ti.gpu)
COLOR_MASK = np.array([0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff], np.uint32)
@ti.kernel
def kernel(color: ti.u32):
red = color & COLOR_MASK[0]
"""
Constant 4278190080 has exceeded the range of i32: [-2147483648, 2147483647]
"""
kernel(0xa53f7600)
既然支持外部变量使用, 用户在定义时也注意符合 uint32 的返回, 用户将不会意识到会有问题出现(直到外部变量中包含大于 i32 范围数字时出现…)
- 如果要将全局变量(如 COLOR_MASK) 作为参数传递, 不但可能让参数表变得非常长, 还会代理变量名污染的问题
import taichi as ti
import numpy as np
ti.init(arch=ti.gpu)
COLOR_MASK = np.array([0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff], np.uint32)
@ti.kernel
def kernel(color: ti.u32, COLOR_MASK: ti.types.ndarray()):
red = color & COLOR_MASK[0] # work
kernel(0xa53f7600, COLOR_MASK)
- 在 ti.kernel 内部定义也不是一个好办法, 首先 python scope 无法使用, ti.func使用需传参, 最后还是要手动处理类型转换
import taichi as ti
ti.init(arch=ti.gpu)
@ti.kernel
def kernel(color: ti.u32):
COLOR_MASK = ti.Vector([ti.u32(0xff000000), 0x00ff0000, 0x0000ff00, 0x000000ff], ti.u32)
red = color & COLOR_MASK[0] # work
kernel(0xf53f7600)
- 对于上述代码, 官方是否有推荐的实践方式?
直接引用外部的 ti.Vector 同样会在运行时报错
直接引用外部的 ti.field 可以实现目的, 但是 field 却只能一一赋值, 不封装的话非常丑
import taichi as ti
ti.init(arch=ti.gpu)
# COLOR_MASK = ti.Vector([0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff], ti.u32)
"""
On line 14 of file "D:\PYTHON_PATH\test_taichi\@dev\learn.py", in kernel:
red = color & COLOR_MASK[0]
^^^^^^^^^^^^^^^^^^^^^
Constant 4278190080 has exceeded the range of i32: [-2147483648, 2147483647]
"""
COLOR_MASK = ti.field(ti.u32, 4)
COLOR_MASK[0] = 0xff000000
COLOR_MASK[1] = 0x00ff0000
COLOR_MASK[2] = 0x0000ff00
COLOR_MASK[3] = 0x000000ff
@ti.kernel
def kernel(color: ti.u32):
red = color & COLOR_MASK[0] # only work for ti.field
green = color & COLOR_MASK[1] # work for ti.field and ti.Vector
kernel(0xf53f7600)
谢谢解答