tack-core 0.7.0__tar.gz

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 (245) hide show
  1. tack_core-0.7.0/.gitignore +25 -0
  2. tack_core-0.7.0/LICENSE +29 -0
  3. tack_core-0.7.0/PKG-INFO +116 -0
  4. tack_core-0.7.0/README.md +70 -0
  5. tack_core-0.7.0/examples/01_hello_tack.py +57 -0
  6. tack_core-0.7.0/examples/02_math_builtins.py +54 -0
  7. tack_core-0.7.0/examples/03_scalar_args.py +56 -0
  8. tack_core-0.7.0/examples/04_control_flow.py +102 -0
  9. tack_core-0.7.0/examples/05_ndindex.py +78 -0
  10. tack_core-0.7.0/examples/06_device_functions.py +78 -0
  11. tack_core-0.7.0/examples/07_atomics.py +91 -0
  12. tack_core-0.7.0/examples/08_reductions.py +45 -0
  13. tack_core-0.7.0/examples/09_shared_memory.py +97 -0
  14. tack_core-0.7.0/examples/10_vectors.py +129 -0
  15. tack_core-0.7.0/examples/11_templates.py +94 -0
  16. tack_core-0.7.0/examples/12_mandelbrot.py +90 -0
  17. tack_core-0.7.0/examples/13_nbody.py +105 -0
  18. tack_core-0.7.0/examples/14_jacobi_solver.py +91 -0
  19. tack_core-0.7.0/examples/15_matmul.py +68 -0
  20. tack_core-0.7.0/examples/16_game_of_life.py +122 -0
  21. tack_core-0.7.0/examples/17_heat_equation.py +114 -0
  22. tack_core-0.7.0/examples/18_wave_equation.py +104 -0
  23. tack_core-0.7.0/examples/19_image_processing.py +163 -0
  24. tack_core-0.7.0/examples/20_multi_backend.py +111 -0
  25. tack_core-0.7.0/examples/21_array_abstraction.py +187 -0
  26. tack_core-0.7.0/examples/23_tuple_arrays.py +349 -0
  27. tack_core-0.7.0/examples/24_point_coordinates.py +386 -0
  28. tack_core-0.7.0/examples/29_volume_render.py +532 -0
  29. tack_core-0.7.0/examples/30_scalar_packing.py +79 -0
  30. tack_core-0.7.0/examples/31_dawn_interop.py +203 -0
  31. tack_core-0.7.0/examples/40_statistics.py +147 -0
  32. tack_core-0.7.0/examples/41_inspect.py +71 -0
  33. tack_core-0.7.0/examples/validate_all.py +457 -0
  34. tack_core-0.7.0/pyproject.toml +86 -0
  35. tack_core-0.7.0/src/tack/__init__.py +294 -0
  36. tack_core-0.7.0/src/tack/algorithms/__init__.py +60 -0
  37. tack_core-0.7.0/src/tack/algorithms/copy.py +49 -0
  38. tack_core-0.7.0/src/tack/algorithms/scan.py +292 -0
  39. tack_core-0.7.0/src/tack/algorithms/segmented.py +612 -0
  40. tack_core-0.7.0/src/tack/algorithms/sort.py +626 -0
  41. tack_core-0.7.0/src/tack/algorithms/stats.py +282 -0
  42. tack_core-0.7.0/src/tack/arrays.py +820 -0
  43. tack_core-0.7.0/src/tack/cache.py +90 -0
  44. tack_core-0.7.0/src/tack/codegen/__init__.py +2 -0
  45. tack_core-0.7.0/src/tack/codegen/atomics.py +40 -0
  46. tack_core-0.7.0/src/tack/codegen/bounds.py +63 -0
  47. tack_core-0.7.0/src/tack/codegen/c_family.py +219 -0
  48. tack_core-0.7.0/src/tack/codegen/cuda_gen.py +767 -0
  49. tack_core-0.7.0/src/tack/codegen/float_division.py +66 -0
  50. tack_core-0.7.0/src/tack/codegen/hip_gen.py +55 -0
  51. tack_core-0.7.0/src/tack/codegen/identifiers.py +58 -0
  52. tack_core-0.7.0/src/tack/codegen/integer_division.py +47 -0
  53. tack_core-0.7.0/src/tack/codegen/integer_ops.py +138 -0
  54. tack_core-0.7.0/src/tack/codegen/llvm_gen.py +1516 -0
  55. tack_core-0.7.0/src/tack/codegen/msl_gen.py +746 -0
  56. tack_core-0.7.0/src/tack/codegen/opencl_gen.py +579 -0
  57. tack_core-0.7.0/src/tack/codegen/reductions.py +109 -0
  58. tack_core-0.7.0/src/tack/codegen/tables.py +53 -0
  59. tack_core-0.7.0/src/tack/codegen/warp_gen.py +761 -0
  60. tack_core-0.7.0/src/tack/communication/__init__.py +43 -0
  61. tack_core-0.7.0/src/tack/communication/_blocks.py +207 -0
  62. tack_core-0.7.0/src/tack/communication/_kernels.py +83 -0
  63. tack_core-0.7.0/src/tack/communication/_plan.py +136 -0
  64. tack_core-0.7.0/src/tack/communication/_route.py +186 -0
  65. tack_core-0.7.0/src/tack/communication/_sort.py +170 -0
  66. tack_core-0.7.0/src/tack/communication/_world.py +165 -0
  67. tack_core-0.7.0/src/tack/lang/__init__.py +2 -0
  68. tack_core-0.7.0/src/tack/lang/array.py +1338 -0
  69. tack_core-0.7.0/src/tack/lang/ast_copy.py +35 -0
  70. tack_core-0.7.0/src/tack/lang/ast_transform.py +1147 -0
  71. tack_core-0.7.0/src/tack/lang/atomic_support.py +85 -0
  72. tack_core-0.7.0/src/tack/lang/call_bindings.py +102 -0
  73. tack_core-0.7.0/src/tack/lang/constant.py +227 -0
  74. tack_core-0.7.0/src/tack/lang/device_class.py +32 -0
  75. tack_core-0.7.0/src/tack/lang/dlpack.py +651 -0
  76. tack_core-0.7.0/src/tack/lang/func.py +114 -0
  77. tack_core-0.7.0/src/tack/lang/inspect_kernel.py +228 -0
  78. tack_core-0.7.0/src/tack/lang/ir.py +530 -0
  79. tack_core-0.7.0/src/tack/lang/ir_bounds.py +154 -0
  80. tack_core-0.7.0/src/tack/lang/ir_names.py +47 -0
  81. tack_core-0.7.0/src/tack/lang/ir_optimize.py +224 -0
  82. tack_core-0.7.0/src/tack/lang/ir_pack_scalars.py +105 -0
  83. tack_core-0.7.0/src/tack/lang/ir_resolve.py +149 -0
  84. tack_core-0.7.0/src/tack/lang/ir_traversal.py +189 -0
  85. tack_core-0.7.0/src/tack/lang/ir_type_annotate.py +514 -0
  86. tack_core-0.7.0/src/tack/lang/ir_verify.py +280 -0
  87. tack_core-0.7.0/src/tack/lang/kernel.py +379 -0
  88. tack_core-0.7.0/src/tack/lang/lowering/__init__.py +25 -0
  89. tack_core-0.7.0/src/tack/lang/lowering/arrays.py +299 -0
  90. tack_core-0.7.0/src/tack/lang/lowering/bounds.py +107 -0
  91. tack_core-0.7.0/src/tack/lang/lowering/checks.py +190 -0
  92. tack_core-0.7.0/src/tack/lang/lowering/inlining.py +344 -0
  93. tack_core-0.7.0/src/tack/lang/lowering/local_arrays.py +135 -0
  94. tack_core-0.7.0/src/tack/lang/lowering/loops.py +387 -0
  95. tack_core-0.7.0/src/tack/lang/lowering/values.py +86 -0
  96. tack_core-0.7.0/src/tack/lang/lowering/vectors.py +664 -0
  97. tack_core-0.7.0/src/tack/lang/parallel_dims.py +90 -0
  98. tack_core-0.7.0/src/tack/lang/source_validation.py +185 -0
  99. tack_core-0.7.0/src/tack/lang/template_rewrite.py +1176 -0
  100. tack_core-0.7.0/src/tack/lang/type_inference.py +144 -0
  101. tack_core-0.7.0/src/tack/lang/types.py +249 -0
  102. tack_core-0.7.0/src/tack/lang/workgroup_participation.py +208 -0
  103. tack_core-0.7.0/src/tack/lang/workgroup_support.py +51 -0
  104. tack_core-0.7.0/src/tack/math.py +93 -0
  105. tack_core-0.7.0/src/tack/py.typed +0 -0
  106. tack_core-0.7.0/src/tack/random.py +137 -0
  107. tack_core-0.7.0/src/tack/runtime/__init__.py +2 -0
  108. tack_core-0.7.0/src/tack/runtime/aio.py +115 -0
  109. tack_core-0.7.0/src/tack/runtime/backend.py +287 -0
  110. tack_core-0.7.0/src/tack/runtime/buffer_cache.py +90 -0
  111. tack_core-0.7.0/src/tack/runtime/cpu.py +2329 -0
  112. tack_core-0.7.0/src/tack/runtime/cpu_pool.py +804 -0
  113. tack_core-0.7.0/src/tack/runtime/cuda_backend.py +1411 -0
  114. tack_core-0.7.0/src/tack/runtime/debug_bounds.py +122 -0
  115. tack_core-0.7.0/src/tack/runtime/device_fill.py +68 -0
  116. tack_core-0.7.0/src/tack/runtime/disk_cache.py +1001 -0
  117. tack_core-0.7.0/src/tack/runtime/dispatch.py +454 -0
  118. tack_core-0.7.0/src/tack/runtime/gpu_backend.py +184 -0
  119. tack_core-0.7.0/src/tack/runtime/hip_backend.py +1163 -0
  120. tack_core-0.7.0/src/tack/runtime/kernel_utils.py +1518 -0
  121. tack_core-0.7.0/src/tack/runtime/level_zero_backend.py +1997 -0
  122. tack_core-0.7.0/src/tack/runtime/metal.py +890 -0
  123. tack_core-0.7.0/src/tack/runtime/nvrtc_version.py +28 -0
  124. tack_core-0.7.0/src/tack/runtime/reductions.py +38 -0
  125. tack_core-0.7.0/src/tack/runtime/warp_backend.py +266 -0
  126. tack_core-0.7.0/tests/_communication_cases.py +246 -0
  127. tack_core-0.7.0/tests/_communication_mpi.py +78 -0
  128. tack_core-0.7.0/tests/_warp_default.py +43 -0
  129. tack_core-0.7.0/tests/compiler_tools.py +164 -0
  130. tack_core-0.7.0/tests/test_array_api.py +258 -0
  131. tack_core-0.7.0/tests/test_array_constructors.py +267 -0
  132. tack_core-0.7.0/tests/test_array_shape.py +346 -0
  133. tack_core-0.7.0/tests/test_array_updates_in_loops.py +254 -0
  134. tack_core-0.7.0/tests/test_array_utils.py +532 -0
  135. tack_core-0.7.0/tests/test_arrays_protocol.py +260 -0
  136. tack_core-0.7.0/tests/test_ast_transform.py +519 -0
  137. tack_core-0.7.0/tests/test_asyncio.py +338 -0
  138. tack_core-0.7.0/tests/test_atomic_contract.py +485 -0
  139. tack_core-0.7.0/tests/test_atomic_results.py +124 -0
  140. tack_core-0.7.0/tests/test_backend_contract.py +296 -0
  141. tack_core-0.7.0/tests/test_backend_isolation.py +96 -0
  142. tack_core-0.7.0/tests/test_block_reduce.py +86 -0
  143. tack_core-0.7.0/tests/test_buffer_cache.py +57 -0
  144. tack_core-0.7.0/tests/test_cleanup.py +276 -0
  145. tack_core-0.7.0/tests/test_communication.py +428 -0
  146. tack_core-0.7.0/tests/test_compiler_contract.py +478 -0
  147. tack_core-0.7.0/tests/test_compiler_tools.py +210 -0
  148. tack_core-0.7.0/tests/test_concurrent_dispatch.py +459 -0
  149. tack_core-0.7.0/tests/test_constant.py +280 -0
  150. tack_core-0.7.0/tests/test_constant_tables.py +195 -0
  151. tack_core-0.7.0/tests/test_cpu_fill.py +228 -0
  152. tack_core-0.7.0/tests/test_cpu_jit.py +388 -0
  153. tack_core-0.7.0/tests/test_cpu_pool.py +441 -0
  154. tack_core-0.7.0/tests/test_cpu_threading.py +1718 -0
  155. tack_core-0.7.0/tests/test_cuda.py +729 -0
  156. tack_core-0.7.0/tests/test_cuda_async.py +265 -0
  157. tack_core-0.7.0/tests/test_cuda_gen.py +288 -0
  158. tack_core-0.7.0/tests/test_debug_bounds.py +417 -0
  159. tack_core-0.7.0/tests/test_default_float.py +107 -0
  160. tack_core-0.7.0/tests/test_devices.py +378 -0
  161. tack_core-0.7.0/tests/test_differential.py +272 -0
  162. tack_core-0.7.0/tests/test_disjoint_fields.py +284 -0
  163. tack_core-0.7.0/tests/test_disk_cache.py +767 -0
  164. tack_core-0.7.0/tests/test_dispatch_fast_path.py +236 -0
  165. tack_core-0.7.0/tests/test_dispatch_signature_property.py +221 -0
  166. tack_core-0.7.0/tests/test_dispatch_types.py +156 -0
  167. tack_core-0.7.0/tests/test_division_and_power.py +342 -0
  168. tack_core-0.7.0/tests/test_dlpack.py +652 -0
  169. tack_core-0.7.0/tests/test_error_messages.py +212 -0
  170. tack_core-0.7.0/tests/test_error_reporting.py +74 -0
  171. tack_core-0.7.0/tests/test_examples.py +99 -0
  172. tack_core-0.7.0/tests/test_explicit_casts.py +223 -0
  173. tack_core-0.7.0/tests/test_f64_refused.py +106 -0
  174. tack_core-0.7.0/tests/test_float_division.py +326 -0
  175. tack_core-0.7.0/tests/test_float_literals.py +359 -0
  176. tack_core-0.7.0/tests/test_float_semantics.py +502 -0
  177. tack_core-0.7.0/tests/test_func_bindings.py +270 -0
  178. tack_core-0.7.0/tests/test_gpu_dispatch_paths.py +399 -0
  179. tack_core-0.7.0/tests/test_gpu_identifiers.py +336 -0
  180. tack_core-0.7.0/tests/test_hip.py +668 -0
  181. tack_core-0.7.0/tests/test_hip_async.py +338 -0
  182. tack_core-0.7.0/tests/test_hip_gen.py +171 -0
  183. tack_core-0.7.0/tests/test_indexable.py +318 -0
  184. tack_core-0.7.0/tests/test_inspect.py +166 -0
  185. tack_core-0.7.0/tests/test_integer_division.py +214 -0
  186. tack_core-0.7.0/tests/test_integer_expression_differential.py +571 -0
  187. tack_core-0.7.0/tests/test_integer_semantics.py +465 -0
  188. tack_core-0.7.0/tests/test_ir_clone.py +171 -0
  189. tack_core-0.7.0/tests/test_ir_optimize.py +148 -0
  190. tack_core-0.7.0/tests/test_ir_traversal.py +139 -0
  191. tack_core-0.7.0/tests/test_ir_verify.py +335 -0
  192. tack_core-0.7.0/tests/test_kernel_cache.py +108 -0
  193. tack_core-0.7.0/tests/test_kernel_results.py +117 -0
  194. tack_core-0.7.0/tests/test_launch_limits.py +93 -0
  195. tack_core-0.7.0/tests/test_level_zero_async.py +354 -0
  196. tack_core-0.7.0/tests/test_level_zero_buffers.py +61 -0
  197. tack_core-0.7.0/tests/test_level_zero_context.py +102 -0
  198. tack_core-0.7.0/tests/test_llvm_gen.py +242 -0
  199. tack_core-0.7.0/tests/test_local_array.py +251 -0
  200. tack_core-0.7.0/tests/test_local_var_types.py +140 -0
  201. tack_core-0.7.0/tests/test_math_helpers.py +78 -0
  202. tack_core-0.7.0/tests/test_matrix.py +319 -0
  203. tack_core-0.7.0/tests/test_metal.py +519 -0
  204. tack_core-0.7.0/tests/test_msl_gen.py +264 -0
  205. tack_core-0.7.0/tests/test_multi_device.py +294 -0
  206. tack_core-0.7.0/tests/test_multi_device_switching.py +689 -0
  207. tack_core-0.7.0/tests/test_nested_templates.py +227 -0
  208. tack_core-0.7.0/tests/test_new_features.py +1780 -0
  209. tack_core-0.7.0/tests/test_numa.py +395 -0
  210. tack_core-0.7.0/tests/test_nvrtc_version.py +17 -0
  211. tack_core-0.7.0/tests/test_opencl_compilation.py +388 -0
  212. tack_core-0.7.0/tests/test_opencl_gen.py +657 -0
  213. tack_core-0.7.0/tests/test_out_of_memory.py +91 -0
  214. tack_core-0.7.0/tests/test_outside_parallel_loop.py +210 -0
  215. tack_core-0.7.0/tests/test_package_surface.py +65 -0
  216. tack_core-0.7.0/tests/test_parallel_dims.py +367 -0
  217. tack_core-0.7.0/tests/test_promotion_and_safety.py +165 -0
  218. tack_core-0.7.0/tests/test_random.py +74 -0
  219. tack_core-0.7.0/tests/test_reduction_semantics.py +347 -0
  220. tack_core-0.7.0/tests/test_scalar_matching.py +159 -0
  221. tack_core-0.7.0/tests/test_scalar_packing.py +105 -0
  222. tack_core-0.7.0/tests/test_segmented.py +188 -0
  223. tack_core-0.7.0/tests/test_shared_like.py +139 -0
  224. tack_core-0.7.0/tests/test_small_int_types.py +225 -0
  225. tack_core-0.7.0/tests/test_soa.py +408 -0
  226. tack_core-0.7.0/tests/test_sort.py +378 -0
  227. tack_core-0.7.0/tests/test_source_validation.py +395 -0
  228. tack_core-0.7.0/tests/test_stats.py +345 -0
  229. tack_core-0.7.0/tests/test_template_iteration.py +193 -0
  230. tack_core-0.7.0/tests/test_templates.py +607 -0
  231. tack_core-0.7.0/tests/test_texture_inline.py +113 -0
  232. tack_core-0.7.0/tests/test_texture_snapshot.py +150 -0
  233. tack_core-0.7.0/tests/test_threading_benchmark.py +273 -0
  234. tack_core-0.7.0/tests/test_type_annotate.py +117 -0
  235. tack_core-0.7.0/tests/test_type_annotate_expr.py +530 -0
  236. tack_core-0.7.0/tests/test_type_inference.py +60 -0
  237. tack_core-0.7.0/tests/test_validation_harness.py +190 -0
  238. tack_core-0.7.0/tests/test_value_constructors.py +102 -0
  239. tack_core-0.7.0/tests/test_variable_length_loop.py +153 -0
  240. tack_core-0.7.0/tests/test_variant_cache.py +367 -0
  241. tack_core-0.7.0/tests/test_vector_add.py +46 -0
  242. tack_core-0.7.0/tests/test_vector_comparisons.py +154 -0
  243. tack_core-0.7.0/tests/test_warp.py +459 -0
  244. tack_core-0.7.0/tests/test_workgroup_contract.py +193 -0
  245. tack_core-0.7.0/tests/test_workgroup_participation.py +446 -0
