numba-cuda 0.21.1__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. _numba_cuda_redirector.pth +4 -0
  2. _numba_cuda_redirector.py +89 -0
  3. numba_cuda/VERSION +1 -0
  4. numba_cuda/__init__.py +6 -0
  5. numba_cuda/_version.py +11 -0
  6. numba_cuda/numba/cuda/__init__.py +70 -0
  7. numba_cuda/numba/cuda/_internal/cuda_bf16.py +16394 -0
  8. numba_cuda/numba/cuda/_internal/cuda_fp16.py +8112 -0
  9. numba_cuda/numba/cuda/api.py +577 -0
  10. numba_cuda/numba/cuda/api_util.py +76 -0
  11. numba_cuda/numba/cuda/args.py +72 -0
  12. numba_cuda/numba/cuda/bf16.py +397 -0
  13. numba_cuda/numba/cuda/cache_hints.py +287 -0
  14. numba_cuda/numba/cuda/cext/__init__.py +2 -0
  15. numba_cuda/numba/cuda/cext/_devicearray.cp313-win_amd64.pyd +0 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cp313-win_amd64.pyd +0 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
  20. numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
  21. numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
  22. numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
  23. numba_cuda/numba/cuda/cext/_helperlib.cp313-win_amd64.pyd +0 -0
  24. numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
  25. numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
  26. numba_cuda/numba/cuda/cext/_typeconv.cp313-win_amd64.pyd +0 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
  28. numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
  29. numba_cuda/numba/cuda/cext/_typeof.h +19 -0
  30. numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
  31. numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
  32. numba_cuda/numba/cuda/cext/mviewbuf.cp313-win_amd64.pyd +0 -0
  33. numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
  34. numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
  35. numba_cuda/numba/cuda/cg.py +67 -0
  36. numba_cuda/numba/cuda/cgutils.py +1294 -0
  37. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  38. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  39. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  40. numba_cuda/numba/cuda/codegen.py +541 -0
  41. numba_cuda/numba/cuda/compiler.py +1396 -0
  42. numba_cuda/numba/cuda/core/analysis.py +758 -0
  43. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  44. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
  45. numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
  46. numba_cuda/numba/cuda/core/base.py +1332 -0
  47. numba_cuda/numba/cuda/core/boxing.py +1411 -0
  48. numba_cuda/numba/cuda/core/bytecode.py +728 -0
  49. numba_cuda/numba/cuda/core/byteflow.py +2346 -0
  50. numba_cuda/numba/cuda/core/caching.py +744 -0
  51. numba_cuda/numba/cuda/core/callconv.py +392 -0
  52. numba_cuda/numba/cuda/core/codegen.py +171 -0
  53. numba_cuda/numba/cuda/core/compiler.py +199 -0
  54. numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
  55. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  56. numba_cuda/numba/cuda/core/config.py +650 -0
  57. numba_cuda/numba/cuda/core/consts.py +124 -0
  58. numba_cuda/numba/cuda/core/controlflow.py +989 -0
  59. numba_cuda/numba/cuda/core/entrypoints.py +57 -0
  60. numba_cuda/numba/cuda/core/environment.py +66 -0
  61. numba_cuda/numba/cuda/core/errors.py +917 -0
  62. numba_cuda/numba/cuda/core/event.py +511 -0
  63. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  64. numba_cuda/numba/cuda/core/generators.py +387 -0
  65. numba_cuda/numba/cuda/core/imputils.py +509 -0
  66. numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
  67. numba_cuda/numba/cuda/core/interpreter.py +3617 -0
  68. numba_cuda/numba/cuda/core/ir.py +1812 -0
  69. numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
  70. numba_cuda/numba/cuda/core/optional.py +129 -0
  71. numba_cuda/numba/cuda/core/options.py +262 -0
  72. numba_cuda/numba/cuda/core/postproc.py +249 -0
  73. numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
  74. numba_cuda/numba/cuda/core/registry.py +46 -0
  75. numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
  76. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  77. numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
  78. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  79. numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
  80. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
  81. numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
  82. numba_cuda/numba/cuda/core/sigutils.py +68 -0
  83. numba_cuda/numba/cuda/core/ssa.py +498 -0
  84. numba_cuda/numba/cuda/core/targetconfig.py +330 -0
  85. numba_cuda/numba/cuda/core/tracing.py +231 -0
  86. numba_cuda/numba/cuda/core/transforms.py +956 -0
  87. numba_cuda/numba/cuda/core/typed_passes.py +867 -0
  88. numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
  89. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  90. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  91. numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
  92. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  93. numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
  94. numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
  95. numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
  96. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  97. numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
  98. numba_cuda/numba/cuda/cpython/iterators.py +167 -0
  99. numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
  100. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  101. numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
  102. numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
  103. numba_cuda/numba/cuda/cpython/slicing.py +322 -0
  104. numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
  105. numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
  106. numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
  107. numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
  108. numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
  109. numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
  110. numba_cuda/numba/cuda/cuda_paths.py +691 -0
  111. numba_cuda/numba/cuda/cudadecl.py +556 -0
  112. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  113. numba_cuda/numba/cuda/cudadrv/devicearray.py +951 -0
  114. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  115. numba_cuda/numba/cuda/cudadrv/driver.py +3222 -0
  116. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  117. numba_cuda/numba/cuda/cudadrv/dummyarray.py +558 -0
  118. numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
  119. numba_cuda/numba/cuda/cudadrv/error.py +48 -0
  120. numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
  121. numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
  122. numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
  123. numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
  124. numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
  125. numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
  126. numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
  127. numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
  128. numba_cuda/numba/cuda/cudaimpl.py +995 -0
  129. numba_cuda/numba/cuda/cudamath.py +149 -0
  130. numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
  131. numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
  132. numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
  133. numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
  134. numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
  135. numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
  136. numba_cuda/numba/cuda/datamodel/manager.py +11 -0
  137. numba_cuda/numba/cuda/datamodel/models.py +9 -0
  138. numba_cuda/numba/cuda/datamodel/packer.py +9 -0
  139. numba_cuda/numba/cuda/datamodel/registry.py +11 -0
  140. numba_cuda/numba/cuda/datamodel/testing.py +11 -0
  141. numba_cuda/numba/cuda/debuginfo.py +903 -0
  142. numba_cuda/numba/cuda/decorators.py +294 -0
  143. numba_cuda/numba/cuda/descriptor.py +35 -0
  144. numba_cuda/numba/cuda/device_init.py +158 -0
  145. numba_cuda/numba/cuda/deviceufunc.py +1021 -0
  146. numba_cuda/numba/cuda/dispatcher.py +2463 -0
  147. numba_cuda/numba/cuda/errors.py +72 -0
  148. numba_cuda/numba/cuda/extending.py +697 -0
  149. numba_cuda/numba/cuda/flags.py +178 -0
  150. numba_cuda/numba/cuda/fp16.py +357 -0
  151. numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
  152. numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
  153. numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
  154. numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
  155. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  156. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  157. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  158. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  159. numba_cuda/numba/cuda/initialize.py +24 -0
  160. numba_cuda/numba/cuda/intrinsic_wrapper.py +41 -0
  161. numba_cuda/numba/cuda/intrinsics.py +382 -0
  162. numba_cuda/numba/cuda/itanium_mangler.py +214 -0
  163. numba_cuda/numba/cuda/kernels/__init__.py +2 -0
  164. numba_cuda/numba/cuda/kernels/reduction.py +265 -0
  165. numba_cuda/numba/cuda/kernels/transpose.py +65 -0
  166. numba_cuda/numba/cuda/libdevice.py +3386 -0
  167. numba_cuda/numba/cuda/libdevicedecl.py +20 -0
  168. numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
  169. numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
  170. numba_cuda/numba/cuda/locks.py +19 -0
  171. numba_cuda/numba/cuda/lowering.py +1951 -0
  172. numba_cuda/numba/cuda/mathimpl.py +374 -0
  173. numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
  174. numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
  175. numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
  176. numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
  177. numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
  178. numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
  179. numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
  180. numba_cuda/numba/cuda/misc/appdirs.py +594 -0
  181. numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
  182. numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
  183. numba_cuda/numba/cuda/misc/dump_style.py +41 -0
  184. numba_cuda/numba/cuda/misc/findlib.py +75 -0
  185. numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
  186. numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
  187. numba_cuda/numba/cuda/misc/literal.py +28 -0
  188. numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
  189. numba_cuda/numba/cuda/misc/special.py +94 -0
  190. numba_cuda/numba/cuda/models.py +56 -0
  191. numba_cuda/numba/cuda/np/arraymath.py +5130 -0
  192. numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
  193. numba_cuda/numba/cuda/np/extensions.py +11 -0
  194. numba_cuda/numba/cuda/np/linalg.py +3087 -0
  195. numba_cuda/numba/cuda/np/math/__init__.py +0 -0
  196. numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
  197. numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
  198. numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
  199. numba_cuda/numba/cuda/np/npdatetime.py +969 -0
  200. numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
  201. numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
  202. numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
  203. numba_cuda/numba/cuda/np/numpy_support.py +798 -0
  204. numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
  205. numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
  206. numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
  207. numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
  208. numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
  209. numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
  210. numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
  211. numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
  212. numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
  213. numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
  214. numba_cuda/numba/cuda/nvvmutils.py +254 -0
  215. numba_cuda/numba/cuda/printimpl.py +126 -0
  216. numba_cuda/numba/cuda/random.py +308 -0
  217. numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
  218. numba_cuda/numba/cuda/serialize.py +267 -0
  219. numba_cuda/numba/cuda/simulator/__init__.py +63 -0
  220. numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
  221. numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
  222. numba_cuda/numba/cuda/simulator/api.py +179 -0
  223. numba_cuda/numba/cuda/simulator/bf16.py +4 -0
  224. numba_cuda/numba/cuda/simulator/compiler.py +38 -0
  225. numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
  226. numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
  227. numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
  228. numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
  229. numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
  230. numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
  231. numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
  232. numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
  233. numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
  234. numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
  235. numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
  236. numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
  237. numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
  238. numba_cuda/numba/cuda/simulator/kernel.py +320 -0
  239. numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
  240. numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
  241. numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
  242. numba_cuda/numba/cuda/simulator/reduction.py +19 -0
  243. numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
  244. numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
  245. numba_cuda/numba/cuda/simulator_init.py +18 -0
  246. numba_cuda/numba/cuda/stubs.py +635 -0
  247. numba_cuda/numba/cuda/target.py +505 -0
  248. numba_cuda/numba/cuda/testing.py +347 -0
  249. numba_cuda/numba/cuda/tests/__init__.py +62 -0
  250. numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
  251. numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
  252. numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
  253. numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
  254. numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
  255. numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
  256. numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
  257. numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
  258. numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
  259. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
  260. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
  261. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
  262. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +313 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +187 -0
  264. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
  265. numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
  266. numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
  267. numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +198 -0
  268. numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
  269. numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
  270. numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
  271. numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
  272. numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
  273. numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
  274. numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
  275. numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
  276. numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
  277. numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
  278. numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
  279. numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
  280. numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
  281. numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
  282. numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
  283. numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
  284. numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
  285. numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
  286. numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
  287. numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
  288. numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
  289. numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
  290. numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
  291. numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
  292. numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
  293. numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
  294. numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
  295. numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
  296. numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
  297. numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
  298. numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
  299. numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
  300. numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
  301. numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
  302. numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
  303. numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
  304. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
  305. numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
  306. numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
  307. numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
  308. numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
  309. numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
  310. numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
  311. numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
  312. numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
  313. numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
  314. numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
  315. numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
  316. numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
  317. numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
  318. numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
  319. numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
  320. numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
  321. numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
  322. numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
  323. numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
  324. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +889 -0
  325. numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
  326. numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
  327. numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
  328. numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
  329. numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
  330. numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
  331. numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
  332. numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
  333. numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
  334. numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
  335. numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
  336. numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
  337. numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
  338. numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
  339. numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
  340. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
  341. numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
  342. numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
  343. numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
  344. numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
  345. numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
  346. numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
  347. numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
  348. numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
  349. numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
  350. numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
  351. numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
  352. numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
  353. numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
  354. numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
  355. numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
  356. numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
  357. numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
  358. numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
  359. numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
  360. numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
  361. numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
  362. numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
  363. numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
  364. numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
  365. numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
  366. numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
  367. numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
  368. numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
  369. numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
  370. numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
  371. numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
  372. numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
  373. numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
  374. numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
  375. numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
  376. numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
  377. numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
  378. numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
  379. numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
  380. numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
  381. numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
  382. numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
  383. numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
  384. numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
  385. numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
  386. numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
  387. numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
  388. numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
  389. numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
  390. numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
  391. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
  392. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
  393. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
  394. numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
  395. numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
  396. numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +331 -0
  397. numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
  398. numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
  399. numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
  400. numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
  401. numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
  402. numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
  403. numba_cuda/numba/cuda/tests/data/error.cu +12 -0
  404. numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
  405. numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
  406. numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
  407. numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
  408. numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
  409. numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
  410. numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
  411. numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
  412. numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
  413. numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
  414. numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
  415. numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
  416. numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
  417. numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
  418. numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
  419. numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
  420. numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
  421. numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
  422. numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
  423. numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
  424. numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
  425. numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
  426. numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +391 -0
  427. numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
  428. numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
  429. numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
  430. numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
  431. numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
  432. numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
  433. numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
  434. numba_cuda/numba/cuda/tests/support.py +900 -0
  435. numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
  436. numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
  437. numba_cuda/numba/cuda/typeconv/rules.py +63 -0
  438. numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
  439. numba_cuda/numba/cuda/types/__init__.py +233 -0
  440. numba_cuda/numba/cuda/types/__init__.pyi +167 -0
  441. numba_cuda/numba/cuda/types/abstract.py +9 -0
  442. numba_cuda/numba/cuda/types/common.py +9 -0
  443. numba_cuda/numba/cuda/types/containers.py +9 -0
  444. numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
  445. numba_cuda/numba/cuda/types/cuda_common.py +110 -0
  446. numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
  447. numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
  448. numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
  449. numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
  450. numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
  451. numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
  452. numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
  453. numba_cuda/numba/cuda/types/ext_types.py +101 -0
  454. numba_cuda/numba/cuda/types/function_type.py +11 -0
  455. numba_cuda/numba/cuda/types/functions.py +9 -0
  456. numba_cuda/numba/cuda/types/iterators.py +9 -0
  457. numba_cuda/numba/cuda/types/misc.py +9 -0
  458. numba_cuda/numba/cuda/types/npytypes.py +9 -0
  459. numba_cuda/numba/cuda/types/scalars.py +9 -0
  460. numba_cuda/numba/cuda/typing/__init__.py +19 -0
  461. numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
  462. numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
  463. numba_cuda/numba/cuda/typing/bufproto.py +70 -0
  464. numba_cuda/numba/cuda/typing/builtins.py +1209 -0
  465. numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
  466. numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
  467. numba_cuda/numba/cuda/typing/collections.py +138 -0
  468. numba_cuda/numba/cuda/typing/context.py +782 -0
  469. numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
  470. numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
  471. numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
  472. numba_cuda/numba/cuda/typing/listdecl.py +147 -0
  473. numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
  474. numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
  475. numba_cuda/numba/cuda/typing/npydecl.py +749 -0
  476. numba_cuda/numba/cuda/typing/setdecl.py +115 -0
  477. numba_cuda/numba/cuda/typing/templates.py +1446 -0
  478. numba_cuda/numba/cuda/typing/typeof.py +301 -0
  479. numba_cuda/numba/cuda/ufuncs.py +746 -0
  480. numba_cuda/numba/cuda/utils.py +724 -0
  481. numba_cuda/numba/cuda/vector_types.py +214 -0
  482. numba_cuda/numba/cuda/vectorizers.py +260 -0
  483. numba_cuda-0.21.1.dist-info/METADATA +109 -0
  484. numba_cuda-0.21.1.dist-info/RECORD +488 -0
  485. numba_cuda-0.21.1.dist-info/WHEEL +5 -0
  486. numba_cuda-0.21.1.dist-info/licenses/LICENSE +26 -0
  487. numba_cuda-0.21.1.dist-info/licenses/LICENSE.numba +24 -0
  488. numba_cuda-0.21.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1475 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ import math
