numba-cuda 0.22.0__cp313-cp313-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-313-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-313-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-313-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-313-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-313-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/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 +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 +313 -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.0.dist-info/METADATA +109 -0
- numba_cuda-0.22.0.dist-info/RECORD +487 -0
- numba_cuda-0.22.0.dist-info/WHEEL +6 -0
- numba_cuda-0.22.0.dist-info/licenses/LICENSE +26 -0
- numba_cuda-0.22.0.dist-info/licenses/LICENSE.numba +24 -0
- numba_cuda-0.22.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1326 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Support for native homogeneous lists.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import operator
|
|
9
|
+
|
|
10
|
+
from llvmlite import ir
|
|
11
|
+
from numba.cuda import types
|
|
12
|
+
from numba.cuda.core import errors
|
|
13
|
+
from numba.cuda import cgutils
|
|
14
|
+
from numba.cuda.core.imputils import (
|
|
15
|
+
Registry,
|
|
16
|
+
iternext_impl,
|
|
17
|
+
impl_ret_borrowed,
|
|
18
|
+
impl_ret_new_ref,
|
|
19
|
+
RefType,
|
|
20
|
+
)
|
|
21
|
+
from numba.cuda.extending import overload_method, overload
|
|
22
|
+
from numba.cuda.cpython import slicing
|
|
23
|
+
from numba.cuda.misc.special import literal_unroll
|
|
24
|
+
|
|
25
|
+
registry = Registry("listobj")
|
|
26
|
+
lower = registry.lower
|
|
27
|
+
lower_cast = registry.lower_cast
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_list_payload(context, builder, list_type, value):
|
|
31
|
+
"""
|
|
32
|
+
Given a list value and type, get its payload structure (as a
|
|
33
|
+
reference, so that mutations are seen by all).
|
|
34
|
+
"""
|
|
35
|
+
payload_type = types.ListPayload(list_type)
|
|
36
|
+
payload = context.nrt.meminfo_data(builder, value.meminfo)
|
|
37
|
+
ptrty = context.get_data_type(payload_type).as_pointer()
|
|
38
|
+
payload = builder.bitcast(payload, ptrty)
|
|
39
|
+
return context.make_data_helper(builder, payload_type, ref=payload)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_itemsize(context, list_type):
|
|
43
|
+
"""
|
|
44
|
+
Return the item size for the given list type.
|
|
45
|
+
"""
|
|
46
|
+
llty = context.get_data_type(list_type.dtype)
|
|
47
|
+
return context.get_abi_sizeof(llty)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class _ListPayloadMixin(object):
|
|
51
|
+
@property
|
|
52
|
+
def size(self):
|
|
53
|
+
return self._payload.size
|
|
54
|
+
|
|
55
|
+
@size.setter
|
|
56
|
+
def size(self, value):
|
|
57
|
+
self._payload.size = value
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def dirty(self):
|
|
61
|
+
return self._payload.dirty
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def data(self):
|
|
65
|
+
return self._payload._get_ptr_by_name("data")
|
|
66
|
+
|
|
67
|
+
def _gep(self, idx):
|
|
68
|
+
return cgutils.gep(self._builder, self.data, idx)
|
|
69
|
+
|
|
70
|
+
def getitem(self, idx):
|
|
71
|
+
ptr = self._gep(idx)
|
|
72
|
+
data_item = self._builder.load(ptr)
|
|
73
|
+
return self._datamodel.from_data(self._builder, data_item)
|
|
74
|
+
|
|
75
|
+
def fix_index(self, idx):
|
|
76
|
+
"""
|
|
77
|
+
Fix negative indices by adding the size to them. Positive
|
|
78
|
+
indices are left untouched.
|
|
79
|
+
"""
|
|
80
|
+
is_negative = self._builder.icmp_signed(
|
|
81
|
+
"<", idx, ir.Constant(idx.type, 0)
|
|
82
|
+
)
|
|
83
|
+
wrapped_index = self._builder.add(idx, self.size)
|
|
84
|
+
return self._builder.select(is_negative, wrapped_index, idx)
|
|
85
|
+
|
|
86
|
+
def is_out_of_bounds(self, idx):
|
|
87
|
+
"""
|
|
88
|
+
Return whether the index is out of bounds.
|
|
89
|
+
"""
|
|
90
|
+
underflow = self._builder.icmp_signed(
|
|
91
|
+
"<", idx, ir.Constant(idx.type, 0)
|
|
92
|
+
)
|
|
93
|
+
overflow = self._builder.icmp_signed(">=", idx, self.size)
|
|
94
|
+
return self._builder.or_(underflow, overflow)
|
|
95
|
+
|
|
96
|
+
def clamp_index(self, idx):
|
|
97
|
+
"""
|
|
98
|
+
Clamp the index in [0, size].
|
|
99
|
+
"""
|
|
100
|
+
builder = self._builder
|
|
101
|
+
idxptr = cgutils.alloca_once_value(builder, idx)
|
|
102
|
+
|
|
103
|
+
zero = ir.Constant(idx.type, 0)
|
|
104
|
+
size = self.size
|
|
105
|
+
|
|
106
|
+
underflow = self._builder.icmp_signed("<", idx, zero)
|
|
107
|
+
with builder.if_then(underflow, likely=False):
|
|
108
|
+
builder.store(zero, idxptr)
|
|
109
|
+
overflow = self._builder.icmp_signed(">=", idx, size)
|
|
110
|
+
with builder.if_then(overflow, likely=False):
|
|
111
|
+
builder.store(size, idxptr)
|
|
112
|
+
|
|
113
|
+
return builder.load(idxptr)
|
|
114
|
+
|
|
115
|
+
def guard_index(self, idx, msg):
|
|
116
|
+
"""
|
|
117
|
+
Raise an error if the index is out of bounds.
|
|
118
|
+
"""
|
|
119
|
+
with self._builder.if_then(self.is_out_of_bounds(idx), likely=False):
|
|
120
|
+
self._context.call_conv.return_user_exc(
|
|
121
|
+
self._builder, IndexError, (msg,)
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def fix_slice(self, slice):
|
|
125
|
+
"""
|
|
126
|
+
Fix slice start and stop to be valid (inclusive and exclusive, resp)
|
|
127
|
+
indexing bounds.
|
|
128
|
+
"""
|
|
129
|
+
return slicing.fix_slice(self._builder, slice, self.size)
|
|
130
|
+
|
|
131
|
+
def incref_value(self, val):
|
|
132
|
+
"Incref an element value"
|
|
133
|
+
self._context.nrt.incref(self._builder, self.dtype, val)
|
|
134
|
+
|
|
135
|
+
def decref_value(self, val):
|
|
136
|
+
"Decref an element value"
|
|
137
|
+
self._context.nrt.decref(self._builder, self.dtype, val)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class ListPayloadAccessor(_ListPayloadMixin):
|
|
141
|
+
"""
|
|
142
|
+
A helper object to access the list attributes given the pointer to the
|
|
143
|
+
payload type.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
def __init__(self, context, builder, list_type, payload_ptr):
|
|
147
|
+
self._context = context
|
|
148
|
+
self._builder = builder
|
|
149
|
+
self._ty = list_type
|
|
150
|
+
self._datamodel = context.data_model_manager[list_type.dtype]
|
|
151
|
+
payload_type = types.ListPayload(list_type)
|
|
152
|
+
ptrty = context.get_data_type(payload_type).as_pointer()
|
|
153
|
+
payload_ptr = builder.bitcast(payload_ptr, ptrty)
|
|
154
|
+
payload = context.make_data_helper(
|
|
155
|
+
builder, payload_type, ref=payload_ptr
|
|
156
|
+
)
|
|
157
|
+
self._payload = payload
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class ListInstance(_ListPayloadMixin):
|
|
161
|
+
def __init__(self, context, builder, list_type, list_val):
|
|
162
|
+
self._context = context
|
|
163
|
+
self._builder = builder
|
|
164
|
+
self._ty = list_type
|
|
165
|
+
self._list = context.make_helper(builder, list_type, list_val)
|
|
166
|
+
self._itemsize = get_itemsize(context, list_type)
|
|
167
|
+
self._datamodel = context.data_model_manager[list_type.dtype]
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def dtype(self):
|
|
171
|
+
return self._ty.dtype
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def _payload(self):
|
|
175
|
+
# This cannot be cached as it can be reallocated
|
|
176
|
+
return get_list_payload(
|
|
177
|
+
self._context, self._builder, self._ty, self._list
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def parent(self):
|
|
182
|
+
return self._list.parent
|
|
183
|
+
|
|
184
|
+
@parent.setter
|
|
185
|
+
def parent(self, value):
|
|
186
|
+
self._list.parent = value
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def value(self):
|
|
190
|
+
return self._list._getvalue()
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def meminfo(self):
|
|
194
|
+
return self._list.meminfo
|
|
195
|
+
|
|
196
|
+
def set_dirty(self, val):
|
|
197
|
+
if self._ty.reflected:
|
|
198
|
+
self._payload.dirty = cgutils.true_bit if val else cgutils.false_bit
|
|
199
|
+
|
|
200
|
+
def clear_value(self, idx):
|
|
201
|
+
"""Remove the value at the location"""
|
|
202
|
+
self.decref_value(self.getitem(idx))
|
|
203
|
+
# it's necessary for the dtor which just decref every slot on it.
|
|
204
|
+
self.zfill(idx, self._builder.add(idx, idx.type(1)))
|
|
205
|
+
|
|
206
|
+
def setitem(self, idx, val, incref, decref_old_value=True):
|
|
207
|
+
# Decref old data
|
|
208
|
+
if decref_old_value:
|
|
209
|
+
self.decref_value(self.getitem(idx))
|
|
210
|
+
|
|
211
|
+
ptr = self._gep(idx)
|
|
212
|
+
data_item = self._datamodel.as_data(self._builder, val)
|
|
213
|
+
self._builder.store(data_item, ptr)
|
|
214
|
+
self.set_dirty(True)
|
|
215
|
+
if incref:
|
|
216
|
+
# Incref the underlying data
|
|
217
|
+
self.incref_value(val)
|
|
218
|
+
|
|
219
|
+
def inititem(self, idx, val, incref=True):
|
|
220
|
+
ptr = self._gep(idx)
|
|
221
|
+
data_item = self._datamodel.as_data(self._builder, val)
|
|
222
|
+
self._builder.store(data_item, ptr)
|
|
223
|
+
if incref:
|
|
224
|
+
self.incref_value(val)
|
|
225
|
+
|
|
226
|
+
def zfill(self, start, stop):
|
|
227
|
+
"""Zero-fill the memory at index *start* to *stop*
|
|
228
|
+
|
|
229
|
+
*stop* MUST not be smaller than *start*.
|
|
230
|
+
"""
|
|
231
|
+
builder = self._builder
|
|
232
|
+
base = self._gep(start)
|
|
233
|
+
end = self._gep(stop)
|
|
234
|
+
intaddr_t = self._context.get_value_type(types.intp)
|
|
235
|
+
size = builder.sub(
|
|
236
|
+
builder.ptrtoint(end, intaddr_t), builder.ptrtoint(base, intaddr_t)
|
|
237
|
+
)
|
|
238
|
+
cgutils.memset(builder, base, size, ir.IntType(8)(0))
|
|
239
|
+
|
|
240
|
+
@classmethod
|
|
241
|
+
def allocate_ex(cls, context, builder, list_type, nitems):
|
|
242
|
+
"""
|
|
243
|
+
Allocate a ListInstance with its storage.
|
|
244
|
+
Return a (ok, instance) tuple where *ok* is a LLVM boolean and
|
|
245
|
+
*instance* is a ListInstance object (the object's contents are
|
|
246
|
+
only valid when *ok* is true).
|
|
247
|
+
"""
|
|
248
|
+
intp_t = context.get_value_type(types.intp)
|
|
249
|
+
|
|
250
|
+
if isinstance(nitems, int):
|
|
251
|
+
nitems = ir.Constant(intp_t, nitems)
|
|
252
|
+
|
|
253
|
+
payload_type = context.get_data_type(types.ListPayload(list_type))
|
|
254
|
+
payload_size = context.get_abi_sizeof(payload_type)
|
|
255
|
+
|
|
256
|
+
itemsize = get_itemsize(context, list_type)
|
|
257
|
+
# Account for the fact that the payload struct contains one entry
|
|
258
|
+
payload_size -= itemsize
|
|
259
|
+
|
|
260
|
+
ok = cgutils.alloca_once_value(builder, cgutils.true_bit)
|
|
261
|
+
self = cls(context, builder, list_type, None)
|
|
262
|
+
|
|
263
|
+
# Total allocation size = <payload header size> + nitems * itemsize
|
|
264
|
+
allocsize, ovf = cgutils.muladd_with_overflow(
|
|
265
|
+
builder,
|
|
266
|
+
nitems,
|
|
267
|
+
ir.Constant(intp_t, itemsize),
|
|
268
|
+
ir.Constant(intp_t, payload_size),
|
|
269
|
+
)
|
|
270
|
+
with builder.if_then(ovf, likely=False):
|
|
271
|
+
builder.store(cgutils.false_bit, ok)
|
|
272
|
+
|
|
273
|
+
with builder.if_then(builder.load(ok), likely=True):
|
|
274
|
+
meminfo = context.nrt.meminfo_new_varsize_dtor_unchecked(
|
|
275
|
+
builder, size=allocsize, dtor=self.get_dtor()
|
|
276
|
+
)
|
|
277
|
+
with builder.if_else(
|
|
278
|
+
cgutils.is_null(builder, meminfo), likely=False
|
|
279
|
+
) as (if_error, if_ok):
|
|
280
|
+
with if_error:
|
|
281
|
+
builder.store(cgutils.false_bit, ok)
|
|
282
|
+
with if_ok:
|
|
283
|
+
self._list.meminfo = meminfo
|
|
284
|
+
self._list.parent = context.get_constant_null(
|
|
285
|
+
types.pyobject
|
|
286
|
+
)
|
|
287
|
+
self._payload.allocated = nitems
|
|
288
|
+
self._payload.size = ir.Constant(intp_t, 0) # for safety
|
|
289
|
+
self._payload.dirty = cgutils.false_bit
|
|
290
|
+
# Zero the allocated region
|
|
291
|
+
self.zfill(self.size.type(0), nitems)
|
|
292
|
+
|
|
293
|
+
return builder.load(ok), self
|
|
294
|
+
|
|
295
|
+
def define_dtor(self):
|
|
296
|
+
"Define the destructor if not already defined"
|
|
297
|
+
context = self._context
|
|
298
|
+
builder = self._builder
|
|
299
|
+
mod = builder.module
|
|
300
|
+
# Declare dtor
|
|
301
|
+
fnty = ir.FunctionType(ir.VoidType(), [cgutils.voidptr_t])
|
|
302
|
+
if isinstance(self.dtype, types.containers.List):
|
|
303
|
+
dtypestr = f"list_{self.dtype.dtype}"
|
|
304
|
+
else:
|
|
305
|
+
dtypestr = str(self.dtype)
|
|
306
|
+
fn = cgutils.get_or_insert_function(
|
|
307
|
+
mod, fnty, f"numba_cuda_dtor_list_{dtypestr}"
|
|
308
|
+
)
|
|
309
|
+
if not fn.is_declaration:
|
|
310
|
+
# End early if the dtor is already defined
|
|
311
|
+
return fn
|
|
312
|
+
fn.linkage = "linkonce_odr"
|
|
313
|
+
# Populate the dtor
|
|
314
|
+
builder = ir.IRBuilder(fn.append_basic_block())
|
|
315
|
+
base_ptr = fn.args[0] # void*
|
|
316
|
+
|
|
317
|
+
# get payload
|
|
318
|
+
payload = ListPayloadAccessor(context, builder, self._ty, base_ptr)
|
|
319
|
+
|
|
320
|
+
# Loop over all data to decref
|
|
321
|
+
intp = payload.size.type
|
|
322
|
+
with cgutils.for_range_slice(
|
|
323
|
+
builder, start=intp(0), stop=payload.size, step=intp(1), intp=intp
|
|
324
|
+
) as (idx, _):
|
|
325
|
+
val = payload.getitem(idx)
|
|
326
|
+
context.nrt.decref(builder, self.dtype, val)
|
|
327
|
+
builder.ret_void()
|
|
328
|
+
return fn
|
|
329
|
+
|
|
330
|
+
def get_dtor(self):
|
|
331
|
+
""" "Get the element dtor function pointer as void pointer.
|
|
332
|
+
|
|
333
|
+
It's safe to be called multiple times.
|
|
334
|
+
"""
|
|
335
|
+
# Define and set the Dtor
|
|
336
|
+
dtor = self.define_dtor()
|
|
337
|
+
dtor_fnptr = self._builder.bitcast(dtor, cgutils.voidptr_t)
|
|
338
|
+
return dtor_fnptr
|
|
339
|
+
|
|
340
|
+
@classmethod
|
|
341
|
+
def allocate(cls, context, builder, list_type, nitems):
|
|
342
|
+
"""
|
|
343
|
+
Allocate a ListInstance with its storage. Same as allocate_ex(),
|
|
344
|
+
but return an initialized *instance*. If allocation failed,
|
|
345
|
+
control is transferred to the caller using the target's current
|
|
346
|
+
call convention.
|
|
347
|
+
"""
|
|
348
|
+
ok, self = cls.allocate_ex(context, builder, list_type, nitems)
|
|
349
|
+
with builder.if_then(builder.not_(ok), likely=False):
|
|
350
|
+
context.call_conv.return_user_exc(
|
|
351
|
+
builder, MemoryError, ("cannot allocate list",)
|
|
352
|
+
)
|
|
353
|
+
return self
|
|
354
|
+
|
|
355
|
+
@classmethod
|
|
356
|
+
def from_meminfo(cls, context, builder, list_type, meminfo):
|
|
357
|
+
"""
|
|
358
|
+
Allocate a new list instance pointing to an existing payload
|
|
359
|
+
(a meminfo pointer).
|
|
360
|
+
Note the parent field has to be filled by the caller.
|
|
361
|
+
"""
|
|
362
|
+
self = cls(context, builder, list_type, None)
|
|
363
|
+
self._list.meminfo = meminfo
|
|
364
|
+
self._list.parent = context.get_constant_null(types.pyobject)
|
|
365
|
+
context.nrt.incref(builder, list_type, self.value)
|
|
366
|
+
# Payload is part of the meminfo, no need to touch it
|
|
367
|
+
return self
|
|
368
|
+
|
|
369
|
+
def resize(self, new_size):
|
|
370
|
+
"""
|
|
371
|
+
Ensure the list is properly sized for the new size.
|
|
372
|
+
"""
|
|
373
|
+
|
|
374
|
+
def _payload_realloc(new_allocated):
|
|
375
|
+
payload_type = context.get_data_type(types.ListPayload(self._ty))
|
|
376
|
+
payload_size = context.get_abi_sizeof(payload_type)
|
|
377
|
+
# Account for the fact that the payload struct contains one entry
|
|
378
|
+
payload_size -= itemsize
|
|
379
|
+
|
|
380
|
+
allocsize, ovf = cgutils.muladd_with_overflow(
|
|
381
|
+
builder,
|
|
382
|
+
new_allocated,
|
|
383
|
+
ir.Constant(intp_t, itemsize),
|
|
384
|
+
ir.Constant(intp_t, payload_size),
|
|
385
|
+
)
|
|
386
|
+
with builder.if_then(ovf, likely=False):
|
|
387
|
+
context.call_conv.return_user_exc(
|
|
388
|
+
builder, MemoryError, ("cannot resize list",)
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
ptr = context.nrt.meminfo_varsize_realloc_unchecked(
|
|
392
|
+
builder, self._list.meminfo, size=allocsize
|
|
393
|
+
)
|
|
394
|
+
cgutils.guard_memory_error(
|
|
395
|
+
context, builder, ptr, "cannot resize list"
|
|
396
|
+
)
|
|
397
|
+
self._payload.allocated = new_allocated
|
|
398
|
+
|
|
399
|
+
context = self._context
|
|
400
|
+
builder = self._builder
|
|
401
|
+
intp_t = new_size.type
|
|
402
|
+
|
|
403
|
+
itemsize = get_itemsize(context, self._ty)
|
|
404
|
+
allocated = self._payload.allocated
|
|
405
|
+
|
|
406
|
+
two = ir.Constant(intp_t, 2)
|
|
407
|
+
eight = ir.Constant(intp_t, 8)
|
|
408
|
+
|
|
409
|
+
# allocated < new_size
|
|
410
|
+
is_too_small = builder.icmp_signed("<", allocated, new_size)
|
|
411
|
+
# (allocated >> 2) > new_size
|
|
412
|
+
is_too_large = builder.icmp_signed(
|
|
413
|
+
">", builder.ashr(allocated, two), new_size
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
with builder.if_then(is_too_large, likely=False):
|
|
417
|
+
# Exact downsize to requested size
|
|
418
|
+
# NOTE: is_too_large must be aggressive enough to avoid repeated
|
|
419
|
+
# upsizes and downsizes when growing a list.
|
|
420
|
+
_payload_realloc(new_size)
|
|
421
|
+
|
|
422
|
+
with builder.if_then(is_too_small, likely=False):
|
|
423
|
+
# Upsize with moderate over-allocation (size + size >> 2 + 8)
|
|
424
|
+
new_allocated = builder.add(
|
|
425
|
+
eight, builder.add(new_size, builder.ashr(new_size, two))
|
|
426
|
+
)
|
|
427
|
+
_payload_realloc(new_allocated)
|
|
428
|
+
self.zfill(self.size, new_allocated)
|
|
429
|
+
|
|
430
|
+
self._payload.size = new_size
|
|
431
|
+
self.set_dirty(True)
|
|
432
|
+
|
|
433
|
+
def move(self, dest_idx, src_idx, count):
|
|
434
|
+
"""
|
|
435
|
+
Move `count` elements from `src_idx` to `dest_idx`.
|
|
436
|
+
"""
|
|
437
|
+
dest_ptr = self._gep(dest_idx)
|
|
438
|
+
src_ptr = self._gep(src_idx)
|
|
439
|
+
cgutils.raw_memmove(
|
|
440
|
+
self._builder, dest_ptr, src_ptr, count, itemsize=self._itemsize
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
self.set_dirty(True)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
class ListIterInstance(_ListPayloadMixin):
|
|
447
|
+
def __init__(self, context, builder, iter_type, iter_val):
|
|
448
|
+
self._context = context
|
|
449
|
+
self._builder = builder
|
|
450
|
+
self._ty = iter_type
|
|
451
|
+
self._iter = context.make_helper(builder, iter_type, iter_val)
|
|
452
|
+
self._datamodel = context.data_model_manager[iter_type.yield_type]
|
|
453
|
+
|
|
454
|
+
@classmethod
|
|
455
|
+
def from_list(cls, context, builder, iter_type, list_val):
|
|
456
|
+
list_inst = ListInstance(
|
|
457
|
+
context, builder, iter_type.container, list_val
|
|
458
|
+
)
|
|
459
|
+
self = cls(context, builder, iter_type, None)
|
|
460
|
+
index = context.get_constant(types.intp, 0)
|
|
461
|
+
self._iter.index = cgutils.alloca_once_value(builder, index)
|
|
462
|
+
self._iter.meminfo = list_inst.meminfo
|
|
463
|
+
return self
|
|
464
|
+
|
|
465
|
+
@property
|
|
466
|
+
def _payload(self):
|
|
467
|
+
# This cannot be cached as it can be reallocated
|
|
468
|
+
return get_list_payload(
|
|
469
|
+
self._context, self._builder, self._ty.container, self._iter
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
@property
|
|
473
|
+
def value(self):
|
|
474
|
+
return self._iter._getvalue()
|
|
475
|
+
|
|
476
|
+
@property
|
|
477
|
+
def index(self):
|
|
478
|
+
return self._builder.load(self._iter.index)
|
|
479
|
+
|
|
480
|
+
@index.setter
|
|
481
|
+
def index(self, value):
|
|
482
|
+
self._builder.store(value, self._iter.index)
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
# -------------------------------------------------------------------------------
|
|
486
|
+
# Constructors
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def build_list(context, builder, list_type, items):
|
|
490
|
+
"""
|
|
491
|
+
Build a list of the given type, containing the given items.
|
|
492
|
+
"""
|
|
493
|
+
nitems = len(items)
|
|
494
|
+
inst = ListInstance.allocate(context, builder, list_type, nitems)
|
|
495
|
+
# Populate list
|
|
496
|
+
inst.size = context.get_constant(types.intp, nitems)
|
|
497
|
+
for i, val in enumerate(items):
|
|
498
|
+
inst.setitem(context.get_constant(types.intp, i), val, incref=True)
|
|
499
|
+
|
|
500
|
+
return impl_ret_new_ref(context, builder, list_type, inst.value)
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@lower(list, types.IterableType)
|
|
504
|
+
def list_constructor(context, builder, sig, args):
|
|
505
|
+
def list_impl(iterable):
|
|
506
|
+
res = []
|
|
507
|
+
res.extend(iterable)
|
|
508
|
+
return res
|
|
509
|
+
|
|
510
|
+
return context.compile_internal(builder, list_impl, sig, args)
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
@lower(list)
|
|
514
|
+
def list_constructor(context, builder, sig, args): # noqa: F811
|
|
515
|
+
list_type = sig.return_type
|
|
516
|
+
list_len = 0
|
|
517
|
+
inst = ListInstance.allocate(context, builder, list_type, list_len)
|
|
518
|
+
return impl_ret_new_ref(context, builder, list_type, inst.value)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
# -------------------------------------------------------------------------------
|
|
522
|
+
# Various operations
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
@lower(len, types.List)
|
|
526
|
+
def list_len(context, builder, sig, args):
|
|
527
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
528
|
+
return inst.size
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
@lower("getiter", types.List)
|
|
532
|
+
def getiter_list(context, builder, sig, args):
|
|
533
|
+
inst = ListIterInstance.from_list(
|
|
534
|
+
context, builder, sig.return_type, args[0]
|
|
535
|
+
)
|
|
536
|
+
return impl_ret_borrowed(context, builder, sig.return_type, inst.value)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
@lower("iternext", types.ListIter)
|
|
540
|
+
@iternext_impl(RefType.BORROWED)
|
|
541
|
+
def iternext_listiter(context, builder, sig, args, result):
|
|
542
|
+
inst = ListIterInstance(context, builder, sig.args[0], args[0])
|
|
543
|
+
|
|
544
|
+
index = inst.index
|
|
545
|
+
nitems = inst.size
|
|
546
|
+
is_valid = builder.icmp_signed("<", index, nitems)
|
|
547
|
+
result.set_valid(is_valid)
|
|
548
|
+
|
|
549
|
+
with builder.if_then(is_valid):
|
|
550
|
+
result.yield_(inst.getitem(index))
|
|
551
|
+
inst.index = builder.add(index, context.get_constant(types.intp, 1))
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
@lower(operator.getitem, types.List, types.Integer)
|
|
555
|
+
def getitem_list(context, builder, sig, args):
|
|
556
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
557
|
+
index = args[1]
|
|
558
|
+
|
|
559
|
+
index = inst.fix_index(index)
|
|
560
|
+
inst.guard_index(index, msg="getitem out of range")
|
|
561
|
+
result = inst.getitem(index)
|
|
562
|
+
|
|
563
|
+
return impl_ret_borrowed(context, builder, sig.return_type, result)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
@lower(operator.setitem, types.List, types.Integer, types.Any)
|
|
567
|
+
def setitem_list(context, builder, sig, args):
|
|
568
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
569
|
+
index = args[1]
|
|
570
|
+
value = args[2]
|
|
571
|
+
|
|
572
|
+
index = inst.fix_index(index)
|
|
573
|
+
inst.guard_index(index, msg="setitem out of range")
|
|
574
|
+
inst.setitem(index, value, incref=True)
|
|
575
|
+
return context.get_dummy_value()
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
@lower(operator.getitem, types.List, types.SliceType)
|
|
579
|
+
def getslice_list(context, builder, sig, args):
|
|
580
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
581
|
+
slice = context.make_helper(builder, sig.args[1], args[1])
|
|
582
|
+
slicing.guard_invalid_slice(context, builder, sig.args[1], slice)
|
|
583
|
+
inst.fix_slice(slice)
|
|
584
|
+
|
|
585
|
+
# Allocate result and populate it
|
|
586
|
+
result_size = slicing.get_slice_length(builder, slice)
|
|
587
|
+
result = ListInstance.allocate(
|
|
588
|
+
context, builder, sig.return_type, result_size
|
|
589
|
+
)
|
|
590
|
+
result.size = result_size
|
|
591
|
+
with cgutils.for_range_slice_generic(
|
|
592
|
+
builder, slice.start, slice.stop, slice.step
|
|
593
|
+
) as (pos_range, neg_range):
|
|
594
|
+
with pos_range as (idx, count):
|
|
595
|
+
value = inst.getitem(idx)
|
|
596
|
+
result.inititem(count, value, incref=True)
|
|
597
|
+
with neg_range as (idx, count):
|
|
598
|
+
value = inst.getitem(idx)
|
|
599
|
+
result.inititem(count, value, incref=True)
|
|
600
|
+
|
|
601
|
+
return impl_ret_new_ref(context, builder, sig.return_type, result.value)
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
@lower(operator.setitem, types.List, types.SliceType, types.Any)
|
|
605
|
+
def setitem_list(context, builder, sig, args): # noqa: F811
|
|
606
|
+
dest = ListInstance(context, builder, sig.args[0], args[0])
|
|
607
|
+
src = ListInstance(context, builder, sig.args[2], args[2])
|
|
608
|
+
|
|
609
|
+
slice = context.make_helper(builder, sig.args[1], args[1])
|
|
610
|
+
slicing.guard_invalid_slice(context, builder, sig.args[1], slice)
|
|
611
|
+
dest.fix_slice(slice)
|
|
612
|
+
|
|
613
|
+
src_size = src.size
|
|
614
|
+
avail_size = slicing.get_slice_length(builder, slice)
|
|
615
|
+
size_delta = builder.sub(src.size, avail_size)
|
|
616
|
+
|
|
617
|
+
zero = ir.Constant(size_delta.type, 0)
|
|
618
|
+
one = ir.Constant(size_delta.type, 1)
|
|
619
|
+
|
|
620
|
+
with builder.if_else(builder.icmp_signed("==", slice.step, one)) as (
|
|
621
|
+
then,
|
|
622
|
+
otherwise,
|
|
623
|
+
):
|
|
624
|
+
with then:
|
|
625
|
+
# Slice step == 1 => we can resize
|
|
626
|
+
|
|
627
|
+
# Compute the real stop, e.g. for dest[2:0] = [...]
|
|
628
|
+
real_stop = builder.add(slice.start, avail_size)
|
|
629
|
+
# Size of the list tail, after the end of slice
|
|
630
|
+
tail_size = builder.sub(dest.size, real_stop)
|
|
631
|
+
|
|
632
|
+
with builder.if_then(builder.icmp_signed(">", size_delta, zero)):
|
|
633
|
+
# Grow list then move list tail
|
|
634
|
+
dest.resize(builder.add(dest.size, size_delta))
|
|
635
|
+
dest.move(
|
|
636
|
+
builder.add(real_stop, size_delta), real_stop, tail_size
|
|
637
|
+
)
|
|
638
|
+
|
|
639
|
+
with builder.if_then(builder.icmp_signed("<", size_delta, zero)):
|
|
640
|
+
# Move list tail then shrink list
|
|
641
|
+
dest.move(
|
|
642
|
+
builder.add(real_stop, size_delta), real_stop, tail_size
|
|
643
|
+
)
|
|
644
|
+
dest.resize(builder.add(dest.size, size_delta))
|
|
645
|
+
|
|
646
|
+
dest_offset = slice.start
|
|
647
|
+
|
|
648
|
+
with cgutils.for_range(builder, src_size) as loop:
|
|
649
|
+
value = src.getitem(loop.index)
|
|
650
|
+
dest.setitem(
|
|
651
|
+
builder.add(loop.index, dest_offset), value, incref=True
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
with otherwise:
|
|
655
|
+
with builder.if_then(builder.icmp_signed("!=", size_delta, zero)):
|
|
656
|
+
msg = "cannot resize extended list slice with step != 1"
|
|
657
|
+
context.call_conv.return_user_exc(builder, ValueError, (msg,))
|
|
658
|
+
|
|
659
|
+
with cgutils.for_range_slice_generic(
|
|
660
|
+
builder, slice.start, slice.stop, slice.step
|
|
661
|
+
) as (pos_range, neg_range):
|
|
662
|
+
with pos_range as (index, count):
|
|
663
|
+
value = src.getitem(count)
|
|
664
|
+
dest.setitem(index, value, incref=True)
|
|
665
|
+
with neg_range as (index, count):
|
|
666
|
+
value = src.getitem(count)
|
|
667
|
+
dest.setitem(index, value, incref=True)
|
|
668
|
+
|
|
669
|
+
return context.get_dummy_value()
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
@lower(operator.delitem, types.List, types.Integer)
|
|
673
|
+
def delitem_list_index(context, builder, sig, args):
|
|
674
|
+
def list_delitem_impl(lst, i):
|
|
675
|
+
lst.pop(i)
|
|
676
|
+
|
|
677
|
+
return context.compile_internal(builder, list_delitem_impl, sig, args)
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
@lower(operator.delitem, types.List, types.SliceType)
|
|
681
|
+
def delitem_list(context, builder, sig, args):
|
|
682
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
683
|
+
slice = context.make_helper(builder, sig.args[1], args[1])
|
|
684
|
+
|
|
685
|
+
slicing.guard_invalid_slice(context, builder, sig.args[1], slice)
|
|
686
|
+
inst.fix_slice(slice)
|
|
687
|
+
|
|
688
|
+
slice_len = slicing.get_slice_length(builder, slice)
|
|
689
|
+
|
|
690
|
+
one = ir.Constant(slice_len.type, 1)
|
|
691
|
+
|
|
692
|
+
with builder.if_then(
|
|
693
|
+
builder.icmp_signed("!=", slice.step, one), likely=False
|
|
694
|
+
):
|
|
695
|
+
msg = "unsupported del list[start:stop:step] with step != 1"
|
|
696
|
+
context.call_conv.return_user_exc(builder, NotImplementedError, (msg,))
|
|
697
|
+
|
|
698
|
+
# Compute the real stop, e.g. for dest[2:0]
|
|
699
|
+
start = slice.start
|
|
700
|
+
real_stop = builder.add(start, slice_len)
|
|
701
|
+
# Decref the removed range
|
|
702
|
+
with cgutils.for_range_slice(builder, start, real_stop, start.type(1)) as (
|
|
703
|
+
idx,
|
|
704
|
+
_,
|
|
705
|
+
):
|
|
706
|
+
inst.decref_value(inst.getitem(idx))
|
|
707
|
+
|
|
708
|
+
# Size of the list tail, after the end of slice
|
|
709
|
+
tail_size = builder.sub(inst.size, real_stop)
|
|
710
|
+
inst.move(start, real_stop, tail_size)
|
|
711
|
+
inst.resize(builder.sub(inst.size, slice_len))
|
|
712
|
+
|
|
713
|
+
return context.get_dummy_value()
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
# XXX should there be a specific module for Sequence or collection base classes?
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
@lower(operator.contains, types.Sequence, types.Any)
|
|
720
|
+
def in_seq(context, builder, sig, args):
|
|
721
|
+
def seq_contains_impl(lst, value):
|
|
722
|
+
for elem in lst:
|
|
723
|
+
if elem == value:
|
|
724
|
+
return True
|
|
725
|
+
return False
|
|
726
|
+
|
|
727
|
+
return context.compile_internal(builder, seq_contains_impl, sig, args)
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
@lower(bool, types.Sequence)
|
|
731
|
+
def sequence_bool(context, builder, sig, args):
|
|
732
|
+
def sequence_bool_impl(seq):
|
|
733
|
+
return len(seq) != 0
|
|
734
|
+
|
|
735
|
+
return context.compile_internal(builder, sequence_bool_impl, sig, args)
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
@overload(operator.truth)
|
|
739
|
+
def sequence_truth(seq):
|
|
740
|
+
if isinstance(seq, types.Sequence):
|
|
741
|
+
|
|
742
|
+
def impl(seq):
|
|
743
|
+
return len(seq) != 0
|
|
744
|
+
|
|
745
|
+
return impl
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
@lower(operator.add, types.List, types.List)
|
|
749
|
+
def list_add(context, builder, sig, args):
|
|
750
|
+
a = ListInstance(context, builder, sig.args[0], args[0])
|
|
751
|
+
b = ListInstance(context, builder, sig.args[1], args[1])
|
|
752
|
+
|
|
753
|
+
a_size = a.size
|
|
754
|
+
b_size = b.size
|
|
755
|
+
nitems = builder.add(a_size, b_size)
|
|
756
|
+
dest = ListInstance.allocate(context, builder, sig.return_type, nitems)
|
|
757
|
+
dest.size = nitems
|
|
758
|
+
|
|
759
|
+
with cgutils.for_range(builder, a_size) as loop:
|
|
760
|
+
value = a.getitem(loop.index)
|
|
761
|
+
value = context.cast(builder, value, a.dtype, dest.dtype)
|
|
762
|
+
dest.setitem(loop.index, value, incref=True)
|
|
763
|
+
with cgutils.for_range(builder, b_size) as loop:
|
|
764
|
+
value = b.getitem(loop.index)
|
|
765
|
+
value = context.cast(builder, value, b.dtype, dest.dtype)
|
|
766
|
+
dest.setitem(builder.add(loop.index, a_size), value, incref=True)
|
|
767
|
+
|
|
768
|
+
return impl_ret_new_ref(context, builder, sig.return_type, dest.value)
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
@lower(operator.iadd, types.List, types.List)
|
|
772
|
+
def list_add_inplace(context, builder, sig, args):
|
|
773
|
+
assert sig.args[0].dtype == sig.return_type.dtype
|
|
774
|
+
dest = _list_extend_list(context, builder, sig, args)
|
|
775
|
+
|
|
776
|
+
return impl_ret_borrowed(context, builder, sig.return_type, dest.value)
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
@lower(operator.mul, types.List, types.Integer)
|
|
780
|
+
@lower(operator.mul, types.Integer, types.List)
|
|
781
|
+
def list_mul(context, builder, sig, args):
|
|
782
|
+
if isinstance(sig.args[0], types.List):
|
|
783
|
+
list_idx, int_idx = 0, 1
|
|
784
|
+
else:
|
|
785
|
+
list_idx, int_idx = 1, 0
|
|
786
|
+
src = ListInstance(context, builder, sig.args[list_idx], args[list_idx])
|
|
787
|
+
src_size = src.size
|
|
788
|
+
|
|
789
|
+
mult = args[int_idx]
|
|
790
|
+
zero = ir.Constant(mult.type, 0)
|
|
791
|
+
mult = builder.select(cgutils.is_neg_int(builder, mult), zero, mult)
|
|
792
|
+
nitems = builder.mul(mult, src_size)
|
|
793
|
+
|
|
794
|
+
dest = ListInstance.allocate(context, builder, sig.return_type, nitems)
|
|
795
|
+
dest.size = nitems
|
|
796
|
+
|
|
797
|
+
with cgutils.for_range_slice(builder, zero, nitems, src_size, inc=True) as (
|
|
798
|
+
dest_offset,
|
|
799
|
+
_,
|
|
800
|
+
):
|
|
801
|
+
with cgutils.for_range(builder, src_size) as loop:
|
|
802
|
+
value = src.getitem(loop.index)
|
|
803
|
+
dest.setitem(
|
|
804
|
+
builder.add(loop.index, dest_offset), value, incref=True
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
return impl_ret_new_ref(context, builder, sig.return_type, dest.value)
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
@lower(operator.imul, types.List, types.Integer)
|
|
811
|
+
def list_mul_inplace(context, builder, sig, args):
|
|
812
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
813
|
+
src_size = inst.size
|
|
814
|
+
|
|
815
|
+
mult = args[1]
|
|
816
|
+
zero = ir.Constant(mult.type, 0)
|
|
817
|
+
mult = builder.select(cgutils.is_neg_int(builder, mult), zero, mult)
|
|
818
|
+
nitems = builder.mul(mult, src_size)
|
|
819
|
+
|
|
820
|
+
inst.resize(nitems)
|
|
821
|
+
|
|
822
|
+
with cgutils.for_range_slice(
|
|
823
|
+
builder, src_size, nitems, src_size, inc=True
|
|
824
|
+
) as (dest_offset, _):
|
|
825
|
+
with cgutils.for_range(builder, src_size) as loop:
|
|
826
|
+
value = inst.getitem(loop.index)
|
|
827
|
+
inst.setitem(
|
|
828
|
+
builder.add(loop.index, dest_offset), value, incref=True
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
return impl_ret_borrowed(context, builder, sig.return_type, inst.value)
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
# -------------------------------------------------------------------------------
|
|
835
|
+
# Comparisons
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
@lower(operator.is_, types.List, types.List)
|
|
839
|
+
def list_is(context, builder, sig, args):
|
|
840
|
+
a = ListInstance(context, builder, sig.args[0], args[0])
|
|
841
|
+
b = ListInstance(context, builder, sig.args[1], args[1])
|
|
842
|
+
ma = builder.ptrtoint(a.meminfo, cgutils.intp_t)
|
|
843
|
+
mb = builder.ptrtoint(b.meminfo, cgutils.intp_t)
|
|
844
|
+
return builder.icmp_signed("==", ma, mb)
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
@lower(operator.eq, types.List, types.List)
|
|
848
|
+
def list_eq(context, builder, sig, args):
|
|
849
|
+
aty, bty = sig.args
|
|
850
|
+
a = ListInstance(context, builder, aty, args[0])
|
|
851
|
+
b = ListInstance(context, builder, bty, args[1])
|
|
852
|
+
|
|
853
|
+
a_size = a.size
|
|
854
|
+
same_size = builder.icmp_signed("==", a_size, b.size)
|
|
855
|
+
|
|
856
|
+
res = cgutils.alloca_once_value(builder, same_size)
|
|
857
|
+
|
|
858
|
+
with builder.if_then(same_size):
|
|
859
|
+
with cgutils.for_range(builder, a_size) as loop:
|
|
860
|
+
v = a.getitem(loop.index)
|
|
861
|
+
w = b.getitem(loop.index)
|
|
862
|
+
itemres = context.generic_compare(
|
|
863
|
+
builder, operator.eq, (aty.dtype, bty.dtype), (v, w)
|
|
864
|
+
)
|
|
865
|
+
with builder.if_then(builder.not_(itemres)):
|
|
866
|
+
# Exit early
|
|
867
|
+
builder.store(cgutils.false_bit, res)
|
|
868
|
+
loop.do_break()
|
|
869
|
+
|
|
870
|
+
return builder.load(res)
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
def all_list(*args):
|
|
874
|
+
return all([isinstance(typ, types.List) for typ in args])
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
@overload(operator.ne)
|
|
878
|
+
def impl_list_ne(a, b):
|
|
879
|
+
if not all_list(a, b):
|
|
880
|
+
return
|
|
881
|
+
|
|
882
|
+
def list_ne_impl(a, b):
|
|
883
|
+
return not (a == b)
|
|
884
|
+
|
|
885
|
+
return list_ne_impl
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
@overload(operator.le)
|
|
889
|
+
def impl_list_le(a, b):
|
|
890
|
+
if not all_list(a, b):
|
|
891
|
+
return
|
|
892
|
+
|
|
893
|
+
def list_le_impl(a, b):
|
|
894
|
+
m = len(a)
|
|
895
|
+
n = len(b)
|
|
896
|
+
for i in range(min(m, n)):
|
|
897
|
+
if a[i] < b[i]:
|
|
898
|
+
return True
|
|
899
|
+
elif a[i] > b[i]:
|
|
900
|
+
return False
|
|
901
|
+
return m <= n
|
|
902
|
+
|
|
903
|
+
return list_le_impl
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
@overload(operator.lt)
|
|
907
|
+
def impl_list_lt(a, b):
|
|
908
|
+
if not all_list(a, b):
|
|
909
|
+
return
|
|
910
|
+
|
|
911
|
+
def list_lt_impl(a, b):
|
|
912
|
+
m = len(a)
|
|
913
|
+
n = len(b)
|
|
914
|
+
for i in range(min(m, n)):
|
|
915
|
+
if a[i] < b[i]:
|
|
916
|
+
return True
|
|
917
|
+
elif a[i] > b[i]:
|
|
918
|
+
return False
|
|
919
|
+
return m < n
|
|
920
|
+
|
|
921
|
+
return list_lt_impl
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
@overload(operator.ge)
|
|
925
|
+
def impl_list_ge(a, b):
|
|
926
|
+
if not all_list(a, b):
|
|
927
|
+
return
|
|
928
|
+
|
|
929
|
+
def list_ge_impl(a, b):
|
|
930
|
+
return b <= a
|
|
931
|
+
|
|
932
|
+
return list_ge_impl
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
@overload(operator.gt)
|
|
936
|
+
def impl_list_gt(a, b):
|
|
937
|
+
if not all_list(a, b):
|
|
938
|
+
return
|
|
939
|
+
|
|
940
|
+
def list_gt_impl(a, b):
|
|
941
|
+
return b < a
|
|
942
|
+
|
|
943
|
+
return list_gt_impl
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
# -------------------------------------------------------------------------------
|
|
947
|
+
# Methods
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
@lower("list.append", types.List, types.Any)
|
|
951
|
+
def list_append(context, builder, sig, args):
|
|
952
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
953
|
+
item = args[1]
|
|
954
|
+
|
|
955
|
+
n = inst.size
|
|
956
|
+
new_size = builder.add(n, ir.Constant(n.type, 1))
|
|
957
|
+
inst.resize(new_size)
|
|
958
|
+
inst.setitem(n, item, incref=True)
|
|
959
|
+
|
|
960
|
+
return context.get_dummy_value()
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
@lower("list.clear", types.List)
|
|
964
|
+
def list_clear(context, builder, sig, args):
|
|
965
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
966
|
+
inst.resize(context.get_constant(types.intp, 0))
|
|
967
|
+
|
|
968
|
+
return context.get_dummy_value()
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
@overload_method(types.List, "copy")
|
|
972
|
+
def list_copy(lst):
|
|
973
|
+
def list_copy_impl(lst):
|
|
974
|
+
return list(lst)
|
|
975
|
+
|
|
976
|
+
return list_copy_impl
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
@overload_method(types.List, "count")
|
|
980
|
+
def list_count(lst, value):
|
|
981
|
+
def list_count_impl(lst, value):
|
|
982
|
+
res = 0
|
|
983
|
+
for elem in lst:
|
|
984
|
+
if elem == value:
|
|
985
|
+
res += 1
|
|
986
|
+
return res
|
|
987
|
+
|
|
988
|
+
return list_count_impl
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
def _list_extend_list(context, builder, sig, args):
|
|
992
|
+
src = ListInstance(context, builder, sig.args[1], args[1])
|
|
993
|
+
dest = ListInstance(context, builder, sig.args[0], args[0])
|
|
994
|
+
|
|
995
|
+
src_size = src.size
|
|
996
|
+
dest_size = dest.size
|
|
997
|
+
nitems = builder.add(src_size, dest_size)
|
|
998
|
+
dest.resize(nitems)
|
|
999
|
+
dest.size = nitems
|
|
1000
|
+
|
|
1001
|
+
with cgutils.for_range(builder, src_size) as loop:
|
|
1002
|
+
value = src.getitem(loop.index)
|
|
1003
|
+
value = context.cast(builder, value, src.dtype, dest.dtype)
|
|
1004
|
+
dest.setitem(builder.add(loop.index, dest_size), value, incref=True)
|
|
1005
|
+
|
|
1006
|
+
return dest
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
@lower("list.extend", types.List, types.IterableType)
|
|
1010
|
+
def list_extend(context, builder, sig, args):
|
|
1011
|
+
if isinstance(sig.args[1], types.List):
|
|
1012
|
+
# Specialize for list operands, for speed.
|
|
1013
|
+
_list_extend_list(context, builder, sig, args)
|
|
1014
|
+
return context.get_dummy_value()
|
|
1015
|
+
|
|
1016
|
+
def list_extend(lst, iterable):
|
|
1017
|
+
# Speed hack to avoid NRT refcount operations inside the loop
|
|
1018
|
+
meth = lst.append
|
|
1019
|
+
for v in iterable:
|
|
1020
|
+
meth(v)
|
|
1021
|
+
|
|
1022
|
+
return context.compile_internal(builder, list_extend, sig, args)
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
intp_max = types.intp.maxval
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
@overload_method(types.List, "index")
|
|
1029
|
+
def list_index(lst, value, start=0, stop=intp_max):
|
|
1030
|
+
if not isinstance(start, (int, types.Integer, types.Omitted)):
|
|
1031
|
+
raise errors.TypingError(f'arg "start" must be an Integer. Got {start}')
|
|
1032
|
+
if not isinstance(stop, (int, types.Integer, types.Omitted)):
|
|
1033
|
+
raise errors.TypingError(f'arg "stop" must be an Integer. Got {stop}')
|
|
1034
|
+
|
|
1035
|
+
def list_index_impl(lst, value, start=0, stop=intp_max):
|
|
1036
|
+
n = len(lst)
|
|
1037
|
+
if start < 0:
|
|
1038
|
+
start += n
|
|
1039
|
+
if start < 0:
|
|
1040
|
+
start = 0
|
|
1041
|
+
if stop < 0:
|
|
1042
|
+
stop += n
|
|
1043
|
+
if stop > n:
|
|
1044
|
+
stop = n
|
|
1045
|
+
for i in range(start, stop):
|
|
1046
|
+
if lst[i] == value:
|
|
1047
|
+
return i
|
|
1048
|
+
# XXX references are leaked when raising
|
|
1049
|
+
raise ValueError("value not in list")
|
|
1050
|
+
|
|
1051
|
+
return list_index_impl
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
@lower("list.insert", types.List, types.Integer, types.Any)
|
|
1055
|
+
def list_insert(context, builder, sig, args):
|
|
1056
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
1057
|
+
index = inst.fix_index(args[1])
|
|
1058
|
+
index = inst.clamp_index(index)
|
|
1059
|
+
value = args[2]
|
|
1060
|
+
|
|
1061
|
+
n = inst.size
|
|
1062
|
+
one = ir.Constant(n.type, 1)
|
|
1063
|
+
new_size = builder.add(n, one)
|
|
1064
|
+
inst.resize(new_size)
|
|
1065
|
+
inst.move(builder.add(index, one), index, builder.sub(n, index))
|
|
1066
|
+
inst.setitem(index, value, incref=True, decref_old_value=False)
|
|
1067
|
+
|
|
1068
|
+
return context.get_dummy_value()
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
@lower("list.pop", types.List)
|
|
1072
|
+
def list_pop(context, builder, sig, args):
|
|
1073
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
1074
|
+
|
|
1075
|
+
n = inst.size
|
|
1076
|
+
cgutils.guard_zero(context, builder, n, (IndexError, "pop from empty list"))
|
|
1077
|
+
n = builder.sub(n, ir.Constant(n.type, 1))
|
|
1078
|
+
res = inst.getitem(n)
|
|
1079
|
+
inst.incref_value(res) # incref the pop'ed element
|
|
1080
|
+
inst.clear_value(n) # clear the storage space
|
|
1081
|
+
inst.resize(n)
|
|
1082
|
+
return impl_ret_new_ref(context, builder, sig.return_type, res)
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
@lower("list.pop", types.List, types.Integer)
|
|
1086
|
+
def list_pop(context, builder, sig, args): # noqa: F811
|
|
1087
|
+
inst = ListInstance(context, builder, sig.args[0], args[0])
|
|
1088
|
+
idx = inst.fix_index(args[1])
|
|
1089
|
+
|
|
1090
|
+
n = inst.size
|
|
1091
|
+
cgutils.guard_zero(context, builder, n, (IndexError, "pop from empty list"))
|
|
1092
|
+
inst.guard_index(idx, "pop index out of range")
|
|
1093
|
+
|
|
1094
|
+
res = inst.getitem(idx)
|
|
1095
|
+
|
|
1096
|
+
one = ir.Constant(n.type, 1)
|
|
1097
|
+
n = builder.sub(n, ir.Constant(n.type, 1))
|
|
1098
|
+
inst.move(idx, builder.add(idx, one), builder.sub(n, idx))
|
|
1099
|
+
inst.resize(n)
|
|
1100
|
+
return impl_ret_new_ref(context, builder, sig.return_type, res)
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
@overload_method(types.List, "remove")
|
|
1104
|
+
def list_remove(lst, value):
|
|
1105
|
+
def list_remove_impl(lst, value):
|
|
1106
|
+
for i in range(len(lst)):
|
|
1107
|
+
if lst[i] == value:
|
|
1108
|
+
lst.pop(i)
|
|
1109
|
+
return
|
|
1110
|
+
# XXX references are leaked when raising
|
|
1111
|
+
raise ValueError("list.remove(x): x not in list")
|
|
1112
|
+
|
|
1113
|
+
return list_remove_impl
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
@overload_method(types.List, "reverse")
|
|
1117
|
+
def list_reverse(lst):
|
|
1118
|
+
def list_reverse_impl(lst):
|
|
1119
|
+
for a in range(0, len(lst) // 2):
|
|
1120
|
+
b = -a - 1
|
|
1121
|
+
lst[a], lst[b] = lst[b], lst[a]
|
|
1122
|
+
|
|
1123
|
+
return list_reverse_impl
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
# -----------------------------------------------------------------------------
|
|
1127
|
+
# Sorting
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
def gt(a, b):
|
|
1131
|
+
return a > b
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def _sort_check_reverse(reverse):
|
|
1135
|
+
if isinstance(reverse, types.Omitted):
|
|
1136
|
+
rty = reverse.value
|
|
1137
|
+
elif isinstance(reverse, types.Optional):
|
|
1138
|
+
rty = reverse.type
|
|
1139
|
+
else:
|
|
1140
|
+
rty = reverse
|
|
1141
|
+
if not isinstance(rty, (types.Boolean, types.Integer, int, bool)):
|
|
1142
|
+
msg = "an integer is required for 'reverse' (got type %s)" % reverse
|
|
1143
|
+
raise errors.TypingError(msg)
|
|
1144
|
+
return rty
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
def _sort_check_key(key):
|
|
1148
|
+
if isinstance(key, types.Optional):
|
|
1149
|
+
msg = (
|
|
1150
|
+
"Key must concretely be None or a Numba JIT compiled function, "
|
|
1151
|
+
"an Optional (union of None and a value) was found"
|
|
1152
|
+
)
|
|
1153
|
+
raise errors.TypingError(msg)
|
|
1154
|
+
if not (cgutils.is_nonelike(key) or isinstance(key, types.Dispatcher)):
|
|
1155
|
+
msg = "Key must be None or a Numba JIT compiled function"
|
|
1156
|
+
raise errors.TypingError(msg)
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
@overload(sorted)
|
|
1160
|
+
def ol_sorted(iterable, key=None, reverse=False):
|
|
1161
|
+
if not isinstance(iterable, types.IterableType):
|
|
1162
|
+
return False
|
|
1163
|
+
|
|
1164
|
+
_sort_check_key(key)
|
|
1165
|
+
_sort_check_reverse(reverse)
|
|
1166
|
+
|
|
1167
|
+
def impl(iterable, key=None, reverse=False):
|
|
1168
|
+
lst = list(iterable)
|
|
1169
|
+
lst.sort(key=key, reverse=reverse)
|
|
1170
|
+
return lst
|
|
1171
|
+
|
|
1172
|
+
return impl
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
# -----------------------------------------------------------------------------
|
|
1176
|
+
# Implicit casting
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
@lower_cast(types.List, types.List)
|
|
1180
|
+
def list_to_list(context, builder, fromty, toty, val):
|
|
1181
|
+
# Casting from non-reflected to reflected
|
|
1182
|
+
assert fromty.dtype == toty.dtype
|
|
1183
|
+
return val
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
# -----------------------------------------------------------------------------
|
|
1187
|
+
# Implementations for types.LiteralList
|
|
1188
|
+
# -----------------------------------------------------------------------------
|
|
1189
|
+
|
|
1190
|
+
_banned_error = errors.TypingError("Cannot mutate a literal list")
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
# Things that mutate literal lists are banned
|
|
1194
|
+
@overload_method(types.LiteralList, "append")
|
|
1195
|
+
def literal_list_banned_append(lst, obj):
|
|
1196
|
+
raise _banned_error
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
@overload_method(types.LiteralList, "extend")
|
|
1200
|
+
def literal_list_banned_extend(lst, iterable):
|
|
1201
|
+
raise _banned_error
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
@overload_method(types.LiteralList, "insert")
|
|
1205
|
+
def literal_list_banned_insert(lst, index, obj):
|
|
1206
|
+
raise _banned_error
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
@overload_method(types.LiteralList, "remove")
|
|
1210
|
+
def literal_list_banned_remove(lst, value):
|
|
1211
|
+
raise _banned_error
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
@overload_method(types.LiteralList, "pop")
|
|
1215
|
+
def literal_list_banned_pop(lst, index=-1):
|
|
1216
|
+
raise _banned_error
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
@overload_method(types.LiteralList, "clear")
|
|
1220
|
+
def literal_list_banned_clear(lst):
|
|
1221
|
+
raise _banned_error
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
@overload_method(types.LiteralList, "sort")
|
|
1225
|
+
def literal_list_banned_sort(lst, key=None, reverse=False):
|
|
1226
|
+
raise _banned_error
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
@overload_method(types.LiteralList, "reverse")
|
|
1230
|
+
def literal_list_banned_reverse(lst):
|
|
1231
|
+
raise _banned_error
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
_index_end = types.intp.maxval
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
@overload_method(types.LiteralList, "index")
|
|
1238
|
+
def literal_list_index(lst, x, start=0, end=_index_end):
|
|
1239
|
+
# TODO: To make this work, need consts as slice for start/end so as to
|
|
1240
|
+
# be able to statically analyse the bounds, then its a just loop body
|
|
1241
|
+
# versioning based iteration along with enumerate to find the item
|
|
1242
|
+
if isinstance(lst, types.LiteralList):
|
|
1243
|
+
msg = "list.index is unsupported for literal lists"
|
|
1244
|
+
raise errors.TypingError(msg)
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
@overload_method(types.LiteralList, "count")
|
|
1248
|
+
def literal_list_count(lst, x):
|
|
1249
|
+
if isinstance(lst, types.LiteralList):
|
|
1250
|
+
|
|
1251
|
+
def impl(lst, x):
|
|
1252
|
+
count = 0
|
|
1253
|
+
for val in literal_unroll(lst):
|
|
1254
|
+
if val == x:
|
|
1255
|
+
count += 1
|
|
1256
|
+
return count
|
|
1257
|
+
|
|
1258
|
+
return impl
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
@overload_method(types.LiteralList, "copy")
|
|
1262
|
+
def literal_list_count(lst): # noqa: F811
|
|
1263
|
+
if isinstance(lst, types.LiteralList):
|
|
1264
|
+
|
|
1265
|
+
def impl(lst):
|
|
1266
|
+
return lst # tuples are immutable, as is this, so just return it
|
|
1267
|
+
|
|
1268
|
+
return impl
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
@overload(operator.delitem)
|
|
1272
|
+
def literal_list_delitem(lst, index):
|
|
1273
|
+
if isinstance(lst, types.LiteralList):
|
|
1274
|
+
raise _banned_error
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
@overload(operator.setitem)
|
|
1278
|
+
def literal_list_setitem(lst, index, value):
|
|
1279
|
+
if isinstance(lst, types.LiteralList):
|
|
1280
|
+
raise errors.TypingError("Cannot mutate a literal list")
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
@overload(operator.getitem)
|
|
1284
|
+
def literal_list_getitem(lst, *args):
|
|
1285
|
+
if not isinstance(lst, types.LiteralList):
|
|
1286
|
+
return
|
|
1287
|
+
msg = (
|
|
1288
|
+
"Cannot __getitem__ on a literal list, return type cannot be "
|
|
1289
|
+
"statically determined."
|
|
1290
|
+
)
|
|
1291
|
+
raise errors.TypingError(msg)
|
|
1292
|
+
|
|
1293
|
+
|
|
1294
|
+
@overload(len)
|
|
1295
|
+
def literal_list_len(lst):
|
|
1296
|
+
if not isinstance(lst, types.LiteralList):
|
|
1297
|
+
return
|
|
1298
|
+
l = lst.count
|
|
1299
|
+
return lambda lst: l
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
@overload(operator.contains)
|
|
1303
|
+
def literal_list_contains(lst, item):
|
|
1304
|
+
if isinstance(lst, types.LiteralList):
|
|
1305
|
+
|
|
1306
|
+
def impl(lst, item):
|
|
1307
|
+
for val in literal_unroll(lst):
|
|
1308
|
+
if val == item:
|
|
1309
|
+
return True
|
|
1310
|
+
return False
|
|
1311
|
+
|
|
1312
|
+
return impl
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
@lower_cast(types.LiteralList, types.LiteralList)
|
|
1316
|
+
def literallist_to_literallist(context, builder, fromty, toty, val):
|
|
1317
|
+
if len(fromty) != len(toty):
|
|
1318
|
+
# Disallowed by typing layer
|
|
1319
|
+
raise NotImplementedError
|
|
1320
|
+
|
|
1321
|
+
olditems = cgutils.unpack_tuple(builder, val, len(fromty))
|
|
1322
|
+
items = [
|
|
1323
|
+
context.cast(builder, v, f, t)
|
|
1324
|
+
for v, f, t in zip(olditems, fromty, toty)
|
|
1325
|
+
]
|
|
1326
|
+
return context.make_tuple(builder, toty, items)
|