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,496 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+ """
4
+ Implement Dominance-Fronter-based SSA by Choi et al described in Inria SSA book
5
+
6
+ References:
7
+
8
+ - Static Single Assignment Book by Inria
9
+ http://ssabook.gforge.inria.fr/latest/book.pdf
10
+ - Choi et al. Incremental computation of static single assignment form.
11
+ """
12
+
13
+ import logging
14
+ import operator
15
+ import warnings
16
+ from functools import reduce
17
+ from copy import copy
18
+ from collections import defaultdict
19
+
20
+ from numba.cuda import config
21
+ from numba.core import ir, ir_utils, errors
22
+ from numba.cuda.utils import OrderedSet, _lazy_pformat
23
+ from numba.core.analysis import compute_cfg_from_blocks
24
+
25
+
26
+ _logger = logging.getLogger(__name__)
27
+
28
+
29
+ def reconstruct_ssa(func_ir):
30
+ """Apply SSA reconstruction algorithm on the given IR.
31
+
32
+ Produces minimal SSA using Choi et al algorithm.
33
+ """
34
+ func_ir.blocks = _run_ssa(func_ir.blocks)
35
+
36
+ return func_ir
37
+
38
+
39
+ class _CacheListVars:
40
+ def __init__(self):
41
+ self._saved = {}
42
+
43
+ def get(self, inst):
44
+ got = self._saved.get(inst)
45
+ if got is None:
46
+ self._saved[inst] = got = inst.list_vars()
47
+ return got
48
+
49
+
50
+ def _run_ssa(blocks):
51
+ """Run SSA reconstruction on IR blocks of a function."""
52
+ if not blocks:
53
+ # Empty blocks?
54
+ return {}
55
+ # Run CFG on the blocks
56
+ cfg = compute_cfg_from_blocks(blocks)
57
+ df_plus = _iterated_domfronts(cfg)
58
+ # Find SSA violators
59
+ violators = _find_defs_violators(blocks, cfg)
60
+ # Make cache for .list_vars()
61
+ cache_list_vars = _CacheListVars()
62
+
63
+ # Process one SSA-violating variable at a time
64
+ for varname in violators:
65
+ _logger.debug(
66
+ "Fix SSA violator on var %s",
67
+ varname,
68
+ )
69
+ # Fix up the LHS
70
+ # Put fresh variables for all assignments to the variable
71
+ blocks, defmap = _fresh_vars(blocks, varname)
72
+ _logger.debug("Replaced assignments: %s", _lazy_pformat(defmap))
73
+ # Fix up the RHS
74
+ # Re-associate the variable uses with the reaching definition
75
+ blocks = _fix_ssa_vars(
76
+ blocks, varname, defmap, cfg, df_plus, cache_list_vars
77
+ )
78
+
79
+ # Post-condition checks.
80
+ # CFG invariant
81
+ cfg_post = compute_cfg_from_blocks(blocks)
82
+ if cfg_post != cfg:
83
+ raise errors.CompilerError("CFG mutated in SSA pass")
84
+ return blocks
85
+
86
+
87
+ def _fix_ssa_vars(blocks, varname, defmap, cfg, df_plus, cache_list_vars):
88
+ """Rewrite all uses to ``varname`` given the definition map"""
89
+ states = _make_states(blocks)
90
+ states["varname"] = varname
91
+ states["defmap"] = defmap
92
+ states["phimap"] = phimap = defaultdict(list)
93
+ states["cfg"] = cfg
94
+ states["phi_locations"] = _compute_phi_locations(df_plus, defmap)
95
+ newblocks = _run_block_rewrite(blocks, states, _FixSSAVars(cache_list_vars))
96
+ # insert phi nodes
97
+ for label, philist in phimap.items():
98
+ curblk = newblocks[label]
99
+ # Prepend PHI nodes to the block
100
+ curblk.body = philist + curblk.body
101
+ return newblocks
102
+
103
+
104
+ def _iterated_domfronts(cfg):
105
+ """Compute the iterated dominance frontiers (DF+ in literatures).
106
+
107
+ Returns a dictionary which maps block label to the set of labels of its
108
+ iterated dominance frontiers.
109
+ """
110
+ domfronts = {k: set(vs) for k, vs in cfg.dominance_frontier().items()}
111
+ keep_going = True
112
+ while keep_going:
113
+ keep_going = False
114
+ for k, vs in domfronts.items():
115
+ inner = reduce(operator.or_, [domfronts[v] for v in vs], set())
116
+ if inner.difference(vs):
117
+ vs |= inner
118
+ keep_going = True
119
+ return domfronts
120
+
121
+
122
+ def _compute_phi_locations(iterated_df, defmap):
123
+ # See basic algorithm in Ch 4.1 in Inria SSA Book
124
+ # Compute DF+(defs)
125
+ # DF of all DFs is the union of all DFs
126
+ phi_locations = set()
127
+ for deflabel, defstmts in defmap.items():
128
+ if defstmts:
129
+ phi_locations |= iterated_df[deflabel]
130
+ return phi_locations
131
+
132
+
133
+ def _fresh_vars(blocks, varname):
134
+ """Rewrite to put fresh variable names"""
135
+ states = _make_states(blocks)
136
+ states["varname"] = varname
137
+ states["defmap"] = defmap = defaultdict(list)
138
+ newblocks = _run_block_rewrite(blocks, states, _FreshVarHandler())
139
+ return newblocks, defmap
140
+
141
+
142
+ def _get_scope(blocks):
143
+ first, *_ = blocks.values()
144
+ return first.scope
145
+
146
+
147
+ def _find_defs_violators(blocks, cfg):
148
+ """
149
+ Returns
150
+ -------
151
+ res : Set[str]
152
+ The SSA violators in a dictionary of variable names.
153
+ """
154
+ defs = defaultdict(list)
155
+ uses = defaultdict(set)
156
+ states = dict(defs=defs, uses=uses)
157
+ _run_block_analysis(blocks, states, _GatherDefsHandler())
158
+ _logger.debug("defs %s", _lazy_pformat(defs))
159
+ # Gather violators by number of definitions.
160
+ # The violators are added by the order that they are seen and the algorithm
161
+ # scan from the first to the last basic-block as they occur in bytecode.
162
+ violators = OrderedSet([k for k, vs in defs.items() if len(vs) > 1])
163
+ # Gather violators by uses not dominated by the one def
164
+ doms = cfg.dominators()
165
+ for k, use_blocks in uses.items():
166
+ if k not in violators:
167
+ for label in use_blocks:
168
+ dom = doms[label]
169
+ def_labels = {label for _assign, label in defs[k]}
170
+ if not def_labels.intersection(dom):
171
+ violators.add(k)
172
+ break
173
+ _logger.debug("SSA violators %s", _lazy_pformat(violators))
174
+ return violators
175
+
176
+
177
+ def _run_block_analysis(blocks, states, handler):
178
+ for label, blk in blocks.items():
179
+ _logger.debug("==== SSA block analysis pass on %s", label)
180
+ states["label"] = label
181
+ for _ in _run_ssa_block_pass(states, blk, handler):
182
+ pass
183
+
184
+
185
+ def _run_block_rewrite(blocks, states, handler):
186
+ newblocks = {}
187
+ for label, blk in blocks.items():
188
+ _logger.debug("==== SSA block rewrite pass on %s", label)
189
+ newblk = ir.Block(scope=blk.scope, loc=blk.loc)
190
+
191
+ newbody = []
192
+ states["label"] = label
193
+ states["block"] = blk
194
+ for stmt in _run_ssa_block_pass(states, blk, handler):
195
+ assert stmt is not None
196
+ newbody.append(stmt)
197
+ newblk.body = newbody
198
+ newblocks[label] = newblk
199
+ return newblocks
200
+
201
+
202
+ def _make_states(blocks):
203
+ return dict(
204
+ scope=_get_scope(blocks),
205
+ )
206
+
207
+
208
+ def _run_ssa_block_pass(states, blk, handler):
209
+ _logger.debug("Running %s", handler)
210
+ for stmt in blk.body:
211
+ _logger.debug("on stmt: %s", stmt)
212
+ if isinstance(stmt, ir.Assign):
213
+ ret = handler.on_assign(states, stmt)
214
+ else:
215
+ ret = handler.on_other(states, stmt)
216
+ if ret is not stmt and ret is not None:
217
+ _logger.debug("replaced with: %s", ret)
218
+ yield ret
219
+
220
+
221
+ class _BaseHandler:
222
+ """A base handler for all the passes used here for the SSA algorithm."""
223
+
224
+ def on_assign(self, states, assign):
225
+ """
226
+ Called when the pass sees an ``ir.Assign``.
227
+
228
+ Subclasses should override this for custom behavior
229
+
230
+ Parameters
231
+ -----------
232
+ states : dict
233
+ assign : numba.ir.Assign
234
+
235
+ Returns
236
+ -------
237
+ stmt : numba.ir.Assign or None
238
+ For rewrite passes, the return value is used as the replacement
239
+ for the given statement.
240
+ """
241
+
242
+ def on_other(self, states, stmt):
243
+ """
244
+ Called when the pass sees an ``ir.Stmt`` that's not an assignment.
245
+
246
+ Subclasses should override this for custom behavior
247
+
248
+ Parameters
249
+ -----------
250
+ states : dict
251
+ assign : numba.ir.Stmt
252
+
253
+ Returns
254
+ -------
255
+ stmt : numba.ir.Stmt or None
256
+ For rewrite passes, the return value is used as the replacement
257
+ for the given statement.
258
+ """
259
+
260
+
261
+ class _GatherDefsHandler(_BaseHandler):
262
+ """Find all defs and uses of variable in each block
263
+
264
+ ``states["label"]`` is a int; label of the current block
265
+ ``states["defs"]`` is a Mapping[str, List[Tuple[ir.Assign, int]]]:
266
+ - a mapping of the name of the assignee variable to the assignment
267
+ IR node and the block label.
268
+ ``states["uses"]`` is a Mapping[Set[int]]
269
+ """
270
+
271
+ def on_assign(self, states, assign):
272
+ # keep track of assignment and the block
273
+ states["defs"][assign.target.name].append((assign, states["label"]))
274
+ # keep track of uses
275
+ for var in assign.list_vars():
276
+ k = var.name
277
+ if k != assign.target.name:
278
+ states["uses"][k].add(states["label"])
279
+
280
+ def on_other(self, states, stmt):
281
+ # keep track of uses
282
+ for var in stmt.list_vars():
283
+ k = var.name
284
+ states["uses"][k].add(states["label"])
285
+
286
+
287
+ class UndefinedVariable:
288
+ def __init__(self):
289
+ raise NotImplementedError("Not intended for instantiation")
290
+
291
+ target = ir.UNDEFINED
292
+
293
+
294
+ class _FreshVarHandler(_BaseHandler):
295
+ """Replaces assignment target with new fresh variables."""
296
+
297
+ def on_assign(self, states, assign):
298
+ if assign.target.name == states["varname"]:
299
+ scope = states["scope"]
300
+ defmap = states["defmap"]
301
+ # Allow first assignment to retain the name
302
+ if len(defmap) == 0:
303
+ newtarget = assign.target
304
+ _logger.debug("first assign: %s", newtarget)
305
+ if newtarget.name not in scope.localvars:
306
+ wmsg = f"variable {newtarget.name!r} is not in scope."
307
+ warnings.warn(
308
+ errors.NumbaIRAssumptionWarning(wmsg, loc=assign.loc)
309
+ )
310
+ else:
311
+ newtarget = scope.redefine(assign.target.name, loc=assign.loc)
312
+ assign = ir.Assign(
313
+ target=newtarget, value=assign.value, loc=assign.loc
314
+ )
315
+ defmap[states["label"]].append(assign)
316
+ return assign
317
+
318
+ def on_other(self, states, stmt):
319
+ return stmt
320
+
321
+
322
+ class _FixSSAVars(_BaseHandler):
323
+ """Replace variable uses in IR nodes to the correct reaching variable
324
+ and introduce Phi nodes if necessary. This class contains the core of
325
+ the SSA reconstruction algorithm.
326
+
327
+ See Ch 5 of the Inria SSA book for reference. The method names used here
328
+ are similar to the names used in the pseudocode in the book.
329
+ """
330
+
331
+ def __init__(self, cache_list_vars):
332
+ self._cache_list_vars = cache_list_vars
333
+
334
+ def on_assign(self, states, assign):
335
+ rhs = assign.value
336
+ if isinstance(rhs, ir.Inst):
337
+ newdef = self._fix_var(
338
+ states,
339
+ assign,
340
+ self._cache_list_vars.get(assign.value),
341
+ )
342
+ # Has a replacement that is not the current variable
343
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
344
+ if states["varname"] != newdef.target.name:
345
+ replmap = {states["varname"]: newdef.target}
346
+ rhs = copy(rhs)
347
+
348
+ ir_utils.replace_vars_inner(rhs, replmap)
349
+ return ir.Assign(
350
+ target=assign.target,
351
+ value=rhs,
352
+ loc=assign.loc,
353
+ )
354
+ elif isinstance(rhs, ir.Var):
355
+ newdef = self._fix_var(states, assign, [rhs])
356
+ # Has a replacement that is not the current variable
357
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
358
+ if states["varname"] != newdef.target.name:
359
+ return ir.Assign(
360
+ target=assign.target,
361
+ value=newdef.target,
362
+ loc=assign.loc,
363
+ )
364
+
365
+ return assign
366
+
367
+ def on_other(self, states, stmt):
368
+ newdef = self._fix_var(
369
+ states,
370
+ stmt,
371
+ self._cache_list_vars.get(stmt),
372
+ )
373
+ if newdef is not None and newdef.target is not ir.UNDEFINED:
374
+ if states["varname"] != newdef.target.name:
375
+ replmap = {states["varname"]: newdef.target}
376
+ stmt = copy(stmt)
377
+ ir_utils.replace_vars_stmt(stmt, replmap)
378
+ return stmt
379
+
380
+ def _fix_var(self, states, stmt, used_vars):
381
+ """Fix all variable uses in ``used_vars``."""
382
+ varnames = [k.name for k in used_vars]
383
+ phivar = states["varname"]
384
+ if phivar in varnames:
385
+ return self._find_def(states, stmt)
386
+
387
+ def _find_def(self, states, stmt):
388
+ """Find definition of ``stmt`` for the statement ``stmt``"""
389
+ _logger.debug("find_def var=%r stmt=%s", states["varname"], stmt)
390
+ selected_def = None
391
+ label = states["label"]
392
+ local_defs = states["defmap"][label]
393
+ local_phis = states["phimap"][label]
394
+ block = states["block"]
395
+
396
+ cur_pos = self._stmt_index(stmt, block)
397
+ for defstmt in reversed(local_defs):
398
+ # Phi nodes have no index
399
+ def_pos = self._stmt_index(defstmt, block, stop=cur_pos)
400
+ if def_pos < cur_pos:
401
+ selected_def = defstmt
402
+ break
403
+ # Maybe it's a PHI
404
+ elif defstmt in local_phis:
405
+ selected_def = local_phis[-1]
406
+ break
407
+
408
+ if selected_def is None:
409
+ selected_def = self._find_def_from_top(
410
+ states,
411
+ label,
412
+ loc=stmt.loc,
413
+ )
414
+ return selected_def
415
+
416
+ def _find_def_from_top(self, states, label, loc):
417
+ """Find definition reaching block of ``label``.
418
+
419
+ This method would look at all dominance frontiers.
420
+ Insert phi node if necessary.
421
+ """
422
+ _logger.debug("find_def_from_top label %r", label)
423
+ cfg = states["cfg"]
424
+ defmap = states["defmap"]
425
+ phimap = states["phimap"]
426
+ phi_locations = states["phi_locations"]
427
+
428
+ if label in phi_locations:
429
+ scope = states["scope"]
430
+ loc = states["block"].loc
431
+ # fresh variable
432
+ freshvar = scope.redefine(states["varname"], loc=loc)
433
+ # insert phi
434
+ phinode = ir.Assign(
435
+ target=freshvar,
436
+ value=ir.Expr.phi(loc=loc),
437
+ loc=loc,
438
+ )
439
+ _logger.debug("insert phi node %s at %s", phinode, label)
440
+ defmap[label].insert(0, phinode)
441
+ phimap[label].append(phinode)
442
+ # Find incoming values for the Phi node
443
+ for pred, _ in cfg.predecessors(label):
444
+ incoming_def = self._find_def_from_bottom(
445
+ states,
446
+ pred,
447
+ loc=loc,
448
+ )
449
+ _logger.debug("incoming_def %s", incoming_def)
450
+ phinode.value.incoming_values.append(incoming_def.target)
451
+ phinode.value.incoming_blocks.append(pred)
452
+ return phinode
453
+ else:
454
+ idom = cfg.immediate_dominators()[label]
455
+ if idom == label:
456
+ # We have searched to the top of the idom tree.
457
+ # Since we still cannot find a definition,
458
+ # we will warn.
459
+ _warn_about_uninitialized_variable(states["varname"], loc)
460
+ return UndefinedVariable
461
+ _logger.debug("idom %s from label %s", idom, label)
462
+ return self._find_def_from_bottom(states, idom, loc=loc)
463
+
464
+ def _find_def_from_bottom(self, states, label, loc):
465
+ """Find definition from within the block at ``label``."""
466
+ _logger.debug("find_def_from_bottom label %r", label)
467
+ defmap = states["defmap"]
468
+ defs = defmap[label]
469
+ if defs:
470
+ lastdef = defs[-1]
471
+ return lastdef
472
+ else:
473
+ return self._find_def_from_top(states, label, loc=loc)
474
+
475
+ def _stmt_index(self, defstmt, block, stop=-1):
476
+ """Find the positional index of the statement at ``block``.
477
+
478
+ Assumptions:
479
+ - no two statements can point to the same object.
480
+ """
481
+ # Compare using id() as IR node equality is for semantic equivalence
482
+ # opposed to direct equality (the location and scope are not considered
483
+ # as part of the equality measure, this is important here).
484
+ for i in range(len(block.body))[:stop]:
485
+ if block.body[i] is defstmt:
486
+ return i
487
+ return len(block.body)
488
+
489
+
490
+ def _warn_about_uninitialized_variable(varname, loc):
491
+ if config.ALWAYS_WARN_UNINIT_VAR:
492
+ warnings.warn(
493
+ errors.NumbaWarning(
494
+ f"Detected uninitialized variable {varname}", loc=loc
495
+ ),
496
+ )