跳转至主要内容
Version: v1.6.0

Taichi 数据类

Taichi provides custom struct types for developers to assemble pieces of data together. However, it would be more convenient to have:

  • 结构体类型的 Python 表示法,使之更面向对象。
  • 与结构体类型关联的函数。

To achieve the ends, Taichi enabled the @ti.dataclass decorator on a Python class. This is inspired by Python's dataclass feature, which uses class fields with annotations to create data types.

从 Python 类创建一个结构体

下面是在 Python 类下定义 Taichi 结构体类型的示例:

vec3 = ti.math.vec3

@ti.dataclass
class Sphere:
center: vec3
radius: ti.f32

这等同于使用 ti.types.struct()

Sphere = ti.types.struct(center=vec3, radius=ti.f32)

@ti.dataclass 装饰器将 Python 类 中带标注的成员转换为生成的结构体类型 中的成员。 In both of the above examples, you end up with the same struct field.

将函数与结构体类型关联

Python 类和 Taichi 结构体类型都可以附加函数。 Building from the above example, one can embed functions in the struct as follows:

vec3 = ti.math.vec3

@ti.dataclass
class Sphere:
center: vec3
radius: ti.f32

@ti.func
def area(self):
# a function to run in taichi scope
return 4 * math.pi * self.radius * self.radius

def is_zero_sized(self):
# a python scope function
return self.radius == 0.0

Functions associated with structs follow the same scope rules as other functions. In other words, they can be placed in either the Taichi scope or the Python scope. Each instance of the Sphere struct type now have the above functions attached to them. The functions can be called in the following way:

a_python_struct = Sphere(center=ti.math.vec3(0.0), radius=1.0)
# calls a python scope function from python
a_python_struct.is_zero_sized() # False

@ti.kernel
def get_area() -> ti.f32:
a_taichi_struct = Sphere(center=ti.math.vec3(0.0), radius=4.0)
# return the area of the sphere, a taichi scope function
return a_taichi_struct.area()
get_area() # 201.062...

Notes

  • Inheritance of Taichi dataclasses is not supported.
  • While it is convenient and recommended to associate functions with a struct defined via @ti.dataclass, ti.types.struct can serve the same purpose with the help of the __struct_methods argument. As mentioned above, the two methods of defining a struct type produce identical output.
@ti.func
def area(self):
# a function to run in taichi scope
return 4 * math.pi * self.radius * self.radius

Sphere = ti.types.struct(center=ti.math.vec3, radius=ti.f32,
__struct_methods={'area': area})