@@ -0,0 +1,25 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Generated images and example output
13
+ results/
14
+ *.npy
15
+ *.vtu
16
+
17
+ # Claude Code local config
18
+ .claude/
19
+
20
+ # Test artifacts
21
+ .coverage
22
+ .pytest_cache/
23
+
24
+ # MkDocs build output
25
+ site/
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Kitware, Inc.
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.5
2
+ Name: tack-core
3
+ Version: 0.7.0
4
+ Summary: Tack — GPU compute framework (core)
5
+ Project-URL: Homepage, https://github.com/Kitware/tack
6
+ Project-URL: Repository, https://github.com/Kitware/tack
7
+ Project-URL: Documentation, https://kitware.github.io/tack/
8
+ Project-URL: Issues, https://github.com/Kitware/tack/issues
9
+ Author: Kitware, Inc.
10
+ License-Expression: BSD-3-Clause
11
+ License-File: LICENSE
12
+ Keywords: compute,cuda,gpu,hip,jit,kernel,metal,visualization
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: Software Development :: Compilers
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: numpy
23
+ Provides-Extra: all
24
+ Requires-Dist: cuda-python>=13.2.0; extra == 'all'
25
+ Requires-Dist: hip-python>=7.0; (sys_platform == 'linux' and platform_machine == 'x86_64') and extra == 'all'
26
+ Requires-Dist: llvmlite; extra == 'all'
27
+ Requires-Dist: pyobjc-framework-metal; extra == 'all'
28
+ Requires-Dist: pyobjc-framework-metalkit; extra == 'all'
29
+ Provides-Extra: cpu
30
+ Requires-Dist: llvmlite; extra == 'cpu'
31
+ Provides-Extra: cuda
32
+ Requires-Dist: cuda-python>=13.2.0; extra == 'cuda'
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest; extra == 'dev'
35
+ Provides-Extra: hip
36
+ Requires-Dist: hip-python>=7.0; (sys_platform == 'linux' and platform_machine == 'x86_64') and extra == 'hip'
37
+ Provides-Extra: level-zero
38
+ Provides-Extra: metal
39
+ Requires-Dist: pyobjc-framework-metal; extra == 'metal'
40
+ Requires-Dist: pyobjc-framework-metalkit; extra == 'metal'
41
+ Provides-Extra: mpi
42
+ Requires-Dist: mpi4py>=4.0; extra == 'mpi'
43
+ Provides-Extra: warp
44
+ Requires-Dist: warp-lang>=1.18; (sys_platform != 'darwin' or platform_machine == 'arm64') and extra == 'warp'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # tack-core
48
+
49
+ Kernels, arrays, types, IR, codegen and backends for [Tack](https://github.com/Kitware/tack) —
50
+ a Python-first GPU compute framework.
51
+
52
+ Write compute kernels as decorated Python functions; they are JIT-compiled at first call (and
53
+ kept in a disk cache, so a later process loads them instead) and dispatched to whichever backend
54
+ is active. The same kernel source runs on five backends, within
55
+ each backend's capabilities (for example, Metal has no `f64` and the CPU has no workgroup
56
+ primitives).
57
+
58
+ ```python
59
+ import tack, numpy as np
60
+ tack.set_default_device("cpu") # or metal, cuda, hip, level_zero
61
+
62
+ @tack.kernel
63
+ def vector_add(x, y, out):
64
+ for i in range(x.shape[0]): # outermost loop → thread parallelism
65
+ out[i] = x[i] + y[i]
66
+
67
+ x = tack.empty((1024,)) # f32 unless a dtype is given
68
+ y = tack.empty((1024,))
69
+ out = tack.empty((1024,))
70
+ tack.copyto(x, np.arange(1024, dtype=np.float32))
71
+ tack.copyto(y, np.ones(1024, dtype=np.float32))
72
+
73
+ vector_add(x, y, out)
74
+ print(out.numpy())
75
+ ```
76
+
77
+ ## Install
78
+
79
+ Pick the extras for your hardware. Keep `cpu` beside a GPU's extra: without it
80
+ the CPU, the default device, cannot run kernels.
81
+
82
+ ```bash
83
+ pip install "tack-core[cpu]" # LLVM JIT via llvmlite
84
+ pip install "tack-core[cpu,metal]" # Apple silicon
85
+ pip install "tack-core[cpu,cuda]" # NVIDIA
86
+ pip install "tack-core[cpu,hip]" # AMD, with ROCm (hip-python: Linux x86-64)
87
+ pip install "tack-core[cpu]" # Intel: Level Zero is the system's runtime, no extra
88
+ ```
89
+
90
+ Python 3.11 or newer. Tack is pure Python and compiles kernels when they are
91
+ first called.
92
+
93
+ ## Backends
94
+
95
+ | Backend | Codegen | Runtime compilation |
96
+ |---------|---------|---------------------|
97
+ | CPU | LLVM IR | llvmlite JIT |
98
+ | Metal | MSL | Metal API |
99
+ | CUDA | CUDA C | NVRTC → PTX |
100
+ | HIP | HIP C | hipRTC |
101
+ | Level Zero | OpenCL C | libocloc → SPIR-V |
102
+
103
+ ## Related packages
104
+
105
+ - `tack-vis`: `tack.dataset`, with meshes, fields and visualization algorithms,
106
+ and the VTK and MFEM interop. It is not on PyPI; install it from the
107
+ repository, at the tag of the `tack-core` release you have, for example:
108
+
109
+ ```bash
110
+ pip install "tack-vis @ git+https://github.com/Kitware/tack@v0.7.0#subdirectory=packages/tack-vis"
111
+ ```
112
+
113
+ Full documentation, examples and the kernel-language reference are in the
114
+ [repository](https://github.com/Kitware/tack).
115
+
116
+ BSD 3-Clause licensed.
@@ -0,0 +1,70 @@
1
+ # tack-core
2
+
3
+ Kernels, arrays, types, IR, codegen and backends for [Tack](https://github.com/Kitware/tack) —
4
+ a Python-first GPU compute framework.
5
+
6
+ Write compute kernels as decorated Python functions; they are JIT-compiled at first call (and
7
+ kept in a disk cache, so a later process loads them instead) and dispatched to whichever backend
8
+ is active. The same kernel source runs on five backends, within
9
+ each backend's capabilities (for example, Metal has no `f64` and the CPU has no workgroup
10
+ primitives).
11
+
12
+ ```python
13
+ import tack, numpy as np
14
+ tack.set_default_device("cpu") # or metal, cuda, hip, level_zero
15
+
16
+ @tack.kernel
17
+ def vector_add(x, y, out):
18
+ for i in range(x.shape[0]): # outermost loop → thread parallelism
19
+ out[i] = x[i] + y[i]
20
+
21
+ x = tack.empty((1024,)) # f32 unless a dtype is given
22
+ y = tack.empty((1024,))
23
+ out = tack.empty((1024,))
24
+ tack.copyto(x, np.arange(1024, dtype=np.float32))
25
+ tack.copyto(y, np.ones(1024, dtype=np.float32))
26
+
27
+ vector_add(x, y, out)
28
+ print(out.numpy())
29
+ ```
30
+
31
+ ## Install
32
+
33
+ Pick the extras for your hardware. Keep `cpu` beside a GPU's extra: without it
34
+ the CPU, the default device, cannot run kernels.
35
+
36
+ ```bash
37
+ pip install "tack-core[cpu]" # LLVM JIT via llvmlite
38
+ pip install "tack-core[cpu,metal]" # Apple silicon
39
+ pip install "tack-core[cpu,cuda]" # NVIDIA
40
+ pip install "tack-core[cpu,hip]" # AMD, with ROCm (hip-python: Linux x86-64)
41
+ pip install "tack-core[cpu]" # Intel: Level Zero is the system's runtime, no extra
42
+ ```
43
+
44
+ Python 3.11 or newer. Tack is pure Python and compiles kernels when they are
45
+ first called.
46
+
47
+ ## Backends
48
+
49
+ | Backend | Codegen | Runtime compilation |
50
+ |---------|---------|---------------------|
51
+ | CPU | LLVM IR | llvmlite JIT |
52
+ | Metal | MSL | Metal API |
53
+ | CUDA | CUDA C | NVRTC → PTX |
54
+ | HIP | HIP C | hipRTC |
55
+ | Level Zero | OpenCL C | libocloc → SPIR-V |
56
+
57
+ ## Related packages
58
+
59
+ - `tack-vis`: `tack.dataset`, with meshes, fields and visualization algorithms,
60
+ and the VTK and MFEM interop. It is not on PyPI; install it from the
61
+ repository, at the tag of the `tack-core` release you have, for example:
62
+
63
+ ```bash
64
+ pip install "tack-vis @ git+https://github.com/Kitware/tack@v0.7.0#subdirectory=packages/tack-vis"
65
+ ```
66
+
67
+ Full documentation, examples and the kernel-language reference are in the
68
+ [repository](https://github.com/Kitware/tack).
69
+
70
+ BSD 3-Clause licensed.
@@ -0,0 +1,57 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """01 -- Hello Tack: your first kernel.
5
+
6
+ This is the simplest possible Tack program. It creates two arrays,
7
+ adds them element-wise on the GPU (or CPU), and checks the result.
8
+
9
+ Key concepts:
10
+ - tack.set_default_device() -- choose a device (cpu, metal, cuda, hip)
11
+ - tack.empty() -- allocate a device array
12
+ - @tack.kernel -- mark a function for GPU compilation
13
+ - from_numpy / to_numpy -- move data between host and device
14
+
15
+ Usage:
16
+ uv run python examples/01_hello_tack.py
17
+ """
18
+
19
+ import argparse
20
+
21
+ import numpy as np
22
+
23
+ import tack
24
+
25
+ _parser = argparse.ArgumentParser()
26
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
27
+ _arch = _parser.parse_args().arch
28
+ tack.set_default_device(_arch)
29
+
30
+ # Allocate 1-D arrays (device arrays)
31
+ n = 10
32
+ x = tack.empty((n,))
33
+ y = tack.empty((n,))
34
+ out = tack.empty((n,))
35
+
36
+ # Upload data from numpy
37
+ tack.copyto(x, np.arange(n, dtype=np.float32)) # [0, 1, 2, ..., 9]
38
+ tack.copyto(y, np.ones(n, dtype=np.float32) * 10.0) # [10, 10, ..., 10]
39
+
40
+
41
+ @tack.kernel
42
+ def add(x, y, out):
43
+ # The top-level for-range is parallelized across threads
44
+ for i in range(x.shape[0]):
45
+ out[i] = x[i] + y[i]
46
+
47
+
48
+ # Run the kernel
49
+ add(x, y, out)
50
+
51
+ # Download result to numpy and print
52
+ result = out.numpy()
53
+ print("x =", x.numpy())
54
+ print("y =", y.numpy())
55
+ print("out=", result)
56
+ assert np.allclose(result, np.arange(n) + 10.0)
57
+ print("\nAll correct!")
@@ -0,0 +1,54 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """02 -- Math builtins available inside kernels.
5
+
6
+ Tack kernels have access to standard math functions without any imports.
7
+ They compile to hardware intrinsics (LLVM on CPU, device functions on GPU).
8
+
9
+ Available: sqrt, sin, cos, tan, asin, acos, atan, atan2,
10
+ exp, exp2, log, log2, log10, floor, ceil,
11
+ abs, min, max, pow
12
+
13
+ Usage:
14
+ uv run python examples/02_math_builtins.py
15
+ """
16
+
17
+ import argparse
18
+
19
+ import numpy as np
20
+
21
+ import tack
22
+
23
+ _parser = argparse.ArgumentParser()
24
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
25
+ _arch = _parser.parse_args().arch
26
+ tack.set_default_device(_arch)
27
+
28
+ n = 256
29
+ x = tack.empty((n,))
30
+ out_sqrt = tack.empty((n,))
31
+ out_sin = tack.empty((n,))
32
+ out_combined = tack.empty((n,))
33
+
34
+ tack.copyto(x, np.linspace(0.1, 10.0, n, dtype=np.float32))
35
+
36
+
37
+ @tack.kernel
38
+ def apply_math(x, out_sqrt, out_sin, out_combined):
39
+ for i in range(x.shape[0]):
40
+ out_sqrt[i] = sqrt(x[i])
41
+ out_sin[i] = sin(x[i])
42
+ # Mix several builtins in one expression
43
+ out_combined[i] = exp(-x[i]) * cos(x[i] * 3.14159) + abs(log(x[i]))
44
+
45
+
46
+ apply_math(x, out_sqrt, out_sin, out_combined)
47
+
48
+ np_x = x.numpy()
49
+ print("sqrt error:", np.max(np.abs(out_sqrt.numpy() - np.sqrt(np_x))))
50
+ print("sin error:", np.max(np.abs(out_sin.numpy() - np.sin(np_x))))
51
+
52
+ expected = np.exp(-np_x) * np.cos(np_x * 3.14159) + np.abs(np.log(np_x))
53
+ print("combo error:", np.max(np.abs(out_combined.numpy() - expected)))
54
+ print("\nAll within float32 tolerance!")
@@ -0,0 +1,56 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """03 -- Scalar arguments: pass Python numbers directly to kernels.
5
+
6
+ Kernels can accept plain Python int/float values alongside arrays.
7
+ This is useful for passing constants like time steps, coefficients,
8
+ or array sizes without creating an array.
9
+
10
+ Usage:
11
+ uv run python examples/03_scalar_args.py
12
+ """
13
+
14
+ import argparse
15
+
16
+ import numpy as np
17
+
18
+ import tack
19
+
20
+ _parser = argparse.ArgumentParser()
21
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
22
+ _arch = _parser.parse_args().arch
23
+ tack.set_default_device(_arch)
24
+
25
+ n = 1000
26
+ x = tack.empty((n,))
27
+ y = tack.empty((n,))
28
+ out = tack.empty((n,))
29
+
30
+ tack.copyto(x, np.arange(n, dtype=np.float32))
31
+ tack.copyto(y, np.ones(n, dtype=np.float32) * 3.0)
32
+
33
+
34
+ @tack.kernel
35
+ def saxpy(x, y, out, alpha, n):
36
+ """out = alpha * x + y (SAXPY: Single-precision A*X Plus Y)"""
37
+ for i in range(n):
38
+ out[i] = alpha * x[i] + y[i]
39
+
40
+
41
+ # Pass scalar values directly -- no need to wrap in arrays
42
+ alpha = 2.5
43
+ saxpy(x, y, out, alpha, n)
44
+
45
+ result = out.numpy()
46
+ expected = alpha * np.arange(n, dtype=np.float32) + 3.0
47
+ assert np.allclose(result, expected)
48
+ print(f"SAXPY with alpha={alpha}: first 5 results = {result[:5]}")
49
+
50
+ # Call again with a different alpha -- same compiled kernel is reused
51
+ saxpy(x, y, out, -1.0, n)
52
+ result2 = out.numpy()
53
+ expected2 = -1.0 * np.arange(n, dtype=np.float32) + 3.0
54
+ assert np.allclose(result2, expected2)
55
+ print(f"SAXPY with alpha=-1.0: first 5 results = {result2[:5]}")
56
+ print("\nScalar arguments work correctly!")
@@ -0,0 +1,102 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """04 -- Control flow: if/else, while loops, break, ternary expressions.
5
+
6
+ Tack kernels support standard Python control flow. The top-level for-range
7
+ is parallelized; everything inside runs per-thread.
8
+
9
+ Usage:
10
+ uv run python examples/04_control_flow.py
11
+ """
12
+
13
+ import argparse
14
+
15
+ import numpy as np
16
+
17
+ import tack
18
+
19
+ _parser = argparse.ArgumentParser()
20
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
21
+ _arch = _parser.parse_args().arch
22
+ tack.set_default_device(_arch)
23
+
24
+ n = 256
25
+ x = tack.empty((n,))
26
+ out = tack.empty((n,))
27
+
28
+ data = np.arange(n, dtype=np.float32) - 128.0 # [-128, ..., 127]
29
+ tack.copyto(x, data)
30
+
31
+ # --- Example 1: if/else (ReLU activation) ---
32
+
33
+ @tack.kernel
34
+ def relu(x, out):
35
+ for i in range(x.shape[0]):
36
+ if x[i] > 0.0:
37
+ out[i] = x[i]
38
+ else:
39
+ out[i] = 0.0
40
+
41
+ relu(x, out)
42
+ assert np.allclose(out.numpy(), np.maximum(data, 0.0))
43
+ print("1. ReLU (if/else): OK")
44
+
45
+ # --- Example 2: while loop with early exit ---
46
+
47
+ @tack.kernel
48
+ def collatz_steps(x, out):
49
+ """Count Collatz steps until reaching 1."""
50
+ for i in range(x.shape[0]):
51
+ val = abs(x[i]) + 1.0 # ensure positive, > 0
52
+ steps = 0.0
53
+ while val > 1.0:
54
+ if val > 1000.0:
55
+ break # safety limit
56
+ n_int = int(val)
57
+ if n_int % 2 == 0:
58
+ val = val / 2.0
59
+ else:
60
+ val = val * 3.0 + 1.0
61
+ steps = steps + 1.0
62
+ out[i] = steps
63
+
64
+ collatz_steps(x, out)
65
+ print("2. Collatz steps (while + break): OK, first 5 steps =", out.numpy()[:5])
66
+
67
+ # --- Example 3: ternary expression ---
68
+
69
+ @tack.kernel
70
+ def clamp(x, out):
71
+ """Clamp values to [-50, 50] using ternary expressions."""
72
+ for i in range(x.shape[0]):
73
+ v = x[i]
74
+ v = v if v > -50.0 else -50.0
75
+ v = v if v < 50.0 else 50.0
76
+ out[i] = v
77
+
78
+ clamp(x, out)
79
+ expected = np.clip(data, -50.0, 50.0)
80
+ assert np.allclose(out.numpy(), expected)
81
+ print("3. Clamp (ternary): OK")
82
+
83
+ # --- Example 4: nested loops ---
84
+
85
+ n2 = 16
86
+ mat = tack.empty((n2 * n2,))
87
+
88
+ @tack.kernel
89
+ def fill_checkerboard(mat):
90
+ for i in range(16):
91
+ for j in range(16):
92
+ if (i + j) % 2 == 0:
93
+ mat[i * 16 + j] = 1.0
94
+ else:
95
+ mat[i * 16 + j] = 0.0
96
+
97
+ fill_checkerboard(mat)
98
+ board = mat.numpy().reshape(16, 16)
99
+ print("4. Checkerboard (nested loops): OK")
100
+ print(" Top-left 4x4:")
101
+ for row in board[:4]:
102
+ print(" ", " ".join(f"{v:.0f}" for v in row[:4]))
@@ -0,0 +1,78 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """05 -- Multi-dimensional parallel iteration with tack.ndindex.
5
+
6
+ Instead of computing linear indices manually, use tack.ndindex(w, h) to
7
+ iterate over a 2D grid in parallel. Each (i, j) pair maps to a separate
8
+ GPU thread.
9
+
10
+ Usage:
11
+ uv run python examples/05_ndindex.py
12
+ """
13
+
14
+ import argparse
15
+
16
+ import numpy as np
17
+
18
+ import tack
19
+
20
+ _parser = argparse.ArgumentParser()
21
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
22
+ _arch = _parser.parse_args().arch
23
+ tack.set_default_device(_arch)
24
+
25
+ width, height = 64, 64
26
+ pixels = tack.empty((width, height))
27
+
28
+
29
+ @tack.kernel
30
+ def distance_array(pixels):
31
+ """Compute distance from center for each pixel."""
32
+ for i, j in tack.ndindex(64, 64):
33
+ dx = float(i) - 32.0
34
+ dy = float(j) - 32.0
35
+ pixels[i, j] = sqrt(dx * dx + dy * dy)
36
+
37
+
38
+ distance_array(pixels)
39
+
40
+ result = pixels.numpy().reshape(64, 64)
41
+ # Check center is ~0, corners are ~45
42
+ assert result[32, 32] == 0.0
43
+ corner_dist = result[0, 0]
44
+ assert abs(corner_dist - np.sqrt(32**2 + 32**2)) < 0.01
45
+ print(f"Center distance: {result[32, 32]:.2f} (expected 0)")
46
+ print(f"Corner distance: {corner_dist:.2f} (expected {np.sqrt(32**2+32**2):.2f})")
47
+
48
+ # --- Example 2: 2D Gaussian blur (3x3 kernel) ---
49
+
50
+ src = tack.empty((64, 64))
51
+ dst = tack.empty((64, 64))
52
+
53
+ # Create a simple image: bright spot at center
54
+ img = np.zeros((64, 64), dtype=np.float32)
55
+ img[32, 32] = 100.0
56
+ tack.copyto(src, img)
57
+
58
+
59
+ @tack.kernel
60
+ def blur_3x3(src, dst):
61
+ """Simple 3x3 box blur, skipping borders."""
62
+ for i, j in tack.ndindex(64, 64):
63
+ if i > 0:
64
+ if i < 63:
65
+ if j > 0:
66
+ if j < 63:
67
+ s = 0.0
68
+ for di in range(-1, 2):
69
+ for dj in range(-1, 2):
70
+ s = s + src[i + di, j + dj]
71
+ dst[i, j] = s / 9.0
72
+
73
+
74
+ blur_3x3(src, dst)
75
+ blurred = dst.numpy().reshape(64, 64)
76
+ print(f"\nBlur: center pixel {blurred[32,32]:.2f} (was 100.00)")
77
+ print(f"Blur: neighbor {blurred[32,33]:.2f} (was 0.00)")
78
+ print("2D ndindex + stencil: OK")
@@ -0,0 +1,78 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2
+ # SPDX-License-Identifier: BSD-3-Clause
3
+
4
+ """06 -- Device functions with @tack.func.
5
+
6
+ Use @tack.func to define helper functions that are inlined into kernels
7
+ at compile time. This keeps kernels clean and lets you reuse logic.
8
+
9
+ Usage:
10
+ uv run python examples/06_device_functions.py
11
+ """
12
+
13
+ import argparse
14
+
15
+ import numpy as np
16
+
17
+ import tack
18
+
19
+ _parser = argparse.ArgumentParser()
20
+ _parser.add_argument('--arch', default='cpu', choices=['cpu', 'metal', 'cuda', 'hip', 'level_zero'])
21
+ _arch = _parser.parse_args().arch
22
+ tack.set_default_device(_arch)
23
+
24
+
25
+ # --- Device function: inlined wherever called ---
26
+
27
+ @tack.func
28
+ def lerp(a, b, t):
29
+ """Linear interpolation: a*(1-t) + b*t"""
30
+ return a + t * (b - a)
31
+
32
+
33
+ @tack.func
34
+ def smoothstep(edge0, edge1, x):
35
+ """Hermite smoothstep interpolation."""
36
+ t = (x - edge0) / (edge1 - edge0)
37
+ t = max(0.0, min(1.0, t))
38
+ return t * t * (3.0 - 2.0 * t)
39
+
40
+
41
+ @tack.func
42
+ def remap(value, in_lo, in_hi, out_lo, out_hi):
43
+ """Remap a value from one range to another."""
44
+ t = (value - in_lo) / (in_hi - in_lo)
45
+ return lerp(out_lo, out_hi, t) # device functions can call each other
46
+
47
+
48
+ # --- Kernel using device functions ---
49
+
50
+ n = 100
51
+ x = tack.empty((n,))
52
+ out_lerp = tack.empty((n,))
53
+ out_smooth = tack.empty((n,))
54
+ out_remap = tack.empty((n,))
55
+
56
+ tack.copyto(x, np.linspace(0.0, 1.0, n, dtype=np.float32))
57
+
58
+
59
+ @tack.kernel
60
+ def apply_all(x, out_lerp, out_smooth, out_remap):
61
+ for i in range(x.shape[0]):
62
+ t = x[i]
63
+ out_lerp[i] = lerp(0.0, 100.0, t)
64
+ out_smooth[i] = smoothstep(0.2, 0.8, t)
65
+ out_remap[i] = remap(t, 0.0, 1.0, -10.0, 10.0)
66
+
67
+
68
+ apply_all(x, out_lerp, out_smooth, out_remap)
69
+
70
+ print("lerp(0,100,t): ", out_lerp.numpy()[[0, 25, 50, 75, 99]])
71
+ print("smoothstep: ", out_smooth.numpy()[[0, 25, 50, 75, 99]])
72
+ print("remap(0,1,-10,10):", out_remap.numpy()[[0, 25, 50, 75, 99]])
73
+
74
+ # Verify lerp
75
+ assert np.allclose(out_lerp.numpy(), np.linspace(0, 100, n))
76
+ # Verify remap
77
+ assert np.allclose(out_remap.numpy(), np.linspace(-10, 10, n))
78
+ print("\nDevice functions: OK")