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,728 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ from collections import namedtuple, OrderedDict
5
+ import dis
6
+ import inspect
7
+ import itertools
8
+
9
+ from types import CodeType, ModuleType
10
+
11
+ from numba.cuda.core import errors
12
+ from numba.cuda import serialize
13
+ from numba.cuda import utils
14
+ from numba.cuda.utils import PYVERSION
15
+
16
+
17
+ if PYVERSION in ((3, 12), (3, 13)):
18
+ from opcode import _inline_cache_entries
19
+
20
+ # Instruction/opcode length in bytes
21
+ INSTR_LEN = 2
22
+ elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
23
+ pass
24
+ else:
25
+ raise NotImplementedError(PYVERSION)
26
+
27
+
28
+ opcode_info = namedtuple("opcode_info", ["argsize"])
29
+ _ExceptionTableEntry = namedtuple(
30
+ "_ExceptionTableEntry", "start end target depth lasti"
31
+ )
32
+
33
+ # The following offset is used as a hack to inject a NOP at the start of the
34
+ # bytecode. So that function starting with `while True` will not have block-0
35
+ # as a jump target. The Lowerer puts argument initialization at block-0.
36
+ _FIXED_OFFSET = 2
37
+
38
+
39
+ def get_function_object(obj):
40
+ """
41
+ Objects that wraps function should provide a "__numba__" magic attribute
42
+ that contains a name of an attribute that contains the actual python
43
+ function object.
44
+ """
45
+ attr = getattr(obj, "__numba__", None)
46
+ if attr:
47
+ return getattr(obj, attr)
48
+ return obj
49
+
50
+
51
+ def get_code_object(obj):
52
+ "Shamelessly borrowed from llpython"
53
+ return getattr(obj, "__code__", getattr(obj, "func_code", None))
54
+
55
+
56
+ def _as_opcodes(seq):
57
+ lst = []
58
+ for s in seq:
59
+ c = dis.opmap.get(s)
60
+ if c is not None:
61
+ lst.append(c)
62
+ return lst
63
+
64
+
65
+ JREL_OPS = frozenset(dis.hasjrel)
66
+ JABS_OPS = frozenset(dis.hasjabs)
67
+ JUMP_OPS = JREL_OPS | JABS_OPS
68
+ TERM_OPS = frozenset(_as_opcodes(["RETURN_VALUE", "RAISE_VARARGS"]))
69
+ EXTENDED_ARG = dis.EXTENDED_ARG
70
+ HAVE_ARGUMENT = dis.HAVE_ARGUMENT
71
+
72
+
73
+ class ByteCodeInst(object):
74
+ """
75
+ Attributes
76
+ ----------
77
+ - offset:
78
+ byte offset of opcode
79
+ - opcode:
80
+ opcode integer value
81
+ - arg:
82
+ instruction arg
83
+ - lineno:
84
+ -1 means unknown
85
+ """
86
+
87
+ __slots__ = "offset", "next", "opcode", "opname", "arg", "lineno"
88
+
89
+ def __init__(self, offset, opcode, arg, nextoffset):
90
+ self.offset = offset
91
+ self.next = nextoffset
92
+ self.opcode = opcode
93
+ self.opname = dis.opname[opcode]
94
+ self.arg = arg
95
+ self.lineno = -1 # unknown line number
96
+
97
+ @property
98
+ def is_jump(self):
99
+ return self.opcode in JUMP_OPS
100
+
101
+ @property
102
+ def is_terminator(self):
103
+ return self.opcode in TERM_OPS
104
+
105
+ def get_jump_target(self):
106
+ # With Python 3.10 the addressing of "bytecode" instructions has
107
+ # changed from using bytes to using 16-bit words instead. As a
108
+ # consequence the code to determine where a jump will lead had to be
109
+ # adapted.
110
+ # See also:
111
+ # https://bugs.python.org/issue26647
112
+ # https://bugs.python.org/issue27129
113
+ # https://github.com/python/cpython/pull/25069
114
+ assert self.is_jump
115
+ if PYVERSION in ((3, 13),):
116
+ if self.opcode in (
117
+ dis.opmap[k]
118
+ for k in ["JUMP_BACKWARD", "JUMP_BACKWARD_NO_INTERRUPT"]
119
+ ):
120
+ return self.next - (self.arg * 2)
121
+ elif PYVERSION in ((3, 12),):
122
+ if self.opcode in (dis.opmap[k] for k in ["JUMP_BACKWARD"]):
123
+ return self.offset - (self.arg - 1) * 2
124
+ elif PYVERSION in ((3, 11),):
125
+ if self.opcode in (
126
+ dis.opmap[k]
127
+ for k in (
128
+ "JUMP_BACKWARD",
129
+ "POP_JUMP_BACKWARD_IF_TRUE",
130
+ "POP_JUMP_BACKWARD_IF_FALSE",
131
+ "POP_JUMP_BACKWARD_IF_NONE",
132
+ "POP_JUMP_BACKWARD_IF_NOT_NONE",
133
+ )
134
+ ):
135
+ return self.offset - (self.arg - 1) * 2
136
+ elif PYVERSION in (
137
+ (3, 9),
138
+ (3, 10),
139
+ ):
140
+ pass
141
+ else:
142
+ raise NotImplementedError(PYVERSION)
143
+
144
+ if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)):
145
+ if self.opcode in JREL_OPS:
146
+ return self.next + self.arg * 2
147
+ else:
148
+ assert self.opcode in JABS_OPS
149
+ return self.arg * 2 - 2
150
+ elif PYVERSION in ((3, 9),):
151
+ if self.opcode in JREL_OPS:
152
+ return self.next + self.arg
153
+ else:
154
+ assert self.opcode in JABS_OPS
155
+ return self.arg
156
+ else:
157
+ raise NotImplementedError(PYVERSION)
158
+
159
+ def __repr__(self):
160
+ return "%s(arg=%s, lineno=%d)" % (self.opname, self.arg, self.lineno)
161
+
162
+ @property
163
+ def block_effect(self):
164
+ """Effect of the block stack
165
+ Returns +1 (push), 0 (none) or -1 (pop)
166
+ """
167
+ if self.opname.startswith("SETUP_"):
168
+ return 1
169
+ elif self.opname == "POP_BLOCK":
170
+ return -1
171
+ else:
172
+ return 0
173
+
174
+
175
+ CODE_LEN = 1
176
+ ARG_LEN = 1
177
+ NO_ARG_LEN = 1
178
+
179
+ OPCODE_NOP = dis.opname.index("NOP")
180
+
181
+
182
+ if PYVERSION in ((3, 13),):
183
+
184
+ def _unpack_opargs(code):
185
+ buf = []
186
+ for i, start_offset, op, arg in dis._unpack_opargs(code):
187
+ buf.append((start_offset, op, arg))
188
+ for i, (start_offset, op, arg) in enumerate(buf):
189
+ if i + 1 < len(buf):
190
+ next_offset = buf[i + 1][0]
191
+ else:
192
+ next_offset = len(code)
193
+ yield (start_offset, op, arg, next_offset)
194
+
195
+ elif PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12)):
196
+ # Adapted from Lib/dis.py
197
+ def _unpack_opargs(code):
198
+ """
199
+ Returns a 4-int-tuple of
200
+ (bytecode offset, opcode, argument, offset of next bytecode).
201
+ """
202
+ extended_arg = 0
203
+ n = len(code)
204
+ offset = i = 0
205
+ while i < n:
206
+ op = code[i]
207
+ i += CODE_LEN
208
+ if op >= HAVE_ARGUMENT:
209
+ arg = code[i] | extended_arg
210
+ for j in range(ARG_LEN):
211
+ arg |= code[i + j] << (8 * j)
212
+ i += ARG_LEN
213
+ if PYVERSION in ((3, 12),):
214
+ # Python 3.12 introduced cache slots. We need to account for
215
+ # cache slots when we determine the offset of the next
216
+ # opcode. The number of cache slots is specific to each
217
+ # opcode and can be looked up in the _inline_cache_entries
218
+ # dictionary.
219
+ i += _inline_cache_entries[op] * INSTR_LEN
220
+ elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
221
+ pass
222
+ else:
223
+ raise NotImplementedError(PYVERSION)
224
+ if op == EXTENDED_ARG:
225
+ # This is a deviation from what dis does...
226
+ # In python 3.11 it seems like EXTENDED_ARGs appear more
227
+ # often and are also used as jump targets. So as to not have
228
+ # to do "book keeping" for where EXTENDED_ARGs have been
229
+ # "skipped" they are replaced with NOPs so as to provide a
230
+ # legal jump target and also ensure that the bytecode
231
+ # offsets are correct.
232
+ yield (offset, OPCODE_NOP, arg, i)
233
+ extended_arg = arg << 8 * ARG_LEN
234
+ offset = i
235
+ continue
236
+ else:
237
+ arg = None
238
+ i += NO_ARG_LEN
239
+ if PYVERSION in ((3, 12),):
240
+ # Python 3.12 introduced cache slots. We need to account for
241
+ # cache slots when we determine the offset of the next
242
+ # opcode. The number of cache slots is specific to each
243
+ # opcode and can be looked up in the _inline_cache_entries
244
+ # dictionary.
245
+ i += _inline_cache_entries[op] * INSTR_LEN
246
+ elif PYVERSION in ((3, 9), (3, 10), (3, 11)):
247
+ pass
248
+ else:
249
+ raise NotImplementedError(PYVERSION)
250
+
251
+ extended_arg = 0
252
+ yield (offset, op, arg, i)
253
+ offset = i # Mark inst offset at first extended
254
+ else:
255
+ raise NotImplementedError(PYVERSION)
256
+
257
+
258
+ def _patched_opargs(bc_stream):
259
+ """Patch the bytecode stream.
260
+
261
+ - Adds a NOP bytecode at the start to avoid jump target being at the entry.
262
+ """
263
+ # Injected NOP
264
+ yield (0, OPCODE_NOP, None, _FIXED_OFFSET)
265
+ # Adjust bytecode offset for the rest of the stream
266
+ for offset, opcode, arg, nextoffset in bc_stream:
267
+ # If the opcode has an absolute jump target, adjust it.
268
+ if opcode in JABS_OPS:
269
+ arg += _FIXED_OFFSET
270
+ yield offset + _FIXED_OFFSET, opcode, arg, nextoffset + _FIXED_OFFSET
271
+
272
+
273
+ class ByteCodeIter(object):
274
+ def __init__(self, code):
275
+ self.code = code
276
+ self.iter = iter(_patched_opargs(_unpack_opargs(self.code.co_code)))
277
+
278
+ def __iter__(self):
279
+ return self
280
+
281
+ def _fetch_opcode(self):
282
+ return next(self.iter)
283
+
284
+ def next(self):
285
+ offset, opcode, arg, nextoffset = self._fetch_opcode()
286
+ return offset, ByteCodeInst(
287
+ offset=offset, opcode=opcode, arg=arg, nextoffset=nextoffset
288
+ )
289
+
290
+ __next__ = next
291
+
292
+ def read_arg(self, size):
293
+ buf = 0
294
+ for i in range(size):
295
+ _offset, byte = next(self.iter)
296
+ buf |= byte << (8 * i)
297
+ return buf
298
+
299
+
300
+ class _ByteCode(object):
301
+ """
302
+ The decoded bytecode of a function, and related information.
303
+ """
304
+
305
+ __slots__ = (
306
+ "func_id",
307
+ "co_names",
308
+ "co_varnames",
309
+ "co_consts",
310
+ "co_cellvars",
311
+ "co_freevars",
312
+ "exception_entries",
313
+ "table",
314
+ "labels",
315
+ )
316
+
317
+ def __init__(self, func_id):
318
+ code = func_id.code
319
+
320
+ labels = set(x + _FIXED_OFFSET for x in dis.findlabels(code.co_code))
321
+ labels.add(0)
322
+
323
+ # A map of {offset: ByteCodeInst}
324
+ table = OrderedDict(ByteCodeIter(code))
325
+ self._compute_lineno(table, code)
326
+
327
+ self.func_id = func_id
328
+ self.co_names = code.co_names
329
+ self.co_varnames = code.co_varnames
330
+ self.co_consts = code.co_consts
331
+ self.co_cellvars = code.co_cellvars
332
+ self.co_freevars = code.co_freevars
333
+
334
+ self.table = table
335
+ self.labels = sorted(labels)
336
+
337
+ @classmethod
338
+ def _compute_lineno(cls, table, code):
339
+ """
340
+ Compute the line numbers for all bytecode instructions.
341
+ """
342
+ for offset, lineno in dis.findlinestarts(code):
343
+ adj_offset = offset + _FIXED_OFFSET
344
+ if adj_offset in table:
345
+ table[adj_offset].lineno = lineno
346
+ # Assign unfilled lineno
347
+ # Start with first bytecode's lineno
348
+ known = code.co_firstlineno
349
+ for inst in table.values():
350
+ if inst.lineno is not None and inst.lineno >= 0:
351
+ known = inst.lineno
352
+ else:
353
+ inst.lineno = known
354
+ return table
355
+
356
+ def __iter__(self):
357
+ return iter(self.table.values())
358
+
359
+ def __getitem__(self, offset):
360
+ return self.table[offset]
361
+
362
+ def __contains__(self, offset):
363
+ return offset in self.table
364
+
365
+ def dump(self):
366
+ def label_marker(i):
367
+ if i[1].offset in self.labels:
368
+ return ">"
369
+ else:
370
+ return " "
371
+
372
+ return "\n".join(
373
+ "%s %10s\t%s" % ((label_marker(i),) + i)
374
+ for i in self.table.items()
375
+ if i[1].opname != "CACHE"
376
+ )
377
+
378
+ @classmethod
379
+ def _compute_used_globals(cls, func, table, co_consts, co_names):
380
+ """
381
+ Compute the globals used by the function with the given
382
+ bytecode table.
383
+ """
384
+ d = {}
385
+ globs = func.__globals__
386
+ builtins = globs.get("__builtins__", utils.builtins)
387
+ if isinstance(builtins, ModuleType):
388
+ builtins = builtins.__dict__
389
+ # Look for LOAD_GLOBALs in the bytecode
390
+ for inst in table.values():
391
+ if inst.opname == "LOAD_GLOBAL":
392
+ name = co_names[_fix_LOAD_GLOBAL_arg(inst.arg)]
393
+ if name not in d:
394
+ try:
395
+ value = globs[name]
396
+ except KeyError:
397
+ value = builtins[name]
398
+ d[name] = value
399
+ # Add globals used by any nested code object
400
+ for co in co_consts:
401
+ if isinstance(co, CodeType):
402
+ subtable = OrderedDict(ByteCodeIter(co))
403
+ d.update(
404
+ cls._compute_used_globals(
405
+ func, subtable, co.co_consts, co.co_names
406
+ )
407
+ )
408
+ return d
409
+
410
+ def get_used_globals(self):
411
+ """
412
+ Get a {name: value} map of the globals used by this code
413
+ object and any nested code objects.
414
+ """
415
+ return self._compute_used_globals(
416
+ self.func_id.func, self.table, self.co_consts, self.co_names
417
+ )
418
+
419
+
420
+ def _fix_LOAD_GLOBAL_arg(arg):
421
+ if PYVERSION in ((3, 11), (3, 12), (3, 13)):
422
+ return arg >> 1
423
+ elif PYVERSION in (
424
+ (3, 9),
425
+ (3, 10),
426
+ ):
427
+ return arg
428
+ else:
429
+ raise NotImplementedError(PYVERSION)
430
+
431
+
432
+ class ByteCodePy311(_ByteCode):
433
+ def __init__(self, func_id):
434
+ super().__init__(func_id)
435
+ entries = dis.Bytecode(func_id.code).exception_entries
436
+ self.exception_entries = tuple(map(self.fixup_eh, entries))
437
+
438
+ @staticmethod
439
+ def fixup_eh(ent):
440
+ # Patch up the exception table offset
441
+ # because we add a NOP in _patched_opargs
442
+ out = dis._ExceptionTableEntry(
443
+ start=ent.start + _FIXED_OFFSET,
444
+ end=ent.end + _FIXED_OFFSET,
445
+ target=ent.target + _FIXED_OFFSET,
446
+ depth=ent.depth,
447
+ lasti=ent.lasti,
448
+ )
449
+ return out
450
+
451
+ def find_exception_entry(self, offset):
452
+ """
453
+ Returns the exception entry for the given instruction offset
454
+ """
455
+ candidates = []
456
+ for ent in self.exception_entries:
457
+ if ent.start <= offset < ent.end:
458
+ candidates.append((ent.depth, ent))
459
+ if candidates:
460
+ ent = max(candidates)[1]
461
+ return ent
462
+
463
+
464
+ class ByteCodePy312(ByteCodePy311):
465
+ def __init__(self, func_id):
466
+ super().__init__(func_id)
467
+
468
+ # initialize lazy property
469
+ self._ordered_offsets = None
470
+
471
+ # Fixup offsets for all exception entries.
472
+ entries = [
473
+ self.fixup_eh(e)
474
+ for e in dis.Bytecode(func_id.code).exception_entries
475
+ ]
476
+
477
+ # Remove exceptions, innermost ones first
478
+ # Can be done by using a stack
479
+ entries = self.remove_build_list_swap_pattern(entries)
480
+
481
+ # If this is a generator, we need to skip any exception table entries
482
+ # that point to the exception handler with the highest offset.
483
+ if func_id.is_generator:
484
+ # Get the exception handler with the highest offset.
485
+ max_exception_target = max([e.target for e in entries])
486
+ # Remove any exception table entries that point to that exception
487
+ # handler.
488
+ entries = [e for e in entries if e.target != max_exception_target]
489
+
490
+ self.exception_entries = tuple(entries)
491
+
492
+ @property
493
+ def ordered_offsets(self):
494
+ if not self._ordered_offsets:
495
+ # Get an ordered list of offsets.
496
+ self._ordered_offsets = [o for o in self.table]
497
+ return self._ordered_offsets
498
+
499
+ def remove_build_list_swap_pattern(self, entries):
500
+ """Find the following bytecode pattern:
501
+
502
+ BUILD_{LIST, MAP, SET}
503
+ SWAP(2)
504
+ FOR_ITER
505
+ ...
506
+ END_FOR
507
+ SWAP(2)
508
+
509
+ This pattern indicates that a list/dict/set comprehension has
510
+ been inlined. In this case we can skip the exception blocks
511
+ entirely along with the dead exceptions that it points to.
512
+ A pair of exception that sandwiches these exception will
513
+ also be merged into a single exception.
514
+
515
+ Update for Python 3.13, the ending of the pattern has a extra
516
+ POP_TOP:
517
+
518
+ ...
519
+ END_FOR
520
+ POP_TOP
521
+ SWAP(2)
522
+
523
+ Update for Python 3.13.1, there's now a GET_ITER before FOR_ITER.
524
+ This patch the GET_ITER to NOP to minimize changes downstream
525
+ (e.g. array-comprehension).
526
+ """
527
+
528
+ def pop_and_merge_exceptions(
529
+ entries: list, entry_to_remove: _ExceptionTableEntry
530
+ ):
531
+ lower_entry_idx = entries.index(entry_to_remove) - 1
532
+ upper_entry_idx = entries.index(entry_to_remove) + 1
533
+
534
+ # Merge the upper and lower exceptions if possible.
535
+ if lower_entry_idx >= 0 and upper_entry_idx < len(entries):
536
+ lower_entry = entries[lower_entry_idx]
537
+ upper_entry = entries[upper_entry_idx]
538
+ if lower_entry.target == upper_entry.target:
539
+ entries[lower_entry_idx] = _ExceptionTableEntry(
540
+ lower_entry.start,
541
+ upper_entry.end,
542
+ lower_entry.target,
543
+ lower_entry.depth,
544
+ upper_entry.lasti,
545
+ )
546
+ entries.remove(upper_entry)
547
+
548
+ # Remove the exception entry.
549
+ entries.remove(entry_to_remove)
550
+ # Remove dead exceptions, if any, that the entry above may point to.
551
+ entries = [
552
+ e for e in entries if not e.start == entry_to_remove.target
553
+ ]
554
+ return entries
555
+
556
+ change_to_nop = set()
557
+ work_remaining = True
558
+ while work_remaining:
559
+ # Temporarily set work_remaining to False, if we find a pattern
560
+ # then work is not complete, hence we set it again to True.
561
+ work_remaining = False
562
+ current_nop_fixes = set()
563
+ for entry in entries.copy():
564
+ # Check start of pattern, three instructions.
565
+ # Work out the index of the instruction.
566
+ index = self.ordered_offsets.index(entry.start)
567
+ # If there is a BUILD_{LIST, MAP, SET} instruction at this
568
+ # location.
569
+ curr_inst = self.table[self.ordered_offsets[index]]
570
+ if curr_inst.opname not in (
571
+ "BUILD_LIST",
572
+ "BUILD_MAP",
573
+ "BUILD_SET",
574
+ ):
575
+ continue
576
+ # Check if the BUILD_{LIST, MAP, SET} instruction is followed
577
+ # by a SWAP(2).
578
+ next_inst = self.table[self.ordered_offsets[index + 1]]
579
+ if not next_inst.opname == "SWAP" and next_inst.arg == 2:
580
+ continue
581
+ next_inst = self.table[self.ordered_offsets[index + 2]]
582
+ # Check if the SWAP is followed by a FOR_ITER
583
+ # BUT Python3.13.1 introduced an extra GET_ITER.
584
+ # If we see a GET_ITER here, check if the next thing is a
585
+ # FOR_ITER.
586
+ if next_inst.opname == "GET_ITER":
587
+ # Add the inst to potentially be replaced to NOP
588
+ current_nop_fixes.add(next_inst)
589
+ # Loop up next instruction.
590
+ next_inst = self.table[self.ordered_offsets[index + 3]]
591
+
592
+ if not next_inst.opname == "FOR_ITER":
593
+ continue
594
+
595
+ if PYVERSION in ((3, 13),):
596
+ # Check end of pattern, two instructions.
597
+ # Check for the corresponding END_FOR, exception table end
598
+ # is non-inclusive, so subtract one.
599
+ index = self.ordered_offsets.index(entry.end)
600
+ curr_inst = self.table[self.ordered_offsets[index - 2]]
601
+ if not curr_inst.opname == "END_FOR":
602
+ continue
603
+ next_inst = self.table[self.ordered_offsets[index - 1]]
604
+ if not next_inst.opname == "POP_TOP":
605
+ continue
606
+ # END_FOR must be followed by SWAP(2)
607
+ next_inst = self.table[self.ordered_offsets[index]]
608
+ if not next_inst.opname == "SWAP" and next_inst.arg == 2:
609
+ continue
610
+ elif PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12)):
611
+ # Check end of pattern, two instructions.
612
+ # Check for the corresponding END_FOR, exception table end
613
+ # is non-inclusive, so subtract one.
614
+ index = self.ordered_offsets.index(entry.end)
615
+ curr_inst = self.table[self.ordered_offsets[index - 1]]
616
+ if not curr_inst.opname == "END_FOR":
617
+ continue
618
+ # END_FOR must be followed by SWAP(2)
619
+ next_inst = self.table[self.ordered_offsets[index]]
620
+ if not next_inst.opname == "SWAP" and next_inst.arg == 2:
621
+ continue
622
+ else:
623
+ raise NotImplementedError(PYVERSION)
624
+ # If all conditions are met that means this exception entry
625
+ # is for a list/dict/set comprehension and can be removed.
626
+ # Also if there exist exception entries above and below this
627
+ # entry pointing to the same target. those can be merged into
628
+ # a single bigger exception block.
629
+ entries = pop_and_merge_exceptions(entries, entry)
630
+ work_remaining = True
631
+
632
+ # Commit NOP fixes since we confirmed the suspects belong to
633
+ # a comprehension code.
634
+ change_to_nop |= current_nop_fixes
635
+
636
+ # Complete fixes to NOPs
637
+ for inst in change_to_nop:
638
+ self.table[inst.offset] = ByteCodeInst(
639
+ inst.offset, dis.opmap["NOP"], None, inst.next
640
+ )
641
+ return entries
642
+
643
+
644
+ if PYVERSION == (3, 11):
645
+ ByteCode = ByteCodePy311
646
+ elif PYVERSION in (
647
+ (3, 12),
648
+ (3, 13),
649
+ ):
650
+ ByteCode = ByteCodePy312
651
+ elif PYVERSION < (3, 11):
652
+ ByteCode = _ByteCode
653
+ else:
654
+ raise NotImplementedError(PYVERSION)
655
+
656
+
657
+ class FunctionIdentity(serialize.ReduceMixin):
658
+ """
659
+ A function's identity and metadata.
660
+
661
+ Note this typically represents a function whose bytecode is
662
+ being compiled, not necessarily the top-level user function
663
+ (the two might be distinct).
664
+ """
665
+
666
+ _unique_ids = itertools.count(1)
667
+
668
+ @classmethod
669
+ def from_function(cls, pyfunc):
670
+ """
671
+ Create the FunctionIdentity of the given function.
672
+ """
673
+ func = get_function_object(pyfunc)
674
+ code = get_code_object(func)
675
+ pysig = utils.pysignature(func)
676
+ if not code:
677
+ raise errors.ByteCodeSupportError(
678
+ "%s does not provide its bytecode" % func
679
+ )
680
+
681
+ try:
682
+ func_qualname = func.__qualname__
683
+ except AttributeError:
684
+ func_qualname = func.__name__
685
+
686
+ self = cls()
687
+ self.func = func
688
+ self.func_qualname = func_qualname
689
+ self.func_name = func_qualname.split(".")[-1]
690
+ self.code = code
691
+ self.module = inspect.getmodule(func)
692
+ self.modname = (
693
+ utils._dynamic_modname
694
+ if self.module is None
695
+ else self.module.__name__
696
+ )
697
+ self.is_generator = inspect.isgeneratorfunction(func)
698
+ self.pysig = pysig
699
+ self.filename = code.co_filename
700
+ self.firstlineno = code.co_firstlineno
701
+ self.arg_count = len(pysig.parameters)
702
+ self.arg_names = list(pysig.parameters)
703
+
704
+ # Even the same function definition can be compiled into
705
+ # several different function objects with distinct closure
706
+ # variables, so we make sure to disambiguate using an unique id.
707
+ uid = next(cls._unique_ids)
708
+ self.unique_name = "{}${}".format(self.func_qualname, uid)
709
+ self.unique_id = uid
710
+
711
+ return self
712
+
713
+ def derive(self):
714
+ """Copy the object and increment the unique counter."""
715
+ return self.from_function(self.func)
716
+
717
+ def _reduce_states(self):
718
+ """
719
+ NOTE: part of ReduceMixin protocol
720
+ """
721
+ return dict(pyfunc=self.func)
722
+
723
+ @classmethod
724
+ def _rebuild(cls, pyfunc):
725
+ """
726
+ NOTE: part of ReduceMixin protocol
727
+ """
728
+ return cls.from_function(pyfunc)