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