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.
- _numba_cuda_redirector.pth +4 -0
- _numba_cuda_redirector.py +89 -0
- numba_cuda/VERSION +1 -0
- numba_cuda/__init__.py +6 -0
- numba_cuda/_version.py +11 -0
- numba_cuda/numba/cuda/__init__.py +70 -0
- numba_cuda/numba/cuda/_internal/cuda_bf16.py +16394 -0
- numba_cuda/numba/cuda/_internal/cuda_fp16.py +8112 -0
- numba_cuda/numba/cuda/api.py +580 -0
- numba_cuda/numba/cuda/api_util.py +76 -0
- numba_cuda/numba/cuda/args.py +72 -0
- numba_cuda/numba/cuda/bf16.py +397 -0
- numba_cuda/numba/cuda/cache_hints.py +287 -0
- numba_cuda/numba/cuda/cext/__init__.py +2 -0
- numba_cuda/numba/cuda/cext/_devicearray.cpp +159 -0
- numba_cuda/numba/cuda/cext/_devicearray.cpython-311-aarch64-linux-gnu.so +0 -0
- numba_cuda/numba/cuda/cext/_devicearray.h +29 -0
- numba_cuda/numba/cuda/cext/_dispatcher.cpp +1098 -0
- numba_cuda/numba/cuda/cext/_dispatcher.cpython-311-aarch64-linux-gnu.so +0 -0
- numba_cuda/numba/cuda/cext/_hashtable.cpp +532 -0
- numba_cuda/numba/cuda/cext/_hashtable.h +135 -0
- numba_cuda/numba/cuda/cext/_helperlib.c +71 -0
- numba_cuda/numba/cuda/cext/_helperlib.cpython-311-aarch64-linux-gnu.so +0 -0
- numba_cuda/numba/cuda/cext/_helpermod.c +82 -0
- numba_cuda/numba/cuda/cext/_pymodule.h +38 -0
- numba_cuda/numba/cuda/cext/_typeconv.cpp +206 -0
- numba_cuda/numba/cuda/cext/_typeconv.cpython-311-aarch64-linux-gnu.so +0 -0
- numba_cuda/numba/cuda/cext/_typeof.cpp +1159 -0
- numba_cuda/numba/cuda/cext/_typeof.h +19 -0
- numba_cuda/numba/cuda/cext/capsulethunk.h +111 -0
- numba_cuda/numba/cuda/cext/mviewbuf.c +385 -0
- numba_cuda/numba/cuda/cext/mviewbuf.cpython-311-aarch64-linux-gnu.so +0 -0
- numba_cuda/numba/cuda/cext/typeconv.cpp +212 -0
- numba_cuda/numba/cuda/cext/typeconv.hpp +101 -0
- numba_cuda/numba/cuda/cg.py +67 -0
- numba_cuda/numba/cuda/cgutils.py +1294 -0
- numba_cuda/numba/cuda/cloudpickle/__init__.py +21 -0
- numba_cuda/numba/cuda/cloudpickle/cloudpickle.py +1598 -0
- numba_cuda/numba/cuda/cloudpickle/cloudpickle_fast.py +17 -0
- numba_cuda/numba/cuda/codegen.py +541 -0
- numba_cuda/numba/cuda/compiler.py +1396 -0
- numba_cuda/numba/cuda/core/analysis.py +758 -0
- numba_cuda/numba/cuda/core/annotations/__init__.py +0 -0
- numba_cuda/numba/cuda/core/annotations/pretty_annotate.py +288 -0
- numba_cuda/numba/cuda/core/annotations/type_annotations.py +305 -0
- numba_cuda/numba/cuda/core/base.py +1332 -0
- numba_cuda/numba/cuda/core/boxing.py +1411 -0
- numba_cuda/numba/cuda/core/bytecode.py +728 -0
- numba_cuda/numba/cuda/core/byteflow.py +2346 -0
- numba_cuda/numba/cuda/core/caching.py +744 -0
- numba_cuda/numba/cuda/core/callconv.py +392 -0
- numba_cuda/numba/cuda/core/codegen.py +171 -0
- numba_cuda/numba/cuda/core/compiler.py +199 -0
- numba_cuda/numba/cuda/core/compiler_lock.py +85 -0
- numba_cuda/numba/cuda/core/compiler_machinery.py +497 -0
- numba_cuda/numba/cuda/core/config.py +650 -0
- numba_cuda/numba/cuda/core/consts.py +124 -0
- numba_cuda/numba/cuda/core/controlflow.py +989 -0
- numba_cuda/numba/cuda/core/cuda_errors.py +917 -0
- numba_cuda/numba/cuda/core/entrypoints.py +57 -0
- numba_cuda/numba/cuda/core/environment.py +66 -0
- numba_cuda/numba/cuda/core/errors.py +9 -0
- numba_cuda/numba/cuda/core/event.py +511 -0
- numba_cuda/numba/cuda/core/funcdesc.py +330 -0
- numba_cuda/numba/cuda/core/generators.py +387 -0
- numba_cuda/numba/cuda/core/imputils.py +509 -0
- numba_cuda/numba/cuda/core/inline_closurecall.py +1787 -0
- numba_cuda/numba/cuda/core/interpreter.py +3617 -0
- numba_cuda/numba/cuda/core/ir.py +1812 -0
- numba_cuda/numba/cuda/core/ir_utils.py +2638 -0
- numba_cuda/numba/cuda/core/optional.py +129 -0
- numba_cuda/numba/cuda/core/options.py +262 -0
- numba_cuda/numba/cuda/core/postproc.py +249 -0
- numba_cuda/numba/cuda/core/pythonapi.py +1859 -0
- numba_cuda/numba/cuda/core/registry.py +46 -0
- numba_cuda/numba/cuda/core/removerefctpass.py +123 -0
- numba_cuda/numba/cuda/core/rewrites/__init__.py +26 -0
- numba_cuda/numba/cuda/core/rewrites/ir_print.py +91 -0
- numba_cuda/numba/cuda/core/rewrites/registry.py +104 -0
- numba_cuda/numba/cuda/core/rewrites/static_binop.py +41 -0
- numba_cuda/numba/cuda/core/rewrites/static_getitem.py +189 -0
- numba_cuda/numba/cuda/core/rewrites/static_raise.py +100 -0
- numba_cuda/numba/cuda/core/sigutils.py +68 -0
- numba_cuda/numba/cuda/core/ssa.py +498 -0
- numba_cuda/numba/cuda/core/targetconfig.py +330 -0
- numba_cuda/numba/cuda/core/tracing.py +231 -0
- numba_cuda/numba/cuda/core/transforms.py +956 -0
- numba_cuda/numba/cuda/core/typed_passes.py +867 -0
- numba_cuda/numba/cuda/core/typeinfer.py +1950 -0
- numba_cuda/numba/cuda/core/unsafe/__init__.py +0 -0
- numba_cuda/numba/cuda/core/unsafe/bytes.py +67 -0
- numba_cuda/numba/cuda/core/unsafe/eh.py +67 -0
- numba_cuda/numba/cuda/core/unsafe/refcount.py +98 -0
- numba_cuda/numba/cuda/core/untyped_passes.py +1979 -0
- numba_cuda/numba/cuda/cpython/builtins.py +1153 -0
- numba_cuda/numba/cuda/cpython/charseq.py +1218 -0
- numba_cuda/numba/cuda/cpython/cmathimpl.py +560 -0
- numba_cuda/numba/cuda/cpython/enumimpl.py +103 -0
- numba_cuda/numba/cuda/cpython/iterators.py +167 -0
- numba_cuda/numba/cuda/cpython/listobj.py +1326 -0
- numba_cuda/numba/cuda/cpython/mathimpl.py +499 -0
- numba_cuda/numba/cuda/cpython/numbers.py +1475 -0
- numba_cuda/numba/cuda/cpython/rangeobj.py +289 -0
- numba_cuda/numba/cuda/cpython/slicing.py +322 -0
- numba_cuda/numba/cuda/cpython/tupleobj.py +456 -0
- numba_cuda/numba/cuda/cpython/unicode.py +2865 -0
- numba_cuda/numba/cuda/cpython/unicode_support.py +1597 -0
- numba_cuda/numba/cuda/cpython/unsafe/__init__.py +0 -0
- numba_cuda/numba/cuda/cpython/unsafe/numbers.py +64 -0
- numba_cuda/numba/cuda/cpython/unsafe/tuple.py +92 -0
- numba_cuda/numba/cuda/cuda_paths.py +691 -0
- numba_cuda/numba/cuda/cudadecl.py +543 -0
- numba_cuda/numba/cuda/cudadrv/__init__.py +14 -0
- numba_cuda/numba/cuda/cudadrv/devicearray.py +954 -0
- numba_cuda/numba/cuda/cudadrv/devices.py +249 -0
- numba_cuda/numba/cuda/cudadrv/driver.py +3238 -0
- numba_cuda/numba/cuda/cudadrv/drvapi.py +435 -0
- numba_cuda/numba/cuda/cudadrv/dummyarray.py +562 -0
- numba_cuda/numba/cuda/cudadrv/enums.py +613 -0
- numba_cuda/numba/cuda/cudadrv/error.py +48 -0
- numba_cuda/numba/cuda/cudadrv/libs.py +220 -0
- numba_cuda/numba/cuda/cudadrv/linkable_code.py +184 -0
- numba_cuda/numba/cuda/cudadrv/mappings.py +14 -0
- numba_cuda/numba/cuda/cudadrv/ndarray.py +26 -0
- numba_cuda/numba/cuda/cudadrv/nvrtc.py +193 -0
- numba_cuda/numba/cuda/cudadrv/nvvm.py +756 -0
- numba_cuda/numba/cuda/cudadrv/rtapi.py +13 -0
- numba_cuda/numba/cuda/cudadrv/runtime.py +34 -0
- numba_cuda/numba/cuda/cudaimpl.py +983 -0
- numba_cuda/numba/cuda/cudamath.py +149 -0
- numba_cuda/numba/cuda/datamodel/__init__.py +7 -0
- numba_cuda/numba/cuda/datamodel/cuda_manager.py +66 -0
- numba_cuda/numba/cuda/datamodel/cuda_models.py +1446 -0
- numba_cuda/numba/cuda/datamodel/cuda_packer.py +224 -0
- numba_cuda/numba/cuda/datamodel/cuda_registry.py +22 -0
- numba_cuda/numba/cuda/datamodel/cuda_testing.py +153 -0
- numba_cuda/numba/cuda/datamodel/manager.py +11 -0
- numba_cuda/numba/cuda/datamodel/models.py +9 -0
- numba_cuda/numba/cuda/datamodel/packer.py +9 -0
- numba_cuda/numba/cuda/datamodel/registry.py +11 -0
- numba_cuda/numba/cuda/datamodel/testing.py +11 -0
- numba_cuda/numba/cuda/debuginfo.py +997 -0
- numba_cuda/numba/cuda/decorators.py +294 -0
- numba_cuda/numba/cuda/descriptor.py +35 -0
- numba_cuda/numba/cuda/device_init.py +155 -0
- numba_cuda/numba/cuda/deviceufunc.py +1021 -0
- numba_cuda/numba/cuda/dispatcher.py +2463 -0
- numba_cuda/numba/cuda/errors.py +72 -0
- numba_cuda/numba/cuda/extending.py +697 -0
- numba_cuda/numba/cuda/flags.py +178 -0
- numba_cuda/numba/cuda/fp16.py +357 -0
- numba_cuda/numba/cuda/include/12/cuda_bf16.h +5118 -0
- numba_cuda/numba/cuda/include/12/cuda_bf16.hpp +3865 -0
- numba_cuda/numba/cuda/include/12/cuda_fp16.h +5363 -0
- numba_cuda/numba/cuda/include/12/cuda_fp16.hpp +3483 -0
- numba_cuda/numba/cuda/include/13/cuda_bf16.h +5118 -0
- numba_cuda/numba/cuda/include/13/cuda_bf16.hpp +3865 -0
- numba_cuda/numba/cuda/include/13/cuda_fp16.h +5363 -0
- numba_cuda/numba/cuda/include/13/cuda_fp16.hpp +3483 -0
- numba_cuda/numba/cuda/initialize.py +24 -0
- numba_cuda/numba/cuda/intrinsics.py +531 -0
- numba_cuda/numba/cuda/itanium_mangler.py +214 -0
- numba_cuda/numba/cuda/kernels/__init__.py +2 -0
- numba_cuda/numba/cuda/kernels/reduction.py +265 -0
- numba_cuda/numba/cuda/kernels/transpose.py +65 -0
- numba_cuda/numba/cuda/libdevice.py +3386 -0
- numba_cuda/numba/cuda/libdevicedecl.py +20 -0
- numba_cuda/numba/cuda/libdevicefuncs.py +1060 -0
- numba_cuda/numba/cuda/libdeviceimpl.py +88 -0
- numba_cuda/numba/cuda/locks.py +19 -0
- numba_cuda/numba/cuda/lowering.py +1980 -0
- numba_cuda/numba/cuda/mathimpl.py +374 -0
- numba_cuda/numba/cuda/memory_management/__init__.py +4 -0
- numba_cuda/numba/cuda/memory_management/memsys.cu +99 -0
- numba_cuda/numba/cuda/memory_management/memsys.cuh +22 -0
- numba_cuda/numba/cuda/memory_management/nrt.cu +212 -0
- numba_cuda/numba/cuda/memory_management/nrt.cuh +48 -0
- numba_cuda/numba/cuda/memory_management/nrt.py +390 -0
- numba_cuda/numba/cuda/memory_management/nrt_context.py +438 -0
- numba_cuda/numba/cuda/misc/appdirs.py +594 -0
- numba_cuda/numba/cuda/misc/cffiimpl.py +24 -0
- numba_cuda/numba/cuda/misc/coverage_support.py +43 -0
- numba_cuda/numba/cuda/misc/dump_style.py +41 -0
- numba_cuda/numba/cuda/misc/findlib.py +75 -0
- numba_cuda/numba/cuda/misc/firstlinefinder.py +96 -0
- numba_cuda/numba/cuda/misc/gdb_hook.py +240 -0
- numba_cuda/numba/cuda/misc/literal.py +28 -0
- numba_cuda/numba/cuda/misc/llvm_pass_timings.py +412 -0
- numba_cuda/numba/cuda/misc/special.py +94 -0
- numba_cuda/numba/cuda/models.py +56 -0
- numba_cuda/numba/cuda/np/arraymath.py +5130 -0
- numba_cuda/numba/cuda/np/arrayobj.py +7635 -0
- numba_cuda/numba/cuda/np/extensions.py +11 -0
- numba_cuda/numba/cuda/np/linalg.py +3087 -0
- numba_cuda/numba/cuda/np/math/__init__.py +0 -0
- numba_cuda/numba/cuda/np/math/cmathimpl.py +558 -0
- numba_cuda/numba/cuda/np/math/mathimpl.py +487 -0
- numba_cuda/numba/cuda/np/math/numbers.py +1461 -0
- numba_cuda/numba/cuda/np/npdatetime.py +969 -0
- numba_cuda/numba/cuda/np/npdatetime_helpers.py +217 -0
- numba_cuda/numba/cuda/np/npyfuncs.py +1808 -0
- numba_cuda/numba/cuda/np/npyimpl.py +1027 -0
- numba_cuda/numba/cuda/np/numpy_support.py +798 -0
- numba_cuda/numba/cuda/np/polynomial/__init__.py +4 -0
- numba_cuda/numba/cuda/np/polynomial/polynomial_core.py +242 -0
- numba_cuda/numba/cuda/np/polynomial/polynomial_functions.py +380 -0
- numba_cuda/numba/cuda/np/ufunc/__init__.py +4 -0
- numba_cuda/numba/cuda/np/ufunc/decorators.py +203 -0
- numba_cuda/numba/cuda/np/ufunc/sigparse.py +68 -0
- numba_cuda/numba/cuda/np/ufunc/ufuncbuilder.py +65 -0
- numba_cuda/numba/cuda/np/ufunc_db.py +1282 -0
- numba_cuda/numba/cuda/np/unsafe/__init__.py +0 -0
- numba_cuda/numba/cuda/np/unsafe/ndarray.py +84 -0
- numba_cuda/numba/cuda/nvvmutils.py +254 -0
- numba_cuda/numba/cuda/printimpl.py +126 -0
- numba_cuda/numba/cuda/random.py +308 -0
- numba_cuda/numba/cuda/reshape_funcs.cu +156 -0
- numba_cuda/numba/cuda/serialize.py +267 -0
- numba_cuda/numba/cuda/simulator/__init__.py +63 -0
- numba_cuda/numba/cuda/simulator/_internal/__init__.py +4 -0
- numba_cuda/numba/cuda/simulator/_internal/cuda_bf16.py +2 -0
- numba_cuda/numba/cuda/simulator/api.py +179 -0
- numba_cuda/numba/cuda/simulator/bf16.py +4 -0
- numba_cuda/numba/cuda/simulator/compiler.py +38 -0
- numba_cuda/numba/cuda/simulator/cudadrv/__init__.py +11 -0
- numba_cuda/numba/cuda/simulator/cudadrv/devicearray.py +462 -0
- numba_cuda/numba/cuda/simulator/cudadrv/devices.py +122 -0
- numba_cuda/numba/cuda/simulator/cudadrv/driver.py +66 -0
- numba_cuda/numba/cuda/simulator/cudadrv/drvapi.py +7 -0
- numba_cuda/numba/cuda/simulator/cudadrv/dummyarray.py +7 -0
- numba_cuda/numba/cuda/simulator/cudadrv/error.py +10 -0
- numba_cuda/numba/cuda/simulator/cudadrv/libs.py +10 -0
- numba_cuda/numba/cuda/simulator/cudadrv/linkable_code.py +61 -0
- numba_cuda/numba/cuda/simulator/cudadrv/nvrtc.py +11 -0
- numba_cuda/numba/cuda/simulator/cudadrv/nvvm.py +32 -0
- numba_cuda/numba/cuda/simulator/cudadrv/runtime.py +22 -0
- numba_cuda/numba/cuda/simulator/dispatcher.py +11 -0
- numba_cuda/numba/cuda/simulator/kernel.py +320 -0
- numba_cuda/numba/cuda/simulator/kernelapi.py +509 -0
- numba_cuda/numba/cuda/simulator/memory_management/__init__.py +4 -0
- numba_cuda/numba/cuda/simulator/memory_management/nrt.py +21 -0
- numba_cuda/numba/cuda/simulator/reduction.py +19 -0
- numba_cuda/numba/cuda/simulator/tests/support.py +4 -0
- numba_cuda/numba/cuda/simulator/vector_types.py +65 -0
- numba_cuda/numba/cuda/simulator_init.py +18 -0
- numba_cuda/numba/cuda/stubs.py +624 -0
- numba_cuda/numba/cuda/target.py +505 -0
- numba_cuda/numba/cuda/testing.py +347 -0
- numba_cuda/numba/cuda/tests/__init__.py +62 -0
- numba_cuda/numba/cuda/tests/benchmarks/__init__.py +0 -0
- numba_cuda/numba/cuda/tests/benchmarks/test_kernel_launch.py +119 -0
- numba_cuda/numba/cuda/tests/cloudpickle_main_class.py +9 -0
- numba_cuda/numba/cuda/tests/core/serialize_usecases.py +113 -0
- numba_cuda/numba/cuda/tests/core/test_itanium_mangler.py +83 -0
- numba_cuda/numba/cuda/tests/core/test_serialize.py +371 -0
- numba_cuda/numba/cuda/tests/cudadrv/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_array_attr.py +147 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_context_stack.py +161 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_array_slicing.py +397 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_auto_context.py +24 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_devicerecord.py +180 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_driver.py +360 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_memory.py +191 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_cuda_ndarray.py +621 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_deallocations.py +247 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_detect.py +100 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_emm_plugins.py +200 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_events.py +53 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_host_alloc.py +72 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_init.py +138 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_inline_ptx.py +43 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_is_fp16.py +15 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_linkable_code.py +58 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_linker.py +348 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_managed_alloc.py +128 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_module_callbacks.py +301 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_nvjitlink.py +174 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_nvrtc.py +28 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_nvvm_driver.py +185 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_pinned.py +39 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_profiler.py +23 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_reset_device.py +38 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_runtime.py +48 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_select_device.py +44 -0
- numba_cuda/numba/cuda/tests/cudadrv/test_streams.py +127 -0
- numba_cuda/numba/cuda/tests/cudapy/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/cudapy/cache_usecases.py +231 -0
- numba_cuda/numba/cuda/tests/cudapy/cache_with_cpu_usecases.py +50 -0
- numba_cuda/numba/cuda/tests/cudapy/cg_cache_usecases.py +36 -0
- numba_cuda/numba/cuda/tests/cudapy/complex_usecases.py +116 -0
- numba_cuda/numba/cuda/tests/cudapy/enum_usecases.py +59 -0
- numba_cuda/numba/cuda/tests/cudapy/extensions_usecases.py +62 -0
- numba_cuda/numba/cuda/tests/cudapy/jitlink.ptx +28 -0
- numba_cuda/numba/cuda/tests/cudapy/overload_usecases.py +33 -0
- numba_cuda/numba/cuda/tests/cudapy/recursion_usecases.py +104 -0
- numba_cuda/numba/cuda/tests/cudapy/test_alignment.py +47 -0
- numba_cuda/numba/cuda/tests/cudapy/test_analysis.py +1122 -0
- numba_cuda/numba/cuda/tests/cudapy/test_array.py +344 -0
- numba_cuda/numba/cuda/tests/cudapy/test_array_alignment.py +268 -0
- numba_cuda/numba/cuda/tests/cudapy/test_array_args.py +203 -0
- numba_cuda/numba/cuda/tests/cudapy/test_array_methods.py +63 -0
- numba_cuda/numba/cuda/tests/cudapy/test_array_reductions.py +360 -0
- numba_cuda/numba/cuda/tests/cudapy/test_atomics.py +1815 -0
- numba_cuda/numba/cuda/tests/cudapy/test_bfloat16.py +599 -0
- numba_cuda/numba/cuda/tests/cudapy/test_bfloat16_bindings.py +377 -0
- numba_cuda/numba/cuda/tests/cudapy/test_blackscholes.py +160 -0
- numba_cuda/numba/cuda/tests/cudapy/test_boolean.py +27 -0
- numba_cuda/numba/cuda/tests/cudapy/test_byteflow.py +98 -0
- numba_cuda/numba/cuda/tests/cudapy/test_cache_hints.py +210 -0
- numba_cuda/numba/cuda/tests/cudapy/test_caching.py +683 -0
- numba_cuda/numba/cuda/tests/cudapy/test_casting.py +265 -0
- numba_cuda/numba/cuda/tests/cudapy/test_cffi.py +42 -0
- numba_cuda/numba/cuda/tests/cudapy/test_compiler.py +718 -0
- numba_cuda/numba/cuda/tests/cudapy/test_complex.py +370 -0
- numba_cuda/numba/cuda/tests/cudapy/test_complex_kernel.py +23 -0
- numba_cuda/numba/cuda/tests/cudapy/test_const_string.py +142 -0
- numba_cuda/numba/cuda/tests/cudapy/test_constmem.py +178 -0
- numba_cuda/numba/cuda/tests/cudapy/test_cooperative_groups.py +193 -0
- numba_cuda/numba/cuda/tests/cudapy/test_copy_propagate.py +131 -0
- numba_cuda/numba/cuda/tests/cudapy/test_cuda_array_interface.py +438 -0
- numba_cuda/numba/cuda/tests/cudapy/test_cuda_jit_no_types.py +94 -0
- numba_cuda/numba/cuda/tests/cudapy/test_datetime.py +101 -0
- numba_cuda/numba/cuda/tests/cudapy/test_debug.py +105 -0
- numba_cuda/numba/cuda/tests/cudapy/test_debuginfo.py +978 -0
- numba_cuda/numba/cuda/tests/cudapy/test_debuginfo_types.py +476 -0
- numba_cuda/numba/cuda/tests/cudapy/test_device_func.py +500 -0
- numba_cuda/numba/cuda/tests/cudapy/test_dispatcher.py +820 -0
- numba_cuda/numba/cuda/tests/cudapy/test_enums.py +152 -0
- numba_cuda/numba/cuda/tests/cudapy/test_errors.py +111 -0
- numba_cuda/numba/cuda/tests/cudapy/test_exception.py +170 -0
- numba_cuda/numba/cuda/tests/cudapy/test_extending.py +1088 -0
- numba_cuda/numba/cuda/tests/cudapy/test_extending_types.py +71 -0
- numba_cuda/numba/cuda/tests/cudapy/test_fastmath.py +265 -0
- numba_cuda/numba/cuda/tests/cudapy/test_flow_control.py +1433 -0
- numba_cuda/numba/cuda/tests/cudapy/test_forall.py +57 -0
- numba_cuda/numba/cuda/tests/cudapy/test_freevar.py +34 -0
- numba_cuda/numba/cuda/tests/cudapy/test_frexp_ldexp.py +69 -0
- numba_cuda/numba/cuda/tests/cudapy/test_globals.py +62 -0
- numba_cuda/numba/cuda/tests/cudapy/test_gufunc.py +474 -0
- numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scalar.py +167 -0
- numba_cuda/numba/cuda/tests/cudapy/test_gufunc_scheduling.py +92 -0
- numba_cuda/numba/cuda/tests/cudapy/test_idiv.py +39 -0
- numba_cuda/numba/cuda/tests/cudapy/test_inline.py +170 -0
- numba_cuda/numba/cuda/tests/cudapy/test_inspect.py +255 -0
- numba_cuda/numba/cuda/tests/cudapy/test_intrinsics.py +1219 -0
- numba_cuda/numba/cuda/tests/cudapy/test_ipc.py +263 -0
- numba_cuda/numba/cuda/tests/cudapy/test_ir.py +598 -0
- numba_cuda/numba/cuda/tests/cudapy/test_ir_utils.py +276 -0
- numba_cuda/numba/cuda/tests/cudapy/test_iterators.py +101 -0
- numba_cuda/numba/cuda/tests/cudapy/test_lang.py +68 -0
- numba_cuda/numba/cuda/tests/cudapy/test_laplace.py +123 -0
- numba_cuda/numba/cuda/tests/cudapy/test_libdevice.py +194 -0
- numba_cuda/numba/cuda/tests/cudapy/test_lineinfo.py +220 -0
- numba_cuda/numba/cuda/tests/cudapy/test_localmem.py +173 -0
- numba_cuda/numba/cuda/tests/cudapy/test_make_function_to_jit_function.py +364 -0
- numba_cuda/numba/cuda/tests/cudapy/test_mandel.py +47 -0
- numba_cuda/numba/cuda/tests/cudapy/test_math.py +842 -0
- numba_cuda/numba/cuda/tests/cudapy/test_matmul.py +76 -0
- numba_cuda/numba/cuda/tests/cudapy/test_minmax.py +78 -0
- numba_cuda/numba/cuda/tests/cudapy/test_montecarlo.py +25 -0
- numba_cuda/numba/cuda/tests/cudapy/test_multigpu.py +145 -0
- numba_cuda/numba/cuda/tests/cudapy/test_multiprocessing.py +39 -0
- numba_cuda/numba/cuda/tests/cudapy/test_multithreads.py +82 -0
- numba_cuda/numba/cuda/tests/cudapy/test_nondet.py +53 -0
- numba_cuda/numba/cuda/tests/cudapy/test_operator.py +504 -0
- numba_cuda/numba/cuda/tests/cudapy/test_optimization.py +93 -0
- numba_cuda/numba/cuda/tests/cudapy/test_overload.py +402 -0
- numba_cuda/numba/cuda/tests/cudapy/test_powi.py +128 -0
- numba_cuda/numba/cuda/tests/cudapy/test_print.py +193 -0
- numba_cuda/numba/cuda/tests/cudapy/test_py2_div_issue.py +37 -0
- numba_cuda/numba/cuda/tests/cudapy/test_random.py +117 -0
- numba_cuda/numba/cuda/tests/cudapy/test_record_dtype.py +614 -0
- numba_cuda/numba/cuda/tests/cudapy/test_recursion.py +130 -0
- numba_cuda/numba/cuda/tests/cudapy/test_reduction.py +94 -0
- numba_cuda/numba/cuda/tests/cudapy/test_retrieve_autoconverted_arrays.py +83 -0
- numba_cuda/numba/cuda/tests/cudapy/test_serialize.py +86 -0
- numba_cuda/numba/cuda/tests/cudapy/test_slicing.py +40 -0
- numba_cuda/numba/cuda/tests/cudapy/test_sm.py +457 -0
- numba_cuda/numba/cuda/tests/cudapy/test_sm_creation.py +233 -0
- numba_cuda/numba/cuda/tests/cudapy/test_ssa.py +454 -0
- numba_cuda/numba/cuda/tests/cudapy/test_stream_api.py +56 -0
- numba_cuda/numba/cuda/tests/cudapy/test_sync.py +277 -0
- numba_cuda/numba/cuda/tests/cudapy/test_tracing.py +200 -0
- numba_cuda/numba/cuda/tests/cudapy/test_transpose.py +90 -0
- numba_cuda/numba/cuda/tests/cudapy/test_typeconv.py +333 -0
- numba_cuda/numba/cuda/tests/cudapy/test_typeinfer.py +538 -0
- numba_cuda/numba/cuda/tests/cudapy/test_ufuncs.py +585 -0
- numba_cuda/numba/cuda/tests/cudapy/test_userexc.py +42 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vector_type.py +485 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vectorize.py +312 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vectorize_complex.py +23 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vectorize_decor.py +183 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vectorize_device.py +40 -0
- numba_cuda/numba/cuda/tests/cudapy/test_vectorize_scalar_arg.py +40 -0
- numba_cuda/numba/cuda/tests/cudapy/test_warning.py +206 -0
- numba_cuda/numba/cuda/tests/cudapy/test_warp_ops.py +446 -0
- numba_cuda/numba/cuda/tests/cudasim/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/cudasim/support.py +9 -0
- numba_cuda/numba/cuda/tests/cudasim/test_cudasim_issues.py +111 -0
- numba_cuda/numba/cuda/tests/data/__init__.py +2 -0
- numba_cuda/numba/cuda/tests/data/cta_barrier.cu +28 -0
- numba_cuda/numba/cuda/tests/data/cuda_include.cu +10 -0
- numba_cuda/numba/cuda/tests/data/error.cu +12 -0
- numba_cuda/numba/cuda/tests/data/include/add.cuh +8 -0
- numba_cuda/numba/cuda/tests/data/jitlink.cu +28 -0
- numba_cuda/numba/cuda/tests/data/jitlink.ptx +49 -0
- numba_cuda/numba/cuda/tests/data/warn.cu +12 -0
- numba_cuda/numba/cuda/tests/doc_examples/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/doc_examples/ffi/__init__.py +2 -0
- numba_cuda/numba/cuda/tests/doc_examples/ffi/functions.cu +54 -0
- numba_cuda/numba/cuda/tests/doc_examples/ffi/include/mul.cuh +8 -0
- numba_cuda/numba/cuda/tests/doc_examples/ffi/saxpy.cu +14 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_cg.py +86 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_cpointer.py +68 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_cpu_gpu_compat.py +81 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_ffi.py +141 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_laplace.py +160 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_matmul.py +180 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_montecarlo.py +119 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_random.py +66 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_reduction.py +80 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_sessionize.py +206 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_ufunc.py +53 -0
- numba_cuda/numba/cuda/tests/doc_examples/test_vecadd.py +76 -0
- numba_cuda/numba/cuda/tests/nocuda/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/nocuda/test_dummyarray.py +452 -0
- numba_cuda/numba/cuda/tests/nocuda/test_function_resolution.py +48 -0
- numba_cuda/numba/cuda/tests/nocuda/test_import.py +63 -0
- numba_cuda/numba/cuda/tests/nocuda/test_library_lookup.py +252 -0
- numba_cuda/numba/cuda/tests/nocuda/test_nvvm.py +59 -0
- numba_cuda/numba/cuda/tests/nrt/__init__.py +9 -0
- numba_cuda/numba/cuda/tests/nrt/test_nrt.py +387 -0
- numba_cuda/numba/cuda/tests/nrt/test_nrt_refct.py +124 -0
- numba_cuda/numba/cuda/tests/support.py +900 -0
- numba_cuda/numba/cuda/typeconv/__init__.py +4 -0
- numba_cuda/numba/cuda/typeconv/castgraph.py +137 -0
- numba_cuda/numba/cuda/typeconv/rules.py +63 -0
- numba_cuda/numba/cuda/typeconv/typeconv.py +121 -0
- numba_cuda/numba/cuda/types/__init__.py +233 -0
- numba_cuda/numba/cuda/types/__init__.pyi +167 -0
- numba_cuda/numba/cuda/types/abstract.py +9 -0
- numba_cuda/numba/cuda/types/common.py +9 -0
- numba_cuda/numba/cuda/types/containers.py +9 -0
- numba_cuda/numba/cuda/types/cuda_abstract.py +533 -0
- numba_cuda/numba/cuda/types/cuda_common.py +110 -0
- numba_cuda/numba/cuda/types/cuda_containers.py +971 -0
- numba_cuda/numba/cuda/types/cuda_function_type.py +230 -0
- numba_cuda/numba/cuda/types/cuda_functions.py +798 -0
- numba_cuda/numba/cuda/types/cuda_iterators.py +120 -0
- numba_cuda/numba/cuda/types/cuda_misc.py +569 -0
- numba_cuda/numba/cuda/types/cuda_npytypes.py +690 -0
- numba_cuda/numba/cuda/types/cuda_scalars.py +280 -0
- numba_cuda/numba/cuda/types/ext_types.py +101 -0
- numba_cuda/numba/cuda/types/function_type.py +11 -0
- numba_cuda/numba/cuda/types/functions.py +9 -0
- numba_cuda/numba/cuda/types/iterators.py +9 -0
- numba_cuda/numba/cuda/types/misc.py +9 -0
- numba_cuda/numba/cuda/types/npytypes.py +9 -0
- numba_cuda/numba/cuda/types/scalars.py +9 -0
- numba_cuda/numba/cuda/typing/__init__.py +19 -0
- numba_cuda/numba/cuda/typing/arraydecl.py +939 -0
- numba_cuda/numba/cuda/typing/asnumbatype.py +130 -0
- numba_cuda/numba/cuda/typing/bufproto.py +70 -0
- numba_cuda/numba/cuda/typing/builtins.py +1209 -0
- numba_cuda/numba/cuda/typing/cffi_utils.py +219 -0
- numba_cuda/numba/cuda/typing/cmathdecl.py +47 -0
- numba_cuda/numba/cuda/typing/collections.py +138 -0
- numba_cuda/numba/cuda/typing/context.py +782 -0
- numba_cuda/numba/cuda/typing/ctypes_utils.py +125 -0
- numba_cuda/numba/cuda/typing/dictdecl.py +63 -0
- numba_cuda/numba/cuda/typing/enumdecl.py +74 -0
- numba_cuda/numba/cuda/typing/listdecl.py +147 -0
- numba_cuda/numba/cuda/typing/mathdecl.py +158 -0
- numba_cuda/numba/cuda/typing/npdatetime.py +322 -0
- numba_cuda/numba/cuda/typing/npydecl.py +749 -0
- numba_cuda/numba/cuda/typing/setdecl.py +115 -0
- numba_cuda/numba/cuda/typing/templates.py +1446 -0
- numba_cuda/numba/cuda/typing/typeof.py +301 -0
- numba_cuda/numba/cuda/ufuncs.py +746 -0
- numba_cuda/numba/cuda/utils.py +724 -0
- numba_cuda/numba/cuda/vector_types.py +214 -0
- numba_cuda/numba/cuda/vectorizers.py +260 -0
- numba_cuda-0.22.1.dist-info/METADATA +109 -0
- numba_cuda-0.22.1.dist-info/RECORD +488 -0
- numba_cuda-0.22.1.dist-info/WHEEL +6 -0
- numba_cuda-0.22.1.dist-info/licenses/LICENSE +26 -0
- numba_cuda-0.22.1.dist-info/licenses/LICENSE.numba +24 -0
- 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)
|