gstaichi 0.1.18.dev1__cp310-cp310-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools/cmake/SPIRV-ToolsConfig.cmake +5 -0
  2. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools/cmake/SPIRV-ToolsTarget-release.cmake +29 -0
  3. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools/cmake/SPIRV-ToolsTarget.cmake +113 -0
  4. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-diff/cmake/SPIRV-Tools-diffConfig.cmake +5 -0
  5. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-diff/cmake/SPIRV-Tools-diffTargets-release.cmake +19 -0
  6. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-diff/cmake/SPIRV-Tools-diffTargets.cmake +122 -0
  7. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-link/cmake/SPIRV-Tools-linkConfig.cmake +5 -0
  8. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-link/cmake/SPIRV-Tools-linkTargets-release.cmake +19 -0
  9. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-link/cmake/SPIRV-Tools-linkTargets.cmake +122 -0
  10. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-lint/cmake/SPIRV-Tools-lintConfig.cmake +5 -0
  11. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-lint/cmake/SPIRV-Tools-lintTargets-release.cmake +19 -0
  12. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-lint/cmake/SPIRV-Tools-lintTargets.cmake +122 -0
  13. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-opt/cmake/SPIRV-Tools-optConfig.cmake +5 -0
  14. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-opt/cmake/SPIRV-Tools-optTargets-release.cmake +19 -0
  15. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-opt/cmake/SPIRV-Tools-optTargets.cmake +122 -0
  16. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-reduce/cmake/SPIRV-Tools-reduceConfig.cmake +5 -0
  17. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-reduce/cmake/SPIRV-Tools-reduceTarget-release.cmake +19 -0
  18. gstaichi-0.1.18.dev1.data/data/SPIRV-Tools-reduce/cmake/SPIRV-Tools-reduceTarget.cmake +122 -0
  19. gstaichi-0.1.18.dev1.data/data/bin/SPIRV-Tools-shared.dll +0 -0
  20. gstaichi-0.1.18.dev1.data/data/include/GLFW/glfw3.h +6389 -0
  21. gstaichi-0.1.18.dev1.data/data/include/GLFW/glfw3native.h +594 -0
  22. gstaichi-0.1.18.dev1.data/data/include/spirv-tools/instrument.hpp +268 -0
  23. gstaichi-0.1.18.dev1.data/data/include/spirv-tools/libspirv.h +907 -0
  24. gstaichi-0.1.18.dev1.data/data/include/spirv-tools/libspirv.hpp +375 -0
  25. gstaichi-0.1.18.dev1.data/data/include/spirv-tools/linker.hpp +97 -0
  26. gstaichi-0.1.18.dev1.data/data/include/spirv-tools/optimizer.hpp +970 -0
  27. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-diff.lib +0 -0
  28. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-link.lib +0 -0
  29. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-lint.lib +0 -0
  30. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-opt.lib +0 -0
  31. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-reduce.lib +0 -0
  32. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools-shared.lib +0 -0
  33. gstaichi-0.1.18.dev1.data/data/lib/SPIRV-Tools.lib +0 -0
  34. gstaichi-0.1.18.dev1.data/data/lib/cmake/glfw3/glfw3Config.cmake +3 -0
  35. gstaichi-0.1.18.dev1.data/data/lib/cmake/glfw3/glfw3ConfigVersion.cmake +65 -0
  36. gstaichi-0.1.18.dev1.data/data/lib/cmake/glfw3/glfw3Targets-release.cmake +19 -0
  37. gstaichi-0.1.18.dev1.data/data/lib/cmake/glfw3/glfw3Targets.cmake +107 -0
  38. gstaichi-0.1.18.dev1.data/data/lib/glfw3.lib +0 -0
  39. gstaichi-0.1.18.dev1.dist-info/METADATA +108 -0
  40. gstaichi-0.1.18.dev1.dist-info/RECORD +198 -0
  41. gstaichi-0.1.18.dev1.dist-info/WHEEL +5 -0
  42. gstaichi-0.1.18.dev1.dist-info/entry_points.txt +2 -0
  43. gstaichi-0.1.18.dev1.dist-info/licenses/LICENSE +201 -0
  44. gstaichi-0.1.18.dev1.dist-info/top_level.txt +1 -0
  45. taichi/CHANGELOG.md +15 -0
  46. taichi/__init__.py +44 -0
  47. taichi/__main__.py +5 -0
  48. taichi/_funcs.py +706 -0
  49. taichi/_kernels.py +420 -0
  50. taichi/_lib/__init__.py +3 -0
  51. taichi/_lib/c_api/bin/taichi_c_api.dll +0 -0
  52. taichi/_lib/c_api/include/taichi/cpp/taichi.hpp +1401 -0
  53. taichi/_lib/c_api/include/taichi/taichi.h +29 -0
  54. taichi/_lib/c_api/include/taichi/taichi_core.h +1111 -0
  55. taichi/_lib/c_api/include/taichi/taichi_cpu.h +29 -0
  56. taichi/_lib/c_api/include/taichi/taichi_cuda.h +36 -0
  57. taichi/_lib/c_api/include/taichi/taichi_platform.h +55 -0
  58. taichi/_lib/c_api/include/taichi/taichi_unity.h +64 -0
  59. taichi/_lib/c_api/include/taichi/taichi_vulkan.h +151 -0
  60. taichi/_lib/c_api/lib/taichi_c_api.lib +0 -0
  61. taichi/_lib/c_api/runtime/runtime_cuda.bc +0 -0
  62. taichi/_lib/c_api/runtime/runtime_x64.bc +0 -0
  63. taichi/_lib/c_api/runtime/slim_libdevice.10.bc +0 -0
  64. taichi/_lib/c_api/taichi/lib/cmake/taichi/TaichiConfig.cmake +29 -0
  65. taichi/_lib/c_api/taichi/lib/cmake/taichi/TaichiConfigVersion.cmake +65 -0
  66. taichi/_lib/c_api/taichi/lib/cmake/taichi/TaichiTargets.cmake +121 -0
  67. taichi/_lib/core/__init__.py +0 -0
  68. taichi/_lib/core/py.typed +0 -0
  69. taichi/_lib/core/taichi_python.cp310-win_amd64.pyd +0 -0
  70. taichi/_lib/core/taichi_python.pyi +3077 -0
  71. taichi/_lib/runtime/runtime_cuda.bc +0 -0
  72. taichi/_lib/runtime/runtime_x64.bc +0 -0
  73. taichi/_lib/runtime/slim_libdevice.10.bc +0 -0
  74. taichi/_lib/utils.py +249 -0
  75. taichi/_logging.py +131 -0
  76. taichi/_main.py +552 -0
  77. taichi/_snode/__init__.py +5 -0
  78. taichi/_snode/fields_builder.py +189 -0
  79. taichi/_snode/snode_tree.py +34 -0
  80. taichi/_ti_module/__init__.py +3 -0
  81. taichi/_ti_module/cppgen.py +309 -0
  82. taichi/_ti_module/module.py +145 -0
  83. taichi/_version.py +1 -0
  84. taichi/_version_check.py +100 -0
  85. taichi/ad/__init__.py +3 -0
  86. taichi/ad/_ad.py +530 -0
  87. taichi/algorithms/__init__.py +3 -0
  88. taichi/algorithms/_algorithms.py +117 -0
  89. taichi/aot/__init__.py +12 -0
  90. taichi/aot/_export.py +28 -0
  91. taichi/aot/conventions/__init__.py +3 -0
  92. taichi/aot/conventions/gfxruntime140/__init__.py +38 -0
  93. taichi/aot/conventions/gfxruntime140/dr.py +244 -0
  94. taichi/aot/conventions/gfxruntime140/sr.py +613 -0
  95. taichi/aot/module.py +253 -0
  96. taichi/aot/utils.py +151 -0
  97. taichi/assets/.git +1 -0
  98. taichi/assets/Go-Regular.ttf +0 -0
  99. taichi/assets/static/imgs/ti_gallery.png +0 -0
  100. taichi/examples/minimal.py +28 -0
  101. taichi/experimental.py +16 -0
  102. taichi/graph/__init__.py +3 -0
  103. taichi/graph/_graph.py +292 -0
  104. taichi/lang/__init__.py +50 -0
  105. taichi/lang/_ndarray.py +348 -0
  106. taichi/lang/_ndrange.py +152 -0
  107. taichi/lang/_texture.py +172 -0
  108. taichi/lang/_wrap_inspect.py +189 -0
  109. taichi/lang/any_array.py +99 -0
  110. taichi/lang/argpack.py +411 -0
  111. taichi/lang/ast/__init__.py +5 -0
  112. taichi/lang/ast/ast_transformer.py +1806 -0
  113. taichi/lang/ast/ast_transformer_utils.py +328 -0
  114. taichi/lang/ast/checkers.py +106 -0
  115. taichi/lang/ast/symbol_resolver.py +57 -0
  116. taichi/lang/ast/transform.py +9 -0
  117. taichi/lang/common_ops.py +310 -0
  118. taichi/lang/exception.py +80 -0
  119. taichi/lang/expr.py +180 -0
  120. taichi/lang/field.py +464 -0
  121. taichi/lang/impl.py +1246 -0
  122. taichi/lang/kernel_arguments.py +157 -0
  123. taichi/lang/kernel_impl.py +1415 -0
  124. taichi/lang/matrix.py +1877 -0
  125. taichi/lang/matrix_ops.py +341 -0
  126. taichi/lang/matrix_ops_utils.py +190 -0
  127. taichi/lang/mesh.py +687 -0
  128. taichi/lang/misc.py +807 -0
  129. taichi/lang/ops.py +1489 -0
  130. taichi/lang/runtime_ops.py +13 -0
  131. taichi/lang/shell.py +35 -0
  132. taichi/lang/simt/__init__.py +5 -0
  133. taichi/lang/simt/block.py +94 -0
  134. taichi/lang/simt/grid.py +7 -0
  135. taichi/lang/simt/subgroup.py +191 -0
  136. taichi/lang/simt/warp.py +96 -0
  137. taichi/lang/snode.py +487 -0
  138. taichi/lang/source_builder.py +150 -0
  139. taichi/lang/struct.py +855 -0
  140. taichi/lang/util.py +381 -0
  141. taichi/linalg/__init__.py +8 -0
  142. taichi/linalg/matrixfree_cg.py +310 -0
  143. taichi/linalg/sparse_cg.py +59 -0
  144. taichi/linalg/sparse_matrix.py +303 -0
  145. taichi/linalg/sparse_solver.py +123 -0
  146. taichi/math/__init__.py +11 -0
  147. taichi/math/_complex.py +204 -0
  148. taichi/math/mathimpl.py +886 -0
  149. taichi/profiler/__init__.py +6 -0
  150. taichi/profiler/kernel_metrics.py +260 -0
  151. taichi/profiler/kernel_profiler.py +592 -0
  152. taichi/profiler/memory_profiler.py +15 -0
  153. taichi/profiler/scoped_profiler.py +36 -0
  154. taichi/shaders/Circles_vk.frag +29 -0
  155. taichi/shaders/Circles_vk.vert +45 -0
  156. taichi/shaders/Circles_vk_frag.spv +0 -0
  157. taichi/shaders/Circles_vk_vert.spv +0 -0
  158. taichi/shaders/Lines_vk.frag +9 -0
  159. taichi/shaders/Lines_vk.vert +11 -0
  160. taichi/shaders/Lines_vk_frag.spv +0 -0
  161. taichi/shaders/Lines_vk_vert.spv +0 -0
  162. taichi/shaders/Mesh_vk.frag +71 -0
  163. taichi/shaders/Mesh_vk.vert +68 -0
  164. taichi/shaders/Mesh_vk_frag.spv +0 -0
  165. taichi/shaders/Mesh_vk_vert.spv +0 -0
  166. taichi/shaders/Particles_vk.frag +95 -0
  167. taichi/shaders/Particles_vk.vert +73 -0
  168. taichi/shaders/Particles_vk_frag.spv +0 -0
  169. taichi/shaders/Particles_vk_vert.spv +0 -0
  170. taichi/shaders/SceneLines2quad_vk_comp.spv +0 -0
  171. taichi/shaders/SceneLines_vk.frag +9 -0
  172. taichi/shaders/SceneLines_vk.vert +12 -0
  173. taichi/shaders/SceneLines_vk_frag.spv +0 -0
  174. taichi/shaders/SceneLines_vk_vert.spv +0 -0
  175. taichi/shaders/SetImage_vk.frag +21 -0
  176. taichi/shaders/SetImage_vk.vert +15 -0
  177. taichi/shaders/SetImage_vk_frag.spv +0 -0
  178. taichi/shaders/SetImage_vk_vert.spv +0 -0
  179. taichi/shaders/Triangles_vk.frag +16 -0
  180. taichi/shaders/Triangles_vk.vert +29 -0
  181. taichi/shaders/Triangles_vk_frag.spv +0 -0
  182. taichi/shaders/Triangles_vk_vert.spv +0 -0
  183. taichi/shaders/lines2quad_vk_comp.spv +0 -0
  184. taichi/sparse/__init__.py +3 -0
  185. taichi/sparse/_sparse_grid.py +77 -0
  186. taichi/tools/__init__.py +12 -0
  187. taichi/tools/diagnose.py +124 -0
  188. taichi/tools/np2ply.py +364 -0
  189. taichi/tools/vtk.py +38 -0
  190. taichi/types/__init__.py +19 -0
  191. taichi/types/annotations.py +47 -0
  192. taichi/types/compound_types.py +90 -0
  193. taichi/types/enums.py +49 -0
  194. taichi/types/ndarray_type.py +147 -0
  195. taichi/types/primitive_types.py +203 -0
  196. taichi/types/quant.py +88 -0
  197. taichi/types/texture_type.py +85 -0
  198. taichi/types/utils.py +13 -0
