pygpgpu 0.1.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 (303) hide show
  1. pygpgpu-0.1.0/LICENSE +21 -0
  2. pygpgpu-0.1.0/MANIFEST.in +14 -0
  3. pygpgpu-0.1.0/PKG-INFO +425 -0
  4. pygpgpu-0.1.0/README.md +363 -0
  5. pygpgpu-0.1.0/README.zh-CN.md +356 -0
  6. pygpgpu-0.1.0/examples/01_basic_kernel.py +58 -0
  7. pygpgpu-0.1.0/examples/02_backend_device_selection.py +64 -0
  8. pygpgpu-0.1.0/examples/03_nd_loop_and_class_method.py +102 -0
  9. pygpgpu-0.1.0/examples/04_vector_types.py +67 -0
  10. pygpgpu-0.1.0/examples/05_gnp_zero_copy_and_atomics.py +112 -0
  11. pygpgpu-0.1.0/examples/06_handwritten_kernels.py +60 -0
  12. pygpgpu-0.1.0/examples/07_low_level_oop.py +67 -0
  13. pygpgpu-0.1.0/examples/08_compare_backends.py +78 -0
  14. pygpgpu-0.1.0/examples/09_reduction.py +160 -0
  15. pygpgpu-0.1.0/examples/README.md +64 -0
  16. pygpgpu-0.1.0/examples/README.zh-CN.md +51 -0
  17. pygpgpu-0.1.0/examples/vecadd.cl +37 -0
  18. pygpgpu-0.1.0/examples/vecadd_cuda.cu +11 -0
  19. pygpgpu-0.1.0/pygpgpu/__init__.py +113 -0
  20. pygpgpu-0.1.0/pygpgpu/constants.py +107 -0
  21. pygpgpu-0.1.0/pygpgpu/cparser/ShaderBuiltins.py +16874 -0
  22. pygpgpu-0.1.0/pygpgpu/cparser/__init__.py +4 -0
  23. pygpgpu-0.1.0/pygpgpu/cparser/cparser.py +1200 -0
  24. pygpgpu-0.1.0/pygpgpu/cparser/cpreprocessor.py +135 -0
  25. pygpgpu-0.1.0/pygpgpu/cparser/csyntaxtree.py +88 -0
  26. pygpgpu-0.1.0/pygpgpu/cparser/ctokens.py +319 -0
  27. pygpgpu-0.1.0/pygpgpu/cparser/generate_code.py +481 -0
  28. pygpgpu-0.1.0/pygpgpu/cparser/minifyc.py +311 -0
  29. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/__init__.py +6 -0
  30. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/evaluator.py +897 -0
  31. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/lextab.py +169 -0
  32. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/parser.py +491 -0
  33. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/parsetab.py +2757 -0
  34. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/pcmd.py +465 -0
  35. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/__init__.py +5 -0
  36. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/cpp.py +1050 -0
  37. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/ctokens.py +159 -0
  38. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/lex.py +1237 -0
  39. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/yacc.py +3751 -0
  40. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/ply/ygen.py +75 -0
  41. pygpgpu-0.1.0/pygpgpu/cparser/pcpp/preprocessor.py +1698 -0
  42. pygpgpu-0.1.0/pygpgpu/cparser/ts_parser.py +691 -0
  43. pygpgpu-0.1.0/pygpgpu/cuda/__init__.py +7 -0
  44. pygpgpu-0.1.0/pygpgpu/cuda/cuimport.py +201 -0
  45. pygpgpu-0.1.0/pygpgpu/cuda/driver/__init__.py +48 -0
  46. pygpgpu-0.1.0/pygpgpu/cuda/driver/cuda.py +187 -0
  47. pygpgpu-0.1.0/pygpgpu/cuda/driver/cuda.pyi +184 -0
  48. pygpgpu-0.1.0/pygpgpu/cuda/driver/cuinfo.py +725 -0
  49. pygpgpu-0.1.0/pygpgpu/cuda/driver/cutypes.py +364 -0
  50. pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtc.py +200 -0
  51. pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtc.pyi +54 -0
  52. pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtcinfo.py +125 -0
  53. pygpgpu-0.1.0/pygpgpu/cuda/driver/nvrtctypes.py +63 -0
  54. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/__init__.py +25 -0
  55. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/char3.py +15 -0
  56. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/char3.pyi +1230 -0
  57. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/double3.py +15 -0
  58. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/double3.pyi +1230 -0
  59. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/float3.py +15 -0
  60. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/float3.pyi +1230 -0
  61. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/int3.py +15 -0
  62. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/int3.pyi +1230 -0
  63. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long2.py +14 -0
  64. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long2.pyi +320 -0
  65. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long3.py +15 -0
  66. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long3.pyi +1229 -0
  67. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long4.py +16 -0
  68. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/long4.pyi +3650 -0
  69. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/short3.py +15 -0
  70. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/short3.pyi +1230 -0
  71. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uchar3.py +15 -0
  72. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uchar3.pyi +1230 -0
  73. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uint3.py +15 -0
  74. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/uint3.pyi +1230 -0
  75. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong2.py +14 -0
  76. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong2.pyi +320 -0
  77. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong3.py +15 -0
  78. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong3.pyi +1229 -0
  79. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong4.py +16 -0
  80. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ulong4.pyi +3650 -0
  81. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ushort3.py +15 -0
  82. pygpgpu-0.1.0/pygpgpu/cuda/driver/vec_types/ushort3.pyi +1227 -0
  83. pygpgpu-0.1.0/pygpgpu/cuda/oop/__init__.py +2 -0
  84. pygpgpu-0.1.0/pygpgpu/cuda/oop/buffer.py +73 -0
  85. pygpgpu-0.1.0/pygpgpu/cuda/oop/build_options.py +198 -0
  86. pygpgpu-0.1.0/pygpgpu/cuda/oop/context.py +210 -0
  87. pygpgpu-0.1.0/pygpgpu/cuda/oop/cuobject.py +137 -0
  88. pygpgpu-0.1.0/pygpgpu/cuda/oop/device.py +88 -0
  89. pygpgpu-0.1.0/pygpgpu/cuda/oop/device.pyi +733 -0
  90. pygpgpu-0.1.0/pygpgpu/cuda/oop/devices.py +92 -0
  91. pygpgpu-0.1.0/pygpgpu/cuda/oop/event.py +55 -0
  92. pygpgpu-0.1.0/pygpgpu/cuda/oop/kernel.py +423 -0
  93. pygpgpu-0.1.0/pygpgpu/cuda/oop/mem_object.py +151 -0
  94. pygpgpu-0.1.0/pygpgpu/cuda/oop/nvrtc_program.py +228 -0
  95. pygpgpu-0.1.0/pygpgpu/cuda/oop/program.py +135 -0
  96. pygpgpu-0.1.0/pygpgpu/cuda/oop/program_info.py +147 -0
  97. pygpgpu-0.1.0/pygpgpu/cuda/oop/program_parser.py +482 -0
  98. pygpgpu-0.1.0/pygpgpu/cuda/oop/stream.py +97 -0
  99. pygpgpu-0.1.0/pygpgpu/exceptions.py +5 -0
  100. pygpgpu-0.1.0/pygpgpu/hip/__init__.py +6 -0
  101. pygpgpu-0.1.0/pygpgpu/hip/driver/__init__.py +15 -0
  102. pygpgpu-0.1.0/pygpgpu/hip/driver/hip.py +129 -0
  103. pygpgpu-0.1.0/pygpgpu/hip/driver/hipinfo.py +138 -0
  104. pygpgpu-0.1.0/pygpgpu/hip/driver/hiptypes.py +28 -0
  105. pygpgpu-0.1.0/pygpgpu/hip/hipimport.py +179 -0
  106. pygpgpu-0.1.0/pygpgpu/hip/oop/__init__.py +8 -0
  107. pygpgpu-0.1.0/pygpgpu/hip/oop/buffer.py +73 -0
  108. pygpgpu-0.1.0/pygpgpu/hip/oop/build_options.py +21 -0
  109. pygpgpu-0.1.0/pygpgpu/hip/oop/context.py +57 -0
  110. pygpgpu-0.1.0/pygpgpu/hip/oop/device.py +82 -0
  111. pygpgpu-0.1.0/pygpgpu/hip/oop/devices.py +93 -0
  112. pygpgpu-0.1.0/pygpgpu/hip/oop/event.py +60 -0
  113. pygpgpu-0.1.0/pygpgpu/hip/oop/hip_compiler.py +209 -0
  114. pygpgpu-0.1.0/pygpgpu/hip/oop/hipobject.py +137 -0
  115. pygpgpu-0.1.0/pygpgpu/hip/oop/kernel.py +423 -0
  116. pygpgpu-0.1.0/pygpgpu/hip/oop/mem_object.py +148 -0
  117. pygpgpu-0.1.0/pygpgpu/hip/oop/program.py +142 -0
  118. pygpgpu-0.1.0/pygpgpu/hip/oop/program_info.py +147 -0
  119. pygpgpu-0.1.0/pygpgpu/hip/oop/program_parser.py +485 -0
  120. pygpgpu-0.1.0/pygpgpu/hip/oop/stream.py +98 -0
  121. pygpgpu-0.1.0/pygpgpu/kernel/__init__.py +14 -0
  122. pygpgpu-0.1.0/pygpgpu/kernel/builtins.py +125 -0
  123. pygpgpu-0.1.0/pygpgpu/kernel/decorator.py +594 -0
  124. pygpgpu-0.1.0/pygpgpu/kernel/translator.py +1846 -0
  125. pygpgpu-0.1.0/pygpgpu/numpy/__init__.py +9 -0
  126. pygpgpu-0.1.0/pygpgpu/numpy/array_creation.py +83 -0
  127. pygpgpu-0.1.0/pygpgpu/numpy/ndarray.py +287 -0
  128. pygpgpu-0.1.0/pygpgpu/opencl/__init__.py +27 -0
  129. pygpgpu-0.1.0/pygpgpu/opencl/climport.py +130 -0
  130. pygpgpu-0.1.0/pygpgpu/opencl/common.py +76 -0
  131. pygpgpu-0.1.0/pygpgpu/opencl/driver/__init__.py +120 -0
  132. pygpgpu-0.1.0/pygpgpu/opencl/driver/cl.py +196 -0
  133. pygpgpu-0.1.0/pygpgpu/opencl/driver/cl.pyi +197 -0
  134. pygpgpu-0.1.0/pygpgpu/opencl/driver/clinfo.py +1913 -0
  135. pygpgpu-0.1.0/pygpgpu/opencl/driver/cltypes.py +964 -0
  136. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/__init__.py +7 -0
  137. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image1d_array_t.py +25 -0
  138. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image1d_t.py +25 -0
  139. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image2d_array_t.py +25 -0
  140. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image2d_t.py +25 -0
  141. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/image3d_t.py +25 -0
  142. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/imagend_t.py +178 -0
  143. pygpgpu-0.1.0/pygpgpu/opencl/driver/image_types/sampler_t.py +42 -0
  144. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/__init__.py +29 -0
  145. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/char3.py +16 -0
  146. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/char3.pyi +1230 -0
  147. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/double3.py +16 -0
  148. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/double3.pyi +1230 -0
  149. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/float3.py +16 -0
  150. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/float3.pyi +1230 -0
  151. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/int3.py +16 -0
  152. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/int3.pyi +1230 -0
  153. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long16.py +28 -0
  154. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long16.pyi +192 -0
  155. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long2.py +14 -0
  156. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long2.pyi +320 -0
  157. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long3.py +16 -0
  158. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long3.pyi +1229 -0
  159. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long4.py +16 -0
  160. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long4.pyi +3650 -0
  161. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long8.py +20 -0
  162. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/long8.pyi +108 -0
  163. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/short3.py +16 -0
  164. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/short3.pyi +1230 -0
  165. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uchar3.py +16 -0
  166. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uchar3.pyi +1230 -0
  167. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uint3.py +16 -0
  168. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/uint3.pyi +1230 -0
  169. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong16.py +28 -0
  170. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong16.pyi +192 -0
  171. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong2.py +14 -0
  172. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong2.pyi +320 -0
  173. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong3.py +16 -0
  174. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong3.pyi +1229 -0
  175. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong4.py +16 -0
  176. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong4.pyi +3650 -0
  177. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong8.py +20 -0
  178. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ulong8.pyi +108 -0
  179. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ushort3.py +16 -0
  180. pygpgpu-0.1.0/pygpgpu/opencl/driver/vec_types/ushort3.pyi +1227 -0
  181. pygpgpu-0.1.0/pygpgpu/opencl/oop/__init__.py +18 -0
  182. pygpgpu-0.1.0/pygpgpu/opencl/oop/buffer.py +127 -0
  183. pygpgpu-0.1.0/pygpgpu/opencl/oop/build_options.py +117 -0
  184. pygpgpu-0.1.0/pygpgpu/opencl/oop/clobject.py +151 -0
  185. pygpgpu-0.1.0/pygpgpu/opencl/oop/command_queue.py +82 -0
  186. pygpgpu-0.1.0/pygpgpu/opencl/oop/command_queue.pyi +42 -0
  187. pygpgpu-0.1.0/pygpgpu/opencl/oop/context.py +312 -0
  188. pygpgpu-0.1.0/pygpgpu/opencl/oop/context.pyi +122 -0
  189. pygpgpu-0.1.0/pygpgpu/opencl/oop/device.py +63 -0
  190. pygpgpu-0.1.0/pygpgpu/opencl/oop/device.pyi +481 -0
  191. pygpgpu-0.1.0/pygpgpu/opencl/oop/event.py +213 -0
  192. pygpgpu-0.1.0/pygpgpu/opencl/oop/event.pyi +68 -0
  193. pygpgpu-0.1.0/pygpgpu/opencl/oop/image1d.py +100 -0
  194. pygpgpu-0.1.0/pygpgpu/opencl/oop/image1d_array.py +100 -0
  195. pygpgpu-0.1.0/pygpgpu/opencl/oop/image2d.py +101 -0
  196. pygpgpu-0.1.0/pygpgpu/opencl/oop/image2d_array.py +100 -0
  197. pygpgpu-0.1.0/pygpgpu/opencl/oop/image3d.py +100 -0
  198. pygpgpu-0.1.0/pygpgpu/opencl/oop/imagend.py +55 -0
  199. pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel.py +495 -0
  200. pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel.pyi +70 -0
  201. pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel_wrapper.py +90 -0
  202. pygpgpu-0.1.0/pygpgpu/opencl/oop/kernel_wrapper.pyi +45 -0
  203. pygpgpu-0.1.0/pygpgpu/opencl/oop/mem_object.py +147 -0
  204. pygpgpu-0.1.0/pygpgpu/opencl/oop/mem_object.pyi +104 -0
  205. pygpgpu-0.1.0/pygpgpu/opencl/oop/pipe.py +85 -0
  206. pygpgpu-0.1.0/pygpgpu/opencl/oop/platform.py +157 -0
  207. pygpgpu-0.1.0/pygpgpu/opencl/oop/platform.pyi +121 -0
  208. pygpgpu-0.1.0/pygpgpu/opencl/oop/platforms.py +88 -0
  209. pygpgpu-0.1.0/pygpgpu/opencl/oop/program.py +369 -0
  210. pygpgpu-0.1.0/pygpgpu/opencl/oop/program.pyi +111 -0
  211. pygpgpu-0.1.0/pygpgpu/opencl/oop/program_info.py +192 -0
  212. pygpgpu-0.1.0/pygpgpu/opencl/oop/program_parser.py +534 -0
  213. pygpgpu-0.1.0/pygpgpu/opencl/oop/program_wrapper.py +109 -0
  214. pygpgpu-0.1.0/pygpgpu/opencl/oop/sampler.py +83 -0
  215. pygpgpu-0.1.0/pygpgpu/opencl/oop/sampler.pyi +34 -0
  216. pygpgpu-0.1.0/pygpgpu/opencl/oop/svm_buffer.py +121 -0
  217. pygpgpu-0.1.0/pygpgpu/py.typed +0 -0
  218. pygpgpu-0.1.0/pygpgpu/utils.py +362 -0
  219. pygpgpu-0.1.0/pygpgpu/vec_types/__init__.py +51 -0
  220. pygpgpu-0.1.0/pygpgpu/vec_types/char16.py +28 -0
  221. pygpgpu-0.1.0/pygpgpu/vec_types/char16.pyi +192 -0
  222. pygpgpu-0.1.0/pygpgpu/vec_types/char2.py +14 -0
  223. pygpgpu-0.1.0/pygpgpu/vec_types/char2.pyi +320 -0
  224. pygpgpu-0.1.0/pygpgpu/vec_types/char4.py +16 -0
  225. pygpgpu-0.1.0/pygpgpu/vec_types/char4.pyi +3652 -0
  226. pygpgpu-0.1.0/pygpgpu/vec_types/char8.py +20 -0
  227. pygpgpu-0.1.0/pygpgpu/vec_types/char8.pyi +108 -0
  228. pygpgpu-0.1.0/pygpgpu/vec_types/double16.py +28 -0
  229. pygpgpu-0.1.0/pygpgpu/vec_types/double16.pyi +192 -0
  230. pygpgpu-0.1.0/pygpgpu/vec_types/double2.py +14 -0
  231. pygpgpu-0.1.0/pygpgpu/vec_types/double2.pyi +320 -0
  232. pygpgpu-0.1.0/pygpgpu/vec_types/double4.py +16 -0
  233. pygpgpu-0.1.0/pygpgpu/vec_types/double4.pyi +3652 -0
  234. pygpgpu-0.1.0/pygpgpu/vec_types/double8.py +20 -0
  235. pygpgpu-0.1.0/pygpgpu/vec_types/double8.pyi +108 -0
  236. pygpgpu-0.1.0/pygpgpu/vec_types/float16.py +28 -0
  237. pygpgpu-0.1.0/pygpgpu/vec_types/float16.pyi +192 -0
  238. pygpgpu-0.1.0/pygpgpu/vec_types/float2.py +15 -0
  239. pygpgpu-0.1.0/pygpgpu/vec_types/float2.pyi +320 -0
  240. pygpgpu-0.1.0/pygpgpu/vec_types/float4.py +16 -0
  241. pygpgpu-0.1.0/pygpgpu/vec_types/float4.pyi +3652 -0
  242. pygpgpu-0.1.0/pygpgpu/vec_types/float8.py +20 -0
  243. pygpgpu-0.1.0/pygpgpu/vec_types/float8.pyi +108 -0
  244. pygpgpu-0.1.0/pygpgpu/vec_types/funcs.py +316 -0
  245. pygpgpu-0.1.0/pygpgpu/vec_types/genVec.py +387 -0
  246. pygpgpu-0.1.0/pygpgpu/vec_types/genVec16.py +18 -0
  247. pygpgpu-0.1.0/pygpgpu/vec_types/genVec16.pyi.in +13 -0
  248. pygpgpu-0.1.0/pygpgpu/vec_types/genVec2.py +13 -0
  249. pygpgpu-0.1.0/pygpgpu/vec_types/genVec2.pyi.in +15 -0
  250. pygpgpu-0.1.0/pygpgpu/vec_types/genVec3.py +13 -0
  251. pygpgpu-0.1.0/pygpgpu/vec_types/genVec3.pyi.in +16 -0
  252. pygpgpu-0.1.0/pygpgpu/vec_types/genVec4.py +13 -0
  253. pygpgpu-0.1.0/pygpgpu/vec_types/genVec4.pyi.in +17 -0
  254. pygpgpu-0.1.0/pygpgpu/vec_types/genVec8.py +14 -0
  255. pygpgpu-0.1.0/pygpgpu/vec_types/genVec8.pyi.in +13 -0
  256. pygpgpu-0.1.0/pygpgpu/vec_types/helper.py +167 -0
  257. pygpgpu-0.1.0/pygpgpu/vec_types/int16.py +28 -0
  258. pygpgpu-0.1.0/pygpgpu/vec_types/int16.pyi +192 -0
  259. pygpgpu-0.1.0/pygpgpu/vec_types/int2.py +14 -0
  260. pygpgpu-0.1.0/pygpgpu/vec_types/int2.pyi +320 -0
  261. pygpgpu-0.1.0/pygpgpu/vec_types/int4.py +16 -0
  262. pygpgpu-0.1.0/pygpgpu/vec_types/int4.pyi +3652 -0
  263. pygpgpu-0.1.0/pygpgpu/vec_types/int8.py +20 -0
  264. pygpgpu-0.1.0/pygpgpu/vec_types/int8.pyi +108 -0
  265. pygpgpu-0.1.0/pygpgpu/vec_types/short16.py +28 -0
  266. pygpgpu-0.1.0/pygpgpu/vec_types/short16.pyi +192 -0
  267. pygpgpu-0.1.0/pygpgpu/vec_types/short2.py +14 -0
  268. pygpgpu-0.1.0/pygpgpu/vec_types/short2.pyi +320 -0
  269. pygpgpu-0.1.0/pygpgpu/vec_types/short4.py +16 -0
  270. pygpgpu-0.1.0/pygpgpu/vec_types/short4.pyi +3652 -0
  271. pygpgpu-0.1.0/pygpgpu/vec_types/short8.py +20 -0
  272. pygpgpu-0.1.0/pygpgpu/vec_types/short8.pyi +108 -0
  273. pygpgpu-0.1.0/pygpgpu/vec_types/uchar16.py +28 -0
  274. pygpgpu-0.1.0/pygpgpu/vec_types/uchar16.pyi +192 -0
  275. pygpgpu-0.1.0/pygpgpu/vec_types/uchar2.py +14 -0
  276. pygpgpu-0.1.0/pygpgpu/vec_types/uchar2.pyi +320 -0
  277. pygpgpu-0.1.0/pygpgpu/vec_types/uchar4.py +16 -0
  278. pygpgpu-0.1.0/pygpgpu/vec_types/uchar4.pyi +3652 -0
  279. pygpgpu-0.1.0/pygpgpu/vec_types/uchar8.py +20 -0
  280. pygpgpu-0.1.0/pygpgpu/vec_types/uchar8.pyi +108 -0
  281. pygpgpu-0.1.0/pygpgpu/vec_types/uint16.py +28 -0
  282. pygpgpu-0.1.0/pygpgpu/vec_types/uint16.pyi +192 -0
  283. pygpgpu-0.1.0/pygpgpu/vec_types/uint2.py +14 -0
  284. pygpgpu-0.1.0/pygpgpu/vec_types/uint2.pyi +320 -0
  285. pygpgpu-0.1.0/pygpgpu/vec_types/uint4.py +16 -0
  286. pygpgpu-0.1.0/pygpgpu/vec_types/uint4.pyi +3652 -0
  287. pygpgpu-0.1.0/pygpgpu/vec_types/uint8.py +20 -0
  288. pygpgpu-0.1.0/pygpgpu/vec_types/uint8.pyi +108 -0
  289. pygpgpu-0.1.0/pygpgpu/vec_types/ushort16.py +28 -0
  290. pygpgpu-0.1.0/pygpgpu/vec_types/ushort16.pyi +192 -0
  291. pygpgpu-0.1.0/pygpgpu/vec_types/ushort2.py +14 -0
  292. pygpgpu-0.1.0/pygpgpu/vec_types/ushort2.pyi +320 -0
  293. pygpgpu-0.1.0/pygpgpu/vec_types/ushort4.py +16 -0
  294. pygpgpu-0.1.0/pygpgpu/vec_types/ushort4.pyi +3652 -0
  295. pygpgpu-0.1.0/pygpgpu/vec_types/ushort8.py +20 -0
  296. pygpgpu-0.1.0/pygpgpu/vec_types/ushort8.pyi +108 -0
  297. pygpgpu-0.1.0/pygpgpu.egg-info/PKG-INFO +425 -0
  298. pygpgpu-0.1.0/pygpgpu.egg-info/SOURCES.txt +301 -0
  299. pygpgpu-0.1.0/pygpgpu.egg-info/dependency_links.txt +1 -0
  300. pygpgpu-0.1.0/pygpgpu.egg-info/requires.txt +12 -0
  301. pygpgpu-0.1.0/pygpgpu.egg-info/top_level.txt +1 -0
  302. pygpgpu-0.1.0/pyproject.toml +184 -0
  303. pygpgpu-0.1.0/setup.cfg +4 -0
