numba-cuda 0.22.1__cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +580 -0
  10. numba_cuda/numba/cuda/api_util.py +76 -0
  11. numba_cuda/numba/cuda/args.py +72 -0
  12. numba_cuda/numba/cuda/bf16.py +397 -0
  13. numba_cuda/numba/cuda/cache_hints.py +287 -0
  14. numba_cuda/numba/cuda/cext/__init__.py +2 -0
  15. numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
  16. numba_cuda/numba/cuda/cext/_devicearray.cpython-311-aarch64-linux-gnu.so +0 -0
  17. numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
  18. numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
  19. numba_cuda/numba/cuda/cext/_dispatcher.cpython-311-aarch64-linux-gnu.so +0 -0
  20. numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
  21. numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
  22. numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
  23. numba_cuda/numba/cuda/cext/_helperlib.cpython-311-aarch64-linux-gnu.so +0 -0
  24. numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
  25. numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
  26. numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
  27. numba_cuda/numba/cuda/cext/_typeconv.cpython-311-aarch64-linux-gnu.so +0 -0
  28. numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
  29. numba_cuda/numba/cuda/cext/_typeof.h +19 -0
  30. numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
  31. numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
  32. numba_cuda/numba/cuda/cext/mviewbuf.cpython-311-aarch64-linux-gnu.so +0 -0
  33. numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
  34. numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
  35. numba_cuda/numba/cuda/cg.py +67 -0
  36. numba_cuda/numba/cuda/cgutils.py +1294 -0
  37. numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
  38. numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
  39. numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
  40. numba_cuda/numba/cuda/codegen.py +541 -0
  41. numba_cuda/numba/cuda/compiler.py +1396 -0
  42. numba_cuda/numba/cuda/core/analysis.py +758 -0
  43. numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
  44. numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
  45. numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
  46. numba_cuda/numba/cuda/core/base.py +1332 -0
  47. numba_cuda/numba/cuda/core/boxing.py +1411 -0
  48. numba_cuda/numba/cuda/core/bytecode.py +728 -0
  49. numba_cuda/numba/cuda/core/byteflow.py +2346 -0
  50. numba_cuda/numba/cuda/core/caching.py +744 -0
  51. numba_cuda/numba/cuda/core/callconv.py +392 -0
  52. numba_cuda/numba/cuda/core/codegen.py +171 -0
  53. numba_cuda/numba/cuda/core/compiler.py +199 -0
  54. numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
  55. numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
  56. numba_cuda/numba/cuda/core/config.py +650 -0
  57. numba_cuda/numba/cuda/core/consts.py +124 -0
  58. numba_cuda/numba/cuda/core/controlflow.py +989 -0
  59. numba_cuda/numba/cuda/core/cuda_errors.py +917 -0
  60. numba_cuda/numba/cuda/core/entrypoints.py +57 -0
  61. numba_cuda/numba/cuda/core/environment.py +66 -0
  62. numba_cuda/numba/cuda/core/errors.py +9 -0
  63. numba_cuda/numba/cuda/core/event.py +511 -0
  64. numba_cuda/numba/cuda/core/funcdesc.py +330 -0
  65. numba_cuda/numba/cuda/core/generators.py +387 -0
  66. numba_cuda/numba/cuda/core/imputils.py +509 -0
  67. numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
  68. numba_cuda/numba/cuda/core/interpreter.py +3617 -0
  69. numba_cuda/numba/cuda/core/ir.py +1812 -0
  70. numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
  71. numba_cuda/numba/cuda/core/optional.py +129 -0
  72. numba_cuda/numba/cuda/core/options.py +262 -0
  73. numba_cuda/numba/cuda/core/postproc.py +249 -0
  74. numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
  75. numba_cuda/numba/cuda/core/registry.py +46 -0
  76. numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
  77. numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
  78. numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
  79. numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
  80. numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
  81. numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
  82. numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
  83. numba_cuda/numba/cuda/core/sigutils.py +68 -0
  84. numba_cuda/numba/cuda/core/ssa.py +498 -0
  85. numba_cuda/numba/cuda/core/targetconfig.py +330 -0
  86. numba_cuda/numba/cuda/core/tracing.py +231 -0
  87. numba_cuda/numba/cuda/core/transforms.py +956 -0
  88. numba_cuda/numba/cuda/core/typed_passes.py +867 -0
  89. numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
  90. numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
  91. numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
  92. numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
  93. numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
  94. numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
  95. numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
  96. numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
  97. numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
  98. numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
  99. numba_cuda/numba/cuda/cpython/iterators.py +167 -0
  100. numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
  101. numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
  102. numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
  103. numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
  104. numba_cuda/numba/cuda/cpython/slicing.py +322 -0
  105. numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
  106. numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
  107. numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
  108. numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
  109. numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
  110. numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
  111. numba_cuda/numba/cuda/cuda_paths.py +691 -0
  112. numba_cuda/numba/cuda/cudadecl.py +543 -0
  113. numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
  114. numba_cuda/numba/cuda/cudadrv/devicearray.py +954 -0
  115. numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
  116. numba_cuda/numba/cuda/cudadrv/driver.py +3238 -0
  117. numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
  118. numba_cuda/numba/cuda/cudadrv/dummyarray.py +562 -0
  119. numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
  120. numba_cuda/numba/cuda/cudadrv/error.py +48 -0
  121. numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
  122. numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
  123. numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
  124. numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
  125. numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
  126. numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
  127. numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
  128. numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
  129. numba_cuda/numba/cuda/cudaimpl.py +983 -0
  130. numba_cuda/numba/cuda/cudamath.py +149 -0
  131. numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
  132. numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
  133. numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
  134. numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
  135. numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
  136. numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
  137. numba_cuda/numba/cuda/datamodel/manager.py +11 -0
  138. numba_cuda/numba/cuda/datamodel/models.py +9 -0
  139. numba_cuda/numba/cuda/datamodel/packer.py +9 -0
  140. numba_cuda/numba/cuda/datamodel/registry.py +11 -0
  141. numba_cuda/numba/cuda/datamodel/testing.py +11 -0
  142. numba_cuda/numba/cuda/debuginfo.py +997 -0
  143. numba_cuda/numba/cuda/decorators.py +294 -0
  144. numba_cuda/numba/cuda/descriptor.py +35 -0
  145. numba_cuda/numba/cuda/device_init.py +155 -0
  146. numba_cuda/numba/cuda/deviceufunc.py +1021 -0
  147. numba_cuda/numba/cuda/dispatcher.py +2463 -0
  148. numba_cuda/numba/cuda/errors.py +72 -0
  149. numba_cuda/numba/cuda/extending.py +697 -0
  150. numba_cuda/numba/cuda/flags.py +178 -0
  151. numba_cuda/numba/cuda/fp16.py +357 -0
  152. numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
  153. numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
  154. numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
  155. numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
  156. numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
  157. numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
  158. numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
  159. numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
  160. numba_cuda/numba/cuda/initialize.py +24 -0
  161. numba_cuda/numba/cuda/intrinsics.py +531 -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 +1980 -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 +624 -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 +360 -0
  263. numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +191 -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 +200 -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 +978 -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 +446 -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 +452 -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.22.1.dist-info/METADATA +109 -0
  484. numba_cuda-0.22.1.dist-info/RECORD +488 -0
  485. numba_cuda-0.22.1.dist-info/WHEEL +6 -0
  486. numba_cuda-0.22.1.dist-info/licenses/LICENSE +26 -0
  487. numba_cuda-0.22.1.dist-info/licenses/LICENSE.numba +24 -0
  488. numba_cuda-0.22.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,969 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: BSD-2-Clause
