numba-cuda 0.19.0__py3-none-any.whl → 0.20.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (353) hide show
  1. _numba_cuda_redirector.pth +3 -0
  2. _numba_cuda_redirector.py +3 -0
  3. numba_cuda/VERSION +1 -1
  4. numba_cuda/__init__.py +2 -1
  5. numba_cuda/_version.py +2 -13
  6. numba_cuda/numba/cuda/__init__.py +4 -1
  7. numba_cuda/numba/cuda/_internal/cuda_bf16.py +12708 -1469
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +2656 -8769
  9. numba_cuda/numba/cuda/api.py +9 -1
  10. numba_cuda/numba/cuda/api_util.py +3 -0
  11. numba_cuda/numba/cuda/args.py +3 -0
  12. numba_cuda/numba/cuda/bf16.py +288 -2
  13. numba_cuda/numba/cuda/cg.py +3 -0
  14. numba_cuda/numba/cuda/cgutils.py +5 -2
  15. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  16. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  17. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  18. numba_cuda/numba/cuda/codegen.py +4 -1
  19. numba_cuda/numba/cuda/compiler.py +376 -30
  20. numba_cuda/numba/cuda/core/analysis.py +319 -0
  21. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  22. numba_cuda/numba/cuda/core/annotations/type_annotations.py +304 -0
  23. numba_cuda/numba/cuda/core/base.py +1289 -0
  24. numba_cuda/numba/cuda/core/bytecode.py +727 -0
  25. numba_cuda/numba/cuda/core/caching.py +5 -2
  26. numba_cuda/numba/cuda/core/callconv.py +3 -0
  27. numba_cuda/numba/cuda/core/codegen.py +3 -0
  28. numba_cuda/numba/cuda/core/compiler.py +9 -14
  29. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  30. numba_cuda/numba/cuda/core/config.py +747 -0
  31. numba_cuda/numba/cuda/core/consts.py +124 -0
  32. numba_cuda/numba/cuda/core/cpu.py +370 -0
  33. numba_cuda/numba/cuda/core/environment.py +68 -0
  34. numba_cuda/numba/cuda/core/event.py +511 -0
  35. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  36. numba_cuda/numba/cuda/core/inline_closurecall.py +1889 -0
  37. numba_cuda/numba/cuda/core/interpreter.py +52 -27
  38. numba_cuda/numba/cuda/core/ir_utils.py +17 -29
  39. numba_cuda/numba/cuda/core/options.py +262 -0
  40. numba_cuda/numba/cuda/core/postproc.py +249 -0
  41. numba_cuda/numba/cuda/core/pythonapi.py +1868 -0
  42. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  43. numba_cuda/numba/cuda/core/rewrites/ir_print.py +90 -0
  44. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  45. numba_cuda/numba/cuda/core/rewrites/static_binop.py +40 -0
  46. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +187 -0
  47. numba_cuda/numba/cuda/core/rewrites/static_raise.py +98 -0
  48. numba_cuda/numba/cuda/core/sigutils.py +3 -0
  49. numba_cuda/numba/cuda/core/ssa.py +496 -0
  50. numba_cuda/numba/cuda/core/targetconfig.py +329 -0
  51. numba_cuda/numba/cuda/core/tracing.py +231 -0
  52. numba_cuda/numba/cuda/core/transforms.py +952 -0
  53. numba_cuda/numba/cuda/core/typed_passes.py +741 -7
  54. numba_cuda/numba/cuda/core/typeinfer.py +1948 -0
  55. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  56. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  57. numba_cuda/numba/cuda/core/unsafe/eh.py +66 -0
  58. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  59. numba_cuda/numba/cuda/core/untyped_passes.py +1983 -0
  60. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  61. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  62. numba_cuda/numba/cuda/cpython/numbers.py +1474 -0
  63. numba_cuda/numba/cuda/cuda_paths.py +425 -246
  64. numba_cuda/numba/cuda/cudadecl.py +4 -1
  65. numba_cuda/numba/cuda/cudadrv/__init__.py +4 -1
  66. numba_cuda/numba/cuda/cudadrv/devicearray.py +5 -1
  67. numba_cuda/numba/cuda/cudadrv/devices.py +3 -0
  68. numba_cuda/numba/cuda/cudadrv/driver.py +14 -140
  69. numba_cuda/numba/cuda/cudadrv/drvapi.py +3 -0
  70. numba_cuda/numba/cuda/cudadrv/dummyarray.py +114 -24
  71. numba_cuda/numba/cuda/cudadrv/enums.py +3 -0
  72. numba_cuda/numba/cuda/cudadrv/error.py +4 -0
  73. numba_cuda/numba/cuda/cudadrv/libs.py +8 -5
  74. numba_cuda/numba/cuda/cudadrv/linkable_code.py +3 -0
  75. numba_cuda/numba/cuda/cudadrv/mappings.py +4 -1
  76. numba_cuda/numba/cuda/cudadrv/ndarray.py +3 -0
  77. numba_cuda/numba/cuda/cudadrv/nvrtc.py +22 -8
  78. numba_cuda/numba/cuda/cudadrv/nvvm.py +4 -4
  79. numba_cuda/numba/cuda/cudadrv/rtapi.py +3 -0
  80. numba_cuda/numba/cuda/cudadrv/runtime.py +4 -1
  81. numba_cuda/numba/cuda/cudaimpl.py +8 -1
  82. numba_cuda/numba/cuda/cudamath.py +3 -0
  83. numba_cuda/numba/cuda/debuginfo.py +88 -2
  84. numba_cuda/numba/cuda/decorators.py +6 -3
  85. numba_cuda/numba/cuda/descriptor.py +6 -4
  86. numba_cuda/numba/cuda/device_init.py +3 -0
  87. numba_cuda/numba/cuda/deviceufunc.py +69 -2
  88. numba_cuda/numba/cuda/dispatcher.py +21 -39
  89. numba_cuda/numba/cuda/errors.py +10 -0
  90. numba_cuda/numba/cuda/extending.py +3 -0
  91. numba_cuda/numba/cuda/flags.py +143 -1
  92. numba_cuda/numba/cuda/fp16.py +3 -2
  93. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  94. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  95. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  96. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  97. numba_cuda/numba/cuda/initialize.py +4 -0
  98. numba_cuda/numba/cuda/intrinsic_wrapper.py +3 -0
  99. numba_cuda/numba/cuda/intrinsics.py +3 -0
  100. numba_cuda/numba/cuda/itanium_mangler.py +3 -0
  101. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  102. numba_cuda/numba/cuda/kernels/reduction.py +3 -0
  103. numba_cuda/numba/cuda/kernels/transpose.py +3 -0
  104. numba_cuda/numba/cuda/libdevice.py +4 -0
  105. numba_cuda/numba/cuda/libdevicedecl.py +3 -0
  106. numba_cuda/numba/cuda/libdevicefuncs.py +3 -0
  107. numba_cuda/numba/cuda/libdeviceimpl.py +3 -0
  108. numba_cuda/numba/cuda/locks.py +3 -0
  109. numba_cuda/numba/cuda/lowering.py +59 -159
  110. numba_cuda/numba/cuda/mathimpl.py +5 -1
  111. numba_cuda/numba/cuda/memory_management/__init__.py +3 -0
  112. numba_cuda/numba/cuda/memory_management/memsys.cu +5 -0
  113. numba_cuda/numba/cuda/memory_management/memsys.cuh +5 -0
  114. numba_cuda/numba/cuda/memory_management/nrt.cu +5 -0
  115. numba_cuda/numba/cuda/memory_management/nrt.cuh +5 -0
  116. numba_cuda/numba/cuda/memory_management/nrt.py +48 -18
  117. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  118. numba_cuda/numba/cuda/models.py +12 -1
  119. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  120. numba_cuda/numba/cuda/np/npyfuncs.py +1807 -0
  121. numba_cuda/numba/cuda/np/numpy_support.py +553 -0
  122. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +59 -0
  123. numba_cuda/numba/cuda/nvvmutils.py +4 -1
  124. numba_cuda/numba/cuda/printimpl.py +15 -1
  125. numba_cuda/numba/cuda/random.py +4 -1
  126. numba_cuda/numba/cuda/reshape_funcs.cu +5 -0
  127. numba_cuda/numba/cuda/serialize.py +4 -1
  128. numba_cuda/numba/cuda/simulator/__init__.py +4 -1
  129. numba_cuda/numba/cuda/simulator/_internal/__init__.py +3 -0
  130. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  131. numba_cuda/numba/cuda/simulator/api.py +4 -1
  132. numba_cuda/numba/cuda/simulator/bf16.py +3 -0
  133. numba_cuda/numba/cuda/simulator/compiler.py +7 -0
  134. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +3 -0
  135. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +4 -1
  136. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +3 -0
  137. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +3 -0
  138. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +3 -0
  139. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +3 -0
  140. numba_cuda/numba/cuda/simulator/cudadrv/error.py +4 -0
  141. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +4 -0
  142. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +4 -0
  143. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +3 -0
  144. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +3 -0
  145. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +3 -0
  146. numba_cuda/numba/cuda/simulator/dispatcher.py +4 -0
  147. numba_cuda/numba/cuda/simulator/kernel.py +3 -0
  148. numba_cuda/numba/cuda/simulator/kernelapi.py +4 -1
  149. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +3 -0
  150. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +17 -2
  151. numba_cuda/numba/cuda/simulator/reduction.py +3 -0
  152. numba_cuda/numba/cuda/simulator/vector_types.py +3 -0
  153. numba_cuda/numba/cuda/simulator_init.py +3 -0
  154. numba_cuda/numba/cuda/stubs.py +3 -0
  155. numba_cuda/numba/cuda/target.py +38 -17
  156. numba_cuda/numba/cuda/testing.py +7 -19
  157. numba_cuda/numba/cuda/tests/__init__.py +4 -1
  158. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  159. numba_cuda/numba/cuda/tests/complex_usecases.py +3 -0
  160. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +3 -0
  161. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +3 -0
  162. numba_cuda/numba/cuda/tests/core/test_serialize.py +7 -4
  163. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +3 -0
  164. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +3 -0
  165. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +3 -0
  166. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +3 -0
  167. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +3 -0
  168. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +4 -1
  169. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +3 -0
  170. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_libraries.py +4 -1
  171. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +3 -0
  172. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +3 -0
  173. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +4 -1
  174. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +9 -3
  175. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +4 -1
  176. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +3 -0
  177. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +3 -0
  178. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +3 -0
  179. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +3 -0
  180. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +3 -0
  181. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +21 -2
  182. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +3 -0
  183. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +5 -1
  184. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +4 -1
  185. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +3 -0
  186. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +3 -0
  187. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +3 -0
  188. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +3 -0
  189. numba_cuda/numba/cuda/tests/cudadrv/test_ptds.py +4 -1
  190. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +3 -0
  191. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +3 -0
  192. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +3 -0
  193. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +3 -0
  194. numba_cuda/numba/cuda/tests/cudapy/__init__.py +3 -0
  195. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +3 -0
  196. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +3 -0
  197. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +3 -0
  198. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +4 -1
  199. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +3 -0
  200. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +3 -0
  201. numba_cuda/numba/cuda/tests/cudapy/test_array.py +5 -1
  202. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +3 -0
  203. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +3 -0
  204. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +3 -0
  205. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +4 -1
  206. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +542 -2
  207. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +84 -1
  208. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +3 -0
  209. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +3 -0
  210. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +4 -3
  211. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +3 -0
  212. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +3 -0
  213. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +3 -0
  214. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +4 -1
  215. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +3 -0
  216. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +3 -0
  217. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +4 -1
  218. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +5 -3
  219. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +130 -0
  220. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +3 -0
  221. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +3 -0
  222. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +4 -1
  223. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +4 -1
  224. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +314 -3
  225. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +4 -1
  226. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +3 -0
  227. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +4 -1
  228. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +3 -0
  229. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +4 -1
  230. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +4 -1
  231. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +5 -1
  232. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +3 -0
  233. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +3 -0
  234. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +3 -0
  235. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +3 -0
  236. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +3 -0
  237. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +3 -0
  238. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +3 -0
  239. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +3 -0
  240. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +3 -0
  241. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +21 -8
  242. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +3 -0
  243. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +3 -0
  244. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +3 -0
  245. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +13 -37
  246. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +3 -0
  247. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +3 -0
  248. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +4 -1
  249. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +3 -0
  250. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +3 -0
  251. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +3 -0
  252. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +3 -0
  253. numba_cuda/numba/cuda/tests/cudapy/test_math.py +4 -1
  254. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +4 -1
  255. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +3 -0
  256. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +3 -0
  257. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +3 -0
  258. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +3 -0
  259. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +3 -0
  260. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +3 -0
  261. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +4 -1
  262. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +3 -0
  263. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +3 -0
  264. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +3 -0
  265. numba_cuda/numba/cuda/tests/cudapy/test_print.py +23 -0
  266. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +3 -0
  267. numba_cuda/numba/cuda/tests/cudapy/test_random.py +3 -0
  268. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +4 -1
  269. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +3 -0
  270. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +4 -1
  271. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +3 -0
  272. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +4 -1
  273. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +3 -0
  274. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +4 -1
  275. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +3 -0
  276. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +453 -0
  277. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +3 -0
  278. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +4 -1
  279. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +3 -0
  280. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  281. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +266 -2
  282. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +4 -1
  283. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +4 -1
  284. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +3 -0
  285. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +3 -0
  286. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +115 -6
  287. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +3 -0
  288. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +3 -0
  289. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +4 -1
  290. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +4 -1
  291. numba_cuda/numba/cuda/tests/cudasim/__init__.py +3 -0
  292. numba_cuda/numba/cuda/tests/cudasim/support.py +3 -0
  293. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +3 -0
  294. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  295. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +5 -0
  296. numba_cuda/numba/cuda/tests/data/cuda_include.cu +5 -0
  297. numba_cuda/numba/cuda/tests/data/error.cu +5 -0
  298. numba_cuda/numba/cuda/tests/data/include/add.cuh +5 -0
  299. numba_cuda/numba/cuda/tests/data/jitlink.cu +5 -0
  300. numba_cuda/numba/cuda/tests/data/warn.cu +5 -0
  301. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +3 -0
  302. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  303. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +5 -0
  304. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +5 -0
  305. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +5 -0
  306. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +3 -2
  307. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +3 -0
  308. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +3 -0
  309. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +6 -2
  310. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +3 -2
  311. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +3 -0
  312. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +3 -0
  313. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +3 -0
  314. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +3 -0
  315. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +3 -2
  316. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +3 -0
  317. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +3 -0
  318. numba_cuda/numba/cuda/tests/enum_usecases.py +3 -0
  319. numba_cuda/numba/cuda/tests/nocuda/__init__.py +3 -0
  320. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +3 -0
  321. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +3 -0
  322. numba_cuda/numba/cuda/tests/nocuda/test_import.py +6 -1
  323. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +27 -12
  324. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +3 -0
  325. numba_cuda/numba/cuda/tests/nrt/__init__.py +3 -0
  326. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +5 -1
  327. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +3 -0
  328. numba_cuda/numba/cuda/tests/support.py +58 -15
  329. numba_cuda/numba/cuda/tests/test_binary_generation/Makefile +3 -0
  330. numba_cuda/numba/cuda/tests/test_binary_generation/generate_raw_ltoir.py +2 -1
  331. numba_cuda/numba/cuda/tests/test_binary_generation/nrt_extern.cu +5 -0
  332. numba_cuda/numba/cuda/tests/test_binary_generation/test_device_functions.cu +5 -0
  333. numba_cuda/numba/cuda/tests/test_binary_generation/undefined_extern.cu +5 -0
  334. numba_cuda/numba/cuda/tests/test_tracing.py +200 -0
  335. numba_cuda/numba/cuda/types.py +59 -0
  336. numba_cuda/numba/cuda/typing/__init__.py +12 -1
  337. numba_cuda/numba/cuda/typing/cffi_utils.py +55 -0
  338. numba_cuda/numba/cuda/typing/context.py +751 -0
  339. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  340. numba_cuda/numba/cuda/typing/npydecl.py +658 -0
  341. numba_cuda/numba/cuda/typing/templates.py +10 -14
  342. numba_cuda/numba/cuda/ufuncs.py +6 -3
  343. numba_cuda/numba/cuda/utils.py +9 -112
  344. numba_cuda/numba/cuda/vector_types.py +3 -0
  345. numba_cuda/numba/cuda/vectorizers.py +3 -0
  346. {numba_cuda-0.19.0.dist-info → numba_cuda-0.20.0.dist-info}/METADATA +6 -2
  347. numba_cuda-0.20.0.dist-info/RECORD +357 -0
  348. {numba_cuda-0.19.0.dist-info → numba_cuda-0.20.0.dist-info}/licenses/LICENSE +1 -0
  349. numba_cuda-0.20.0.dist-info/licenses/LICENSE.numba +24 -0
  350. numba_cuda/numba/cuda/tests/cudadrv/test_mvc.py +0 -57
  351. numba_cuda-0.19.0.dist-info/RECORD +0 -301
  352. {numba_cuda-0.19.0.dist-info → numba_cuda-0.20.0.dist-info}/WHEEL +0 -0
  353. {numba_cuda-0.19.0.dist-info → numba_cuda-0.20.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1289 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ from collections import defaultdict
5
+ import copy
6
+ import sys
7
+ from itertools import permutations, takewhile
8
+ from contextlib import contextmanager
9
+ from functools import cached_property
10
+
11
+ from llvmlite import ir as llvmir
12
+ from llvmlite.ir import Constant
13
+ import llvmlite.binding as ll
14
+
15
+ from numba.core import (
16
+ types,
17
+ utils,
18
+ datamodel,
19
+ funcdesc,
20
+ config,
21
+ imputils,
22
+ )
23
+ from numba.cuda import cgutils, debuginfo
24
+ from numba.core import errors, targetconfig
25
+ from numba import _dynfunc, _helperlib
26
+ from numba.core.compiler_lock import global_compiler_lock
27
+ from numba.cuda.core.pythonapi import PythonAPI
28
+ from numba.core.imputils import (
29
+ user_function,
30
+ user_generator,
31
+ builtin_registry,
32
+ impl_ret_borrowed,
33
+ RegistryLoader,
34
+ )
35
+
36
+ GENERIC_POINTER = llvmir.PointerType(llvmir.IntType(8))
37
+ PYOBJECT = GENERIC_POINTER
38
+ void_ptr = GENERIC_POINTER
39
+
40
+
41
+ class OverloadSelector(object):
42
+ """
43
+ An object matching an actual signature against a registry of formal
44
+ signatures and choosing the best candidate, if any.
45
+
46
+ In the current implementation:
47
+ - a "signature" is a tuple of type classes or type instances
48
+ - the "best candidate" is the most specific match
49
+ """
50
+
51
+ def __init__(self):
52
+ # A list of (formal args tuple, value)
53
+ self.versions = []
54
+ self._cache = {}
55
+
56
+ def find(self, sig):
57
+ out = self._cache.get(sig)
58
+ if out is None:
59
+ out = self._find(sig)
60
+ self._cache[sig] = out
61
+ return out
62
+
63
+ def _find(self, sig):
64
+ candidates = self._select_compatible(sig)
65
+ if candidates:
66
+ return candidates[self._best_signature(candidates)]
67
+ else:
68
+ raise errors.NumbaNotImplementedError(f"{self}, {sig}")
69
+
70
+ def _select_compatible(self, sig):
71
+ """
72
+ Select all compatible signatures and their implementation.
73
+ """
74
+ out = {}
75
+ for ver_sig, impl in self.versions:
76
+ if self._match_arglist(ver_sig, sig):
77
+ out[ver_sig] = impl
78
+ return out
79
+
80
+ def _best_signature(self, candidates):
81
+ """
82
+ Returns the best signature out of the candidates
83
+ """
84
+ ordered, genericity = self._sort_signatures(candidates)
85
+ # check for ambiguous signatures
86
+ if len(ordered) > 1:
87
+ firstscore = genericity[ordered[0]]
88
+ same = list(
89
+ takewhile(lambda x: genericity[x] == firstscore, ordered)
90
+ )
91
+ if len(same) > 1:
92
+ msg = ["{n} ambiguous signatures".format(n=len(same))]
93
+ for sig in same:
94
+ msg += ["{0} => {1}".format(sig, candidates[sig])]
95
+ raise errors.NumbaTypeError("\n".join(msg))
96
+ return ordered[0]
97
+
98
+ def _sort_signatures(self, candidates):
99
+ """
100
+ Sort signatures in ascending level of genericity.
101
+
102
+ Returns a 2-tuple:
103
+
104
+ * ordered list of signatures
105
+ * dictionary containing genericity scores
106
+ """
107
+ # score by genericity
108
+ genericity = defaultdict(int)
109
+ for this, other in permutations(candidates.keys(), r=2):
110
+ matched = self._match_arglist(formal_args=this, actual_args=other)
111
+ if matched:
112
+ # genericity score +1 for every another compatible signature
113
+ genericity[this] += 1
114
+ # order candidates in ascending level of genericity
115
+ ordered = sorted(candidates.keys(), key=lambda x: genericity[x])
116
+ return ordered, genericity
117
+
118
+ def _match_arglist(self, formal_args, actual_args):
119
+ """
120
+ Returns True if the signature is "matching".
121
+ A formal signature is "matching" if the actual signature matches exactly
122
+ or if the formal signature is a compatible generic signature.
123
+ """
124
+ # normalize VarArg
125
+ if formal_args and isinstance(formal_args[-1], types.VarArg):
126
+ ndiff = len(actual_args) - len(formal_args) + 1
127
+ formal_args = formal_args[:-1] + (formal_args[-1].dtype,) * ndiff
128
+
129
+ if len(formal_args) != len(actual_args):
130
+ return False
131
+
132
+ for formal, actual in zip(formal_args, actual_args):
133
+ if not self._match(formal, actual):
134
+ return False
135
+
136
+ return True
137
+
138
+ def _match(self, formal, actual):
139
+ if formal == actual:
140
+ # formal argument matches actual arguments
141
+ return True
142
+ elif types.Any == formal:
143
+ # formal argument is any
144
+ return True
145
+ elif isinstance(formal, type) and issubclass(formal, types.Type):
146
+ if isinstance(actual, type) and issubclass(actual, formal):
147
+ # formal arg is a type class and actual arg is a subclass
148
+ return True
149
+ elif isinstance(actual, formal):
150
+ # formal arg is a type class of which actual arg is an instance
151
+ return True
152
+
153
+ def append(self, value, sig):
154
+ """
155
+ Add a formal signature and its associated value.
156
+ """
157
+ assert isinstance(sig, tuple), (value, sig)
158
+ self.versions.append((sig, value))
159
+ self._cache.clear()
160
+
161
+
162
+ @utils.runonce
163
+ def _load_global_helpers():
164
+ """
165
+ Execute once to install special symbols into the LLVM symbol table.
166
+ """
167
+ # This is Py_None's real C name
168
+ ll.add_symbol("_Py_NoneStruct", id(None))
169
+
170
+ # Add Numba C helper functions
171
+ for c_helpers in (_helperlib.c_helpers, _dynfunc.c_helpers):
172
+ for py_name, c_address in c_helpers.items():
173
+ c_name = "numba_" + py_name
174
+ ll.add_symbol(c_name, c_address)
175
+
176
+ # Add all built-in exception classes
177
+ for obj in utils.builtins.__dict__.values():
178
+ if isinstance(obj, type) and issubclass(obj, BaseException):
179
+ ll.add_symbol("PyExc_%s" % (obj.__name__), id(obj))
180
+
181
+
182
+ class BaseContext(object):
183
+ """
184
+
185
+ Notes on Structure
186
+ ------------------
187
+
188
+ Most objects are lowered as plain-old-data structure in the generated
189
+ llvm. They are passed around by reference (a pointer to the structure).
190
+ Only POD structure can live across function boundaries by copying the
191
+ data.
192
+ """
193
+
194
+ # True if the target requires strict alignment
195
+ # Causes exception to be raised if the record members are not aligned.
196
+ strict_alignment = False
197
+
198
+ # Force powi implementation as math.pow call
199
+ implement_powi_as_math_call = False
200
+ implement_pow_as_math_call = False
201
+
202
+ # Emit Debug info
203
+ enable_debuginfo = False
204
+ DIBuilder = debuginfo.DIBuilder
205
+
206
+ # Bound checking
207
+ @property
208
+ def enable_boundscheck(self):
209
+ if config.BOUNDSCHECK is not None:
210
+ return config.BOUNDSCHECK
211
+ return self._boundscheck
212
+
213
+ @enable_boundscheck.setter
214
+ def enable_boundscheck(self, value):
215
+ self._boundscheck = value
216
+
217
+ # NRT
218
+ enable_nrt = False
219
+
220
+ # Auto parallelization
221
+ auto_parallel = False
222
+
223
+ # PYCC
224
+ aot_mode = False
225
+
226
+ # Error model for various operations (only FP exceptions currently)
227
+ error_model = None
228
+
229
+ # Whether dynamic globals (CPU runtime addresses) is allowed
230
+ allow_dynamic_globals = False
231
+
232
+ # Fast math flags
233
+ fastmath = False
234
+
235
+ # python execution environment
236
+ environment = None
237
+
238
+ # the function descriptor
239
+ fndesc = None
240
+
241
+ def __init__(self, typing_context, target):
242
+ _load_global_helpers()
243
+
244
+ self.address_size = utils.MACHINE_BITS
245
+ self.typing_context = typing_context
246
+ from numba.core.target_extension import target_registry
247
+
248
+ self.target_name = target
249
+ self.target = target_registry[target]
250
+
251
+ # A mapping of installed registries to their loaders
252
+ self._registries = {}
253
+ # Declarations loaded from registries and other sources
254
+ self._defns = defaultdict(OverloadSelector)
255
+ self._getattrs = defaultdict(OverloadSelector)
256
+ self._setattrs = defaultdict(OverloadSelector)
257
+ self._casts = OverloadSelector()
258
+ self._get_constants = OverloadSelector()
259
+ # Other declarations
260
+ self._generators = {}
261
+ self.special_ops = {}
262
+ self.cached_internal_func = {}
263
+ self._pid = None
264
+ self._codelib_stack = []
265
+
266
+ self._boundscheck = False
267
+
268
+ self.data_model_manager = datamodel.default_manager
269
+
270
+ # Initialize
271
+ self.init()
272
+
273
+ def init(self):
274
+ """
275
+ For subclasses to add initializer
276
+ """
277
+
278
+ def refresh(self):
279
+ """
280
+ Refresh context with new declarations from known registries.
281
+ Useful for third-party extensions.
282
+ """
283
+ # load target specific registries
284
+ self.load_additional_registries()
285
+
286
+ # Populate the builtin registry, this has to happen after loading
287
+ # additional registries as some of the "additional" registries write
288
+ # their implementations into the builtin_registry and would be missed if
289
+ # this ran first.
290
+ self.install_registry(builtin_registry)
291
+
292
+ # Also refresh typing context, since @overload declarations can
293
+ # affect it.
294
+ self.typing_context.refresh()
295
+
296
+ def load_additional_registries(self):
297
+ """
298
+ Load target-specific registries. Can be overridden by subclasses.
299
+ """
300
+
301
+ def mangler(self, name, types, *, abi_tags=(), uid=None):
302
+ """
303
+ Perform name mangling.
304
+ """
305
+ return funcdesc.default_mangler(name, types, abi_tags=abi_tags, uid=uid)
306
+
307
+ def get_env_name(self, fndesc):
308
+ """Get the environment name given a FunctionDescriptor.
309
+
310
+ Use this instead of the ``fndesc.env_name`` so that the target-context
311
+ can provide necessary mangling of the symbol to meet ABI requirements.
312
+ """
313
+ return fndesc.env_name
314
+
315
+ def declare_env_global(self, module, envname):
316
+ """Declare the Environment pointer as a global of the module.
317
+
318
+ The pointer is initialized to NULL. It must be filled by the runtime
319
+ with the actual address of the Env before the associated function
320
+ can be executed.
321
+
322
+ Parameters
323
+ ----------
324
+ module :
325
+ The LLVM Module
326
+ envname : str
327
+ The name of the global variable.
328
+ """
329
+ if envname not in module.globals:
330
+ gv = llvmir.GlobalVariable(module, cgutils.voidptr_t, name=envname)
331
+ gv.linkage = "common"
332
+ gv.initializer = cgutils.get_null_value(gv.type.pointee)
333
+
334
+ return module.globals[envname]
335
+
336
+ def get_arg_packer(self, fe_args):
337
+ return datamodel.ArgPacker(self.data_model_manager, fe_args)
338
+
339
+ def get_data_packer(self, fe_types):
340
+ return datamodel.DataPacker(self.data_model_manager, fe_types)
341
+
342
+ @property
343
+ def target_data(self):
344
+ raise NotImplementedError
345
+
346
+ @cached_property
347
+ def nonconst_module_attrs(self):
348
+ """
349
+ All module attrs are constant for targets using BaseContext.
350
+ """
351
+ return tuple()
352
+
353
+ @cached_property
354
+ def nrt(self):
355
+ from numba.core.runtime.context import NRTContext
356
+
357
+ return NRTContext(self, self.enable_nrt)
358
+
359
+ def subtarget(self, **kws):
360
+ obj = copy.copy(self) # shallow copy
361
+ for k, v in kws.items():
362
+ if not hasattr(obj, k):
363
+ raise NameError("unknown option {0!r}".format(k))
364
+ setattr(obj, k, v)
365
+ if obj.codegen() is not self.codegen():
366
+ # We can't share functions across different codegens
367
+ obj.cached_internal_func = {}
368
+ return obj
369
+
370
+ def install_registry(self, registry):
371
+ """
372
+ Install a *registry* (a imputils.Registry instance) of function
373
+ and attribute implementations.
374
+ """
375
+ try:
376
+ loader = self._registries[registry]
377
+ except KeyError:
378
+ loader = RegistryLoader(registry)
379
+ self._registries[registry] = loader
380
+ self.insert_func_defn(loader.new_registrations("functions"))
381
+ self._insert_getattr_defn(loader.new_registrations("getattrs"))
382
+ self._insert_setattr_defn(loader.new_registrations("setattrs"))
383
+ self._insert_cast_defn(loader.new_registrations("casts"))
384
+ self._insert_get_constant_defn(loader.new_registrations("constants"))
385
+
386
+ def insert_func_defn(self, defns):
387
+ for impl, func, sig in defns:
388
+ self._defns[func].append(impl, sig)
389
+
390
+ def _insert_getattr_defn(self, defns):
391
+ for impl, attr, sig in defns:
392
+ self._getattrs[attr].append(impl, sig)
393
+
394
+ def _insert_setattr_defn(self, defns):
395
+ for impl, attr, sig in defns:
396
+ self._setattrs[attr].append(impl, sig)
397
+
398
+ def _insert_cast_defn(self, defns):
399
+ for impl, sig in defns:
400
+ self._casts.append(impl, sig)
401
+
402
+ def _insert_get_constant_defn(self, defns):
403
+ for impl, sig in defns:
404
+ self._get_constants.append(impl, sig)
405
+
406
+ def insert_user_function(self, func, fndesc, libs=()):
407
+ impl = user_function(fndesc, libs)
408
+ self._defns[func].append(impl, impl.signature)
409
+
410
+ def insert_generator(self, genty, gendesc, libs=()):
411
+ assert isinstance(genty, types.Generator)
412
+ impl = user_generator(gendesc, libs)
413
+ self._generators[genty] = gendesc, impl
414
+
415
+ def remove_user_function(self, func):
416
+ """
417
+ Remove user function *func*.
418
+ KeyError is raised if the function isn't known to us.
419
+ """
420
+ del self._defns[func]
421
+
422
+ def get_external_function_type(self, fndesc):
423
+ argtypes = [self.get_argument_type(aty) for aty in fndesc.argtypes]
424
+ # don't wrap in pointer
425
+ restype = self.get_argument_type(fndesc.restype)
426
+ fnty = llvmir.FunctionType(restype, argtypes)
427
+ return fnty
428
+
429
+ def declare_function(self, module, fndesc):
430
+ fnty = self.call_conv.get_function_type(fndesc.restype, fndesc.argtypes)
431
+ fn = cgutils.get_or_insert_function(module, fnty, fndesc.mangled_name)
432
+ self.call_conv.decorate_function(
433
+ fn, fndesc.args, fndesc.argtypes, noalias=fndesc.noalias
434
+ )
435
+ if fndesc.inline:
436
+ fn.attributes.add("alwaysinline")
437
+ # alwaysinline overrides optnone
438
+ fn.attributes.discard("noinline")
439
+ fn.attributes.discard("optnone")
440
+ return fn
441
+
442
+ def declare_external_function(self, module, fndesc):
443
+ fnty = self.get_external_function_type(fndesc)
444
+ fn = cgutils.get_or_insert_function(module, fnty, fndesc.mangled_name)
445
+ assert fn.is_declaration
446
+ for ak, av in zip(fndesc.args, fn.args):
447
+ av.name = "arg.%s" % ak
448
+ return fn
449
+
450
+ def insert_const_string(self, mod, string):
451
+ """
452
+ Insert constant *string* (a str object) into module *mod*.
453
+ """
454
+ stringtype = GENERIC_POINTER
455
+ name = ".const.%s" % string
456
+ text = cgutils.make_bytearray(string.encode("utf-8") + b"\x00")
457
+ gv = self.insert_unique_const(mod, name, text)
458
+ return Constant.bitcast(gv, stringtype)
459
+
460
+ def insert_const_bytes(self, mod, bytes, name=None):
461
+ """
462
+ Insert constant *byte* (a `bytes` object) into module *mod*.
463
+ """
464
+ stringtype = GENERIC_POINTER
465
+ name = ".bytes.%s" % (name or hash(bytes))
466
+ text = cgutils.make_bytearray(bytes)
467
+ gv = self.insert_unique_const(mod, name, text)
468
+ return Constant.bitcast(gv, stringtype)
469
+
470
+ def insert_unique_const(self, mod, name, val):
471
+ """
472
+ Insert a unique internal constant named *name*, with LLVM value
473
+ *val*, into module *mod*.
474
+ """
475
+ try:
476
+ gv = mod.get_global(name)
477
+ except KeyError:
478
+ return cgutils.global_constant(mod, name, val)
479
+ else:
480
+ return gv
481
+
482
+ def get_argument_type(self, ty):
483
+ return self.data_model_manager[ty].get_argument_type()
484
+
485
+ def get_return_type(self, ty):
486
+ return self.data_model_manager[ty].get_return_type()
487
+
488
+ def get_data_type(self, ty):
489
+ """
490
+ Get a LLVM data representation of the Numba type *ty* that is safe
491
+ for storage. Record data are stored as byte array.
492
+
493
+ The return value is a llvmlite.ir.Type object, or None if the type
494
+ is an opaque pointer (???).
495
+ """
496
+ return self.data_model_manager[ty].get_data_type()
497
+
498
+ def get_value_type(self, ty):
499
+ return self.data_model_manager[ty].get_value_type()
500
+
501
+ def pack_value(self, builder, ty, value, ptr, align=None):
502
+ """
503
+ Pack value into the array storage at *ptr*.
504
+ If *align* is given, it is the guaranteed alignment for *ptr*
505
+ (by default, the standard ABI alignment).
506
+ """
507
+ dataval = self.data_model_manager[ty].as_data(builder, value)
508
+ builder.store(dataval, ptr, align=align)
509
+
510
+ def unpack_value(self, builder, ty, ptr, align=None):
511
+ """
512
+ Unpack value from the array storage at *ptr*.
513
+ If *align* is given, it is the guaranteed alignment for *ptr*
514
+ (by default, the standard ABI alignment).
515
+ """
516
+ dm = self.data_model_manager[ty]
517
+ return dm.load_from_data_pointer(builder, ptr, align)
518
+
519
+ def get_constant_generic(self, builder, ty, val):
520
+ """
521
+ Return a LLVM constant representing value *val* of Numba type *ty*.
522
+ """
523
+ try:
524
+ impl = self._get_constants.find((ty,))
525
+ return impl(self, builder, ty, val)
526
+ except NotImplementedError:
527
+ raise NotImplementedError(
528
+ "Cannot lower constant of type '%s'" % (ty,)
529
+ )
530
+
531
+ def get_constant(self, ty, val):
532
+ """
533
+ Same as get_constant_generic(), but without specifying *builder*.
534
+ Works only for simple types.
535
+ """
536
+ # HACK: pass builder=None to preserve get_constant() API
537
+ return self.get_constant_generic(None, ty, val)
538
+
539
+ def get_constant_undef(self, ty):
540
+ lty = self.get_value_type(ty)
541
+ return Constant(lty, llvmir.Undefined)
542
+
543
+ def get_constant_null(self, ty):
544
+ lty = self.get_value_type(ty)
545
+ return Constant(lty, None)
546
+
547
+ def get_function(self, fn, sig, _firstcall=True):
548
+ """
549
+ Return the implementation of function *fn* for signature *sig*.
550
+ The return value is a callable with the signature (builder, args).
551
+ """
552
+ assert sig is not None
553
+ sig = sig.as_function()
554
+ if isinstance(fn, types.Callable):
555
+ key = fn.get_impl_key(sig)
556
+ overloads = self._defns[key]
557
+ else:
558
+ key = fn
559
+ overloads = self._defns[key]
560
+
561
+ try:
562
+ return _wrap_impl(overloads.find(sig.args), self, sig)
563
+ except errors.NumbaNotImplementedError:
564
+ pass
565
+ if isinstance(fn, types.Type):
566
+ # It's a type instance => try to find a definition for the type class
567
+ try:
568
+ return self.get_function(type(fn), sig)
569
+ except NotImplementedError:
570
+ # Raise exception for the type instance, for a better error message
571
+ pass
572
+
573
+ # Automatically refresh the context to load new registries if we are
574
+ # calling the first time.
575
+ if _firstcall:
576
+ self.refresh()
577
+ return self.get_function(fn, sig, _firstcall=False)
578
+
579
+ raise NotImplementedError(
580
+ "No definition for lowering %s%s" % (key, sig)
581
+ )
582
+
583
+ def get_generator_desc(self, genty):
584
+ """ """
585
+ return self._generators[genty][0]
586
+
587
+ def get_generator_impl(self, genty):
588
+ """ """
589
+ res = self._generators[genty][1]
590
+ self.add_linking_libs(getattr(res, "libs", ()))
591
+ return res
592
+
593
+ def get_bound_function(self, builder, obj, ty):
594
+ assert self.get_value_type(ty) == obj.type
595
+ return obj
596
+
597
+ def get_getattr(self, typ, attr):
598
+ """
599
+ Get the getattr() implementation for the given type and attribute name.
600
+ The return value is a callable with the signature
601
+ (context, builder, typ, val, attr).
602
+ """
603
+ const_attr = (typ, attr) not in self.nonconst_module_attrs
604
+ is_module = isinstance(typ, types.Module)
605
+ if is_module and const_attr:
606
+ # Implement getattr for module-level globals that we treat as
607
+ # constants.
608
+ # XXX We shouldn't have to retype this
609
+ attrty = self.typing_context.resolve_module_constants(typ, attr)
610
+ if attrty is None or isinstance(attrty, types.Dummy):
611
+ # No implementation required for dummies (functions, modules...),
612
+ # which are dealt with later
613
+ return None
614
+ else:
615
+ pyval = getattr(typ.pymod, attr)
616
+
617
+ def imp(context, builder, typ, val, attr):
618
+ llval = self.get_constant_generic(builder, attrty, pyval)
619
+ return impl_ret_borrowed(context, builder, attrty, llval)
620
+
621
+ return imp
622
+
623
+ # Lookup specific getattr implementation for this type and attribute
624
+ overloads = self._getattrs[attr]
625
+ try:
626
+ return overloads.find((typ,))
627
+ except errors.NumbaNotImplementedError:
628
+ pass
629
+ # Lookup generic getattr implementation for this type
630
+ overloads = self._getattrs[None]
631
+ try:
632
+ return overloads.find((typ,))
633
+ except errors.NumbaNotImplementedError:
634
+ pass
635
+
636
+ raise NotImplementedError(
637
+ "No definition for lowering %s.%s" % (typ, attr)
638
+ )
639
+
640
+ def get_setattr(self, attr, sig):
641
+ """
642
+ Get the setattr() implementation for the given attribute name
643
+ and signature.
644
+ The return value is a callable with the signature (builder, args).
645
+ """
646
+ assert len(sig.args) == 2
647
+ typ = sig.args[0]
648
+ valty = sig.args[1]
649
+
650
+ def wrap_setattr(impl):
651
+ def wrapped(builder, args):
652
+ return impl(self, builder, sig, args, attr)
653
+
654
+ return wrapped
655
+
656
+ # Lookup specific setattr implementation for this type and attribute
657
+ overloads = self._setattrs[attr]
658
+ try:
659
+ return wrap_setattr(overloads.find((typ, valty)))
660
+ except errors.NumbaNotImplementedError:
661
+ pass
662
+ # Lookup generic setattr implementation for this type
663
+ overloads = self._setattrs[None]
664
+ try:
665
+ return wrap_setattr(overloads.find((typ, valty)))
666
+ except errors.NumbaNotImplementedError:
667
+ pass
668
+
669
+ raise NotImplementedError(
670
+ "No definition for lowering %s.%s = %s" % (typ, attr, valty)
671
+ )
672
+
673
+ def get_argument_value(self, builder, ty, val):
674
+ """
675
+ Argument representation to local value representation
676
+ """
677
+ return self.data_model_manager[ty].from_argument(builder, val)
678
+
679
+ def get_returned_value(self, builder, ty, val):
680
+ """
681
+ Return value representation to local value representation
682
+ """
683
+ return self.data_model_manager[ty].from_return(builder, val)
684
+
685
+ def get_return_value(self, builder, ty, val):
686
+ """
687
+ Local value representation to return type representation
688
+ """
689
+ return self.data_model_manager[ty].as_return(builder, val)
690
+
691
+ def get_value_as_argument(self, builder, ty, val):
692
+ """Prepare local value representation as argument type representation"""
693
+ return self.data_model_manager[ty].as_argument(builder, val)
694
+
695
+ def get_value_as_data(self, builder, ty, val):
696
+ return self.data_model_manager[ty].as_data(builder, val)
697
+
698
+ def get_data_as_value(self, builder, ty, val):
699
+ return self.data_model_manager[ty].from_data(builder, val)
700
+
701
+ def pair_first(self, builder, val, ty):
702
+ """
703
+ Extract the first element of a heterogeneous pair.
704
+ """
705
+ pair = self.make_helper(builder, ty, val)
706
+ return pair.first
707
+
708
+ def pair_second(self, builder, val, ty):
709
+ """
710
+ Extract the second element of a heterogeneous pair.
711
+ """
712
+ pair = self.make_helper(builder, ty, val)
713
+ return pair.second
714
+
715
+ def cast(self, builder, val, fromty, toty):
716
+ """
717
+ Cast a value of type *fromty* to type *toty*.
718
+ This implements implicit conversions as can happen due to the
719
+ granularity of the Numba type system, or lax Python semantics.
720
+ """
721
+ if fromty is types._undef_var:
722
+ # Special case for undefined variable
723
+ return self.get_constant_null(toty)
724
+ elif fromty == toty or toty == types.Any:
725
+ return val
726
+ try:
727
+ impl = self._casts.find((fromty, toty))
728
+ return impl(self, builder, fromty, toty, val)
729
+ except errors.NumbaNotImplementedError:
730
+ raise errors.NumbaNotImplementedError(
731
+ "Cannot cast %s to %s: %s" % (fromty, toty, val)
732
+ )
733
+
734
+ def generic_compare(self, builder, key, argtypes, args):
735
+ """
736
+ Compare the given LLVM values of the given Numba types using
737
+ the comparison *key* (e.g. '=='). The values are first cast to
738
+ a common safe conversion type.
739
+ """
740
+ at, bt = argtypes
741
+ av, bv = args
742
+ ty = self.typing_context.unify_types(at, bt)
743
+ assert ty is not None
744
+ cav = self.cast(builder, av, at, ty)
745
+ cbv = self.cast(builder, bv, bt, ty)
746
+ fnty = self.typing_context.resolve_value_type(key)
747
+ # the sig is homogeneous in the unified casted type
748
+ cmpsig = fnty.get_call_type(self.typing_context, (ty, ty), {})
749
+ cmpfunc = self.get_function(fnty, cmpsig)
750
+ self.add_linking_libs(getattr(cmpfunc, "libs", ()))
751
+ return cmpfunc(builder, (cav, cbv))
752
+
753
+ def make_optional_none(self, builder, valtype):
754
+ optval = self.make_helper(builder, types.Optional(valtype))
755
+ optval.valid = cgutils.false_bit
756
+ return optval._getvalue()
757
+
758
+ def make_optional_value(self, builder, valtype, value):
759
+ optval = self.make_helper(builder, types.Optional(valtype))
760
+ optval.valid = cgutils.true_bit
761
+ optval.data = value
762
+ return optval._getvalue()
763
+
764
+ def is_true(self, builder, typ, val):
765
+ """
766
+ Return the truth value of a value of the given Numba type.
767
+ """
768
+ fnty = self.typing_context.resolve_value_type(bool)
769
+ sig = fnty.get_call_type(self.typing_context, (typ,), {})
770
+ impl = self.get_function(fnty, sig)
771
+ return impl(builder, (val,))
772
+
773
+ def get_c_value(self, builder, typ, name, dllimport=False):
774
+ """
775
+ Get a global value through its C-accessible *name*, with the given
776
+ LLVM type.
777
+ If *dllimport* is true, the symbol will be marked as imported
778
+ from a DLL (necessary for AOT compilation under Windows).
779
+ """
780
+ module = builder.function.module
781
+ try:
782
+ gv = module.globals[name]
783
+ except KeyError:
784
+ gv = cgutils.add_global_variable(module, typ, name)
785
+ if dllimport and self.aot_mode and sys.platform == "win32":
786
+ gv.storage_class = "dllimport"
787
+ return gv
788
+
789
+ def call_external_function(self, builder, callee, argtys, args):
790
+ args = [
791
+ self.get_value_as_argument(builder, ty, arg)
792
+ for ty, arg in zip(argtys, args)
793
+ ]
794
+ retval = builder.call(callee, args)
795
+ return retval
796
+
797
+ def get_function_pointer_type(self, typ):
798
+ return self.data_model_manager[typ].get_data_type()
799
+
800
+ def call_function_pointer(self, builder, funcptr, args, cconv=None):
801
+ return builder.call(funcptr, args, cconv=cconv)
802
+
803
+ def print_string(self, builder, text):
804
+ mod = builder.module
805
+ cstring = GENERIC_POINTER
806
+ fnty = llvmir.FunctionType(llvmir.IntType(32), [cstring])
807
+ puts = cgutils.get_or_insert_function(mod, fnty, "puts")
808
+ return builder.call(puts, [text])
809
+
810
+ def debug_print(self, builder, text):
811
+ mod = builder.module
812
+ cstr = self.insert_const_string(mod, str(text))
813
+ self.print_string(builder, cstr)
814
+
815
+ def printf(self, builder, format_string, *args):
816
+ mod = builder.module
817
+ if isinstance(format_string, str):
818
+ cstr = self.insert_const_string(mod, format_string)
819
+ else:
820
+ cstr = format_string
821
+ fnty = llvmir.FunctionType(
822
+ llvmir.IntType(32), (GENERIC_POINTER,), var_arg=True
823
+ )
824
+ fn = cgutils.get_or_insert_function(mod, fnty, "printf")
825
+ return builder.call(fn, (cstr,) + tuple(args))
826
+
827
+ def get_struct_type(self, struct):
828
+ """
829
+ Get the LLVM struct type for the given Structure class *struct*.
830
+ """
831
+ fields = [self.get_value_type(v) for _, v in struct._fields]
832
+ return llvmir.LiteralStructType(fields)
833
+
834
+ def get_dummy_value(self):
835
+ return Constant(self.get_dummy_type(), None)
836
+
837
+ def get_dummy_type(self):
838
+ return GENERIC_POINTER
839
+
840
+ def _compile_subroutine_no_cache(
841
+ self, builder, impl, sig, locals={}, flags=None
842
+ ):
843
+ """
844
+ Invoke the compiler to compile a function to be used inside a
845
+ nopython function, but without generating code to call that
846
+ function.
847
+
848
+ Note this context's flags are not inherited.
849
+ """
850
+ # Compile
851
+ from numba.core import compiler
852
+
853
+ with global_compiler_lock:
854
+ codegen = self.codegen()
855
+ library = codegen.create_library(impl.__name__)
856
+ if flags is None:
857
+ cstk = targetconfig.ConfigStack()
858
+ flags = compiler.Flags()
859
+ if cstk:
860
+ tls_flags = cstk.top()
861
+ if tls_flags.is_set("nrt") and tls_flags.nrt:
862
+ flags.nrt = True
863
+
864
+ flags.no_compile = True
865
+ flags.no_cpython_wrapper = True
866
+ flags.no_cfunc_wrapper = True
867
+
868
+ cres = compiler.compile_internal(
869
+ self.typing_context,
870
+ self,
871
+ library,
872
+ impl,
873
+ sig.args,
874
+ sig.return_type,
875
+ flags,
876
+ locals=locals,
877
+ )
878
+
879
+ # Allow inlining the function inside callers.
880
+ self.active_code_library.add_linking_library(cres.library)
881
+ return cres
882
+
883
+ def compile_subroutine(
884
+ self, builder, impl, sig, locals={}, flags=None, caching=True
885
+ ):
886
+ """
887
+ Compile the function *impl* for the given *sig* (in nopython mode).
888
+ Return an instance of CompileResult.
889
+
890
+ If *caching* evaluates True, the function keeps the compiled function
891
+ for reuse in *.cached_internal_func*.
892
+ """
893
+ cache_key = (impl.__code__, sig, type(self.error_model))
894
+ if not caching:
895
+ cached = None
896
+ else:
897
+ if impl.__closure__:
898
+ # XXX This obviously won't work if a cell's value is
899
+ # unhashable.
900
+ cache_key += tuple(c.cell_contents for c in impl.__closure__)
901
+ cached = self.cached_internal_func.get(cache_key)
902
+ if cached is None:
903
+ cres = self._compile_subroutine_no_cache(
904
+ builder, impl, sig, locals=locals, flags=flags
905
+ )
906
+ self.cached_internal_func[cache_key] = cres
907
+
908
+ cres = self.cached_internal_func[cache_key]
909
+ # Allow inlining the function inside callers.
910
+ self.active_code_library.add_linking_library(cres.library)
911
+ return cres
912
+
913
+ def compile_internal(self, builder, impl, sig, args, locals={}):
914
+ """
915
+ Like compile_subroutine(), but also call the function with the given
916
+ *args*.
917
+ """
918
+ cres = self.compile_subroutine(builder, impl, sig, locals)
919
+ return self.call_internal(builder, cres.fndesc, sig, args)
920
+
921
+ def call_internal(self, builder, fndesc, sig, args):
922
+ """
923
+ Given the function descriptor of an internally compiled function,
924
+ emit a call to that function with the given arguments.
925
+ """
926
+ status, res = self.call_internal_no_propagate(
927
+ builder, fndesc, sig, args
928
+ )
929
+ with cgutils.if_unlikely(builder, status.is_error):
930
+ self.call_conv.return_status_propagate(builder, status)
931
+
932
+ res = imputils.fix_returning_optional(self, builder, sig, status, res)
933
+ return res
934
+
935
+ def call_internal_no_propagate(self, builder, fndesc, sig, args):
936
+ """Similar to `.call_internal()` but does not handle or propagate
937
+ the return status automatically.
938
+ """
939
+ # Add call to the generated function
940
+ llvm_mod = builder.module
941
+ fn = self.declare_function(llvm_mod, fndesc)
942
+ status, res = self.call_conv.call_function(
943
+ builder, fn, sig.return_type, sig.args, args
944
+ )
945
+ return status, res
946
+
947
+ def call_unresolved(self, builder, name, sig, args):
948
+ """
949
+ Insert a function call to an unresolved symbol with the given *name*.
950
+
951
+ Note: this is used for recursive call.
952
+
953
+ In the mutual recursion case::
954
+
955
+ @njit
956
+ def foo(): ... # calls bar()
957
+
958
+
959
+ @njit
960
+ def bar(): ... # calls foo()
961
+
962
+
963
+ foo()
964
+
965
+ When foo() is called, the compilation of bar() is fully completed
966
+ (codegen'ed and loaded) before foo() is. Since MCJIT's eager compilation
967
+ doesn't allow loading modules with declare-only functions (which is
968
+ needed for foo() in bar()), the call_unresolved injects a global
969
+ variable that the "linker" can update even after the module is loaded by
970
+ MCJIT. The linker would allocate space for the global variable before
971
+ the bar() module is loaded. When later foo() module is defined, it will
972
+ update bar()'s reference to foo().
973
+
974
+ The legacy lazy JIT and the new ORC JIT would allow a declare-only
975
+ function be used in a module as long as it is defined by the time of its
976
+ first use.
977
+ """
978
+ # Insert an unresolved reference to the function being called.
979
+ codegen = self.codegen()
980
+ fnty = self.call_conv.get_function_type(sig.return_type, sig.args)
981
+ fn = codegen.insert_unresolved_ref(builder, fnty, name)
982
+ # Normal call sequence
983
+ status, res = self.call_conv.call_function(
984
+ builder, fn, sig.return_type, sig.args, args
985
+ )
986
+ with cgutils.if_unlikely(builder, status.is_error):
987
+ self.call_conv.return_status_propagate(builder, status)
988
+
989
+ res = imputils.fix_returning_optional(self, builder, sig, status, res)
990
+ return res
991
+
992
+ def get_executable(self, func, fndesc, env):
993
+ raise NotImplementedError
994
+
995
+ def get_python_api(self, builder):
996
+ return PythonAPI(self, builder)
997
+
998
+ def sentry_record_alignment(self, rectyp, attr):
999
+ """
1000
+ Assumes offset starts from a properly aligned location
1001
+ """
1002
+ if self.strict_alignment:
1003
+ offset = rectyp.offset(attr)
1004
+ elemty = rectyp.typeof(attr)
1005
+ if isinstance(elemty, types.NestedArray):
1006
+ # For a NestedArray we need to consider the data type of
1007
+ # elements of the array for alignment, not the array structure
1008
+ # itself
1009
+ elemty = elemty.dtype
1010
+ align = self.get_abi_alignment(self.get_data_type(elemty))
1011
+ if offset % align:
1012
+ msg = "{rec}.{attr} of type {type} is not aligned".format(
1013
+ rec=rectyp, attr=attr, type=elemty
1014
+ )
1015
+ raise errors.NumbaTypeError(msg)
1016
+
1017
+ def get_helper_class(self, typ, kind="value"):
1018
+ """
1019
+ Get a helper class for the given *typ*.
1020
+ """
1021
+ # XXX handle all types: complex, array, etc.
1022
+ # XXX should it be a method on the model instead? this would allow a default kind...
1023
+ return cgutils.create_struct_proxy(typ, kind)
1024
+
1025
+ def _make_helper(self, builder, typ, value=None, ref=None, kind="value"):
1026
+ cls = self.get_helper_class(typ, kind)
1027
+ return cls(self, builder, value=value, ref=ref)
1028
+
1029
+ def make_helper(self, builder, typ, value=None, ref=None):
1030
+ """
1031
+ Get a helper object to access the *typ*'s members,
1032
+ for the given value or reference.
1033
+ """
1034
+ return self._make_helper(builder, typ, value, ref, kind="value")
1035
+
1036
+ def make_data_helper(self, builder, typ, ref=None):
1037
+ """
1038
+ As make_helper(), but considers the value as stored in memory,
1039
+ rather than a live value.
1040
+ """
1041
+ return self._make_helper(builder, typ, ref=ref, kind="data")
1042
+
1043
+ def make_array(self, typ):
1044
+ from numba.np import arrayobj
1045
+
1046
+ return arrayobj.make_array(typ)
1047
+
1048
+ def populate_array(self, arr, **kwargs):
1049
+ """
1050
+ Populate array structure.
1051
+ """
1052
+ from numba.np import arrayobj
1053
+
1054
+ return arrayobj.populate_array(arr, **kwargs)
1055
+
1056
+ def make_complex(self, builder, typ, value=None):
1057
+ """
1058
+ Get a helper object to access the given complex numbers' members.
1059
+ """
1060
+ assert isinstance(typ, types.Complex), typ
1061
+ return self.make_helper(builder, typ, value)
1062
+
1063
+ def make_tuple(self, builder, typ, values):
1064
+ """
1065
+ Create a tuple of the given *typ* containing the *values*.
1066
+ """
1067
+ tup = self.get_constant_undef(typ)
1068
+ for i, val in enumerate(values):
1069
+ tup = builder.insert_value(tup, val, i)
1070
+ return tup
1071
+
1072
+ def make_constant_array(self, builder, typ, ary):
1073
+ """
1074
+ Create an array structure reifying the given constant array.
1075
+ A low-level contiguous array constant is created in the LLVM IR.
1076
+ """
1077
+ datatype = self.get_data_type(typ.dtype)
1078
+ # don't freeze ary of non-contig or bigger than 1MB
1079
+ size_limit = 10**6
1080
+
1081
+ if self.allow_dynamic_globals and (
1082
+ typ.layout not in "FC" or ary.nbytes > size_limit
1083
+ ):
1084
+ # get pointer from the ary
1085
+ dataptr = ary.ctypes.data
1086
+ data = self.add_dynamic_addr(
1087
+ builder, dataptr, info=str(type(dataptr))
1088
+ )
1089
+ rt_addr = self.add_dynamic_addr(
1090
+ builder, id(ary), info=str(type(ary))
1091
+ )
1092
+ else:
1093
+ # Handle data: reify the flattened array in "C" or "F" order as a
1094
+ # global array of bytes.
1095
+ flat = ary.flatten(order=typ.layout)
1096
+ # Note: we use `bytearray(flat.data)` instead of `bytearray(flat)` to
1097
+ # workaround issue #1850 which is due to numpy issue #3147
1098
+ consts = cgutils.create_constant_array(
1099
+ llvmir.IntType(8), bytearray(flat.data)
1100
+ )
1101
+ data = cgutils.global_constant(builder, ".const.array.data", consts)
1102
+ # Ensure correct data alignment (issue #1933)
1103
+ data.align = self.get_abi_alignment(datatype)
1104
+ # No reference to parent ndarray
1105
+ rt_addr = None
1106
+
1107
+ # Handle shape
1108
+ llintp = self.get_value_type(types.intp)
1109
+ shapevals = [self.get_constant(types.intp, s) for s in ary.shape]
1110
+ cshape = cgutils.create_constant_array(llintp, shapevals)
1111
+
1112
+ # Handle strides
1113
+ stridevals = [self.get_constant(types.intp, s) for s in ary.strides]
1114
+ cstrides = cgutils.create_constant_array(llintp, stridevals)
1115
+
1116
+ # Create array structure
1117
+ cary = self.make_array(typ)(self, builder)
1118
+
1119
+ intp_itemsize = self.get_constant(types.intp, ary.dtype.itemsize)
1120
+ self.populate_array(
1121
+ cary,
1122
+ data=builder.bitcast(data, cary.data.type),
1123
+ shape=cshape,
1124
+ strides=cstrides,
1125
+ itemsize=intp_itemsize,
1126
+ parent=rt_addr,
1127
+ meminfo=None,
1128
+ )
1129
+
1130
+ return cary._getvalue()
1131
+
1132
+ def add_dynamic_addr(self, builder, intaddr, info):
1133
+ """
1134
+ Returns dynamic address as a void pointer `i8*`.
1135
+
1136
+ Internally, a global variable is added to inform the lowerer about
1137
+ the usage of dynamic addresses. Caching will be disabled.
1138
+ """
1139
+ assert self.allow_dynamic_globals, "dyn globals disabled in this target"
1140
+ assert isinstance(intaddr, int), "dyn addr not of int type"
1141
+ mod = builder.module
1142
+ llvoidptr = self.get_value_type(types.voidptr)
1143
+ addr = self.get_constant(types.uintp, intaddr).inttoptr(llvoidptr)
1144
+ # Use a unique name by embedding the address value
1145
+ symname = "numba.dynamic.globals.{:x}".format(intaddr)
1146
+ gv = cgutils.add_global_variable(mod, llvoidptr, symname)
1147
+ # Use linkonce linkage to allow merging with other GV of the same name.
1148
+ # And, avoid optimization from assuming its value.
1149
+ gv.linkage = "linkonce"
1150
+ gv.initializer = addr
1151
+ return builder.load(gv)
1152
+
1153
+ def get_abi_sizeof(self, ty):
1154
+ """
1155
+ Get the ABI size of LLVM type *ty*.
1156
+ """
1157
+ assert isinstance(ty, llvmir.Type), "Expected LLVM type"
1158
+ return ty.get_abi_size(self.target_data)
1159
+
1160
+ def get_abi_alignment(self, ty):
1161
+ """
1162
+ Get the ABI alignment of LLVM type *ty*.
1163
+ """
1164
+ assert isinstance(ty, llvmir.Type), "Expected LLVM type"
1165
+ return ty.get_abi_alignment(self.target_data)
1166
+
1167
+ def get_preferred_array_alignment(context, ty):
1168
+ """
1169
+ Get preferred array alignment for Numba type *ty*.
1170
+ """
1171
+ # AVX prefers 32-byte alignment
1172
+ return 32
1173
+
1174
+ def post_lowering(self, mod, library):
1175
+ """Run target specific post-lowering transformation here."""
1176
+
1177
+ def create_module(self, name):
1178
+ """Create a LLVM module
1179
+
1180
+ The default implementation in BaseContext always raises a
1181
+ ``NotImplementedError`` exception. Subclasses should implement
1182
+ this method.
1183
+ """
1184
+ raise NotImplementedError
1185
+
1186
+ @property
1187
+ def active_code_library(self):
1188
+ """Get the active code library"""
1189
+ return self._codelib_stack[-1]
1190
+
1191
+ @contextmanager
1192
+ def push_code_library(self, lib):
1193
+ """Push the active code library for the context"""
1194
+ self._codelib_stack.append(lib)
1195
+ try:
1196
+ yield
1197
+ finally:
1198
+ self._codelib_stack.pop()
1199
+
1200
+ def add_linking_libs(self, libs):
1201
+ """Add iterable of linking libraries to the *active_code_library*."""
1202
+ colib = self.active_code_library
1203
+ for lib in libs:
1204
+ colib.add_linking_library(lib)
1205
+
1206
+ def get_ufunc_info(self, ufunc_key):
1207
+ """Get the ufunc implementation for a given ufunc object.
1208
+
1209
+ The default implementation in BaseContext always raises a
1210
+ ``NotImplementedError`` exception. Subclasses may raise ``KeyError``
1211
+ to signal that the given ``ufunc_key`` is not available.
1212
+
1213
+ Parameters
1214
+ ----------
1215
+ ufunc_key : NumPy ufunc
1216
+
1217
+ Returns
1218
+ -------
1219
+ res : dict[str, callable]
1220
+ A mapping of a NumPy ufunc type signature to a lower-level
1221
+ implementation.
1222
+ """
1223
+ raise NotImplementedError(f"{self} does not support ufunc")
1224
+
1225
+
1226
+ class _wrap_impl(object):
1227
+ """
1228
+ A wrapper object to call an implementation function with some predefined
1229
+ (context, signature) arguments.
1230
+ The wrapper also forwards attribute queries, which is important.
1231
+ """
1232
+
1233
+ def __init__(self, imp, context, sig):
1234
+ self._callable = _wrap_missing_loc(imp)
1235
+ self._imp = self._callable()
1236
+ self._context = context
1237
+ self._sig = sig
1238
+
1239
+ def __call__(self, builder, args, loc=None):
1240
+ res = self._imp(self._context, builder, self._sig, args, loc=loc)
1241
+ self._context.add_linking_libs(getattr(self, "libs", ()))
1242
+ return res
1243
+
1244
+ def __getattr__(self, item):
1245
+ return getattr(self._imp, item)
1246
+
1247
+ def __repr__(self):
1248
+ return "<wrapped %s>" % repr(self._callable)
1249
+
1250
+
1251
+ def _has_loc(fn):
1252
+ """Does function *fn* take ``loc`` argument?"""
1253
+ sig = utils.pysignature(fn)
1254
+ return "loc" in sig.parameters
1255
+
1256
+
1257
+ class _wrap_missing_loc(object):
1258
+ def __init__(self, fn):
1259
+ self.func = fn # store this to help with debug
1260
+
1261
+ def __call__(self):
1262
+ """Wrap function for missing ``loc`` keyword argument.
1263
+ Otherwise, return the original *fn*.
1264
+ """
1265
+ fn = self.func
1266
+ if not _has_loc(fn):
1267
+
1268
+ def wrapper(*args, **kwargs):
1269
+ kwargs.pop("loc") # drop unused loc
1270
+ return fn(*args, **kwargs)
1271
+
1272
+ # Copy the following attributes from the wrapped.
1273
+ # Following similar implementation as functools.wraps but
1274
+ # ignore attributes if not available (i.e fix py2.7)
1275
+ attrs = "__name__", "libs"
1276
+ for attr in attrs:
1277
+ try:
1278
+ val = getattr(fn, attr)
1279
+ except AttributeError:
1280
+ pass
1281
+ else:
1282
+ setattr(wrapper, attr, val)
1283
+
1284
+ return wrapper
1285
+ else:
1286
+ return fn
1287
+
1288
+ def __repr__(self):
1289
+ return "<wrapped %s>" % self.func