pygpgpu-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Time-Coder
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # Source distribution contents beyond the package itself.
2
+ #
3
+ # The numbered scripts under examples/ are the project's end-to-end smoke tests and
4
+ # the only worked examples covering all three backends, so they ship with the sdist
5
+ # (the wheel installs just the pygpgpu package). Their generated .pyi stubs are
6
+ # excluded because they are byproducts of running the examples.
7
+ include README.md
8
+ include README.zh-CN.md
9
+ include LICENSE
10
+ recursive-include examples *.py *.md *.cl *.cu *.hip
11
+ recursive-exclude examples *.pyi
12
+
13
+ # doc/ is deliberately not included: it holds vendor reference PDFs for the CUDA
14
+ # driver API and NVRTC guides, not project documentation.
pygpgpu-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,425 @@
1
+ Metadata-Version: 2.4
2
+ Name: pygpgpu
3
+ Version: 0.1.0
4
+ Summary: Import GPU kernels like Python functions across OpenCL / CUDA / HIP backends
5
+ Author: Time-Coder
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Time-Coder
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/Time-Coder/PyGPGPU
29
+ Keywords: gpu,opencl,cuda,hip,rocm,kernel,jit
30
+ Classifier: Development Status :: 3 - Alpha
31
+ Classifier: Intended Audience :: Developers
32
+ Classifier: Intended Audience :: Science/Research
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: Microsoft :: Windows
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.7
37
+ Classifier: Programming Language :: Python :: 3.8
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Programming Language :: Python :: 3.14
44
+ Classifier: Topic :: Scientific/Engineering
45
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
46
+ Classifier: Typing :: Typed
47
+ Requires-Python: >=3.7
48
+ Description-Content-Type: text/markdown
49
+ License-File: LICENSE
50
+ Requires-Dist: numpy>=1.21
51
+ Requires-Dist: imageio>=2.30
52
+ Requires-Dist: tree-sitter>=0.20.0
53
+ Requires-Dist: tree-sitter-opencl>=0.0.2
54
+ Requires-Dist: tree-sitter-cuda37>=0.21.2
55
+ Requires-Dist: pygf>=0.1.4
56
+ Requires-Dist: typing_extensions>=4.4.0
57
+ Provides-Extra: dev
58
+ Requires-Dist: pytest>=8; extra == "dev"
59
+ Requires-Dist: ruff>=0.9; extra == "dev"
60
+ Requires-Dist: ty>=0.0.60; extra == "dev"
61
+ Dynamic: license-file
62
+
63
+ # PyGPGPU
64
+
65
+ **English** | [Chinese](README.zh-CN.md)
66
+
67
+ Decorate a Python function and it runs on the GPU — one codebase, three backends (**OpenCL / CUDA / HIP**).
68
+
69
+ ```python
70
+ import numpy as np
71
+ from pygpgpu import kernel
72
+
73
+ @kernel
74
+ def saxpy(x, y, out, alpha):
75
+ for i in range(out.shape[0]):
76
+ out[i] = x[i] * alpha + y[i]
77
+
78
+ x = np.arange(1_000_000, dtype=np.float32)
79
+ out = np.zeros_like(x)
80
+
81
+ saxpy(x, x, out, 2.0) # no backend given: probe cuda -> hip -> opencl, take the first available
82
+ saxpy["cuda"](x, x, out, 2.0) # bracket switches the backend
83
+ saxpy["hip:gfx1036"](x, x, out, 2.0) # backend:device
84
+ ```
85
+
86
+ No C code to write, no build system to configure; the first call translates, compiles and caches, every later call is free. Existing handwritten kernels are fine too — `.cl`/`.cu`/`.hip` files can be `import`ed like Python modules.
87
+
88
+ ## Features
89
+
90
+ - **`@kernel` decorator** — decorate a Python function directly (class methods and static methods included); at call time it is specialized per argument type, translated to backend source and compiled (monomorphization).
91
+ - **Plain-Python helper functions** — a helper called from a kernel needs no decorator and no type annotations: it is translated into a device function and monomorphized from the call site, recursively for helpers that call helpers.
92
+ - **All three backends in one process** — the bracket chooses the backend per call, so a single process (and even a single kernel object) can mix OpenCL, CUDA and HIP; each backend/device pair is specialized and cached separately.
93
+ - **Handwritten kernel file import** — `.cl` / `.cu` / `.hip` files import like Python modules: kernels and struct types become module attributes, and a `.pyi` type stub is generated automatically.
94
+ - **Low-level OOP API** — Device/Context/Buffer/Program/Kernel, for when you need full control.
95
+ - **One bracket syntax** for backend/device/work size (identical to handwritten kernels, order does not matter):
96
+ ```python
97
+ k(args) # fully automatic
98
+ k["cuda"](args) # backend (opencl/cuda/hip, aliases ocl/cu/rocm/amd)
99
+ k["opencl:gfx1036"](args) # backend:device
100
+ k[(1024, 256)](args) # work size: (total, per group), None = automatic
101
+ k["cuda"][(1024, 256)](args) # combined
102
+ ```
103
+ - **Total-work semantics** (OpenCL/SYCL style): in `(global, local)`, `global` is the **total number of work items**; CUDA/HIP grid dimensions are derived as `global / local`, so all three backends behave exactly the same.
104
+ - **Static read/write analysis**: the kernel body is parsed to infer whether each pointer argument is read-only, write-only or read-write — write-only arguments skip the upload, read-only arguments skip the read-back, and data stays on the device across calls (zero intermediate copies for gnp arrays).
105
+ - **Vector types**: 50 vector types (float4/int3/...) with `.x/.y/.z/.w` members, swizzles, construction, arithmetic (scalar broadcast), comparisons and component-wise math.
106
+ - **Dual-sided function library** `pygpgpu.funcs` (aka `pygpgpu.vec_types.funcs`): `dot/cross/normalize/clamp/...` run as-is in host Python and are translated to device builtins inside `@kernel`.
107
+ - **Device builtin namespace** `gpu.*`: `get_global_id/barrier/atomic_add/dot/...` covers GPU builtins that have no Python counterpart, mapped per backend.
108
+ - **Multi-dimensional iteration**: `np.ndindex(shape)` / `np.ndenumerate(arr)` magic loops (2D/3D), `enumerate(arr)` for a 1D index plus value snapshot.
109
+ - **Three cache layers**: parsed metadata / compiled artifacts / generated sources, all invalidated by mtime — unchanged sources mean zero recompilation.
110
+
111
+ ## Installation
112
+
113
+ ```bash
114
+ pip install -e .
115
+ ```
116
+
117
+ Python ≥ 3.12. Bring your own GPU runtime (any one of them is enough):
118
+
119
+ | Backend | What you need | Notes |
120
+ |---|---|---|
121
+ | OpenCL | GPU driver (usually already installed) | Nothing extra to install; works across NVIDIA/AMD/Intel |
122
+ | CUDA | NVIDIA driver (includes NVRTC) | The Toolkit is not required — the driver-provided nvrtc is enough |
123
+ | HIP | AMD HIP SDK | On Windows compilation runs through the SDK's clang; if MSVC/Windows SDK headers are not on the default paths, point `PYGPGPU_HIP_INCLUDES` at the include directories (os.pathsep-separated) |
124
+
125
+ When `@kernel` has no explicit `backend`, backends are probed in **cuda -> hip -> opencl** order and the first one that enumerates a device wins.
126
+
127
+ ## Quick start
128
+
129
+ Every commonly used API is importable straight from the `pygpgpu` top level — no need to remember submodule names:
130
+
131
+ ```python
132
+ from pygpgpu import kernel, gpu, funcs, float4 # @kernel / device builtins / dual-sided funcs / vector types
133
+ from pygpgpu import available_devices, get_device
134
+ from pygpgpu import climport, cuimport, hipimport # import hooks for handwritten .cl/.cu/.hip files
135
+ ```
136
+
137
+ The submodule paths (`pygpgpu.kernel` / `pygpgpu.vec_types` / `pygpgpu.opencl` / ...) still work. Note that top-level `pygpgpu.kernel` is the `@kernel` decorator; to reach things inside the submodule write `from pygpgpu.kernel import ...`.
138
+
139
+ The three import hooks load lazily: the corresponding backend is only loaded when you actually use the hook, so `import pygpgpu` itself needs no GPU runtime at all.
140
+
141
+ ### The @kernel decorator
142
+
143
+ ```python
144
+ import math
145
+ import numpy as np
146
+ from pygpgpu import kernel, gpu, funcs, float4
147
+
148
+ def norm2(v):
149
+ return funcs.dot(v, v)
150
+
151
+ @kernel
152
+ def normalize_all(vecs, out):
153
+ for i, v in enumerate(vecs): # 1D: index + float4 value snapshot
154
+ out[i] = funcs.normalize(v) # expanded component-wise on device
155
+
156
+ @kernel
157
+ def matrix_scale(m, out, k):
158
+ for y, x in np.ndindex(out.shape): # 2D NDRange
159
+ out[y, x] = m[y, x] * k
160
+
161
+ @kernel(backend="cuda")
162
+ def histogram(data, counts):
163
+ gpu.work_size(data) # iteration domain for a gid-style kernel
164
+ i = gpu.get_global_id(0)
165
+ gpu.atomic_add(counts, data[i], 1) # atomics, results read back automatically
166
+ ```
167
+
168
+ Supported: scalar/array/vector arguments, if/while/for-range, arithmetic/comparison/bit ops, `math.*` and `np.*` math functions, class methods (`self.xxx` attributes become arguments automatically), static methods. Unsupported syntax raises a `SyntaxError` carrying the line number.
169
+
170
+ A kernel needs an iteration domain for its work size to be derived. Either use a magic loop (`for i in range(x.shape[0])`, whose bound is the domain) or, when dispatching on `gpu.get_global_id`, declare `gpu.work_size(x)` — that statement is host-side only, erased by the translator, and contributes all of `x`'s dimensions. A `k[(total, local)]` bracket also works. Without any of these the call raises instead of guessing.
171
+
172
+ ### Handwritten kernel files
173
+
174
+ Already have C-style kernels? `.cl` / `.cu` / `.hip` files (native syntax of the matching backend) import like Python modules. Write a `vecadd.cl`:
175
+
176
+ ```c
177
+ __kernel void vecadd(__global const float* a, __global const float* b,
178
+ __global float* out, const int n)
179
+ {
180
+ int i = get_global_id(0);
181
+ if (i >= n) return;
182
+ out[i] = a[i] + b[i];
183
+ }
184
+ ```
185
+
186
+ ```python
187
+ from pygpgpu import climport # cuimport / hipimport work the same way
188
+ import numpy as np
189
+ import vecadd # just like importing a Python module
190
+
191
+ a = np.random.rand(1_000_000).astype(np.float32)
192
+ out = np.zeros_like(a)
193
+ vecadd.vecadd(a, a, out, np.int32(len(a))) # work size inferred
194
+ vecadd.vecadd[(1_000_192, 256)](a, a, out, np.int32(len(a))) # explicit (total, per group)
195
+ ```
196
+
197
+ Note the `n` argument: a handwritten kernel must clamp against the real element count, because the
198
+ launch size is rounded up to a multiple of the local size. `get_global_size(0)` reports that rounded
199
+ size, not the buffer length, so it is not a usable bound.
200
+
201
+ Struct definitions map to ctypes types; a `.pyi` stub is generated next to the kernel so IDE completion works.
202
+
203
+ ### Class methods
204
+
205
+ ```python
206
+ class Model:
207
+ def __init__(self):
208
+ self.weights = np.random.rand(1024).astype(np.float32)
209
+ self.lr = 0.01
210
+
211
+ @kernel
212
+ def apply(self, x, out):
213
+ for i in range(out.shape[0]):
214
+ out[i] = x[i] * self.weights[i] + self.lr
215
+
216
+ m = Model()
217
+ m.apply(x, out) # self.weights/self.lr are passed as kernel arguments
218
+ m.apply["cuda"](x, out) # brackets still available
219
+ ```
220
+
221
+ ### Copy optimization
222
+
223
+ Each pointer argument goes through function-body-level static analysis (`points[i] = ...` is a write, `x = a[i]` is a read, plus pointer-alias propagation and interprocedural analysis across functions):
224
+
225
+ ```python
226
+ @kernel
227
+ def k(a, b, out):
228
+ for i in range(out.shape[0]):
229
+ out[i] = a[i] + b[i] * 2.0 # a read-only, b read-only, out write-only
230
+ # at runtime: a/b skip the read-back after upload, out skips the upload and only reads back
231
+ ```
232
+
233
+ Combined with `pygpgpu.numpy` (gnp) arrays, data stays entirely on the device between consecutive kernel calls and is synchronized only when the host touches it.
234
+
235
+ ## How it compares
236
+
237
+ The same computation, written in this library and in three other GPU-from-Python projects
238
+ ([Taichi](https://www.taichi-lang.org/), [Numba](https://numba.pydata.org/),
239
+ [NVIDIA Warp](https://github.com/NVIDIA/warp)). Snippets are cut down to the parts that
240
+ differ — check each project's docs for exact syntax. The examples also show a shared helper
241
+ function, which is where the API gap is widest: here it stays ordinary Python, while the
242
+ others need a second decorator and typed signatures.
243
+
244
+ **PyGPGPU** — arrays in, arrays out; no launch geometry, no buffer management, and helper
245
+ functions need no decorator at all:
246
+
247
+ ```python
248
+ from pygpgpu import kernel
249
+
250
+ def square(v): # plain Python: no decorator, no annotations
251
+ return v * v
252
+
253
+ def clamp01(v):
254
+ if v < 0.0:
255
+ return 0.0
256
+ if v > 1.0:
257
+ return 1.0
258
+ return v
259
+
260
+ def weight(v): # helpers may call other helpers
261
+ return clamp01(square(v)) * 0.5 + 0.25
262
+
263
+ @kernel
264
+ def apply_all(x, out):
265
+ for i in range(out.shape[0]): # loop bound = work size
266
+ out[i] = weight(x[i])
267
+
268
+ apply_all(x, out) # numpy arrays as-is
269
+ apply_all["hip"](x, out) # the same function, another backend
270
+ ```
271
+
272
+ **Taichi** — declare fields first, then copy data in and out by hand; a helper needs `@ti.func`
273
+ and every argument must be annotated:
274
+
275
+ ```python
276
+ import taichi as ti
277
+ ti.init(arch=ti.gpu)
278
+
279
+ x = ti.field(ti.f32, n)
280
+ y = ti.field(ti.f32, n)
281
+ out = ti.field(ti.f32, n)
282
+ x.from_numpy(nx)
283
+ y.from_numpy(ny)
284
+
285
+ @ti.func # helpers need their own decorator
286
+ def weight(v: ti.f32) -> ti.f32:
287
+ return ti.max(0.0, ti.min(1.0, v * v)) * 0.5 + 0.25
288
+
289
+ @ti.kernel
290
+ def saxpy(a: ti.f32):
291
+ for i in range(n):
292
+ out[i] = x[i] * a + y[i] + weight(x[i])
293
+
294
+ saxpy(2.0)
295
+ res = out.to_numpy()
296
+ ```
297
+
298
+ **Numba** — compute blocks/threads yourself, guard inside, manage device memory; callable helpers
299
+ are compiled separately with `@cuda.jit(device=True)`:
300
+
301
+ ```python
302
+ from numba import cuda
303
+
304
+ @cuda.jit(device=True) # helpers need device=True
305
+ def weight(v):
306
+ return min(1.0, max(0.0, v * v)) * 0.5 + 0.25
307
+
308
+ @cuda.jit
309
+ def saxpy(x, y, out, a):
310
+ i = cuda.grid(1)
311
+ if i < out.size: # bounds guard is your job
312
+ out[i] = x[i] * a + y[i] + weight(x[i])
313
+
314
+ d_x = cuda.to_device(nx)
315
+ d_y = cuda.to_device(ny)
316
+ d_out = cuda.device_array_like(nx)
317
+ threads = 256
318
+ saxpy[(n + threads - 1) // threads, threads](d_x, d_y, d_out, 2.0)
319
+ res = d_out.copy_to_host()
320
+ ```
321
+
322
+ **Warp** — typed array parameters, the launch size is passed explicitly, and helpers need `@wp.func`:
323
+
324
+ ```python
325
+ import warp as wp
326
+ wp.init()
327
+
328
+ @wp.func # helpers need their own decorator
329
+ def weight(v: float) -> float:
330
+ return wp.min(1.0, wp.max(0.0, v * v)) * 0.5 + 0.25
331
+
332
+ @wp.kernel
333
+ def saxpy(x: wp.array(dtype=float), y: wp.array(dtype=float),
334
+ out: wp.array(dtype=float), a: float):
335
+ i = wp.tid()
336
+ out[i] = x[i] * a + y[i] + weight(x[i])
337
+
338
+ wp.launch(saxpy, dim=n, inputs=[x, y, out, 2.0])
339
+ ```
340
+
341
+ | | PyGPGPU | Taichi | Numba | Warp |
342
+ |---|---|---|---|---|
343
+ | Input data | numpy arrays directly | wrap in `ti.field`, explicit `from_numpy`/`to_numpy` | `cuda.to_device` + `copy_to_host` by hand | wrap in `wp.array` |
344
+ | Helper functions | **plain Python — no decorator, no annotations** | `@ti.func` + annotated args | `@cuda.jit(device=True)` | `@wp.func` + annotated args |
345
+ | Backends in one process | **all three, mixed freely** | one, fixed by `ti.init(arch=...)` | CUDA only | CUDA only |
346
+ | Launch size | inferred from the loop bound (or `gpu.work_size(x)` / a bracket) | inferred from `range` | blocks × threads by hand, plus a guard | pass `dim=` |
347
+ | Bounds guard | emitted for you | emitted for you | you write it | you write it |
348
+ | Backends | OpenCL, CUDA, HIP | CPU, CUDA, Vulkan and others | CPU, CUDA | CPU, CUDA |
349
+ | AMD GPU | HIP (native AMD codegen) and OpenCL | via Vulkan | no | no |
350
+ | Switching backend | bracket `k["hip"]`, same source | `ti.init(arch=...)`, same source | not applicable | not applicable |
351
+ | Install footprint | Python + ctypes only: no LLVM, no CUDA Toolkit | ships its own runtime | needs LLVM | needs the CUDA Toolkit |
352
+ | Handwritten `.cl`/`.cu`/`.hip` | imported as Python modules, `.pyi` generated | no | via the `cuda` module's PTX/cubin path | no |
353
+ | Static read/write analysis | yes — uploads/read-backs skipped per argument | no | no | no |
354
+
355
+ ### Several backends at the same time
356
+
357
+ Taichi fixes its backend once, at `ti.init(arch=...)`; Numba and Warp only target CUDA. Here the
358
+ bracket picks the backend per call, so one process — and even one kernel object — can use every
359
+ backend the machine has:
360
+
361
+ ```python
362
+ @kernel
363
+ def apply_all(x, out):
364
+ for i in range(out.shape[0]):
365
+ out[i] = square(x[i]) + 1.0
366
+
367
+ apply_all["cuda"](x, out) # NVIDIA
368
+ apply_all["hip"](x, out) # AMD
369
+ apply_all["opencl"](x, out) # whichever device OpenCL enumerates
370
+ apply_all(x, out) # unqualified: probe cuda -> hip -> opencl
371
+ ```
372
+
373
+ Each backend/device pair is specialized and cached separately, so alternating between them is just
374
+ an extra dictionary lookup — no recompilation after the first call. This is useful for comparing a
375
+ kernel across vendors on one machine (`examples/08_compare_backends.py`), or for falling back to a
376
+ second GPU when the first is busy.
377
+
378
+ Where the others are ahead — worth knowing before you pick:
379
+ - **Automatic differentiation**: Taichi and Warp can differentiate kernels; this library cannot.
380
+ - **Sparse and irregular data structures**: Taichi has sparse grids and SNode trees; here you pass dense numpy arrays (or handle sparsity yourself).
381
+ - **CPU fallback**: all three can run on the CPU; this library needs a GPU.
382
+ - **Minimum interpreter version**: this library requires Python 3.12+ (it runs on 3.14); the others support a wider range of older versions.
383
+
384
+ This table was written from each project's documentation and the snippets above; their APIs move
385
+ fast, so confirm against current docs before relying on a specific cell.
386
+
387
+ ## Device selection
388
+
389
+ Three forms of device identifier inside the brackets (same on every backend):
390
+
391
+ | Form | Meaning |
392
+ |---|---|
393
+ | `"0"`, `"1"` | index in the backend's device list (OpenCL uses flat numbering across platforms) |
394
+ | `"gfx1036"`, `"geforce"` | case-insensitive substring match on name/vendor/**architecture name** |
395
+ | `"geforce:1"` | when a name matches several devices, take the n-th one |
396
+
397
+ Helpers:
398
+
399
+ ```python
400
+ from pygpgpu import available_devices, get_device
401
+
402
+ available_devices() # every available "backend:device" string, e.g. ['cuda:0', 'hip:0', 'opencl:0']
403
+ dev = get_device("cuda:0") # the Device object of that backend, directly
404
+ ```
405
+
406
+ ## Caching
407
+
408
+ | Backend | Directory | Contents |
409
+ |---|---|---|
410
+ | OpenCL | `__clcache__/` | parsed meta + per-device binaries |
411
+ | CUDA | `__cucache__/` | parsed meta + per-device cubin/ptx |
412
+ | HIP | `__hipcache__/` | parsed meta + per-device code objects |
413
+
414
+ Caches are invalidated by the mtime of the source file (and every `#include`); sources generated by `@kernel` are keyed by a hash of the Python source. These directories should be in `.gitignore`.
415
+
416
+ ## Known limitations
417
+
418
+ - `@kernel` does not support: strings/lists/dicts, closures, recursion, kernel return values, dynamic multi-dimensional shape indexing;
419
+ - vector comparison, writing through a swizzle, and nesting beyond three operands are restricted in favour of cross-backend consistency (the error message suggests a workaround);
420
+ - fp16 (`np.float16`) arguments are unavailable on the CUDA/HIP backends (use float32);
421
+ - the HIP backend compiles with the clang shipped by the AMD HIP SDK; hipRTC on this machine (ROCm 7.2 Windows) fails on any input, so it is not used.
422
+
423
+ ## License
424
+
425
+ MIT