numba-cuda 0.22.0__cp312-cp312-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.

Potentially problematic release.


This version of numba-cuda might be problematic. Click here for more details.

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-312-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-312-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-312-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-312-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-312-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,1812 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ from collections import defaultdict
5
+ import copy
6
+ import itertools
7
+ import os
8
+ import linecache
9
+ import pprint
10
+ import re
11
+ import sys
12
+ import operator
13
+ from types import FunctionType, BuiltinFunctionType
14
+ from functools import total_ordering
15
+ from io import StringIO
16
+
17
+ from numba.cuda import HAS_NUMBA
18
+
19
+ if HAS_NUMBA:
20
+ import numba
21
+ from numba.cuda.core import errors
22
+ from numba.cuda.core import config
23
+ from numba.cuda.utils import UNARY_BUILTINS_TO_OPERATORS, OPERATORS_TO_BUILTINS
24
+ from numba.cuda.core.errors import (
25
+ NotDefinedError,
26
+ RedefinedError,
27
+ VerificationError,
28
+ ConstantInferenceError,
29
+ )
30
+ from numba.cuda.core import consts
31
+
32
+ # terminal color markup
33
+ _termcolor = errors.termcolor()
34
+
35
+
36
+ class Loc(object):
37
+ """Source location"""
38
+
39
+ _defmatcher = re.compile(r"def\s+(\w+)")
40
+
41
+ def __init__(self, filename, line, col=None, maybe_decorator=False):
42
+ """Arguments:
43
+ filename - name of the file
44
+ line - line in file
45
+ col - column
46
+ maybe_decorator - Set to True if location is likely a jit decorator
47
+ """
48
+ self.filename = filename
49
+ self.line = line
50
+ self.col = col
51
+ self.lines = None # the source lines from the linecache
52
+ self.maybe_decorator = maybe_decorator
53
+
54
+ def __eq__(self, other):
55
+ # equivalence is solely based on filename, line and col
56
+ if type(self) is not type(other):
57
+ return False
58
+ if self.filename != other.filename:
59
+ return False
60
+ if self.line != other.line:
61
+ return False
62
+ if self.col != other.col:
63
+ return False
64
+ return True
65
+
66
+ def __ne__(self, other):
67
+ return not self.__eq__(other)
68
+
69
+ @classmethod
70
+ def from_function_id(cls, func_id):
71
+ return cls(func_id.filename, func_id.firstlineno, maybe_decorator=True)
72
+
73
+ def __repr__(self):
74
+ return "Loc(filename=%s, line=%s, col=%s)" % (
75
+ self.filename,
76
+ self.line,
77
+ self.col,
78
+ )
79
+
80
+ def __str__(self):
81
+ if self.col is not None:
82
+ return "%s (%s:%s)" % (self.filename, self.line, self.col)
83
+ else:
84
+ return "%s (%s)" % (self.filename, self.line)
85
+
86
+ def _find_definition(self):
87
+ # try and find a def, go backwards from error line
88
+ fn_name = None
89
+ lines = self.get_lines()
90
+ for x in reversed(lines[: self.line - 1]):
91
+ # the strip and startswith is to handle user code with commented out
92
+ # 'def' or use of 'def' in a docstring.
93
+ if x.strip().startswith("def "):
94
+ fn_name = x
95
+ break
96
+
97
+ return fn_name
98
+
99
+ def _raw_function_name(self):
100
+ defn = self._find_definition()
101
+ if defn:
102
+ m = self._defmatcher.match(defn.strip())
103
+ if m:
104
+ return m.groups()[0]
105
+ # Probably exec(<string>) or REPL.
106
+ return None
107
+
108
+ def get_lines(self):
109
+ if self.lines is None:
110
+ path = self._get_path()
111
+ # Avoid reading from dynamic string. They are most likely
112
+ # overridden. Problem started with Python 3.13. "<string>" seems
113
+ # to be something from multiprocessing.
114
+ lns = [] if path == "<string>" else linecache.getlines(path)
115
+ self.lines = lns
116
+ return self.lines
117
+
118
+ def _get_path(self):
119
+ path = None
120
+ try:
121
+ # Try to get a relative path
122
+ # ipython/jupyter input just returns as self.filename
123
+ path = os.path.relpath(self.filename)
124
+ except ValueError:
125
+ # Fallback to absolute path if error occurred in getting the
126
+ # relative path.
127
+ # This may happen on windows if the drive is different
128
+ path = os.path.abspath(self.filename)
129
+ return path
130
+
131
+ def strformat(self, nlines_up=2):
132
+ lines = self.get_lines()
133
+
134
+ use_line = self.line
135
+
136
+ if self.maybe_decorator:
137
+ # try and sort out a better `loc`, if it's suspected that this loc
138
+ # points at a jit decorator by virtue of
139
+ # `__code__.co_firstlineno`
140
+
141
+ # get lines, add a dummy entry at the start as lines count from
142
+ # 1 but list index counts from 0
143
+ tmplines = [""] + lines
144
+
145
+ if lines and use_line and "def " not in tmplines[use_line]:
146
+ # look forward 10 lines, unlikely anyone managed to stretch
147
+ # a jit call declaration over >10 lines?!
148
+ min_line = max(0, use_line)
149
+ max_line = use_line + 10
150
+ selected = tmplines[min_line:max_line]
151
+ index = 0
152
+ for idx, x in enumerate(selected):
153
+ if "def " in x:
154
+ index = idx
155
+ break
156
+ use_line = use_line + index
157
+
158
+ ret = [] # accumulates output
159
+ if lines and use_line > 0:
160
+
161
+ def count_spaces(string):
162
+ spaces = 0
163
+ for x in itertools.takewhile(str.isspace, str(string)):
164
+ spaces += 1
165
+ return spaces
166
+
167
+ # A few places in the code still use no `loc` or default to line 1
168
+ # this is often in places where exceptions are used for the purposes
169
+ # of flow control. As a result max is in use to prevent slice from
170
+ # `[negative: positive]`
171
+ selected = lines[max(0, use_line - nlines_up) : use_line]
172
+
173
+ # see if selected contains a definition
174
+ def_found = False
175
+ for x in selected:
176
+ if "def " in x:
177
+ def_found = True
178
+
179
+ # no definition found, try and find one
180
+ if not def_found:
181
+ # try and find a def, go backwards from error line
182
+ fn_name = None
183
+ for x in reversed(lines[: use_line - 1]):
184
+ if "def " in x:
185
+ fn_name = x
186
+ break
187
+ if fn_name:
188
+ ret.append(fn_name)
189
+ spaces = count_spaces(x)
190
+ ret.append(" " * (4 + spaces) + "<source elided>\n")
191
+
192
+ if selected:
193
+ ret.extend(selected[:-1])
194
+ ret.append(_termcolor.highlight(selected[-1]))
195
+
196
+ # point at the problem with a caret
197
+ spaces = count_spaces(selected[-1])
198
+ ret.append(" " * (spaces) + _termcolor.indicate("^"))
199
+
200
+ # if in the REPL source may not be available
201
+ if not ret:
202
+ if not lines:
203
+ ret = "<source missing, REPL/exec in use?>"
204
+ elif use_line <= 0:
205
+ ret = "<source line number missing>"
206
+
207
+ err = _termcolor.filename('\nFile "%s", line %d:') + "\n%s"
208
+ tmp = err % (self._get_path(), use_line, _termcolor.code("".join(ret)))
209
+ return tmp
210
+
211
+ def with_lineno(self, line, col=None):
212
+ """
213
+ Return a new Loc with this line number.
214
+ """
215
+ return type(self)(self.filename, line, col)
216
+
217
+ def short(self):
218
+ """
219
+ Returns a short string
220
+ """
221
+ shortfilename = os.path.basename(self.filename)
222
+ return "%s:%s" % (shortfilename, self.line)
223
+
224
+
225
+ # Used for annotating errors when source location is unknown.
226
+ unknown_loc = Loc("unknown location", 0, 0)
227
+
228
+
229
+ @total_ordering
230
+ class SlotEqualityCheckMixin(object):
231
+ # some ir nodes are __dict__ free using __slots__ instead, this mixin
232
+ # should not trigger the unintended creation of __dict__.
233
+ __slots__ = tuple()
234
+
235
+ def __eq__(self, other):
236
+ if type(self) is type(other):
237
+ for name in self.__slots__:
238
+ if getattr(self, name) != getattr(other, name):
239
+ return False
240
+ else:
241
+ return True
242
+ return False
243
+
244
+ def __le__(self, other):
245
+ return str(self) <= str(other)
246
+
247
+ def __hash__(self):
248
+ return id(self)
249
+
250
+
251
+ @total_ordering
252
+ class EqualityCheckMixin(object):
253
+ """Mixin for basic equality checking"""
254
+
255
+ def __eq__(self, other):
256
+ if type(self) is type(other):
257
+
258
+ def fixup(adict):
259
+ bad = ("loc", "scope")
260
+ d = dict(adict)
261
+ for x in bad:
262
+ d.pop(x, None)
263
+ return d
264
+
265
+ d1 = fixup(self.__dict__)
266
+ d2 = fixup(other.__dict__)
267
+ if d1 == d2:
268
+ return True
269
+ return False
270
+
271
+ def __le__(self, other):
272
+ return str(self) < str(other)
273
+
274
+ def __hash__(self):
275
+ return id(self)
276
+
277
+
278
+ class VarMap(object):
279
+ def __init__(self):
280
+ self._con = {}
281
+
282
+ def define(self, name, var):
283
+ if name in self._con:
284
+ raise RedefinedError(name)
285
+ else:
286
+ self._con[name] = var
287
+
288
+ def get(self, name):
289
+ try:
290
+ return self._con[name]
291
+ except KeyError:
292
+ raise NotDefinedError(name)
293
+
294
+ def __contains__(self, name):
295
+ return name in self._con
296
+
297
+ def __len__(self):
298
+ return len(self._con)
299
+
300
+ def __repr__(self):
301
+ return pprint.pformat(self._con)
302
+
303
+ def __hash__(self):
304
+ return hash(self.name)
305
+
306
+ def __iter__(self):
307
+ return self._con.iterkeys()
308
+
309
+ def __eq__(self, other):
310
+ if type(self) is type(other):
311
+ # check keys only, else __eq__ ref cycles, scope -> varmap -> var
312
+ return self._con.keys() == other._con.keys()
313
+ return False
314
+
315
+ def __ne__(self, other):
316
+ return not self.__eq__(other)
317
+
318
+
319
+ class AbstractRHS(object):
320
+ """Abstract base class for anything that can be the RHS of an assignment.
321
+ This class **does not** define any methods.
322
+ """
323
+
324
+
325
+ class Inst(EqualityCheckMixin, AbstractRHS):
326
+ """
327
+ Base class for all IR instructions.
328
+ """
329
+
330
+ def list_vars(self):
331
+ """
332
+ List the variables used (read or written) by the instruction.
333
+ """
334
+ raise NotImplementedError
335
+
336
+ def _rec_list_vars(self, val):
337
+ """
338
+ A recursive helper used to implement list_vars() in subclasses.
339
+ """
340
+ if isinstance(val, Var):
341
+ return [val]
342
+ elif isinstance(val, Inst):
343
+ return val.list_vars()
344
+ elif isinstance(val, (list, tuple)):
345
+ lst = []
346
+ for v in val:
347
+ lst.extend(self._rec_list_vars(v))
348
+ return lst
349
+ elif isinstance(val, dict):
350
+ lst = []
351
+ for v in val.values():
352
+ lst.extend(self._rec_list_vars(v))
353
+ return lst
354
+ else:
355
+ return []
356
+
357
+
358
+ class Stmt(Inst):
359
+ """
360
+ Base class for IR statements (instructions which can appear on their
361
+ own in a Block).
362
+ """
363
+
364
+ # Whether this statement ends its basic block (i.e. it will either jump
365
+ # to another block or exit the function).
366
+ is_terminator = False
367
+ # Whether this statement exits the function.
368
+ is_exit = False
369
+
370
+ def list_vars(self):
371
+ return self._rec_list_vars(self.__dict__)
372
+
373
+
374
+ class Terminator(Stmt):
375
+ """
376
+ IR statements that are terminators: the last statement in a block.
377
+ A terminator must either:
378
+ - exit the function
379
+ - jump to a block
380
+
381
+ All subclass of Terminator must override `.get_targets()` to return a list
382
+ of jump targets.
383
+ """
384
+
385
+ is_terminator = True
386
+
387
+ def get_targets(self):
388
+ raise NotImplementedError(type(self))
389
+
390
+
391
+ class Expr(Inst):
392
+ """
393
+ An IR expression (an instruction which can only be part of a larger
394
+ statement).
395
+ """
396
+
397
+ def __init__(self, op, loc, **kws):
398
+ assert isinstance(op, str)
399
+ assert isinstance(loc, Loc)
400
+ self.op = op
401
+ self.loc = loc
402
+ self._kws = kws
403
+
404
+ def __getattr__(self, name):
405
+ if name.startswith("_"):
406
+ return Inst.__getattr__(self, name)
407
+ return self._kws[name]
408
+
409
+ def __setattr__(self, name, value):
410
+ if name in ("op", "loc", "_kws"):
411
+ self.__dict__[name] = value
412
+ else:
413
+ self._kws[name] = value
414
+
415
+ @classmethod
416
+ def binop(cls, fn, lhs, rhs, loc):
417
+ assert isinstance(fn, BuiltinFunctionType)
418
+ assert isinstance(lhs, Var)
419
+ assert isinstance(rhs, Var)
420
+ assert isinstance(loc, Loc)
421
+ op = "binop"
422
+ return cls(
423
+ op=op,
424
+ loc=loc,
425
+ fn=fn,
426
+ lhs=lhs,
427
+ rhs=rhs,
428
+ static_lhs=UNDEFINED,
429
+ static_rhs=UNDEFINED,
430
+ )
431
+
432
+ @classmethod
433
+ def inplace_binop(cls, fn, immutable_fn, lhs, rhs, loc):
434
+ assert isinstance(fn, BuiltinFunctionType)
435
+ assert isinstance(immutable_fn, BuiltinFunctionType)
436
+ assert isinstance(lhs, Var)
437
+ assert isinstance(rhs, Var)
438
+ assert isinstance(loc, Loc)
439
+ op = "inplace_binop"
440
+ return cls(
441
+ op=op,
442
+ loc=loc,
443
+ fn=fn,
444
+ immutable_fn=immutable_fn,
445
+ lhs=lhs,
446
+ rhs=rhs,
447
+ static_lhs=UNDEFINED,
448
+ static_rhs=UNDEFINED,
449
+ )
450
+
451
+ @classmethod
452
+ def unary(cls, fn, value, loc):
453
+ assert isinstance(value, (str, Var, FunctionType))
454
+ assert isinstance(loc, Loc)
455
+ op = "unary"
456
+ fn = UNARY_BUILTINS_TO_OPERATORS.get(fn, fn)
457
+ return cls(op=op, loc=loc, fn=fn, value=value)
458
+
459
+ @classmethod
460
+ def call(
461
+ cls, func, args, kws, loc, vararg=None, varkwarg=None, target=None
462
+ ):
463
+ assert isinstance(func, Var)
464
+ assert isinstance(loc, Loc)
465
+ op = "call"
466
+ return cls(
467
+ op=op,
468
+ loc=loc,
469
+ func=func,
470
+ args=args,
471
+ kws=kws,
472
+ vararg=vararg,
473
+ varkwarg=varkwarg,
474
+ target=target,
475
+ )
476
+
477
+ @classmethod
478
+ def build_tuple(cls, items, loc):
479
+ assert isinstance(loc, Loc)
480
+ op = "build_tuple"
481
+ return cls(op=op, loc=loc, items=items)
482
+
483
+ @classmethod
484
+ def build_list(cls, items, loc):
485
+ assert isinstance(loc, Loc)
486
+ op = "build_list"
487
+ return cls(op=op, loc=loc, items=items)
488
+
489
+ @classmethod
490
+ def build_set(cls, items, loc):
491
+ assert isinstance(loc, Loc)
492
+ op = "build_set"
493
+ return cls(op=op, loc=loc, items=items)
494
+
495
+ @classmethod
496
+ def build_map(cls, items, size, literal_value, value_indexes, loc):
497
+ assert isinstance(loc, Loc)
498
+ op = "build_map"
499
+ return cls(
500
+ op=op,
501
+ loc=loc,
502
+ items=items,
503
+ size=size,
504
+ literal_value=literal_value,
505
+ value_indexes=value_indexes,
506
+ )
507
+
508
+ @classmethod
509
+ def pair_first(cls, value, loc):
510
+ assert isinstance(value, Var)
511
+ op = "pair_first"
512
+ return cls(op=op, loc=loc, value=value)
513
+
514
+ @classmethod
515
+ def pair_second(cls, value, loc):
516
+ assert isinstance(value, Var)
517
+ assert isinstance(loc, Loc)
518
+ op = "pair_second"
519
+ return cls(op=op, loc=loc, value=value)
520
+
521
+ @classmethod
522
+ def getiter(cls, value, loc):
523
+ assert isinstance(value, Var)
524
+ assert isinstance(loc, Loc)
525
+ op = "getiter"
526
+ return cls(op=op, loc=loc, value=value)
527
+
528
+ @classmethod
529
+ def iternext(cls, value, loc):
530
+ assert isinstance(value, Var)
531
+ assert isinstance(loc, Loc)
532
+ op = "iternext"
533
+ return cls(op=op, loc=loc, value=value)
534
+
535
+ @classmethod
536
+ def exhaust_iter(cls, value, count, loc):
537
+ assert isinstance(value, Var)
538
+ assert isinstance(count, int)
539
+ assert isinstance(loc, Loc)
540
+ op = "exhaust_iter"
541
+ return cls(op=op, loc=loc, value=value, count=count)
542
+
543
+ @classmethod
544
+ def getattr(cls, value, attr, loc):
545
+ assert isinstance(value, Var)
546
+ assert isinstance(attr, str)
547
+ assert isinstance(loc, Loc)
548
+ op = "getattr"
549
+ return cls(op=op, loc=loc, value=value, attr=attr)
550
+
551
+ @classmethod
552
+ def getitem(cls, value, index, loc):
553
+ assert isinstance(value, Var)
554
+ assert isinstance(index, Var)
555
+ assert isinstance(loc, Loc)
556
+ op = "getitem"
557
+ fn = operator.getitem
558
+ return cls(op=op, loc=loc, value=value, index=index, fn=fn)
559
+
560
+ @classmethod
561
+ def typed_getitem(cls, value, dtype, index, loc):
562
+ assert isinstance(value, Var)
563
+ assert isinstance(loc, Loc)
564
+ op = "typed_getitem"
565
+ return cls(op=op, loc=loc, value=value, dtype=dtype, index=index)
566
+
567
+ @classmethod
568
+ def static_getitem(cls, value, index, index_var, loc):
569
+ assert isinstance(value, Var)
570
+ assert index_var is None or isinstance(index_var, Var)
571
+ assert isinstance(loc, Loc)
572
+ op = "static_getitem"
573
+ fn = operator.getitem
574
+ return cls(
575
+ op=op, loc=loc, value=value, index=index, index_var=index_var, fn=fn
576
+ )
577
+
578
+ @classmethod
579
+ def cast(cls, value, loc):
580
+ """
581
+ A node for implicit casting at the return statement
582
+ """
583
+ assert isinstance(value, Var)
584
+ assert isinstance(loc, Loc)
585
+ op = "cast"
586
+ return cls(op=op, value=value, loc=loc)
587
+
588
+ @classmethod
589
+ def phi(cls, loc):
590
+ """Phi node"""
591
+ assert isinstance(loc, Loc)
592
+ return cls(op="phi", incoming_values=[], incoming_blocks=[], loc=loc)
593
+
594
+ @classmethod
595
+ def make_function(cls, name, code, closure, defaults, loc):
596
+ """
597
+ A node for making a function object.
598
+ """
599
+ assert isinstance(loc, Loc)
600
+ op = "make_function"
601
+ return cls(
602
+ op=op,
603
+ name=name,
604
+ code=code,
605
+ closure=closure,
606
+ defaults=defaults,
607
+ loc=loc,
608
+ )
609
+
610
+ @classmethod
611
+ def null(cls, loc):
612
+ """
613
+ A node for null value.
614
+
615
+ This node is not handled by type inference. It is only added by
616
+ post-typing passes.
617
+ """
618
+ assert isinstance(loc, Loc)
619
+ op = "null"
620
+ return cls(op=op, loc=loc)
621
+
622
+ @classmethod
623
+ def undef(cls, loc):
624
+ """
625
+ A node for undefined value specifically from LOAD_FAST_AND_CLEAR opcode.
626
+ """
627
+ assert isinstance(loc, Loc)
628
+ op = "undef"
629
+ return cls(op=op, loc=loc)
630
+
631
+ @classmethod
632
+ def dummy(cls, op, info, loc):
633
+ """
634
+ A node for a dummy value.
635
+
636
+ This node is a place holder for carrying information through to a point
637
+ where it is rewritten into something valid. This node is not handled
638
+ by type inference or lowering. It's presence outside of the interpreter
639
+ renders IR as illegal.
640
+ """
641
+ assert isinstance(loc, Loc)
642
+ assert isinstance(op, str)
643
+ return cls(op=op, info=info, loc=loc)
644
+
645
+ def __repr__(self):
646
+ if self.op == "call":
647
+ args = ", ".join(str(a) for a in self.args)
648
+ pres_order = (
649
+ self._kws.items()
650
+ if config.DIFF_IR == 0
651
+ else sorted(self._kws.items())
652
+ )
653
+ kws = ", ".join("%s=%s" % (k, v) for k, v in pres_order)
654
+ vararg = "*%s" % (self.vararg,) if self.vararg is not None else ""
655
+ arglist = ", ".join(filter(None, [args, vararg, kws]))
656
+ return "call %s(%s)" % (self.func, arglist)
657
+ elif self.op == "binop":
658
+ lhs, rhs = self.lhs, self.rhs
659
+ if self.fn == operator.contains:
660
+ lhs, rhs = rhs, lhs
661
+ fn = OPERATORS_TO_BUILTINS.get(self.fn, self.fn)
662
+ return "%s %s %s" % (lhs, fn, rhs)
663
+ else:
664
+ pres_order = (
665
+ self._kws.items()
666
+ if config.DIFF_IR == 0
667
+ else sorted(self._kws.items())
668
+ )
669
+ args = ("%s=%s" % (k, v) for k, v in pres_order)
670
+ return "%s(%s)" % (self.op, ", ".join(args))
671
+
672
+ def list_vars(self):
673
+ return self._rec_list_vars(self._kws)
674
+
675
+ def infer_constant(self):
676
+ raise ConstantInferenceError("%s" % self, loc=self.loc)
677
+
678
+
679
+ class SetItem(Stmt):
680
+ """
681
+ target[index] = value
682
+ """
683
+
684
+ def __init__(self, target, index, value, loc):
685
+ assert isinstance(target, Var)
686
+ assert isinstance(index, Var)
687
+ assert isinstance(value, Var)
688
+ assert isinstance(loc, Loc)
689
+ self.target = target
690
+ self.index = index
691
+ self.value = value
692
+ self.loc = loc
693
+
694
+ def __repr__(self):
695
+ return "%s[%s] = %s" % (self.target, self.index, self.value)
696
+
697
+
698
+ class StaticSetItem(Stmt):
699
+ """
700
+ target[constant index] = value
701
+ """
702
+
703
+ def __init__(self, target, index, index_var, value, loc):
704
+ assert isinstance(target, Var)
705
+ assert not isinstance(index, Var)
706
+ assert isinstance(index_var, Var)
707
+ assert isinstance(value, Var)
708
+ assert isinstance(loc, Loc)
709
+ self.target = target
710
+ self.index = index
711
+ self.index_var = index_var
712
+ self.value = value
713
+ self.loc = loc
714
+
715
+ def __repr__(self):
716
+ return "%s[%r] = %s" % (self.target, self.index, self.value)
717
+
718
+
719
+ class DelItem(Stmt):
720
+ """
721
+ del target[index]
722
+ """
723
+
724
+ def __init__(self, target, index, loc):
725
+ assert isinstance(target, Var)
726
+ assert isinstance(index, Var)
727
+ assert isinstance(loc, Loc)
728
+ self.target = target
729
+ self.index = index
730
+ self.loc = loc
731
+
732
+ def __repr__(self):
733
+ return "del %s[%s]" % (self.target, self.index)
734
+
735
+
736
+ class SetAttr(Stmt):
737
+ def __init__(self, target, attr, value, loc):
738
+ assert isinstance(target, Var)
739
+ assert isinstance(attr, str)
740
+ assert isinstance(value, Var)
741
+ assert isinstance(loc, Loc)
742
+ self.target = target
743
+ self.attr = attr
744
+ self.value = value
745
+ self.loc = loc
746
+
747
+ def __repr__(self):
748
+ return "(%s).%s = %s" % (self.target, self.attr, self.value)
749
+
750
+
751
+ class DelAttr(Stmt):
752
+ def __init__(self, target, attr, loc):
753
+ assert isinstance(target, Var)
754
+ assert isinstance(attr, str)
755
+ assert isinstance(loc, Loc)
756
+ self.target = target
757
+ self.attr = attr
758
+ self.loc = loc
759
+
760
+ def __repr__(self):
761
+ return "del (%s).%s" % (self.target, self.attr)
762
+
763
+
764
+ class StoreMap(Stmt):
765
+ def __init__(self, dct, key, value, loc):
766
+ assert isinstance(dct, Var)
767
+ assert isinstance(key, Var)
768
+ assert isinstance(value, Var)
769
+ assert isinstance(loc, Loc)
770
+ self.dct = dct
771
+ self.key = key
772
+ self.value = value
773
+ self.loc = loc
774
+
775
+ def __repr__(self):
776
+ return "%s[%s] = %s" % (self.dct, self.key, self.value)
777
+
778
+
779
+ class Del(Stmt):
780
+ def __init__(self, value, loc):
781
+ assert isinstance(value, str)
782
+ if HAS_NUMBA:
783
+ assert isinstance(loc, (Loc, numba.core.ir.Loc))
784
+ else:
785
+ assert isinstance(loc, (Loc))
786
+ self.value = value
787
+ self.loc = loc
788
+
789
+ def __str__(self):
790
+ return "del %s" % self.value
791
+
792
+
793
+ class Raise(Terminator):
794
+ is_exit = True
795
+
796
+ def __init__(self, exception, loc):
797
+ assert exception is None or isinstance(exception, Var)
798
+ assert isinstance(loc, Loc)
799
+ self.exception = exception
800
+ self.loc = loc
801
+
802
+ def __str__(self):
803
+ return "raise %s" % self.exception
804
+
805
+ def get_targets(self):
806
+ return []
807
+
808
+
809
+ class StaticRaise(Terminator):
810
+ """
811
+ Raise an exception class and arguments known at compile-time.
812
+ Note that if *exc_class* is None, a bare "raise" statement is implied
813
+ (i.e. re-raise the current exception).
814
+ """
815
+
816
+ is_exit = True
817
+
818
+ def __init__(self, exc_class, exc_args, loc):
819
+ assert exc_class is None or isinstance(exc_class, type)
820
+ assert isinstance(loc, Loc)
821
+ assert exc_args is None or isinstance(exc_args, tuple)
822
+ self.exc_class = exc_class
823
+ self.exc_args = exc_args
824
+ self.loc = loc
825
+
826
+ def __str__(self):
827
+ if self.exc_class is None:
828
+ return "<static> raise"
829
+ elif self.exc_args is None:
830
+ return "<static> raise %s" % (self.exc_class,)
831
+ else:
832
+ return "<static> raise %s(%s)" % (
833
+ self.exc_class,
834
+ ", ".join(map(repr, self.exc_args)),
835
+ )
836
+
837
+ def get_targets(self):
838
+ return []
839
+
840
+
841
+ class DynamicRaise(Terminator):
842
+ """
843
+ Raise an exception class and some argument *values* unknown at compile-time.
844
+ Note that if *exc_class* is None, a bare "raise" statement is implied
845
+ (i.e. re-raise the current exception).
846
+ """
847
+
848
+ is_exit = True
849
+
850
+ def __init__(self, exc_class, exc_args, loc):
851
+ assert exc_class is None or isinstance(exc_class, type)
852
+ assert isinstance(loc, Loc)
853
+ assert exc_args is None or isinstance(exc_args, tuple)
854
+ self.exc_class = exc_class
855
+ self.exc_args = exc_args
856
+ self.loc = loc
857
+
858
+ def __str__(self):
859
+ if self.exc_class is None:
860
+ return "<dynamic> raise"
861
+ elif self.exc_args is None:
862
+ return "<dynamic> raise %s" % (self.exc_class,)
863
+ else:
864
+ return "<dynamic> raise %s(%s)" % (
865
+ self.exc_class,
866
+ ", ".join(map(repr, self.exc_args)),
867
+ )
868
+
869
+ def get_targets(self):
870
+ return []
871
+
872
+
873
+ class TryRaise(Stmt):
874
+ """A raise statement inside a try-block
875
+ Similar to ``Raise`` but does not terminate.
876
+ """
877
+
878
+ def __init__(self, exception, loc):
879
+ assert exception is None or isinstance(exception, Var)
880
+ assert isinstance(loc, Loc)
881
+ self.exception = exception
882
+ self.loc = loc
883
+
884
+ def __str__(self):
885
+ return "try_raise %s" % self.exception
886
+
887
+
888
+ class StaticTryRaise(Stmt):
889
+ """A raise statement inside a try-block.
890
+ Similar to ``StaticRaise`` but does not terminate.
891
+ """
892
+
893
+ def __init__(self, exc_class, exc_args, loc):
894
+ assert exc_class is None or isinstance(exc_class, type)
895
+ assert isinstance(loc, Loc)
896
+ assert exc_args is None or isinstance(exc_args, tuple)
897
+ self.exc_class = exc_class
898
+ self.exc_args = exc_args
899
+ self.loc = loc
900
+
901
+ def __str__(self):
902
+ if self.exc_class is None:
903
+ return "static_try_raise"
904
+ elif self.exc_args is None:
905
+ return f"static_try_raise {self.exc_class}"
906
+ else:
907
+ args = ", ".join(map(repr, self.exc_args))
908
+ return f"static_try_raise {self.exc_class}({args})"
909
+
910
+
911
+ class DynamicTryRaise(Stmt):
912
+ """A raise statement inside a try-block.
913
+ Similar to ``DynamicRaise`` but does not terminate.
914
+ """
915
+
916
+ def __init__(self, exc_class, exc_args, loc):
917
+ assert exc_class is None or isinstance(exc_class, type)
918
+ assert isinstance(loc, Loc)
919
+ assert exc_args is None or isinstance(exc_args, tuple)
920
+ self.exc_class = exc_class
921
+ self.exc_args = exc_args
922
+ self.loc = loc
923
+
924
+ def __str__(self):
925
+ if self.exc_class is None:
926
+ return "dynamic_try_raise"
927
+ elif self.exc_args is None:
928
+ return f"dynamic_try_raise {self.exc_class}"
929
+ else:
930
+ args = ", ".join(map(repr, self.exc_args))
931
+ return f"dynamic_try_raise {self.exc_class}({args})"
932
+
933
+
934
+ class Return(Terminator):
935
+ """
936
+ Return to caller.
937
+ """
938
+
939
+ is_exit = True
940
+
941
+ def __init__(self, value, loc):
942
+ assert isinstance(value, Var), type(value)
943
+ assert isinstance(loc, Loc)
944
+ self.value = value
945
+ self.loc = loc
946
+
947
+ def __str__(self):
948
+ return "return %s" % self.value
949
+
950
+ def get_targets(self):
951
+ return []
952
+
953
+
954
+ class Jump(Terminator):
955
+ """
956
+ Unconditional branch.
957
+ """
958
+
959
+ def __init__(self, target, loc):
960
+ assert isinstance(loc, Loc)
961
+ self.target = target
962
+ self.loc = loc
963
+
964
+ def __str__(self):
965
+ return "jump %s" % self.target
966
+
967
+ def get_targets(self):
968
+ return [self.target]
969
+
970
+
971
+ class Branch(Terminator):
972
+ """
973
+ Conditional branch.
974
+ """
975
+
976
+ def __init__(self, cond, truebr, falsebr, loc):
977
+ assert isinstance(cond, Var)
978
+ assert isinstance(loc, Loc)
979
+ self.cond = cond
980
+ self.truebr = truebr
981
+ self.falsebr = falsebr
982
+ self.loc = loc
983
+
984
+ def __str__(self):
985
+ return "branch %s, %s, %s" % (self.cond, self.truebr, self.falsebr)
986
+
987
+ def get_targets(self):
988
+ return [self.truebr, self.falsebr]
989
+
990
+
991
+ class Assign(Stmt):
992
+ """
993
+ Assign to a variable.
994
+ """
995
+
996
+ def __init__(self, value, target, loc):
997
+ assert isinstance(value, AbstractRHS)
998
+ assert isinstance(target, Var)
999
+ assert isinstance(loc, Loc)
1000
+ self.value = value
1001
+ self.target = target
1002
+ self.loc = loc
1003
+
1004
+ def __str__(self):
1005
+ return "%s = %s" % (self.target, self.value)
1006
+
1007
+
1008
+ class Print(Stmt):
1009
+ """
1010
+ Print some values.
1011
+ """
1012
+
1013
+ def __init__(self, args, vararg, loc):
1014
+ assert all(isinstance(x, Var) for x in args)
1015
+ assert vararg is None or isinstance(vararg, Var)
1016
+ assert isinstance(loc, Loc)
1017
+ self.args = tuple(args)
1018
+ self.vararg = vararg
1019
+ # Constant-inferred arguments
1020
+ self.consts = {}
1021
+ self.loc = loc
1022
+
1023
+ def __str__(self):
1024
+ return "print(%s)" % ", ".join(str(v) for v in self.args)
1025
+
1026
+
1027
+ class Yield(Inst):
1028
+ def __init__(self, value, loc, index):
1029
+ assert isinstance(value, Var)
1030
+ assert isinstance(loc, Loc)
1031
+ self.value = value
1032
+ self.loc = loc
1033
+ self.index = index
1034
+
1035
+ def __str__(self):
1036
+ return "yield %s" % (self.value,)
1037
+
1038
+ def list_vars(self):
1039
+ return [self.value]
1040
+
1041
+
1042
+ class EnterWith(Stmt):
1043
+ """Enter a "with" context"""
1044
+
1045
+ def __init__(self, contextmanager, begin, end, loc):
1046
+ """
1047
+ Parameters
1048
+ ----------
1049
+ contextmanager : IR value
1050
+ begin, end : int
1051
+ The beginning and the ending offset of the with-body.
1052
+ loc : ir.Loc instance
1053
+ Source location
1054
+ """
1055
+ assert isinstance(contextmanager, Var)
1056
+ assert isinstance(loc, Loc)
1057
+ self.contextmanager = contextmanager
1058
+ self.begin = begin
1059
+ self.end = end
1060
+ self.loc = loc
1061
+
1062
+ def __str__(self):
1063
+ return "enter_with {}".format(self.contextmanager)
1064
+
1065
+ def list_vars(self):
1066
+ return [self.contextmanager]
1067
+
1068
+
1069
+ class PopBlock(Stmt):
1070
+ """Marker statement for a pop block op code"""
1071
+
1072
+ def __init__(self, loc):
1073
+ assert isinstance(loc, Loc)
1074
+ self.loc = loc
1075
+
1076
+ def __str__(self):
1077
+ return "pop_block"
1078
+
1079
+
1080
+ class Arg(EqualityCheckMixin, AbstractRHS):
1081
+ def __init__(self, name, index, loc):
1082
+ assert isinstance(name, str)
1083
+ assert isinstance(index, int)
1084
+ assert isinstance(loc, Loc)
1085
+ self.name = name
1086
+ self.index = index
1087
+ self.loc = loc
1088
+
1089
+ def __repr__(self):
1090
+ return "arg(%d, name=%s)" % (self.index, self.name)
1091
+
1092
+ def infer_constant(self):
1093
+ raise ConstantInferenceError("%s" % self, loc=self.loc)
1094
+
1095
+
1096
+ class Const(EqualityCheckMixin, AbstractRHS):
1097
+ def __init__(self, value, loc, use_literal_type=True):
1098
+ assert isinstance(loc, Loc)
1099
+ self.value = value
1100
+ self.loc = loc
1101
+ # Note: need better way to tell if this is a literal or not.
1102
+ self.use_literal_type = use_literal_type
1103
+
1104
+ def __repr__(self):
1105
+ return "const(%s, %s)" % (type(self.value).__name__, self.value)
1106
+
1107
+ def infer_constant(self):
1108
+ return self.value
1109
+
1110
+ def __deepcopy__(self, memo):
1111
+ # Override to not copy constant values in code
1112
+ return Const(
1113
+ value=self.value,
1114
+ loc=self.loc,
1115
+ use_literal_type=self.use_literal_type,
1116
+ )
1117
+
1118
+
1119
+ class Global(EqualityCheckMixin, AbstractRHS):
1120
+ def __init__(self, name, value, loc):
1121
+ assert isinstance(loc, Loc)
1122
+ self.name = name
1123
+ self.value = value
1124
+ self.loc = loc
1125
+
1126
+ def __str__(self):
1127
+ return "global(%s: %s)" % (self.name, self.value)
1128
+
1129
+ def infer_constant(self):
1130
+ return self.value
1131
+
1132
+ def __deepcopy__(self, memo):
1133
+ # don't copy value since it can fail (e.g. modules)
1134
+ # value is readonly and doesn't need copying
1135
+ return Global(self.name, self.value, copy.deepcopy(self.loc))
1136
+
1137
+
1138
+ class FreeVar(EqualityCheckMixin, AbstractRHS):
1139
+ """
1140
+ A freevar, as loaded by LOAD_DECREF.
1141
+ (i.e. a variable defined in an enclosing non-global scope)
1142
+ """
1143
+
1144
+ def __init__(self, index, name, value, loc):
1145
+ assert isinstance(index, int)
1146
+ assert isinstance(name, str)
1147
+ assert isinstance(loc, Loc)
1148
+ # index inside __code__.co_freevars
1149
+ self.index = index
1150
+ # variable name
1151
+ self.name = name
1152
+ # frozen value
1153
+ self.value = value
1154
+ self.loc = loc
1155
+
1156
+ def __str__(self):
1157
+ return "freevar(%s: %s)" % (self.name, self.value)
1158
+
1159
+ def infer_constant(self):
1160
+ return self.value
1161
+
1162
+ def __deepcopy__(self, memo):
1163
+ # Override to not copy constant values in code
1164
+ return FreeVar(
1165
+ index=self.index, name=self.name, value=self.value, loc=self.loc
1166
+ )
1167
+
1168
+
1169
+ class Var(EqualityCheckMixin, AbstractRHS):
1170
+ """
1171
+ Attributes
1172
+ -----------
1173
+ - scope: Scope
1174
+
1175
+ - name: str
1176
+
1177
+ - loc: Loc
1178
+ Definition location
1179
+ """
1180
+
1181
+ def __init__(self, scope, name, loc):
1182
+ # NOTE: Use of scope=None should be removed.
1183
+ assert scope is None or isinstance(scope, Scope)
1184
+ assert isinstance(name, str)
1185
+ assert isinstance(loc, Loc)
1186
+ self.scope = scope
1187
+ self.name = name
1188
+ self.loc = loc
1189
+
1190
+ def __repr__(self):
1191
+ return "Var(%s, %s)" % (self.name, self.loc.short())
1192
+
1193
+ def __str__(self):
1194
+ return self.name
1195
+
1196
+ @property
1197
+ def is_temp(self):
1198
+ return self.name.startswith("$")
1199
+
1200
+ @property
1201
+ def unversioned_name(self):
1202
+ """The unversioned name of this variable, i.e. SSA renaming removed"""
1203
+ for k, redef_set in self.scope.var_redefinitions.items():
1204
+ if self.name in redef_set:
1205
+ return k
1206
+ return self.name
1207
+
1208
+ @property
1209
+ def versioned_names(self):
1210
+ """Known versioned names for this variable, i.e. known variable names in
1211
+ the scope that have been formed from applying SSA to this variable
1212
+ """
1213
+ return self.scope.get_versions_of(self.unversioned_name)
1214
+
1215
+ @property
1216
+ def all_names(self):
1217
+ """All known versioned and unversioned names for this variable"""
1218
+ return self.versioned_names | {
1219
+ self.unversioned_name,
1220
+ }
1221
+
1222
+ def __deepcopy__(self, memo):
1223
+ out = Var(copy.deepcopy(self.scope, memo), self.name, self.loc)
1224
+ memo[id(self)] = out
1225
+ return out
1226
+
1227
+
1228
+ class Scope(EqualityCheckMixin):
1229
+ """
1230
+ Attributes
1231
+ -----------
1232
+ - parent: Scope
1233
+ Parent scope
1234
+
1235
+ - localvars: VarMap
1236
+ Scope-local variable map
1237
+
1238
+ - loc: Loc
1239
+ Start of scope location
1240
+
1241
+ """
1242
+
1243
+ def __init__(self, parent, loc):
1244
+ assert parent is None or isinstance(parent, Scope)
1245
+ assert isinstance(loc, Loc)
1246
+ self.parent = parent
1247
+ self.localvars = VarMap()
1248
+ self.loc = loc
1249
+ self.redefined = defaultdict(int)
1250
+ self.var_redefinitions = defaultdict(set)
1251
+
1252
+ def define(self, name, loc):
1253
+ """
1254
+ Define a variable
1255
+ """
1256
+ v = Var(scope=self, name=name, loc=loc)
1257
+ self.localvars.define(v.name, v)
1258
+ return v
1259
+
1260
+ def get(self, name):
1261
+ """
1262
+ Refer to a variable. Returns the latest version.
1263
+ """
1264
+ if name in self.redefined:
1265
+ name = "%s.%d" % (name, self.redefined[name])
1266
+ return self.get_exact(name)
1267
+
1268
+ def get_exact(self, name):
1269
+ """
1270
+ Refer to a variable. The returned variable has the exact
1271
+ name (exact variable version).
1272
+ """
1273
+ try:
1274
+ return self.localvars.get(name)
1275
+ except NotDefinedError:
1276
+ if self.has_parent:
1277
+ return self.parent.get(name)
1278
+ else:
1279
+ raise
1280
+
1281
+ def get_or_define(self, name, loc):
1282
+ if name in self.redefined:
1283
+ name = "%s.%d" % (name, self.redefined[name])
1284
+
1285
+ if name not in self.localvars:
1286
+ return self.define(name, loc)
1287
+ else:
1288
+ return self.localvars.get(name)
1289
+
1290
+ def redefine(self, name, loc, rename=True):
1291
+ """
1292
+ Redefine if the name is already defined
1293
+ """
1294
+ if name not in self.localvars:
1295
+ return self.define(name, loc)
1296
+ elif not rename:
1297
+ # Must use the same name if the variable is a cellvar, which
1298
+ # means it could be captured in a closure.
1299
+ return self.localvars.get(name)
1300
+ else:
1301
+ while True:
1302
+ ct = self.redefined[name]
1303
+ self.redefined[name] = ct + 1
1304
+ newname = "%s.%d" % (name, ct + 1)
1305
+ try:
1306
+ res = self.define(newname, loc)
1307
+ except RedefinedError:
1308
+ continue
1309
+ else:
1310
+ self.var_redefinitions[name].add(newname)
1311
+ return res
1312
+
1313
+ def get_versions_of(self, name):
1314
+ """
1315
+ Gets all known versions of a given name
1316
+ """
1317
+ vers = set()
1318
+
1319
+ def walk(thename):
1320
+ redefs = self.var_redefinitions.get(thename, None)
1321
+ if redefs:
1322
+ for v in redefs:
1323
+ vers.add(v)
1324
+ walk(v)
1325
+
1326
+ walk(name)
1327
+ return vers
1328
+
1329
+ def make_temp(self, loc):
1330
+ n = len(self.localvars)
1331
+ v = Var(scope=self, name="$%d" % n, loc=loc)
1332
+ self.localvars.define(v.name, v)
1333
+ return v
1334
+
1335
+ @property
1336
+ def has_parent(self):
1337
+ return self.parent is not None
1338
+
1339
+ def __repr__(self):
1340
+ return "Scope(has_parent=%r, num_vars=%d, %s)" % (
1341
+ self.has_parent,
1342
+ len(self.localvars),
1343
+ self.loc,
1344
+ )
1345
+
1346
+
1347
+ class Block(EqualityCheckMixin):
1348
+ """A code block"""
1349
+
1350
+ def __init__(self, scope, loc):
1351
+ if HAS_NUMBA:
1352
+ assert isinstance(scope, (Scope, numba.core.ir.Scope))
1353
+ assert isinstance(loc, (Loc, numba.core.ir.Loc))
1354
+ else:
1355
+ assert isinstance(scope, Scope)
1356
+ assert isinstance(loc, Loc)
1357
+ self.scope = scope
1358
+ self.body = []
1359
+ self.loc = loc
1360
+
1361
+ def copy(self):
1362
+ block = Block(self.scope, self.loc)
1363
+ block.body = self.body[:]
1364
+ return block
1365
+
1366
+ def find_exprs(self, op=None):
1367
+ """
1368
+ Iterate over exprs of the given *op* in this block.
1369
+ """
1370
+ for inst in self.body:
1371
+ if isinstance(inst, Assign):
1372
+ expr = inst.value
1373
+ if isinstance(expr, Expr):
1374
+ if op is None or expr.op == op:
1375
+ yield expr
1376
+
1377
+ def find_insts(self, cls=None):
1378
+ """
1379
+ Iterate over insts of the given class in this block.
1380
+ """
1381
+ for inst in self.body:
1382
+ if isinstance(inst, cls):
1383
+ yield inst
1384
+
1385
+ def find_variable_assignment(self, name):
1386
+ """
1387
+ Returns the assignment inst associated with variable "name", None if
1388
+ it cannot be found.
1389
+ """
1390
+ for x in self.find_insts(cls=Assign):
1391
+ if x.target.name == name:
1392
+ return x
1393
+ return None
1394
+
1395
+ def prepend(self, inst):
1396
+ assert isinstance(inst, Stmt)
1397
+ self.body.insert(0, inst)
1398
+
1399
+ def append(self, inst):
1400
+ assert isinstance(inst, Stmt)
1401
+ self.body.append(inst)
1402
+
1403
+ def remove(self, inst):
1404
+ assert isinstance(inst, Stmt)
1405
+ del self.body[self.body.index(inst)]
1406
+
1407
+ def clear(self):
1408
+ del self.body[:]
1409
+
1410
+ def dump(self, file=None):
1411
+ # Avoid early bind of sys.stdout as default value
1412
+ file = file or sys.stdout
1413
+ for inst in self.body:
1414
+ if hasattr(inst, "dump"):
1415
+ inst.dump(file)
1416
+ else:
1417
+ inst_vars = sorted(str(v) for v in inst.list_vars())
1418
+ print(" %-40s %s" % (inst, inst_vars), file=file)
1419
+
1420
+ @property
1421
+ def terminator(self):
1422
+ return self.body[-1]
1423
+
1424
+ @property
1425
+ def is_terminated(self):
1426
+ return self.body and self.body[-1].is_terminator
1427
+
1428
+ def verify(self):
1429
+ if not self.is_terminated:
1430
+ raise VerificationError("Missing block terminator")
1431
+ # Only the last instruction can be a terminator
1432
+ for inst in self.body[:-1]:
1433
+ if inst.is_terminator:
1434
+ raise VerificationError(
1435
+ "Terminator before the last instruction"
1436
+ )
1437
+
1438
+ def insert_after(self, stmt, other):
1439
+ """
1440
+ Insert *stmt* after *other*.
1441
+ """
1442
+ index = self.body.index(other)
1443
+ self.body.insert(index + 1, stmt)
1444
+
1445
+ def insert_before_terminator(self, stmt):
1446
+ assert isinstance(stmt, Stmt)
1447
+ assert self.is_terminated
1448
+ self.body.insert(-1, stmt)
1449
+
1450
+ def __repr__(self):
1451
+ return "<ir.Block at %s>" % (self.loc,)
1452
+
1453
+
1454
+ class Loop(SlotEqualityCheckMixin):
1455
+ """Describes a loop-block"""
1456
+
1457
+ __slots__ = "entry", "exit"
1458
+
1459
+ def __init__(self, entry, exit):
1460
+ self.entry = entry
1461
+ self.exit = exit
1462
+
1463
+ def __repr__(self):
1464
+ args = self.entry, self.exit
1465
+ return "Loop(entry=%s, exit=%s)" % args
1466
+
1467
+
1468
+ class With(SlotEqualityCheckMixin):
1469
+ """Describes a with-block"""
1470
+
1471
+ __slots__ = "entry", "exit"
1472
+
1473
+ def __init__(self, entry, exit):
1474
+ self.entry = entry
1475
+ self.exit = exit
1476
+
1477
+ def __repr__(self):
1478
+ args = self.entry, self.exit
1479
+ return "With(entry=%s, exit=%s)" % args
1480
+
1481
+
1482
+ class FunctionIR(object):
1483
+ def __init__(
1484
+ self,
1485
+ blocks,
1486
+ is_generator,
1487
+ func_id,
1488
+ loc,
1489
+ definitions,
1490
+ arg_count,
1491
+ arg_names,
1492
+ ):
1493
+ self.blocks = blocks
1494
+ self.is_generator = is_generator
1495
+ self.func_id = func_id
1496
+ self.loc = loc
1497
+ self.arg_count = arg_count
1498
+ self.arg_names = arg_names
1499
+
1500
+ self._definitions = definitions
1501
+
1502
+ self._reset_analysis_variables()
1503
+
1504
+ def equal_ir(self, other):
1505
+ """Checks that the IR contained within is equal to the IR in other.
1506
+ Equality is defined by being equal in fundamental structure (blocks,
1507
+ labels, IR node type and the order in which they are defined) and the
1508
+ IR nodes being equal. IR node equality essentially comes down to
1509
+ ensuring a node's `.__dict__` or `.__slots__` is equal, with the
1510
+ exception of ignoring 'loc' and 'scope' entries. The upshot is that the
1511
+ comparison is essentially location and scope invariant, but otherwise
1512
+ behaves as unsurprisingly as possible.
1513
+ """
1514
+ if type(self) is type(other):
1515
+ return self.blocks == other.blocks
1516
+ return False
1517
+
1518
+ def diff_str(self, other):
1519
+ """
1520
+ Compute a human readable difference in the IR, returns a formatted
1521
+ string ready for printing.
1522
+ """
1523
+ msg = []
1524
+ for label, block in self.blocks.items():
1525
+ other_blk = other.blocks.get(label, None)
1526
+ if other_blk is not None:
1527
+ if block != other_blk:
1528
+ msg.append(("Block %s differs" % label).center(80, "-"))
1529
+ # see if the instructions are just a permutation
1530
+ block_del = [x for x in block.body if isinstance(x, Del)]
1531
+ oth_del = [x for x in other_blk.body if isinstance(x, Del)]
1532
+ if block_del != oth_del:
1533
+ # this is a common issue, dels are all present, but
1534
+ # order shuffled.
1535
+ if sorted(block_del) == sorted(oth_del):
1536
+ msg.append(
1537
+ (
1538
+ "Block %s contains the same dels but "
1539
+ "their order is different"
1540
+ )
1541
+ % label
1542
+ )
1543
+ if len(block.body) > len(other_blk.body):
1544
+ msg.append("This block contains more statements")
1545
+ elif len(block.body) < len(other_blk.body):
1546
+ msg.append("Other block contains more statements")
1547
+
1548
+ # find the indexes where they don't match
1549
+ tmp = []
1550
+ for idx, stmts in enumerate(
1551
+ zip(block.body, other_blk.body)
1552
+ ):
1553
+ b_s, o_s = stmts
1554
+ if b_s != o_s:
1555
+ tmp.append(idx)
1556
+
1557
+ def get_pad(ablock, l):
1558
+ pointer = "-> "
1559
+ sp = len(pointer) * " "
1560
+ pad = []
1561
+ nstmt = len(ablock)
1562
+ for i in range(nstmt):
1563
+ if i in tmp:
1564
+ item = pointer
1565
+ elif i >= l:
1566
+ item = pointer
1567
+ else:
1568
+ item = sp
1569
+ pad.append(item)
1570
+ return pad
1571
+
1572
+ min_stmt_len = min(len(block.body), len(other_blk.body))
1573
+
1574
+ with StringIO() as buf:
1575
+ it = [("self", block), ("other", other_blk)]
1576
+ for name, _block in it:
1577
+ buf.truncate(0)
1578
+ _block.dump(file=buf)
1579
+ stmts = buf.getvalue().splitlines()
1580
+ pad = get_pad(_block.body, min_stmt_len)
1581
+ title = "%s: block %s" % (name, label)
1582
+ msg.append(title.center(80, "-"))
1583
+ msg.extend(
1584
+ [
1585
+ "{0}{1}".format(a, b)
1586
+ for a, b in zip(pad, stmts)
1587
+ ]
1588
+ )
1589
+ if msg == []:
1590
+ msg.append("IR is considered equivalent.")
1591
+ return "\n".join(msg)
1592
+
1593
+ def _reset_analysis_variables(self):
1594
+ self._consts = consts.ConstantInference(self)
1595
+
1596
+ # Will be computed by PostProcessor
1597
+ self.generator_info = None
1598
+ self.variable_lifetime = None
1599
+ # { ir.Block: { variable names (potentially) alive at start of block } }
1600
+ self.block_entry_vars = {}
1601
+
1602
+ def derive(
1603
+ self,
1604
+ blocks,
1605
+ arg_count=None,
1606
+ arg_names=None,
1607
+ force_non_generator=False,
1608
+ loc=None,
1609
+ ):
1610
+ """
1611
+ Derive a new function IR from this one, using the given blocks,
1612
+ and possibly modifying the argument count and generator flag.
1613
+
1614
+ Post-processing will have to be run again on the new IR.
1615
+ """
1616
+ firstblock = blocks[min(blocks)]
1617
+
1618
+ new_ir = copy.copy(self)
1619
+ new_ir.blocks = blocks
1620
+ new_ir.loc = firstblock.loc if loc is None else loc
1621
+ if force_non_generator:
1622
+ new_ir.is_generator = False
1623
+ if arg_count is not None:
1624
+ new_ir.arg_count = arg_count
1625
+ if arg_names is not None:
1626
+ new_ir.arg_names = arg_names
1627
+ new_ir._reset_analysis_variables()
1628
+ # Make fresh func_id
1629
+ new_ir.func_id = new_ir.func_id.derive()
1630
+ return new_ir
1631
+
1632
+ def copy(self):
1633
+ new_ir = copy.copy(self)
1634
+ blocks = {}
1635
+ block_entry_vars = {}
1636
+ for label, block in self.blocks.items():
1637
+ new_block = block.copy()
1638
+ blocks[label] = new_block
1639
+ if block in self.block_entry_vars:
1640
+ block_entry_vars[new_block] = self.block_entry_vars[block]
1641
+ new_ir.blocks = blocks
1642
+ new_ir.block_entry_vars = block_entry_vars
1643
+ return new_ir
1644
+
1645
+ def get_block_entry_vars(self, block):
1646
+ """
1647
+ Return a set of variable names possibly alive at the beginning of
1648
+ the block.
1649
+ """
1650
+ return self.block_entry_vars[block]
1651
+
1652
+ def infer_constant(self, name):
1653
+ """
1654
+ Try to infer the constant value of a given variable.
1655
+ """
1656
+ if isinstance(name, Var):
1657
+ name = name.name
1658
+ return self._consts.infer_constant(name)
1659
+
1660
+ def get_definition(self, value, lhs_only=False):
1661
+ """
1662
+ Get the definition site for the given variable name or instance.
1663
+ A Expr instance is returned by default, but if lhs_only is set
1664
+ to True, the left-hand-side variable is returned instead.
1665
+ """
1666
+ lhs = value
1667
+ while True:
1668
+ if isinstance(value, Var):
1669
+ lhs = value
1670
+ name = value.name
1671
+ elif isinstance(value, str):
1672
+ lhs = value
1673
+ name = value
1674
+ else:
1675
+ return lhs if lhs_only else value
1676
+ defs = self._definitions[name]
1677
+ if len(defs) == 0:
1678
+ raise KeyError("no definition for %r" % (name,))
1679
+ if len(defs) > 1:
1680
+ raise KeyError("more than one definition for %r" % (name,))
1681
+ value = defs[0]
1682
+
1683
+ def get_assignee(self, rhs_value, in_blocks=None):
1684
+ """
1685
+ Finds the assignee for a given RHS value. If in_blocks is given the
1686
+ search will be limited to the specified blocks.
1687
+ """
1688
+ if in_blocks is None:
1689
+ blocks = self.blocks.values()
1690
+ elif isinstance(in_blocks, int):
1691
+ blocks = [self.blocks[in_blocks]]
1692
+ else:
1693
+ blocks = [self.blocks[blk] for blk in list(in_blocks)]
1694
+
1695
+ assert isinstance(rhs_value, AbstractRHS)
1696
+
1697
+ for blk in blocks:
1698
+ for assign in blk.find_insts(Assign):
1699
+ if assign.value == rhs_value:
1700
+ return assign.target
1701
+
1702
+ raise ValueError("Could not find an assignee for %s" % rhs_value)
1703
+
1704
+ def dump(self, file=None):
1705
+ nofile = file is None
1706
+ # Avoid early bind of sys.stdout as default value
1707
+ file = file or StringIO()
1708
+ for offset, block in sorted(self.blocks.items()):
1709
+ print("label %s:" % (offset,), file=file)
1710
+ block.dump(file=file)
1711
+ if nofile:
1712
+ text = file.getvalue()
1713
+ if config.HIGHLIGHT_DUMPS:
1714
+ try:
1715
+ import pygments # noqa
1716
+ except ImportError:
1717
+ msg = "Please install pygments to see highlighted dumps"
1718
+ raise ValueError(msg)
1719
+ else:
1720
+ from pygments import highlight
1721
+ from numba.cuda.misc.dump_style import NumbaIRLexer as lexer
1722
+ from numba.cuda.misc.dump_style import by_colorscheme
1723
+ from pygments.formatters import Terminal256Formatter
1724
+
1725
+ print(
1726
+ highlight(
1727
+ text,
1728
+ lexer(),
1729
+ Terminal256Formatter(style=by_colorscheme()),
1730
+ )
1731
+ )
1732
+ else:
1733
+ print(text)
1734
+
1735
+ def dump_to_string(self):
1736
+ with StringIO() as sb:
1737
+ self.dump(file=sb)
1738
+ return sb.getvalue()
1739
+
1740
+ def dump_generator_info(self, file=None):
1741
+ file = file or sys.stdout
1742
+ gi = self.generator_info
1743
+ print("generator state variables:", sorted(gi.state_vars), file=file)
1744
+ for index, yp in sorted(gi.yield_points.items()):
1745
+ print(
1746
+ "yield point #%d: live variables = %s, weak live variables = %s"
1747
+ % (index, sorted(yp.live_vars), sorted(yp.weak_live_vars)),
1748
+ file=file,
1749
+ )
1750
+
1751
+ def render_dot(self, filename_prefix="numba_ir", include_ir=True):
1752
+ """Render the CFG of the IR with GraphViz DOT via the
1753
+ ``graphviz`` python binding.
1754
+
1755
+ Returns
1756
+ -------
1757
+ g : graphviz.Digraph
1758
+ Use `g.view()` to open the graph in the default PDF application.
1759
+ """
1760
+
1761
+ try:
1762
+ import graphviz as gv
1763
+ except ImportError:
1764
+ raise ImportError(
1765
+ "The feature requires `graphviz` but it is not available. "
1766
+ "Please install with `pip install graphviz`"
1767
+ )
1768
+ g = gv.Digraph(
1769
+ filename="{}{}.dot".format(
1770
+ filename_prefix,
1771
+ self.func_id.unique_name,
1772
+ )
1773
+ )
1774
+ # Populate the nodes
1775
+ for k, blk in self.blocks.items():
1776
+ with StringIO() as sb:
1777
+ blk.dump(sb)
1778
+ label = sb.getvalue()
1779
+ if include_ir:
1780
+ label = "".join(
1781
+ [r" {}\l".format(x) for x in label.splitlines()],
1782
+ )
1783
+ label = r"block {}\l".format(k) + label
1784
+ g.node(str(k), label=label, shape="rect")
1785
+ else:
1786
+ label = r"{}\l".format(k)
1787
+ g.node(str(k), label=label, shape="circle")
1788
+ # Populate the edges
1789
+ for src, blk in self.blocks.items():
1790
+ for dst in blk.terminator.get_targets():
1791
+ g.edge(str(src), str(dst))
1792
+ return g
1793
+
1794
+
1795
+ # A stub for undefined global reference
1796
+ class UndefinedType(EqualityCheckMixin):
1797
+ _singleton = None
1798
+
1799
+ def __new__(cls):
1800
+ obj = cls._singleton
1801
+ if obj is not None:
1802
+ return obj
1803
+ else:
1804
+ obj = object.__new__(cls)
1805
+ cls._singleton = obj
1806
+ return obj
1807
+
1808
+ def __repr__(self):
1809
+ return "Undefined"
1810
+
1811
+
1812
+ UNDEFINED = UndefinedType()