5
+ import numbers
6
+
7
+ import numpy as np
8
+ import operator
9
+
10
+ from llvmlite import ir
11
+ from llvmlite.ir import Constant
12
+
13
+ from numba.cuda.core.imputils import impl_ret_untracked, Registry
14
+ from numba.cuda import types
15
+ from numba.cuda.core import errors
16
+ from numba.cuda.extending import overload_method
17
+ from numba.cuda.cpython.unsafe.numbers import viewer
18
+ from numba.cuda import cgutils, typing
19
+
20
+ registry = Registry("numbers")
21
+ lower_builtin = registry.lower
22
+ lower_cast = registry.lower_cast
23
+ lower_constant = registry.lower_constant
24
+ lower_getattr = registry.lower_getattr
25
+
26
+
27
+ def _int_arith_flags(rettype):
28
+ """
29
+ Return the modifier flags for integer arithmetic.
30
+ """
31
+ if rettype.signed:
32
+ # Ignore the effects of signed overflow. This is important for
33
+ # optimization of some indexing operations. For example
34
+ # array[i+1] could see `i+1` trigger a signed overflow and
35
+ # give a negative number. With Python's indexing, a negative
36
+ # index is treated differently: its resolution has a runtime cost.
37
+ # Telling LLVM to ignore signed overflows allows it to optimize
38
+ # away the check for a negative `i+1` if it knows `i` is positive.
39
+ return ["nsw"]
40
+ else:
41
+ return []
42
+
43
+
44
+ def int_add_impl(context, builder, sig, args):
45
+ [va, vb] = args
46
+ [ta, tb] = sig.args
47
+ a = context.cast(builder, va, ta, sig.return_type)
48
+ b = context.cast(builder, vb, tb, sig.return_type)
49
+ res = builder.add(a, b, flags=_int_arith_flags(sig.return_type))
50
+ return impl_ret_untracked(context, builder, sig.return_type, res)
51
+
52
+
53
+ def int_sub_impl(context, builder, sig, args):
54
+ [va, vb] = args
55
+ [ta, tb] = sig.args
56
+ a = context.cast(builder, va, ta, sig.return_type)
57
+ b = context.cast(builder, vb, tb, sig.return_type)
58
+ res = builder.sub(a, b, flags=_int_arith_flags(sig.return_type))
59
+ return impl_ret_untracked(context, builder, sig.return_type, res)
60
+
61
+
62
+ def int_mul_impl(context, builder, sig, args):
63
+ [va, vb] = args
64
+ [ta, tb] = sig.args
65
+ a = context.cast(builder, va, ta, sig.return_type)
66
+ b = context.cast(builder, vb, tb, sig.return_type)
67
+ res = builder.mul(a, b, flags=_int_arith_flags(sig.return_type))
68
+ return impl_ret_untracked(context, builder, sig.return_type, res)
69
+
70
+
71
+ def int_divmod_signed(context, builder, ty, x, y):
72
+ """
73
+ Reference Objects/intobject.c
74
+ xdivy = x / y;
75
+ xmody = (long)(x - (unsigned long)xdivy * y);
76
+ /* If the signs of x and y differ, and the remainder is non-0,
77
+ * C89 doesn't define whether xdivy is now the floor or the
78
+ * ceiling of the infinitely precise quotient. We want the floor,
79
+ * and we have it iff the remainder's sign matches y's.
80
+ */
81
+ if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
82
+ xmody += y;
83
+ --xdivy;
84
+ assert(xmody && ((y ^ xmody) >= 0));
85
+ }
86
+ *p_xdivy = xdivy;
87
+ *p_xmody = xmody;
88
+ """
89
+ assert x.type == y.type
90
+
91
+ ZERO = y.type(0)
92
+ ONE = y.type(1)
93
+
94
+ # NOTE: On x86 at least, dividing the lowest representable integer
95
+ # (e.g. 0x80000000 for int32) by -1 causes a SIFGPE (division overflow),
96
+ # causing the process to crash.
97
+ # We return 0, 0 instead (more or less like Numpy).
98
+
99
+ resdiv = cgutils.alloca_once_value(builder, ZERO)
100
+ resmod = cgutils.alloca_once_value(builder, ZERO)
101
+
102
+ is_overflow = builder.and_(
103
+ builder.icmp_signed("==", x, x.type(ty.minval)),
104
+ builder.icmp_signed("==", y, y.type(-1)),
105
+ )
106
+
107
+ with builder.if_then(builder.not_(is_overflow), likely=True):
108
+ # Note LLVM will optimize this to a single divmod instruction,
109
+ # if available on the target CPU (e.g. x86).
110
+ xdivy = builder.sdiv(x, y)
111
+ xmody = builder.srem(x, y)
112
+
113
+ y_xor_xmody_ltz = builder.icmp_signed("<", builder.xor(y, xmody), ZERO)
114
+ xmody_istrue = builder.icmp_signed("!=", xmody, ZERO)
115
+ cond = builder.and_(xmody_istrue, y_xor_xmody_ltz)
116
+
117
+ with builder.if_else(cond) as (if_different_signs, if_same_signs):
118
+ with if_same_signs:
119
+ builder.store(xdivy, resdiv)
120
+ builder.store(xmody, resmod)
121
+
122
+ with if_different_signs:
123
+ builder.store(builder.sub(xdivy, ONE), resdiv)
124
+ builder.store(builder.add(xmody, y), resmod)
125
+
126
+ return builder.load(resdiv), builder.load(resmod)
127
+
128
+
129
+ def int_divmod(context, builder, ty, x, y):
130
+ """
131
+ Integer divmod(x, y). The caller must ensure that y != 0.
132
+ """
133
+ if ty.signed:
134
+ return int_divmod_signed(context, builder, ty, x, y)
135
+ else:
136
+ return builder.udiv(x, y), builder.urem(x, y)
137
+
138
+
139
+ def _int_divmod_impl(context, builder, sig, args, zerodiv_message):
140
+ va, vb = args
141
+ ta, tb = sig.args
142
+
143
+ ty = sig.return_type
144
+ if isinstance(ty, types.UniTuple):
145
+ ty = ty.dtype
146
+ a = context.cast(builder, va, ta, ty)
147
+ b = context.cast(builder, vb, tb, ty)
148
+ quot = cgutils.alloca_once(builder, a.type, name="quot")
149
+ rem = cgutils.alloca_once(builder, a.type, name="rem")
150
+
151
+ with builder.if_else(cgutils.is_scalar_zero(builder, b), likely=False) as (
152
+ if_zero,
153
+ if_non_zero,
154
+ ):
155
+ with if_zero:
156
+ if not context.error_model.fp_zero_division(
157
+ builder, (zerodiv_message,)
158
+ ):
159
+ # No exception raised => return 0
160
+ # XXX We should also set the FPU exception status, but
161
+ # there's no easy way to do that from LLVM.
162
+ builder.store(b, quot)
163
+ builder.store(b, rem)
164
+ with if_non_zero:
165
+ q, r = int_divmod(context, builder, ty, a, b)
166
+ builder.store(q, quot)
167
+ builder.store(r, rem)
168
+
169
+ return quot, rem
170
+
171
+
172
+ @lower_builtin(divmod, types.Integer, types.Integer)
173
+ def int_divmod_impl(context, builder, sig, args):
174
+ quot, rem = _int_divmod_impl(
175
+ context, builder, sig, args, "integer divmod by zero"
176
+ )
177
+
178
+ return cgutils.pack_array(builder, (builder.load(quot), builder.load(rem)))
179
+
180
+
181
+ @lower_builtin(operator.floordiv, types.Integer, types.Integer)
182
+ @lower_builtin(operator.ifloordiv, types.Integer, types.Integer)
183
+ def int_floordiv_impl(context, builder, sig, args):
184
+ quot, rem = _int_divmod_impl(
185
+ context, builder, sig, args, "integer division by zero"
186
+ )
187
+ return builder.load(quot)
188
+
189
+
190
+ @lower_builtin(operator.truediv, types.Integer, types.Integer)
191
+ @lower_builtin(operator.itruediv, types.Integer, types.Integer)
192
+ def int_truediv_impl(context, builder, sig, args):
193
+ [va, vb] = args
194
+ [ta, tb] = sig.args
195
+ a = context.cast(builder, va, ta, sig.return_type)
196
+ b = context.cast(builder, vb, tb, sig.return_type)
197
+ with cgutils.if_zero(builder, b):
198
+ context.error_model.fp_zero_division(builder, ("division by zero",))
199
+ res = builder.fdiv(a, b)
200
+ return impl_ret_untracked(context, builder, sig.return_type, res)
201
+
202
+
203
+ @lower_builtin(operator.mod, types.Integer, types.Integer)
204
+ @lower_builtin(operator.imod, types.Integer, types.Integer)
205
+ def int_rem_impl(context, builder, sig, args):
206
+ quot, rem = _int_divmod_impl(
207
+ context, builder, sig, args, "integer modulo by zero"
208
+ )
209
+ return builder.load(rem)
210
+
211
+
212
+ def _get_power_zerodiv_return(context, return_type):
213
+ if (
214
+ isinstance(return_type, types.Integer)
215
+ and not context.error_model.raise_on_fp_zero_division
216
+ ):
217
+ # If not raising, return 0x8000... when computing 0 ** <negative number>
218
+ return -1 << (return_type.bitwidth - 1)
219
+ else:
220
+ return False
221
+
222
+
223
+ def int_power_impl(context, builder, sig, args):
224
+ """
225
+ a ^ b, where a is an integer or real, and b an integer
226
+ """
227
+ is_integer = isinstance(sig.args[0], types.Integer)
228
+ tp = sig.return_type
229
+ zerodiv_return = _get_power_zerodiv_return(context, tp)
230
+
231
+ def int_power(a, b):
232
+ # Ensure computations are done with a large enough width
233
+ r = tp(1)
234
+ a = tp(a)
235
+ if b < 0:
236
+ invert = True
237
+ exp = -b
238
+ if exp < 0:
239
+ raise OverflowError
240
+ if is_integer:
241
+ if a == 0:
242
+ if zerodiv_return:
243
+ return zerodiv_return
244
+ else:
245
+ raise ZeroDivisionError(
246
+ "0 cannot be raised to a negative power"
247
+ )
248
+ if a != 1 and a != -1:
249
+ return 0
250
+ else:
251
+ invert = False
252
+ exp = b
253
+ if exp > 0x10000:
254
+ # Optimization cutoff: fallback on the generic algorithm
255
+ return math.pow(a, float(b))
256
+ while exp != 0:
257
+ if exp & 1:
258
+ r *= a
259
+ exp >>= 1
260
+ a *= a
261
+
262
+ return 1.0 / r if invert else r
263
+
264
+ res = context.compile_internal(builder, int_power, sig, args)
265
+ return impl_ret_untracked(context, builder, sig.return_type, res)
266
+
267
+
268
+ @lower_builtin(operator.pow, types.Integer, types.IntegerLiteral)
269
+ @lower_builtin(operator.ipow, types.Integer, types.IntegerLiteral)
270
+ @lower_builtin(operator.pow, types.Float, types.IntegerLiteral)
271
+ @lower_builtin(operator.ipow, types.Float, types.IntegerLiteral)
272
+ def static_power_impl(context, builder, sig, args):
273
+ """
274
+ a ^ b, where a is an integer or real, and b a constant integer
275
+ """
276
+ exp = sig.args[1].value
277
+ if not isinstance(exp, numbers.Integral):
278
+ raise NotImplementedError
279
+ if abs(exp) > 0x10000:
280
+ # Optimization cutoff: fallback on the generic algorithm above
281
+ raise NotImplementedError
282
+ invert = exp < 0
283
+ exp = abs(exp)
284
+
285
+ tp = sig.return_type
286
+ is_integer = isinstance(tp, types.Integer)
287
+ zerodiv_return = _get_power_zerodiv_return(context, tp)
288
+
289
+ val = context.cast(builder, args[0], sig.args[0], tp)
290
+ lty = val.type
291
+
292
+ def mul(a, b):
293
+ if is_integer:
294
+ return builder.mul(a, b)
295
+ else:
296
+ return builder.fmul(a, b)
297
+
298
+ # Unroll the exponentiation loop
299
+ res = lty(1)
300
+ while exp != 0:
301
+ if exp & 1:
302
+ res = mul(res, val)
303
+ exp >>= 1
304
+ val = mul(val, val)
305
+
306
+ if invert:
307
+ # If the exponent was negative, fix the result by inverting it
308
+ if is_integer:
309
+ # Integer inversion
310
+ def invert_impl(a):
311
+ if a == 0:
312
+ if zerodiv_return:
313
+ return zerodiv_return
314
+ else:
315
+ raise ZeroDivisionError(
316
+ "0 cannot be raised to a negative power"
317
+ )
318
+ if a != 1 and a != -1:
319
+ return 0
320
+ else:
321
+ return a
322
+
323
+ else:
324
+ # Real inversion
325
+ def invert_impl(a):
326
+ return 1.0 / a
327
+
328
+ res = context.compile_internal(
329
+ builder, invert_impl, typing.signature(tp, tp), (res,)
330
+ )
331
+
332
+ return res
333
+
334
+
335
+ def int_slt_impl(context, builder, sig, args):
336
+ res = builder.icmp_signed("<", *args)
337
+ return impl_ret_untracked(context, builder, sig.return_type, res)
338
+
339
+
340
+ def int_sle_impl(context, builder, sig, args):
341
+ res = builder.icmp_signed("<=", *args)
342
+ return impl_ret_untracked(context, builder, sig.return_type, res)
343
+
344
+
345
+ def int_sgt_impl(context, builder, sig, args):
346
+ res = builder.icmp_signed(">", *args)
347
+ return impl_ret_untracked(context, builder, sig.return_type, res)
348
+
349
+
350
+ def int_sge_impl(context, builder, sig, args):
351
+ res = builder.icmp_signed(">=", *args)
352
+ return impl_ret_untracked(context, builder, sig.return_type, res)
353
+
354
+
355
+ def int_ult_impl(context, builder, sig, args):
356
+ res = builder.icmp_unsigned("<", *args)
357
+ return impl_ret_untracked(context, builder, sig.return_type, res)
358
+
359
+
360
+ def int_ule_impl(context, builder, sig, args):
361
+ res = builder.icmp_unsigned("<=", *args)
362
+ return impl_ret_untracked(context, builder, sig.return_type, res)
363
+
364
+
365
+ def int_ugt_impl(context, builder, sig, args):
366
+ res = builder.icmp_unsigned(">", *args)
367
+ return impl_ret_untracked(context, builder, sig.return_type, res)
368
+
369
+
370
+ def int_uge_impl(context, builder, sig, args):
371
+ res = builder.icmp_unsigned(">=", *args)
372
+ return impl_ret_untracked(context, builder, sig.return_type, res)
373
+
374
+
375
+ def int_eq_impl(context, builder, sig, args):
376
+ res = builder.icmp_unsigned("==", *args)
377
+ return impl_ret_untracked(context, builder, sig.return_type, res)
378
+
379
+
380
+ def int_ne_impl(context, builder, sig, args):
381
+ res = builder.icmp_unsigned("!=", *args)
382
+ return impl_ret_untracked(context, builder, sig.return_type, res)
383
+
384
+
385
+ def int_signed_unsigned_cmp(op):
386
+ def impl(context, builder, sig, args):
387
+ (left, right) = args
388
+ # This code is translated from the NumPy source.
389
+ # What we're going to do is divide the range of a signed value at zero.
390
+ # If the signed value is less than zero, then we can treat zero as the
391
+ # unsigned value since the unsigned value is necessarily zero or larger
392
+ # and any signed comparison between a negative value and zero/infinity
393
+ # will yield the same result. If the signed value is greater than or
394
+ # equal to zero, then we can safely cast it to an unsigned value and do
395
+ # the expected unsigned-unsigned comparison operation.
396
+ # Original: https://github.com/numpy/numpy/pull/23713
397
+ cmp_zero = builder.icmp_signed("<", left, Constant(left.type, 0))
398
+ lt_zero = builder.icmp_signed(op, left, Constant(left.type, 0))
399
+ ge_zero = builder.icmp_unsigned(op, left, right)
400
+ res = builder.select(cmp_zero, lt_zero, ge_zero)
401
+ return impl_ret_untracked(context, builder, sig.return_type, res)
402
+
403
+ return impl
404
+
405
+
406
+ def int_unsigned_signed_cmp(op):
407
+ def impl(context, builder, sig, args):
408
+ (left, right) = args
409
+ # See the function `int_signed_unsigned_cmp` for implementation notes.
410
+ cmp_zero = builder.icmp_signed("<", right, Constant(right.type, 0))
411
+ lt_zero = builder.icmp_signed(op, Constant(right.type, 0), right)
412
+ ge_zero = builder.icmp_unsigned(op, left, right)
413
+ res = builder.select(cmp_zero, lt_zero, ge_zero)
414
+ return impl_ret_untracked(context, builder, sig.return_type, res)
415
+
416
+ return impl
417
+
418
+
419
+ def int_abs_impl(context, builder, sig, args):
420
+ [x] = args
421
+ ZERO = Constant(x.type, None)
422
+ ltz = builder.icmp_signed("<", x, ZERO)
423
+ negated = builder.neg(x)
424
+ res = builder.select(ltz, negated, x)
425
+ return impl_ret_untracked(context, builder, sig.return_type, res)
426
+
427
+
428
+ def uint_abs_impl(context, builder, sig, args):
429
+ [x] = args
430
+ return impl_ret_untracked(context, builder, sig.return_type, x)
431
+
432
+
433
+ def int_shl_impl(context, builder, sig, args):
434
+ [valty, amtty] = sig.args
435
+ [val, amt] = args
436
+ val = context.cast(builder, val, valty, sig.return_type)
437
+ amt = context.cast(builder, amt, amtty, sig.return_type)
438
+ res = builder.shl(val, amt)
439
+ return impl_ret_untracked(context, builder, sig.return_type, res)
440
+
441
+
442
+ def int_shr_impl(context, builder, sig, args):
443
+ [valty, amtty] = sig.args
444
+ [val, amt] = args
445
+ val = context.cast(builder, val, valty, sig.return_type)
446
+ amt = context.cast(builder, amt, amtty, sig.return_type)
447
+ if sig.return_type.signed:
448
+ res = builder.ashr(val, amt)
449
+ else:
450
+ res = builder.lshr(val, amt)
451
+ return impl_ret_untracked(context, builder, sig.return_type, res)
452
+
453
+
454
+ def int_and_impl(context, builder, sig, args):
455
+ [at, bt] = sig.args
456
+ [av, bv] = args
457
+ cav = context.cast(builder, av, at, sig.return_type)
458
+ cbc = context.cast(builder, bv, bt, sig.return_type)
459
+ res = builder.and_(cav, cbc)
460
+ return impl_ret_untracked(context, builder, sig.return_type, res)
461
+
462
+
463
+ def int_or_impl(context, builder, sig, args):
464
+ [at, bt] = sig.args
465
+ [av, bv] = args
466
+ cav = context.cast(builder, av, at, sig.return_type)
467
+ cbc = context.cast(builder, bv, bt, sig.return_type)
468
+ res = builder.or_(cav, cbc)
469
+ return impl_ret_untracked(context, builder, sig.return_type, res)
470
+
471
+
472
+ def int_xor_impl(context, builder, sig, args):
473
+ [at, bt] = sig.args
474
+ [av, bv] = args
475
+ cav = context.cast(builder, av, at, sig.return_type)
476
+ cbc = context.cast(builder, bv, bt, sig.return_type)
477
+ res = builder.xor(cav, cbc)
478
+ return impl_ret_untracked(context, builder, sig.return_type, res)
479
+
480
+
481
+ def int_negate_impl(context, builder, sig, args):
482
+ [typ] = sig.args
483
+ [val] = args
484
+ # Negate before upcasting, for unsigned numbers
485
+ res = builder.neg(val)
486
+ res = context.cast(builder, res, typ, sig.return_type)
487
+ return impl_ret_untracked(context, builder, sig.return_type, res)
488
+
489
+
490
+ def int_positive_impl(context, builder, sig, args):
491
+ [typ] = sig.args
492
+ [val] = args
493
+ res = context.cast(builder, val, typ, sig.return_type)
494
+ return impl_ret_untracked(context, builder, sig.return_type, res)
495
+
496
+
497
+ def int_invert_impl(context, builder, sig, args):
498
+ [typ] = sig.args
499
+ [val] = args
500
+ # Invert before upcasting, for unsigned numbers
501
+ res = builder.xor(val, Constant(val.type, int("1" * val.type.width, 2)))
502
+ res = context.cast(builder, res, typ, sig.return_type)
503
+ return impl_ret_untracked(context, builder, sig.return_type, res)
504
+
505
+
506
+ def int_sign_impl(context, builder, sig, args):
507
+ """
508
+ np.sign(int)
509
+ """
510
+ [x] = args
511
+ POS = Constant(x.type, 1)
512
+ NEG = Constant(x.type, -1)
513
+ ZERO = Constant(x.type, 0)
514
+
515
+ cmp_zero = builder.icmp_unsigned("==", x, ZERO)
516
+ cmp_pos = builder.icmp_signed(">", x, ZERO)
517
+
518
+ presult = cgutils.alloca_once(builder, x.type)
519
+
520
+ bb_zero = builder.append_basic_block(".zero")
521
+ bb_postest = builder.append_basic_block(".postest")
522
+ bb_pos = builder.append_basic_block(".pos")
523
+ bb_neg = builder.append_basic_block(".neg")
524
+ bb_exit = builder.append_basic_block(".exit")
525
+
526
+ builder.cbranch(cmp_zero, bb_zero, bb_postest)
527
+
528
+ with builder.goto_block(bb_zero):
529
+ builder.store(ZERO, presult)
530
+ builder.branch(bb_exit)
531
+
532
+ with builder.goto_block(bb_postest):
533
+ builder.cbranch(cmp_pos, bb_pos, bb_neg)
534
+
535
+ with builder.goto_block(bb_pos):
536
+ builder.store(POS, presult)
537
+ builder.branch(bb_exit)
538
+
539
+ with builder.goto_block(bb_neg):
540
+ builder.store(NEG, presult)
541
+ builder.branch(bb_exit)
542
+
543
+ builder.position_at_end(bb_exit)
544
+ res = builder.load(presult)
545
+ return impl_ret_untracked(context, builder, sig.return_type, res)
546
+
547
+
548
+ def bool_negate_impl(context, builder, sig, args):
549
+ [typ] = sig.args
550
+ [val] = args
551
+ res = context.cast(builder, val, typ, sig.return_type)
552
+ res = builder.neg(res)
553
+ return impl_ret_untracked(context, builder, sig.return_type, res)
554
+
555
+
556
+ def bool_unary_positive_impl(context, builder, sig, args):
557
+ [typ] = sig.args
558
+ [val] = args
559
+ res = context.cast(builder, val, typ, sig.return_type)
560
+ return impl_ret_untracked(context, builder, sig.return_type, res)
561
+
562
+
563
+ lower_builtin(operator.eq, types.boolean, types.boolean)(int_eq_impl)
564
+ lower_builtin(operator.ne, types.boolean, types.boolean)(int_ne_impl)
565
+ lower_builtin(operator.lt, types.boolean, types.boolean)(int_ult_impl)
566
+ lower_builtin(operator.le, types.boolean, types.boolean)(int_ule_impl)
567
+ lower_builtin(operator.gt, types.boolean, types.boolean)(int_ugt_impl)
568
+ lower_builtin(operator.ge, types.boolean, types.boolean)(int_uge_impl)
569
+ lower_builtin(operator.neg, types.boolean)(bool_negate_impl)
570
+ lower_builtin(operator.pos, types.boolean)(bool_unary_positive_impl)
571
+
572
+
573
+ def _implement_integer_operators():
574
+ ty = types.Integer
575
+
576
+ lower_builtin(operator.add, ty, ty)(int_add_impl)
577
+ lower_builtin(operator.iadd, ty, ty)(int_add_impl)
578
+ lower_builtin(operator.sub, ty, ty)(int_sub_impl)
579
+ lower_builtin(operator.isub, ty, ty)(int_sub_impl)
580
+ lower_builtin(operator.mul, ty, ty)(int_mul_impl)
581
+ lower_builtin(operator.imul, ty, ty)(int_mul_impl)
582
+ lower_builtin(operator.eq, ty, ty)(int_eq_impl)
583
+ lower_builtin(operator.ne, ty, ty)(int_ne_impl)
584
+
585
+ lower_builtin(operator.lshift, ty, ty)(int_shl_impl)
586
+ lower_builtin(operator.ilshift, ty, ty)(int_shl_impl)
587
+ lower_builtin(operator.rshift, ty, ty)(int_shr_impl)
588
+ lower_builtin(operator.irshift, ty, ty)(int_shr_impl)
589
+
590
+ lower_builtin(operator.neg, ty)(int_negate_impl)
591
+ lower_builtin(operator.pos, ty)(int_positive_impl)
592
+
593
+ lower_builtin(operator.pow, ty, ty)(int_power_impl)
594
+ lower_builtin(operator.ipow, ty, ty)(int_power_impl)
595
+ lower_builtin(pow, ty, ty)(int_power_impl)
596
+
597
+ for ty in types.unsigned_domain:
598
+ lower_builtin(operator.lt, ty, ty)(int_ult_impl)
599
+ lower_builtin(operator.le, ty, ty)(int_ule_impl)
600
+ lower_builtin(operator.gt, ty, ty)(int_ugt_impl)
601
+ lower_builtin(operator.ge, ty, ty)(int_uge_impl)
602
+ lower_builtin(operator.pow, types.Float, ty)(int_power_impl)
603
+ lower_builtin(operator.ipow, types.Float, ty)(int_power_impl)
604
+ lower_builtin(pow, types.Float, ty)(int_power_impl)
605
+ lower_builtin(abs, ty)(uint_abs_impl)
606
+
607
+ lower_builtin(operator.lt, types.IntegerLiteral, types.IntegerLiteral)(
608
+ int_slt_impl
609
+ )
610
+ lower_builtin(operator.gt, types.IntegerLiteral, types.IntegerLiteral)(
611
+ int_slt_impl
612
+ )
613
+ lower_builtin(operator.le, types.IntegerLiteral, types.IntegerLiteral)(
614
+ int_slt_impl
615
+ )
616
+ lower_builtin(operator.ge, types.IntegerLiteral, types.IntegerLiteral)(
617
+ int_slt_impl
618
+ )
619
+ for ty in types.signed_domain:
620
+ lower_builtin(operator.lt, ty, ty)(int_slt_impl)
621
+ lower_builtin(operator.le, ty, ty)(int_sle_impl)
622
+ lower_builtin(operator.gt, ty, ty)(int_sgt_impl)
623
+ lower_builtin(operator.ge, ty, ty)(int_sge_impl)
624
+ lower_builtin(operator.pow, types.Float, ty)(int_power_impl)
625
+ lower_builtin(operator.ipow, types.Float, ty)(int_power_impl)
626
+ lower_builtin(pow, types.Float, ty)(int_power_impl)
627
+ lower_builtin(abs, ty)(int_abs_impl)
628
+
629
+
630
+ def _implement_bitwise_operators():
631
+ for ty in (types.Boolean, types.Integer):
632
+ lower_builtin(operator.and_, ty, ty)(int_and_impl)
633
+ lower_builtin(operator.iand, ty, ty)(int_and_impl)
634
+ lower_builtin(operator.or_, ty, ty)(int_or_impl)
635
+ lower_builtin(operator.ior, ty, ty)(int_or_impl)
636
+ lower_builtin(operator.xor, ty, ty)(int_xor_impl)
637
+ lower_builtin(operator.ixor, ty, ty)(int_xor_impl)
638
+
639
+ lower_builtin(operator.invert, ty)(int_invert_impl)
640
+
641
+
642
+ _implement_integer_operators()
643
+
644
+ _implement_bitwise_operators()
645
+
646
+
647
+ def real_add_impl(context, builder, sig, args):
648
+ res = builder.fadd(*args)
649
+ return impl_ret_untracked(context, builder, sig.return_type, res)
650
+
651
+
652
+ def real_sub_impl(context, builder, sig, args):
653
+ res = builder.fsub(*args)
654
+ return impl_ret_untracked(context, builder, sig.return_type, res)
655
+
656
+
657
+ def real_mul_impl(context, builder, sig, args):
658
+ res = builder.fmul(*args)
659
+ return impl_ret_untracked(context, builder, sig.return_type, res)
660
+
661
+
662
+ def real_div_impl(context, builder, sig, args):
663
+ with cgutils.if_zero(builder, args[1]):
664
+ context.error_model.fp_zero_division(builder, ("division by zero",))
665
+ res = builder.fdiv(*args)
666
+ return impl_ret_untracked(context, builder, sig.return_type, res)
667
+
668
+
669
+ def real_divmod(context, builder, x, y):
670
+ assert x.type == y.type
671
+ floatty = x.type
672
+
673
+ module = builder.module
674
+ fname = context.mangler(".numba.python.rem", [x.type])
675
+ fnty = ir.FunctionType(floatty, (floatty, floatty, ir.PointerType(floatty)))
676
+ fn = cgutils.get_or_insert_function(module, fnty, fname)
677
+
678
+ if fn.is_declaration:
679
+ fn.linkage = "linkonce_odr"
680
+ fnbuilder = ir.IRBuilder(fn.append_basic_block("entry"))
681
+ fx, fy, pmod = fn.args
682
+ div, mod = real_divmod_func_body(context, fnbuilder, fx, fy)
683
+ fnbuilder.store(mod, pmod)
684
+ fnbuilder.ret(div)
685
+
686
+ pmod = cgutils.alloca_once(builder, floatty)
687
+ quotient = builder.call(fn, (x, y, pmod))
688
+ return quotient, builder.load(pmod)
689
+
690
+
691
+ def real_divmod_func_body(context, builder, vx, wx):
692
+ # Reference Objects/floatobject.c
693
+ #
694
+ # float_divmod(PyObject *v, PyObject *w)
695
+ # {
696
+ # double vx, wx;
697
+ # double div, mod, floordiv;
698
+ # CONVERT_TO_DOUBLE(v, vx);
699
+ # CONVERT_TO_DOUBLE(w, wx);
700
+ # mod = fmod(vx, wx);
701
+ # /* fmod is typically exact, so vx-mod is *mathematically* an
702
+ # exact multiple of wx. But this is fp arithmetic, and fp
703
+ # vx - mod is an approximation; the result is that div may
704
+ # not be an exact integral value after the division, although
705
+ # it will always be very close to one.
706
+ # */
707
+ # div = (vx - mod) / wx;
708
+ # if (mod) {
709
+ # /* ensure the remainder has the same sign as the denominator */
710
+ # if ((wx < 0) != (mod < 0)) {
711
+ # mod += wx;
712
+ # div -= 1.0;
713
+ # }
714
+ # }
715
+ # else {
716
+ # /* the remainder is zero, and in the presence of signed zeroes
717
+ # fmod returns different results across platforms; ensure
718
+ # it has the same sign as the denominator; we'd like to do
719
+ # "mod = wx * 0.0", but that may get optimized away */
720
+ # mod *= mod; /* hide "mod = +0" from optimizer */
721
+ # if (wx < 0.0)
722
+ # mod = -mod;
723
+ # }
724
+ # /* snap quotient to nearest integral value */
725
+ # if (div) {
726
+ # floordiv = floor(div);
727
+ # if (div - floordiv > 0.5)
728
+ # floordiv += 1.0;
729
+ # }
730
+ # else {
731
+ # /* div is zero - get the same sign as the true quotient */
732
+ # div *= div; /* hide "div = +0" from optimizers */
733
+ # floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
734
+ # }
735
+ # return Py_BuildValue("(dd)", floordiv, mod);
736
+ # }
737
+ pmod = cgutils.alloca_once(builder, vx.type)
738
+ pdiv = cgutils.alloca_once(builder, vx.type)
739
+ pfloordiv = cgutils.alloca_once(builder, vx.type)
740
+
741
+ mod = builder.frem(vx, wx)
742
+ div = builder.fdiv(builder.fsub(vx, mod), wx)
743
+
744
+ builder.store(mod, pmod)
745
+ builder.store(div, pdiv)
746
+
747
+ # Note the use of negative zero for proper negating with `ZERO - x`
748
+ ZERO = vx.type(0.0)
749
+ NZERO = vx.type(-0.0)
750
+ ONE = vx.type(1.0)
751
+ mod_istrue = builder.fcmp_unordered("!=", mod, ZERO)
752
+ wx_ltz = builder.fcmp_ordered("<", wx, ZERO)
753
+ mod_ltz = builder.fcmp_ordered("<", mod, ZERO)
754
+
755
+ with builder.if_else(mod_istrue, likely=True) as (
756
+ if_nonzero_mod,
757
+ if_zero_mod,
758
+ ):
759
+ with if_nonzero_mod:
760
+ # `mod` is non-zero or NaN
761
+ # Ensure the remainder has the same sign as the denominator
762
+ wx_ltz_ne_mod_ltz = builder.icmp_unsigned("!=", wx_ltz, mod_ltz)
763
+
764
+ with builder.if_then(wx_ltz_ne_mod_ltz):
765
+ builder.store(builder.fsub(div, ONE), pdiv)
766
+ builder.store(builder.fadd(mod, wx), pmod)
767
+
768
+ with if_zero_mod:
769
+ # `mod` is zero, select the proper sign depending on
770
+ # the denominator's sign
771
+ mod = builder.select(wx_ltz, NZERO, ZERO)
772
+ builder.store(mod, pmod)
773
+
774
+ del mod, div
775
+
776
+ div = builder.load(pdiv)
777
+ div_istrue = builder.fcmp_ordered("!=", div, ZERO)
778
+
779
+ with builder.if_then(div_istrue):
780
+ realtypemap = {"float": types.float32, "double": types.float64}
781
+ realtype = realtypemap[str(wx.type)]
782
+ floorfn = context.get_function(
783
+ math.floor, typing.signature(realtype, realtype)
784
+ )
785
+ floordiv = floorfn(builder, [div])
786
+ floordivdiff = builder.fsub(div, floordiv)
787
+ floordivincr = builder.fadd(floordiv, ONE)
788
+ HALF = Constant(wx.type, 0.5)
789
+ pred = builder.fcmp_ordered(">", floordivdiff, HALF)
790
+ floordiv = builder.select(pred, floordivincr, floordiv)
791
+ builder.store(floordiv, pfloordiv)
792
+
793
+ with cgutils.ifnot(builder, div_istrue):
794
+ div = builder.fmul(div, div)
795
+ builder.store(div, pdiv)
796
+ floordiv = builder.fdiv(builder.fmul(div, vx), wx)
797
+ builder.store(floordiv, pfloordiv)
798
+
799
+ return builder.load(pfloordiv), builder.load(pmod)
800
+
801
+
802
+ @lower_builtin(divmod, types.Float, types.Float)
803
+ def real_divmod_impl(context, builder, sig, args, loc=None):
804
+ x, y = args
805
+ quot = cgutils.alloca_once(builder, x.type, name="quot")
806
+ rem = cgutils.alloca_once(builder, x.type, name="rem")
807
+
808
+ with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False) as (
809
+ if_zero,
810
+ if_non_zero,
811
+ ):
812
+ with if_zero:
813
+ if not context.error_model.fp_zero_division(
814
+ builder, ("modulo by zero",), loc
815
+ ):
816
+ # No exception raised => compute the nan result,
817
+ # and set the FP exception word for Numpy warnings.
818
+ q = builder.fdiv(x, y)
819
+ r = builder.frem(x, y)
820
+ builder.store(q, quot)
821
+ builder.store(r, rem)
822
+ with if_non_zero:
823
+ q, r = real_divmod(context, builder, x, y)
824
+ builder.store(q, quot)
825
+ builder.store(r, rem)
826
+
827
+ return cgutils.pack_array(builder, (builder.load(quot), builder.load(rem)))
828
+
829
+
830
+ def real_mod_impl(context, builder, sig, args, loc=None):
831
+ x, y = args
832
+ res = cgutils.alloca_once(builder, x.type)
833
+ with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False) as (
834
+ if_zero,
835
+ if_non_zero,
836
+ ):
837
+ with if_zero:
838
+ if not context.error_model.fp_zero_division(
839
+ builder, ("modulo by zero",), loc
840
+ ):
841
+ # No exception raised => compute the nan result,
842
+ # and set the FP exception word for Numpy warnings.
843
+ rem = builder.frem(x, y)
844
+ builder.store(rem, res)
845
+ with if_non_zero:
846
+ _, rem = real_divmod(context, builder, x, y)
847
+ builder.store(rem, res)
848
+ return impl_ret_untracked(
849
+ context, builder, sig.return_type, builder.load(res)
850
+ )
851
+
852
+
853
+ def real_floordiv_impl(context, builder, sig, args, loc=None):
854
+ x, y = args
855
+ res = cgutils.alloca_once(builder, x.type)
856
+ with builder.if_else(cgutils.is_scalar_zero(builder, y), likely=False) as (
857
+ if_zero,
858
+ if_non_zero,
859
+ ):
860
+ with if_zero:
861
+ if not context.error_model.fp_zero_division(
862
+ builder, ("division by zero",), loc
863
+ ):
864
+ # No exception raised => compute the +/-inf or nan result,
865
+ # and set the FP exception word for Numpy warnings.
866
+ quot = builder.fdiv(x, y)
867
+ builder.store(quot, res)
868
+ with if_non_zero:
869
+ quot, _ = real_divmod(context, builder, x, y)
870
+ builder.store(quot, res)
871
+ return impl_ret_untracked(
872
+ context, builder, sig.return_type, builder.load(res)
873
+ )
874
+
875
+
876
+ def real_power_impl(context, builder, sig, args):
877
+ x, y = args
878
+ module = builder.module
879
+ if context.implement_powi_as_math_call:
880
+ imp = context.get_function(math.pow, sig)
881
+ res = imp(builder, args)
882
+ else:
883
+ fn = module.declare_intrinsic("llvm.pow", [y.type])
884
+ res = builder.call(fn, (x, y))
885
+ return impl_ret_untracked(context, builder, sig.return_type, res)
886
+
887
+
888
+ def real_lt_impl(context, builder, sig, args):
889
+ res = builder.fcmp_ordered("<", *args)
890
+ return impl_ret_untracked(context, builder, sig.return_type, res)
891
+
892
+
893
+ def real_le_impl(context, builder, sig, args):
894
+ res = builder.fcmp_ordered("<=", *args)
895
+ return impl_ret_untracked(context, builder, sig.return_type, res)
896
+
897
+
898
+ def real_gt_impl(context, builder, sig, args):
899
+ res = builder.fcmp_ordered(">", *args)
900
+ return impl_ret_untracked(context, builder, sig.return_type, res)
901
+
902
+
903
+ def real_ge_impl(context, builder, sig, args):
904
+ res = builder.fcmp_ordered(">=", *args)
905
+ return impl_ret_untracked(context, builder, sig.return_type, res)
906
+
907
+
908
+ def real_eq_impl(context, builder, sig, args):
909
+ res = builder.fcmp_ordered("==", *args)
910
+ return impl_ret_untracked(context, builder, sig.return_type, res)
911
+
912
+
913
+ def real_ne_impl(context, builder, sig, args):
914
+ res = builder.fcmp_unordered("!=", *args)
915
+ return impl_ret_untracked(context, builder, sig.return_type, res)
916
+
917
+
918
+ def real_abs_impl(context, builder, sig, args):
919
+ [ty] = sig.args
920
+ sig = typing.signature(ty, ty)
921
+ impl = context.get_function(math.fabs, sig)
922
+ return impl(builder, args)
923
+
924
+
925
+ def real_negate_impl(context, builder, sig, args):
926
+ from numba.cuda.cpython import mathimpl
927
+
928
+ res = mathimpl.negate_real(builder, args[0])
929
+ return impl_ret_untracked(context, builder, sig.return_type, res)
930
+
931
+
932
+ def real_positive_impl(context, builder, sig, args):
933
+ [typ] = sig.args
934
+ [val] = args
935
+ res = context.cast(builder, val, typ, sig.return_type)
936
+ return impl_ret_untracked(context, builder, sig.return_type, res)
937
+
938
+
939
+ def real_sign_impl(context, builder, sig, args):
940
+ """
941
+ np.sign(float)
942
+ """
943
+ [x] = args
944
+ POS = Constant(x.type, 1)
945
+ NEG = Constant(x.type, -1)
946
+ ZERO = Constant(x.type, 0)
947
+
948
+ presult = cgutils.alloca_once(builder, x.type)
949
+
950
+ is_pos = builder.fcmp_ordered(">", x, ZERO)
951
+ is_neg = builder.fcmp_ordered("<", x, ZERO)
952
+
953
+ with builder.if_else(is_pos) as (gt_zero, not_gt_zero):
954
+ with gt_zero:
955
+ builder.store(POS, presult)
956
+ with not_gt_zero:
957
+ with builder.if_else(is_neg) as (lt_zero, not_lt_zero):
958
+ with lt_zero:
959
+ builder.store(NEG, presult)
960
+ with not_lt_zero:
961
+ # For both NaN and 0, the result of sign() is simply
962
+ # the input value.
963
+ builder.store(x, presult)
964
+
965
+ res = builder.load(presult)
966
+ return impl_ret_untracked(context, builder, sig.return_type, res)
967
+
968
+
969
+ ty = types.Float
970
+
971
+ lower_builtin(operator.add, ty, ty)(real_add_impl)
972
+ lower_builtin(operator.iadd, ty, ty)(real_add_impl)
973
+ lower_builtin(operator.sub, ty, ty)(real_sub_impl)
974
+ lower_builtin(operator.isub, ty, ty)(real_sub_impl)
975
+ lower_builtin(operator.mul, ty, ty)(real_mul_impl)
976
+ lower_builtin(operator.imul, ty, ty)(real_mul_impl)
977
+ lower_builtin(operator.floordiv, ty, ty)(real_floordiv_impl)
978
+ lower_builtin(operator.ifloordiv, ty, ty)(real_floordiv_impl)
979
+ lower_builtin(operator.truediv, ty, ty)(real_div_impl)
980
+ lower_builtin(operator.itruediv, ty, ty)(real_div_impl)
981
+ lower_builtin(operator.mod, ty, ty)(real_mod_impl)
982
+ lower_builtin(operator.imod, ty, ty)(real_mod_impl)
983
+ lower_builtin(operator.pow, ty, ty)(real_power_impl)
984
+ lower_builtin(operator.ipow, ty, ty)(real_power_impl)
985
+ lower_builtin(pow, ty, ty)(real_power_impl)
986
+
987
+ lower_builtin(operator.eq, ty, ty)(real_eq_impl)
988
+ lower_builtin(operator.ne, ty, ty)(real_ne_impl)
989
+ lower_builtin(operator.lt, ty, ty)(real_lt_impl)
990
+ lower_builtin(operator.le, ty, ty)(real_le_impl)
991
+ lower_builtin(operator.gt, ty, ty)(real_gt_impl)
992
+ lower_builtin(operator.ge, ty, ty)(real_ge_impl)
993
+
994
+ lower_builtin(abs, ty)(real_abs_impl)
995
+
996
+ lower_builtin(operator.neg, ty)(real_negate_impl)
997
+ lower_builtin(operator.pos, ty)(real_positive_impl)
998
+
999
+ del ty
1000
+
1001
+
1002
+ @lower_getattr(types.Complex, "real")
1003
+ def complex_real_impl(context, builder, typ, value):
1004
+ cplx = context.make_complex(builder, typ, value=value)
1005
+ res = cplx.real
1006
+ return impl_ret_untracked(context, builder, typ, res)
1007
+
1008
+
1009
+ @lower_getattr(types.Complex, "imag")
1010
+ def complex_imag_impl(context, builder, typ, value):
1011
+ cplx = context.make_complex(builder, typ, value=value)
1012
+ res = cplx.imag
1013
+ return impl_ret_untracked(context, builder, typ, res)
1014
+
1015
+
1016
+ @lower_builtin("complex.conjugate", types.Complex)
1017
+ def complex_conjugate_impl(context, builder, sig, args):
1018
+ from numba.cuda.cpython import mathimpl
1019
+
1020
+ z = context.make_complex(builder, sig.args[0], args[0])
1021
+ z.imag = mathimpl.negate_real(builder, z.imag)
1022
+ res = z._getvalue()
1023
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1024
+
1025
+
1026
+ def real_real_impl(context, builder, typ, value):
1027
+ return impl_ret_untracked(context, builder, typ, value)
1028
+
1029
+
1030
+ def real_imag_impl(context, builder, typ, value):
1031
+ res = cgutils.get_null_value(value.type)
1032
+ return impl_ret_untracked(context, builder, typ, res)
1033
+
1034
+
1035
+ def real_conjugate_impl(context, builder, sig, args):
1036
+ return impl_ret_untracked(context, builder, sig.return_type, args[0])
1037
+
1038
+
1039
+ for cls in (types.Float, types.Integer):
1040
+ lower_getattr(cls, "real")(real_real_impl)
1041
+ lower_getattr(cls, "imag")(real_imag_impl)
1042
+ lower_builtin("complex.conjugate", cls)(real_conjugate_impl)
1043
+
1044
+
1045
+ @lower_builtin(operator.pow, types.Complex, types.Complex)
1046
+ @lower_builtin(operator.ipow, types.Complex, types.Complex)
1047
+ @lower_builtin(pow, types.Complex, types.Complex)
1048
+ def complex_power_impl(context, builder, sig, args):
1049
+ [ca, cb] = args
1050
+ ty = sig.args[0]
1051
+ fty = ty.underlying_float
1052
+ a = context.make_helper(builder, ty, value=ca)
1053
+ b = context.make_helper(builder, ty, value=cb)
1054
+ c = context.make_helper(builder, ty)
1055
+ module = builder.module
1056
+ pa = a._getpointer()
1057
+ pb = b._getpointer()
1058
+ pc = c._getpointer()
1059
+
1060
+ # Optimize for square because cpow loses a lot of precision
1061
+ TWO = context.get_constant(fty, 2)
1062
+ ZERO = context.get_constant(fty, 0)
1063
+
1064
+ b_real_is_two = builder.fcmp_ordered("==", b.real, TWO)
1065
+ b_imag_is_zero = builder.fcmp_ordered("==", b.imag, ZERO)
1066
+ b_is_two = builder.and_(b_real_is_two, b_imag_is_zero)
1067
+
1068
+ with builder.if_else(b_is_two) as (then, otherwise):
1069
+ with then:
1070
+ # Lower as multiplication
1071
+ res = complex_mul_impl(context, builder, sig, (ca, ca))
1072
+ cres = context.make_helper(builder, ty, value=res)
1073
+ c.real = cres.real
1074
+ c.imag = cres.imag
1075
+
1076
+ with otherwise:
1077
+ # Lower with call to external function
1078
+ func_name = {
1079
+ types.complex64: "numba_cpowf",
1080
+ types.complex128: "numba_cpow",
1081
+ }[ty]
1082
+ fnty = ir.FunctionType(ir.VoidType(), [pa.type] * 3)
1083
+ cpow = cgutils.get_or_insert_function(module, fnty, func_name)
1084
+ builder.call(cpow, (pa, pb, pc))
1085
+
1086
+ res = builder.load(pc)
1087
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1088
+
1089
+
1090
+ def complex_add_impl(context, builder, sig, args):
1091
+ [cx, cy] = args
1092
+ ty = sig.args[0]
1093
+ x = context.make_complex(builder, ty, value=cx)
1094
+ y = context.make_complex(builder, ty, value=cy)
1095
+ z = context.make_complex(builder, ty)
1096
+ a = x.real
1097
+ b = x.imag
1098
+ c = y.real
1099
+ d = y.imag
1100
+ z.real = builder.fadd(a, c)
1101
+ z.imag = builder.fadd(b, d)
1102
+ res = z._getvalue()
1103
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1104
+
1105
+
1106
+ def complex_sub_impl(context, builder, sig, args):
1107
+ [cx, cy] = args
1108
+ ty = sig.args[0]
1109
+ x = context.make_complex(builder, ty, value=cx)
1110
+ y = context.make_complex(builder, ty, value=cy)
1111
+ z = context.make_complex(builder, ty)
1112
+ a = x.real
1113
+ b = x.imag
1114
+ c = y.real
1115
+ d = y.imag
1116
+ z.real = builder.fsub(a, c)
1117
+ z.imag = builder.fsub(b, d)
1118
+ res = z._getvalue()
1119
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1120
+
1121
+
1122
+ def complex_mul_impl(context, builder, sig, args):
1123
+ """
1124
+ (a+bi)(c+di)=(ac-bd)+i(ad+bc)
1125
+ """
1126
+ [cx, cy] = args
1127
+ ty = sig.args[0]
1128
+ x = context.make_complex(builder, ty, value=cx)
1129
+ y = context.make_complex(builder, ty, value=cy)
1130
+ z = context.make_complex(builder, ty)
1131
+ a = x.real
1132
+ b = x.imag
1133
+ c = y.real
1134
+ d = y.imag
1135
+ ac = builder.fmul(a, c)
1136
+ bd = builder.fmul(b, d)
1137
+ ad = builder.fmul(a, d)
1138
+ bc = builder.fmul(b, c)
1139
+ z.real = builder.fsub(ac, bd)
1140
+ z.imag = builder.fadd(ad, bc)
1141
+ res = z._getvalue()
1142
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1143
+
1144
+
1145
+ NAN = float("nan")
1146
+
1147
+
1148
+ def complex_div_impl(context, builder, sig, args):
1149
+ def complex_div(a, b):
1150
+ # This is CPython's algorithm (in _Py_c_quot()).
1151
+ areal = a.real
1152
+ aimag = a.imag
1153
+ breal = b.real
1154
+ bimag = b.imag
1155
+ if not breal and not bimag:
1156
+ raise ZeroDivisionError("complex division by zero")
1157
+ if abs(breal) >= abs(bimag):
1158
+ # Divide tops and bottom by b.real
1159
+ if not breal:
1160
+ return complex(NAN, NAN)
1161
+ ratio = bimag / breal
1162
+ denom = breal + bimag * ratio
1163
+ return complex(
1164
+ (areal + aimag * ratio) / denom, (aimag - areal * ratio) / denom
1165
+ )
1166
+ else:
1167
+ # Divide tops and bottom by b.imag
1168
+ if not bimag:
1169
+ return complex(NAN, NAN)
1170
+ ratio = breal / bimag
1171
+ denom = breal * ratio + bimag
1172
+ return complex(
1173
+ (a.real * ratio + a.imag) / denom,
1174
+ (a.imag * ratio - a.real) / denom,
1175
+ )
1176
+
1177
+ res = context.compile_internal(builder, complex_div, sig, args)
1178
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1179
+
1180
+
1181
+ def complex_negate_impl(context, builder, sig, args):
1182
+ from numba.cuda.cpython import mathimpl
1183
+
1184
+ [typ] = sig.args
1185
+ [val] = args
1186
+ cmplx = context.make_complex(builder, typ, value=val)
1187
+ res = context.make_complex(builder, typ)
1188
+ res.real = mathimpl.negate_real(builder, cmplx.real)
1189
+ res.imag = mathimpl.negate_real(builder, cmplx.imag)
1190
+ res = res._getvalue()
1191
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1192
+
1193
+
1194
+ def complex_positive_impl(context, builder, sig, args):
1195
+ [val] = args
1196
+ return impl_ret_untracked(context, builder, sig.return_type, val)
1197
+
1198
+
1199
+ def complex_eq_impl(context, builder, sig, args):
1200
+ [cx, cy] = args
1201
+ typ = sig.args[0]
1202
+ x = context.make_complex(builder, typ, value=cx)
1203
+ y = context.make_complex(builder, typ, value=cy)
1204
+
1205
+ reals_are_eq = builder.fcmp_ordered("==", x.real, y.real)
1206
+ imags_are_eq = builder.fcmp_ordered("==", x.imag, y.imag)
1207
+ res = builder.and_(reals_are_eq, imags_are_eq)
1208
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1209
+
1210
+
1211
+ def complex_ne_impl(context, builder, sig, args):
1212
+ [cx, cy] = args
1213
+ typ = sig.args[0]
1214
+ x = context.make_complex(builder, typ, value=cx)
1215
+ y = context.make_complex(builder, typ, value=cy)
1216
+
1217
+ reals_are_ne = builder.fcmp_unordered("!=", x.real, y.real)
1218
+ imags_are_ne = builder.fcmp_unordered("!=", x.imag, y.imag)
1219
+ res = builder.or_(reals_are_ne, imags_are_ne)
1220
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1221
+
1222
+
1223
+ def complex_abs_impl(context, builder, sig, args):
1224
+ """
1225
+ abs(z) := hypot(z.real, z.imag)
1226
+ """
1227
+
1228
+ def complex_abs(z):
1229
+ return math.hypot(z.real, z.imag)
1230
+
1231
+ res = context.compile_internal(builder, complex_abs, sig, args)
1232
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1233
+
1234
+
1235
+ ty = types.Complex
1236
+
1237
+ lower_builtin(operator.add, ty, ty)(complex_add_impl)
1238
+ lower_builtin(operator.iadd, ty, ty)(complex_add_impl)
1239
+ lower_builtin(operator.sub, ty, ty)(complex_sub_impl)
1240
+ lower_builtin(operator.isub, ty, ty)(complex_sub_impl)
1241
+ lower_builtin(operator.mul, ty, ty)(complex_mul_impl)
1242
+ lower_builtin(operator.imul, ty, ty)(complex_mul_impl)
1243
+ lower_builtin(operator.truediv, ty, ty)(complex_div_impl)
1244
+ lower_builtin(operator.itruediv, ty, ty)(complex_div_impl)
1245
+ lower_builtin(operator.neg, ty)(complex_negate_impl)
1246
+ lower_builtin(operator.pos, ty)(complex_positive_impl)
1247
+ # Complex modulo is deprecated in python3
1248
+
1249
+ lower_builtin(operator.eq, ty, ty)(complex_eq_impl)
1250
+ lower_builtin(operator.ne, ty, ty)(complex_ne_impl)
1251
+
1252
+ lower_builtin(abs, ty)(complex_abs_impl)
1253
+
1254
+ del ty
1255
+
1256
+
1257
+ @lower_builtin("number.item", types.Boolean)
1258
+ @lower_builtin("number.item", types.Number)
1259
+ def number_item_impl(context, builder, sig, args):
1260
+ """
1261
+ The no-op .item() method on booleans and numbers.
1262
+ """
1263
+ return args[0]
1264
+
1265
+
1266
+ # ------------------------------------------------------------------------------
1267
+
1268
+
1269
+ def number_not_impl(context, builder, sig, args):
1270
+ [typ] = sig.args
1271
+ [val] = args
1272
+ istrue = context.cast(builder, val, typ, sig.return_type)
1273
+ res = builder.not_(istrue)
1274
+ return impl_ret_untracked(context, builder, sig.return_type, res)
1275
+
1276
+
1277
+ @lower_builtin(bool, types.Boolean)
1278
+ def bool_as_bool(context, builder, sig, args):
1279
+ [val] = args
1280
+ return val
1281
+
1282
+
1283
+ @lower_builtin(bool, types.Integer)
1284
+ def int_as_bool(context, builder, sig, args):
1285
+ [val] = args
1286
+ return builder.icmp_unsigned("!=", val, Constant(val.type, 0))
1287
+
1288
+
1289
+ @lower_builtin(bool, types.Float)
1290
+ def float_as_bool(context, builder, sig, args):
1291
+ [val] = args
1292
+ return builder.fcmp_unordered("!=", val, Constant(val.type, 0.0))
1293
+
1294
+
1295
+ @lower_builtin(bool, types.Complex)
1296
+ def complex_as_bool(context, builder, sig, args):
1297
+ [typ] = sig.args
1298
+ [val] = args
1299
+ cmplx = context.make_complex(builder, typ, val)
1300
+ real, imag = cmplx.real, cmplx.imag
1301
+ zero = Constant(real.type, 0.0)
1302
+ real_istrue = builder.fcmp_unordered("!=", real, zero)
1303
+ imag_istrue = builder.fcmp_unordered("!=", imag, zero)
1304
+ return builder.or_(real_istrue, imag_istrue)
1305
+
1306
+
1307
+ for ty in (types.Integer, types.Float, types.Complex):
1308
+ lower_builtin(operator.not_, ty)(number_not_impl)
1309
+
1310
+ lower_builtin(operator.not_, types.boolean)(number_not_impl)
1311
+
1312
+
1313
+ # ------------------------------------------------------------------------------
1314
+ # Hashing numbers, see hashing.py
1315
+
1316
+ # -------------------------------------------------------------------------------
1317
+ # Implicit casts between numerics
1318
+
1319
+
1320
+ @lower_cast(types.IntegerLiteral, types.Integer)
1321
+ @lower_cast(types.IntegerLiteral, types.Float)
1322
+ @lower_cast(types.IntegerLiteral, types.Complex)
1323
+ def literal_int_to_number(context, builder, fromty, toty, val):
1324
+ lit = context.get_constant_generic(
1325
+ builder,
1326
+ fromty.literal_type,
1327
+ fromty.literal_value,
1328
+ )
1329
+ return context.cast(builder, lit, fromty.literal_type, toty)
1330
+
1331
+
1332
+ @lower_cast(types.Integer, types.Integer)
1333
+ def integer_to_integer(context, builder, fromty, toty, val):
1334
+ if toty.bitwidth == fromty.bitwidth:
1335
+ # Just a change of signedness
1336
+ return val
1337
+ elif toty.bitwidth < fromty.bitwidth:
1338
+ # Downcast
1339
+ return builder.trunc(val, context.get_value_type(toty))
1340
+ elif fromty.signed:
1341
+ # Signed upcast
1342
+ return builder.sext(val, context.get_value_type(toty))
1343
+ else:
1344
+ # Unsigned upcast
1345
+ return builder.zext(val, context.get_value_type(toty))
1346
+
1347
+
1348
+ @lower_cast(types.Integer, types.voidptr)
1349
+ def integer_to_voidptr(context, builder, fromty, toty, val):
1350
+ return builder.inttoptr(val, context.get_value_type(toty))
1351
+
1352
+
1353
+ @lower_cast(types.Float, types.Float)
1354
+ def float_to_float(context, builder, fromty, toty, val):
1355
+ lty = context.get_value_type(toty)
1356
+ if fromty.bitwidth < toty.bitwidth:
1357
+ return builder.fpext(val, lty)
1358
+ else:
1359
+ return builder.fptrunc(val, lty)
1360
+
1361
+
1362
+ @lower_cast(types.Integer, types.Float)
1363
+ def integer_to_float(context, builder, fromty, toty, val):
1364
+ lty = context.get_value_type(toty)
1365
+ if fromty.signed:
1366
+ return builder.sitofp(val, lty)
1367
+ else:
1368
+ return builder.uitofp(val, lty)
1369
+
1370
+
1371
+ @lower_cast(types.Float, types.Integer)
1372
+ def float_to_integer(context, builder, fromty, toty, val):
1373
+ lty = context.get_value_type(toty)
1374
+ if toty.signed:
1375
+ return builder.fptosi(val, lty)
1376
+ else:
1377
+ return builder.fptoui(val, lty)
1378
+
1379
+
1380
+ @lower_cast(types.Float, types.Complex)
1381
+ @lower_cast(types.Integer, types.Complex)
1382
+ def non_complex_to_complex(context, builder, fromty, toty, val):
1383
+ real = context.cast(builder, val, fromty, toty.underlying_float)
1384
+ imag = context.get_constant(toty.underlying_float, 0)
1385
+
1386
+ cmplx = context.make_complex(builder, toty)
1387
+ cmplx.real = real
1388
+ cmplx.imag = imag
1389
+ return cmplx._getvalue()
1390
+
1391
+
1392
+ @lower_cast(types.Complex, types.Complex)
1393
+ def complex_to_complex(context, builder, fromty, toty, val):
1394
+ srcty = fromty.underlying_float
1395
+ dstty = toty.underlying_float
1396
+
1397
+ src = context.make_complex(builder, fromty, value=val)
1398
+ dst = context.make_complex(builder, toty)
1399
+ dst.real = context.cast(builder, src.real, srcty, dstty)
1400
+ dst.imag = context.cast(builder, src.imag, srcty, dstty)
1401
+ return dst._getvalue()
1402
+
1403
+
1404
+ @lower_cast(types.Any, types.Boolean)
1405
+ def any_to_boolean(context, builder, fromty, toty, val):
1406
+ return context.is_true(builder, fromty, val)
1407
+
1408
+
1409
+ @lower_cast(types.Boolean, types.Number)
1410
+ def boolean_to_any(context, builder, fromty, toty, val):
1411
+ # Casting from boolean to anything first casts to int32
1412
+ asint = builder.zext(val, ir.IntType(32))
1413
+ return context.cast(builder, asint, types.int32, toty)
1414
+
1415
+
1416
+ @lower_cast(types.IntegerLiteral, types.Boolean)
1417
+ @lower_cast(types.BooleanLiteral, types.Boolean)
1418
+ def literal_int_to_boolean(context, builder, fromty, toty, val):
1419
+ lit = context.get_constant_generic(
1420
+ builder,
1421
+ fromty.literal_type,
1422
+ fromty.literal_value,
1423
+ )
1424
+ return context.is_true(builder, fromty.literal_type, lit)
1425
+
1426
+
1427
+ # -------------------------------------------------------------------------------
1428
+ # Constants
1429
+
1430
+
1431
+ @lower_constant(types.Complex)
1432
+ def constant_complex(context, builder, ty, pyval):
1433
+ fty = ty.underlying_float
1434
+ real = context.get_constant_generic(builder, fty, pyval.real)
1435
+ imag = context.get_constant_generic(builder, fty, pyval.imag)
1436
+ return Constant.literal_struct((real, imag))
1437
+
1438
+
1439
+ @lower_constant(types.Integer)
1440
+ @lower_constant(types.Float)
1441
+ @lower_constant(types.Boolean)
1442
+ def constant_integer(context, builder, ty, pyval):
1443
+ # See https://github.com/numba/numba/issues/6979
1444
+ # llvmlite ir.IntType specialises the formatting of the constant for a
1445
+ # cpython bool. A NumPy np.bool_ is not a cpython bool so force it to be one
1446
+ # so that the constant renders correctly!
1447
+ if isinstance(pyval, np.bool_):
1448
+ pyval = bool(pyval)
1449
+ lty = context.get_value_type(ty)
1450
+ return lty(pyval)
1451
+
1452
+
1453
+ # -------------------------------------------------------------------------------
1454
+ # View
1455
+
1456
+
1457
+ def scalar_view(scalar, viewty):
1458
+ """Typing for the np scalar 'view' method."""
1459
+ if isinstance(scalar, (types.Float, types.Integer)) and isinstance(
1460
+ viewty, types.abstract.DTypeSpec
1461
+ ):
1462
+ if scalar.bitwidth != viewty.dtype.bitwidth:
1463
+ raise errors.TypingError(
1464
+ "Changing the dtype of a 0d array is only supported if the "
1465
+ "itemsize is unchanged"
1466
+ )
1467
+
1468
+ def impl(scalar, viewty):
1469
+ return viewer(scalar, viewty)
1470
+
1471
+ return impl
1472
+
1473
+
1474
+ overload_method(types.Float, "view")(scalar_view)
1475
+ overload_method(types.Integer, "view")(scalar_view)