numba-cuda 0.22.0__cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.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 (487) hide show
  1. _numba_cuda_redirector.pth +4 -0
  2. _numba_cuda_redirector.py +89 -0
  3. numba_cuda/VERSION +1 -0
  4. numba_cuda/__init__.py +6 -0
  5. numba_cuda/_version.py +11 -0
  6. numba_cuda/numba/cuda/__init__.py +70 -0
  7. numba_cuda/numba/cuda/_internal/cuda_bf16.py +16394 -0
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +8112 -0
  9. numba_cuda/numba/cuda/api.py +580 -0
  10. numba_cuda/numba/cuda/api_util.py +76 -0
  11. numba_cuda/numba/cuda/args.py +72 -0
  12. numba_cuda/numba/cuda/bf16.py +397 -0
  13. numba_cuda/numba/cuda/cache_hints.py +287 -0
  14. numba_cuda/numba/cuda/cext/__init__.py +2 -0
  15. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpython-313-aarch64-linux-gnu.so +0 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpython-313-aarch64-linux-gnu.so +0 -0
  20. numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
  21. numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
  22. numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
  23. numba_cuda/numba/cuda/cext/_helperlib.cpython-313-aarch64-linux-gnu.so +0 -0
  24. numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
  25. numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
  26. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpython-313-aarch64-linux-gnu.so +0 -0
  28. numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
  29. numba_cuda/numba/cuda/cext/_typeof.h +19 -0
  30. numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
  31. numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
  32. numba_cuda/numba/cuda/cext/mviewbuf.cpython-313-aarch64-linux-gnu.so +0 -0
  33. numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
  34. numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
  35. numba_cuda/numba/cuda/cg.py +67 -0
  36. numba_cuda/numba/cuda/cgutils.py +1294 -0
  37. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  38. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  39. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  40. numba_cuda/numba/cuda/codegen.py +541 -0
  41. numba_cuda/numba/cuda/compiler.py +1396 -0
  42. numba_cuda/numba/cuda/core/analysis.py +758 -0
  43. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  44. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
  45. numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
  46. numba_cuda/numba/cuda/core/base.py +1332 -0
  47. numba_cuda/numba/cuda/core/boxing.py +1411 -0
  48. numba_cuda/numba/cuda/core/bytecode.py +728 -0
  49. numba_cuda/numba/cuda/core/byteflow.py +2346 -0
  50. numba_cuda/numba/cuda/core/caching.py +744 -0
  51. numba_cuda/numba/cuda/core/callconv.py +392 -0
  52. numba_cuda/numba/cuda/core/codegen.py +171 -0
  53. numba_cuda/numba/cuda/core/compiler.py +199 -0
  54. numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
  55. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  56. numba_cuda/numba/cuda/core/config.py +650 -0
  57. numba_cuda/numba/cuda/core/consts.py +124 -0
  58. numba_cuda/numba/cuda/core/controlflow.py +989 -0
  59. numba_cuda/numba/cuda/core/entrypoints.py +57 -0
  60. numba_cuda/numba/cuda/core/environment.py +66 -0
  61. numba_cuda/numba/cuda/core/errors.py +917 -0
  62. numba_cuda/numba/cuda/core/event.py +511 -0
  63. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  64. numba_cuda/numba/cuda/core/generators.py +387 -0
  65. numba_cuda/numba/cuda/core/imputils.py +509 -0
  66. numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
  67. numba_cuda/numba/cuda/core/interpreter.py +3617 -0
  68. numba_cuda/numba/cuda/core/ir.py +1812 -0
  69. numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
  70. numba_cuda/numba/cuda/core/optional.py +129 -0
  71. numba_cuda/numba/cuda/core/options.py +262 -0
  72. numba_cuda/numba/cuda/core/postproc.py +249 -0
  73. numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
  74. numba_cuda/numba/cuda/core/registry.py +46 -0
  75. numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
  76. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  77. numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
  78. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  79. numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
  80. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
  81. numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
  82. numba_cuda/numba/cuda/core/sigutils.py +68 -0
  83. numba_cuda/numba/cuda/core/ssa.py +498 -0
  84. numba_cuda/numba/cuda/core/targetconfig.py +330 -0
  85. numba_cuda/numba/cuda/core/tracing.py +231 -0
  86. numba_cuda/numba/cuda/core/transforms.py +956 -0
  87. numba_cuda/numba/cuda/core/typed_passes.py +867 -0
  88. numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
  89. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  90. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  91. numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
  92. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  93. numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
  94. numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
  95. numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
  96. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  97. numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
  98. numba_cuda/numba/cuda/cpython/iterators.py +167 -0
  99. numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
  100. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  101. numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
  102. numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
  103. numba_cuda/numba/cuda/cpython/slicing.py +322 -0
  104. numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
  105. numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
  106. numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
  107. numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
  108. numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
  109. numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
  110. numba_cuda/numba/cuda/cuda_paths.py +691 -0
  111. numba_cuda/numba/cuda/cudadecl.py +543 -0
  112. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  113. numba_cuda/numba/cuda/cudadrv/devicearray.py +954 -0
  114. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  115. numba_cuda/numba/cuda/cudadrv/driver.py +3238 -0
  116. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  117. numba_cuda/numba/cuda/cudadrv/dummyarray.py +562 -0
  118. numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
  119. numba_cuda/numba/cuda/cudadrv/error.py +48 -0
  120. numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
  121. numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
  122. numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
  123. numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
  124. numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
  125. numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
  126. numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
  127. numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
  128. numba_cuda/numba/cuda/cudaimpl.py +983 -0
  129. numba_cuda/numba/cuda/cudamath.py +149 -0
  130. numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
  131. numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
  132. numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
  133. numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
  134. numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
  135. numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
  136. numba_cuda/numba/cuda/datamodel/manager.py +11 -0
  137. numba_cuda/numba/cuda/datamodel/models.py +9 -0
  138. numba_cuda/numba/cuda/datamodel/packer.py +9 -0
  139. numba_cuda/numba/cuda/datamodel/registry.py +11 -0
  140. numba_cuda/numba/cuda/datamodel/testing.py +11 -0
  141. numba_cuda/numba/cuda/debuginfo.py +997 -0
  142. numba_cuda/numba/cuda/decorators.py +294 -0
  143. numba_cuda/numba/cuda/descriptor.py +35 -0
  144. numba_cuda/numba/cuda/device_init.py +155 -0
  145. numba_cuda/numba/cuda/deviceufunc.py +1021 -0
  146. numba_cuda/numba/cuda/dispatcher.py +2463 -0
  147. numba_cuda/numba/cuda/errors.py +72 -0
  148. numba_cuda/numba/cuda/extending.py +697 -0
  149. numba_cuda/numba/cuda/flags.py +178 -0
  150. numba_cuda/numba/cuda/fp16.py +357 -0
  151. numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
  152. numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
  153. numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
  154. numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
  155. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  156. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  157. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  158. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  159. numba_cuda/numba/cuda/initialize.py +24 -0
  160. numba_cuda/numba/cuda/intrinsics.py +531 -0
  161. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  162. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  163. numba_cuda/numba/cuda/kernels/reduction.py +265 -0
  164. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  165. numba_cuda/numba/cuda/libdevice.py +3386 -0
  166. numba_cuda/numba/cuda/libdevicedecl.py +20 -0
  167. numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
  168. numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
  169. numba_cuda/numba/cuda/locks.py +19 -0
  170. numba_cuda/numba/cuda/lowering.py +1980 -0
  171. numba_cuda/numba/cuda/mathimpl.py +374 -0
  172. numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
  173. numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
  174. numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
  175. numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
  176. numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
  177. numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
  178. numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
  179. numba_cuda/numba/cuda/misc/appdirs.py +594 -0
  180. numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
  181. numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
  182. numba_cuda/numba/cuda/misc/dump_style.py +41 -0
  183. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  184. numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
  185. numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
  186. numba_cuda/numba/cuda/misc/literal.py +28 -0
  187. numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
  188. numba_cuda/numba/cuda/misc/special.py +94 -0
  189. numba_cuda/numba/cuda/models.py +56 -0
  190. numba_cuda/numba/cuda/np/arraymath.py +5130 -0
  191. numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
  192. numba_cuda/numba/cuda/np/extensions.py +11 -0
  193. numba_cuda/numba/cuda/np/linalg.py +3087 -0
  194. numba_cuda/numba/cuda/np/math/__init__.py +0 -0
  195. numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
  196. numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
  197. numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
  198. numba_cuda/numba/cuda/np/npdatetime.py +969 -0
  199. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  200. numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
  201. numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
  202. numba_cuda/numba/cuda/np/numpy_support.py +798 -0
  203. numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
  204. numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
  205. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
  206. numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
  207. numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
  208. numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
  209. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
  210. numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
  211. numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
  212. numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
  213. numba_cuda/numba/cuda/nvvmutils.py +254 -0
  214. numba_cuda/numba/cuda/printimpl.py +126 -0
  215. numba_cuda/numba/cuda/random.py +308 -0
  216. numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
  217. numba_cuda/numba/cuda/serialize.py +267 -0
  218. numba_cuda/numba/cuda/simulator/__init__.py +63 -0
  219. numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
  220. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  221. numba_cuda/numba/cuda/simulator/api.py +179 -0
  222. numba_cuda/numba/cuda/simulator/bf16.py +4 -0
  223. numba_cuda/numba/cuda/simulator/compiler.py +38 -0
  224. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
  225. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
  226. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
  227. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
  228. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
  229. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
  230. numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
  231. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
  232. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
  233. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
  234. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
  235. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
  236. numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
  237. numba_cuda/numba/cuda/simulator/kernel.py +320 -0
  238. numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
  239. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
  240. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
  241. numba_cuda/numba/cuda/simulator/reduction.py +19 -0
  242. numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
  243. numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
  244. numba_cuda/numba/cuda/simulator_init.py +18 -0
  245. numba_cuda/numba/cuda/stubs.py +624 -0
  246. numba_cuda/numba/cuda/target.py +505 -0
  247. numba_cuda/numba/cuda/testing.py +347 -0
  248. numba_cuda/numba/cuda/tests/__init__.py +62 -0
  249. numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
  250. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
  251. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  252. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
  253. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  254. numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
  255. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
  256. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
  257. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
  258. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
  259. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
  260. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
  261. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +313 -0
  262. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +191 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
  264. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
  265. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
  266. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +200 -0
  267. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
  268. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
  269. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
  270. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
  271. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
  272. numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
  273. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
  274. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
  275. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
  276. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
  277. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
  278. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
  279. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
  280. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
  281. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
  282. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
  283. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
  284. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
  285. numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
  286. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
  287. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
  288. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
  289. numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
  290. numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
  291. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
  292. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
  293. numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
  294. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
  295. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
  296. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
  297. numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
  298. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
  299. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
  300. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
  301. numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
  302. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
  303. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
  304. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
  305. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
  306. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
  307. numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
  308. numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
  309. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
  310. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
  311. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
  312. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
  313. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
  314. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
  315. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
  316. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
  317. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
  318. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
  319. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
  320. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
  321. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
  322. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
  323. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +978 -0
  324. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  325. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
  326. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
  327. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
  328. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
  329. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
  330. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
  331. numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
  332. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
  333. numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
  334. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
  335. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
  336. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
  337. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
  338. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
  339. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
  340. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
  341. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
  342. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
  343. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
  344. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
  345. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
  346. numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
  347. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
  348. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
  349. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
  350. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
  351. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
  352. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
  353. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
  354. numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
  355. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
  356. numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
  357. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
  358. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
  359. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
  360. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
  361. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
  362. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
  363. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
  364. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
  365. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
  366. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
  367. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
  368. numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
  369. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
  370. numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
  371. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
  372. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
  373. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
  374. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  375. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
  376. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
  377. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
  378. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
  379. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
  380. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
  381. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
  382. numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
  383. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
  384. numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
  385. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  386. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
  387. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
  388. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
  389. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
  390. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
  391. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
  392. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
  393. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
  394. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
  395. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +446 -0
  396. numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
  397. numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
  398. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
  399. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  400. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
  401. numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
  402. numba_cuda/numba/cuda/tests/data/error.cu +12 -0
  403. numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
  404. numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
  405. numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
  406. numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
  407. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
  408. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  409. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
  410. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
  411. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
  412. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
  413. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
  414. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
  415. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
  416. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
  417. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
  418. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
  419. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
  420. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
  421. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
  422. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
  423. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
  424. numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
  425. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +452 -0
  426. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
  427. numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
  428. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
  429. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
  430. numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
  431. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
  432. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
  433. numba_cuda/numba/cuda/tests/support.py +900 -0
  434. numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
  435. numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
  436. numba_cuda/numba/cuda/typeconv/rules.py +63 -0
  437. numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
  438. numba_cuda/numba/cuda/types/__init__.py +233 -0
  439. numba_cuda/numba/cuda/types/__init__.pyi +167 -0
  440. numba_cuda/numba/cuda/types/abstract.py +9 -0
  441. numba_cuda/numba/cuda/types/common.py +9 -0
  442. numba_cuda/numba/cuda/types/containers.py +9 -0
  443. numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
  444. numba_cuda/numba/cuda/types/cuda_common.py +110 -0
  445. numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
  446. numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
  447. numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
  448. numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
  449. numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
  450. numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
  451. numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
  452. numba_cuda/numba/cuda/types/ext_types.py +101 -0
  453. numba_cuda/numba/cuda/types/function_type.py +11 -0
  454. numba_cuda/numba/cuda/types/functions.py +9 -0
  455. numba_cuda/numba/cuda/types/iterators.py +9 -0
  456. numba_cuda/numba/cuda/types/misc.py +9 -0
  457. numba_cuda/numba/cuda/types/npytypes.py +9 -0
  458. numba_cuda/numba/cuda/types/scalars.py +9 -0
  459. numba_cuda/numba/cuda/typing/__init__.py +19 -0
  460. numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
  461. numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
  462. numba_cuda/numba/cuda/typing/bufproto.py +70 -0
  463. numba_cuda/numba/cuda/typing/builtins.py +1209 -0
  464. numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
  465. numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
  466. numba_cuda/numba/cuda/typing/collections.py +138 -0
  467. numba_cuda/numba/cuda/typing/context.py +782 -0
  468. numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
  469. numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
  470. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  471. numba_cuda/numba/cuda/typing/listdecl.py +147 -0
  472. numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
  473. numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
  474. numba_cuda/numba/cuda/typing/npydecl.py +749 -0
  475. numba_cuda/numba/cuda/typing/setdecl.py +115 -0
  476. numba_cuda/numba/cuda/typing/templates.py +1446 -0
  477. numba_cuda/numba/cuda/typing/typeof.py +301 -0
  478. numba_cuda/numba/cuda/ufuncs.py +746 -0
  479. numba_cuda/numba/cuda/utils.py +724 -0
  480. numba_cuda/numba/cuda/vector_types.py +214 -0
  481. numba_cuda/numba/cuda/vectorizers.py +260 -0
  482. numba_cuda-0.22.0.dist-info/METADATA +109 -0
  483. numba_cuda-0.22.0.dist-info/RECORD +487 -0
  484. numba_cuda-0.22.0.dist-info/WHEEL +6 -0
  485. numba_cuda-0.22.0.dist-info/licenses/LICENSE +26 -0
  486. numba_cuda-0.22.0.dist-info/licenses/LICENSE.numba +24 -0
  487. numba_cuda-0.22.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,100 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ from numba.cuda.core import errors
