numba-cuda 0.21.1__cp313-cp313-win_amd64.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 (488) 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 +577 -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.cp313-win_amd64.pyd +0 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -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.cp313-win_amd64.pyd +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.cp313-win_amd64.pyd +0 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -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.cp313-win_amd64.pyd +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 +556 -0
  112. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  113. numba_cuda/numba/cuda/cudadrv/devicearray.py +951 -0
  114. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  115. numba_cuda/numba/cuda/cudadrv/driver.py +3222 -0
  116. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  117. numba_cuda/numba/cuda/cudadrv/dummyarray.py +558 -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 +995 -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 +903 -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 +158 -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/intrinsic_wrapper.py +41 -0
  161. numba_cuda/numba/cuda/intrinsics.py +382 -0
  162. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  163. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  164. numba_cuda/numba/cuda/kernels/reduction.py +265 -0
  165. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  166. numba_cuda/numba/cuda/libdevice.py +3386 -0
  167. numba_cuda/numba/cuda/libdevicedecl.py +20 -0
  168. numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
  169. numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
  170. numba_cuda/numba/cuda/locks.py +19 -0
  171. numba_cuda/numba/cuda/lowering.py +1951 -0
  172. numba_cuda/numba/cuda/mathimpl.py +374 -0
  173. numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
  174. numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
  175. numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
  176. numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
  177. numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
  178. numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
  179. numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
  180. numba_cuda/numba/cuda/misc/appdirs.py +594 -0
  181. numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
  182. numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
  183. numba_cuda/numba/cuda/misc/dump_style.py +41 -0
  184. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  185. numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
  186. numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
  187. numba_cuda/numba/cuda/misc/literal.py +28 -0
  188. numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
  189. numba_cuda/numba/cuda/misc/special.py +94 -0
  190. numba_cuda/numba/cuda/models.py +56 -0
  191. numba_cuda/numba/cuda/np/arraymath.py +5130 -0
  192. numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
  193. numba_cuda/numba/cuda/np/extensions.py +11 -0
  194. numba_cuda/numba/cuda/np/linalg.py +3087 -0
  195. numba_cuda/numba/cuda/np/math/__init__.py +0 -0
  196. numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
  197. numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
  198. numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
  199. numba_cuda/numba/cuda/np/npdatetime.py +969 -0
  200. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  201. numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
  202. numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
  203. numba_cuda/numba/cuda/np/numpy_support.py +798 -0
  204. numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
  205. numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
  206. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
  207. numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
  208. numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
  209. numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
  210. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
  211. numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
  212. numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
  213. numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
  214. numba_cuda/numba/cuda/nvvmutils.py +254 -0
  215. numba_cuda/numba/cuda/printimpl.py +126 -0
  216. numba_cuda/numba/cuda/random.py +308 -0
  217. numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
  218. numba_cuda/numba/cuda/serialize.py +267 -0
  219. numba_cuda/numba/cuda/simulator/__init__.py +63 -0
  220. numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
  221. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  222. numba_cuda/numba/cuda/simulator/api.py +179 -0
  223. numba_cuda/numba/cuda/simulator/bf16.py +4 -0
  224. numba_cuda/numba/cuda/simulator/compiler.py +38 -0
  225. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
  226. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
  227. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
  228. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
  229. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
  230. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
  231. numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
  232. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
  233. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
  234. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
  235. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
  236. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
  237. numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
  238. numba_cuda/numba/cuda/simulator/kernel.py +320 -0
  239. numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
  240. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
  241. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
  242. numba_cuda/numba/cuda/simulator/reduction.py +19 -0
  243. numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
  244. numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
  245. numba_cuda/numba/cuda/simulator_init.py +18 -0
  246. numba_cuda/numba/cuda/stubs.py +635 -0
  247. numba_cuda/numba/cuda/target.py +505 -0
  248. numba_cuda/numba/cuda/testing.py +347 -0
  249. numba_cuda/numba/cuda/tests/__init__.py +62 -0
  250. numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
  251. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
  252. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  253. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
  254. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  255. numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
  256. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
  257. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
  258. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
  259. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
  260. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
  261. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
  262. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +313 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +187 -0
  264. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
  265. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
  266. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
  267. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +198 -0
  268. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
  269. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
  270. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
  271. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
  272. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
  273. numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
  274. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
  275. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
  276. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
  277. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
  278. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
  279. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
  280. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
  281. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
  282. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
  283. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
  284. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
  285. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
  286. numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
  287. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
  288. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
  289. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
  290. numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
  291. numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
  292. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
  293. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
  294. numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
  295. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
  296. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
  297. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
  298. numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
  299. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
  300. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
  301. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
  302. numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
  303. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
  304. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
  305. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
  306. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
  307. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
  308. numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
  309. numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
  310. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
  311. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
  312. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
  313. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
  314. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
  315. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
  316. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
  317. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
  318. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
  319. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
  320. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
  321. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
  322. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
  323. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
  324. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +889 -0
  325. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  326. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
  327. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
  328. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
  329. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
  330. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
  331. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
  332. numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
  333. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
  334. numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
  335. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
  336. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
  337. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
  338. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
  339. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
  340. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
  341. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
  342. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
  343. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
  344. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
  345. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
  346. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
  347. numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
  348. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
  349. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
  350. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
  351. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
  352. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
  353. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
  354. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
  355. numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
  356. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
  357. numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
  358. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
  359. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
  360. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
  361. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
  362. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
  363. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
  364. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
  365. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
  366. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
  367. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
  368. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
  369. numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
  370. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
  371. numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
  372. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
  373. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
  374. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
  375. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  376. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
  377. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
  378. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
  379. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
  380. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
  381. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
  382. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
  383. numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
  384. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
  385. numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
  386. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  387. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
  388. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
  389. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
  390. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
  391. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
  392. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
  393. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
  394. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
  395. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
  396. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +331 -0
  397. numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
  398. numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
  399. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
  400. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  401. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
  402. numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
  403. numba_cuda/numba/cuda/tests/data/error.cu +12 -0
  404. numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
  405. numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
  406. numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
  407. numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
  408. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
  409. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  410. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
  411. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
  412. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
  413. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
  414. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
  415. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
  416. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
  417. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
  418. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
  419. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
  420. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
  421. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
  422. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
  423. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
  424. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
  425. numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
  426. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +391 -0
  427. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
  428. numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
  429. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
  430. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
  431. numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
  432. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
  433. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
  434. numba_cuda/numba/cuda/tests/support.py +900 -0
  435. numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
  436. numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
  437. numba_cuda/numba/cuda/typeconv/rules.py +63 -0
  438. numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
  439. numba_cuda/numba/cuda/types/__init__.py +233 -0
  440. numba_cuda/numba/cuda/types/__init__.pyi +167 -0
  441. numba_cuda/numba/cuda/types/abstract.py +9 -0
  442. numba_cuda/numba/cuda/types/common.py +9 -0
  443. numba_cuda/numba/cuda/types/containers.py +9 -0
  444. numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
  445. numba_cuda/numba/cuda/types/cuda_common.py +110 -0
  446. numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
  447. numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
  448. numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
  449. numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
  450. numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
  451. numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
  452. numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
  453. numba_cuda/numba/cuda/types/ext_types.py +101 -0
  454. numba_cuda/numba/cuda/types/function_type.py +11 -0
  455. numba_cuda/numba/cuda/types/functions.py +9 -0
  456. numba_cuda/numba/cuda/types/iterators.py +9 -0
  457. numba_cuda/numba/cuda/types/misc.py +9 -0
  458. numba_cuda/numba/cuda/types/npytypes.py +9 -0
  459. numba_cuda/numba/cuda/types/scalars.py +9 -0
  460. numba_cuda/numba/cuda/typing/__init__.py +19 -0
  461. numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
  462. numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
  463. numba_cuda/numba/cuda/typing/bufproto.py +70 -0
  464. numba_cuda/numba/cuda/typing/builtins.py +1209 -0
  465. numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
  466. numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
  467. numba_cuda/numba/cuda/typing/collections.py +138 -0
  468. numba_cuda/numba/cuda/typing/context.py +782 -0
  469. numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
  470. numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
  471. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  472. numba_cuda/numba/cuda/typing/listdecl.py +147 -0
  473. numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
  474. numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
  475. numba_cuda/numba/cuda/typing/npydecl.py +749 -0
  476. numba_cuda/numba/cuda/typing/setdecl.py +115 -0
  477. numba_cuda/numba/cuda/typing/templates.py +1446 -0
  478. numba_cuda/numba/cuda/typing/typeof.py +301 -0
  479. numba_cuda/numba/cuda/ufuncs.py +746 -0
  480. numba_cuda/numba/cuda/utils.py +724 -0
  481. numba_cuda/numba/cuda/vector_types.py +214 -0
  482. numba_cuda/numba/cuda/vectorizers.py +260 -0
  483. numba_cuda-0.21.1.dist-info/METADATA +109 -0
  484. numba_cuda-0.21.1.dist-info/RECORD +488 -0
  485. numba_cuda-0.21.1.dist-info/WHEEL +5 -0
  486. numba_cuda-0.21.1.dist-info/licenses/LICENSE +26 -0
  487. numba_cuda-0.21.1.dist-info/licenses/LICENSE.numba +24 -0
  488. numba_cuda-0.21.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1950 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ # ========================================================================== #
