numba-cuda 0.18.1__py3-none-any.whl → 0.19.1__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 (301) 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 +5 -2
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +4 -1
  9. numba_cuda/numba/cuda/api.py +5 -7
  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 +3 -0
  13. numba_cuda/numba/cuda/cg.py +3 -0
  14. numba_cuda/numba/cuda/cgutils.py +3 -0
  15. numba_cuda/numba/cuda/codegen.py +3 -0
  16. numba_cuda/numba/cuda/compiler.py +10 -4
  17. numba_cuda/numba/cuda/core/caching.py +3 -0
  18. numba_cuda/numba/cuda/core/callconv.py +3 -0
  19. numba_cuda/numba/cuda/core/codegen.py +3 -0
  20. numba_cuda/numba/cuda/core/compiler.py +3 -0
  21. numba_cuda/numba/cuda/core/interpreter.py +3595 -0
  22. numba_cuda/numba/cuda/core/ir_utils.py +2644 -0
  23. numba_cuda/numba/cuda/core/sigutils.py +58 -0
  24. numba_cuda/numba/cuda/core/typed_passes.py +3 -0
  25. numba_cuda/numba/cuda/cuda_paths.py +12 -17
  26. numba_cuda/numba/cuda/cudadecl.py +4 -1
  27. numba_cuda/numba/cuda/cudadrv/__init__.py +3 -0
  28. numba_cuda/numba/cuda/cudadrv/devicearray.py +3 -0
  29. numba_cuda/numba/cuda/cudadrv/devices.py +3 -0
  30. numba_cuda/numba/cuda/cudadrv/driver.py +7 -19
  31. numba_cuda/numba/cuda/cudadrv/drvapi.py +3 -0
  32. numba_cuda/numba/cuda/cudadrv/dummyarray.py +3 -0
  33. numba_cuda/numba/cuda/cudadrv/enums.py +3 -0
  34. numba_cuda/numba/cuda/cudadrv/error.py +4 -0
  35. numba_cuda/numba/cuda/cudadrv/libs.py +4 -2
  36. numba_cuda/numba/cuda/cudadrv/linkable_code.py +3 -0
  37. numba_cuda/numba/cuda/cudadrv/mappings.py +3 -0
  38. numba_cuda/numba/cuda/cudadrv/ndarray.py +3 -0
  39. numba_cuda/numba/cuda/cudadrv/nvrtc.py +47 -44
  40. numba_cuda/numba/cuda/cudadrv/nvvm.py +6 -18
  41. numba_cuda/numba/cuda/cudadrv/rtapi.py +3 -0
  42. numba_cuda/numba/cuda/cudadrv/runtime.py +15 -1
  43. numba_cuda/numba/cuda/cudaimpl.py +3 -0
  44. numba_cuda/numba/cuda/cudamath.py +4 -1
  45. numba_cuda/numba/cuda/debuginfo.py +3 -0
  46. numba_cuda/numba/cuda/decorators.py +7 -3
  47. numba_cuda/numba/cuda/descriptor.py +3 -0
  48. numba_cuda/numba/cuda/device_init.py +3 -0
  49. numba_cuda/numba/cuda/deviceufunc.py +5 -1
  50. numba_cuda/numba/cuda/dispatcher.py +6 -2
  51. numba_cuda/numba/cuda/errors.py +10 -0
  52. numba_cuda/numba/cuda/extending.py +4 -1
  53. numba_cuda/numba/cuda/flags.py +2 -0
  54. numba_cuda/numba/cuda/fp16.py +3 -0
  55. numba_cuda/numba/cuda/initialize.py +4 -0
  56. numba_cuda/numba/cuda/intrinsic_wrapper.py +3 -0
  57. numba_cuda/numba/cuda/intrinsics.py +3 -0
  58. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  59. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  60. numba_cuda/numba/cuda/kernels/reduction.py +3 -0
  61. numba_cuda/numba/cuda/kernels/transpose.py +3 -0
  62. numba_cuda/numba/cuda/libdevice.py +4 -0
  63. numba_cuda/numba/cuda/libdevicedecl.py +4 -1
  64. numba_cuda/numba/cuda/libdevicefuncs.py +4 -1
  65. numba_cuda/numba/cuda/libdeviceimpl.py +3 -0
  66. numba_cuda/numba/cuda/locks.py +3 -0
  67. numba_cuda/numba/cuda/lowering.py +53 -16
  68. numba_cuda/numba/cuda/mathimpl.py +3 -0
  69. numba_cuda/numba/cuda/memory_management/__init__.py +3 -0
  70. numba_cuda/numba/cuda/memory_management/memsys.cu +5 -0
  71. numba_cuda/numba/cuda/memory_management/memsys.cuh +5 -0
  72. numba_cuda/numba/cuda/memory_management/nrt.cu +5 -0
  73. numba_cuda/numba/cuda/memory_management/nrt.cuh +5 -0
  74. numba_cuda/numba/cuda/memory_management/nrt.py +5 -1
  75. numba_cuda/numba/cuda/models.py +3 -0
  76. numba_cuda/numba/cuda/nvvmutils.py +3 -0
  77. numba_cuda/numba/cuda/printimpl.py +3 -0
  78. numba_cuda/numba/cuda/random.py +3 -0
  79. numba_cuda/numba/cuda/reshape_funcs.cu +5 -0
  80. numba_cuda/numba/cuda/serialize.py +3 -0
  81. numba_cuda/numba/cuda/simulator/__init__.py +3 -0
  82. numba_cuda/numba/cuda/simulator/_internal/__init__.py +3 -0
  83. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  84. numba_cuda/numba/cuda/simulator/api.py +4 -1
  85. numba_cuda/numba/cuda/simulator/bf16.py +3 -0
  86. numba_cuda/numba/cuda/simulator/compiler.py +3 -0
  87. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +3 -0
  88. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +3 -0
  89. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +3 -0
  90. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +3 -7
  91. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +3 -0
  92. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +3 -0
  93. numba_cuda/numba/cuda/simulator/cudadrv/error.py +4 -0
  94. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +4 -0
  95. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +4 -0
  96. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +3 -0
  97. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +3 -0
  98. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +3 -0
  99. numba_cuda/numba/cuda/simulator/dispatcher.py +4 -0
  100. numba_cuda/numba/cuda/simulator/kernel.py +3 -0
  101. numba_cuda/numba/cuda/simulator/kernelapi.py +3 -0
  102. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +3 -0
  103. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +3 -0
  104. numba_cuda/numba/cuda/simulator/reduction.py +3 -0
  105. numba_cuda/numba/cuda/simulator/vector_types.py +3 -0
  106. numba_cuda/numba/cuda/simulator_init.py +3 -0
  107. numba_cuda/numba/cuda/stubs.py +3 -0
  108. numba_cuda/numba/cuda/target.py +4 -2
  109. numba_cuda/numba/cuda/testing.py +7 -6
  110. numba_cuda/numba/cuda/tests/__init__.py +3 -0
  111. numba_cuda/numba/cuda/tests/complex_usecases.py +3 -0
  112. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +3 -0
  113. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  114. numba_cuda/numba/cuda/tests/core/test_serialize.py +3 -0
  115. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +3 -0
  116. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +3 -0
  117. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +3 -0
  118. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +3 -0
  119. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +3 -0
  120. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +3 -0
  121. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +3 -0
  122. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_libraries.py +3 -0
  123. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +3 -0
  124. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +4 -1
  125. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +4 -1
  126. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +4 -1
  127. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +4 -1
  128. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +3 -0
  129. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +3 -0
  130. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +3 -0
  131. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +3 -0
  132. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +3 -0
  133. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +4 -1
  134. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +4 -1
  135. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +3 -0
  136. numba_cuda/numba/cuda/tests/cudadrv/test_mvc.py +4 -1
  137. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +3 -0
  138. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +7 -6
  139. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +3 -4
  140. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +3 -0
  141. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +3 -0
  142. numba_cuda/numba/cuda/tests/cudadrv/test_ptds.py +4 -1
  143. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +3 -0
  144. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +3 -0
  145. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +3 -0
  146. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +3 -0
  147. numba_cuda/numba/cuda/tests/cudapy/__init__.py +3 -0
  148. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +3 -0
  149. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +3 -0
  150. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +3 -0
  151. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +3 -0
  152. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +3 -0
  153. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +3 -0
  154. numba_cuda/numba/cuda/tests/cudapy/test_array.py +3 -0
  155. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +3 -0
  156. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +3 -0
  157. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +3 -0
  158. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +3 -0
  159. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +4 -3
  160. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +4 -3
  161. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +3 -0
  162. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +3 -0
  163. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +149 -3
  164. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +3 -0
  165. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +4 -1
  166. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +3 -4
  167. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +3 -0
  168. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +3 -0
  169. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +3 -0
  170. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +3 -0
  171. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +3 -0
  172. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +4 -1
  173. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +4 -1
  174. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +3 -0
  175. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +4 -1
  176. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +23 -284
  177. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  178. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +4 -1
  179. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +3 -0
  180. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +3 -0
  181. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +4 -1
  182. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +3 -0
  183. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +4 -6
  184. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +3 -0
  185. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +3 -0
  186. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +3 -0
  187. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +3 -0
  188. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +3 -0
  189. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +4 -1
  190. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +3 -0
  191. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +3 -0
  192. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +3 -0
  193. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +3 -0
  194. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +3 -0
  195. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +3 -0
  196. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +4 -1
  197. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +298 -0
  198. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +3 -0
  199. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +3 -0
  200. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +3 -0
  201. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +3 -0
  202. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +4 -1
  203. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +3 -0
  204. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +3 -0
  205. numba_cuda/numba/cuda/tests/cudapy/test_math.py +3 -0
  206. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +3 -0
  207. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +3 -0
  208. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +3 -0
  209. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +3 -0
  210. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +3 -0
  211. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +3 -0
  212. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +3 -0
  213. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +4 -1
  214. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +3 -0
  215. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +3 -0
  216. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +3 -0
  217. numba_cuda/numba/cuda/tests/cudapy/test_print.py +3 -0
  218. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +3 -0
  219. numba_cuda/numba/cuda/tests/cudapy/test_random.py +3 -0
  220. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +3 -0
  221. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +3 -0
  222. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +3 -0
  223. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +3 -0
  224. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +3 -0
  225. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +3 -0
  226. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +3 -0
  227. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +3 -0
  228. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +3 -0
  229. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +3 -0
  230. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +3 -0
  231. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +4 -1
  232. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +3 -0
  233. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +3 -0
  234. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +3 -0
  235. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +3 -0
  236. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +3 -0
  237. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +3 -0
  238. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +3 -0
  239. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +8 -1
  240. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +3 -0
  241. numba_cuda/numba/cuda/tests/cudasim/__init__.py +3 -0
  242. numba_cuda/numba/cuda/tests/cudasim/support.py +3 -0
  243. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +3 -0
  244. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  245. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +5 -0
  246. numba_cuda/numba/cuda/tests/data/cuda_include.cu +5 -0
  247. numba_cuda/numba/cuda/tests/data/error.cu +5 -0
  248. numba_cuda/numba/cuda/tests/data/include/add.cuh +5 -0
  249. numba_cuda/numba/cuda/tests/data/jitlink.cu +5 -0
  250. numba_cuda/numba/cuda/tests/data/warn.cu +5 -0
  251. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +3 -0
  252. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  253. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +5 -0
  254. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +5 -0
  255. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +5 -0
  256. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +3 -0
  257. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +4 -1
  258. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +4 -1
  259. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +4 -1
  260. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +4 -1
  261. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +4 -1
  262. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +4 -1
  263. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +3 -0
  264. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +4 -1
  265. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +4 -1
  266. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +4 -1
  267. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +4 -1
  268. numba_cuda/numba/cuda/tests/enum_usecases.py +3 -0
  269. numba_cuda/numba/cuda/tests/nocuda/__init__.py +3 -0
  270. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +3 -0
  271. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +3 -0
  272. numba_cuda/numba/cuda/tests/nocuda/test_import.py +4 -1
  273. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +3 -0
  274. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +3 -0
  275. numba_cuda/numba/cuda/tests/nrt/__init__.py +3 -0
  276. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +5 -2
  277. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +4 -1
  278. numba_cuda/numba/cuda/tests/support.py +755 -0
  279. numba_cuda/numba/cuda/tests/test_binary_generation/Makefile +6 -3
  280. numba_cuda/numba/cuda/tests/test_binary_generation/generate_raw_ltoir.py +6 -2
  281. numba_cuda/numba/cuda/tests/test_binary_generation/nrt_extern.cu +5 -0
  282. numba_cuda/numba/cuda/tests/test_binary_generation/test_device_functions.cu +5 -0
  283. numba_cuda/numba/cuda/tests/test_binary_generation/undefined_extern.cu +5 -0
  284. numba_cuda/numba/cuda/types.py +3 -0
  285. numba_cuda/numba/cuda/typing/__init__.py +11 -0
  286. numba_cuda/numba/cuda/typing/templates.py +1448 -0
  287. numba_cuda/numba/cuda/ufuncs.py +3 -0
  288. numba_cuda/numba/cuda/utils.py +3 -0
  289. numba_cuda/numba/cuda/vector_types.py +6 -3
  290. numba_cuda/numba/cuda/vectorizers.py +3 -0
  291. {numba_cuda-0.18.1.dist-info → numba_cuda-0.19.1.dist-info}/METADATA +25 -29
  292. numba_cuda-0.19.1.dist-info/RECORD +302 -0
  293. {numba_cuda-0.18.1.dist-info → numba_cuda-0.19.1.dist-info}/licenses/LICENSE +1 -0
  294. numba_cuda-0.19.1.dist-info/licenses/LICENSE.numba +24 -0
  295. numba_cuda/numba/cuda/include/11/cuda_bf16.h +0 -3749
  296. numba_cuda/numba/cuda/include/11/cuda_bf16.hpp +0 -2683
  297. numba_cuda/numba/cuda/include/11/cuda_fp16.h +0 -3794
  298. numba_cuda/numba/cuda/include/11/cuda_fp16.hpp +0 -2614
  299. numba_cuda-0.18.1.dist-info/RECORD +0 -296
  300. {numba_cuda-0.18.1.dist-info → numba_cuda-0.19.1.dist-info}/WHEEL +0 -0
  301. {numba_cuda-0.18.1.dist-info → numba_cuda-0.19.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,37 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ import cmath
5
+ import contextlib
6
+ import enum
7
+ import gc
8
+ import math
9
+ import unittest
10
+ import os
11
+ import io
12
+ import subprocess
13
+ import sys
14
+ import shutil
15
+ import warnings
16
+ import tempfile
17
+ import time
18
+ import types as pytypes
19
+ from functools import cached_property
20
+
21
+ import numpy as np
22
+
23
+ from numba import types
24
+ from numba.core import errors, config
25
+ from numba.core.typing import cffi_utils
1
26
  from numba.cuda.memory_management.nrt import rtsys
27
+ from numba.core.extending import (
28
+ typeof_impl,
29
+ register_model,
30
+ unbox,
31
+ NativeValue,
32
+ )
33
+ from numba.core.datamodel.models import OpaqueModel
34
+ from numba.np import numpy_support
2
35
 
3
36
 
4
37
  class EnableNRTStatsMixin(object):
@@ -9,3 +42,725 @@ class EnableNRTStatsMixin(object):
9
42
 
10
43
  def tearDown(self):
11
44
  rtsys.memsys_disable_stats()
45
+
46
+
47
+ skip_unless_cffi = unittest.skipUnless(cffi_utils.SUPPORTED, "requires cffi")
48
+
49
+ _lnx_reason = "linux only test"
50
+ linux_only = unittest.skipIf(not sys.platform.startswith("linux"), _lnx_reason)
51
+
52
+ _win_reason = "Windows only test"
53
+ windows_only = unittest.skipIf(not sys.platform.startswith("win"), _win_reason)
54
+
55
+ IS_NUMPY_2 = numpy_support.numpy_version >= (2, 0)
56
+ skip_if_numpy_2 = unittest.skipIf(IS_NUMPY_2, "Not supported on numpy 2.0+")
57
+
58
+ _trashcan_dir = "numba-cuda-tests"
59
+
60
+ if os.name == "nt":
61
+ # Under Windows, gettempdir() points to the user-local temp dir
62
+ _trashcan_dir = os.path.join(tempfile.gettempdir(), _trashcan_dir)
63
+ else:
64
+ # Mix the UID into the directory name to allow different users to
65
+ # run the test suite without permission errors (issue #1586)
66
+ _trashcan_dir = os.path.join(
67
+ tempfile.gettempdir(), "%s.%s" % (_trashcan_dir, os.getuid())
68
+ )
69
+
70
+ # Stale temporary directories are deleted after they are older than this value.
71
+ # The test suite probably won't ever take longer than this...
72
+ _trashcan_timeout = 24 * 3600 # 1 day
73
+
74
+
75
+ def _create_trashcan_dir():
76
+ try:
77
+ os.mkdir(_trashcan_dir)
78
+ except FileExistsError:
79
+ pass
80
+
81
+
82
+ def _purge_trashcan_dir():
83
+ freshness_threshold = time.time() - _trashcan_timeout
84
+ for fn in sorted(os.listdir(_trashcan_dir)):
85
+ fn = os.path.join(_trashcan_dir, fn)
86
+ try:
87
+ st = os.stat(fn)
88
+ if st.st_mtime < freshness_threshold:
89
+ shutil.rmtree(fn, ignore_errors=True)
90
+ except OSError:
91
+ # In parallel testing, several processes can attempt to
92
+ # remove the same entry at once, ignore.
93
+ pass
94
+
95
+
96
+ def _create_trashcan_subdir(prefix):
97
+ _purge_trashcan_dir()
98
+ path = tempfile.mkdtemp(prefix=prefix + "-", dir=_trashcan_dir)
99
+ return path
100
+
101
+
102
+ def temp_directory(prefix):
103
+ """
104
+ Create a temporary directory with the given *prefix* that will survive
105
+ at least as long as this process invocation. The temporary directory
106
+ will be eventually deleted when it becomes stale enough.
107
+
108
+ This is necessary because a DLL file can't be deleted while in use
109
+ under Windows.
110
+
111
+ An interesting side-effect is to be able to inspect the test files
112
+ shortly after a test suite run.
113
+ """
114
+ _create_trashcan_dir()
115
+ return _create_trashcan_subdir(prefix)
116
+
117
+
118
+ def import_dynamic(modname):
119
+ """
120
+ Import and return a module of the given name. Care is taken to
121
+ avoid issues due to Python's internal directory caching.
122
+ """
123
+ import importlib
124
+
125
+ importlib.invalidate_caches()
126
+ __import__(modname)
127
+ return sys.modules[modname]
128
+
129
+
130
+ def ignore_internal_warnings():
131
+ """Use in testing within a ` warnings.catch_warnings` block to filter out
132
+ warnings that are unrelated/internally generated by Numba.
133
+ """
134
+ # Filter out warnings from typeguard
135
+ warnings.filterwarnings("ignore", module="typeguard")
136
+ # Filter out warnings about TBB interface mismatch
137
+ warnings.filterwarnings(
138
+ action="ignore",
139
+ message=r".*TBB_INTERFACE_VERSION.*",
140
+ category=errors.NumbaWarning,
141
+ module=r"numba\.np\.ufunc\.parallel.*",
142
+ )
143
+
144
+
145
+ @contextlib.contextmanager
146
+ def override_config(name, value):
147
+ """
148
+ Return a context manager that temporarily sets Numba config variable
149
+ *name* to *value*. *name* must be the name of an existing variable
150
+ in numba.config.
151
+ """
152
+ old_value = getattr(config, name)
153
+ setattr(config, name, value)
154
+ try:
155
+ yield
156
+ finally:
157
+ setattr(config, name, old_value)
158
+
159
+
160
+ def run_in_subprocess(code, flags=None, env=None, timeout=30):
161
+ """Run a snippet of Python code in a subprocess with flags, if any are
162
+ given. 'env' is passed to subprocess.Popen(). 'timeout' is passed to
163
+ popen.communicate().
164
+
165
+ Returns the stdout and stderr of the subprocess after its termination.
166
+ """
167
+ if flags is None:
168
+ flags = []
169
+ cmd = (
170
+ [
171
+ sys.executable,
172
+ ]
173
+ + flags
174
+ + ["-c", code]
175
+ )
176
+ popen = subprocess.Popen(
177
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env
178
+ )
179
+ out, err = popen.communicate(timeout=timeout)
180
+ if popen.returncode != 0:
181
+ msg = "process failed with code %s: stderr follows\n%s\n"
182
+ raise AssertionError(msg % (popen.returncode, err.decode()))
183
+ return out, err
184
+
185
+
186
+ @contextlib.contextmanager
187
+ def captured_output(stream_name):
188
+ """Return a context manager used by captured_stdout/stdin/stderr
189
+ that temporarily replaces the sys stream *stream_name* with a StringIO."""
190
+ orig_stdout = getattr(sys, stream_name)
191
+ setattr(sys, stream_name, io.StringIO())
192
+ try:
193
+ yield getattr(sys, stream_name)
194
+ finally:
195
+ setattr(sys, stream_name, orig_stdout)
196
+
197
+
198
+ def captured_stdout():
199
+ """Capture the output of sys.stdout:
200
+
201
+ with captured_stdout() as stdout:
202
+ print("hello")
203
+ self.assertEqual(stdout.getvalue(), "hello\n")
204
+ """
205
+ return captured_output("stdout")
206
+
207
+
208
+ def captured_stderr():
209
+ """Capture the output of sys.stderr:
210
+
211
+ with captured_stderr() as stderr:
212
+ print("hello", file=sys.stderr)
213
+ self.assertEqual(stderr.getvalue(), "hello\n")
214
+ """
215
+ return captured_output("stderr")
216
+
217
+
218
+ class TestCase(unittest.TestCase):
219
+ longMessage = True
220
+
221
+ # A random state yielding the same random numbers for any test case.
222
+ # Use as `self.random.<method name>`
223
+ @cached_property
224
+ def random(self):
225
+ return np.random.RandomState(42)
226
+
227
+ def reset_module_warnings(self, module):
228
+ """
229
+ Reset the warnings registry of a module. This can be necessary
230
+ as the warnings module is buggy in that regard.
231
+ See http://bugs.python.org/issue4180
232
+ """
233
+ if isinstance(module, str):
234
+ module = sys.modules[module]
235
+ try:
236
+ del module.__warningregistry__
237
+ except AttributeError:
238
+ pass
239
+
240
+ @contextlib.contextmanager
241
+ def assertTypingError(self):
242
+ """
243
+ A context manager that asserts the enclosed code block fails
244
+ compiling in nopython mode.
245
+ """
246
+ _accepted_errors = (
247
+ errors.LoweringError,
248
+ errors.TypingError,
249
+ TypeError,
250
+ NotImplementedError,
251
+ )
252
+ with self.assertRaises(_accepted_errors) as cm:
253
+ yield cm
254
+
255
+ @contextlib.contextmanager
256
+ def assertRefCount(self, *objects):
257
+ """
258
+ A context manager that asserts the given objects have the
259
+ same reference counts before and after executing the
260
+ enclosed block.
261
+ """
262
+ old_refcounts = [sys.getrefcount(x) for x in objects]
263
+ yield
264
+ gc.collect()
265
+ new_refcounts = [sys.getrefcount(x) for x in objects]
266
+ for old, new, obj in zip(old_refcounts, new_refcounts, objects):
267
+ if old != new:
268
+ self.fail(
269
+ "Refcount changed from %d to %d for object: %r"
270
+ % (old, new, obj)
271
+ )
272
+
273
+ def assertRefCountEqual(self, *objects):
274
+ gc.collect()
275
+ rc = [sys.getrefcount(x) for x in objects]
276
+ rc_0 = rc[0]
277
+ for i in range(len(objects))[1:]:
278
+ rc_i = rc[i]
279
+ if rc_0 != rc_i:
280
+ self.fail(
281
+ f"Refcount for objects does not match. "
282
+ f"#0({rc_0}) != #{i}({rc_i}) does not match."
283
+ )
284
+
285
+ @contextlib.contextmanager
286
+ def assertNoNRTLeak(self):
287
+ """
288
+ A context manager that asserts no NRT leak was created during
289
+ the execution of the enclosed block.
290
+ """
291
+ old = rtsys.get_allocation_stats()
292
+ yield
293
+ new = rtsys.get_allocation_stats()
294
+ total_alloc = new.alloc - old.alloc
295
+ total_free = new.free - old.free
296
+ total_mi_alloc = new.mi_alloc - old.mi_alloc
297
+ total_mi_free = new.mi_free - old.mi_free
298
+ self.assertEqual(
299
+ total_alloc,
300
+ total_free,
301
+ "number of data allocs != number of data frees",
302
+ )
303
+ self.assertEqual(
304
+ total_mi_alloc,
305
+ total_mi_free,
306
+ "number of meminfo allocs != number of meminfo frees",
307
+ )
308
+
309
+ _bool_types = (bool, np.bool_)
310
+ _exact_typesets = [
311
+ _bool_types,
312
+ (int,),
313
+ (str,),
314
+ (np.integer,),
315
+ (bytes, np.bytes_),
316
+ ]
317
+ _approx_typesets = [(float,), (complex,), (np.inexact)]
318
+ _sequence_typesets = [(tuple, list)]
319
+ _float_types = (float, np.floating)
320
+ _complex_types = (complex, np.complexfloating)
321
+
322
+ def _detect_family(self, numeric_object):
323
+ """
324
+ This function returns a string description of the type family
325
+ that the object in question belongs to. Possible return values
326
+ are: "exact", "complex", "approximate", "sequence", and "unknown"
327
+ """
328
+ if isinstance(numeric_object, np.ndarray):
329
+ return "ndarray"
330
+
331
+ if isinstance(numeric_object, enum.Enum):
332
+ return "enum"
333
+
334
+ for tp in self._sequence_typesets:
335
+ if isinstance(numeric_object, tp):
336
+ return "sequence"
337
+
338
+ for tp in self._exact_typesets:
339
+ if isinstance(numeric_object, tp):
340
+ return "exact"
341
+
342
+ for tp in self._complex_types:
343
+ if isinstance(numeric_object, tp):
344
+ return "complex"
345
+
346
+ for tp in self._approx_typesets:
347
+ if isinstance(numeric_object, tp):
348
+ return "approximate"
349
+
350
+ return "unknown"
351
+
352
+ def _fix_dtype(self, dtype):
353
+ """
354
+ Fix the given *dtype* for comparison.
355
+ """
356
+ # Under 64-bit Windows, Numpy may return either int32 or int64
357
+ # arrays depending on the function.
358
+ if (
359
+ sys.platform == "win32"
360
+ and sys.maxsize > 2**32
361
+ and dtype == np.dtype("int32")
362
+ ):
363
+ return np.dtype("int64")
364
+ else:
365
+ return dtype
366
+
367
+ def _fix_strides(self, arr):
368
+ """
369
+ Return the strides of the given array, fixed for comparison.
370
+ Strides for 0- or 1-sized dimensions are ignored.
371
+ """
372
+ if arr.size == 0:
373
+ return [0] * arr.ndim
374
+ else:
375
+ return [
376
+ stride / arr.itemsize
377
+ for (stride, shape) in zip(arr.strides, arr.shape)
378
+ if shape > 1
379
+ ]
380
+
381
+ def assertStridesEqual(self, first, second):
382
+ """
383
+ Test that two arrays have the same shape and strides.
384
+ """
385
+ self.assertEqual(first.shape, second.shape, "shapes differ")
386
+ self.assertEqual(first.itemsize, second.itemsize, "itemsizes differ")
387
+ self.assertEqual(
388
+ self._fix_strides(first),
389
+ self._fix_strides(second),
390
+ "strides differ",
391
+ )
392
+
393
+ def assertPreciseEqual(
394
+ self,
395
+ first,
396
+ second,
397
+ prec="exact",
398
+ ulps=1,
399
+ msg=None,
400
+ ignore_sign_on_zero=False,
401
+ abs_tol=None,
402
+ ):
403
+ """
404
+ Versatile equality testing function with more built-in checks than
405
+ standard assertEqual().
406
+
407
+ For arrays, test that layout, dtype, shape are identical, and
408
+ recursively call assertPreciseEqual() on the contents.
409
+
410
+ For other sequences, recursively call assertPreciseEqual() on
411
+ the contents.
412
+
413
+ For scalars, test that two scalars or have similar types and are
414
+ equal up to a computed precision.
415
+ If the scalars are instances of exact types or if *prec* is
416
+ 'exact', they are compared exactly.
417
+ If the scalars are instances of inexact types (float, complex)
418
+ and *prec* is not 'exact', then the number of significant bits
419
+ is computed according to the value of *prec*: 53 bits if *prec*
420
+ is 'double', 24 bits if *prec* is single. This number of bits
421
+ can be lowered by raising the *ulps* value.
422
+ ignore_sign_on_zero can be set to True if zeros are to be considered
423
+ equal regardless of their sign bit.
424
+ abs_tol if this is set to a float value its value is used in the
425
+ following. If, however, this is set to the string "eps" then machine
426
+ precision of the type(first) is used in the following instead. This
427
+ kwarg is used to check if the absolute difference in value between first
428
+ and second is less than the value set, if so the numbers being compared
429
+ are considered equal. (This is to handle small numbers typically of
430
+ magnitude less than machine precision).
431
+
432
+ Any value of *prec* other than 'exact', 'single' or 'double'
433
+ will raise an error.
434
+ """
435
+ try:
436
+ self._assertPreciseEqual(
437
+ first, second, prec, ulps, msg, ignore_sign_on_zero, abs_tol
438
+ )
439
+ except AssertionError as exc:
440
+ failure_msg = str(exc)
441
+ # Fall off of the 'except' scope to avoid Python 3 exception
442
+ # chaining.
443
+ else:
444
+ return
445
+ # Decorate the failure message with more information
446
+ self.fail("when comparing %s and %s: %s" % (first, second, failure_msg))
447
+
448
+ def _assertPreciseEqual(
449
+ self,
450
+ first,
451
+ second,
452
+ prec="exact",
453
+ ulps=1,
454
+ msg=None,
455
+ ignore_sign_on_zero=False,
456
+ abs_tol=None,
457
+ ):
458
+ """Recursive workhorse for assertPreciseEqual()."""
459
+
460
+ def _assertNumberEqual(first, second, delta=None):
461
+ if (
462
+ delta is None
463
+ or first == second == 0.0
464
+ or math.isinf(first)
465
+ or math.isinf(second)
466
+ ):
467
+ self.assertEqual(first, second, msg=msg)
468
+ # For signed zeros
469
+ if not ignore_sign_on_zero:
470
+ try:
471
+ if math.copysign(1, first) != math.copysign(1, second):
472
+ self.fail(
473
+ self._formatMessage(
474
+ msg, "%s != %s" % (first, second)
475
+ )
476
+ )
477
+ except TypeError:
478
+ pass
479
+ else:
480
+ self.assertAlmostEqual(first, second, delta=delta, msg=msg)
481
+
482
+ first_family = self._detect_family(first)
483
+ second_family = self._detect_family(second)
484
+
485
+ assertion_message = "Type Family mismatch. (%s != %s)" % (
486
+ first_family,
487
+ second_family,
488
+ )
489
+ if msg:
490
+ assertion_message += ": %s" % (msg,)
491
+ self.assertEqual(first_family, second_family, msg=assertion_message)
492
+
493
+ # We now know they are in the same comparison family
494
+ compare_family = first_family
495
+
496
+ # For recognized sequences, recurse
497
+ if compare_family == "ndarray":
498
+ dtype = self._fix_dtype(first.dtype)
499
+ self.assertEqual(dtype, self._fix_dtype(second.dtype))
500
+ self.assertEqual(
501
+ first.ndim, second.ndim, "different number of dimensions"
502
+ )
503
+ self.assertEqual(first.shape, second.shape, "different shapes")
504
+ self.assertEqual(
505
+ first.flags.writeable,
506
+ second.flags.writeable,
507
+ "different mutability",
508
+ )
509
+ # itemsize is already checked by the dtype test above
510
+ self.assertEqual(
511
+ self._fix_strides(first),
512
+ self._fix_strides(second),
513
+ "different strides",
514
+ )
515
+ if first.dtype != dtype:
516
+ first = first.astype(dtype)
517
+ if second.dtype != dtype:
518
+ second = second.astype(dtype)
519
+ for a, b in zip(first.flat, second.flat):
520
+ self._assertPreciseEqual(
521
+ a, b, prec, ulps, msg, ignore_sign_on_zero, abs_tol
522
+ )
523
+ return
524
+
525
+ elif compare_family == "sequence":
526
+ self.assertEqual(len(first), len(second), msg=msg)
527
+ for a, b in zip(first, second):
528
+ self._assertPreciseEqual(
529
+ a, b, prec, ulps, msg, ignore_sign_on_zero, abs_tol
530
+ )
531
+ return
532
+
533
+ elif compare_family == "exact":
534
+ exact_comparison = True
535
+
536
+ elif compare_family in ["complex", "approximate"]:
537
+ exact_comparison = False
538
+
539
+ elif compare_family == "enum":
540
+ self.assertIs(first.__class__, second.__class__)
541
+ self._assertPreciseEqual(
542
+ first.value,
543
+ second.value,
544
+ prec,
545
+ ulps,
546
+ msg,
547
+ ignore_sign_on_zero,
548
+ abs_tol,
549
+ )
550
+ return
551
+
552
+ elif compare_family == "unknown":
553
+ # Assume these are non-numeric types: we will fall back
554
+ # on regular unittest comparison.
555
+ self.assertIs(first.__class__, second.__class__)
556
+ exact_comparison = True
557
+
558
+ else:
559
+ assert 0, "unexpected family"
560
+
561
+ # If a Numpy scalar, check the dtype is exactly the same too
562
+ # (required for datetime64 and timedelta64).
563
+ if hasattr(first, "dtype") and hasattr(second, "dtype"):
564
+ self.assertEqual(first.dtype, second.dtype)
565
+
566
+ # Mixing bools and non-bools should always fail
567
+ if isinstance(first, self._bool_types) != isinstance(
568
+ second, self._bool_types
569
+ ):
570
+ assertion_message = "Mismatching return types (%s vs. %s)" % (
571
+ first.__class__,
572
+ second.__class__,
573
+ )
574
+ if msg:
575
+ assertion_message += ": %s" % (msg,)
576
+ self.fail(assertion_message)
577
+
578
+ try:
579
+ if cmath.isnan(first) and cmath.isnan(second):
580
+ # The NaNs will compare unequal, skip regular comparison
581
+ return
582
+ except TypeError:
583
+ # Not floats.
584
+ pass
585
+
586
+ # if absolute comparison is set, use it
587
+ if abs_tol is not None:
588
+ if abs_tol == "eps":
589
+ rtol = np.finfo(type(first)).eps
590
+ elif isinstance(abs_tol, float):
591
+ rtol = abs_tol
592
+ else:
593
+ raise ValueError(
594
+ 'abs_tol is not "eps" or a float, found %s' % abs_tol
595
+ )
596
+ if abs(first - second) < rtol:
597
+ return
598
+
599
+ exact_comparison = exact_comparison or prec == "exact"
600
+
601
+ if not exact_comparison and prec != "exact":
602
+ if prec == "single":
603
+ bits = 24
604
+ elif prec == "double":
605
+ bits = 53
606
+ else:
607
+ raise ValueError("unsupported precision %r" % (prec,))
608
+ k = 2 ** (ulps - bits - 1)
609
+ delta = k * (abs(first) + abs(second))
610
+ else:
611
+ delta = None
612
+ if isinstance(first, self._complex_types):
613
+ _assertNumberEqual(first.real, second.real, delta)
614
+ _assertNumberEqual(first.imag, second.imag, delta)
615
+ elif isinstance(first, (np.timedelta64, np.datetime64)):
616
+ # Since Np 1.16 NaT == NaT is False, so special comparison needed
617
+ if np.isnat(first):
618
+ self.assertEqual(np.isnat(first), np.isnat(second))
619
+ else:
620
+ _assertNumberEqual(first, second, delta)
621
+ else:
622
+ _assertNumberEqual(first, second, delta)
623
+
624
+ def subprocess_test_runner(
625
+ self,
626
+ test_module,
627
+ test_class=None,
628
+ test_name=None,
629
+ envvars=None,
630
+ timeout=60,
631
+ flags=None,
632
+ _subproc_test_env="1",
633
+ ):
634
+ """
635
+ Runs named unit test(s) as specified in the arguments as:
636
+ test_module.test_class.test_name. test_module must always be supplied
637
+ and if no further refinement is made with test_class and test_name then
638
+ all tests in the module will be run. The tests will be run in a
639
+ subprocess with environment variables specified in `envvars`.
640
+ If given, envvars must be a map of form:
641
+ environment variable name (str) -> value (str)
642
+ If given, flags must be a map of form:
643
+ flag including the `-` (str) -> value (str)
644
+ It is most convenient to use this method in conjunction with
645
+ @needs_subprocess as the decorator will cause the decorated test to be
646
+ skipped unless the `SUBPROC_TEST` environment variable is set to
647
+ the same value of ``_subproc_test_env``
648
+ (this special environment variable is set by this method such that the
649
+ specified test(s) will not be skipped in the subprocess).
650
+
651
+
652
+ Following execution in the subprocess this method will check the test(s)
653
+ executed without error. The timeout kwarg can be used to allow more time
654
+ for longer running tests, it defaults to 60 seconds.
655
+ """
656
+ parts = (test_module, test_class, test_name)
657
+ fully_qualified_test = ".".join(x for x in parts if x is not None)
658
+ flags_args = []
659
+ if flags is not None:
660
+ for flag, value in flags.items():
661
+ flags_args.append(f"{flag}")
662
+ flags_args.append(f"{value}")
663
+ cmd = [
664
+ sys.executable,
665
+ *flags_args,
666
+ "-m",
667
+ "numba.runtests",
668
+ fully_qualified_test,
669
+ ]
670
+ env_copy = os.environ.copy()
671
+ env_copy["SUBPROC_TEST"] = _subproc_test_env
672
+ try:
673
+ env_copy["COVERAGE_PROCESS_START"] = os.environ["COVERAGE_RCFILE"]
674
+ except KeyError:
675
+ pass # ignored
676
+ envvars = pytypes.MappingProxyType({} if envvars is None else envvars)
677
+ env_copy.update(envvars)
678
+ status = subprocess.run(
679
+ cmd,
680
+ stdout=subprocess.PIPE,
681
+ stderr=subprocess.PIPE,
682
+ timeout=timeout,
683
+ env=env_copy,
684
+ universal_newlines=True,
685
+ )
686
+ streams = (
687
+ f"\ncaptured stdout: {status.stdout}\n"
688
+ f"captured stderr: {status.stderr}"
689
+ )
690
+ self.assertEqual(status.returncode, 0, streams)
691
+ # Python 3.12.1 report
692
+ no_tests_ran = "NO TESTS RAN"
693
+ if no_tests_ran in status.stderr:
694
+ self.skipTest(no_tests_ran)
695
+ else:
696
+ self.assertIn("OK", status.stderr)
697
+ return status
698
+
699
+ def run_test_in_subprocess(maybefunc=None, timeout=60, envvars=None):
700
+ """Runs the decorated test in a subprocess via invoking numba's test
701
+ runner. kwargs timeout and envvars are passed through to
702
+ subprocess_test_runner."""
703
+
704
+ def wrapper(func):
705
+ def inner(self, *args, **kwargs):
706
+ if os.environ.get("SUBPROC_TEST", None) != func.__name__:
707
+ # Not in a subprocess test env, so stage the call to run the
708
+ # test in a subprocess which will set the env var.
709
+ class_name = self.__class__.__name__
710
+ self.subprocess_test_runner(
711
+ test_module=self.__module__,
712
+ test_class=class_name,
713
+ test_name=func.__name__,
714
+ timeout=timeout,
715
+ envvars=envvars,
716
+ _subproc_test_env=func.__name__,
717
+ )
718
+ else:
719
+ # env var is set, so we're in the subprocess, run the
720
+ # actual test.
721
+ func(self)
722
+
723
+ return inner
724
+
725
+ if isinstance(maybefunc, pytypes.FunctionType):
726
+ return wrapper(maybefunc)
727
+ else:
728
+ return wrapper
729
+
730
+ def make_dummy_type(self):
731
+ """Use to generate a dummy type unique to this test. Returns a python
732
+ Dummy class and a corresponding Numba type DummyType."""
733
+
734
+ # Use test_id to make sure no collision is possible.
735
+ test_id = self.id()
736
+ DummyType = type("DummyTypeFor{}".format(test_id), (types.Opaque,), {})
737
+
738
+ dummy_type = DummyType("my_dummy")
739
+ register_model(DummyType)(OpaqueModel)
740
+
741
+ class Dummy(object):
742
+ pass
743
+
744
+ @typeof_impl.register(Dummy)
745
+ def typeof_dummy(val, c):
746
+ return dummy_type
747
+
748
+ @unbox(DummyType)
749
+ def unbox_dummy(typ, obj, c):
750
+ return NativeValue(c.context.get_dummy_value())
751
+
752
+ return Dummy, DummyType
753
+
754
+ def skip_if_no_external_compiler(self):
755
+ """
756
+ Call this to ensure the test is skipped if no suitable external compiler
757
+ is found. This is a method on the TestCase opposed to a stand-alone
758
+ decorator so as to make it "lazy" via runtime evaluation opposed to
759
+ running at test-discovery time.
760
+ """
761
+ # This is a local import to avoid deprecation warnings being generated
762
+ # through the use of the numba.pycc module.
763
+ from numba.pycc.platform import external_compiler_works
764
+
765
+ if not external_compiler_works():
766
+ self.skipTest("No suitable external compiler was found.")