5
+ from numba.cuda.core import ir
6
+ from numba.cuda.core import consts
7
+ from numba.cuda.core.rewrites import register_rewrite, Rewrite
8
+
9
+
10
+ @register_rewrite("before-inference")
11
+ class RewriteConstRaises(Rewrite):
12
+ """
13
+ Rewrite IR statements of the kind `raise(value)`
14
+ where `value` is the result of instantiating an exception with
15
+ constant arguments
16
+ into `static_raise(exception_type, constant args)`.
17
+
18
+ This allows lowering in nopython mode, where one can't instantiate
19
+ exception instances from runtime data.
20
+ """
21
+
22
+ def _is_exception_type(self, const):
23
+ return isinstance(const, type) and issubclass(const, Exception)
24
+
25
+ def _break_constant(self, const, loc):
26
+ """
27
+ Break down constant exception.
28
+ """
29
+ if isinstance(const, tuple): # it's a tuple(exception class, args)
30
+ if not self._is_exception_type(const[0]):
31
+ msg = "Encountered unsupported exception constant %r"
32
+ raise errors.UnsupportedError(msg % (const[0],), loc)
33
+ return const[0], tuple(const[1])
34
+ elif self._is_exception_type(const):
35
+ return const, None
36
+ else:
37
+ if isinstance(const, str):
38
+ msg = (
39
+ "Directly raising a string constant as an exception is "
40
+ "not supported."
41
+ )
42
+ else:
43
+ msg = "Encountered unsupported constant type used for exception"
44
+ raise errors.UnsupportedError(msg, loc)
45
+
46
+ def _try_infer_constant(self, func_ir, inst):
47
+ try:
48
+ return func_ir.infer_constant(inst.exception)
49
+ except consts.ConstantInferenceError:
50
+ # not a static exception
51
+ return None
52
+
53
+ def match(self, func_ir, block, typemap, calltypes):
54
+ self.raises = raises = {}
55
+ self.tryraises = tryraises = {}
56
+ self.block = block
57
+ # Detect all raise statements and find which ones can be
58
+ # rewritten
59
+ for inst in block.find_insts((ir.Raise, ir.TryRaise)):
60
+ if inst.exception is None:
61
+ # re-reraise
62
+ exc_type, exc_args = None, None
63
+ else:
64
+ # raise <something> => find the definition site for <something>
65
+ const = self._try_infer_constant(func_ir, inst)
66
+
67
+ # failure to infer constant indicates this isn't a static
68
+ # exception
69
+ if const is None:
70
+ continue
71
+
72
+ loc = inst.exception.loc
73
+ exc_type, exc_args = self._break_constant(const, loc)
74
+
75
+ if isinstance(inst, ir.Raise):
76
+ raises[inst] = exc_type, exc_args
77
+ elif isinstance(inst, ir.TryRaise):
78
+ tryraises[inst] = exc_type, exc_args
79
+ else:
80
+ raise ValueError("unexpected: {}".format(type(inst)))
81
+ return (len(raises) + len(tryraises)) > 0
82
+
83
+ def apply(self):
84
+ """
85
+ Rewrite all matching setitems as static_setitems.
86
+ """
87
+ new_block = self.block.copy()
88
+ new_block.clear()
89
+ for inst in self.block.body:
90
+ if inst in self.raises:
91
+ exc_type, exc_args = self.raises[inst]
92
+ new_inst = ir.StaticRaise(exc_type, exc_args, inst.loc)
93
+ new_block.append(new_inst)
94
+ elif inst in self.tryraises:
95
+ exc_type, exc_args = self.tryraises[inst]
96
+ new_inst = ir.StaticTryRaise(exc_type, exc_args, inst.loc)
97
+ new_block.append(new_inst)
98
+ else:
99
+ new_block.append(inst)
100
+ return new_block
@@ -0,0 +1,68 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ from numba.cuda import types, typing, HAS_NUMBA
5
+
6
+ if HAS_NUMBA:
7
+ from numba.core.typing import Signature as CoreSignature
8
+
9
+
10
+ def is_signature(sig):
11
+ """
12
+ Return whether *sig* is a potentially valid signature
13
+ specification (for user-facing APIs).
14
+ """
15
+ sig_types = (str, tuple, typing.Signature)
16
+ if HAS_NUMBA:
17
+ sig_types = (str, tuple, typing.Signature, CoreSignature)
18
+ return isinstance(sig, sig_types)
19
+
20
+
21
+ def _parse_signature_string(signature_str):
22
+ """
23
+ Parameters
24
+ ----------
25
+ signature_str : str
26
+ """
27
+ # Just eval signature_str using the types submodules as globals
28
+ return eval(signature_str, {}, types.__dict__)
29
+
30
+
31
+ def normalize_signature(sig):
32
+ """
33
+ From *sig* (a signature specification), return a ``(args, return_type)``
34
+ tuple, where ``args`` itself is a tuple of types, and ``return_type``
35
+ can be None if not specified.
36
+ """
37
+ if isinstance(sig, str):
38
+ parsed = _parse_signature_string(sig)
39
+ else:
40
+ parsed = sig
41
+ if isinstance(parsed, tuple):
42
+ args, return_type = parsed, None
43
+ else:
44
+ sig_types = (typing.Signature,)
45
+ if HAS_NUMBA:
46
+ sig_types = (typing.Signature, CoreSignature)
47
+ if isinstance(parsed, sig_types):
48
+ args, return_type = parsed.args, parsed.return_type
49
+ else:
50
+ raise TypeError(
51
+ "invalid signature: %r (type: %r) evaluates to %r "
52
+ "instead of tuple or Signature"
53
+ % (sig, sig.__class__.__name__, parsed.__class__.__name__)
54
+ )
55
+
56
+ def check_type(ty):
57
+ if not isinstance(ty, types.Type):
58
+ raise TypeError(
59
+ "invalid type in signature: expected a type "
60
+ "instance, got %r" % (ty,)
61
+ )
62
+
63
+ if return_type is not None:
64
+ check_type(return_type)
65
+ for ty in args:
66
+ check_type(ty)
67
+
68
+ return args, return_type
@@ -0,0 +1,498 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+ """
4
+ Implement Dominance-Fronter-based SSA by Choi et al described in Inria SSA book
5
+
6
+ References:
7
+
8
+ - Static Single Assignment Book by Inria
9
+ http://ssabook.gforge.inria.fr/latest/book.pdf
10
+ - Choi et al. Incremental computation of static single assignment form.
11
+ """
12
+
13
+ import logging
14
+ import operator
15
+ import warnings
16
+ from functools import reduce
17
+ from copy import copy
18
+ from collections import defaultdict
19
+
20
+ from numba.cuda import config
21
+ from numba.cuda.core import ir
22
+ from numba.cuda.core import errors
23
+ from numba.cuda.core import ir_utils
24
+ from numba.cuda.utils import _lazy_pformat
25
+ from numba.cuda.core.analysis import compute_cfg_from_blocks
26
+
27
+
28
+ _logger = logging.getLogger(__name__)
29
+
30
+
31
+ def reconstruct_ssa(func_ir):
32
+ """Apply SSA reconstruction algorithm on the given IR.
33
+
34
+ Produces minimal SSA using Choi et al algorithm.
35
+ """
36
+ func_ir.blocks = _run_ssa(func_ir.blocks)
37
+
38
+ return func_ir
39
+
40
+
41
+ class _CacheListVars:
42
+ def __init__(self):
43
+ self._saved = {}
44
+
45
+ def get(self, inst):
46
+ got = self._saved.get(inst)
47
+ if got is None:
48
+ self._saved[inst] = got = inst.list_vars()
49
+ return got
50
+
51
+
52
+ def _run_ssa(blocks):
53
+ """Run SSA reconstruction on IR blocks of a function."""
54
+ if not blocks:
55
+ # Empty blocks?
56
+ return {}
57
+ # Run CFG on the blocks
58
+ cfg = compute_cfg_from_blocks(blocks)
59
+ df_plus = _iterated_domfronts(cfg)
60
+ # Find SSA violators
61
+ violators = _find_defs_violators(blocks, cfg)
62
+ # Make cache for .list_vars()
63
+ cache_list_vars = _CacheListVars()
64
+
65
+ # Process one SSA-violating variable at a time
66
+ for varname in violators:
67
+ _logger.debug(
68
+ "Fix SSA violator on var %s",
69
+ varname,
70
+ )
71
+ # Fix up the LHS
72
+ # Put fresh variables for all assignments to the variable
73
+ blocks, defmap = _fresh_vars(blocks, varname)
74
+ _logger.debug("Replaced assignments: %s", _lazy_pformat(defmap))
75
+ # Fix up the RHS
76
+ # Re-associate the variable uses with the reaching definition
77
+ blocks = _fix_ssa_vars(
78
+ blocks, varname, defmap, cfg, df_plus, cache_list_vars
79
+ )
80
+
81
+ # Post-condition checks.
82
+ # CFG invariant
83
+ cfg_post = compute_cfg_from_blocks(blocks)
84
+ if cfg_post != cfg:
85
+ raise errors.CompilerError("CFG mutated in SSA pass")
86
+ return blocks
87
+
88
+
89
+ def _fix_ssa_vars(blocks, varname, defmap, cfg, df_plus, cache_list_vars):
90
+ """Rewrite all uses to ``varname`` given the definition map"""
91
+ states = _make_states(blocks)
92
+ states["varname"] = varname
93
+ states["defmap"] = defmap
94
+ states["phimap"] = phimap = defaultdict(list)
95
+ states["cfg"] = cfg
96
+ states["phi_locations"] = _compute_phi_locations(df_plus, defmap)
97
+ newblocks = _run_block_rewrite(blocks, states, _FixSSAVars(cache_list_vars))
98
+ # insert phi nodes
99
+ for label, philist in phimap.items():
100
+ curblk = newblocks[label]
101
+ # Prepend PHI nodes to the block
102
+ curblk.body = philist + curblk.body
103
+ return newblocks
104
+
105
+
106
+ def _iterated_domfronts(cfg):
107
+ """Compute the iterated dominance frontiers (DF+ in literatures).
108
+
109
+ Returns a dictionary which maps block label to the set of labels of its
110
+ iterated dominance frontiers.
111
+ """
112
+ domfronts = {k: set(vs) for k, vs in cfg.dominance_frontier().items()}
113
+ keep_going = True
114
+ while keep_going:
115
+ keep_going = False
116
+ for k, vs in domfronts.items():
117
+ inner = reduce(operator.or_, [domfronts[v] for v in vs], set())
118
+ if inner.difference(vs):
119
+ vs |= inner
120
+ keep_going = True
121
+ return domfronts
122
+
123
+
124
+ def _compute_phi_locations(iterated_df, defmap):
125
+ # See basic algorithm in Ch 4.1 in Inria SSA Book
126
+ # Compute DF+(defs)
127
+ # DF of all DFs is the union of all DFs
128
+ phi_locations = set()
129
+ for deflabel, defstmts in defmap.items():
130
+ if defstmts:
131
+ phi_locations |= iterated_df[deflabel]
132
+ return phi_locations
133
+
134
+
135
+ def _fresh_vars(blocks, varname):
136
+ """Rewrite to put fresh variable names"""
137
+ states = _make_states(blocks)
138
+ states["varname"] = varname
139
+ states["defmap"] = defmap = defaultdict(list)
140
+ newblocks = _run_block_rewrite(blocks, states, _FreshVarHandler())
141
+ return newblocks, defmap
142
+
143
+
144
+ def _get_scope(blocks):
145
+ first, *_ = blocks.values()
146
+ return first.scope
147
+
148
+
149
+ def _find_defs_violators(blocks, cfg):
150
+ """
151
+ Returns
152
+ -------
153
+ res : Set[str]
154
+ The SSA violators in a dictionary of variable names.
155
+ """
156
+ defs = defaultdict(list)
157
+ uses = defaultdict(set)
158
+ states = dict(defs=defs, uses=uses)
159
+ _run_block_analysis(blocks, states, _GatherDefsHandler())
160
+ _logger.debug("defs %s", _lazy_pformat(defs))
161
+ # Gather violators by number of definitions.
162
+ # The violators are added by the order that they are seen and the algorithm
163
+ # scan from the first to the last basic-block as they occur in bytecode.
164
+ violators = {k: None for k, vs in defs.items() if len(vs) > 1}
165
+ # Gather violators by uses not dominated by the one def
166
+ doms = cfg.dominators()
167
+ for k, use_blocks in uses.items():
168
+ if k not in violators:
169
+ for label in use_blocks:
170
+ dom = doms[label]
171
+ def_labels = {label for _assign, label in defs[k]}
172
+ if not def_labels.intersection(dom):
173
+ violators[k] = None
174
+ break
175
+ _logger.debug("SSA violators %s", _lazy_pformat(list(violators)))
176
+ return violators
177
+
178
+
179
+ def _run_block_analysis(blocks, states, handler):
180
+ for label, blk in blocks.items():
181
+ _logger.debug("==== SSA block analysis pass on %s", label)
182
+ states["label"] = label
183
+ for _ in _run_ssa_block_pass(states, blk, handler):
184
+ pass
185
+
186
+
187
+ def _run_block_rewrite(blocks, states, handler):
188
+ newblocks = {}
189
+ for label, blk in blocks.items():
190
+ _logger.debug("==== SSA block rewrite pass on %s", label)
191
+ newblk = ir.Block(scope=blk.scope, loc=blk.loc)
192
+
193
+ newbody = []
194
+ states["label"] = label
195
+ states["block"] = blk
196
+ for stmt in _run_ssa_block_pass(states, blk, handler):
197
+ assert stmt is not None
198
+ newbody.append(stmt)
199
+ newblk.body = newbody
200
+ newblocks[label] = newblk
201
+ return newblocks
202
+
203
+
204
+ def _make_states(blocks):
205
+ return dict(
206
+ scope=_get_scope(blocks),
207
+ )
208
+
209
+
210
+ def _run_ssa_block_pass(states, blk, handler):
211
+ _logger.debug("Running %s", handler)
212
+ for stmt in blk.body:
213
+ _logger.debug("on stmt: %s", stmt)
214
+ if isinstance(stmt, ir.Assign):
215
+ ret = handler.on_assign(states, stmt)
216
+ else:
217
+ ret = handler.on_other(states, stmt)
218
+ if ret is not stmt and ret is not None:
219
+ _logger.debug("replaced with: %s", ret)
220
+ yield ret
221
+
222
+
223
+ class _BaseHandler:
224
+ """A base handler for all the passes used here for the SSA algorithm."""
225
+
226
+ def on_assign(self, states, assign):
227
+ """
228
+ Called when the pass sees an ``ir.Assign``.
229
+
230
+ Subclasses should override this for custom behavior
231
+
232
+ Parameters
233
+ -----------
234
+ states : dict
235
+ assign : numba.ir.Assign
236
+
237
+ Returns
238
+ -------
239
+ stmt : numba.ir.Assign or None
240
+ For rewrite passes, the return value is used as the replacement
241
+ for the given statement.
242
+ """
243
+
244
+ def on_other(self, states, stmt):
245
+ """
246
+ Called when the pass sees an ``ir.Stmt`` that's not an assignment.
247
+
248
+ Subclasses should override this for custom behavior
249
+
250
+ Parameters
251
+ -----------
252
+ states : dict
253
+ assign : numba.ir.Stmt
254
+
255
+ Returns
256
+ -------
257
+ stmt : numba.ir.Stmt or None
258
+ For rewrite passes, the return value is used as the replacement
259
+ for the given statement.
260
+ """
261
+
262
+
263
+ class _GatherDefsHandler(_BaseHandler):
264
+ """Find all defs and uses of variable in each block
265
+
266
+ ``states["label"]`` is a int; label of the current block
267
+ ``states["defs"]`` is a Mapping[str, List[Tuple[ir.Assign, int]]]:
268
+ - a mapping of the name of the assignee variable to the assignment
269
+ IR node and the block label.
270
+ ``states["uses"]`` is a Mapping[Set[int]]
271
+ """
272
+
273
+ def on_assign(self, states, assign):
274
+ # keep track of assignment and the block
275
+ states["defs"][assign.target.name].append((assign, states["label"]))
276
+ # keep track of uses
277
+ for var in assign.list_vars():
278
+ k = var.name
279
+ if k != assign.target.name:
280
+ states["uses"][k].add(states["label"])
281
+
282
+ def on_other(self, states, stmt):
283
+ # keep track of uses
284
+ for var in stmt.list_vars():
285
+ k = var.name
286
+ states["uses"][k].add(states["label"])
287
+
288
+
289
+ class UndefinedVariable:
290
+ def __init__(self):
291
+ raise NotImplementedError("Not intended for instantiation")
292
+
293
+ target = ir.UNDEFINED
294
+
295
+
296
+ class _FreshVarHandler(_BaseHandler):
297
+ """Replaces assignment target with new fresh variables."""
298
+
299
+ def on_assign(self, states, assign):
300
+ if assign.target.name == states["varname"]:
301
+ scope = states["scope"]
302
+ defmap = states["defmap"]
303
+ # Allow first assignment to retain the name
304
+ if len(defmap) == 0:
305
+ newtarget = assign.target
306
+ _logger.debug("first assign: %s", newtarget)
307
+ if newtarget.name not in scope.localvars:
308
+ wmsg = f"variable {newtarget.name!r} is not in scope."
309
+ warnings.warn(
310
+ errors.NumbaIRAssumptionWarning(wmsg, loc=assign.loc)
311
+ )
312
+ else:
313
+ newtarget = scope.redefine(assign.target.name, loc=assign.loc)
314
+ assign = ir.Assign(
315
+ target=newtarget, value=assign.value, loc=assign.loc
316
+ )
317
+ defmap[states["label"]].append(assign)
318
+ return assign
319
+
320
+ def on_other(self, states, stmt):
321
+ return stmt
322
+
323
+
324
+ class _FixSSAVars(_BaseHandler):
325
+ """Replace variable uses in IR nodes to the correct reaching variable
326
+ and introduce Phi nodes if necessary. This class contains the core of
327
+ the SSA reconstruction algorithm.
328
+
329
+ See Ch 5 of the Inria SSA book for reference. The method names used here
330
+ are similar to the names used in the pseudocode in the book.
331
+ """
332
+
333
+ def __init__(self, cache_list_vars):
334
+ self._cache_list_vars = cache_list_vars
335
+
336
+ def on_assign(self, states, assign):
337
+ rhs = assign.value
338
+ if isinstance(rhs, ir.Inst):
339
+ newdef = self._fix_var(
340
+ states,
341
+ assign,
342
+ self._cache_list_vars.get(assign.value),
343
+ )
344
+ # Has a replacement that is not the current variable
345
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
346
+ if states["varname"] != newdef.target.name:
347
+ replmap = {states["varname"]: newdef.target}
348
+ rhs = copy(rhs)
349
+
350
+ ir_utils.replace_vars_inner(rhs, replmap)
351
+ return ir.Assign(
352
+ target=assign.target,
353
+ value=rhs,
354
+ loc=assign.loc,
355
+ )
356
+ elif isinstance(rhs, ir.Var):
357
+ newdef = self._fix_var(states, assign, [rhs])
358
+ # Has a replacement that is not the current variable
359
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
360
+ if states["varname"] != newdef.target.name:
361
+ return ir.Assign(
362
+ target=assign.target,
363
+ value=newdef.target,
364
+ loc=assign.loc,
365
+ )
366
+
367
+ return assign
368
+
369
+ def on_other(self, states, stmt):
370
+ newdef = self._fix_var(
371
+ states,
372
+ stmt,
373
+ self._cache_list_vars.get(stmt),
374
+ )
375
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
376
+ if states["varname"] != newdef.target.name:
377
+ replmap = {states["varname"]: newdef.target}
378
+ stmt = copy(stmt)
379
+ ir_utils.replace_vars_stmt(stmt, replmap)
380
+ return stmt
381
+
382
+ def _fix_var(self, states, stmt, used_vars):
383
+ """Fix all variable uses in ``used_vars``."""
384
+ varnames = [k.name for k in used_vars]
385
+ phivar = states["varname"]
386
+ if phivar in varnames:
387
+ return self._find_def(states, stmt)
388
+
389
+ def _find_def(self, states, stmt):
390
+ """Find definition of ``stmt`` for the statement ``stmt``"""
391
+ _logger.debug("find_def var=%r stmt=%s", states["varname"], stmt)
392
+ selected_def = None
393
+ label = states["label"]
394
+ local_defs = states["defmap"][label]
395
+ local_phis = states["phimap"][label]
396
+ block = states["block"]
397
+
398
+ cur_pos = self._stmt_index(stmt, block)
399
+ for defstmt in reversed(local_defs):
400
+ # Phi nodes have no index
401
+ def_pos = self._stmt_index(defstmt, block, stop=cur_pos)
402
+ if def_pos < cur_pos:
403
+ selected_def = defstmt
404
+ break
405
+ # Maybe it's a PHI
406
+ elif defstmt in local_phis:
407
+ selected_def = local_phis[-1]
408
+ break
409
+
410
+ if selected_def is None:
411
+ selected_def = self._find_def_from_top(
412
+ states,
413
+ label,
414
+ loc=stmt.loc,
415
+ )
416
+ return selected_def
417
+
418
+ def _find_def_from_top(self, states, label, loc):
419
+ """Find definition reaching block of ``label``.
420
+
421
+ This method would look at all dominance frontiers.
422
+ Insert phi node if necessary.
423
+ """
424
+ _logger.debug("find_def_from_top label %r", label)
425
+ cfg = states["cfg"]
426
+ defmap = states["defmap"]
427
+ phimap = states["phimap"]
428
+ phi_locations = states["phi_locations"]
429
+
430
+ if label in phi_locations:
431
+ scope = states["scope"]
432
+ loc = states["block"].loc
433
+ # fresh variable
434
+ freshvar = scope.redefine(states["varname"], loc=loc)
435
+ # insert phi
436
+ phinode = ir.Assign(
437
+ target=freshvar,
438
+ value=ir.Expr.phi(loc=loc),
439
+ loc=loc,
440
+ )
441
+ _logger.debug("insert phi node %s at %s", phinode, label)
442
+ defmap[label].insert(0, phinode)
443
+ phimap[label].append(phinode)
444
+ # Find incoming values for the Phi node
445
+ for pred, _ in cfg.predecessors(label):
446
+ incoming_def = self._find_def_from_bottom(
447
+ states,
448
+ pred,
449
+ loc=loc,
450
+ )
451
+ _logger.debug("incoming_def %s", incoming_def)
452
+ phinode.value.incoming_values.append(incoming_def.target)
453
+ phinode.value.incoming_blocks.append(pred)
454
+ return phinode
455
+ else:
456
+ idom = cfg.immediate_dominators()[label]
457
+ if idom == label:
458
+ # We have searched to the top of the idom tree.
459
+ # Since we still cannot find a definition,
460
+ # we will warn.
461
+ _warn_about_uninitialized_variable(states["varname"], loc)
462
+ return UndefinedVariable
463
+ _logger.debug("idom %s from label %s", idom, label)
464
+ return self._find_def_from_bottom(states, idom, loc=loc)
465
+
466
+ def _find_def_from_bottom(self, states, label, loc):
467
+ """Find definition from within the block at ``label``."""
468
+ _logger.debug("find_def_from_bottom label %r", label)
469
+ defmap = states["defmap"]
470
+ defs = defmap[label]
471
+ if defs:
472
+ lastdef = defs[-1]
473
+ return lastdef
474
+ else:
475
+ return self._find_def_from_top(states, label, loc=loc)
476
+
477
+ def _stmt_index(self, defstmt, block, stop=-1):
478
+ """Find the positional index of the statement at ``block``.
479
+
480
+ Assumptions:
481
+ - no two statements can point to the same object.
482
+ """
483
+ # Compare using id() as IR node equality is for semantic equivalence
484
+ # opposed to direct equality (the location and scope are not considered
485
+ # as part of the equality measure, this is important here).
486
+ for i in range(len(block.body))[:stop]:
487
+ if block.body[i] is defstmt:
488
+ return i
489
+ return len(block.body)
490
+
491
+
492
+ def _warn_about_uninitialized_variable(varname, loc):
493
+ if config.ALWAYS_WARN_UNINIT_VAR:
494
+ warnings.warn(
495
+ errors.NumbaWarning(
496
+ f"Detected uninitialized variable {varname}", loc=loc
497
+ ),
498
+ )