面向数据对象式编程

Taichi是一种 面向数据的 编程(DOP)语言。 但是,单纯的DOP会使模块化变得困难。

为了允许代码模块化,Taichi从面向对象编程(OOP)中借鉴了一些概念。

为了方便起见,我们将称此混合方案为 面向数据对象式编程 (ODOP)。

待办事项:此处应有更多文档。

一个简单的例子:

  1. import taichi as ti
  2. ti.init()
  3. @ti.data_oriented
  4. class Array2D:
  5. def __init__(self, n, m, increment):
  6. self.n = n
  7. self.m = m
  8. self.val = ti.var(ti.f32)
  9. self.total = ti.var(ti.f32)
  10. self.increment = increment
  11. ti.root.dense(ti.ij, (self.n, self.m)).place(self.val)
  12. ti.root.place(self.total)
  13. @staticmethod
  14. @ti.func
  15. def clamp(x): # Clamp to [0, 1)
  16. return max(0, min(1 - 1e-6, x))
  17. @ti.kernel
  18. def inc(self):
  19. for i, j in self.val:
  20. ti.atomic_add(self.val[i, j], self.increment)
  21. @ti.kernel
  22. def inc2(self, increment: ti.i32):
  23. for i, j in self.val:
  24. ti.atomic_add(self.val[i, j], increment)
  25. @ti.kernel
  26. def reduce(self):
  27. for i, j in self.val:
  28. ti.atomic_add(self.total, self.val[i, j] * 4)
  29. arr = Array2D(128, 128, 3)
  30. double_total = ti.var(ti.f32, shape=())
  31. ti.root.lazy_grad()
  32. arr.inc()
  33. arr.inc.grad()
  34. assert arr.val[3, 4] == 3
  35. arr.inc2(4)
  36. assert arr.val[3, 4] == 7
  37. with ti.Tape(loss=arr.total):
  38. arr.reduce()
  39. for i in range(arr.n):
  40. for j in range(arr.m):
  41. assert arr.val.grad[i, j] == 4
  42. @ti.kernel
  43. def double():
  44. double_total[None] = 2 * arr.total
  45. with ti.Tape(loss=double_total):
  46. arr.reduce()
  47. double()
  48. for i in range(arr.n):
  49. for j in range(arr.m):
  50. assert arr.val.grad[i, j] == 8