3
+
4
+ """
5
+ Implementation of operations on numpy timedelta64.
6
+ """
7
+
8
+ import numpy as np
9
+ import operator
10
+
11
+ import llvmlite.ir
12
+ from llvmlite.ir import Constant
13
+
14
+ from numba.cuda import types
15
+ from numba.cuda import cgutils
16
+ from numba.cuda.cgutils import create_constant_array
17
+ from numba.cuda.core.imputils import (
18
+ impl_ret_untracked,
19
+ lower_cast,
20
+ Registry,
21
+ )
22
+ from numba.cuda.np import npdatetime_helpers, numpy_support, npyfuncs
23
+ from numba.cuda.extending import overload_method
24
+ from numba.cuda.core.config import IS_32BITS
25
+ from numba.cuda.core.errors import LoweringError
26
+
27
+ # datetime64 and timedelta64 use the same internal representation
28
+ DATETIME64 = TIMEDELTA64 = llvmlite.ir.IntType(64)
29
+ NAT = Constant(TIMEDELTA64, npdatetime_helpers.NAT)
30
+
31
+ TIMEDELTA_BINOP_SIG = (types.NPTimedelta,) * 2
32
+
33
+ registry = Registry("np.npdatetime")
34
+ lower = registry.lower
35
+ lower_constant = registry.lower_constant
36
+
37
+
38
+ def scale_by_constant(builder, val, factor):
39
+ """
40
+ Multiply *val* by the constant *factor*.
41
+ """
42
+ return builder.mul(val, Constant(TIMEDELTA64, factor))
43
+
44
+
45
+ def unscale_by_constant(builder, val, factor):
46
+ """
47
+ Divide *val* by the constant *factor*.
48
+ """
49
+ return builder.sdiv(val, Constant(TIMEDELTA64, factor))
50
+
51
+
52
+ def add_constant(builder, val, const):
53
+ """
54
+ Add constant *const* to *val*.
55
+ """
56
+ return builder.add(val, Constant(TIMEDELTA64, const))
57
+
58
+
59
+ def scale_timedelta(context, builder, val, srcty, destty):
60
+ """
61
+ Scale the timedelta64 *val* from *srcty* to *destty*
62
+ (both numba.types.NPTimedelta instances)
63
+ """
64
+ factor = npdatetime_helpers.get_timedelta_conversion_factor(
65
+ srcty.unit, destty.unit
66
+ )
67
+ if factor is None:
68
+ # This can happen when using explicit output in a ufunc.
69
+ msg = f"cannot convert timedelta64 from {srcty.unit} to {destty.unit}"
70
+ raise LoweringError(msg)
71
+ return scale_by_constant(builder, val, factor)
72
+
73
+
74
+ def normalize_timedeltas(context, builder, left, right, leftty, rightty):
75
+ """
76
+ Scale either *left* or *right* to the other's unit, in order to have
77
+ homogeneous units.
78
+ """
79
+ factor = npdatetime_helpers.get_timedelta_conversion_factor(
80
+ leftty.unit, rightty.unit
81
+ )
82
+ if factor is not None:
83
+ return scale_by_constant(builder, left, factor), right
84
+ factor = npdatetime_helpers.get_timedelta_conversion_factor(
85
+ rightty.unit, leftty.unit
86
+ )
87
+ if factor is not None:
88
+ return left, scale_by_constant(builder, right, factor)
89
+ # Typing should not let this happen, except on == and != operators
90
+ raise RuntimeError("cannot normalize %r and %r" % (leftty, rightty))
91
+
92
+
93
+ def alloc_timedelta_result(builder, name="ret"):
94
+ """
95
+ Allocate a NaT-initialized datetime64 (or timedelta64) result slot.
96
+ """
97
+ ret = cgutils.alloca_once(builder, TIMEDELTA64, name=name)
98
+ builder.store(NAT, ret)
99
+ return ret
100
+
101
+
102
+ def alloc_boolean_result(builder, name="ret"):
103
+ """
104
+ Allocate an uninitialized boolean result slot.
105
+ """
106
+ ret = cgutils.alloca_once(builder, llvmlite.ir.IntType(1), name=name)
107
+ return ret
108
+
109
+
110
+ def is_not_nat(builder, val):
111
+ """
112
+ Return a predicate which is true if *val* is not NaT.
113
+ """
114
+ return builder.icmp_unsigned("!=", val, NAT)
115
+
116
+
117
+ def are_not_nat(builder, vals):
118
+ """
119
+ Return a predicate which is true if all of *vals* are not NaT.
120
+ """
121
+ assert len(vals) >= 1
122
+ pred = is_not_nat(builder, vals[0])
123
+ for val in vals[1:]:
124
+ pred = builder.and_(pred, is_not_nat(builder, val))
125
+ return pred
126
+
127
+
128
+ normal_year_months = create_constant_array(
129
+ TIMEDELTA64, [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
130
+ )
131
+ leap_year_months = create_constant_array(
132
+ TIMEDELTA64, [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
133
+ )
134
+ normal_year_months_acc = create_constant_array(
135
+ TIMEDELTA64, [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
136
+ )
137
+ leap_year_months_acc = create_constant_array(
138
+ TIMEDELTA64, [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
139
+ )
140
+
141
+
142
+ @lower_constant(types.NPDatetime)
143
+ @lower_constant(types.NPTimedelta)
144
+ def datetime_constant(context, builder, ty, pyval):
145
+ return DATETIME64(pyval.astype(np.int64))
146
+
147
+
148
+ # Arithmetic operators on timedelta64
149
+
150
+
151
+ @lower(operator.pos, types.NPTimedelta)
152
+ def timedelta_pos_impl(context, builder, sig, args):
153
+ res = args[0]
154
+ return impl_ret_untracked(context, builder, sig.return_type, res)
155
+
156
+
157
+ @lower(operator.neg, types.NPTimedelta)
158
+ def timedelta_neg_impl(context, builder, sig, args):
159
+ res = builder.neg(args[0])
160
+ return impl_ret_untracked(context, builder, sig.return_type, res)
161
+
162
+
163
+ @lower(abs, types.NPTimedelta)
164
+ def timedelta_abs_impl(context, builder, sig, args):
165
+ (val,) = args
166
+ ret = alloc_timedelta_result(builder)
167
+ with builder.if_else(cgutils.is_scalar_neg(builder, val)) as (
168
+ then,
169
+ otherwise,
170
+ ):
171
+ with then:
172
+ builder.store(builder.neg(val), ret)
173
+ with otherwise:
174
+ builder.store(val, ret)
175
+ res = builder.load(ret)
176
+ return impl_ret_untracked(context, builder, sig.return_type, res)
177
+
178
+
179
+ def timedelta_sign_impl(context, builder, sig, args):
180
+ """
181
+ np.sign(timedelta64)
182
+ """
183
+ (val,) = args
184
+ ret = alloc_timedelta_result(builder)
185
+ zero = Constant(TIMEDELTA64, 0)
186
+ with builder.if_else(builder.icmp_signed(">", val, zero)) as (
187
+ gt_zero,
188
+ le_zero,
189
+ ):
190
+ with gt_zero:
191
+ builder.store(Constant(TIMEDELTA64, 1), ret)
192
+ with le_zero:
193
+ with builder.if_else(builder.icmp_unsigned("==", val, zero)) as (
194
+ eq_zero,
195
+ lt_zero,
196
+ ):
197
+ with eq_zero:
198
+ builder.store(Constant(TIMEDELTA64, 0), ret)
199
+ with lt_zero:
200
+ builder.store(Constant(TIMEDELTA64, -1), ret)
201
+ res = builder.load(ret)
202
+ return impl_ret_untracked(context, builder, sig.return_type, res)
203
+
204
+
205
+ @lower(operator.add, *TIMEDELTA_BINOP_SIG)
206
+ @lower(operator.iadd, *TIMEDELTA_BINOP_SIG)
207
+ def timedelta_add_impl(context, builder, sig, args):
208
+ [va, vb] = args
209
+ [ta, tb] = sig.args
210
+ ret = alloc_timedelta_result(builder)
211
+ with cgutils.if_likely(builder, are_not_nat(builder, [va, vb])):
212
+ va = scale_timedelta(context, builder, va, ta, sig.return_type)
213
+ vb = scale_timedelta(context, builder, vb, tb, sig.return_type)
214
+ builder.store(builder.add(va, vb), ret)
215
+ res = builder.load(ret)
216
+ return impl_ret_untracked(context, builder, sig.return_type, res)
217
+
218
+
219
+ @lower(operator.sub, *TIMEDELTA_BINOP_SIG)
220
+ @lower(operator.isub, *TIMEDELTA_BINOP_SIG)
221
+ def timedelta_sub_impl(context, builder, sig, args):
222
+ [va, vb] = args
223
+ [ta, tb] = sig.args
224
+ ret = alloc_timedelta_result(builder)
225
+ with cgutils.if_likely(builder, are_not_nat(builder, [va, vb])):
226
+ va = scale_timedelta(context, builder, va, ta, sig.return_type)
227
+ vb = scale_timedelta(context, builder, vb, tb, sig.return_type)
228
+ builder.store(builder.sub(va, vb), ret)
229
+ res = builder.load(ret)
230
+ return impl_ret_untracked(context, builder, sig.return_type, res)
231
+
232
+
233
+ def _timedelta_times_number(
234
+ context, builder, td_arg, td_type, number_arg, number_type, return_type
235
+ ):
236
+ ret = alloc_timedelta_result(builder)
237
+ with cgutils.if_likely(builder, is_not_nat(builder, td_arg)):
238
+ if isinstance(number_type, types.Float):
239
+ val = builder.sitofp(td_arg, number_arg.type)
240
+ val = builder.fmul(val, number_arg)
241
+ val = _cast_to_timedelta(context, builder, val)
242
+ else:
243
+ val = builder.mul(td_arg, number_arg)
244
+ # The scaling is required for ufunc np.multiply() with an explicit
245
+ # output in a different unit.
246
+ val = scale_timedelta(context, builder, val, td_type, return_type)
247
+ builder.store(val, ret)
248
+ return builder.load(ret)
249
+
250
+
251
+ @lower(operator.mul, types.NPTimedelta, types.Integer)
252
+ @lower(operator.imul, types.NPTimedelta, types.Integer)
253
+ @lower(operator.mul, types.NPTimedelta, types.Float)
254
+ @lower(operator.imul, types.NPTimedelta, types.Float)
255
+ def timedelta_times_number(context, builder, sig, args):
256
+ res = _timedelta_times_number(
257
+ context,
258
+ builder,
259
+ args[0],
260
+ sig.args[0],
261
+ args[1],
262
+ sig.args[1],
263
+ sig.return_type,
264
+ )
265
+ return impl_ret_untracked(context, builder, sig.return_type, res)
266
+
267
+
268
+ @lower(operator.mul, types.Integer, types.NPTimedelta)
269
+ @lower(operator.imul, types.Integer, types.NPTimedelta)
270
+ @lower(operator.mul, types.Float, types.NPTimedelta)
271
+ @lower(operator.imul, types.Float, types.NPTimedelta)
272
+ def number_times_timedelta(context, builder, sig, args):
273
+ res = _timedelta_times_number(
274
+ context,
275
+ builder,
276
+ args[1],
277
+ sig.args[1],
278
+ args[0],
279
+ sig.args[0],
280
+ sig.return_type,
281
+ )
282
+ return impl_ret_untracked(context, builder, sig.return_type, res)
283
+
284
+
285
+ @lower(operator.truediv, types.NPTimedelta, types.Integer)
286
+ @lower(operator.itruediv, types.NPTimedelta, types.Integer)
287
+ @lower(operator.floordiv, types.NPTimedelta, types.Integer)
288
+ @lower(operator.ifloordiv, types.NPTimedelta, types.Integer)
289
+ @lower(operator.truediv, types.NPTimedelta, types.Float)
290
+ @lower(operator.itruediv, types.NPTimedelta, types.Float)
291
+ @lower(operator.floordiv, types.NPTimedelta, types.Float)
292
+ @lower(operator.ifloordiv, types.NPTimedelta, types.Float)
293
+ def timedelta_over_number(context, builder, sig, args):
294
+ td_arg, number_arg = args
295
+ number_type = sig.args[1]
296
+ ret = alloc_timedelta_result(builder)
297
+ ok = builder.and_(
298
+ is_not_nat(builder, td_arg),
299
+ builder.not_(cgutils.is_scalar_zero_or_nan(builder, number_arg)),
300
+ )
301
+ with cgutils.if_likely(builder, ok):
302
+ # Denominator is non-zero, non-NaN
303
+ if isinstance(number_type, types.Float):
304
+ val = builder.sitofp(td_arg, number_arg.type)
305
+ val = builder.fdiv(val, number_arg)
306
+ val = _cast_to_timedelta(context, builder, val)
307
+ else:
308
+ val = builder.sdiv(td_arg, number_arg)
309
+ # The scaling is required for ufuncs np.*divide() with an explicit
310
+ # output in a different unit.
311
+ val = scale_timedelta(
312
+ context, builder, val, sig.args[0], sig.return_type
313
+ )
314
+ builder.store(val, ret)
315
+ res = builder.load(ret)
316
+ return impl_ret_untracked(context, builder, sig.return_type, res)
317
+
318
+
319
+ @lower(operator.truediv, *TIMEDELTA_BINOP_SIG)
320
+ @lower(operator.itruediv, *TIMEDELTA_BINOP_SIG)
321
+ def timedelta_over_timedelta(context, builder, sig, args):
322
+ [va, vb] = args
323
+ [ta, tb] = sig.args
324
+ not_nan = are_not_nat(builder, [va, vb])
325
+ ll_ret_type = context.get_value_type(sig.return_type)
326
+ ret = cgutils.alloca_once(builder, ll_ret_type, name="ret")
327
+ builder.store(Constant(ll_ret_type, float("nan")), ret)
328
+ with cgutils.if_likely(builder, not_nan):
329
+ va, vb = normalize_timedeltas(context, builder, va, vb, ta, tb)
330
+ va = builder.sitofp(va, ll_ret_type)
331
+ vb = builder.sitofp(vb, ll_ret_type)
332
+ builder.store(builder.fdiv(va, vb), ret)
333
+ res = builder.load(ret)
334
+ return impl_ret_untracked(context, builder, sig.return_type, res)
335
+
336
+
337
+ @lower(operator.floordiv, *TIMEDELTA_BINOP_SIG)
338
+ def timedelta_floor_div_timedelta(context, builder, sig, args):
339
+ [va, vb] = args
340
+ [ta, tb] = sig.args
341
+ ll_ret_type = context.get_value_type(sig.return_type)
342
+ not_nan = are_not_nat(builder, [va, vb])
343
+ ret = cgutils.alloca_once(builder, ll_ret_type, name="ret")
344
+ zero = Constant(ll_ret_type, 0)
345
+ one = Constant(ll_ret_type, 1)
346
+ builder.store(zero, ret)
347
+ with cgutils.if_likely(builder, not_nan):
348
+ va, vb = normalize_timedeltas(context, builder, va, vb, ta, tb)
349
+ # is the denominator zero or NaT?
350
+ denom_ok = builder.not_(builder.icmp_signed("==", vb, zero))
351
+ with cgutils.if_likely(builder, denom_ok):
352
+ # is either arg negative?
353
+ vaneg = builder.icmp_signed("<", va, zero)
354
+ neg = builder.or_(vaneg, builder.icmp_signed("<", vb, zero))
355
+ with builder.if_else(neg) as (then, otherwise):
356
+ with then: # one or more value negative
357
+ with builder.if_else(vaneg) as (negthen, negotherwise):
358
+ with negthen:
359
+ top = builder.sub(va, one)
360
+ div = builder.sdiv(top, vb)
361
+ builder.store(div, ret)
362
+ with negotherwise:
363
+ top = builder.add(va, one)
364
+ div = builder.sdiv(top, vb)
365
+ builder.store(div, ret)
366
+ with otherwise:
367
+ div = builder.sdiv(va, vb)
368
+ builder.store(div, ret)
369
+ res = builder.load(ret)
370
+ return impl_ret_untracked(context, builder, sig.return_type, res)
371
+
372
+
373
+ def timedelta_mod_timedelta(context, builder, sig, args):
374
+ # inspired by https://github.com/numpy/numpy/blob/fe8072a12d65e43bd2e0b0f9ad67ab0108cc54b3/numpy/core/src/umath/loops.c.src#L1424
375
+ # alg is basically as `a % b`:
376
+ # if a or b is NaT return NaT
377
+ # elseif b is 0 return NaT
378
+ # else pretend a and b are int and do pythonic int modulus
379
+
380
+ [va, vb] = args
381
+ [ta, tb] = sig.args
382
+ not_nan = are_not_nat(builder, [va, vb])
383
+ ll_ret_type = context.get_value_type(sig.return_type)
384
+ ret = alloc_timedelta_result(builder)
385
+ builder.store(NAT, ret)
386
+ zero = Constant(ll_ret_type, 0)
387
+ with cgutils.if_likely(builder, not_nan):
388
+ va, vb = normalize_timedeltas(context, builder, va, vb, ta, tb)
389
+ # is the denominator zero or NaT?
390
+ denom_ok = builder.not_(builder.icmp_signed("==", vb, zero))
391
+ with cgutils.if_likely(builder, denom_ok):
392
+ # is either arg negative?
393
+ vapos = builder.icmp_signed(">", va, zero)
394
+ vbpos = builder.icmp_signed(">", vb, zero)
395
+ rem = builder.srem(va, vb)
396
+ cond = builder.or_(
397
+ builder.and_(vapos, vbpos), builder.icmp_signed("==", rem, zero)
398
+ )
399
+ with builder.if_else(cond) as (then, otherwise):
400
+ with then:
401
+ builder.store(rem, ret)
402
+ with otherwise:
403
+ builder.store(builder.add(rem, vb), ret)
404
+
405
+ res = builder.load(ret)
406
+ return impl_ret_untracked(context, builder, sig.return_type, res)
407
+
408
+
409
+ # Comparison operators on timedelta64
410
+
411
+
412
+ def _create_timedelta_comparison_impl(ll_op, default_value):
413
+ def impl(context, builder, sig, args):
414
+ [va, vb] = args
415
+ [ta, tb] = sig.args
416
+ ret = alloc_boolean_result(builder)
417
+ with builder.if_else(are_not_nat(builder, [va, vb])) as (
418
+ then,
419
+ otherwise,
420
+ ):
421
+ with then:
422
+ try:
423
+ norm_a, norm_b = normalize_timedeltas(
424
+ context, builder, va, vb, ta, tb
425
+ )
426
+ except RuntimeError:
427
+ # Cannot normalize units => the values are unequal (except if NaT)
428
+ builder.store(default_value, ret)
429
+ else:
430
+ builder.store(
431
+ builder.icmp_unsigned(ll_op, norm_a, norm_b), ret
432
+ )
433
+ with otherwise:
434
+ # NaT ==/>=/>/</<= NaT is False
435
+ # NaT != <anything, including NaT> is True
436
+ if ll_op == "!=":
437
+ builder.store(cgutils.true_bit, ret)
438
+ else:
439
+ builder.store(cgutils.false_bit, ret)
440
+ res = builder.load(ret)
441
+ return impl_ret_untracked(context, builder, sig.return_type, res)
442
+
443
+ return impl
444
+
445
+
446
+ def _create_timedelta_ordering_impl(ll_op):
447
+ def impl(context, builder, sig, args):
448
+ [va, vb] = args
449
+ [ta, tb] = sig.args
450
+ ret = alloc_boolean_result(builder)
451
+ with builder.if_else(are_not_nat(builder, [va, vb])) as (
452
+ then,
453
+ otherwise,
454
+ ):
455
+ with then:
456
+ norm_a, norm_b = normalize_timedeltas(
457
+ context, builder, va, vb, ta, tb
458
+ )
459
+ builder.store(builder.icmp_signed(ll_op, norm_a, norm_b), ret)
460
+ with otherwise:
461
+ # NaT >=/>/</<= NaT is False
462
+ builder.store(cgutils.false_bit, ret)
463
+ res = builder.load(ret)
464
+ return impl_ret_untracked(context, builder, sig.return_type, res)
465
+
466
+ return impl
467
+
468
+
469
+ timedelta_eq_timedelta_impl = _create_timedelta_comparison_impl(
470
+ "==", cgutils.false_bit
471
+ )
472
+ timedelta_ne_timedelta_impl = _create_timedelta_comparison_impl(
473
+ "!=", cgutils.true_bit
474
+ )
475
+ timedelta_lt_timedelta_impl = _create_timedelta_ordering_impl("<")
476
+ timedelta_le_timedelta_impl = _create_timedelta_ordering_impl("<=")
477
+ timedelta_gt_timedelta_impl = _create_timedelta_ordering_impl(">")
478
+ timedelta_ge_timedelta_impl = _create_timedelta_ordering_impl(">=")
479
+
480
+ for op_, func in [
481
+ (operator.eq, timedelta_eq_timedelta_impl),
482
+ (operator.ne, timedelta_ne_timedelta_impl),
483
+ (operator.lt, timedelta_lt_timedelta_impl),
484
+ (operator.le, timedelta_le_timedelta_impl),
485
+ (operator.gt, timedelta_gt_timedelta_impl),
486
+ (operator.ge, timedelta_ge_timedelta_impl),
487
+ ]:
488
+ lower(op_, *TIMEDELTA_BINOP_SIG)(func)
489
+
490
+
491
+ # Arithmetic on datetime64
492
+
493
+
494
+ def is_leap_year(builder, year_val):
495
+ """
496
+ Return a predicate indicating whether *year_val* (offset by 1970) is a
497
+ leap year.
498
+ """
499
+ actual_year = builder.add(year_val, Constant(DATETIME64, 1970))
500
+ multiple_of_4 = cgutils.is_null(
501
+ builder, builder.and_(actual_year, Constant(DATETIME64, 3))
502
+ )
503
+ not_multiple_of_100 = cgutils.is_not_null(
504
+ builder, builder.srem(actual_year, Constant(DATETIME64, 100))
505
+ )
506
+ multiple_of_400 = cgutils.is_null(
507
+ builder, builder.srem(actual_year, Constant(DATETIME64, 400))
508
+ )
509
+ return builder.and_(
510
+ multiple_of_4, builder.or_(not_multiple_of_100, multiple_of_400)
511
+ )
512
+
513
+
514
+ def year_to_days(builder, year_val):
515
+ """
516
+ Given a year *year_val* (offset to 1970), return the number of days
517
+ since the 1970 epoch.
518
+ """
519
+ # The algorithm below is copied from Numpy's get_datetimestruct_days()
520
+ # (src/multiarray/datetime.c)
521
+ ret = cgutils.alloca_once(builder, TIMEDELTA64)
522
+ # First approximation
523
+ days = scale_by_constant(builder, year_val, 365)
524
+ # Adjust for leap years
525
+ with builder.if_else(cgutils.is_neg_int(builder, year_val)) as (
526
+ if_neg,
527
+ if_pos,
528
+ ):
529
+ with if_pos:
530
+ # At or after 1970:
531
+ # 1968 is the closest leap year before 1970.
532
+ # Exclude the current year, so add 1.
533
+ from_1968 = add_constant(builder, year_val, 1)
534
+ # Add one day for each 4 years
535
+ p_days = builder.add(
536
+ days, unscale_by_constant(builder, from_1968, 4)
537
+ )
538
+ # 1900 is the closest previous year divisible by 100
539
+ from_1900 = add_constant(builder, from_1968, 68)
540
+ # Subtract one day for each 100 years
541
+ p_days = builder.sub(
542
+ p_days, unscale_by_constant(builder, from_1900, 100)
543
+ )
544
+ # 1600 is the closest previous year divisible by 400
545
+ from_1600 = add_constant(builder, from_1900, 300)
546
+ # Add one day for each 400 years
547
+ p_days = builder.add(
548
+ p_days, unscale_by_constant(builder, from_1600, 400)
549
+ )
550
+ builder.store(p_days, ret)
551
+ with if_neg:
552
+ # Before 1970:
553
+ # NOTE `year_val` is negative, and so will be `from_1972` and `from_2000`.
554
+ # 1972 is the closest later year after 1970.
555
+ # Include the current year, so subtract 2.
556
+ from_1972 = add_constant(builder, year_val, -2)
557
+ # Subtract one day for each 4 years (`from_1972` is negative)
558
+ n_days = builder.add(
559
+ days, unscale_by_constant(builder, from_1972, 4)
560
+ )
561
+ # 2000 is the closest later year divisible by 100
562
+ from_2000 = add_constant(builder, from_1972, -28)
563
+ # Add one day for each 100 years
564
+ n_days = builder.sub(
565
+ n_days, unscale_by_constant(builder, from_2000, 100)
566
+ )
567
+ # 2000 is also the closest later year divisible by 400
568
+ # Subtract one day for each 400 years
569
+ n_days = builder.add(
570
+ n_days, unscale_by_constant(builder, from_2000, 400)
571
+ )
572
+ builder.store(n_days, ret)
573
+ return builder.load(ret)
574
+
575
+
576
+ def reduce_datetime_for_unit(builder, dt_val, src_unit, dest_unit):
577
+ dest_unit_code = npdatetime_helpers.DATETIME_UNITS[dest_unit]
578
+ src_unit_code = npdatetime_helpers.DATETIME_UNITS[src_unit]
579
+ if dest_unit_code < 2 or src_unit_code >= 2:
580
+ return dt_val, src_unit
581
+ # Need to compute the day ordinal for *dt_val*
582
+ if src_unit_code == 0:
583
+ # Years to days
584
+ year_val = dt_val
585
+ days_val = year_to_days(builder, year_val)
586
+
587
+ else:
588
+ # Months to days
589
+ leap_array = cgutils.global_constant(
590
+ builder, "leap_year_months_acc", leap_year_months_acc
591
+ )
592
+ normal_array = cgutils.global_constant(
593
+ builder, "normal_year_months_acc", normal_year_months_acc
594
+ )
595
+
596
+ days = cgutils.alloca_once(builder, TIMEDELTA64)
597
+
598
+ # First compute year number and month number
599
+ year, month = cgutils.divmod_by_constant(builder, dt_val, 12)
600
+
601
+ # Then deduce the number of days
602
+ with builder.if_else(is_leap_year(builder, year)) as (then, otherwise):
603
+ with then:
604
+ addend = builder.load(
605
+ cgutils.gep(builder, leap_array, 0, month, inbounds=True)
606
+ )
607
+ builder.store(addend, days)
608
+ with otherwise:
609
+ addend = builder.load(
610
+ cgutils.gep(builder, normal_array, 0, month, inbounds=True)
611
+ )
612
+ builder.store(addend, days)
613
+
614
+ days_val = year_to_days(builder, year)
615
+ days_val = builder.add(days_val, builder.load(days))
616
+
617
+ if dest_unit_code == 2:
618
+ # Need to scale back to weeks
619
+ weeks, _ = cgutils.divmod_by_constant(builder, days_val, 7)
620
+ return weeks, "W"
621
+ else:
622
+ return days_val, "D"
623
+
624
+
625
+ def convert_datetime_for_arith(builder, dt_val, src_unit, dest_unit):
626
+ """
627
+ Convert datetime *dt_val* from *src_unit* to *dest_unit*.
628
+ """
629
+ # First partial conversion to days or weeks, if necessary.
630
+ dt_val, dt_unit = reduce_datetime_for_unit(
631
+ builder, dt_val, src_unit, dest_unit
632
+ )
633
+ # Then multiply by the remaining constant factor.
634
+ dt_factor = npdatetime_helpers.get_timedelta_conversion_factor(
635
+ dt_unit, dest_unit
636
+ )
637
+ if dt_factor is None:
638
+ # This can happen when using explicit output in a ufunc.
639
+ raise LoweringError(
640
+ "cannot convert datetime64 from %r to %r" % (src_unit, dest_unit)
641
+ )
642
+ return scale_by_constant(builder, dt_val, dt_factor)
643
+
644
+
645
+ def _datetime_timedelta_arith(ll_op_name):
646
+ def impl(context, builder, dt_arg, dt_unit, td_arg, td_unit, ret_unit):
647
+ ret = alloc_timedelta_result(builder)
648
+ with cgutils.if_likely(builder, are_not_nat(builder, [dt_arg, td_arg])):
649
+ dt_arg = convert_datetime_for_arith(
650
+ builder, dt_arg, dt_unit, ret_unit
651
+ )
652
+ td_factor = npdatetime_helpers.get_timedelta_conversion_factor(
653
+ td_unit, ret_unit
654
+ )
655
+ td_arg = scale_by_constant(builder, td_arg, td_factor)
656
+ ret_val = getattr(builder, ll_op_name)(dt_arg, td_arg)
657
+ builder.store(ret_val, ret)
658
+ return builder.load(ret)
659
+
660
+ return impl
661
+
662
+
663
+ _datetime_plus_timedelta = _datetime_timedelta_arith("add")
664
+ _datetime_minus_timedelta = _datetime_timedelta_arith("sub")
665
+
666
+ # datetime64 + timedelta64
667
+
668
+
669
+ @lower(operator.add, types.NPDatetime, types.NPTimedelta)
670
+ @lower(operator.iadd, types.NPDatetime, types.NPTimedelta)
671
+ def datetime_plus_timedelta(context, builder, sig, args):
672
+ dt_arg, td_arg = args
673
+ dt_type, td_type = sig.args
674
+ res = _datetime_plus_timedelta(
675
+ context,
676
+ builder,
677
+ dt_arg,
678
+ dt_type.unit,
679
+ td_arg,
680
+ td_type.unit,
681
+ sig.return_type.unit,
682
+ )
683
+ return impl_ret_untracked(context, builder, sig.return_type, res)
684
+
685
+
686
+ @lower(operator.add, types.NPTimedelta, types.NPDatetime)
687
+ @lower(operator.iadd, types.NPTimedelta, types.NPDatetime)
688
+ def timedelta_plus_datetime(context, builder, sig, args):
689
+ td_arg, dt_arg = args
690
+ td_type, dt_type = sig.args
691
+ res = _datetime_plus_timedelta(
692
+ context,
693
+ builder,
694
+ dt_arg,
695
+ dt_type.unit,
696
+ td_arg,
697
+ td_type.unit,
698
+ sig.return_type.unit,
699
+ )
700
+ return impl_ret_untracked(context, builder, sig.return_type, res)
701
+
702
+
703
+ # datetime64 - timedelta64
704
+
705
+
706
+ @lower(operator.sub, types.NPDatetime, types.NPTimedelta)
707
+ @lower(operator.isub, types.NPDatetime, types.NPTimedelta)
708
+ def datetime_minus_timedelta(context, builder, sig, args):
709
+ dt_arg, td_arg = args
710
+ dt_type, td_type = sig.args
711
+ res = _datetime_minus_timedelta(
712
+ context,
713
+ builder,
714
+ dt_arg,
715
+ dt_type.unit,
716
+ td_arg,
717
+ td_type.unit,
718
+ sig.return_type.unit,
719
+ )
720
+ return impl_ret_untracked(context, builder, sig.return_type, res)
721
+
722
+
723
+ # datetime64 - datetime64
724
+
725
+
726
+ @lower(operator.sub, types.NPDatetime, types.NPDatetime)
727
+ def datetime_minus_datetime(context, builder, sig, args):
728
+ va, vb = args
729
+ ta, tb = sig.args
730
+ unit_a = ta.unit
731
+ unit_b = tb.unit
732
+ ret_unit = sig.return_type.unit
733
+ ret = alloc_timedelta_result(builder)
734
+ with cgutils.if_likely(builder, are_not_nat(builder, [va, vb])):
735
+ va = convert_datetime_for_arith(builder, va, unit_a, ret_unit)
736
+ vb = convert_datetime_for_arith(builder, vb, unit_b, ret_unit)
737
+ ret_val = builder.sub(va, vb)
738
+ builder.store(ret_val, ret)
739
+ res = builder.load(ret)
740
+ return impl_ret_untracked(context, builder, sig.return_type, res)
741
+
742
+
743
+ # datetime64 comparisons
744
+
745
+
746
+ def _create_datetime_comparison_impl(ll_op):
747
+ def impl(context, builder, sig, args):
748
+ va, vb = args
749
+ ta, tb = sig.args
750
+ unit_a = ta.unit
751
+ unit_b = tb.unit
752
+ ret_unit = npdatetime_helpers.get_best_unit(unit_a, unit_b)
753
+ ret = alloc_boolean_result(builder)
754
+ with builder.if_else(are_not_nat(builder, [va, vb])) as (
755
+ then,
756
+ otherwise,
757
+ ):
758
+ with then:
759
+ norm_a = convert_datetime_for_arith(
760
+ builder, va, unit_a, ret_unit
761
+ )
762
+ norm_b = convert_datetime_for_arith(
763
+ builder, vb, unit_b, ret_unit
764
+ )
765
+ ret_val = builder.icmp_signed(ll_op, norm_a, norm_b)
766
+ builder.store(ret_val, ret)
767
+ with otherwise:
768
+ if ll_op == "!=":
769
+ ret_val = cgutils.true_bit
770
+ else:
771
+ ret_val = cgutils.false_bit
772
+ builder.store(ret_val, ret)
773
+ res = builder.load(ret)
774
+ return impl_ret_untracked(context, builder, sig.return_type, res)
775
+
776
+ return impl
777
+
778
+
779
+ datetime_eq_datetime_impl = _create_datetime_comparison_impl("==")
780
+ datetime_ne_datetime_impl = _create_datetime_comparison_impl("!=")
781
+ datetime_lt_datetime_impl = _create_datetime_comparison_impl("<")
782
+ datetime_le_datetime_impl = _create_datetime_comparison_impl("<=")
783
+ datetime_gt_datetime_impl = _create_datetime_comparison_impl(">")
784
+ datetime_ge_datetime_impl = _create_datetime_comparison_impl(">=")
785
+
786
+ for op, func in [
787
+ (operator.eq, datetime_eq_datetime_impl),
788
+ (operator.ne, datetime_ne_datetime_impl),
789
+ (operator.lt, datetime_lt_datetime_impl),
790
+ (operator.le, datetime_le_datetime_impl),
791
+ (operator.gt, datetime_gt_datetime_impl),
792
+ (operator.ge, datetime_ge_datetime_impl),
793
+ ]:
794
+ lower(op, *[types.NPDatetime] * 2)(func)
795
+
796
+
797
+ ########################################################################
798
+ # datetime/timedelta fmax/fmin maximum/minimum support
799
+
800
+
801
+ def _gen_datetime_max_impl(NAT_DOMINATES):
802
+ def datetime_max_impl(context, builder, sig, args):
803
+ # note this could be optimizing relying on the actual value of NAT
804
+ # but as NumPy doesn't rely on this, this seems more resilient
805
+ in1, in2 = args
806
+ in1_not_nat = is_not_nat(builder, in1)
807
+ in2_not_nat = is_not_nat(builder, in2)
808
+ in1_ge_in2 = builder.icmp_signed(">=", in1, in2)
809
+ res = builder.select(in1_ge_in2, in1, in2)
810
+ if NAT_DOMINATES:
811
+ # NaT now dominates, like NaN
812
+ in1, in2 = in2, in1
813
+ res = builder.select(in1_not_nat, res, in2)
814
+ res = builder.select(in2_not_nat, res, in1)
815
+
816
+ return impl_ret_untracked(context, builder, sig.return_type, res)
817
+
818
+ return datetime_max_impl
819
+
820
+
821
+ datetime_maximum_impl = _gen_datetime_max_impl(True)
822
+ datetime_fmax_impl = _gen_datetime_max_impl(False)
823
+
824
+
825
+ def _gen_datetime_min_impl(NAT_DOMINATES):
826
+ def datetime_min_impl(context, builder, sig, args):
827
+ # note this could be optimizing relying on the actual value of NAT
828
+ # but as NumPy doesn't rely on this, this seems more resilient
829
+ in1, in2 = args
830
+ in1_not_nat = is_not_nat(builder, in1)
831
+ in2_not_nat = is_not_nat(builder, in2)
832
+ in1_le_in2 = builder.icmp_signed("<=", in1, in2)
833
+ res = builder.select(in1_le_in2, in1, in2)
834
+ if NAT_DOMINATES:
835
+ # NaT now dominates, like NaN
836
+ in1, in2 = in2, in1
837
+ res = builder.select(in1_not_nat, res, in2)
838
+ res = builder.select(in2_not_nat, res, in1)
839
+
840
+ return impl_ret_untracked(context, builder, sig.return_type, res)
841
+
842
+ return datetime_min_impl
843
+
844
+
845
+ datetime_minimum_impl = _gen_datetime_min_impl(True)
846
+ datetime_fmin_impl = _gen_datetime_min_impl(False)
847
+
848
+
849
+ def _gen_timedelta_max_impl(NAT_DOMINATES):
850
+ def timedelta_max_impl(context, builder, sig, args):
851
+ # note this could be optimizing relying on the actual value of NAT
852
+ # but as NumPy doesn't rely on this, this seems more resilient
853
+ in1, in2 = args
854
+ in1_not_nat = is_not_nat(builder, in1)
855
+ in2_not_nat = is_not_nat(builder, in2)
856
+ in1_ge_in2 = builder.icmp_signed(">=", in1, in2)
857
+ res = builder.select(in1_ge_in2, in1, in2)
858
+ if NAT_DOMINATES:
859
+ # NaT now dominates, like NaN
860
+ in1, in2 = in2, in1
861
+ res = builder.select(in1_not_nat, res, in2)
862
+ res = builder.select(in2_not_nat, res, in1)
863
+
864
+ return impl_ret_untracked(context, builder, sig.return_type, res)
865
+
866
+ return timedelta_max_impl
867
+
868
+
869
+ timedelta_maximum_impl = _gen_timedelta_max_impl(True)
870
+ timedelta_fmax_impl = _gen_timedelta_max_impl(False)
871
+
872
+
873
+ def _gen_timedelta_min_impl(NAT_DOMINATES):
874
+ def timedelta_min_impl(context, builder, sig, args):
875
+ # note this could be optimizing relying on the actual value of NAT
876
+ # but as NumPy doesn't rely on this, this seems more resilient
877
+ in1, in2 = args
878
+ in1_not_nat = is_not_nat(builder, in1)
879
+ in2_not_nat = is_not_nat(builder, in2)
880
+ in1_le_in2 = builder.icmp_signed("<=", in1, in2)
881
+ res = builder.select(in1_le_in2, in1, in2)
882
+ if NAT_DOMINATES:
883
+ # NaT now dominates, like NaN
884
+ in1, in2 = in2, in1
885
+ res = builder.select(in1_not_nat, res, in2)
886
+ res = builder.select(in2_not_nat, res, in1)
887
+
888
+ return impl_ret_untracked(context, builder, sig.return_type, res)
889
+
890
+ return timedelta_min_impl
891
+
892
+
893
+ timedelta_minimum_impl = _gen_timedelta_min_impl(True)
894
+ timedelta_fmin_impl = _gen_timedelta_min_impl(False)
895
+
896
+
897
+ def _cast_to_timedelta(context, builder, val):
898
+ temp = builder.alloca(TIMEDELTA64)
899
+ val_is_nan = builder.fcmp_unordered("uno", val, val)
900
+ with builder.if_else(val_is_nan) as (then, els):
901
+ with then:
902
+ # NaN does not guarantee to cast to NAT.
903
+ # We should store NAT explicitly.
904
+ builder.store(NAT, temp)
905
+ with els:
906
+ builder.store(builder.fptosi(val, TIMEDELTA64), temp)
907
+ return builder.load(temp)
908
+
909
+
910
+ @lower(np.isnat, types.NPDatetime)
911
+ @lower(np.isnat, types.NPTimedelta)
912
+ def _np_isnat_impl(context, builder, sig, args):
913
+ return npyfuncs.np_datetime_isnat_impl(context, builder, sig, args)
914
+
915
+
916
+ @lower_cast(types.NPDatetime, types.Integer)
917
+ @lower_cast(types.NPTimedelta, types.Integer)
918
+ def _cast_npdatetime_int64(context, builder, fromty, toty, val):
919
+ if toty.bitwidth != 64: # all date time types are 64 bit
920
+ msg = f"Cannot cast {fromty} to {toty} as {toty} is not 64 bits wide."
921
+ raise ValueError(msg)
922
+ return val
923
+
924
+
925
+ @overload_method(types.NPTimedelta, "__hash__")
926
+ @overload_method(types.NPDatetime, "__hash__")
927
+ def ol_hash_npdatetime(x):
928
+ if (
929
+ numpy_support.numpy_version >= (2, 2)
930
+ and isinstance(x, types.NPTimedelta)
931
+ and not x.unit
932
+ ):
933
+ raise ValueError("Can't hash generic timedelta64")
934
+
935
+ if IS_32BITS:
936
+
937
+ def impl(x):
938
+ x = np.int64(x)
939
+ if x < 2**31 - 1: # x < LONG_MAX
940
+ y = np.int32(x)
941
+ else:
942
+ hi = (np.int64(x) & 0xFFFFFFFF00000000) >> 32
943
+ lo = np.int64(x) & 0x00000000FFFFFFFF
944
+ y = np.int32(lo + (1000003) * hi)
945
+ if y == -1:
946
+ y = np.int32(-2)
947
+ return y
948
+ else:
949
+
950
+ def impl(x):
951
+ if np.int64(x) == -1:
952
+ return np.int64(-2)
953
+ return np.int64(x)
954
+
955
+ return impl
956
+
957
+
958
+ lower(npdatetime_helpers.datetime_minimum, types.NPDatetime, types.NPDatetime)(
959
+ datetime_minimum_impl
960
+ )
961
+ lower(
962
+ npdatetime_helpers.datetime_minimum, types.NPTimedelta, types.NPTimedelta
963
+ )(datetime_minimum_impl)
964
+ lower(npdatetime_helpers.datetime_maximum, types.NPDatetime, types.NPDatetime)(
965
+ datetime_maximum_impl
966
+ )
967
+ lower(
968
+ npdatetime_helpers.datetime_maximum, types.NPTimedelta, types.NPTimedelta
969
+ )(datetime_maximum_impl)