numba-cuda 0.22.0__cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. _numba_cuda_redirector.pth +4 -0
  2. _numba_cuda_redirector.py +89 -0
  3. numba_cuda/VERSION +1 -0
  4. numba_cuda/__init__.py +6 -0
  5. numba_cuda/_version.py +11 -0
  6. numba_cuda/numba/cuda/__init__.py +70 -0
  7. numba_cuda/numba/cuda/_internal/cuda_bf16.py +16394 -0
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +8112 -0
  9. numba_cuda/numba/cuda/api.py +580 -0
  10. numba_cuda/numba/cuda/api_util.py +76 -0
  11. numba_cuda/numba/cuda/args.py +72 -0
  12. numba_cuda/numba/cuda/bf16.py +397 -0
  13. numba_cuda/numba/cuda/cache_hints.py +287 -0
  14. numba_cuda/numba/cuda/cext/__init__.py +2 -0
  15. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpython-313-aarch64-linux-gnu.so +0 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpython-313-aarch64-linux-gnu.so +0 -0
  20. numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
  21. numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
  22. numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
  23. numba_cuda/numba/cuda/cext/_helperlib.cpython-313-aarch64-linux-gnu.so +0 -0
  24. numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
  25. numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
  26. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpython-313-aarch64-linux-gnu.so +0 -0
  28. numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
  29. numba_cuda/numba/cuda/cext/_typeof.h +19 -0
  30. numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
  31. numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
  32. numba_cuda/numba/cuda/cext/mviewbuf.cpython-313-aarch64-linux-gnu.so +0 -0
  33. numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
  34. numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
  35. numba_cuda/numba/cuda/cg.py +67 -0
  36. numba_cuda/numba/cuda/cgutils.py +1294 -0
  37. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  38. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  39. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  40. numba_cuda/numba/cuda/codegen.py +541 -0
  41. numba_cuda/numba/cuda/compiler.py +1396 -0
  42. numba_cuda/numba/cuda/core/analysis.py +758 -0
  43. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  44. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
  45. numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
  46. numba_cuda/numba/cuda/core/base.py +1332 -0
  47. numba_cuda/numba/cuda/core/boxing.py +1411 -0
  48. numba_cuda/numba/cuda/core/bytecode.py +728 -0
  49. numba_cuda/numba/cuda/core/byteflow.py +2346 -0
  50. numba_cuda/numba/cuda/core/caching.py +744 -0
  51. numba_cuda/numba/cuda/core/callconv.py +392 -0
  52. numba_cuda/numba/cuda/core/codegen.py +171 -0
  53. numba_cuda/numba/cuda/core/compiler.py +199 -0
  54. numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
  55. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  56. numba_cuda/numba/cuda/core/config.py +650 -0
  57. numba_cuda/numba/cuda/core/consts.py +124 -0
  58. numba_cuda/numba/cuda/core/controlflow.py +989 -0
  59. numba_cuda/numba/cuda/core/entrypoints.py +57 -0
  60. numba_cuda/numba/cuda/core/environment.py +66 -0
  61. numba_cuda/numba/cuda/core/errors.py +917 -0
  62. numba_cuda/numba/cuda/core/event.py +511 -0
  63. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  64. numba_cuda/numba/cuda/core/generators.py +387 -0
  65. numba_cuda/numba/cuda/core/imputils.py +509 -0
  66. numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
  67. numba_cuda/numba/cuda/core/interpreter.py +3617 -0
  68. numba_cuda/numba/cuda/core/ir.py +1812 -0
  69. numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
  70. numba_cuda/numba/cuda/core/optional.py +129 -0
  71. numba_cuda/numba/cuda/core/options.py +262 -0
  72. numba_cuda/numba/cuda/core/postproc.py +249 -0
  73. numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
  74. numba_cuda/numba/cuda/core/registry.py +46 -0
  75. numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
  76. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  77. numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
  78. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  79. numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
  80. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
  81. numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
  82. numba_cuda/numba/cuda/core/sigutils.py +68 -0
  83. numba_cuda/numba/cuda/core/ssa.py +498 -0
  84. numba_cuda/numba/cuda/core/targetconfig.py +330 -0
  85. numba_cuda/numba/cuda/core/tracing.py +231 -0
  86. numba_cuda/numba/cuda/core/transforms.py +956 -0
  87. numba_cuda/numba/cuda/core/typed_passes.py +867 -0
  88. numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
  89. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  90. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  91. numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
  92. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  93. numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
  94. numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
  95. numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
  96. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  97. numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
  98. numba_cuda/numba/cuda/cpython/iterators.py +167 -0
  99. numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
  100. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  101. numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
  102. numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
  103. numba_cuda/numba/cuda/cpython/slicing.py +322 -0
  104. numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
  105. numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
  106. numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
  107. numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
  108. numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
  109. numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
  110. numba_cuda/numba/cuda/cuda_paths.py +691 -0
  111. numba_cuda/numba/cuda/cudadecl.py +543 -0
  112. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  113. numba_cuda/numba/cuda/cudadrv/devicearray.py +954 -0
  114. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  115. numba_cuda/numba/cuda/cudadrv/driver.py +3238 -0
  116. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  117. numba_cuda/numba/cuda/cudadrv/dummyarray.py +562 -0
  118. numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
  119. numba_cuda/numba/cuda/cudadrv/error.py +48 -0
  120. numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
  121. numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
  122. numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
  123. numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
  124. numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
  125. numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
  126. numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
  127. numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
  128. numba_cuda/numba/cuda/cudaimpl.py +983 -0
  129. numba_cuda/numba/cuda/cudamath.py +149 -0
  130. numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
  131. numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
  132. numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
  133. numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
  134. numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
  135. numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
  136. numba_cuda/numba/cuda/datamodel/manager.py +11 -0
  137. numba_cuda/numba/cuda/datamodel/models.py +9 -0
  138. numba_cuda/numba/cuda/datamodel/packer.py +9 -0
  139. numba_cuda/numba/cuda/datamodel/registry.py +11 -0
  140. numba_cuda/numba/cuda/datamodel/testing.py +11 -0
  141. numba_cuda/numba/cuda/debuginfo.py +997 -0
  142. numba_cuda/numba/cuda/decorators.py +294 -0
  143. numba_cuda/numba/cuda/descriptor.py +35 -0
  144. numba_cuda/numba/cuda/device_init.py +155 -0
  145. numba_cuda/numba/cuda/deviceufunc.py +1021 -0
  146. numba_cuda/numba/cuda/dispatcher.py +2463 -0
  147. numba_cuda/numba/cuda/errors.py +72 -0
  148. numba_cuda/numba/cuda/extending.py +697 -0
  149. numba_cuda/numba/cuda/flags.py +178 -0
  150. numba_cuda/numba/cuda/fp16.py +357 -0
  151. numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
  152. numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
  153. numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
  154. numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
  155. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  156. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  157. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  158. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  159. numba_cuda/numba/cuda/initialize.py +24 -0
  160. numba_cuda/numba/cuda/intrinsics.py +531 -0
  161. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  162. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  163. numba_cuda/numba/cuda/kernels/reduction.py +265 -0
  164. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  165. numba_cuda/numba/cuda/libdevice.py +3386 -0
  166. numba_cuda/numba/cuda/libdevicedecl.py +20 -0
  167. numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
  168. numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
  169. numba_cuda/numba/cuda/locks.py +19 -0
  170. numba_cuda/numba/cuda/lowering.py +1980 -0
  171. numba_cuda/numba/cuda/mathimpl.py +374 -0
  172. numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
  173. numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
  174. numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
  175. numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
  176. numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
  177. numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
  178. numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
  179. numba_cuda/numba/cuda/misc/appdirs.py +594 -0
  180. numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
  181. numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
  182. numba_cuda/numba/cuda/misc/dump_style.py +41 -0
  183. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  184. numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
  185. numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
  186. numba_cuda/numba/cuda/misc/literal.py +28 -0
  187. numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
  188. numba_cuda/numba/cuda/misc/special.py +94 -0
  189. numba_cuda/numba/cuda/models.py +56 -0
  190. numba_cuda/numba/cuda/np/arraymath.py +5130 -0
  191. numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
  192. numba_cuda/numba/cuda/np/extensions.py +11 -0
  193. numba_cuda/numba/cuda/np/linalg.py +3087 -0
  194. numba_cuda/numba/cuda/np/math/__init__.py +0 -0
  195. numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
  196. numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
  197. numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
  198. numba_cuda/numba/cuda/np/npdatetime.py +969 -0
  199. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  200. numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
  201. numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
  202. numba_cuda/numba/cuda/np/numpy_support.py +798 -0
  203. numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
  204. numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
  205. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
  206. numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
  207. numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
  208. numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
  209. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
  210. numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
  211. numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
  212. numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
  213. numba_cuda/numba/cuda/nvvmutils.py +254 -0
  214. numba_cuda/numba/cuda/printimpl.py +126 -0
  215. numba_cuda/numba/cuda/random.py +308 -0
  216. numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
  217. numba_cuda/numba/cuda/serialize.py +267 -0
  218. numba_cuda/numba/cuda/simulator/__init__.py +63 -0
  219. numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
  220. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  221. numba_cuda/numba/cuda/simulator/api.py +179 -0
  222. numba_cuda/numba/cuda/simulator/bf16.py +4 -0
  223. numba_cuda/numba/cuda/simulator/compiler.py +38 -0
  224. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
  225. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
  226. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
  227. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
  228. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
  229. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
  230. numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
  231. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
  232. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
  233. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
  234. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
  235. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
  236. numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
  237. numba_cuda/numba/cuda/simulator/kernel.py +320 -0
  238. numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
  239. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
  240. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
  241. numba_cuda/numba/cuda/simulator/reduction.py +19 -0
  242. numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
  243. numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
  244. numba_cuda/numba/cuda/simulator_init.py +18 -0
  245. numba_cuda/numba/cuda/stubs.py +624 -0
  246. numba_cuda/numba/cuda/target.py +505 -0
  247. numba_cuda/numba/cuda/testing.py +347 -0
  248. numba_cuda/numba/cuda/tests/__init__.py +62 -0
  249. numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
  250. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
  251. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  252. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
  253. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  254. numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
  255. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
  256. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
  257. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
  258. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
  259. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
  260. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
  261. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +313 -0
  262. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +191 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
  264. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
  265. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
  266. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +200 -0
  267. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
  268. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
  269. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
  270. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
  271. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
  272. numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
  273. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
  274. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
  275. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
  276. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
  277. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
  278. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
  279. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
  280. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
  281. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
  282. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
  283. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
  284. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
  285. numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
  286. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
  287. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
  288. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
  289. numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
  290. numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
  291. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
  292. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
  293. numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
  294. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
  295. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
  296. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
  297. numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
  298. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
  299. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
  300. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
  301. numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
  302. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
  303. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
  304. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
  305. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
  306. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
  307. numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
  308. numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
  309. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
  310. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
  311. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
  312. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
  313. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
  314. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
  315. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
  316. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
  317. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
  318. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
  319. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
  320. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
  321. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
  322. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
  323. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +978 -0
  324. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  325. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
  326. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
  327. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
  328. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
  329. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
  330. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
  331. numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
  332. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
  333. numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
  334. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
  335. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
  336. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
  337. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
  338. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
  339. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
  340. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
  341. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
  342. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
  343. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
  344. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
  345. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
  346. numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
  347. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
  348. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
  349. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
  350. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
  351. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
  352. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
  353. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
  354. numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
  355. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
  356. numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
  357. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
  358. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
  359. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
  360. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
  361. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
  362. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
  363. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
  364. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
  365. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
  366. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
  367. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
  368. numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
  369. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
  370. numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
  371. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
  372. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
  373. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
  374. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  375. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
  376. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
  377. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
  378. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
  379. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
  380. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
  381. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
  382. numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
  383. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
  384. numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
  385. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  386. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
  387. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
  388. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
  389. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
  390. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
  391. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
  392. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
  393. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
  394. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
  395. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +446 -0
  396. numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
  397. numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
  398. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
  399. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  400. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
  401. numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
  402. numba_cuda/numba/cuda/tests/data/error.cu +12 -0
  403. numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
  404. numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
  405. numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
  406. numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
  407. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
  408. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  409. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
  410. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
  411. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
  412. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
  413. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
  414. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
  415. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
  416. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
  417. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
  418. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
  419. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
  420. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
  421. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
  422. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
  423. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
  424. numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
  425. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +452 -0
  426. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
  427. numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
  428. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
  429. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
  430. numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
  431. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
  432. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
  433. numba_cuda/numba/cuda/tests/support.py +900 -0
  434. numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
  435. numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
  436. numba_cuda/numba/cuda/typeconv/rules.py +63 -0
  437. numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
  438. numba_cuda/numba/cuda/types/__init__.py +233 -0
  439. numba_cuda/numba/cuda/types/__init__.pyi +167 -0
  440. numba_cuda/numba/cuda/types/abstract.py +9 -0
  441. numba_cuda/numba/cuda/types/common.py +9 -0
  442. numba_cuda/numba/cuda/types/containers.py +9 -0
  443. numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
  444. numba_cuda/numba/cuda/types/cuda_common.py +110 -0
  445. numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
  446. numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
  447. numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
  448. numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
  449. numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
  450. numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
  451. numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
  452. numba_cuda/numba/cuda/types/ext_types.py +101 -0
  453. numba_cuda/numba/cuda/types/function_type.py +11 -0
  454. numba_cuda/numba/cuda/types/functions.py +9 -0
  455. numba_cuda/numba/cuda/types/iterators.py +9 -0
  456. numba_cuda/numba/cuda/types/misc.py +9 -0
  457. numba_cuda/numba/cuda/types/npytypes.py +9 -0
  458. numba_cuda/numba/cuda/types/scalars.py +9 -0
  459. numba_cuda/numba/cuda/typing/__init__.py +19 -0
  460. numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
  461. numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
  462. numba_cuda/numba/cuda/typing/bufproto.py +70 -0
  463. numba_cuda/numba/cuda/typing/builtins.py +1209 -0
  464. numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
  465. numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
  466. numba_cuda/numba/cuda/typing/collections.py +138 -0
  467. numba_cuda/numba/cuda/typing/context.py +782 -0
  468. numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
  469. numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
  470. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  471. numba_cuda/numba/cuda/typing/listdecl.py +147 -0
  472. numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
  473. numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
  474. numba_cuda/numba/cuda/typing/npydecl.py +749 -0
  475. numba_cuda/numba/cuda/typing/setdecl.py +115 -0
  476. numba_cuda/numba/cuda/typing/templates.py +1446 -0
  477. numba_cuda/numba/cuda/typing/typeof.py +301 -0
  478. numba_cuda/numba/cuda/ufuncs.py +746 -0
  479. numba_cuda/numba/cuda/utils.py +724 -0
  480. numba_cuda/numba/cuda/vector_types.py +214 -0
  481. numba_cuda/numba/cuda/vectorizers.py +260 -0
  482. numba_cuda-0.22.0.dist-info/METADATA +109 -0
  483. numba_cuda-0.22.0.dist-info/RECORD +487 -0
  484. numba_cuda-0.22.0.dist-info/WHEEL +6 -0
  485. numba_cuda-0.22.0.dist-info/licenses/LICENSE +26 -0
  486. numba_cuda-0.22.0.dist-info/licenses/LICENSE.numba +24 -0
  487. numba_cuda-0.22.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1411 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ """
5
+ Boxing and unboxing of native Numba values to / from CPython objects.
6
+ """
7
+
8
+ from llvmlite import ir
9
+
10
+ from numba.cuda import types, cgutils
11
+ from numba.cuda.core.pythonapi import box, unbox, reflect, NativeValue
12
+ from numba.cuda.core.errors import NumbaNotImplementedError, TypingError
13
+ from numba.cuda.typing.typeof import typeof, Purpose
14
+
15
+ from numba.cuda.cpython import setobj, listobj
16
+ from numba.cuda.np import numpy_support
17
+ from contextlib import ExitStack
18
+
19
+
20
+ #
21
+ # Scalar types
22
+ #
23
+
24
+
25
+ @box(types.Boolean)
26
+ def box_bool(typ, val, c):
27
+ return c.pyapi.bool_from_bool(val)
28
+
29
+
30
+ @unbox(types.Boolean)
31
+ def unbox_boolean(typ, obj, c):
32
+ istrue = c.pyapi.object_istrue(obj)
33
+ zero = ir.Constant(istrue.type, 0)
34
+ val = c.builder.icmp_signed("!=", istrue, zero)
35
+ return NativeValue(val, is_error=c.pyapi.c_api_error())
36
+
37
+
38
+ @box(types.IntegerLiteral)
39
+ @box(types.BooleanLiteral)
40
+ def box_literal_integer(typ, val, c):
41
+ val = c.context.cast(c.builder, val, typ, typ.literal_type)
42
+ return c.box(typ.literal_type, val)
43
+
44
+
45
+ @box(types.Integer)
46
+ def box_integer(typ, val, c):
47
+ if typ.signed:
48
+ ival = c.builder.sext(val, c.pyapi.longlong)
49
+ return c.pyapi.long_from_longlong(ival)
50
+ else:
51
+ ullval = c.builder.zext(val, c.pyapi.ulonglong)
52
+ return c.pyapi.long_from_ulonglong(ullval)
53
+
54
+
55
+ @unbox(types.Integer)
56
+ def unbox_integer(typ, obj, c):
57
+ ll_type = c.context.get_argument_type(typ)
58
+ val = cgutils.alloca_once(c.builder, ll_type)
59
+ longobj = c.pyapi.number_long(obj)
60
+ with c.pyapi.if_object_ok(longobj):
61
+ if typ.signed:
62
+ llval = c.pyapi.long_as_longlong(longobj)
63
+ else:
64
+ llval = c.pyapi.long_as_ulonglong(longobj)
65
+ c.pyapi.decref(longobj)
66
+ c.builder.store(c.builder.trunc(llval, ll_type), val)
67
+ return NativeValue(c.builder.load(val), is_error=c.pyapi.c_api_error())
68
+
69
+
70
+ @box(types.Float)
71
+ def box_float(typ, val, c):
72
+ if typ == types.float32:
73
+ dbval = c.builder.fpext(val, c.pyapi.double)
74
+ else:
75
+ assert typ == types.float64
76
+ dbval = val
77
+ return c.pyapi.float_from_double(dbval)
78
+
79
+
80
+ @unbox(types.Float)
81
+ def unbox_float(typ, obj, c):
82
+ fobj = c.pyapi.number_float(obj)
83
+ dbval = c.pyapi.float_as_double(fobj)
84
+ c.pyapi.decref(fobj)
85
+ if typ == types.float32:
86
+ val = c.builder.fptrunc(dbval, c.context.get_argument_type(typ))
87
+ else:
88
+ assert typ == types.float64
89
+ val = dbval
90
+ return NativeValue(val, is_error=c.pyapi.c_api_error())
91
+
92
+
93
+ @box(types.Complex)
94
+ def box_complex(typ, val, c):
95
+ cval = c.context.make_complex(c.builder, typ, value=val)
96
+
97
+ if typ == types.complex64:
98
+ freal = c.builder.fpext(cval.real, c.pyapi.double)
99
+ fimag = c.builder.fpext(cval.imag, c.pyapi.double)
100
+ else:
101
+ assert typ == types.complex128
102
+ freal, fimag = cval.real, cval.imag
103
+ return c.pyapi.complex_from_doubles(freal, fimag)
104
+
105
+
106
+ @unbox(types.Complex)
107
+ def unbox_complex(typ, obj, c):
108
+ # First unbox to complex128, since that's what CPython gives us
109
+ c128 = c.context.make_complex(c.builder, types.complex128)
110
+ ok = c.pyapi.complex_adaptor(obj, c128._getpointer())
111
+ failed = cgutils.is_false(c.builder, ok)
112
+
113
+ with cgutils.if_unlikely(c.builder, failed):
114
+ c.pyapi.err_set_string(
115
+ "PyExc_TypeError", "conversion to %s failed" % (typ,)
116
+ )
117
+
118
+ if typ == types.complex64:
119
+ # Downcast to complex64 if necessary
120
+ cplx = c.context.make_complex(c.builder, typ)
121
+ cplx.real = c.context.cast(
122
+ c.builder, c128.real, types.float64, types.float32
123
+ )
124
+ cplx.imag = c.context.cast(
125
+ c.builder, c128.imag, types.float64, types.float32
126
+ )
127
+ else:
128
+ assert typ == types.complex128
129
+ cplx = c128
130
+ return NativeValue(cplx._getvalue(), is_error=failed)
131
+
132
+
133
+ @box(types.NoneType)
134
+ def box_none(typ, val, c):
135
+ return c.pyapi.make_none()
136
+
137
+
138
+ @unbox(types.NoneType)
139
+ @unbox(types.EllipsisType)
140
+ def unbox_none(typ, val, c):
141
+ return NativeValue(c.context.get_dummy_value())
142
+
143
+
144
+ @box(types.NPDatetime)
145
+ def box_npdatetime(typ, val, c):
146
+ return c.pyapi.create_np_datetime(val, typ.unit_code)
147
+
148
+
149
+ @unbox(types.NPDatetime)
150
+ def unbox_npdatetime(typ, obj, c):
151
+ val = c.pyapi.extract_np_datetime(obj)
152
+ return NativeValue(val, is_error=c.pyapi.c_api_error())
153
+
154
+
155
+ @box(types.NPTimedelta)
156
+ def box_nptimedelta(typ, val, c):
157
+ return c.pyapi.create_np_timedelta(val, typ.unit_code)
158
+
159
+
160
+ @unbox(types.NPTimedelta)
161
+ def unbox_nptimedelta(typ, obj, c):
162
+ val = c.pyapi.extract_np_timedelta(obj)
163
+ return NativeValue(val, is_error=c.pyapi.c_api_error())
164
+
165
+
166
+ @box(types.RawPointer)
167
+ def box_raw_pointer(typ, val, c):
168
+ """
169
+ Convert a raw pointer to a Python int.
170
+ """
171
+ ll_intp = c.context.get_value_type(types.uintp)
172
+ addr = c.builder.ptrtoint(val, ll_intp)
173
+ return c.box(types.uintp, addr)
174
+
175
+
176
+ @box(types.EnumMember)
177
+ def box_enum(typ, val, c):
178
+ """
179
+ Fetch an enum member given its native value.
180
+ """
181
+ valobj = c.box(typ.dtype, val)
182
+ # Call the enum class with the value object
183
+ cls_obj = c.pyapi.unserialize(c.pyapi.serialize_object(typ.instance_class))
184
+ return c.pyapi.call_function_objargs(cls_obj, (valobj,))
185
+
186
+
187
+ @unbox(types.EnumMember)
188
+ def unbox_enum(typ, obj, c):
189
+ """
190
+ Convert an enum member's value to its native value.
191
+ """
192
+ valobj = c.pyapi.object_getattr_string(obj, "value")
193
+ return c.unbox(typ.dtype, valobj)
194
+
195
+
196
+ @box(types.UndefVar)
197
+ def box_undefvar(typ, val, c):
198
+ """This type cannot be boxed, there's no Python equivalent"""
199
+ msg = (
200
+ "UndefVar type cannot be boxed, there is no Python equivalent of "
201
+ "this type."
202
+ )
203
+ raise TypingError(msg)
204
+
205
+
206
+ #
207
+ # Composite types
208
+ #
209
+
210
+
211
+ @box(types.Record)
212
+ def box_record(typ, val, c):
213
+ # Note we will create a copy of the record
214
+ # This is the only safe way.
215
+ size = ir.Constant(ir.IntType(32), val.type.pointee.count)
216
+ ptr = c.builder.bitcast(val, ir.PointerType(ir.IntType(8)))
217
+ return c.pyapi.recreate_record(ptr, size, typ.dtype, c.env_manager)
218
+
219
+
220
+ @unbox(types.Record)
221
+ def unbox_record(typ, obj, c):
222
+ buf = c.pyapi.alloca_buffer()
223
+ ptr = c.pyapi.extract_record_data(obj, buf)
224
+ is_error = cgutils.is_null(c.builder, ptr)
225
+
226
+ ltyp = c.context.get_value_type(typ)
227
+ val = c.builder.bitcast(ptr, ltyp)
228
+
229
+ def cleanup():
230
+ c.pyapi.release_buffer(buf)
231
+
232
+ return NativeValue(val, cleanup=cleanup, is_error=is_error)
233
+
234
+
235
+ @box(types.UnicodeCharSeq)
236
+ def box_unicodecharseq(typ, val, c):
237
+ # XXX could kind be determined from strptr?
238
+ unicode_kind = {
239
+ 1: c.pyapi.py_unicode_1byte_kind,
240
+ 2: c.pyapi.py_unicode_2byte_kind,
241
+ 4: c.pyapi.py_unicode_4byte_kind,
242
+ }[numpy_support.sizeof_unicode_char]
243
+ kind = c.context.get_constant(types.int32, unicode_kind)
244
+ rawptr = cgutils.alloca_once_value(c.builder, value=val)
245
+ strptr = c.builder.bitcast(rawptr, c.pyapi.cstring)
246
+
247
+ fullsize = c.context.get_constant(types.intp, typ.count)
248
+ zero = fullsize.type(0)
249
+ one = fullsize.type(1)
250
+ step = fullsize.type(numpy_support.sizeof_unicode_char)
251
+ count = cgutils.alloca_once_value(c.builder, zero)
252
+ with cgutils.loop_nest(c.builder, [fullsize], fullsize.type) as [idx]:
253
+ # Get char at idx
254
+ ch = c.builder.load(c.builder.gep(strptr, [c.builder.mul(idx, step)]))
255
+ # If the char is a non-null-byte, store the next index as count
256
+ with c.builder.if_then(cgutils.is_not_null(c.builder, ch)):
257
+ c.builder.store(c.builder.add(idx, one), count)
258
+ strlen = c.builder.load(count)
259
+ return c.pyapi.string_from_kind_and_data(kind, strptr, strlen)
260
+
261
+
262
+ @unbox(types.UnicodeCharSeq)
263
+ def unbox_unicodecharseq(typ, obj, c):
264
+ lty = c.context.get_value_type(typ)
265
+
266
+ ok, buffer, size, kind, is_ascii, hashv = (
267
+ c.pyapi.string_as_string_size_and_kind(obj)
268
+ )
269
+
270
+ # If conversion is ok, copy the buffer to the output storage.
271
+ with cgutils.if_likely(c.builder, ok):
272
+ # Check if the returned string size fits in the charseq
273
+ storage_size = ir.Constant(size.type, typ.count)
274
+ size_fits = c.builder.icmp_unsigned("<=", size, storage_size)
275
+
276
+ # Allow truncation of string
277
+ size = c.builder.select(size_fits, size, storage_size)
278
+
279
+ # Initialize output to zero bytes
280
+ null_string = ir.Constant(lty, None)
281
+ outspace = cgutils.alloca_once_value(c.builder, null_string)
282
+
283
+ # We don't need to set the NULL-terminator because the storage
284
+ # is already zero-filled.
285
+ cgutils.memcpy(
286
+ c.builder, c.builder.bitcast(outspace, buffer.type), buffer, size
287
+ )
288
+
289
+ ret = c.builder.load(outspace)
290
+ return NativeValue(ret, is_error=c.builder.not_(ok))
291
+
292
+
293
+ @box(types.Bytes)
294
+ def box_bytes(typ, val, c):
295
+ obj = c.context.make_helper(c.builder, typ, val)
296
+ ret = c.pyapi.bytes_from_string_and_size(obj.data, obj.nitems)
297
+ c.context.nrt.decref(c.builder, typ, val)
298
+ return ret
299
+
300
+
301
+ @box(types.CharSeq)
302
+ def box_charseq(typ, val, c):
303
+ rawptr = cgutils.alloca_once_value(c.builder, value=val)
304
+ strptr = c.builder.bitcast(rawptr, c.pyapi.cstring)
305
+ fullsize = c.context.get_constant(types.intp, typ.count)
306
+ zero = fullsize.type(0)
307
+ one = fullsize.type(1)
308
+ count = cgutils.alloca_once_value(c.builder, zero)
309
+
310
+ # Find the length of the string, mimicking Numpy's behaviour:
311
+ # search for the last non-null byte in the underlying storage
312
+ # (e.g. b'A\0\0B\0\0\0' will return the logical string b'A\0\0B')
313
+ with cgutils.loop_nest(c.builder, [fullsize], fullsize.type) as [idx]:
314
+ # Get char at idx
315
+ ch = c.builder.load(c.builder.gep(strptr, [idx]))
316
+ # If the char is a non-null-byte, store the next index as count
317
+ with c.builder.if_then(cgutils.is_not_null(c.builder, ch)):
318
+ c.builder.store(c.builder.add(idx, one), count)
319
+
320
+ strlen = c.builder.load(count)
321
+ return c.pyapi.bytes_from_string_and_size(strptr, strlen)
322
+
323
+
324
+ @unbox(types.CharSeq)
325
+ def unbox_charseq(typ, obj, c):
326
+ lty = c.context.get_value_type(typ)
327
+ ok, buffer, size = c.pyapi.string_as_string_and_size(obj)
328
+
329
+ # If conversion is ok, copy the buffer to the output storage.
330
+ with cgutils.if_likely(c.builder, ok):
331
+ # Check if the returned string size fits in the charseq
332
+ storage_size = ir.Constant(size.type, typ.count)
333
+ size_fits = c.builder.icmp_unsigned("<=", size, storage_size)
334
+
335
+ # Allow truncation of string
336
+ size = c.builder.select(size_fits, size, storage_size)
337
+
338
+ # Initialize output to zero bytes
339
+ null_string = ir.Constant(lty, None)
340
+ outspace = cgutils.alloca_once_value(c.builder, null_string)
341
+
342
+ # We don't need to set the NULL-terminator because the storage
343
+ # is already zero-filled.
344
+ cgutils.memcpy(
345
+ c.builder, c.builder.bitcast(outspace, buffer.type), buffer, size
346
+ )
347
+
348
+ ret = c.builder.load(outspace)
349
+ return NativeValue(ret, is_error=c.builder.not_(ok))
350
+
351
+
352
+ @box(types.Optional)
353
+ def box_optional(typ, val, c):
354
+ optval = c.context.make_helper(c.builder, typ, val)
355
+ ret = cgutils.alloca_once_value(c.builder, c.pyapi.borrow_none())
356
+ with c.builder.if_else(optval.valid) as (then, otherwise):
357
+ with then:
358
+ validres = c.box(typ.type, optval.data)
359
+ c.builder.store(validres, ret)
360
+ with otherwise:
361
+ c.builder.store(c.pyapi.make_none(), ret)
362
+ return c.builder.load(ret)
363
+
364
+
365
+ @unbox(types.Optional)
366
+ def unbox_optional(typ, obj, c):
367
+ """
368
+ Convert object *obj* to a native optional structure.
369
+ """
370
+ noneval = c.context.make_optional_none(c.builder, typ.type)
371
+ is_not_none = c.builder.icmp_signed("!=", obj, c.pyapi.borrow_none())
372
+
373
+ retptr = cgutils.alloca_once(c.builder, noneval.type)
374
+ errptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
375
+
376
+ with c.builder.if_else(is_not_none) as (then, orelse):
377
+ with then:
378
+ native = c.unbox(typ.type, obj)
379
+ just = c.context.make_optional_value(
380
+ c.builder, typ.type, native.value
381
+ )
382
+ c.builder.store(just, retptr)
383
+ c.builder.store(native.is_error, errptr)
384
+
385
+ with orelse:
386
+ c.builder.store(noneval, retptr)
387
+
388
+ if native.cleanup is not None:
389
+
390
+ def cleanup():
391
+ with c.builder.if_then(is_not_none):
392
+ native.cleanup()
393
+ else:
394
+ cleanup = None
395
+
396
+ ret = c.builder.load(retptr)
397
+ return NativeValue(ret, is_error=c.builder.load(errptr), cleanup=cleanup)
398
+
399
+
400
+ @unbox(types.SliceType)
401
+ def unbox_slice(typ, obj, c):
402
+ """
403
+ Convert object *obj* to a native slice structure.
404
+ """
405
+ ok, start, stop, step = c.pyapi.slice_as_ints(obj)
406
+ sli = c.context.make_helper(c.builder, typ)
407
+ sli.start = start
408
+ sli.stop = stop
409
+ sli.step = step
410
+ return NativeValue(sli._getvalue(), is_error=c.builder.not_(ok))
411
+
412
+
413
+ @box(types.SliceLiteral)
414
+ def box_slice_literal(typ, val, c):
415
+ # Check for integer overflows at compile time.
416
+ slice_lit = typ.literal_value
417
+ for field_name in ("start", "stop", "step"):
418
+ field_obj = getattr(slice_lit, field_name)
419
+ if isinstance(field_obj, int):
420
+ try:
421
+ typeof(field_obj, Purpose)
422
+ except ValueError as e:
423
+ raise ValueError(
424
+ (
425
+ f"Unable to create literal slice. "
426
+ f"Error encountered with {field_name} "
427
+ f"attribute. {str(e)}"
428
+ )
429
+ )
430
+
431
+ py_ctor, py_args = typ.literal_value.__reduce__()
432
+ serialized_ctor = c.pyapi.serialize_object(py_ctor)
433
+ serialized_args = c.pyapi.serialize_object(py_args)
434
+ ctor = c.pyapi.unserialize(serialized_ctor)
435
+ args = c.pyapi.unserialize(serialized_args)
436
+ obj = c.pyapi.call(ctor, args)
437
+ c.pyapi.decref(ctor)
438
+ c.pyapi.decref(args)
439
+ return obj
440
+
441
+
442
+ @unbox(types.StringLiteral)
443
+ def unbox_string_literal(typ, obj, c):
444
+ # A string literal is a dummy value
445
+ return NativeValue(c.context.get_dummy_value())
446
+
447
+
448
+ #
449
+ # Collections
450
+ #
451
+
452
+ # NOTE: boxing functions are supposed to steal any NRT references in
453
+ # the given native value.
454
+
455
+
456
+ @box(types.Array)
457
+ def box_array(typ, val, c):
458
+ nativearycls = c.context.make_array(typ)
459
+ nativeary = nativearycls(c.context, c.builder, value=val)
460
+ if c.context.enable_nrt:
461
+ np_dtype = numpy_support.as_dtype(typ.dtype)
462
+ dtypeptr = c.env_manager.read_const(c.env_manager.add_const(np_dtype))
463
+ newary = c.pyapi.nrt_adapt_ndarray_to_python(typ, val, dtypeptr)
464
+ # Steals NRT ref
465
+ c.context.nrt.decref(c.builder, typ, val)
466
+ return newary
467
+ else:
468
+ parent = nativeary.parent
469
+ c.pyapi.incref(parent)
470
+ return parent
471
+
472
+
473
+ @unbox(types.Buffer)
474
+ def unbox_buffer(typ, obj, c):
475
+ """
476
+ Convert a Py_buffer-providing object to a native array structure.
477
+ """
478
+ buf = c.pyapi.alloca_buffer()
479
+ res = c.pyapi.get_buffer(obj, buf)
480
+ is_error = cgutils.is_not_null(c.builder, res)
481
+
482
+ nativearycls = c.context.make_array(typ)
483
+ nativeary = nativearycls(c.context, c.builder)
484
+ aryptr = nativeary._getpointer()
485
+
486
+ with cgutils.if_likely(c.builder, c.builder.not_(is_error)):
487
+ ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
488
+ if c.context.enable_nrt:
489
+ c.pyapi.nrt_adapt_buffer_from_python(buf, ptr)
490
+ else:
491
+ c.pyapi.numba_buffer_adaptor(buf, ptr)
492
+
493
+ def cleanup():
494
+ c.pyapi.release_buffer(buf)
495
+
496
+ return NativeValue(
497
+ c.builder.load(aryptr), is_error=is_error, cleanup=cleanup
498
+ )
499
+
500
+
501
+ @unbox(types.Array)
502
+ def unbox_array(typ, obj, c):
503
+ """
504
+ Convert a Numpy array object to a native array structure.
505
+ """
506
+ # This is necessary because unbox_buffer() does not work on some
507
+ # dtypes, e.g. datetime64 and timedelta64.
508
+ # TODO check matching dtype.
509
+ # currently, mismatching dtype will still work and causes
510
+ # potential memory corruption
511
+ nativearycls = c.context.make_array(typ)
512
+ nativeary = nativearycls(c.context, c.builder)
513
+ aryptr = nativeary._getpointer()
514
+
515
+ ptr = c.builder.bitcast(aryptr, c.pyapi.voidptr)
516
+ if c.context.enable_nrt:
517
+ errcode = c.pyapi.nrt_adapt_ndarray_from_python(obj, ptr)
518
+ else:
519
+ errcode = c.pyapi.numba_array_adaptor(obj, ptr)
520
+
521
+ # TODO: here we have minimal typechecking by the itemsize.
522
+ # need to do better
523
+ try:
524
+ expected_itemsize = numpy_support.as_dtype(typ.dtype).itemsize
525
+ except NumbaNotImplementedError:
526
+ # Don't check types that can't be `as_dtype()`-ed
527
+ itemsize_mismatch = cgutils.false_bit
528
+ else:
529
+ expected_itemsize = nativeary.itemsize.type(expected_itemsize)
530
+ itemsize_mismatch = c.builder.icmp_unsigned(
531
+ "!=",
532
+ nativeary.itemsize,
533
+ expected_itemsize,
534
+ )
535
+
536
+ failed = c.builder.or_(
537
+ cgutils.is_not_null(c.builder, errcode),
538
+ itemsize_mismatch,
539
+ )
540
+ # Handle error
541
+ with c.builder.if_then(failed, likely=False):
542
+ c.pyapi.err_set_string(
543
+ "PyExc_TypeError",
544
+ "can't unbox array from PyObject into "
545
+ "native value. The object maybe of a "
546
+ "different type",
547
+ )
548
+ return NativeValue(c.builder.load(aryptr), is_error=failed)
549
+
550
+
551
+ @box(types.Tuple)
552
+ @box(types.UniTuple)
553
+ def box_tuple(typ, val, c):
554
+ """
555
+ Convert native array or structure *val* to a tuple object.
556
+ """
557
+ tuple_val = c.pyapi.tuple_new(typ.count)
558
+
559
+ for i, dtype in enumerate(typ):
560
+ item = c.builder.extract_value(val, i)
561
+ obj = c.box(dtype, item)
562
+ c.pyapi.tuple_setitem(tuple_val, i, obj)
563
+
564
+ return tuple_val
565
+
566
+
567
+ @box(types.NamedTuple)
568
+ @box(types.NamedUniTuple)
569
+ def box_namedtuple(typ, val, c):
570
+ """
571
+ Convert native array or structure *val* to a namedtuple object.
572
+ """
573
+ cls_obj = c.pyapi.unserialize(c.pyapi.serialize_object(typ.instance_class))
574
+ tuple_obj = box_tuple(typ, val, c)
575
+ obj = c.pyapi.call(cls_obj, tuple_obj)
576
+ c.pyapi.decref(cls_obj)
577
+ c.pyapi.decref(tuple_obj)
578
+ return obj
579
+
580
+
581
+ @unbox(types.BaseTuple)
582
+ def unbox_tuple(typ, obj, c):
583
+ """
584
+ Convert tuple *obj* to a native array (if homogeneous) or structure.
585
+ """
586
+ n = len(typ)
587
+ values = []
588
+ cleanups = []
589
+ lty = c.context.get_value_type(typ)
590
+
591
+ is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
592
+ value_ptr = cgutils.alloca_once(c.builder, lty)
593
+
594
+ # Issue #1638: need to check the tuple size
595
+ actual_size = c.pyapi.tuple_size(obj)
596
+ size_matches = c.builder.icmp_unsigned(
597
+ "==", actual_size, ir.Constant(actual_size.type, n)
598
+ )
599
+ with c.builder.if_then(c.builder.not_(size_matches), likely=False):
600
+ c.pyapi.err_format(
601
+ "PyExc_ValueError",
602
+ "size mismatch for tuple, expected %d element(s) but got %%zd"
603
+ % (n,),
604
+ actual_size,
605
+ )
606
+ c.builder.store(cgutils.true_bit, is_error_ptr)
607
+
608
+ # We unbox the items even if not `size_matches`, to avoid issues with
609
+ # the generated IR (instruction doesn't dominate all uses)
610
+ for i, eltype in enumerate(typ):
611
+ elem = c.pyapi.tuple_getitem(obj, i)
612
+ native = c.unbox(eltype, elem)
613
+ values.append(native.value)
614
+ with c.builder.if_then(native.is_error, likely=False):
615
+ c.builder.store(cgutils.true_bit, is_error_ptr)
616
+ if native.cleanup is not None:
617
+ cleanups.append(native.cleanup)
618
+
619
+ value = c.context.make_tuple(c.builder, typ, values)
620
+ c.builder.store(value, value_ptr)
621
+
622
+ if cleanups:
623
+ with c.builder.if_then(size_matches, likely=True):
624
+
625
+ def cleanup():
626
+ for func in reversed(cleanups):
627
+ func()
628
+ else:
629
+ cleanup = None
630
+
631
+ return NativeValue(
632
+ c.builder.load(value_ptr),
633
+ cleanup=cleanup,
634
+ is_error=c.builder.load(is_error_ptr),
635
+ )
636
+
637
+
638
+ @box(types.List)
639
+ def box_list(typ, val, c):
640
+ """
641
+ Convert native list *val* to a list object.
642
+ """
643
+ list = listobj.ListInstance(c.context, c.builder, typ, val)
644
+ obj = list.parent
645
+ res = cgutils.alloca_once_value(c.builder, obj)
646
+ with c.builder.if_else(cgutils.is_not_null(c.builder, obj)) as (
647
+ has_parent,
648
+ otherwise,
649
+ ):
650
+ with has_parent:
651
+ # List is actually reflected => return the original object
652
+ # (note not all list instances whose *type* is reflected are
653
+ # actually reflected; see numba.tests.test_lists for an example)
654
+ c.pyapi.incref(obj)
655
+
656
+ with otherwise:
657
+ # Build a new Python list
658
+ nitems = list.size
659
+ obj = c.pyapi.list_new(nitems)
660
+ with c.builder.if_then(
661
+ cgutils.is_not_null(c.builder, obj), likely=True
662
+ ):
663
+ with cgutils.for_range(c.builder, nitems) as loop:
664
+ item = list.getitem(loop.index)
665
+ list.incref_value(item)
666
+ itemobj = c.box(typ.dtype, item)
667
+ c.pyapi.list_setitem(obj, loop.index, itemobj)
668
+
669
+ c.builder.store(obj, res)
670
+
671
+ # Steal NRT ref
672
+ c.context.nrt.decref(c.builder, typ, val)
673
+ return c.builder.load(res)
674
+
675
+
676
+ class _NumbaTypeHelper(object):
677
+ """A helper for acquiring `numba.typeof` for type checking.
678
+
679
+ Usage
680
+ -----
681
+
682
+ # `c` is the boxing context.
683
+ with _NumbaTypeHelper(c) as nth:
684
+ # This contextmanager maintains the lifetime of the `numba.typeof`
685
+ # function.
686
+ the_numba_type = nth.typeof(some_object)
687
+ # Do work on the type object
688
+ do_checks(the_numba_type)
689
+ # Cleanup
690
+ c.pyapi.decref(the_numba_type)
691
+ # At this point *nth* should not be used.
692
+ """
693
+
694
+ def __init__(self, c):
695
+ self.c = c
696
+
697
+ def __enter__(self):
698
+ c = self.c
699
+ numba_name = c.context.insert_const_string(c.builder.module, "numba")
700
+ numba_mod = c.pyapi.import_module(numba_name)
701
+ typeof_fn = c.pyapi.object_getattr_string(numba_mod, "typeof")
702
+ self.typeof_fn = typeof_fn
703
+ c.pyapi.decref(numba_mod)
704
+ return self
705
+
706
+ def __exit__(self, *args, **kwargs):
707
+ c = self.c
708
+ c.pyapi.decref(self.typeof_fn)
709
+
710
+ def typeof(self, obj):
711
+ res = self.c.pyapi.call_function_objargs(self.typeof_fn, [obj])
712
+ return res
713
+
714
+
715
+ def _python_list_to_native(typ, obj, c, size, listptr, errorptr):
716
+ """
717
+ Construct a new native list from a Python list.
718
+ """
719
+
720
+ def check_element_type(nth, itemobj, expected_typobj):
721
+ typobj = nth.typeof(itemobj)
722
+ # Check if *typobj* is NULL
723
+ with c.builder.if_then(
724
+ cgutils.is_null(c.builder, typobj),
725
+ likely=False,
726
+ ):
727
+ c.builder.store(cgutils.true_bit, errorptr)
728
+ loop.do_break()
729
+ # Mandate that objects all have the same exact type
730
+ type_mismatch = c.builder.icmp_signed("!=", typobj, expected_typobj)
731
+
732
+ with c.builder.if_then(type_mismatch, likely=False):
733
+ c.builder.store(cgutils.true_bit, errorptr)
734
+ c.pyapi.err_format(
735
+ "PyExc_TypeError",
736
+ "can't unbox heterogeneous list: %S != %S",
737
+ expected_typobj,
738
+ typobj,
739
+ )
740
+ c.pyapi.decref(typobj)
741
+ loop.do_break()
742
+ c.pyapi.decref(typobj)
743
+
744
+ # Allocate a new native list
745
+ ok, list = listobj.ListInstance.allocate_ex(c.context, c.builder, typ, size)
746
+ with c.builder.if_else(ok, likely=True) as (if_ok, if_not_ok):
747
+ with if_ok:
748
+ list.size = size
749
+ zero = ir.Constant(size.type, 0)
750
+ with c.builder.if_then(
751
+ c.builder.icmp_signed(">", size, zero), likely=True
752
+ ):
753
+ # Traverse Python list and unbox objects into native list
754
+ with _NumbaTypeHelper(c) as nth:
755
+ # Note: *expected_typobj* can't be NULL
756
+ expected_typobj = nth.typeof(
757
+ c.pyapi.list_getitem(obj, zero)
758
+ )
759
+ with cgutils.for_range(c.builder, size) as loop:
760
+ itemobj = c.pyapi.list_getitem(obj, loop.index)
761
+ check_element_type(nth, itemobj, expected_typobj)
762
+ # XXX we don't call native cleanup for each
763
+ # list element, since that would require keeping
764
+ # of which unboxings have been successful.
765
+ native = c.unbox(typ.dtype, itemobj)
766
+ with c.builder.if_then(native.is_error, likely=False):
767
+ c.builder.store(cgutils.true_bit, errorptr)
768
+ loop.do_break()
769
+ # The reference is borrowed so incref=False
770
+ list.setitem(loop.index, native.value, incref=False)
771
+ c.pyapi.decref(expected_typobj)
772
+ if typ.reflected:
773
+ list.parent = obj
774
+ # Stuff meminfo pointer into the Python object for
775
+ # later reuse.
776
+ with c.builder.if_then(
777
+ c.builder.not_(c.builder.load(errorptr)), likely=False
778
+ ):
779
+ c.pyapi.object_set_private_data(obj, list.meminfo)
780
+ list.set_dirty(False)
781
+ c.builder.store(list.value, listptr)
782
+
783
+ with if_not_ok:
784
+ c.builder.store(cgutils.true_bit, errorptr)
785
+
786
+ # If an error occurred, drop the whole native list
787
+ with c.builder.if_then(c.builder.load(errorptr)):
788
+ c.context.nrt.decref(c.builder, typ, list.value)
789
+
790
+
791
+ @unbox(types.List)
792
+ def unbox_list(typ, obj, c):
793
+ """
794
+ Convert list *obj* to a native list.
795
+
796
+ If list was previously unboxed, we reuse the existing native list
797
+ to ensure consistency.
798
+ """
799
+ size = c.pyapi.list_size(obj)
800
+
801
+ errorptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
802
+ listptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))
803
+
804
+ # See if the list was previously unboxed, if so, re-use the meminfo.
805
+ ptr = c.pyapi.object_get_private_data(obj)
806
+
807
+ with c.builder.if_else(cgutils.is_not_null(c.builder, ptr)) as (
808
+ has_meminfo,
809
+ otherwise,
810
+ ):
811
+ with has_meminfo:
812
+ # List was previously unboxed => reuse meminfo
813
+ list = listobj.ListInstance.from_meminfo(
814
+ c.context, c.builder, typ, ptr
815
+ )
816
+ list.size = size
817
+ if typ.reflected:
818
+ list.parent = obj
819
+ c.builder.store(list.value, listptr)
820
+
821
+ with otherwise:
822
+ _python_list_to_native(typ, obj, c, size, listptr, errorptr)
823
+
824
+ def cleanup():
825
+ # Clean up the associated pointer, as the meminfo is now invalid.
826
+ c.pyapi.object_reset_private_data(obj)
827
+
828
+ return NativeValue(
829
+ c.builder.load(listptr),
830
+ is_error=c.builder.load(errorptr),
831
+ cleanup=cleanup,
832
+ )
833
+
834
+
835
+ @reflect(types.List)
836
+ def reflect_list(typ, val, c):
837
+ """
838
+ Reflect the native list's contents into the Python object.
839
+ """
840
+ if not typ.reflected:
841
+ return
842
+ if typ.dtype.reflected:
843
+ msg = "cannot reflect element of reflected container: {}\n".format(typ)
844
+ raise TypeError(msg)
845
+
846
+ list = listobj.ListInstance(c.context, c.builder, typ, val)
847
+ with c.builder.if_then(list.dirty, likely=False):
848
+ obj = list.parent
849
+ size = c.pyapi.list_size(obj)
850
+ new_size = list.size
851
+ diff = c.builder.sub(new_size, size)
852
+ diff_gt_0 = c.builder.icmp_signed(">=", diff, ir.Constant(diff.type, 0))
853
+ with c.builder.if_else(diff_gt_0) as (if_grow, if_shrink):
854
+ # XXX no error checking below
855
+ with if_grow:
856
+ # First overwrite existing items
857
+ with cgutils.for_range(c.builder, size) as loop:
858
+ item = list.getitem(loop.index)
859
+ list.incref_value(item)
860
+ itemobj = c.box(typ.dtype, item)
861
+ c.pyapi.list_setitem(obj, loop.index, itemobj)
862
+ # Then add missing items
863
+ with cgutils.for_range(c.builder, diff) as loop:
864
+ idx = c.builder.add(size, loop.index)
865
+ item = list.getitem(idx)
866
+ list.incref_value(item)
867
+ itemobj = c.box(typ.dtype, item)
868
+ c.pyapi.list_append(obj, itemobj)
869
+ c.pyapi.decref(itemobj)
870
+
871
+ with if_shrink:
872
+ # First delete list tail
873
+ c.pyapi.list_setslice(obj, new_size, size, None)
874
+ # Then overwrite remaining items
875
+ with cgutils.for_range(c.builder, new_size) as loop:
876
+ item = list.getitem(loop.index)
877
+ list.incref_value(item)
878
+ itemobj = c.box(typ.dtype, item)
879
+ c.pyapi.list_setitem(obj, loop.index, itemobj)
880
+
881
+ # Mark the list clean, in case it is reflected twice
882
+ list.set_dirty(False)
883
+
884
+
885
+ def _python_set_to_native(typ, obj, c, size, setptr, errorptr):
886
+ """
887
+ Construct a new native set from a Python set.
888
+ """
889
+ # Allocate a new native set
890
+ ok, inst = setobj.SetInstance.allocate_ex(c.context, c.builder, typ, size)
891
+ with c.builder.if_else(ok, likely=True) as (if_ok, if_not_ok):
892
+ with if_ok:
893
+ # Traverse Python set and unbox objects into native set
894
+ typobjptr = cgutils.alloca_once_value(
895
+ c.builder, ir.Constant(c.pyapi.pyobj, None)
896
+ )
897
+
898
+ with c.pyapi.set_iterate(obj) as loop:
899
+ itemobj = loop.value
900
+ # Mandate that objects all have the same exact type
901
+ typobj = c.pyapi.get_type(itemobj)
902
+ expected_typobj = c.builder.load(typobjptr)
903
+
904
+ with c.builder.if_else(
905
+ cgutils.is_null(c.builder, expected_typobj), likely=False
906
+ ) as (if_first, if_not_first):
907
+ with if_first:
908
+ # First iteration => store item type
909
+ c.builder.store(typobj, typobjptr)
910
+ with if_not_first:
911
+ # Otherwise, check item type
912
+ type_mismatch = c.builder.icmp_signed(
913
+ "!=", typobj, expected_typobj
914
+ )
915
+ with c.builder.if_then(type_mismatch, likely=False):
916
+ c.builder.store(cgutils.true_bit, errorptr)
917
+ c.pyapi.err_set_string(
918
+ "PyExc_TypeError",
919
+ "can't unbox heterogeneous set",
920
+ )
921
+ loop.do_break()
922
+
923
+ # XXX we don't call native cleanup for each set element,
924
+ # since that would require keeping track
925
+ # of which unboxings have been successful.
926
+ native = c.unbox(typ.dtype, itemobj)
927
+ with c.builder.if_then(native.is_error, likely=False):
928
+ c.builder.store(cgutils.true_bit, errorptr)
929
+ inst.add_pyapi(c.pyapi, native.value, do_resize=False)
930
+
931
+ if typ.reflected:
932
+ inst.parent = obj
933
+ # Associate meminfo pointer with the Python object for later reuse.
934
+ with c.builder.if_then(
935
+ c.builder.not_(c.builder.load(errorptr)), likely=False
936
+ ):
937
+ c.pyapi.object_set_private_data(obj, inst.meminfo)
938
+ inst.set_dirty(False)
939
+ c.builder.store(inst.value, setptr)
940
+
941
+ with if_not_ok:
942
+ c.builder.store(cgutils.true_bit, errorptr)
943
+
944
+ # If an error occurred, drop the whole native set
945
+ with c.builder.if_then(c.builder.load(errorptr)):
946
+ c.context.nrt.decref(c.builder, typ, inst.value)
947
+
948
+
949
+ @unbox(types.Set)
950
+ def unbox_set(typ, obj, c):
951
+ """
952
+ Convert set *obj* to a native set.
953
+
954
+ If set was previously unboxed, we reuse the existing native set
955
+ to ensure consistency.
956
+ """
957
+ size = c.pyapi.set_size(obj)
958
+
959
+ errorptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
960
+ setptr = cgutils.alloca_once(c.builder, c.context.get_value_type(typ))
961
+
962
+ # See if the set was previously unboxed, if so, re-use the meminfo.
963
+ ptr = c.pyapi.object_get_private_data(obj)
964
+
965
+ with c.builder.if_else(cgutils.is_not_null(c.builder, ptr)) as (
966
+ has_meminfo,
967
+ otherwise,
968
+ ):
969
+ with has_meminfo:
970
+ # Set was previously unboxed => reuse meminfo
971
+ inst = setobj.SetInstance.from_meminfo(
972
+ c.context, c.builder, typ, ptr
973
+ )
974
+ if typ.reflected:
975
+ inst.parent = obj
976
+ c.builder.store(inst.value, setptr)
977
+
978
+ with otherwise:
979
+ _python_set_to_native(typ, obj, c, size, setptr, errorptr)
980
+
981
+ def cleanup():
982
+ # Clean up the associated pointer, as the meminfo is now invalid.
983
+ c.pyapi.object_reset_private_data(obj)
984
+
985
+ return NativeValue(
986
+ c.builder.load(setptr),
987
+ is_error=c.builder.load(errorptr),
988
+ cleanup=cleanup,
989
+ )
990
+
991
+
992
+ def _native_set_to_python_list(typ, payload, c):
993
+ """
994
+ Create a Python list from a native set's items.
995
+ """
996
+ nitems = payload.used
997
+ listobj = c.pyapi.list_new(nitems)
998
+ ok = cgutils.is_not_null(c.builder, listobj)
999
+ with c.builder.if_then(ok, likely=True):
1000
+ index = cgutils.alloca_once_value(
1001
+ c.builder, ir.Constant(nitems.type, 0)
1002
+ )
1003
+ with payload._iterate() as loop:
1004
+ i = c.builder.load(index)
1005
+ item = loop.entry.key
1006
+ c.context.nrt.incref(c.builder, typ.dtype, item)
1007
+ itemobj = c.box(typ.dtype, item)
1008
+ c.pyapi.list_setitem(listobj, i, itemobj)
1009
+ i = c.builder.add(i, ir.Constant(i.type, 1))
1010
+ c.builder.store(i, index)
1011
+
1012
+ return ok, listobj
1013
+
1014
+
1015
+ @box(types.Set)
1016
+ def box_set(typ, val, c):
1017
+ """
1018
+ Convert native set *val* to a set object.
1019
+ """
1020
+ inst = setobj.SetInstance(c.context, c.builder, typ, val)
1021
+ obj = inst.parent
1022
+ res = cgutils.alloca_once_value(c.builder, obj)
1023
+
1024
+ with c.builder.if_else(cgutils.is_not_null(c.builder, obj)) as (
1025
+ has_parent,
1026
+ otherwise,
1027
+ ):
1028
+ with has_parent:
1029
+ # Set is actually reflected => return the original object
1030
+ # (note not all set instances whose *type* is reflected are
1031
+ # actually reflected; see numba.tests.test_sets for an example)
1032
+ c.pyapi.incref(obj)
1033
+
1034
+ with otherwise:
1035
+ # Build a new Python list and then create a set from that
1036
+ payload = inst.payload
1037
+ ok, listobj = _native_set_to_python_list(typ, payload, c)
1038
+ with c.builder.if_then(ok, likely=True):
1039
+ obj = c.pyapi.set_new(listobj)
1040
+ c.pyapi.decref(listobj)
1041
+ c.builder.store(obj, res)
1042
+
1043
+ # Steal NRT ref
1044
+ c.context.nrt.decref(c.builder, typ, val)
1045
+ return c.builder.load(res)
1046
+
1047
+
1048
+ @reflect(types.Set)
1049
+ def reflect_set(typ, val, c):
1050
+ """
1051
+ Reflect the native set's contents into the Python object.
1052
+ """
1053
+ if not typ.reflected:
1054
+ return
1055
+ inst = setobj.SetInstance(c.context, c.builder, typ, val)
1056
+ payload = inst.payload
1057
+
1058
+ with c.builder.if_then(payload.dirty, likely=False):
1059
+ obj = inst.parent
1060
+ # XXX errors are not dealt with below
1061
+ c.pyapi.set_clear(obj)
1062
+
1063
+ # Build a new Python list and then update the set with that
1064
+ ok, listobj = _native_set_to_python_list(typ, payload, c)
1065
+ with c.builder.if_then(ok, likely=True):
1066
+ c.pyapi.set_update(obj, listobj)
1067
+ c.pyapi.decref(listobj)
1068
+
1069
+ # Mark the set clean, in case it is reflected twice
1070
+ inst.set_dirty(False)
1071
+
1072
+
1073
+ #
1074
+ # Other types
1075
+ #
1076
+
1077
+
1078
+ @box(types.Generator)
1079
+ def box_generator(typ, val, c):
1080
+ return c.pyapi.from_native_generator(val, typ, c.env_manager.env_ptr)
1081
+
1082
+
1083
+ @unbox(types.Generator)
1084
+ def unbox_generator(typ, obj, c):
1085
+ return c.pyapi.to_native_generator(obj, typ)
1086
+
1087
+
1088
+ @box(types.DType)
1089
+ def box_dtype(typ, val, c):
1090
+ np_dtype = numpy_support.as_dtype(typ.dtype)
1091
+ return c.pyapi.unserialize(c.pyapi.serialize_object(np_dtype))
1092
+
1093
+
1094
+ @unbox(types.DType)
1095
+ def unbox_dtype(typ, val, c):
1096
+ return NativeValue(c.context.get_dummy_value())
1097
+
1098
+
1099
+ @box(types.NumberClass)
1100
+ def box_number_class(typ, val, c):
1101
+ np_dtype = numpy_support.as_dtype(typ.dtype)
1102
+ return c.pyapi.unserialize(c.pyapi.serialize_object(np_dtype))
1103
+
1104
+
1105
+ @unbox(types.NumberClass)
1106
+ def unbox_number_class(typ, val, c):
1107
+ return NativeValue(c.context.get_dummy_value())
1108
+
1109
+
1110
+ @box(types.PyObject)
1111
+ @box(types.Object)
1112
+ def box_pyobject(typ, val, c): # noqa: F811
1113
+ return val
1114
+
1115
+
1116
+ @unbox(types.PyObject)
1117
+ @unbox(types.Object)
1118
+ def unbox_pyobject(typ, obj, c):
1119
+ return NativeValue(obj)
1120
+
1121
+
1122
+ @unbox(types.ExternalFunctionPointer)
1123
+ def unbox_funcptr(typ, obj, c):
1124
+ if typ.get_pointer is None:
1125
+ raise NotImplementedError(typ)
1126
+
1127
+ # Call get_pointer() on the object to get the raw pointer value
1128
+ ptrty = c.context.get_function_pointer_type(typ)
1129
+ ret = cgutils.alloca_once_value(
1130
+ c.builder, ir.Constant(ptrty, None), name="fnptr"
1131
+ )
1132
+ ser = c.pyapi.serialize_object(typ.get_pointer)
1133
+ get_pointer = c.pyapi.unserialize(ser)
1134
+ with cgutils.if_likely(
1135
+ c.builder, cgutils.is_not_null(c.builder, get_pointer)
1136
+ ):
1137
+ intobj = c.pyapi.call_function_objargs(get_pointer, (obj,))
1138
+ c.pyapi.decref(get_pointer)
1139
+ with cgutils.if_likely(
1140
+ c.builder, cgutils.is_not_null(c.builder, intobj)
1141
+ ):
1142
+ ptr = c.pyapi.long_as_voidptr(intobj)
1143
+ c.pyapi.decref(intobj)
1144
+ c.builder.store(c.builder.bitcast(ptr, ptrty), ret)
1145
+ return NativeValue(c.builder.load(ret), is_error=c.pyapi.c_api_error())
1146
+
1147
+
1148
+ @box(types.DeferredType)
1149
+ def box_deferred(typ, val, c):
1150
+ out = c.pyapi.from_native_value(
1151
+ typ.get(), c.builder.extract_value(val, [0]), env_manager=c.env_manager
1152
+ )
1153
+ return out
1154
+
1155
+
1156
+ @unbox(types.DeferredType)
1157
+ def unbox_deferred(typ, obj, c):
1158
+ native_value = c.pyapi.to_native_value(typ.get(), obj)
1159
+ model = c.context.data_model_manager[typ]
1160
+ res = model.set(c.builder, model.make_uninitialized(), native_value.value)
1161
+ return NativeValue(
1162
+ res, is_error=native_value.is_error, cleanup=native_value.cleanup
1163
+ )
1164
+
1165
+
1166
+ @unbox(types.Dispatcher)
1167
+ def unbox_dispatcher(typ, obj, c):
1168
+ # In native code, Dispatcher types can be casted to FunctionType.
1169
+ return NativeValue(obj)
1170
+
1171
+
1172
+ @box(types.Dispatcher)
1173
+ def box_pyobject(typ, val, c): # noqa: F811
1174
+ c.pyapi.incref(val)
1175
+ return val
1176
+
1177
+
1178
+ def unbox_unsupported(typ, obj, c):
1179
+ c.pyapi.err_set_string(
1180
+ "PyExc_TypeError", "can't unbox {!r} type".format(typ)
1181
+ )
1182
+ res = c.context.get_constant_null(typ)
1183
+ return NativeValue(res, is_error=cgutils.true_bit)
1184
+
1185
+
1186
+ def box_unsupported(typ, val, c):
1187
+ msg = "cannot convert native %s to Python object" % (typ,)
1188
+ c.pyapi.err_set_string("PyExc_TypeError", msg)
1189
+ res = c.pyapi.get_null_object()
1190
+ return res
1191
+
1192
+
1193
+ @box(types.Literal)
1194
+ def box_literal(typ, val, c):
1195
+ # Const type contains the python object of the constant value,
1196
+ # which we can directly return.
1197
+ retval = typ.literal_value
1198
+ # Serialize the value into the IR
1199
+ return c.pyapi.unserialize(c.pyapi.serialize_object(retval))
1200
+
1201
+
1202
+ @box(types.MemInfoPointer)
1203
+ def box_meminfo_pointer(typ, val, c):
1204
+ return c.pyapi.nrt_meminfo_as_pyobject(val)
1205
+
1206
+
1207
+ @unbox(types.MemInfoPointer)
1208
+ def unbox_meminfo_pointer(typ, obj, c):
1209
+ res = c.pyapi.nrt_meminfo_from_pyobject(obj)
1210
+ errored = cgutils.is_null(c.builder, res)
1211
+ return NativeValue(res, is_error=errored)
1212
+
1213
+
1214
+ @unbox(types.TypeRef)
1215
+ def unbox_typeref(typ, val, c):
1216
+ return NativeValue(c.context.get_dummy_value(), is_error=cgutils.false_bit)
1217
+
1218
+
1219
+ @box(types.LiteralStrKeyDict)
1220
+ def box_LiteralStrKeyDict(typ, val, c):
1221
+ return box_unsupported(typ, val, c)
1222
+
1223
+
1224
+ # Original implementation at: https://github.com/numba/numba/issues/4499#issuecomment-1063138477
1225
+ @unbox(types.NumPyRandomBitGeneratorType)
1226
+ def unbox_numpy_random_bitgenerator(typ, obj, c):
1227
+ """
1228
+ The bit_generator instance has a `.ctypes` attr which is a namedtuple
1229
+ with the following members (types):
1230
+ * state_address (Python int)
1231
+ * state (ctypes.c_void_p)
1232
+ * next_uint64 (ctypes.CFunctionType instance)
1233
+ * next_uint32 (ctypes.CFunctionType instance)
1234
+ * next_double (ctypes.CFunctionType instance)
1235
+ * bit_generator (ctypes.c_void_p)
1236
+ """
1237
+
1238
+ is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
1239
+ extra_refs = []
1240
+
1241
+ def clear_extra_refs():
1242
+ for _ref in extra_refs:
1243
+ c.pyapi.decref(_ref)
1244
+
1245
+ def handle_failure():
1246
+ c.builder.store(cgutils.true_bit, is_error_ptr)
1247
+ clear_extra_refs()
1248
+
1249
+ with ExitStack() as stack:
1250
+
1251
+ def object_getattr_safely(obj, attr):
1252
+ attr_obj = c.pyapi.object_getattr_string(obj, attr)
1253
+ extra_refs.append(attr_obj)
1254
+ return attr_obj
1255
+
1256
+ struct_ptr = cgutils.create_struct_proxy(typ)(c.context, c.builder)
1257
+ struct_ptr.parent = obj
1258
+
1259
+ # Get the .ctypes attr
1260
+ ctypes_binding = object_getattr_safely(obj, "ctypes")
1261
+ with cgutils.early_exit_if_null(c.builder, stack, ctypes_binding):
1262
+ handle_failure()
1263
+
1264
+ # Look up the "state_address" member and wire it into the struct
1265
+ interface_state_address = object_getattr_safely(
1266
+ ctypes_binding, "state_address"
1267
+ )
1268
+ with cgutils.early_exit_if_null(
1269
+ c.builder, stack, interface_state_address
1270
+ ):
1271
+ handle_failure()
1272
+
1273
+ setattr(
1274
+ struct_ptr,
1275
+ "state_address",
1276
+ c.unbox(types.uintp, interface_state_address).value,
1277
+ )
1278
+
1279
+ # Look up the "state" member and wire it into the struct
1280
+ interface_state = object_getattr_safely(ctypes_binding, "state")
1281
+ with cgutils.early_exit_if_null(c.builder, stack, interface_state):
1282
+ handle_failure()
1283
+
1284
+ interface_state_value = object_getattr_safely(interface_state, "value")
1285
+ with cgutils.early_exit_if_null(
1286
+ c.builder, stack, interface_state_value
1287
+ ):
1288
+ handle_failure()
1289
+ setattr(
1290
+ struct_ptr,
1291
+ "state",
1292
+ c.unbox(types.uintp, interface_state_value).value,
1293
+ )
1294
+
1295
+ # Want to store callable function pointers to these CFunctionTypes, so
1296
+ # import ctypes and use it to cast the CFunctionTypes to c_void_p and
1297
+ # store the results.
1298
+ # First find ctypes.cast, and ctypes.c_void_p
1299
+ ctypes_name = c.context.insert_const_string(c.builder.module, "ctypes")
1300
+ ctypes_module = c.pyapi.import_module(ctypes_name)
1301
+ extra_refs.append(ctypes_module)
1302
+ with cgutils.early_exit_if_null(c.builder, stack, ctypes_module):
1303
+ handle_failure()
1304
+
1305
+ ct_cast = object_getattr_safely(ctypes_module, "cast")
1306
+ with cgutils.early_exit_if_null(c.builder, stack, ct_cast):
1307
+ handle_failure()
1308
+
1309
+ ct_voidptr_ty = object_getattr_safely(ctypes_module, "c_void_p")
1310
+ with cgutils.early_exit_if_null(c.builder, stack, ct_voidptr_ty):
1311
+ handle_failure()
1312
+
1313
+ # This wires in the fnptrs referred to by name
1314
+ def wire_in_fnptrs(name):
1315
+ # Find the CFunctionType function
1316
+ interface_next_fn = c.pyapi.object_getattr_string(
1317
+ ctypes_binding, name
1318
+ )
1319
+
1320
+ extra_refs.append(interface_next_fn)
1321
+ with cgutils.early_exit_if_null(
1322
+ c.builder, stack, interface_next_fn
1323
+ ):
1324
+ handle_failure()
1325
+
1326
+ # Want to do ctypes.cast(CFunctionType, ctypes.c_void_p), create an
1327
+ # args tuple for that.
1328
+ args = c.pyapi.tuple_pack([interface_next_fn, ct_voidptr_ty])
1329
+ with cgutils.early_exit_if_null(c.builder, stack, args):
1330
+ handle_failure()
1331
+ extra_refs.append(args)
1332
+
1333
+ # Call ctypes.cast()
1334
+ interface_next_fn_casted = c.pyapi.call(ct_cast, args)
1335
+ extra_refs.append(interface_next_fn_casted)
1336
+
1337
+ # Fetch the .value attr on the resulting ctypes.c_void_p for storage
1338
+ # in the function pointer slot.
1339
+ interface_next_fn_casted_value = object_getattr_safely(
1340
+ interface_next_fn_casted, "value"
1341
+ )
1342
+ with cgutils.early_exit_if_null(
1343
+ c.builder, stack, interface_next_fn_casted_value
1344
+ ):
1345
+ handle_failure()
1346
+
1347
+ # Wire up
1348
+ setattr(
1349
+ struct_ptr,
1350
+ f"fnptr_{name}",
1351
+ c.unbox(types.uintp, interface_next_fn_casted_value).value,
1352
+ )
1353
+
1354
+ wire_in_fnptrs("next_double")
1355
+ wire_in_fnptrs("next_uint64")
1356
+ wire_in_fnptrs("next_uint32")
1357
+
1358
+ clear_extra_refs()
1359
+
1360
+ return NativeValue(
1361
+ struct_ptr._getvalue(), is_error=c.builder.load(is_error_ptr)
1362
+ )
1363
+
1364
+
1365
+ _bit_gen_type = types.NumPyRandomBitGeneratorType("bit_generator")
1366
+
1367
+
1368
+ @unbox(types.NumPyRandomGeneratorType)
1369
+ def unbox_numpy_random_generator(typ, obj, c):
1370
+ """
1371
+ Here we're creating a NumPyRandomGeneratorType StructModel with following fields:
1372
+ * ('bit_generator', _bit_gen_type): The unboxed BitGenerator associated with
1373
+ this Generator object instance.
1374
+ * ('parent', types.pyobject): Pointer to the original Generator PyObject.
1375
+ * ('meminfo', types.MemInfoPointer(types.voidptr)): The information about the memory
1376
+ stored at the pointer (to the original Generator PyObject). This is useful for
1377
+ keeping track of reference counts within the Python runtime. Helps prevent cases
1378
+ where deletion happens in Python runtime without NRT being awareness of it.
1379
+ """
1380
+ is_error_ptr = cgutils.alloca_once_value(c.builder, cgutils.false_bit)
1381
+
1382
+ with ExitStack() as stack:
1383
+ struct_ptr = cgutils.create_struct_proxy(typ)(c.context, c.builder)
1384
+ bit_gen_inst = c.pyapi.object_getattr_string(obj, "bit_generator")
1385
+ with cgutils.early_exit_if_null(c.builder, stack, bit_gen_inst):
1386
+ c.builder.store(cgutils.true_bit, is_error_ptr)
1387
+ unboxed = c.unbox(_bit_gen_type, bit_gen_inst).value
1388
+ struct_ptr.bit_generator = unboxed
1389
+ struct_ptr.parent = obj
1390
+ NULL = cgutils.voidptr_t(None)
1391
+ struct_ptr.meminfo = c.pyapi.nrt_meminfo_new_from_pyobject(
1392
+ NULL, # there's no data
1393
+ obj, # the python object, the call to nrt_meminfo_new_from_pyobject
1394
+ # will py_incref
1395
+ )
1396
+ c.pyapi.decref(bit_gen_inst)
1397
+
1398
+ return NativeValue(
1399
+ struct_ptr._getvalue(), is_error=c.builder.load(is_error_ptr)
1400
+ )
1401
+
1402
+
1403
+ @box(types.NumPyRandomGeneratorType)
1404
+ def box_numpy_random_generator(typ, val, c):
1405
+ inst = c.context.make_helper(c.builder, typ, val)
1406
+ obj = inst.parent
1407
+ res = cgutils.alloca_once_value(c.builder, obj)
1408
+ c.pyapi.incref(obj)
1409
+ # Steal NRT ref
1410
+ c.context.nrt.decref(c.builder, typ, val)
1411
+ return c.builder.load(res)