类型系统
Taichi 支持常见的数据类型。每种类型都由一个字符表示,指明它的 类别 和 精度位数,例如 i32
和 f64
。
数据的 类别 可以是以下其中之一:
i
用于有符号整数,例如233,-666u
用于无符号整数,例如233,666f
用于浮点数,例如2.33, 1e-4
数据的 精度位数 可以是以下其中之一:
8
16
32
64
它表示存储数据时使用了多少 位。位数越多,精度越高。
例如,下列是两种最常用的数据类型:
i32
表示一个32位有符号整数。f32
表示一个32位浮点数。
支持的类型
目前,Taichi支持的基本类型有
- int8
ti.i8
- int16
ti.i16
- int32
ti.i32
- int64
ti.i64
- uint8
ti.u8
- uint16
ti.u16
- uint32
ti.u32
- uint64
ti.u64
- float32
ti.f32
- float64
ti.f64
注解
每种后端支持的类型分别有:
类型 | CPU/CUDA | OpenGL | Metal |
---|---|---|---|
i8 | OK | N/A | OK |
i16 | OK | N/A | OK |
i32 | OK | OK | OK |
i64 | OK | EXT | N/A |
u8 | OK | N/A | OK |
u16 | OK | N/A | OK |
u32 | OK | N/A | OK |
u64 | OK | N/A | N/A |
f32 | OK | OK | OK |
f64 | OK | OK | N/A |
(OK:已支持,EXT:需要扩展支持,N/A:目前不支持)
注解
布尔类型使用 ti.i32
表示。
类型提升
不同类型间的二元运算将会发生数据类型提升,提升遵循 C 语言下的转换规则,例如:
i32 + f32 = f32
(integer + float = float)i32 + i64 = i64
(less-bits + more-bits = more-bits)
简单地说,在发生数据提升时会尝试选择更精确的数据类型来包含结果值。
默认精度
默认情况下,所有的数值都具有32位精度。 例如,42
的类型为 ti.i32
, 3.14
的类型为 ti.f32
。
可以在 Taichi 初始化时,指定默认的整数和浮点精度( 分别通过 default_ip
和 default_fp
):
ti.init(default_fp=ti.f32)
ti.init(default_fp=ti.f64)
ti.init(default_ip=ti.i32)
ti.init(default_ip=ti.i64)
另外需要注意的是,你可以在类型定义时使用 float
或 int
作为默认精度的别名,例如:
ti.init(default_ip=ti.i64, default_fp=ti.f32)
x = ti.var(float, 5)
y = ti.var(int, 5)
# 相当于:
x = ti.var(ti.f32, 5)
y = ti.var(ti.i64, 5)
def func(a: float) -> int:
…
# 相当于:
def func(a: ti.f32) -> ti.i64:
…
类型转换
隐式类型转换
警告
变量的类型在它 初始化时决定。
当一个 低精度 变量被赋值给 高精度 变量时,它将被隐式提升为 高精度 类型,并且不会发出警告:
a = 1.7
a = 1
print(a) # 1.0
当一个 高精度 变量被赋值给 低精度 类型时,它会被隐式向下转换为 低精度 类型,此时 Taichi 会发出警告:
a = 1
a = 1.7
print(a) # 1
显式类型转换
你可以使用 ti.cast
在不同类型之间显式地强制转换标量值:
a = 1.7
b = ti.cast(a, ti.i32) # 1
c = ti.cast(b, ti.f32) # 1.0
同样,可以使用 int()
和 float()
将标量值转换为默认精度的浮点或整数类型:
a = 1.7
b = int(a) # 1
c = float(a) # 1.0
向量和矩阵的类型转换
应用于向量/矩阵中的类型转换是逐元素的:
u = ti.Vector([2.3, 4.7])
v = int(u) # ti.Vector([2, 4])
# 如果你使用的是 ti.i32 作为默认整型精度, 那么这相当于:
v = ti.cast(u, ti.i32) # ti.Vector([2, 4])
位强制类型转换
使用 ti.bit_cast
将一个值按位转换为另一种数据类型。 基础位将在此转换中保留。 新类型的宽度必须与旧类型的宽度相同。 例如,不允许将 i32
转换成 f64
。 请谨慎使用此操作。