@@ -0,0 +1,189 @@
1
+ # type: ignore
2
+
3
+ from typing import Any, Optional, Sequence, Union
4
+
5
+ from taichi._lib import core as _ti_core
6
+ from taichi._lib.core.taichi_python import SNode as SNodeCxx
7
+ from taichi._snode.snode_tree import SNodeTree
8
+ from taichi.lang import impl, snode
9
+ from taichi.lang.exception import TaichiRuntimeError
10
+ from taichi.lang.util import warning
11
+
12
+ _snode_registry = _ti_core.SNodeRegistry()
13
+
14
+ _Axis = _ti_core.Axis
15
+
16
+
17
+ class FieldsBuilder:
18
+ """A builder that constructs a SNodeTree instance.
19
+
20
+ Example::
21
+
22
+ x = ti.field(ti.i32)
23
+ y = ti.field(ti.f32)
24
+ fb = ti.FieldsBuilder()
25
+ fb.dense(ti.ij, 8).place(x)
26
+ fb.pointer(ti.ij, 8).dense(ti.ij, 4).place(y)
27
+
28
+ # After this line, `x` and `y` are placed. No more fields can be placed
29
+ # into `fb`.
30
+ #
31
+ # The tree looks like the following:
32
+ # (implicit root)
33
+ # |
34
+ # +-- dense +-- place(x)
35
+ # |
36
+ # +-- pointer +-- dense +-- place(y)
37
+ fb.finalize()
38
+ """
39
+
40
+ def __init__(self):
41
+ self.ptr: SNodeCxx = _snode_registry.create_root(impl.get_runtime().prog)
42
+ self.root = snode.SNode(self.ptr)
43
+ self.finalized = False
44
+ self.empty = True
45
+ impl.get_runtime().initialize_fields_builder(self)
46
+
47
+ # TODO: move this into SNodeTree
48
+ @classmethod
49
+ def _finalized_roots(cls):
50
+ """Gets all the roots of the finalized SNodeTree.
51
+
52
+ Returns:
53
+ A list of the roots of the finalized SNodeTree.
54
+ """
55
+ roots_ptr = []
56
+ size = impl.get_runtime().prog.get_snode_tree_size()
57
+ for i in range(size):
58
+ res = impl.get_runtime().prog.get_snode_root(i)
59
+ roots_ptr.append(snode.SNode(res))
60
+ return roots_ptr
61
+
62
+ # TODO: move this to SNodeTree class.
63
+ def deactivate_all(self):
64
+ """Same as :func:`taichi.lang.snode.SNode.deactivate_all`"""
65
+ if self.finalized:
66
+ self.root.deactivate_all()
67
+ else:
68
+ warning("""'deactivate_all()' would do nothing if FieldsBuilder is not finalized""")
69
+
70
+ def dense(
71
+ self,
72
+ indices: Union[Sequence[_Axis], _Axis],
73
+ dimensions: Union[Sequence[int], int],
74
+ ):
75
+ """Same as :func:`taichi.lang.snode.SNode.dense`"""
76
+ self._check_not_finalized()
77
+ self.empty = False
78
+ return self.root.dense(indices, dimensions)
79
+
80
+ def pointer(
81
+ self,
82
+ indices: Union[Sequence[_Axis], _Axis],
83
+ dimensions: Union[Sequence[int], int],
84
+ ):
85
+ """Same as :func:`taichi.lang.snode.SNode.pointer`"""
86
+ if not _ti_core.is_extension_supported(impl.current_cfg().arch, _ti_core.Extension.sparse):
87
+ raise TaichiRuntimeError("Pointer SNode is not supported on this backend.")
88
+ self._check_not_finalized()
89
+ self.empty = False
90
+ return self.root.pointer(indices, dimensions)
91
+
92
+ def _hash(self, indices, dimensions):
93
+ """Same as :func:`taichi.lang.snode.SNode.hash`"""
94
+ raise NotImplementedError()
95
+
96
+ def dynamic(
97
+ self,
98
+ index: Union[Sequence[_Axis], _Axis],
99
+ dimension: Union[Sequence[int], int],
100
+ chunk_size: Optional[int] = None,
101
+ ):
102
+ """Same as :func:`taichi.lang.snode.SNode.dynamic`"""
103
+ if not _ti_core.is_extension_supported(impl.current_cfg().arch, _ti_core.Extension.sparse):
104
+ raise TaichiRuntimeError("Dynamic SNode is not supported on this backend.")
105
+
106
+ if dimension >= 2**31:
107
+ raise TaichiRuntimeError(
108
+ f"The maximum dimension of a dynamic SNode cannot exceed the maximum value of a 32-bit signed integer: Got {dimension} > 2**31-1"
109
+ )
110
+ if chunk_size is not None and chunk_size >= 2**31:
111
+ raise TaichiRuntimeError(
112
+ f"Chunk size cannot exceed the maximum value of a 32-bit signed integer: Got {chunk_size} > 2**31-1"
113
+ )
114
+
115
+ self._check_not_finalized()
116
+ self.empty = False
117
+ return self.root.dynamic(index, dimension, chunk_size)
118
+
119
+ def bitmasked(
120
+ self,
121
+ indices: Union[Sequence[_Axis], _Axis],
122
+ dimensions: Union[Sequence[int], int],
123
+ ):
124
+ """Same as :func:`taichi.lang.snode.SNode.bitmasked`"""
125
+ if not _ti_core.is_extension_supported(impl.current_cfg().arch, _ti_core.Extension.sparse):
126
+ raise TaichiRuntimeError("Bitmasked SNode is not supported on this backend.")
127
+ self._check_not_finalized()
128
+ self.empty = False
129
+ return self.root.bitmasked(indices, dimensions)
130
+
131
+ def quant_array(
132
+ self,
133
+ indices: Union[Sequence[_Axis], _Axis],
134
+ dimensions: Union[Sequence[int], int],
135
+ max_num_bits: int,
136
+ ):
137
+ """Same as :func:`taichi.lang.snode.SNode.quant_array`"""
138
+ self._check_not_finalized()
139
+ self.empty = False
140
+ return self.root.quant_array(indices, dimensions, max_num_bits)
141
+
142
+ def place(self, *args: Any, offset: Optional[Union[Sequence[int], int]] = None):
143
+ """Same as :func:`taichi.lang.snode.SNode.place`"""
144
+ self._check_not_finalized()
145
+ self.empty = False
146
+ self.root.place(*args, offset=offset)
147
+
148
+ def lazy_grad(self):
149
+ """Same as :func:`taichi.lang.snode.SNode.lazy_grad`"""
150
+ # TODO: This complicates the implementation. Figure out why we need this
151
+ self._check_not_finalized()
152
+ self.empty = False
153
+ self.root.lazy_grad()
154
+
155
+ def _allocate_adjoint_checkbit(self):
156
+ """Same as :func:`taichi.lang.snode.SNode._allocate_adjoint_checkbit`"""
157
+ self._check_not_finalized()
158
+ self.empty = False
159
+ self.root._allocate_adjoint_checkbit()
160
+
161
+ def lazy_dual(self):
162
+ """Same as :func:`taichi.lang.snode.SNode.lazy_dual`"""
163
+ # TODO: This complicates the implementation. Figure out why we need this
164
+ self._check_not_finalized()
165
+ self.empty = False
166
+ self.root.lazy_dual()
167
+
168
+ def finalize(self, raise_warning=True):
169
+ """Constructs the SNodeTree and finalizes this builder.
170
+
171
+ Args:
172
+ raise_warning (bool): Raise warning or not."""
173
+ return self._finalize(raise_warning, compile_only=False)
174
+
175
+ def _finalize_for_aot(self):
176
+ """Constructs the SNodeTree and compiles the type for AOT purpose."""
177
+ return self._finalize(raise_warning=False, compile_only=True)
178
+
179
+ def _finalize(self, raise_warning, compile_only):
180
+ self._check_not_finalized()
181
+ if self.empty and raise_warning:
182
+ warning("Finalizing an empty FieldsBuilder!")
183
+ self.finalized = True
184
+ impl.get_runtime().finalize_fields_builder(self)
185
+ return SNodeTree(_ti_core.finalize_snode_tree(_snode_registry, self.ptr, impl.get_runtime().prog, compile_only))
186
+
187
+ def _check_not_finalized(self):
188
+ if self.finalized:
189
+ raise TaichiRuntimeError("FieldsBuilder finalized")
@@ -0,0 +1,34 @@
1
+ # type: ignore
2
+
3
+ # The reason we import just the taichi.core.util module, instead of the ti_python_core
4
+ # object within it, is that ti_python_core is stateful. While in practice ti_python_core is
5
+ # loaded during the import procedure, it's probably still good to delay the
6
+ # access to it.
7
+
8
+ from taichi.lang import impl
9
+ from taichi.lang.exception import TaichiRuntimeError
10
+
11
+
12
+ class SNodeTree:
13
+ def __init__(self, ptr):
14
+ self.prog = impl.get_runtime().prog
15
+ self.ptr = ptr
16
+ self.destroyed = False
17
+
18
+ def destroy(self):
19
+ if self.destroyed:
20
+ raise TaichiRuntimeError("SNode tree has been destroyed")
21
+ if self.prog != impl.get_runtime().prog:
22
+ return
23
+ self.ptr.destroy_snode_tree(impl.get_runtime().prog)
24
+
25
+ # FieldExpression holds a SNode* to the place-SNode associated with a SNodeTree
26
+ # Therefore, we have to recompile all the kernels after destroying a SNodeTree
27
+ impl.get_runtime().clear_compiled_functions()
28
+ self.destroyed = True
29
+
30
+ @property
31
+ def id(self):
32
+ if self.destroyed:
33
+ raise TaichiRuntimeError("SNode tree has been destroyed")
34
+ return self.ptr.id()
@@ -0,0 +1,3 @@
1
+ # type: ignore
2
+
3
+ from taichi._ti_module.module import _main
@@ -0,0 +1,309 @@
1
+ # type: ignore
2
+
3
+ from typing import Any, List, Optional, Set
4
+
5
+ from taichi.aot.conventions.gfxruntime140 import GfxRuntime140, sr
6
+
7
+ dtype2ctype = {
8
+ sr.DataType.f16: "half_t",
9
+ sr.DataType.f32: "float",
10
+ sr.DataType.f64: "double",
11
+ sr.DataType.i8: "int8_t",
12
+ sr.DataType.i16: "int16_t",
13
+ sr.DataType.i32: "int32_t",
14
+ sr.DataType.i64: "int64_t",
15
+ sr.DataType.u8: "uint8_t",
16
+ sr.DataType.u16: "uint16_t",
17
+ sr.DataType.u32: "uint32_t",
18
+ sr.DataType.u64: "uint64_t",
19
+ }
20
+
21
+
22
+ def check_arg(actual: str, expect: Any) -> List[str]:
23
+ out = []
24
+
25
+ expect = str(expect)
26
+ out += [
27
+ f" if (value.{actual} != {expect}) {{",
28
+ f' ti_set_last_error(TI_ERROR_INVALID_ARGUMENT, "value.{actual} != {expect}");',
29
+ " return *this;",
30
+ " }",
31
+ ]
32
+
33
+ return out
34
+
35
+
36
+ def get_arg_dst(i: int, is_named: bool) -> str:
37
+ if is_named:
38
+ return f"args_[{i}].argument"
39
+ return f"args_[{i}]"
40
+
41
+
42
+ def generate_scalar_assign(cls_name: str, i: int, arg_name: str, arg: sr.ArgumentScalar, is_named: bool) -> List[str]:
43
+ ctype = dtype2ctype[arg.dtype]
44
+
45
+ out = []
46
+
47
+ out += [
48
+ f" {cls_name} &set_{arg_name}({ctype} value) {{",
49
+ ]
50
+
51
+ if is_named:
52
+ out += [
53
+ f' args_[{i}].name = "{arg_name}";',
54
+ ]
55
+ if ctype == "float":
56
+ out += [
57
+ f" {get_arg_dst(i, is_named)}.type = TI_ARGUMENT_TYPE_F32;",
58
+ f" {get_arg_dst(i, is_named)}.value.f32 = value;",
59
+ ]
60
+ elif ctype == "int32_t":
61
+ out += [
62
+ f" {get_arg_dst(i, is_named)}.type = TI_ARGUMENT_TYPE_I32;",
63
+ f" {get_arg_dst(i, is_named)}.value.i32 = value;",
64
+ ]
65
+ else:
66
+ out += [
67
+ f" {get_arg_dst(i, is_named)}.type = TI_ARGUMENT_TYPE_SCALAR;",
68
+ f" {get_arg_dst(i, is_named)}.value.scalar.type = TI_DATA_TYPE_{arg.dtype.name.upper()};",
69
+ f" *(({ctype}*)(&{get_arg_dst(i, is_named)}.value.scalar.value)) = value;",
70
+ ]
71
+ assert False, f"{ctype} is not a supported scalar type."
72
+
73
+ out += [
74
+ " return *this;",
75
+ " }",
76
+ ]
77
+ return out
78
+
79
+
80
+ def generate_ndarray_assign(cls_name: str, i: int, arg_name: str, arg: sr.ArgumentNdArray, is_named: bool) -> List[str]:
81
+ out = []
82
+
83
+ out += [
84
+ f" {cls_name} &set_{arg_name}(const TiNdArray &value) {{",
85
+ ]
86
+
87
+ out += check_arg("elem_type", f"TI_DATA_TYPE_{arg.dtype.name.upper()}")
88
+ out += check_arg("shape.dim_count", arg.ndim)
89
+ assert len(arg.element_shape) <= 16
90
+ out += check_arg("elem_shape.dim_count", len(arg.element_shape))
91
+ for j, dim in enumerate(arg.element_shape):
92
+ out += check_arg(f"elem_shape.dims[{j}]", dim)
93
+
94
+ if is_named:
95
+ out += [
96
+ f' args_[{i}].name = "{arg_name}";',
97
+ ]
98
+ out += [
99
+ f" {get_arg_dst(i, is_named)}.type = TI_ARGUMENT_TYPE_NDARRAY;",
100
+ f" {get_arg_dst(i, is_named)}.value.ndarray = value;",
101
+ " return *this;",
102
+ " }",
103
+ ]
104
+ return out
105
+
106
+
107
+ def generate_texture_assign(
108
+ cls_name: str,
109
+ i: int,
110
+ arg_name: str,
111
+ arg: sr.ArgumentTexture | sr.ArgumentRwTexture,
112
+ is_named: bool,
113
+ ) -> List[str]:
114
+ out = []
115
+
116
+ out += [
117
+ f" {cls_name} &set_{arg_name}(const TiTexture &value) {{",
118
+ ]
119
+
120
+ assert arg.ndim in [1, 2, 3]
121
+ out += check_arg("dimension", f"TI_IMAGE_DIMENSION_{arg.ndim}D")
122
+ if isinstance(arg, sr.ArgumentRwTexture):
123
+ out += check_arg("format", f"TI_FORMAT_{arg.fmt.name.upper()}")
124
+
125
+ if is_named:
126
+ out += [
127
+ f' args_[{i}].name = "{arg_name}";',
128
+ ]
129
+ out += [
130
+ f" {get_arg_dst(i, is_named)}.type = TI_ARGUMENT_TYPE_TEXTURE;",
131
+ f" {get_arg_dst(i, is_named)}.value.texture = value;",
132
+ " return *this;",
133
+ " }",
134
+ ]
135
+ return out
136
+
137
+
138
+ def generate_kernel_args_builder(kernel: sr.Kernel) -> List[str]:
139
+ out = []
140
+
141
+ out += [
142
+ f"struct Kernel_{kernel.name} : public ti::Kernel {{",
143
+ f" explicit Kernel_{kernel.name}(TiRuntime runtime, TiKernel kernel) :",
144
+ " ti::Kernel(runtime, kernel) {",
145
+ f" args_.resize({len(kernel.context.args)});",
146
+ " }",
147
+ "",
148
+ ]
149
+
150
+ cls_name = f"Kernel_{kernel.name}"
151
+ for i, arg in enumerate(kernel.context.args):
152
+ arg_name = arg.name if arg.name else f"arg{i}"
153
+ if isinstance(arg, sr.ArgumentScalar):
154
+ out += generate_scalar_assign(cls_name, i, arg_name, arg, False)
155
+ elif isinstance(arg, sr.ArgumentNdArray):
156
+ out += generate_ndarray_assign(cls_name, i, arg_name, arg, False)
157
+ elif isinstance(arg, (sr.ArgumentTexture, sr.ArgumentRwTexture)):
158
+ out += generate_texture_assign(cls_name, i, arg_name, arg, False)
159
+ else:
160
+ assert False
161
+ out += [""]
162
+
163
+ out += [
164
+ "};",
165
+ "",
166
+ ]
167
+ return out
168
+
169
+
170
+ def generate_graph_args_builder(graph: sr.Graph) -> List[str]:
171
+ out = []
172
+
173
+ out += [
174
+ f"struct ComputeGraph_{graph.name} : public ti::ComputeGraph {{",
175
+ f" explicit ComputeGraph_{graph.name}(TiRuntime runtime, TiComputeGraph graph) :",
176
+ " ti::ComputeGraph(runtime, graph) {",
177
+ f" args_.resize({len(graph.args)});",
178
+ " }",
179
+ "",
180
+ ]
181
+
182
+ cls_name = f"ComputeGraph_{graph.name}"
183
+ for i, arg in enumerate(graph.args):
184
+ arg_name = arg.name
185
+ if isinstance(arg.arg, sr.ArgumentScalar):
186
+ out += generate_scalar_assign(cls_name, i, arg_name, arg.arg, True)
187
+ elif isinstance(arg.arg, sr.ArgumentNdArray):
188
+ out += generate_ndarray_assign(cls_name, i, arg_name, arg.arg, True)
189
+ elif isinstance(arg.arg, (sr.ArgumentTexture, sr.ArgumentRwTexture)):
190
+ out += generate_texture_assign(cls_name, i, arg_name, arg.arg, True)
191
+ else:
192
+ assert False
193
+ out += [""]
194
+
195
+ out += [
196
+ "};",
197
+ "",
198
+ ]
199
+ return out
200
+
201
+
202
+ def generate_module_content_repr(m: GfxRuntime140, module_name: str, cgraph_kernel_names: Set[str]) -> List[str]:
203
+ out = []
204
+
205
+ if module_name:
206
+ module_name = f"AotModule_{module_name}"
207
+ else:
208
+ module_name = "AotModule"
209
+
210
+ out += [
211
+ f"struct {module_name} : public ti::AotModule {{",
212
+ f" explicit {module_name}(TiRuntime runtime, TiAotModule aot_module, bool should_destroy = true) :",
213
+ " ti::AotModule(runtime, aot_module, should_destroy) {}",
214
+ "",
215
+ f" static {module_name} load(TiRuntime runtime, const char *path) {{",
216
+ " TiAotModule aot_module = ti_load_aot_module(runtime, path);",
217
+ f" return {module_name}(runtime, aot_module, true);",
218
+ " }",
219
+ f" static {module_name} load(TiRuntime runtime, const std::string &path) {{",
220
+ f" return {module_name}::load(runtime, path.c_str());",
221
+ " }",
222
+ f" static {module_name} create(TiRuntime runtime, const void *tcm, size_t size) {{",
223
+ " TiAotModule aot_module = ti_create_aot_module(runtime, tcm, size);",
224
+ f" return {module_name}(runtime, aot_module, true);",
225
+ " }",
226
+ f" static {module_name} create(TiRuntime runtime, const std::vector<uint8_t> &tcm) {{",
227
+ f" return {module_name}::create(runtime, tcm.data(), tcm.size());",
228
+ " }",
229
+ "",
230
+ ]
231
+ for kernel in m.metadata.kernels.values():
232
+ if kernel.name in cgraph_kernel_names:
233
+ continue
234
+ out += [
235
+ f" Kernel_{kernel.name} get_kernel_{kernel.name}() const {{",
236
+ f' return Kernel_{kernel.name}(runtime_, ti_get_aot_module_kernel(aot_module(), "{kernel.name}"));',
237
+ " }",
238
+ ]
239
+ for graph in m.graphs:
240
+ out += [
241
+ f" ComputeGraph_{graph.name} get_compute_graph_{graph.name}() const {{",
242
+ f' return ComputeGraph_{graph.name}(runtime_, ti_get_aot_module_compute_graph(aot_module(), "{graph.name}"));',
243
+ " }",
244
+ ]
245
+ out += [
246
+ "};",
247
+ "",
248
+ ]
249
+ return out
250
+
251
+
252
+ def generate_module_content(m: GfxRuntime140, module_name: str) -> List[str]:
253
+ # This has all kernels including all the ones launched by compute graphs.
254
+ cgraph_kernel_names = set(dispatch.kernel.name for graph in m.graphs for dispatch in graph.dispatches)
255
+
256
+ out = []
257
+ for kernel in m.metadata.kernels.values():
258
+ if kernel.name in cgraph_kernel_names:
259
+ continue
260
+ out += generate_kernel_args_builder(kernel)
261
+
262
+ for graph in m.graphs:
263
+ out += generate_graph_args_builder(graph)
264
+
265
+ out += generate_module_content_repr(m, module_name, cgraph_kernel_names)
266
+
267
+ return out
268
+
269
+
270
+ def generate_header(m: GfxRuntime140, module_name: str, namespace: str, tcm: Optional[bytes]) -> List[str]:
271
+ out = []
272
+
273
+ out += [
274
+ "// THIS IS A GENERATED HEADER; PLEASE DO NOT MODIFY.",
275
+ "#pragma once",
276
+ "#include <vector>",
277
+ "#include <string>",
278
+ "#include <taichi/cpp/taichi.hpp>",
279
+ "",
280
+ ]
281
+
282
+ if namespace:
283
+ out += [
284
+ f"namespace {namespace} {{",
285
+ "",
286
+ ]
287
+
288
+ if tcm is not None:
289
+ tcm_bytes = [x for x in tcm]
290
+
291
+ out += [
292
+ f"static const uint8_t {module_name}_tcm[{len(tcm_bytes)}] = {{",
293
+ ]
294
+
295
+ out += [f" {', '.join(str(x) for x in tcm_bytes[i:i + 8])}," for i in range(0, len(tcm_bytes), 8)]
296
+
297
+ out += [
298
+ "};",
299
+ "",
300
+ f"static const size_t {module_name}_tcm_size = {len(tcm_bytes)};",
301
+ "",
302
+ ]
303
+
304
+ out += generate_module_content(m, module_name)
305
+
306
+ if namespace:
307
+ out += [f"}} // namespace {namespace}", ""]
308
+
309
+ return out
@@ -0,0 +1,145 @@
1
+ # type: ignore
2
+
3
+ import argparse
4
+ import runpy
5
+ from pathlib import Path
6
+ from typing import List
7
+
8
+ import taichi
9
+ from taichi._ti_module.cppgen import generate_header
10
+ from taichi.aot._export import _aot_kernels
11
+ from taichi.aot.conventions.gfxruntime140 import GfxRuntime140
12
+ from taichi.aot.module import Module
13
+ from taichi.types.ndarray_type import NdarrayType
14
+ from taichi.types.primitive_types import integer_type_ids, real_type_ids
15
+ from taichi.types.texture_type import RWTextureType, TextureType
16
+
17
+
18
+ def module_cppgen(parser: argparse.ArgumentParser):
19
+ """Generate C++ headers for Taichi modules."""
20
+ parser.add_argument("MODOLE", help="Path to the module directory.")
21
+ parser.add_argument("-n", "--namespace", type=str, help="C++ namespace if wanted.")
22
+ parser.add_argument(
23
+ "-m",
24
+ "--module-name",
25
+ type=str,
26
+ help="Module name to be a part of the module class. By default, it's the directory name.",
27
+ default=None,
28
+ )
29
+ parser.add_argument("-o", "--output", type=str, help="Output C++ header path.", default="module.h")
30
+ parser.add_argument(
31
+ "--bin2c",
32
+ help="Save the entire TCM archive to an in-memory buffer. This flag is ignored if the module is not a TCM archive",
33
+ action="store_true",
34
+ )
35
+ parser.set_defaults(func=module_cppgen_impl)
36
+
37
+
38
+ def module_cppgen_impl(a):
39
+ module_path = a.MODOLE
40
+
41
+ print(f"Generating C++ header for Taichi module: {Path(module_path).absolute()}")
42
+
43
+ tcm = None
44
+ if a.bin2c and module_path.endswith(".tcm"):
45
+ with open(module_path, "rb") as f:
46
+ tcm = f.read()
47
+
48
+ if a.module_name:
49
+ module_name = a.module_name
50
+ else:
51
+ module_name = Path(module_path).name
52
+ if module_name.endswith(".tcm"):
53
+ module_name = module_name[:-4]
54
+
55
+ m = GfxRuntime140.from_module(module_path)
56
+
57
+ out = generate_header(m, module_name, a.namespace, tcm)
58
+
59
+ with open(a.output, "w") as f:
60
+ f.write("\n".join(out))
61
+
62
+ print(f"Module header is saved to: {Path(a.output).absolute()}")
63
+
64
+
65
+ def module_build(parser: argparse.ArgumentParser):
66
+ """Build Taichi modules from python scripts."""
67
+ parser.add_argument("SOURCE", help="Path to the Taichi program source (Python script).")
68
+ parser.add_argument("-o", "--output", type=str, help="Output module path.", default=None)
69
+ parser.set_defaults(func=module_build_impl)
70
+
71
+
72
+ def module_build_impl(a):
73
+ source_path = a.SOURCE
74
+ module_path = a.output
75
+
76
+ source_path = Path(source_path)
77
+ assert source_path.name.endswith(".py"), "Source must be a Python script."
78
+ if module_path is None:
79
+ module_path = f"{source_path.name[:-3]}.tcm"
80
+ module_path = Path(module_path)
81
+
82
+ print(f"Building Taichi module: {source_path}")
83
+ print()
84
+
85
+ d = runpy.run_path(str(source_path), run_name="__main__")
86
+ print()
87
+
88
+ required_caps = d["REQUIRED_CAPS"] if "REQUIRED_CAPS" in d else []
89
+ assert isinstance(required_caps, list), "REQUIRED_CAPS must be a list."
90
+
91
+ if required_caps:
92
+ print("Module requires the following capabilities:")
93
+ for cap in required_caps:
94
+ print(f" - {cap}")
95
+ print()
96
+
97
+ m = Module(caps=required_caps)
98
+ for record in _aot_kernels:
99
+ print("Added kernel:", record.name)
100
+ template_args = None
101
+ if record.template_types:
102
+ print(" Template types:")
103
+ template_args = {}
104
+ for k, v in record.template_types.items():
105
+ print(f" - {k}: {v}")
106
+ # TODO: (penguinliong) Remove this hack. It's not properly
107
+ # working with unusual numeric types like f16 or i64.
108
+ if isinstance(v, int) or id(v) in integer_type_ids:
109
+ value = 0
110
+ elif isinstance(v, float) or id(v) in real_type_ids:
111
+ value = 0.0
112
+ elif isinstance(v, NdarrayType):
113
+ if v.ndim is None or v.ndim <= 0:
114
+ raise ValueError("Ndarray template type must specify a non-zero dimension.")
115
+ value = taichi.ndarray(v.dtype, (1,) * v.ndim)
116
+ elif isinstance(v, TextureType):
117
+ value = taichi.Texture(taichi.Format.rgba8, (4,) * v.num_dimensions)
118
+ elif isinstance(v, RWTextureType):
119
+ value = taichi.Texture(v.fmt, (4,) * v.num_dimensions)
120
+ else:
121
+ raise ValueError(f"Unsupported template type: {type(v)}")
122
+ template_args[k] = value
123
+ m.add_kernel(record.kernel, template_args)
124
+ print()
125
+
126
+ if module_path.name.endswith(".tcm"):
127
+ m.archive(str(module_path))
128
+ else:
129
+ m.save(str(module_path))
130
+
131
+ print(f"Module is archive to: {module_path}")
132
+ print()
133
+
134
+
135
+ def _main(arguments: List[str]):
136
+ """Taichi module tools."""
137
+ parser = argparse.ArgumentParser(prog="ti module", description=_main.__doc__)
138
+ subparsers = parser.add_subparsers(title="Taichi module manager commands", required=True)
139
+
140
+ cppgen_parser = subparsers.add_parser("cppgen", help=module_cppgen.__doc__)
141
+ build_parser = subparsers.add_parser("build", help=module_build.__doc__)
142
+ module_cppgen(cppgen_parser)
143
+ module_build(build_parser)
144
+ args = parser.parse_args(arguments)
145
+ args.func(args)
taichi/_version.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = '0.1.18.dev1'