5
+ # #
6
+ # IMPORTANT: Before modifying type inference, it is important to port the #
7
+ # following tests from `numba.tests.test_typeinfer`: #
8
+ # #
9
+ # - TestArgRetCasting #
10
+ # - TestUnifyUseCases #
11
+ # - TestMiscIssues, with exceptions: #
12
+ # - test_list_unify{1,2}: Lists not supported #
13
+ # - test_load_fast_and_clear*: Uses list comprehensions #
14
+ # #
15
+ # ========================================================================== #
16
+ """
17
+ Type inference base on CPA.
18
+ The algorithm guarantees monotonic growth of type-sets for each variable.
19
+
20
+ Steps:
21
+ 1. seed initial types
22
+ 2. build constraints
23
+ 3. propagate constraints
24
+ 4. unify types
25
+
26
+ Constraint propagation is precise and does not regret (no backtracing).
27
+ Constraints push types forward following the dataflow.
28
+ """
29
+
30
+ import logging
31
+ import operator
32
+ import contextlib
33
+ import itertools
34
+ from pprint import pprint
35
+ from collections import OrderedDict, defaultdict
36
+ from functools import reduce
37
+
38
+ from numba.cuda import types, utils, config
39
+ from numba.cuda.core import ir
40
+ from numba.cuda import typing
41
+ from numba.cuda.typing.templates import Signature
42
+ from numba.cuda.core.errors import (
43
+ TypingError,
44
+ UntypedAttributeError,
45
+ new_error_context,
46
+ termcolor,
47
+ UnsupportedError,
48
+ ForceLiteralArg,
49
+ CompilerError,
50
+ NumbaValueError,
51
+ )
52
+ from numba.cuda.core.funcdesc import qualifying_prefix
53
+ from numba.cuda.typeconv import Conversion
54
+
55
+ _logger = logging.getLogger(__name__)
56
+
57
+
58
+ class NOTSET:
59
+ pass
60
+
61
+
62
+ # terminal color markup
63
+ _termcolor = termcolor()
64
+
65
+
66
+ class TypeVar(object):
67
+ def __init__(self, context, var):
68
+ self.context = context
69
+ self.var = var
70
+ self.type = None
71
+ self.locked = False
72
+ # Stores source location of first definition
73
+ self.define_loc = None
74
+ # Qualifiers
75
+ self.literal_value = NOTSET
76
+
77
+ def add_type(self, tp, loc):
78
+ assert isinstance(tp, types.Type), type(tp)
79
+ # Special case for _undef_var.
80
+ # If the typevar is the _undef_var, use the incoming type directly.
81
+ if self.type is types._undef_var:
82
+ self.type = tp
83
+ return self.type
84
+
85
+ if self.locked:
86
+ if tp != self.type:
87
+ if self.context.can_convert(tp, self.type) is None:
88
+ msg = "No conversion from %s to %s for '%s', defined at %s"
89
+ raise TypingError(
90
+ msg % (tp, self.type, self.var, self.define_loc),
91
+ loc=loc,
92
+ )
93
+ else:
94
+ if self.type is not None:
95
+ unified = self.context.unify_pairs(self.type, tp)
96
+ if unified is None:
97
+ msg = "Cannot unify %s and %s for '%s', defined at %s"
98
+ raise TypingError(
99
+ msg % (self.type, tp, self.var, self.define_loc),
100
+ loc=self.define_loc,
101
+ )
102
+ else:
103
+ # First time definition
104
+ unified = tp
105
+ self.define_loc = loc
106
+
107
+ self.type = unified
108
+
109
+ return self.type
110
+
111
+ def lock(self, tp, loc, literal_value=NOTSET):
112
+ assert isinstance(tp, types.Type), type(tp)
113
+
114
+ if self.locked:
115
+ msg = (
116
+ "Invalid reassignment of a type-variable detected, type "
117
+ "variables are locked according to the user provided "
118
+ "function signature or from an ir.Const node. This is a "
119
+ "bug! Type={}. {}"
120
+ ).format(tp, self.type)
121
+ raise CompilerError(msg, loc)
122
+
123
+ # If there is already a type, ensure we can convert it to the
124
+ # locked type.
125
+ if (
126
+ self.type is not None
127
+ and self.context.can_convert(self.type, tp) is None
128
+ ):
129
+ raise TypingError(
130
+ "No conversion from %s to %s for "
131
+ "'%s'" % (tp, self.type, self.var),
132
+ loc=loc,
133
+ )
134
+
135
+ self.type = tp
136
+ self.locked = True
137
+ if self.define_loc is None:
138
+ self.define_loc = loc
139
+ self.literal_value = literal_value
140
+
141
+ def union(self, other, loc):
142
+ if other.type is not None:
143
+ self.add_type(other.type, loc=loc)
144
+
145
+ return self.type
146
+
147
+ def __repr__(self):
148
+ return "%s := %s" % (self.var, self.type or "<undecided>")
149
+
150
+ @property
151
+ def defined(self):
152
+ return self.type is not None
153
+
154
+ def get(self):
155
+ return (self.type,) if self.type is not None else ()
156
+
157
+ def getone(self):
158
+ if self.type is None:
159
+ raise TypingError("Undecided type {}".format(self))
160
+ return self.type
161
+
162
+ def __len__(self):
163
+ return 1 if self.type is not None else 0
164
+
165
+
166
+ class ConstraintNetwork(object):
167
+ """
168
+ TODO: It is possible to optimize constraint propagation to consider only
169
+ dirty type variables.
170
+ """
171
+
172
+ def __init__(self):
173
+ self.constraints = []
174
+
175
+ def append(self, constraint):
176
+ self.constraints.append(constraint)
177
+
178
+ def propagate(self, typeinfer):
179
+ """
180
+ Execute all constraints. Errors are caught and returned as a list.
181
+ This allows progressing even though some constraints may fail
182
+ due to lack of information
183
+ (e.g. imprecise types such as List(undefined)).
184
+ """
185
+ errors = []
186
+ for constraint in self.constraints:
187
+ loc = constraint.loc
188
+ with typeinfer.warnings.catch_warnings(
189
+ filename=loc.filename, lineno=loc.line
190
+ ):
191
+ try:
192
+ constraint(typeinfer)
193
+ except ForceLiteralArg as e:
194
+ errors.append(e)
195
+ except TypingError as e:
196
+ _logger.debug("captured error", exc_info=e)
197
+ new_exc = TypingError(
198
+ str(e),
199
+ loc=constraint.loc,
200
+ highlighting=False,
201
+ )
202
+ errors.append(utils.chain_exception(new_exc, e))
203
+
204
+ return errors
205
+
206
+
207
+ class Propagate(object):
208
+ """
209
+ A simple constraint for direct propagation of types for assignments.
210
+ """
211
+
212
+ def __init__(self, dst, src, loc):
213
+ self.dst = dst
214
+ self.src = src
215
+ self.loc = loc
216
+
217
+ def __call__(self, typeinfer):
218
+ with new_error_context(
219
+ "typing of assignment at {0}", self.loc, loc=self.loc
220
+ ):
221
+ typeinfer.copy_type(self.src, self.dst, loc=self.loc)
222
+ # If `dst` is refined, notify us
223
+ typeinfer.refine_map[self.dst] = self
224
+
225
+ def refine(self, typeinfer, target_type):
226
+ # Do not back-propagate to locked variables (e.g. constants)
227
+ assert target_type.is_precise()
228
+ typeinfer.add_type(
229
+ self.src, target_type, unless_locked=True, loc=self.loc
230
+ )
231
+
232
+
233
+ class ArgConstraint(object):
234
+ def __init__(self, dst, src, loc):
235
+ self.dst = dst
236
+ self.src = src
237
+ self.loc = loc
238
+
239
+ def __call__(self, typeinfer):
240
+ with new_error_context("typing of argument at {0}", self.loc):
241
+ typevars = typeinfer.typevars
242
+ src = typevars[self.src]
243
+ if not src.defined:
244
+ return
245
+ ty = src.getone()
246
+ if isinstance(ty, types.Omitted):
247
+ ty = typeinfer.context.resolve_value_type_prefer_literal(
248
+ ty.value,
249
+ )
250
+ if not ty.is_precise():
251
+ raise TypingError("non-precise type {}".format(ty))
252
+ typeinfer.add_type(self.dst, ty, loc=self.loc)
253
+
254
+
255
+ class BuildTupleConstraint(object):
256
+ def __init__(self, target, items, loc):
257
+ self.target = target
258
+ self.items = items
259
+ self.loc = loc
260
+
261
+ def __call__(self, typeinfer):
262
+ with new_error_context("typing of tuple at {0}", self.loc):
263
+ typevars = typeinfer.typevars
264
+ tsets = [typevars[i.name].get() for i in self.items]
265
+ for vals in itertools.product(*tsets):
266
+ if vals and all(vals[0] == v for v in vals):
267
+ tup = types.UniTuple(dtype=vals[0], count=len(vals))
268
+ else:
269
+ # empty tuples fall here as well
270
+ tup = types.Tuple(vals)
271
+ assert tup.is_precise()
272
+ typeinfer.add_type(self.target, tup, loc=self.loc)
273
+
274
+
275
+ class _BuildContainerConstraint(object):
276
+ def __init__(self, target, items, loc):
277
+ self.target = target
278
+ self.items = items
279
+ self.loc = loc
280
+
281
+ def __call__(self, typeinfer):
282
+ with new_error_context(
283
+ "typing of {0} at {1}", self.container_type, self.loc
284
+ ):
285
+ typevars = typeinfer.typevars
286
+ tsets = [typevars[i.name].get() for i in self.items]
287
+ if not tsets:
288
+ typeinfer.add_type(
289
+ self.target,
290
+ self.container_type(types.undefined),
291
+ loc=self.loc,
292
+ )
293
+ else:
294
+ for typs in itertools.product(*tsets):
295
+ unified = typeinfer.context.unify_types(*typs)
296
+ if unified is not None:
297
+ typeinfer.add_type(
298
+ self.target,
299
+ self.container_type(unified),
300
+ loc=self.loc,
301
+ )
302
+
303
+
304
+ class BuildListConstraint(_BuildContainerConstraint):
305
+ def __init__(self, target, items, loc):
306
+ self.target = target
307
+ self.items = items
308
+ self.loc = loc
309
+
310
+ def __call__(self, typeinfer):
311
+ with new_error_context("typing of {0} at {1}", types.List, self.loc):
312
+ typevars = typeinfer.typevars
313
+ tsets = [typevars[i.name].get() for i in self.items]
314
+ if not tsets:
315
+ typeinfer.add_type(
316
+ self.target, types.List(types.undefined), loc=self.loc
317
+ )
318
+ else:
319
+ for typs in itertools.product(*tsets):
320
+ unified = typeinfer.context.unify_types(*typs)
321
+ if unified is not None:
322
+ # pull out literals if available
323
+ islit = [isinstance(x, types.Literal) for x in typs]
324
+ iv = None
325
+ if all(islit):
326
+ iv = [x.literal_value for x in typs]
327
+ typeinfer.add_type(
328
+ self.target,
329
+ types.List(unified, initial_value=iv),
330
+ loc=self.loc,
331
+ )
332
+ else:
333
+ typeinfer.add_type(
334
+ self.target, types.LiteralList(typs), loc=self.loc
335
+ )
336
+
337
+
338
+ class BuildSetConstraint(_BuildContainerConstraint):
339
+ container_type = types.Set
340
+
341
+
342
+ class BuildMapConstraint(object):
343
+ def __init__(self, target, items, special_value, value_indexes, loc):
344
+ self.target = target
345
+ self.items = items
346
+ self.special_value = special_value
347
+ self.value_indexes = value_indexes
348
+ self.loc = loc
349
+
350
+ def __call__(self, typeinfer):
351
+ with new_error_context("typing of dict at {0}", self.loc):
352
+ typevars = typeinfer.typevars
353
+
354
+ # figure out what sort of dict is being dealt with
355
+ tsets = [
356
+ (typevars[k.name].getone(), typevars[v.name].getone())
357
+ for k, v in self.items
358
+ ]
359
+
360
+ if not tsets:
361
+ typeinfer.add_type(
362
+ self.target,
363
+ types.DictType(
364
+ types.undefined, types.undefined, self.special_value
365
+ ),
366
+ loc=self.loc,
367
+ )
368
+ else:
369
+ # all the info is known about the dict, if its
370
+ # str keys -> random heterogeneous values treat as literalstrkey
371
+ ktys = [x[0] for x in tsets]
372
+ vtys = [x[1] for x in tsets]
373
+ strkey = all([isinstance(x, types.StringLiteral) for x in ktys])
374
+ literalvty = all([isinstance(x, types.Literal) for x in vtys])
375
+ vt0 = types.unliteral(vtys[0])
376
+
377
+ # homogeneous values comes in the form of being able to cast
378
+ # all the other values in the ctor to the type of the first.
379
+ # The order is important as `typed.Dict` takes it's type from
380
+ # the first element.
381
+ def check(other):
382
+ conv = typeinfer.context.can_convert(other, vt0)
383
+ return conv is not None and conv < Conversion.unsafe
384
+
385
+ homogeneous = all([check(types.unliteral(x)) for x in vtys])
386
+
387
+ # Special cases:
388
+ # Single key:value in ctor, key is str, value is an otherwise
389
+ # illegal container type, e.g. LiteralStrKeyDict or
390
+ # List, there's no way to put this into a typed.Dict, so make it
391
+ # a LiteralStrKeyDict, same goes for LiteralList.
392
+ if len(vtys) == 1:
393
+ valty = vtys[0]
394
+ if isinstance(
395
+ valty,
396
+ (
397
+ types.LiteralStrKeyDict,
398
+ types.List,
399
+ types.LiteralList,
400
+ ),
401
+ ):
402
+ homogeneous = False
403
+
404
+ if strkey and not homogeneous:
405
+ resolved_dict = {x: y for x, y in zip(ktys, vtys)}
406
+ ty = types.LiteralStrKeyDict(
407
+ resolved_dict, self.value_indexes
408
+ )
409
+ typeinfer.add_type(self.target, ty, loc=self.loc)
410
+ else:
411
+ init_value = self.special_value if literalvty else None
412
+ key_type, value_type = tsets[0]
413
+ typeinfer.add_type(
414
+ self.target,
415
+ types.DictType(key_type, value_type, init_value),
416
+ loc=self.loc,
417
+ )
418
+
419
+
420
+ class ExhaustIterConstraint(object):
421
+ def __init__(self, target, count, iterator, loc):
422
+ self.target = target
423
+ self.count = count
424
+ self.iterator = iterator
425
+ self.loc = loc
426
+
427
+ def __call__(self, typeinfer):
428
+ with new_error_context("typing of exhaust iter at {0}", self.loc):
429
+ typevars = typeinfer.typevars
430
+ for tp in typevars[self.iterator.name].get():
431
+ # unpack optional
432
+ tp = tp.type if isinstance(tp, types.Optional) else tp
433
+ if isinstance(tp, types.BaseTuple):
434
+ if len(tp) == self.count:
435
+ assert tp.is_precise()
436
+ typeinfer.add_type(self.target, tp, loc=self.loc)
437
+ break
438
+ else:
439
+ msg = (
440
+ f"wrong tuple length for {self.iterator.name}: ",
441
+ f"expected {self.count}, got {len(tp)}",
442
+ )
443
+ raise NumbaValueError(msg)
444
+ elif isinstance(tp, types.IterableType):
445
+ tup = types.UniTuple(
446
+ dtype=tp.iterator_type.yield_type, count=self.count
447
+ )
448
+ assert tup.is_precise()
449
+ typeinfer.add_type(self.target, tup, loc=self.loc)
450
+ break
451
+ else:
452
+ raise TypingError(
453
+ "failed to unpack {}".format(tp), loc=self.loc
454
+ )
455
+
456
+
457
+ class PairFirstConstraint(object):
458
+ def __init__(self, target, pair, loc):
459
+ self.target = target
460
+ self.pair = pair
461
+ self.loc = loc
462
+
463
+ def __call__(self, typeinfer):
464
+ with new_error_context("typing of pair-first at {0}", self.loc):
465
+ typevars = typeinfer.typevars
466
+ for tp in typevars[self.pair.name].get():
467
+ if not isinstance(tp, types.Pair):
468
+ # XXX is this an error?
469
+ continue
470
+ assert (
471
+ isinstance(tp.first_type, types.UndefinedFunctionType)
472
+ or tp.first_type.is_precise()
473
+ )
474
+ typeinfer.add_type(self.target, tp.first_type, loc=self.loc)
475
+
476
+
477
+ class PairSecondConstraint(object):
478
+ def __init__(self, target, pair, loc):
479
+ self.target = target
480
+ self.pair = pair
481
+ self.loc = loc
482
+
483
+ def __call__(self, typeinfer):
484
+ with new_error_context("typing of pair-second at {0}", self.loc):
485
+ typevars = typeinfer.typevars
486
+ for tp in typevars[self.pair.name].get():
487
+ if not isinstance(tp, types.Pair):
488
+ # XXX is this an error?
489
+ continue
490
+ assert tp.second_type.is_precise()
491
+ typeinfer.add_type(self.target, tp.second_type, loc=self.loc)
492
+
493
+
494
+ class StaticGetItemConstraint(object):
495
+ def __init__(self, target, value, index, index_var, loc):
496
+ self.target = target
497
+ self.value = value
498
+ self.index = index
499
+ if index_var is not None:
500
+ self.fallback = IntrinsicCallConstraint(
501
+ target, operator.getitem, (value, index_var), {}, None, loc
502
+ )
503
+ else:
504
+ self.fallback = None
505
+ self.loc = loc
506
+
507
+ def __call__(self, typeinfer):
508
+ with new_error_context("typing of static-get-item at {0}", self.loc):
509
+ typevars = typeinfer.typevars
510
+ for ty in typevars[self.value.name].get():
511
+ sig = typeinfer.context.resolve_static_getitem(
512
+ value=ty,
513
+ index=self.index,
514
+ )
515
+
516
+ if sig is not None:
517
+ itemty = sig.return_type
518
+ # if the itemty is not precise, let it through, unification
519
+ # will catch it and produce a better error message
520
+ typeinfer.add_type(self.target, itemty, loc=self.loc)
521
+ elif self.fallback is not None:
522
+ self.fallback(typeinfer)
523
+
524
+ def get_call_signature(self):
525
+ # The signature is only needed for the fallback case in lowering
526
+ return self.fallback and self.fallback.get_call_signature()
527
+
528
+
529
+ class TypedGetItemConstraint(object):
530
+ def __init__(self, target, value, dtype, index, loc):
531
+ self.target = target
532
+ self.value = value
533
+ self.dtype = dtype
534
+ self.index = index
535
+ self.loc = loc
536
+
537
+ def __call__(self, typeinfer):
538
+ with new_error_context("typing of typed-get-item at {0}", self.loc):
539
+ typevars = typeinfer.typevars
540
+ idx_ty = typevars[self.index.name].get()
541
+ ty = typevars[self.value.name].get()
542
+ self.signature = Signature(self.dtype, ty + idx_ty, None)
543
+ typeinfer.add_type(self.target, self.dtype, loc=self.loc)
544
+
545
+ def get_call_signature(self):
546
+ return self.signature
547
+
548
+
549
+ def fold_arg_vars(typevars, args, vararg, kws):
550
+ """
551
+ Fold and resolve the argument variables of a function call.
552
+ """
553
+ # Fetch all argument types, bail if any is unknown
554
+ n_pos_args = len(args)
555
+ kwds = [kw for (kw, var) in kws]
556
+ argtypes = [typevars[a.name] for a in args]
557
+ argtypes += [typevars[var.name] for (kw, var) in kws]
558
+ if vararg is not None:
559
+ argtypes.append(typevars[vararg.name])
560
+
561
+ if not all(a.defined for a in argtypes):
562
+ return
563
+
564
+ args = tuple(a.getone() for a in argtypes)
565
+
566
+ pos_args = args[:n_pos_args]
567
+ if vararg is not None:
568
+ errmsg = "*args in function call should be a tuple, got %s"
569
+ # Handle constant literal used for `*args`
570
+ if isinstance(args[-1], types.Literal):
571
+ const_val = args[-1].literal_value
572
+ # Is the constant value a tuple?
573
+ if not isinstance(const_val, tuple):
574
+ raise TypingError(errmsg % (args[-1],))
575
+ # Append the elements in the const tuple to the positional args
576
+ pos_args += const_val
577
+ # Handle non-constant
578
+ elif not isinstance(args[-1], types.BaseTuple):
579
+ # Unsuitable for *args
580
+ # (Python is more lenient and accepts all iterables)
581
+ raise TypingError(errmsg % (args[-1],))
582
+ else:
583
+ # Append the elements in the tuple to the positional args
584
+ pos_args += args[-1].types
585
+ # Drop the last arg
586
+ args = args[:-1]
587
+ kw_args = dict(zip(kwds, args[n_pos_args:]))
588
+ return pos_args, kw_args
589
+
590
+
591
+ def _is_array_not_precise(arrty):
592
+ """Check type is array and it is not precise"""
593
+ return isinstance(arrty, types.Array) and not arrty.is_precise()
594
+
595
+
596
+ class CallConstraint(object):
597
+ """Constraint for calling functions.
598
+ Perform case analysis foreach combinations of argument types.
599
+ """
600
+
601
+ signature = None
602
+
603
+ def __init__(self, target, func, args, kws, vararg, loc):
604
+ self.target = target
605
+ self.func = func
606
+ self.args = args
607
+ self.kws = kws or {}
608
+ self.vararg = vararg
609
+ self.loc = loc
610
+
611
+ def __call__(self, typeinfer):
612
+ msg = "typing of call at {0}\n".format(self.loc)
613
+ with new_error_context(msg):
614
+ typevars = typeinfer.typevars
615
+ with new_error_context(
616
+ "resolving caller type: {}".format(self.func)
617
+ ):
618
+ fnty = typevars[self.func].getone()
619
+ with new_error_context("resolving callee type: {0}", fnty):
620
+ self.resolve(typeinfer, typevars, fnty)
621
+
622
+ def resolve(self, typeinfer, typevars, fnty):
623
+ assert fnty
624
+ context = typeinfer.context
625
+
626
+ r = fold_arg_vars(typevars, self.args, self.vararg, self.kws)
627
+ if r is None:
628
+ # Cannot resolve call type until all argument types are known
629
+ return
630
+ pos_args, kw_args = r
631
+
632
+ # Check argument to be precise
633
+ for a in itertools.chain(pos_args, kw_args.values()):
634
+ # Forbids imprecise type except array of undefined dtype
635
+ if not a.is_precise() and not isinstance(a, types.Array):
636
+ return
637
+
638
+ # Resolve call type
639
+ if isinstance(fnty, types.TypeRef):
640
+ # Unwrap TypeRef
641
+ fnty = fnty.instance_type
642
+ try:
643
+ sig = typeinfer.resolve_call(fnty, pos_args, kw_args)
644
+ except ForceLiteralArg as e:
645
+ # Adjust for bound methods
646
+ folding_args = (
647
+ (fnty.this,) + tuple(self.args)
648
+ if isinstance(fnty, types.BoundFunction)
649
+ else self.args
650
+ )
651
+ folded = e.fold_arguments(folding_args, self.kws)
652
+ requested = set()
653
+ unsatisfied = set()
654
+ for idx in e.requested_args:
655
+ maybe_arg = typeinfer.func_ir.get_definition(folded[idx])
656
+ if isinstance(maybe_arg, ir.Arg):
657
+ requested.add(maybe_arg.index)
658
+ else:
659
+ unsatisfied.add(idx)
660
+ if unsatisfied:
661
+ raise TypingError("Cannot request literal type.", loc=self.loc)
662
+ elif requested:
663
+ raise ForceLiteralArg(requested, loc=self.loc)
664
+ if sig is None:
665
+ # Note: duplicated error checking.
666
+ # See types.BaseFunction.get_call_type
667
+ # Arguments are invalid => explain why
668
+ headtemp = "Invalid use of {0} with parameters ({1})"
669
+ args = [str(a) for a in pos_args]
670
+ args += ["%s=%s" % (k, v) for k, v in sorted(kw_args.items())]
671
+ head = headtemp.format(fnty, ", ".join(map(str, args)))
672
+ desc = context.explain_function_type(fnty)
673
+ msg = "\n".join([head, desc])
674
+ raise TypingError(msg)
675
+
676
+ typeinfer.add_type(self.target, sig.return_type, loc=self.loc)
677
+
678
+ # If the function is a bound function and its receiver type
679
+ # was refined, propagate it.
680
+ if (
681
+ isinstance(fnty, types.BoundFunction)
682
+ and sig.recvr is not None
683
+ and sig.recvr != fnty.this
684
+ ):
685
+ refined_this = context.unify_pairs(sig.recvr, fnty.this)
686
+ if (
687
+ refined_this is None
688
+ and fnty.this.is_precise()
689
+ and sig.recvr.is_precise()
690
+ ):
691
+ msg = "Cannot refine type {} to {}".format(
692
+ sig.recvr,
693
+ fnty.this,
694
+ )
695
+ raise TypingError(msg, loc=self.loc)
696
+ if refined_this is not None and refined_this.is_precise():
697
+ refined_fnty = fnty.copy(this=refined_this)
698
+ typeinfer.propagate_refined_type(self.func, refined_fnty)
699
+
700
+ # If the return type is imprecise but can be unified with the
701
+ # target variable's inferred type, use the latter.
702
+ # Useful for code such as::
703
+ # s = set()
704
+ # s.add(1)
705
+ # (the set() call must be typed as int64(), not undefined())
706
+ if not sig.return_type.is_precise():
707
+ target = typevars[self.target]
708
+ if target.defined:
709
+ targetty = target.getone()
710
+ if context.unify_pairs(targetty, sig.return_type) == targetty:
711
+ sig = sig.replace(return_type=targetty)
712
+
713
+ self.signature = sig
714
+ self._add_refine_map(typeinfer, typevars, sig)
715
+
716
+ def _add_refine_map(self, typeinfer, typevars, sig):
717
+ """Add this expression to the refine_map base on the type of target_type"""
718
+ target_type = typevars[self.target].getone()
719
+ # Array
720
+ if isinstance(target_type, types.Array) and isinstance(
721
+ sig.return_type.dtype, types.Undefined
722
+ ):
723
+ typeinfer.refine_map[self.target] = self
724
+ # DictType
725
+ if (
726
+ isinstance(target_type, types.DictType)
727
+ and not target_type.is_precise()
728
+ ):
729
+ typeinfer.refine_map[self.target] = self
730
+
731
+ def refine(self, typeinfer, updated_type):
732
+ # Is getitem?
733
+ if self.func == operator.getitem:
734
+ aryty = typeinfer.typevars[self.args[0].name].getone()
735
+ # is array not precise?
736
+ if _is_array_not_precise(aryty):
737
+ # allow refinement of dtype
738
+ assert updated_type.is_precise()
739
+ newtype = aryty.copy(dtype=updated_type.dtype)
740
+ typeinfer.add_type(self.args[0].name, newtype, loc=self.loc)
741
+ else:
742
+ m = "no type refinement implemented for function {} updating to {}"
743
+ raise TypingError(m.format(self.func, updated_type))
744
+
745
+ def get_call_signature(self):
746
+ return self.signature
747
+
748
+
749
+ class IntrinsicCallConstraint(CallConstraint):
750
+ def __call__(self, typeinfer):
751
+ with new_error_context("typing of intrinsic-call at {0}", self.loc):
752
+ fnty = self.func
753
+ if fnty in utils.OPERATORS_TO_BUILTINS:
754
+ fnty = typeinfer.resolve_value_type(None, fnty)
755
+ self.resolve(typeinfer, typeinfer.typevars, fnty=fnty)
756
+
757
+
758
+ class GetAttrConstraint(object):
759
+ def __init__(self, target, attr, value, loc, inst):
760
+ self.target = target
761
+ self.attr = attr
762
+ self.value = value
763
+ self.loc = loc
764
+ self.inst = inst
765
+
766
+ def __call__(self, typeinfer):
767
+ with new_error_context("typing of get attribute at {0}", self.loc):
768
+ typevars = typeinfer.typevars
769
+ valtys = typevars[self.value.name].get()
770
+ for ty in valtys:
771
+ attrty = typeinfer.context.resolve_getattr(ty, self.attr)
772
+ if attrty is None:
773
+ raise UntypedAttributeError(
774
+ ty, self.attr, loc=self.inst.loc
775
+ )
776
+ else:
777
+ assert attrty.is_precise()
778
+ typeinfer.add_type(self.target, attrty, loc=self.loc)
779
+ typeinfer.refine_map[self.target] = self
780
+
781
+ def refine(self, typeinfer, target_type):
782
+ if isinstance(target_type, types.BoundFunction):
783
+ recvr = target_type.this
784
+ assert recvr.is_precise()
785
+ typeinfer.add_type(self.value.name, recvr, loc=self.loc)
786
+ source_constraint = typeinfer.refine_map.get(self.value.name)
787
+ if source_constraint is not None:
788
+ source_constraint.refine(typeinfer, recvr)
789
+
790
+ def __repr__(self):
791
+ return 'resolving type of attribute "{attr}" of "{value}"'.format(
792
+ value=self.value, attr=self.attr
793
+ )
794
+
795
+
796
+ class SetItemRefinement(object):
797
+ """A mixin class to provide the common refinement logic in setitem
798
+ and static setitem.
799
+ """
800
+
801
+ def _refine_target_type(self, typeinfer, targetty, idxty, valty, sig):
802
+ """Refine the target-type given the known index type and value type."""
803
+ # For array setitem, refine imprecise array dtype
804
+ if _is_array_not_precise(targetty):
805
+ typeinfer.add_type(self.target.name, sig.args[0], loc=self.loc)
806
+ # For Dict setitem
807
+ if isinstance(targetty, types.DictType):
808
+ if not targetty.is_precise():
809
+ refined = targetty.refine(idxty, valty)
810
+ typeinfer.add_type(
811
+ self.target.name,
812
+ refined,
813
+ loc=self.loc,
814
+ )
815
+ elif isinstance(targetty, types.LiteralStrKeyDict):
816
+ typeinfer.add_type(
817
+ self.target.name,
818
+ types.DictType(idxty, valty),
819
+ loc=self.loc,
820
+ )
821
+
822
+
823
+ class SetItemConstraint(SetItemRefinement):
824
+ def __init__(self, target, index, value, loc):
825
+ self.target = target
826
+ self.index = index
827
+ self.value = value
828
+ self.loc = loc
829
+
830
+ def __call__(self, typeinfer):
831
+ with new_error_context("typing of setitem at {0}", self.loc):
832
+ typevars = typeinfer.typevars
833
+ if not all(
834
+ typevars[var.name].defined
835
+ for var in (self.target, self.index, self.value)
836
+ ):
837
+ return
838
+ targetty = typevars[self.target.name].getone()
839
+ idxty = typevars[self.index.name].getone()
840
+ valty = typevars[self.value.name].getone()
841
+
842
+ sig = typeinfer.context.resolve_setitem(targetty, idxty, valty)
843
+ if sig is None:
844
+ raise TypingError(
845
+ "Cannot resolve setitem: %s[%s] = %s"
846
+ % (targetty, idxty, valty),
847
+ loc=self.loc,
848
+ )
849
+
850
+ self.signature = sig
851
+ self._refine_target_type(typeinfer, targetty, idxty, valty, sig)
852
+
853
+ def get_call_signature(self):
854
+ return self.signature
855
+
856
+
857
+ class StaticSetItemConstraint(SetItemRefinement):
858
+ def __init__(self, target, index, index_var, value, loc):
859
+ self.target = target
860
+ self.index = index
861
+ self.index_var = index_var
862
+ self.value = value
863
+ self.loc = loc
864
+
865
+ def __call__(self, typeinfer):
866
+ with new_error_context("typing of staticsetitem at {0}", self.loc):
867
+ typevars = typeinfer.typevars
868
+ if not all(
869
+ typevars[var.name].defined
870
+ for var in (self.target, self.index_var, self.value)
871
+ ):
872
+ return
873
+ targetty = typevars[self.target.name].getone()
874
+ idxty = typevars[self.index_var.name].getone()
875
+ valty = typevars[self.value.name].getone()
876
+
877
+ sig = typeinfer.context.resolve_static_setitem(
878
+ targetty, self.index, valty
879
+ )
880
+ if sig is None:
881
+ sig = typeinfer.context.resolve_setitem(targetty, idxty, valty)
882
+ if sig is None:
883
+ raise TypingError(
884
+ "Cannot resolve setitem: %s[%r] = %s"
885
+ % (targetty, self.index, valty),
886
+ loc=self.loc,
887
+ )
888
+ self.signature = sig
889
+ self._refine_target_type(typeinfer, targetty, idxty, valty, sig)
890
+
891
+ def get_call_signature(self):
892
+ return self.signature
893
+
894
+
895
+ class DelItemConstraint(object):
896
+ def __init__(self, target, index, loc):
897
+ self.target = target
898
+ self.index = index
899
+ self.loc = loc
900
+
901
+ def __call__(self, typeinfer):
902
+ with new_error_context("typing of delitem at {0}", self.loc):
903
+ typevars = typeinfer.typevars
904
+ if not all(
905
+ typevars[var.name].defined for var in (self.target, self.index)
906
+ ):
907
+ return
908
+ targetty = typevars[self.target.name].getone()
909
+ idxty = typevars[self.index.name].getone()
910
+
911
+ sig = typeinfer.context.resolve_delitem(targetty, idxty)
912
+ if sig is None:
913
+ raise TypingError(
914
+ "Cannot resolve delitem: %s[%s]" % (targetty, idxty),
915
+ loc=self.loc,
916
+ )
917
+ self.signature = sig
918
+
919
+ def get_call_signature(self):
920
+ return self.signature
921
+
922
+
923
+ class SetAttrConstraint(object):
924
+ def __init__(self, target, attr, value, loc):
925
+ self.target = target
926
+ self.attr = attr
927
+ self.value = value
928
+ self.loc = loc
929
+
930
+ def __call__(self, typeinfer):
931
+ with new_error_context(
932
+ "typing of set attribute {0!r} at {1}", self.attr, self.loc
933
+ ):
934
+ typevars = typeinfer.typevars
935
+ if not all(
936
+ typevars[var.name].defined for var in (self.target, self.value)
937
+ ):
938
+ return
939
+ targetty = typevars[self.target.name].getone()
940
+ valty = typevars[self.value.name].getone()
941
+ sig = typeinfer.context.resolve_setattr(targetty, self.attr, valty)
942
+ if sig is None:
943
+ raise TypingError(
944
+ "Cannot resolve setattr: (%s).%s = %s"
945
+ % (targetty, self.attr, valty),
946
+ loc=self.loc,
947
+ )
948
+ self.signature = sig
949
+
950
+ def get_call_signature(self):
951
+ return self.signature
952
+
953
+
954
+ class PrintConstraint(object):
955
+ def __init__(self, args, vararg, loc):
956
+ self.args = args
957
+ self.vararg = vararg
958
+ self.loc = loc
959
+
960
+ def __call__(self, typeinfer):
961
+ typevars = typeinfer.typevars
962
+
963
+ r = fold_arg_vars(typevars, self.args, self.vararg, {})
964
+ if r is None:
965
+ # Cannot resolve call type until all argument types are known
966
+ return
967
+ pos_args, kw_args = r
968
+
969
+ fnty = typeinfer.context.resolve_value_type(print)
970
+ assert fnty is not None
971
+ sig = typeinfer.resolve_call(fnty, pos_args, kw_args)
972
+ self.signature = sig
973
+
974
+ def get_call_signature(self):
975
+ return self.signature
976
+
977
+
978
+ class TypeVarMap(dict):
979
+ def set_context(self, context):
980
+ self.context = context
981
+
982
+ def __getitem__(self, name):
983
+ if name not in self:
984
+ self[name] = TypeVar(self.context, name)
985
+ return super(TypeVarMap, self).__getitem__(name)
986
+
987
+ def __setitem__(self, name, value):
988
+ assert isinstance(name, str)
989
+ if name in self:
990
+ raise KeyError("Cannot redefine typevar %s" % name)
991
+ else:
992
+ super(TypeVarMap, self).__setitem__(name, value)
993
+
994
+
995
+ # A temporary mapping of {function name: dispatcher object}
996
+ _temporary_dispatcher_map = {}
997
+ # A temporary mapping of {function name: dispatcher object reference count}
998
+ # Reference: https://github.com/numba/numba/issues/3658
999
+ _temporary_dispatcher_map_ref_count = defaultdict(int)
1000
+
1001
+
1002
+ @contextlib.contextmanager
1003
+ def register_dispatcher(disp):
1004
+ """
1005
+ Register a Dispatcher for inference while it is not yet stored
1006
+ as global or closure variable (e.g. during execution of the @jit()
1007
+ call). This allows resolution of recursive calls with eager
1008
+ compilation.
1009
+ """
1010
+ assert callable(disp)
1011
+ assert callable(disp.py_func)
1012
+ name = disp.py_func.__name__
1013
+ _temporary_dispatcher_map[name] = disp
1014
+ _temporary_dispatcher_map_ref_count[name] += 1
1015
+ try:
1016
+ yield
1017
+ finally:
1018
+ _temporary_dispatcher_map_ref_count[name] -= 1
1019
+ if not _temporary_dispatcher_map_ref_count[name]:
1020
+ del _temporary_dispatcher_map[name]
1021
+
1022
+
1023
+ typeinfer_extensions = {}
1024
+
1025
+
1026
+ class TypeInferer(object):
1027
+ """
1028
+ Operates on block that shares the same ir.Scope.
1029
+ """
1030
+
1031
+ def __init__(self, context, func_ir, warnings):
1032
+ self.context = context
1033
+ # sort based on label, ensure iteration order!
1034
+ self.blocks = OrderedDict()
1035
+ for k in sorted(func_ir.blocks.keys()):
1036
+ self.blocks[k] = func_ir.blocks[k]
1037
+ self.generator_info = func_ir.generator_info
1038
+ self.func_id = func_ir.func_id
1039
+ self.func_ir = func_ir
1040
+
1041
+ self.typevars = TypeVarMap()
1042
+ self.typevars.set_context(context)
1043
+ self.constraints = ConstraintNetwork()
1044
+ self.warnings = warnings
1045
+
1046
+ # { index: mangled name }
1047
+ self.arg_names = {}
1048
+ # self.return_type = None
1049
+ # Set of assumed immutable globals
1050
+ self.assumed_immutables = set()
1051
+ # Track all calls and associated constraints
1052
+ self.calls = []
1053
+ # The inference result of the above calls
1054
+ self.calltypes = utils.UniqueDict()
1055
+ # Target var -> constraint with refine hook
1056
+ self.refine_map = {}
1057
+
1058
+ if config.DEBUG or config.DEBUG_TYPEINFER:
1059
+ self.debug = TypeInferDebug(self)
1060
+ else:
1061
+ self.debug = NullDebug()
1062
+
1063
+ self._skip_recursion = False
1064
+
1065
+ def copy(self, skip_recursion=False):
1066
+ clone = TypeInferer(self.context, self.func_ir, self.warnings)
1067
+ clone.arg_names = self.arg_names.copy()
1068
+ clone._skip_recursion = skip_recursion
1069
+
1070
+ for k, v in self.typevars.items():
1071
+ if not v.locked and v.defined:
1072
+ clone.typevars[k].add_type(v.getone(), loc=v.define_loc)
1073
+
1074
+ return clone
1075
+
1076
+ def _mangle_arg_name(self, name):
1077
+ # Disambiguise argument name
1078
+ return "arg.%s" % (name,)
1079
+
1080
+ def _get_return_vars(self):
1081
+ rets = []
1082
+ for blk in self.blocks.values():
1083
+ inst = blk.terminator
1084
+ if isinstance(inst, ir.Return):
1085
+ rets.append(inst.value)
1086
+ return rets
1087
+
1088
+ def get_argument_types(self):
1089
+ return [self.typevars[k].getone() for k in self.arg_names.values()]
1090
+
1091
+ def seed_argument(self, name, index, typ):
1092
+ name = self._mangle_arg_name(name)
1093
+ self.seed_type(name, typ)
1094
+ self.arg_names[index] = name
1095
+
1096
+ def seed_type(self, name, typ):
1097
+ """All arguments should be seeded."""
1098
+ self.lock_type(name, typ, loc=None)
1099
+
1100
+ def seed_return(self, typ):
1101
+ """Seeding of return value is optional."""
1102
+ for var in self._get_return_vars():
1103
+ self.lock_type(var.name, typ, loc=None)
1104
+
1105
+ def build_constraint(self):
1106
+ for blk in self.blocks.values():
1107
+ for inst in blk.body:
1108
+ self.constrain_statement(inst)
1109
+
1110
+ def return_types_from_partial(self):
1111
+ """
1112
+ Resume type inference partially to deduce the return type.
1113
+ Note: No side-effect to `self`.
1114
+
1115
+ Returns the inferred return type or None if it cannot deduce the return
1116
+ type.
1117
+ """
1118
+ # Clone the typeinferer and disable typing recursive calls
1119
+ cloned = self.copy(skip_recursion=True)
1120
+ # rebuild constraint network
1121
+ cloned.build_constraint()
1122
+ # propagate without raising
1123
+ cloned.propagate(raise_errors=False)
1124
+ # get return types
1125
+ rettypes = set()
1126
+ for retvar in cloned._get_return_vars():
1127
+ if retvar.name in cloned.typevars:
1128
+ typevar = cloned.typevars[retvar.name]
1129
+ if typevar and typevar.defined:
1130
+ rettypes.add(types.unliteral(typevar.getone()))
1131
+ if not rettypes:
1132
+ return
1133
+ # unify return types
1134
+ return cloned._unify_return_types(rettypes)
1135
+
1136
+ def propagate(self, raise_errors=True):
1137
+ newtoken = self.get_state_token()
1138
+ oldtoken = None
1139
+ # Since the number of types are finite, the typesets will eventually
1140
+ # stop growing.
1141
+
1142
+ while newtoken != oldtoken:
1143
+ self.debug.propagate_started()
1144
+ oldtoken = newtoken
1145
+ # Errors can appear when the type set is incomplete; only
1146
+ # raise them when there is no progress anymore.
1147
+ errors = self.constraints.propagate(self)
1148
+ newtoken = self.get_state_token()
1149
+ self.debug.propagate_finished()
1150
+ if errors:
1151
+ if raise_errors:
1152
+ force_lit_args = [
1153
+ e for e in errors if isinstance(e, ForceLiteralArg)
1154
+ ]
1155
+ if not force_lit_args:
1156
+ raise errors[0]
1157
+ else:
1158
+ raise reduce(operator.or_, force_lit_args)
1159
+ else:
1160
+ return errors
1161
+
1162
+ def add_type(self, var, tp, loc, unless_locked=False):
1163
+ assert isinstance(var, str), type(var)
1164
+ tv = self.typevars[var]
1165
+ if unless_locked and tv.locked:
1166
+ return
1167
+ oldty = tv.type
1168
+ unified = tv.add_type(tp, loc=loc)
1169
+ if unified != oldty:
1170
+ self.propagate_refined_type(var, unified)
1171
+
1172
+ def add_calltype(self, inst, signature):
1173
+ assert signature is not None
1174
+ self.calltypes[inst] = signature
1175
+
1176
+ def copy_type(self, src_var, dest_var, loc):
1177
+ self.typevars[dest_var].union(self.typevars[src_var], loc=loc)
1178
+
1179
+ def lock_type(self, var, tp, loc, literal_value=NOTSET):
1180
+ tv = self.typevars[var]
1181
+ tv.lock(tp, loc=loc, literal_value=literal_value)
1182
+
1183
+ def propagate_refined_type(self, updated_var, updated_type):
1184
+ source_constraint = self.refine_map.get(updated_var)
1185
+ if source_constraint is not None:
1186
+ source_constraint.refine(self, updated_type)
1187
+
1188
+ def unify(self, raise_errors=True):
1189
+ """
1190
+ Run the final unification pass over all inferred types, and
1191
+ catch imprecise types.
1192
+ """
1193
+ typdict = utils.UniqueDict()
1194
+
1195
+ def find_offender(name, exhaustive=False):
1196
+ # finds the offending variable definition by name
1197
+ # if exhaustive is set it will try and trace through temporary
1198
+ # variables to find a concrete offending definition.
1199
+ offender = None
1200
+ for block in self.func_ir.blocks.values():
1201
+ offender = block.find_variable_assignment(name)
1202
+ if offender is not None:
1203
+ if not exhaustive:
1204
+ break
1205
+ try: # simple assignment
1206
+ hasattr(offender.value, "name")
1207
+ offender_value = offender.value.name
1208
+ except (AttributeError, KeyError):
1209
+ break
1210
+ orig_offender = offender
1211
+ if offender_value.startswith("$"):
1212
+ offender = find_offender(
1213
+ offender_value, exhaustive=exhaustive
1214
+ )
1215
+ if offender is None:
1216
+ offender = orig_offender
1217
+ break
1218
+ return offender
1219
+
1220
+ def diagnose_imprecision(offender):
1221
+ # helper for diagnosing imprecise types
1222
+
1223
+ list_msg = """\n
1224
+ For Numba to be able to compile a list, the list must have a known and
1225
+ precise type that can be inferred from the other variables. Whilst sometimes
1226
+ the type of empty lists can be inferred, this is not always the case, see this
1227
+ documentation for help:
1228
+
1229
+ https://numba.readthedocs.io/en/stable/user/troubleshoot.html#my-code-has-an-untyped-list-problem
1230
+ """
1231
+ if offender is not None:
1232
+ # This block deals with imprecise lists
1233
+ if hasattr(offender, "value"):
1234
+ if hasattr(offender.value, "op"):
1235
+ # might be `foo = []`
1236
+ if offender.value.op == "build_list":
1237
+ return list_msg
1238
+ # or might be `foo = list()`
1239
+ elif offender.value.op == "call":
1240
+ try: # assignment involving a call
1241
+ call_name = offender.value.func.name
1242
+ # find the offender based on the call name
1243
+ offender = find_offender(call_name)
1244
+ if isinstance(offender.value, ir.Global):
1245
+ if offender.value.name == "list":
1246
+ return list_msg
1247
+ except (AttributeError, KeyError):
1248
+ pass
1249
+ return "" # no help possible
1250
+
1251
+ def check_var(name):
1252
+ tv = self.typevars[name]
1253
+ if not tv.defined:
1254
+ if raise_errors:
1255
+ offender = find_offender(name)
1256
+ val = getattr(offender, "value", "unknown operation")
1257
+ loc = getattr(offender, "loc", ir.unknown_loc)
1258
+ msg = (
1259
+ "Type of variable '%s' cannot be determined, "
1260
+ "operation: %s, location: %s"
1261
+ )
1262
+ raise TypingError(msg % (var, val, loc), loc)
1263
+ else:
1264
+ typdict[var] = types.unknown
1265
+ return
1266
+ tp = tv.getone()
1267
+
1268
+ if isinstance(tp, types.UndefinedFunctionType):
1269
+ tp = tp.get_precise()
1270
+
1271
+ if not tp.is_precise():
1272
+ offender = find_offender(name, exhaustive=True)
1273
+ msg = (
1274
+ "Cannot infer the type of variable '%s'%s, "
1275
+ "have imprecise type: %s. %s"
1276
+ )
1277
+ istmp = " (temporary variable)" if var.startswith("$") else ""
1278
+ loc = getattr(offender, "loc", ir.unknown_loc)
1279
+ # is this an untyped list? try and provide help
1280
+ extra_msg = diagnose_imprecision(offender)
1281
+ if raise_errors:
1282
+ raise TypingError(msg % (var, istmp, tp, extra_msg), loc)
1283
+ else:
1284
+ typdict[var] = types.unknown
1285
+ return
1286
+ else: # type is precise, hold it
1287
+ typdict[var] = tp
1288
+
1289
+ # For better error display, check first user-visible vars, then
1290
+ # temporaries
1291
+ temps = set(k for k in self.typevars if not k[0].isalpha())
1292
+ others = set(self.typevars) - temps
1293
+ for var in sorted(others):
1294
+ check_var(var)
1295
+ for var in sorted(temps):
1296
+ check_var(var)
1297
+
1298
+ try:
1299
+ retty = self.get_return_type(typdict)
1300
+ except Exception as e:
1301
+ # partial type inference may raise e.g. attribute error if a
1302
+ # constraint has no computable signature, ignore this as needed
1303
+ if raise_errors:
1304
+ raise e
1305
+ else:
1306
+ retty = None
1307
+ else:
1308
+ typdict = utils.UniqueDict(
1309
+ typdict, **{v.name: retty for v in self._get_return_vars()}
1310
+ )
1311
+
1312
+ try:
1313
+ fntys = self.get_function_types(typdict)
1314
+ except Exception as e:
1315
+ # partial type inference may raise e.g. attribute error if a
1316
+ # constraint has no computable signature, ignore this as needed
1317
+ if raise_errors:
1318
+ raise e
1319
+ else:
1320
+ fntys = None
1321
+
1322
+ if self.generator_info:
1323
+ retty = self.get_generator_type(
1324
+ typdict, retty, raise_errors=raise_errors
1325
+ )
1326
+
1327
+ def check_undef_var_in_calls():
1328
+ # Check for undefined variables in the call arguments.
1329
+ for callnode, calltype in self.calltypes.items():
1330
+ if calltype is not None:
1331
+ for i, v in enumerate(calltype.args, start=1):
1332
+ if v is types._undef_var:
1333
+ m = f"undefined variable used in call argument #{i}"
1334
+ raise TypingError(m, loc=callnode.loc)
1335
+
1336
+ check_undef_var_in_calls()
1337
+
1338
+ self.debug.unify_finished(typdict, retty, fntys)
1339
+
1340
+ return typdict, retty, fntys
1341
+
1342
+ def get_generator_type(self, typdict, retty, raise_errors=True):
1343
+ gi = self.generator_info
1344
+ arg_types = [None] * len(self.arg_names)
1345
+ for index, name in self.arg_names.items():
1346
+ arg_types[index] = typdict[name]
1347
+
1348
+ state_types = None
1349
+ try:
1350
+ state_types = [typdict[var_name] for var_name in gi.state_vars]
1351
+ except KeyError:
1352
+ msg = "Cannot type generator: state variable types cannot be found"
1353
+ if raise_errors:
1354
+ raise TypingError(msg)
1355
+ state_types = [types.unknown for _ in gi.state_vars]
1356
+
1357
+ yield_types = None
1358
+ try:
1359
+ yield_types = [
1360
+ typdict[y.inst.value.name] for y in gi.get_yield_points()
1361
+ ]
1362
+ except KeyError:
1363
+ msg = "Cannot type generator: yield type cannot be found"
1364
+ if raise_errors:
1365
+ raise TypingError(msg)
1366
+ if not yield_types:
1367
+ msg = "Cannot type generator: it does not yield any value"
1368
+ if raise_errors:
1369
+ raise TypingError(msg)
1370
+ yield_types = [types.unknown for _ in gi.get_yield_points()]
1371
+
1372
+ if not yield_types or all(yield_types) == types.unknown:
1373
+ # unknown yield, probably partial type inference, escape
1374
+ return types.Generator(
1375
+ self.func_id.func,
1376
+ types.unknown,
1377
+ arg_types,
1378
+ state_types,
1379
+ has_finalizer=True,
1380
+ )
1381
+
1382
+ yield_type = self.context.unify_types(*yield_types)
1383
+ if yield_type is None or isinstance(yield_type, types.Optional):
1384
+ msg = "Cannot type generator: cannot unify yielded types %s"
1385
+ yp_highlights = []
1386
+ for y in gi.get_yield_points():
1387
+ msg = _termcolor.errmsg(
1388
+ "Yield of: IR '%s', type '%s', location: %s"
1389
+ )
1390
+ yp_highlights.append(
1391
+ msg
1392
+ % (
1393
+ str(y.inst),
1394
+ typdict[y.inst.value.name],
1395
+ y.inst.loc.strformat(),
1396
+ )
1397
+ )
1398
+
1399
+ explain_ty = set()
1400
+ for ty in yield_types:
1401
+ if isinstance(ty, types.Optional):
1402
+ explain_ty.add(ty.type)
1403
+ explain_ty.add(types.NoneType("none"))
1404
+ else:
1405
+ explain_ty.add(ty)
1406
+ if raise_errors:
1407
+ raise TypingError(
1408
+ "Can't unify yield type from the "
1409
+ "following types: %s"
1410
+ % ", ".join(sorted(map(str, explain_ty)))
1411
+ + "\n\n"
1412
+ + "\n".join(yp_highlights)
1413
+ )
1414
+
1415
+ return types.Generator(
1416
+ self.func_id.func,
1417
+ yield_type,
1418
+ arg_types,
1419
+ state_types,
1420
+ has_finalizer=True,
1421
+ )
1422
+
1423
+ def get_function_types(self, typemap):
1424
+ """
1425
+ Fill and return the calltypes map.
1426
+ """
1427
+ # XXX why can't this be done on the fly?
1428
+ calltypes = self.calltypes
1429
+ for call, constraint in self.calls:
1430
+ calltypes[call] = constraint.get_call_signature()
1431
+ return calltypes
1432
+
1433
+ def _unify_return_types(self, rettypes):
1434
+ if rettypes:
1435
+ unified = self.context.unify_types(*rettypes)
1436
+ if isinstance(unified, types.FunctionType):
1437
+ # unified is allowed to be UndefinedFunctionType
1438
+ # instance (that is imprecise).
1439
+ return unified
1440
+ if unified is None or not unified.is_precise():
1441
+
1442
+ def check_type(atype):
1443
+ lst = []
1444
+ for k, v in self.typevars.items():
1445
+ if atype == v.type:
1446
+ lst.append(k)
1447
+ returns = {}
1448
+ for x in reversed(lst):
1449
+ for block in self.func_ir.blocks.values():
1450
+ for instr in block.find_insts(ir.Return):
1451
+ value = instr.value
1452
+ if isinstance(value, ir.Var):
1453
+ name = value.name
1454
+ else:
1455
+ pass
1456
+ if x == name:
1457
+ returns[x] = instr
1458
+ break
1459
+
1460
+ interped = ""
1461
+ for name, offender in returns.items():
1462
+ loc = getattr(offender, "loc", ir.unknown_loc)
1463
+ msg = "Return of: IR name '%s', type '%s', location: %s"
1464
+ interped = msg % (name, atype, loc.strformat())
1465
+ return interped
1466
+
1467
+ problem_str = []
1468
+ for xtype in rettypes:
1469
+ problem_str.append(_termcolor.errmsg(check_type(xtype)))
1470
+
1471
+ raise TypingError(
1472
+ "Can't unify return type from the "
1473
+ "following types: %s"
1474
+ % ", ".join(sorted(map(str, rettypes)))
1475
+ + "\n"
1476
+ + "\n".join(problem_str)
1477
+ )
1478
+ return unified
1479
+ else:
1480
+ # Function without a successful return path
1481
+ return types.none
1482
+
1483
+ def get_return_type(self, typemap):
1484
+ rettypes = set()
1485
+ for var in self._get_return_vars():
1486
+ rettypes.add(typemap[var.name])
1487
+ retty = self._unify_return_types(rettypes)
1488
+ # Check return value is not undefined
1489
+ if retty is types._undef_var:
1490
+ raise TypingError("return value is undefined")
1491
+ return retty
1492
+
1493
+ def get_state_token(self):
1494
+ """The algorithm is monotonic. It can only grow or "refine" the
1495
+ typevar map.
1496
+ """
1497
+ return [tv.type for name, tv in sorted(self.typevars.items())]
1498
+
1499
+ def constrain_statement(self, inst):
1500
+ if isinstance(inst, ir.Assign):
1501
+ self.typeof_assign(inst)
1502
+ elif isinstance(inst, ir.SetItem):
1503
+ self.typeof_setitem(inst)
1504
+ elif isinstance(inst, ir.StaticSetItem):
1505
+ self.typeof_static_setitem(inst)
1506
+ elif isinstance(inst, ir.DelItem):
1507
+ self.typeof_delitem(inst)
1508
+ elif isinstance(inst, ir.SetAttr):
1509
+ self.typeof_setattr(inst)
1510
+ elif isinstance(inst, ir.Print):
1511
+ self.typeof_print(inst)
1512
+ elif isinstance(inst, ir.StoreMap):
1513
+ self.typeof_storemap(inst)
1514
+ elif isinstance(inst, (ir.Jump, ir.Branch, ir.Return, ir.Del)):
1515
+ pass
1516
+ elif isinstance(inst, (ir.DynamicRaise, ir.DynamicTryRaise)):
1517
+ pass
1518
+ elif isinstance(inst, (ir.StaticRaise, ir.StaticTryRaise)):
1519
+ pass
1520
+ elif isinstance(inst, ir.PopBlock):
1521
+ pass # It's a marker statement
1522
+ elif type(inst) in typeinfer_extensions:
1523
+ # let external calls handle stmt if type matches
1524
+ f = typeinfer_extensions[type(inst)]
1525
+ f(inst, self)
1526
+ else:
1527
+ msg = "Unsupported constraint encountered: %s" % inst
1528
+ raise UnsupportedError(msg, loc=inst.loc)
1529
+
1530
+ def typeof_setitem(self, inst):
1531
+ constraint = SetItemConstraint(
1532
+ target=inst.target, index=inst.index, value=inst.value, loc=inst.loc
1533
+ )
1534
+ self.constraints.append(constraint)
1535
+ self.calls.append((inst, constraint))
1536
+
1537
+ def typeof_storemap(self, inst):
1538
+ constraint = SetItemConstraint(
1539
+ target=inst.dct, index=inst.key, value=inst.value, loc=inst.loc
1540
+ )
1541
+ self.constraints.append(constraint)
1542
+ self.calls.append((inst, constraint))
1543
+
1544
+ def typeof_static_setitem(self, inst):
1545
+ constraint = StaticSetItemConstraint(
1546
+ target=inst.target,
1547
+ index=inst.index,
1548
+ index_var=inst.index_var,
1549
+ value=inst.value,
1550
+ loc=inst.loc,
1551
+ )
1552
+ self.constraints.append(constraint)
1553
+ self.calls.append((inst, constraint))
1554
+
1555
+ def typeof_delitem(self, inst):
1556
+ constraint = DelItemConstraint(
1557
+ target=inst.target, index=inst.index, loc=inst.loc
1558
+ )
1559
+ self.constraints.append(constraint)
1560
+ self.calls.append((inst, constraint))
1561
+
1562
+ def typeof_setattr(self, inst):
1563
+ constraint = SetAttrConstraint(
1564
+ target=inst.target, attr=inst.attr, value=inst.value, loc=inst.loc
1565
+ )
1566
+ self.constraints.append(constraint)
1567
+ self.calls.append((inst, constraint))
1568
+
1569
+ def typeof_print(self, inst):
1570
+ constraint = PrintConstraint(
1571
+ args=inst.args, vararg=inst.vararg, loc=inst.loc
1572
+ )
1573
+ self.constraints.append(constraint)
1574
+ self.calls.append((inst, constraint))
1575
+
1576
+ def typeof_assign(self, inst):
1577
+ value = inst.value
1578
+ if isinstance(value, ir.Const):
1579
+ self.typeof_const(inst, inst.target, value.value)
1580
+ elif isinstance(value, ir.Var):
1581
+ self.constraints.append(
1582
+ Propagate(dst=inst.target.name, src=value.name, loc=inst.loc)
1583
+ )
1584
+ elif isinstance(value, (ir.Global, ir.FreeVar)):
1585
+ self.typeof_global(inst, inst.target, value)
1586
+ elif isinstance(value, ir.Arg):
1587
+ self.typeof_arg(inst, inst.target, value)
1588
+ elif isinstance(value, ir.Expr):
1589
+ self.typeof_expr(inst, inst.target, value)
1590
+ elif isinstance(value, ir.Yield):
1591
+ self.typeof_yield(inst, inst.target, value)
1592
+ else:
1593
+ msg = "Unsupported assignment encountered: %s %s" % (
1594
+ type(value),
1595
+ str(value),
1596
+ )
1597
+ raise UnsupportedError(msg, loc=inst.loc)
1598
+
1599
+ def resolve_value_type(self, inst, val):
1600
+ """
1601
+ Resolve the type of a simple Python value, such as can be
1602
+ represented by literals.
1603
+ """
1604
+ try:
1605
+ return self.context.resolve_value_type(val)
1606
+ except ValueError as e:
1607
+ msg = str(e)
1608
+ raise TypingError(msg, loc=inst.loc)
1609
+
1610
+ def typeof_arg(self, inst, target, arg):
1611
+ src_name = self._mangle_arg_name(arg.name)
1612
+ self.constraints.append(
1613
+ ArgConstraint(dst=target.name, src=src_name, loc=inst.loc)
1614
+ )
1615
+
1616
+ def typeof_const(self, inst, target, const):
1617
+ ty = self.resolve_value_type(inst, const)
1618
+ if inst.value.use_literal_type:
1619
+ lit = types.maybe_literal(value=const)
1620
+ else:
1621
+ lit = None
1622
+ self.add_type(target.name, lit or ty, loc=inst.loc)
1623
+
1624
+ def typeof_yield(self, inst, target, yield_):
1625
+ # Sending values into generators isn't supported.
1626
+ self.add_type(target.name, types.none, loc=inst.loc)
1627
+
1628
+ def sentry_modified_builtin(self, inst, gvar):
1629
+ """
1630
+ Ensure that builtins are not modified.
1631
+ """
1632
+ if gvar.name == "range" and gvar.value is not range:
1633
+ bad = True
1634
+ elif gvar.name == "slice" and gvar.value is not slice:
1635
+ bad = True
1636
+ elif gvar.name == "len" and gvar.value is not len:
1637
+ bad = True
1638
+ else:
1639
+ bad = False
1640
+
1641
+ if bad:
1642
+ raise TypingError("Modified builtin '%s'" % gvar.name, loc=inst.loc)
1643
+
1644
+ def resolve_call(self, fnty, pos_args, kw_args):
1645
+ """
1646
+ Resolve a call to a given function type. A signature is returned.
1647
+ """
1648
+ if isinstance(fnty, types.FunctionType):
1649
+ return fnty.get_call_type(self, pos_args, kw_args)
1650
+ if isinstance(fnty, types.RecursiveCall) and not self._skip_recursion:
1651
+ # Recursive call
1652
+ disp = fnty.dispatcher_type.dispatcher
1653
+ pysig, args = disp.fold_argument_types(pos_args, kw_args)
1654
+
1655
+ frame = self.context.callstack.match(disp.py_func, args)
1656
+
1657
+ # If the signature is not being compiled
1658
+ if frame is None:
1659
+ sig = self.context.resolve_function_type(
1660
+ fnty.dispatcher_type, pos_args, kw_args
1661
+ )
1662
+ fndesc = disp.overloads[args].fndesc
1663
+ qual = qualifying_prefix(fndesc.modname, fndesc.qualname)
1664
+ fnty.add_overloads(args, qual, fndesc.uid)
1665
+ return sig
1666
+
1667
+ fnid = frame.func_id
1668
+ qual = qualifying_prefix(fnid.modname, fnid.func_qualname)
1669
+ fnty.add_overloads(args, qual, fnid.unique_id)
1670
+ # Resume propagation in parent frame
1671
+ return_type = frame.typeinfer.return_types_from_partial()
1672
+ # No known return type
1673
+ if return_type is None:
1674
+ raise TypingError("cannot type infer runaway recursion")
1675
+
1676
+ sig = typing.signature(return_type, *args)
1677
+ sig = sig.replace(pysig=pysig)
1678
+ # Keep track of unique return_type
1679
+ frame.add_return_type(return_type)
1680
+ return sig
1681
+ else:
1682
+ # Normal non-recursive call
1683
+ return self.context.resolve_function_type(fnty, pos_args, kw_args)
1684
+
1685
+ def typeof_global(self, inst, target, gvar):
1686
+ try:
1687
+ typ = self.resolve_value_type(inst, gvar.value)
1688
+ except TypingError as e:
1689
+ if (
1690
+ gvar.name == self.func_id.func_name
1691
+ and gvar.name in _temporary_dispatcher_map
1692
+ ):
1693
+ # Self-recursion case where the dispatcher is not (yet?) known
1694
+ # as a global variable
1695
+ typ = types.Dispatcher(_temporary_dispatcher_map[gvar.name])
1696
+ else:
1697
+ from numba.cuda.misc import special
1698
+
1699
+ nm = gvar.name
1700
+ # check if the problem is actually a name error
1701
+ func_glbls = self.func_id.func.__globals__
1702
+ if (
1703
+ nm not in func_glbls.keys()
1704
+ and nm not in special.__all__
1705
+ and nm not in __builtins__.keys()
1706
+ and nm not in self.func_id.code.co_freevars
1707
+ ):
1708
+ errstr = "NameError: name '%s' is not defined"
1709
+ msg = _termcolor.errmsg(errstr % nm)
1710
+ e.patch_message(msg)
1711
+ raise
1712
+ else:
1713
+ msg = _termcolor.errmsg("Untyped global name '%s':" % nm)
1714
+ msg += " %s" # interps the actual error
1715
+
1716
+ # if the untyped global is a numba internal function then add
1717
+ # to the error message asking if it's been imported.
1718
+
1719
+ if nm in special.__all__:
1720
+ tmp = (
1721
+ "\n'%s' looks like a Numba internal function, has "
1722
+ "it been imported (i.e. 'from numba import %s')?\n"
1723
+ % (nm, nm)
1724
+ )
1725
+ msg += _termcolor.errmsg(tmp)
1726
+ e.patch_message(msg % e)
1727
+ raise
1728
+
1729
+ if isinstance(typ, types.Dispatcher) and typ.dispatcher.is_compiling:
1730
+ # Recursive call
1731
+ callstack = self.context.callstack
1732
+ callframe = callstack.findfirst(typ.dispatcher.py_func)
1733
+ if callframe is not None:
1734
+ typ = types.RecursiveCall(typ)
1735
+ else:
1736
+ raise NotImplementedError(
1737
+ "call to %s: unsupported recursion" % typ.dispatcher
1738
+ )
1739
+
1740
+ if isinstance(typ, types.Array):
1741
+ # Global array in nopython mode is constant
1742
+ typ = typ.copy(readonly=True)
1743
+
1744
+ if isinstance(typ, types.BaseAnonymousTuple):
1745
+ # if it's a tuple of literal types, swap the type for the more
1746
+ # specific literal version
1747
+ literaled = [types.maybe_literal(x) for x in gvar.value]
1748
+ if all(literaled):
1749
+ typ = types.Tuple(literaled)
1750
+
1751
+ # if any of the items in the tuple are arrays, they need to be
1752
+ # typed as readonly, mutating an array in a global container
1753
+ # is not supported (should be compile time constant etc).
1754
+ def mark_array_ro(tup):
1755
+ newtup = []
1756
+ for item in tup.types:
1757
+ if isinstance(item, types.Array):
1758
+ item = item.copy(readonly=True)
1759
+ elif isinstance(item, types.BaseAnonymousTuple):
1760
+ item = mark_array_ro(item)
1761
+ newtup.append(item)
1762
+ return types.BaseTuple.from_types(newtup)
1763
+
1764
+ typ = mark_array_ro(typ)
1765
+
1766
+ self.sentry_modified_builtin(inst, gvar)
1767
+ # Setting literal_value for globals because they are handled
1768
+ # like const value in numba
1769
+ lit = types.maybe_literal(gvar.value)
1770
+ # The user may have provided the type for this variable already.
1771
+ # In this case, call add_type() to make sure the value type is
1772
+ # consistent. See numba.tests.test_array_reductions
1773
+ # TestArrayReductions.test_array_cumsum for examples.
1774
+ # Variable type locked by using the locals dict.
1775
+ tv = self.typevars[target.name]
1776
+ if tv.locked:
1777
+ tv.add_type(lit or typ, loc=inst.loc)
1778
+ else:
1779
+ self.lock_type(target.name, lit or typ, loc=inst.loc)
1780
+ self.assumed_immutables.add(inst)
1781
+
1782
+ def typeof_expr(self, inst, target, expr):
1783
+ if expr.op == "call":
1784
+ self.typeof_call(inst, target, expr)
1785
+ elif expr.op in ("getiter", "iternext"):
1786
+ self.typeof_intrinsic_call(inst, target, expr.op, expr.value)
1787
+ elif expr.op == "exhaust_iter":
1788
+ constraint = ExhaustIterConstraint(
1789
+ target.name, count=expr.count, iterator=expr.value, loc=expr.loc
1790
+ )
1791
+ self.constraints.append(constraint)
1792
+ elif expr.op == "pair_first":
1793
+ constraint = PairFirstConstraint(
1794
+ target.name, pair=expr.value, loc=expr.loc
1795
+ )
1796
+ self.constraints.append(constraint)
1797
+ elif expr.op == "pair_second":
1798
+ constraint = PairSecondConstraint(
1799
+ target.name, pair=expr.value, loc=expr.loc
1800
+ )
1801
+ self.constraints.append(constraint)
1802
+ elif expr.op == "binop":
1803
+ self.typeof_intrinsic_call(
1804
+ inst, target, expr.fn, expr.lhs, expr.rhs
1805
+ )
1806
+ elif expr.op == "inplace_binop":
1807
+ self.typeof_intrinsic_call(
1808
+ inst, target, expr.fn, expr.lhs, expr.rhs
1809
+ )
1810
+ elif expr.op == "unary":
1811
+ self.typeof_intrinsic_call(inst, target, expr.fn, expr.value)
1812
+ elif expr.op == "static_getitem":
1813
+ constraint = StaticGetItemConstraint(
1814
+ target.name,
1815
+ value=expr.value,
1816
+ index=expr.index,
1817
+ index_var=expr.index_var,
1818
+ loc=expr.loc,
1819
+ )
1820
+ self.constraints.append(constraint)
1821
+ self.calls.append((inst.value, constraint))
1822
+ elif expr.op == "getitem":
1823
+ self.typeof_intrinsic_call(
1824
+ inst,
1825
+ target,
1826
+ operator.getitem,
1827
+ expr.value,
1828
+ expr.index,
1829
+ )
1830
+ elif expr.op == "typed_getitem":
1831
+ constraint = TypedGetItemConstraint(
1832
+ target.name,
1833
+ value=expr.value,
1834
+ dtype=expr.dtype,
1835
+ index=expr.index,
1836
+ loc=expr.loc,
1837
+ )
1838
+ self.constraints.append(constraint)
1839
+ self.calls.append((inst.value, constraint))
1840
+
1841
+ elif expr.op == "getattr":
1842
+ constraint = GetAttrConstraint(
1843
+ target.name,
1844
+ attr=expr.attr,
1845
+ value=expr.value,
1846
+ loc=inst.loc,
1847
+ inst=inst,
1848
+ )
1849
+ self.constraints.append(constraint)
1850
+ elif expr.op == "build_tuple":
1851
+ constraint = BuildTupleConstraint(
1852
+ target.name, items=expr.items, loc=inst.loc
1853
+ )
1854
+ self.constraints.append(constraint)
1855
+ elif expr.op == "build_list":
1856
+ constraint = BuildListConstraint(
1857
+ target.name, items=expr.items, loc=inst.loc
1858
+ )
1859
+ self.constraints.append(constraint)
1860
+ elif expr.op == "build_set":
1861
+ constraint = BuildSetConstraint(
1862
+ target.name, items=expr.items, loc=inst.loc
1863
+ )
1864
+ self.constraints.append(constraint)
1865
+ elif expr.op == "build_map":
1866
+ constraint = BuildMapConstraint(
1867
+ target.name,
1868
+ items=expr.items,
1869
+ special_value=expr.literal_value,
1870
+ value_indexes=expr.value_indexes,
1871
+ loc=inst.loc,
1872
+ )
1873
+ self.constraints.append(constraint)
1874
+ elif expr.op == "cast":
1875
+ self.constraints.append(
1876
+ Propagate(dst=target.name, src=expr.value.name, loc=inst.loc)
1877
+ )
1878
+ elif expr.op == "phi":
1879
+ for iv in expr.incoming_values:
1880
+ if iv is not ir.UNDEFINED:
1881
+ self.constraints.append(
1882
+ Propagate(dst=target.name, src=iv.name, loc=inst.loc)
1883
+ )
1884
+ elif expr.op == "make_function":
1885
+ self.lock_type(
1886
+ target.name,
1887
+ types.MakeFunctionLiteral(expr),
1888
+ loc=inst.loc,
1889
+ literal_value=expr,
1890
+ )
1891
+
1892
+ elif expr.op == "undef":
1893
+ self.add_type(target.name, types._undef_var, loc=inst.loc)
1894
+
1895
+ else:
1896
+ msg = "Unsupported op-code encountered: %s" % expr
1897
+ raise UnsupportedError(msg, loc=inst.loc)
1898
+
1899
+ def typeof_call(self, inst, target, call):
1900
+ constraint = CallConstraint(
1901
+ target.name,
1902
+ call.func.name,
1903
+ call.args,
1904
+ call.kws,
1905
+ call.vararg,
1906
+ loc=inst.loc,
1907
+ )
1908
+ self.constraints.append(constraint)
1909
+ self.calls.append((inst.value, constraint))
1910
+
1911
+ def typeof_intrinsic_call(self, inst, target, func, *args):
1912
+ constraint = IntrinsicCallConstraint(
1913
+ target.name, func, args, kws=(), vararg=None, loc=inst.loc
1914
+ )
1915
+ self.constraints.append(constraint)
1916
+ self.calls.append((inst.value, constraint))
1917
+
1918
+
1919
+ class NullDebug(object):
1920
+ def propagate_started(self):
1921
+ pass
1922
+
1923
+ def propagate_finished(self):
1924
+ pass
1925
+
1926
+ def unify_finished(self, typdict, retty, fntys):
1927
+ pass
1928
+
1929
+
1930
+ class TypeInferDebug(object):
1931
+ def __init__(self, typeinfer):
1932
+ self.typeinfer = typeinfer
1933
+
1934
+ def _dump_state(self):
1935
+ print("---- type variables ----")
1936
+ pprint([v for k, v in sorted(self.typeinfer.typevars.items())])
1937
+
1938
+ def propagate_started(self):
1939
+ print("propagate".center(80, "-"))
1940
+
1941
+ def propagate_finished(self):
1942
+ self._dump_state()
1943
+
1944
+ def unify_finished(self, typdict, retty, fntys):
1945
+ print("Variable types".center(80, "-"))
1946
+ pprint(typdict)
1947
+ print("Return type".center(80, "-"))
1948
+ pprint(retty)
1949
+ print("Call types".center(80, "-"))
1950
+ pprint(fntys)