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,1122 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
3
|
+
|
|
4
|
+
# Tests numba.analysis functions
|
|
5
|
+
import collections
|
|
6
|
+
import types as pytypes
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
from numba.cuda.compiler import run_frontend
|
|
10
|
+
from numba.cuda.flags import Flags
|
|
11
|
+
from numba.cuda.core.compiler import StateDict
|
|
12
|
+
from numba.cuda import jit
|
|
13
|
+
from numba.cuda import types
|
|
14
|
+
from numba.cuda.core import errors
|
|
15
|
+
from numba.cuda.core import ir
|
|
16
|
+
from numba.cuda.utils import PYVERSION
|
|
17
|
+
from numba.cuda.core import postproc, rewrites, ir_utils
|
|
18
|
+
from numba.cuda.core.options import ParallelOptions
|
|
19
|
+
from numba.cuda.core.inline_closurecall import InlineClosureCallPass
|
|
20
|
+
from numba.cuda.tests.support import TestCase, override_config
|
|
21
|
+
from numba.cuda.core.analysis import (
|
|
22
|
+
dead_branch_prune,
|
|
23
|
+
rewrite_semantic_constants,
|
|
24
|
+
)
|
|
25
|
+
from numba.cuda.core.untyped_passes import (
|
|
26
|
+
ReconstructSSA,
|
|
27
|
+
)
|
|
28
|
+
import unittest
|
|
29
|
+
from numba.cuda.core import config
|
|
30
|
+
|
|
31
|
+
_GLOBAL = 123
|
|
32
|
+
|
|
33
|
+
enable_pyobj_flags = Flags()
|
|
34
|
+
enable_pyobj_flags.enable_pyobject = True
|
|
35
|
+
|
|
36
|
+
if config.ENABLE_CUDASIM:
|
|
37
|
+
raise unittest.SkipTest("Analysis passes not done in simulator")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def compile_to_ir(func):
|
|
41
|
+
func_ir = run_frontend(func)
|
|
42
|
+
state = StateDict()
|
|
43
|
+
state.func_ir = func_ir
|
|
44
|
+
state.typemap = None
|
|
45
|
+
state.calltypes = None
|
|
46
|
+
# Transform to SSA
|
|
47
|
+
ReconstructSSA().run_pass(state)
|
|
48
|
+
# call this to get print etc rewrites
|
|
49
|
+
rewrites.rewrite_registry.apply("before-inference", state)
|
|
50
|
+
return func_ir
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class TestBranchPruneBase(TestCase):
|
|
54
|
+
"""
|
|
55
|
+
Tests branch pruning
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
_DEBUG = False
|
|
59
|
+
|
|
60
|
+
# find *all* branches
|
|
61
|
+
def find_branches(self, the_ir):
|
|
62
|
+
branches = []
|
|
63
|
+
for blk in the_ir.blocks.values():
|
|
64
|
+
tmp = [_ for _ in blk.find_insts(cls=ir.Branch)]
|
|
65
|
+
branches.extend(tmp)
|
|
66
|
+
return branches
|
|
67
|
+
|
|
68
|
+
def assert_prune(self, func, args_tys, prune, *args, **kwargs):
|
|
69
|
+
# This checks that the expected pruned branches have indeed been pruned.
|
|
70
|
+
# func is a python function to assess
|
|
71
|
+
# args_tys is the numba types arguments tuple
|
|
72
|
+
# prune arg is a list, one entry per branch. The value in the entry is
|
|
73
|
+
# encoded as follows:
|
|
74
|
+
# True: using constant inference only, the True branch will be pruned
|
|
75
|
+
# False: using constant inference only, the False branch will be pruned
|
|
76
|
+
# None: under no circumstances should this branch be pruned
|
|
77
|
+
# *args: the argument instances to pass to the function to check
|
|
78
|
+
# execution is still valid post transform
|
|
79
|
+
# **kwargs:
|
|
80
|
+
# - flags: args to pass to `jit` default is `nopython=True`,
|
|
81
|
+
# e.g. permits use of e.g. object mode.
|
|
82
|
+
|
|
83
|
+
func_ir = compile_to_ir(func)
|
|
84
|
+
before = func_ir.copy()
|
|
85
|
+
if self._DEBUG:
|
|
86
|
+
print("=" * 80)
|
|
87
|
+
print("before inline")
|
|
88
|
+
func_ir.dump()
|
|
89
|
+
|
|
90
|
+
# run closure inlining to ensure that nonlocals in closures are visible
|
|
91
|
+
inline_pass = InlineClosureCallPass(
|
|
92
|
+
func_ir,
|
|
93
|
+
ParallelOptions(False),
|
|
94
|
+
)
|
|
95
|
+
inline_pass.run()
|
|
96
|
+
|
|
97
|
+
# Remove all Dels, and re-run postproc
|
|
98
|
+
post_proc = postproc.PostProcessor(func_ir)
|
|
99
|
+
post_proc.run()
|
|
100
|
+
|
|
101
|
+
rewrite_semantic_constants(func_ir, args_tys)
|
|
102
|
+
if self._DEBUG:
|
|
103
|
+
print("=" * 80)
|
|
104
|
+
print("before prune")
|
|
105
|
+
func_ir.dump()
|
|
106
|
+
|
|
107
|
+
dead_branch_prune(func_ir, args_tys)
|
|
108
|
+
|
|
109
|
+
after = func_ir
|
|
110
|
+
if self._DEBUG:
|
|
111
|
+
print("after prune")
|
|
112
|
+
func_ir.dump()
|
|
113
|
+
|
|
114
|
+
before_branches = self.find_branches(before)
|
|
115
|
+
self.assertEqual(len(before_branches), len(prune))
|
|
116
|
+
|
|
117
|
+
# what is expected to be pruned
|
|
118
|
+
expect_removed = []
|
|
119
|
+
for idx, prune in enumerate(prune):
|
|
120
|
+
branch = before_branches[idx]
|
|
121
|
+
if prune is True:
|
|
122
|
+
expect_removed.append(branch.truebr)
|
|
123
|
+
elif prune is False:
|
|
124
|
+
expect_removed.append(branch.falsebr)
|
|
125
|
+
elif prune is None:
|
|
126
|
+
pass # nothing should be removed!
|
|
127
|
+
elif prune == "both":
|
|
128
|
+
expect_removed.append(branch.falsebr)
|
|
129
|
+
expect_removed.append(branch.truebr)
|
|
130
|
+
else:
|
|
131
|
+
assert 0, "unreachable"
|
|
132
|
+
|
|
133
|
+
# compare labels
|
|
134
|
+
original_labels = set([_ for _ in before.blocks.keys()])
|
|
135
|
+
new_labels = set([_ for _ in after.blocks.keys()])
|
|
136
|
+
# assert that the new labels are precisely the original less the
|
|
137
|
+
# expected pruned labels
|
|
138
|
+
try:
|
|
139
|
+
self.assertEqual(new_labels, original_labels - set(expect_removed))
|
|
140
|
+
except AssertionError as e:
|
|
141
|
+
print("new_labels", sorted(new_labels))
|
|
142
|
+
print("original_labels", sorted(original_labels))
|
|
143
|
+
print("expect_removed", sorted(expect_removed))
|
|
144
|
+
raise e
|
|
145
|
+
|
|
146
|
+
if [
|
|
147
|
+
arg is types.NoneType("none") or arg is types.Omitted(None)
|
|
148
|
+
for arg in args_tys
|
|
149
|
+
].count(True) == 0:
|
|
150
|
+
self.run_func(func, args)
|
|
151
|
+
|
|
152
|
+
def run_func(self, impl, args):
|
|
153
|
+
cres = jit(impl)
|
|
154
|
+
dargs = args
|
|
155
|
+
out = np.zeros(1)
|
|
156
|
+
cout = np.zeros(1)
|
|
157
|
+
args += (out,)
|
|
158
|
+
dargs += (cout,)
|
|
159
|
+
cres.py_func(*args)
|
|
160
|
+
with override_config("DISABLE_PERFORMANCE_WARNINGS", 1):
|
|
161
|
+
cres[1, 1](*dargs)
|
|
162
|
+
self.assertPreciseEqual(out[0], cout[0])
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class TestBranchPrune(TestBranchPruneBase):
|
|
166
|
+
def test_single_if(self):
|
|
167
|
+
def impl(x, res):
|
|
168
|
+
if 1 == 0:
|
|
169
|
+
res[0] = 3.14159
|
|
170
|
+
|
|
171
|
+
self.assert_prune(
|
|
172
|
+
impl,
|
|
173
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
174
|
+
[True],
|
|
175
|
+
None,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
def impl(x, res):
|
|
179
|
+
if 1 == 1:
|
|
180
|
+
res[0] = 3.14159
|
|
181
|
+
|
|
182
|
+
self.assert_prune(
|
|
183
|
+
impl,
|
|
184
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
185
|
+
[False],
|
|
186
|
+
None,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
def impl(x, res):
|
|
190
|
+
if x is None:
|
|
191
|
+
res[0] = 3.14159
|
|
192
|
+
|
|
193
|
+
self.assert_prune(
|
|
194
|
+
impl,
|
|
195
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
196
|
+
[False],
|
|
197
|
+
None,
|
|
198
|
+
)
|
|
199
|
+
self.assert_prune(
|
|
200
|
+
impl,
|
|
201
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
202
|
+
[True],
|
|
203
|
+
10,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
def impl(x, res):
|
|
207
|
+
if x == 10:
|
|
208
|
+
res[0] = 3.14159
|
|
209
|
+
|
|
210
|
+
self.assert_prune(
|
|
211
|
+
impl,
|
|
212
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
213
|
+
[True],
|
|
214
|
+
None,
|
|
215
|
+
)
|
|
216
|
+
self.assert_prune(
|
|
217
|
+
impl,
|
|
218
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
219
|
+
[None],
|
|
220
|
+
10,
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
def impl(x, res):
|
|
224
|
+
if x == 10:
|
|
225
|
+
z = 3.14159 # noqa: F841 # no effect
|
|
226
|
+
|
|
227
|
+
self.assert_prune(
|
|
228
|
+
impl,
|
|
229
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
230
|
+
[True],
|
|
231
|
+
None,
|
|
232
|
+
)
|
|
233
|
+
self.assert_prune(
|
|
234
|
+
impl,
|
|
235
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
236
|
+
[None],
|
|
237
|
+
10,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
def impl(x, res):
|
|
241
|
+
z = None
|
|
242
|
+
y = z
|
|
243
|
+
if x == y:
|
|
244
|
+
res[0] = 100
|
|
245
|
+
|
|
246
|
+
self.assert_prune(
|
|
247
|
+
impl,
|
|
248
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
249
|
+
[False],
|
|
250
|
+
None,
|
|
251
|
+
)
|
|
252
|
+
self.assert_prune(
|
|
253
|
+
impl,
|
|
254
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
255
|
+
[True],
|
|
256
|
+
10,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def test_single_if_else(self):
|
|
260
|
+
def impl(x, res):
|
|
261
|
+
if x is None:
|
|
262
|
+
res[0] = 3.14159
|
|
263
|
+
else:
|
|
264
|
+
res[0] = 1.61803
|
|
265
|
+
|
|
266
|
+
self.assert_prune(
|
|
267
|
+
impl,
|
|
268
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
269
|
+
[False],
|
|
270
|
+
None,
|
|
271
|
+
)
|
|
272
|
+
self.assert_prune(
|
|
273
|
+
impl,
|
|
274
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
275
|
+
[True],
|
|
276
|
+
10,
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
def test_single_if_const_val(self):
|
|
280
|
+
def impl(x, res):
|
|
281
|
+
if x == 100:
|
|
282
|
+
res[0] = 3.14159
|
|
283
|
+
|
|
284
|
+
self.assert_prune(
|
|
285
|
+
impl,
|
|
286
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
287
|
+
[True],
|
|
288
|
+
None,
|
|
289
|
+
)
|
|
290
|
+
self.assert_prune(
|
|
291
|
+
impl,
|
|
292
|
+
(types.IntegerLiteral(100), types.Array(types.float64, 1, "C")),
|
|
293
|
+
[None],
|
|
294
|
+
100,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def impl(x, res):
|
|
298
|
+
# switch the condition order
|
|
299
|
+
if 100 == x:
|
|
300
|
+
res[0] = 3.14159
|
|
301
|
+
|
|
302
|
+
self.assert_prune(
|
|
303
|
+
impl,
|
|
304
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
305
|
+
[True],
|
|
306
|
+
None,
|
|
307
|
+
)
|
|
308
|
+
self.assert_prune(
|
|
309
|
+
impl,
|
|
310
|
+
(types.IntegerLiteral(100), types.Array(types.float64, 1, "C")),
|
|
311
|
+
[None],
|
|
312
|
+
100,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
def test_single_if_else_two_const_val(self):
|
|
316
|
+
def impl(x, y, res):
|
|
317
|
+
if x == y:
|
|
318
|
+
res[0] = 3.14159
|
|
319
|
+
else:
|
|
320
|
+
res[0] = 1.61803
|
|
321
|
+
|
|
322
|
+
self.assert_prune(
|
|
323
|
+
impl,
|
|
324
|
+
(types.IntegerLiteral(100),) * 2
|
|
325
|
+
+ (types.Array(types.float64, 1, "C"),),
|
|
326
|
+
[None],
|
|
327
|
+
100,
|
|
328
|
+
100,
|
|
329
|
+
)
|
|
330
|
+
self.assert_prune(
|
|
331
|
+
impl,
|
|
332
|
+
(types.NoneType("none"),) * 2
|
|
333
|
+
+ (types.Array(types.float64, 1, "C"),),
|
|
334
|
+
[False],
|
|
335
|
+
None,
|
|
336
|
+
None,
|
|
337
|
+
)
|
|
338
|
+
self.assert_prune(
|
|
339
|
+
impl,
|
|
340
|
+
(
|
|
341
|
+
types.IntegerLiteral(100),
|
|
342
|
+
types.NoneType("none"),
|
|
343
|
+
types.Array(types.float64, 1, "C"),
|
|
344
|
+
),
|
|
345
|
+
[True],
|
|
346
|
+
100,
|
|
347
|
+
None,
|
|
348
|
+
)
|
|
349
|
+
self.assert_prune(
|
|
350
|
+
impl,
|
|
351
|
+
(
|
|
352
|
+
types.IntegerLiteral(100),
|
|
353
|
+
types.IntegerLiteral(1000),
|
|
354
|
+
types.Array(types.float64, 1, "C"),
|
|
355
|
+
),
|
|
356
|
+
[None],
|
|
357
|
+
100,
|
|
358
|
+
1000,
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
def test_single_if_else_w_following_undetermined(self):
|
|
362
|
+
def impl(x, res):
|
|
363
|
+
x_is_none_work = False
|
|
364
|
+
if x is None:
|
|
365
|
+
x_is_none_work = True
|
|
366
|
+
else:
|
|
367
|
+
dead = 7 # noqa: F841 # no effect
|
|
368
|
+
|
|
369
|
+
if x_is_none_work:
|
|
370
|
+
y = 10
|
|
371
|
+
else:
|
|
372
|
+
y = -3
|
|
373
|
+
res[0] = y
|
|
374
|
+
|
|
375
|
+
self.assert_prune(
|
|
376
|
+
impl,
|
|
377
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
378
|
+
[False, None],
|
|
379
|
+
None,
|
|
380
|
+
)
|
|
381
|
+
self.assert_prune(
|
|
382
|
+
impl,
|
|
383
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
384
|
+
[True, None],
|
|
385
|
+
10,
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
def impl(x, res):
|
|
389
|
+
x_is_none_work = False
|
|
390
|
+
if x is None:
|
|
391
|
+
x_is_none_work = True
|
|
392
|
+
else:
|
|
393
|
+
pass
|
|
394
|
+
|
|
395
|
+
if x_is_none_work:
|
|
396
|
+
y = 10
|
|
397
|
+
else:
|
|
398
|
+
y = -3
|
|
399
|
+
res[0] = y
|
|
400
|
+
|
|
401
|
+
# Python 3.10 creates a block with a NOP in it for the `pass` which
|
|
402
|
+
# means it gets pruned.
|
|
403
|
+
if PYVERSION >= (3, 10):
|
|
404
|
+
# Python 3.10 creates a block with a NOP in it for the `pass` which
|
|
405
|
+
# means it gets pruned.
|
|
406
|
+
self.assert_prune(
|
|
407
|
+
impl,
|
|
408
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
409
|
+
[False, None],
|
|
410
|
+
None,
|
|
411
|
+
)
|
|
412
|
+
else:
|
|
413
|
+
self.assert_prune(
|
|
414
|
+
impl,
|
|
415
|
+
(types.NoneType("none"), types.Array(types.float64, 1, "C")),
|
|
416
|
+
[None, None],
|
|
417
|
+
None,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
self.assert_prune(
|
|
421
|
+
impl,
|
|
422
|
+
(types.IntegerLiteral(10), types.Array(types.float64, 1, "C")),
|
|
423
|
+
[True, None],
|
|
424
|
+
10,
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
def test_double_if_else_rt_const(self):
|
|
428
|
+
def impl(x, res):
|
|
429
|
+
one_hundred = 100
|
|
430
|
+
x_is_none_work = 4
|
|
431
|
+
if x is None:
|
|
432
|
+
x_is_none_work = 100
|
|
433
|
+
else:
|
|
434
|
+
dead = 7 # noqa: F841 # no effect
|
|
435
|
+
|
|
436
|
+
if x_is_none_work == one_hundred:
|
|
437
|
+
y = 10
|
|
438
|
+
else:
|
|
439
|
+
y = -3
|
|
440
|
+
|
|
441
|
+
res[0] = y + x_is_none_work
|
|
442
|
+
|
|
443
|
+
self.assert_prune(impl, (types.NoneType("none"),), [False, None], None)
|
|
444
|
+
self.assert_prune(impl, (types.IntegerLiteral(10),), [True, None], 10)
|
|
445
|
+
|
|
446
|
+
def test_double_if_else_non_literal_const(self):
|
|
447
|
+
def impl(x, res):
|
|
448
|
+
one_hundred = 100
|
|
449
|
+
if x == one_hundred:
|
|
450
|
+
res[0] = 3.14159
|
|
451
|
+
else:
|
|
452
|
+
res[0] = 1.61803
|
|
453
|
+
|
|
454
|
+
# no prune as compilation specialization on literal value not permitted
|
|
455
|
+
self.assert_prune(impl, (types.IntegerLiteral(10),), [None], 10)
|
|
456
|
+
self.assert_prune(impl, (types.IntegerLiteral(100),), [None], 100)
|
|
457
|
+
|
|
458
|
+
def test_single_two_branches_same_cond(self):
|
|
459
|
+
def impl(x, res):
|
|
460
|
+
if x is None:
|
|
461
|
+
y = 10
|
|
462
|
+
else:
|
|
463
|
+
y = 40
|
|
464
|
+
|
|
465
|
+
if x is not None:
|
|
466
|
+
z = 100
|
|
467
|
+
else:
|
|
468
|
+
z = 400
|
|
469
|
+
|
|
470
|
+
res[0] = z + y
|
|
471
|
+
|
|
472
|
+
self.assert_prune(impl, (types.NoneType("none"),), [False, True], None)
|
|
473
|
+
self.assert_prune(impl, (types.IntegerLiteral(10),), [True, False], 10)
|
|
474
|
+
|
|
475
|
+
def test_cond_is_kwarg_none(self):
|
|
476
|
+
def impl(x=None, res=None):
|
|
477
|
+
if x is None:
|
|
478
|
+
y = 10
|
|
479
|
+
else:
|
|
480
|
+
y = 40
|
|
481
|
+
|
|
482
|
+
if x is not None:
|
|
483
|
+
z = 100
|
|
484
|
+
else:
|
|
485
|
+
z = 400
|
|
486
|
+
|
|
487
|
+
res[0] = z + y
|
|
488
|
+
|
|
489
|
+
self.assert_prune(impl, (types.Omitted(None),), [False, True], None)
|
|
490
|
+
self.assert_prune(impl, (types.NoneType("none"),), [False, True], None)
|
|
491
|
+
self.assert_prune(impl, (types.IntegerLiteral(10),), [True, False], 10)
|
|
492
|
+
|
|
493
|
+
def test_cond_is_kwarg_value(self):
|
|
494
|
+
def impl(x=1000, res=None):
|
|
495
|
+
if x == 1000:
|
|
496
|
+
y = 10
|
|
497
|
+
else:
|
|
498
|
+
y = 40
|
|
499
|
+
|
|
500
|
+
if x != 1000:
|
|
501
|
+
z = 100
|
|
502
|
+
else:
|
|
503
|
+
z = 400
|
|
504
|
+
|
|
505
|
+
res[0] = z + y
|
|
506
|
+
|
|
507
|
+
self.assert_prune(impl, (types.Omitted(1000),), [None, None], 1000)
|
|
508
|
+
self.assert_prune(
|
|
509
|
+
impl, (types.IntegerLiteral(1000),), [None, None], 1000
|
|
510
|
+
)
|
|
511
|
+
self.assert_prune(impl, (types.IntegerLiteral(0),), [None, None], 0)
|
|
512
|
+
self.assert_prune(impl, (types.NoneType("none"),), [True, False], None)
|
|
513
|
+
|
|
514
|
+
def test_cond_rewrite_is_correct(self):
|
|
515
|
+
# this checks that when a condition is replaced, it is replace by a
|
|
516
|
+
# true/false bit that correctly represents the evaluated condition
|
|
517
|
+
def fn(x):
|
|
518
|
+
if x is None:
|
|
519
|
+
return 10
|
|
520
|
+
return 12
|
|
521
|
+
|
|
522
|
+
def check(func, arg_tys, bit_val):
|
|
523
|
+
func_ir = compile_to_ir(func)
|
|
524
|
+
|
|
525
|
+
# check there is 1 branch
|
|
526
|
+
before_branches = self.find_branches(func_ir)
|
|
527
|
+
self.assertEqual(len(before_branches), 1)
|
|
528
|
+
|
|
529
|
+
# check the condition in the branch is a binop
|
|
530
|
+
pred_var = before_branches[0].cond
|
|
531
|
+
pred_defn = ir_utils.get_definition(func_ir, pred_var)
|
|
532
|
+
self.assertEqual(pred_defn.op, "call")
|
|
533
|
+
condition_var = pred_defn.args[0]
|
|
534
|
+
condition_op = ir_utils.get_definition(func_ir, condition_var)
|
|
535
|
+
self.assertEqual(condition_op.op, "binop")
|
|
536
|
+
|
|
537
|
+
# do the prune, this should kill the dead branch and rewrite the
|
|
538
|
+
#'condition to a true/false const bit
|
|
539
|
+
if self._DEBUG:
|
|
540
|
+
print("=" * 80)
|
|
541
|
+
print("before prune")
|
|
542
|
+
func_ir.dump()
|
|
543
|
+
dead_branch_prune(func_ir, arg_tys)
|
|
544
|
+
if self._DEBUG:
|
|
545
|
+
print("=" * 80)
|
|
546
|
+
print("after prune")
|
|
547
|
+
func_ir.dump()
|
|
548
|
+
|
|
549
|
+
# after mutation, the condition should be a const value `bit_val`
|
|
550
|
+
new_condition_defn = ir_utils.get_definition(func_ir, condition_var)
|
|
551
|
+
self.assertTrue(isinstance(new_condition_defn, ir.Const))
|
|
552
|
+
self.assertEqual(new_condition_defn.value, bit_val)
|
|
553
|
+
|
|
554
|
+
check(fn, (types.NoneType("none"),), 1)
|
|
555
|
+
check(fn, (types.IntegerLiteral(10),), 0)
|
|
556
|
+
|
|
557
|
+
def test_global_bake_in(self):
|
|
558
|
+
def impl(x, res):
|
|
559
|
+
if _GLOBAL == 123:
|
|
560
|
+
res[0] = x
|
|
561
|
+
else:
|
|
562
|
+
res[0] = x + 10
|
|
563
|
+
|
|
564
|
+
self.assert_prune(
|
|
565
|
+
impl,
|
|
566
|
+
(types.IntegerLiteral(1), types.Array(types.float64, 1, "C")),
|
|
567
|
+
[False],
|
|
568
|
+
1,
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
global _GLOBAL
|
|
572
|
+
tmp = _GLOBAL
|
|
573
|
+
|
|
574
|
+
try:
|
|
575
|
+
_GLOBAL = 5
|
|
576
|
+
|
|
577
|
+
def impl(x, res):
|
|
578
|
+
if _GLOBAL == 123:
|
|
579
|
+
res[0] = x
|
|
580
|
+
else:
|
|
581
|
+
res[0] = x + 10
|
|
582
|
+
|
|
583
|
+
self.assert_prune(
|
|
584
|
+
impl,
|
|
585
|
+
(types.IntegerLiteral(1), types.Array(types.float64, 1, "C")),
|
|
586
|
+
[True],
|
|
587
|
+
1,
|
|
588
|
+
)
|
|
589
|
+
finally:
|
|
590
|
+
_GLOBAL = tmp
|
|
591
|
+
|
|
592
|
+
def test_freevar_bake_in(self):
|
|
593
|
+
_FREEVAR = 123
|
|
594
|
+
|
|
595
|
+
def impl(x, res):
|
|
596
|
+
if _FREEVAR == 123:
|
|
597
|
+
res[0] = x
|
|
598
|
+
else:
|
|
599
|
+
res[0] = x + 10
|
|
600
|
+
|
|
601
|
+
self.assert_prune(
|
|
602
|
+
impl,
|
|
603
|
+
(types.IntegerLiteral(1), types.Array(types.float64, 1, "C")),
|
|
604
|
+
[False],
|
|
605
|
+
1,
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
_FREEVAR = 12
|
|
609
|
+
|
|
610
|
+
def impl(x, res):
|
|
611
|
+
if _FREEVAR == 123:
|
|
612
|
+
res[0] = x
|
|
613
|
+
else:
|
|
614
|
+
res[0] = x + 10
|
|
615
|
+
|
|
616
|
+
self.assert_prune(
|
|
617
|
+
impl,
|
|
618
|
+
(types.IntegerLiteral(1), types.Array(types.float64, 1, "C")),
|
|
619
|
+
[True],
|
|
620
|
+
1,
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
def test_redefined_variables_are_not_considered_in_prune(self):
|
|
624
|
+
# see issue #4163, checks that if a variable that is an argument is
|
|
625
|
+
# redefined in the user code it is not considered const
|
|
626
|
+
|
|
627
|
+
def impl(array, a=None, res=None):
|
|
628
|
+
if a is None:
|
|
629
|
+
a = 0
|
|
630
|
+
if a < 0:
|
|
631
|
+
res[0] = 10
|
|
632
|
+
res[0] = 30
|
|
633
|
+
|
|
634
|
+
self.assert_prune(
|
|
635
|
+
impl,
|
|
636
|
+
(
|
|
637
|
+
types.Array(types.float64, 2, "C"),
|
|
638
|
+
types.NoneType("none"),
|
|
639
|
+
types.Array(types.float64, 1, "C"),
|
|
640
|
+
),
|
|
641
|
+
[None, None],
|
|
642
|
+
np.zeros((2, 3)),
|
|
643
|
+
None,
|
|
644
|
+
)
|
|
645
|
+
|
|
646
|
+
def test_redefinition_analysis_same_block(self):
|
|
647
|
+
# checks that a redefinition in a block with prunable potential doesn't
|
|
648
|
+
# break
|
|
649
|
+
|
|
650
|
+
def impl(array, x, a=None, res=None):
|
|
651
|
+
b = 2
|
|
652
|
+
if x < 4:
|
|
653
|
+
b = 12
|
|
654
|
+
if a is None: # known true
|
|
655
|
+
a = 7 # live
|
|
656
|
+
else:
|
|
657
|
+
b = 15 # dead
|
|
658
|
+
if a < 0: # valid as a result of the redefinition of 'a'
|
|
659
|
+
res[0] = 10
|
|
660
|
+
res[0] = 30 + b + a
|
|
661
|
+
|
|
662
|
+
self.assert_prune(
|
|
663
|
+
impl,
|
|
664
|
+
(
|
|
665
|
+
types.Array(types.float64, 2, "C"),
|
|
666
|
+
types.float64,
|
|
667
|
+
types.NoneType("none"),
|
|
668
|
+
types.Array(types.float64, 1, "C"),
|
|
669
|
+
),
|
|
670
|
+
[None, False, None],
|
|
671
|
+
np.zeros((2, 3)),
|
|
672
|
+
1.0,
|
|
673
|
+
None,
|
|
674
|
+
)
|
|
675
|
+
|
|
676
|
+
def test_redefinition_analysis_different_block_can_exec(self):
|
|
677
|
+
# checks that a redefinition in a block that may be executed prevents
|
|
678
|
+
# pruning
|
|
679
|
+
|
|
680
|
+
def impl(array, x, res):
|
|
681
|
+
b = 0
|
|
682
|
+
if x > 5:
|
|
683
|
+
a = 11 # a redefined, cannot tell statically if this will exec
|
|
684
|
+
if x < 4:
|
|
685
|
+
b = 12
|
|
686
|
+
if a is None: # cannot prune, cannot determine if re-defn occurred
|
|
687
|
+
b += 5
|
|
688
|
+
else:
|
|
689
|
+
b += 7
|
|
690
|
+
if a < 0:
|
|
691
|
+
res[0] = 10
|
|
692
|
+
res[0] = 30 + b
|
|
693
|
+
|
|
694
|
+
self.assert_prune(
|
|
695
|
+
impl,
|
|
696
|
+
(
|
|
697
|
+
types.Array(types.float64, 2, "C"),
|
|
698
|
+
types.float64,
|
|
699
|
+
types.NoneType("none"),
|
|
700
|
+
types.Array(types.float64, 1, "C"),
|
|
701
|
+
),
|
|
702
|
+
[None, None, None, None],
|
|
703
|
+
np.zeros((2, 3)),
|
|
704
|
+
1.0,
|
|
705
|
+
None,
|
|
706
|
+
)
|
|
707
|
+
|
|
708
|
+
def test_redefinition_analysis_different_block_cannot_exec(self):
|
|
709
|
+
# checks that a redefinition in a block guarded by something that
|
|
710
|
+
# has prune potential
|
|
711
|
+
|
|
712
|
+
def impl(array, x=None, a=None, res=None):
|
|
713
|
+
b = 0
|
|
714
|
+
if x is not None:
|
|
715
|
+
a = 11
|
|
716
|
+
if a is None:
|
|
717
|
+
b += 5
|
|
718
|
+
else:
|
|
719
|
+
b += 7
|
|
720
|
+
res[0] = 30 + b
|
|
721
|
+
|
|
722
|
+
self.assert_prune(
|
|
723
|
+
impl,
|
|
724
|
+
(
|
|
725
|
+
types.Array(types.float64, 2, "C"),
|
|
726
|
+
types.NoneType("none"),
|
|
727
|
+
types.NoneType("none"),
|
|
728
|
+
types.Array(types.float64, 1, "C"),
|
|
729
|
+
),
|
|
730
|
+
[True, None],
|
|
731
|
+
np.zeros((2, 3)),
|
|
732
|
+
None,
|
|
733
|
+
None,
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
self.assert_prune(
|
|
737
|
+
impl,
|
|
738
|
+
(
|
|
739
|
+
types.Array(types.float64, 2, "C"),
|
|
740
|
+
types.NoneType("none"),
|
|
741
|
+
types.float64,
|
|
742
|
+
types.Array(types.float64, 1, "C"),
|
|
743
|
+
),
|
|
744
|
+
[True, None],
|
|
745
|
+
np.zeros((2, 3)),
|
|
746
|
+
None,
|
|
747
|
+
1.2,
|
|
748
|
+
)
|
|
749
|
+
|
|
750
|
+
self.assert_prune(
|
|
751
|
+
impl,
|
|
752
|
+
(
|
|
753
|
+
types.Array(types.float64, 2, "C"),
|
|
754
|
+
types.float64,
|
|
755
|
+
types.NoneType("none"),
|
|
756
|
+
types.Array(types.float64, 1, "C"),
|
|
757
|
+
),
|
|
758
|
+
[None, None],
|
|
759
|
+
np.zeros((2, 3)),
|
|
760
|
+
1.2,
|
|
761
|
+
None,
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
def test_closure_and_nonlocal_can_prune(self):
|
|
765
|
+
# Closures must be inlined ahead of branch pruning in case nonlocal
|
|
766
|
+
# is used. See issue #6585.
|
|
767
|
+
def impl(res):
|
|
768
|
+
x = 1000
|
|
769
|
+
|
|
770
|
+
def closure():
|
|
771
|
+
nonlocal x
|
|
772
|
+
x = 0
|
|
773
|
+
|
|
774
|
+
closure()
|
|
775
|
+
|
|
776
|
+
if x == 0:
|
|
777
|
+
res[0] = True
|
|
778
|
+
else:
|
|
779
|
+
res[0] = False
|
|
780
|
+
|
|
781
|
+
self.assert_prune(
|
|
782
|
+
impl,
|
|
783
|
+
(types.Array(types.float64, 1, "C"),),
|
|
784
|
+
[
|
|
785
|
+
False,
|
|
786
|
+
],
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
def test_closure_and_nonlocal_cannot_prune(self):
|
|
790
|
+
# Closures must be inlined ahead of branch pruning in case nonlocal
|
|
791
|
+
# is used. See issue #6585.
|
|
792
|
+
def impl(n, res):
|
|
793
|
+
x = 1000
|
|
794
|
+
|
|
795
|
+
def closure(t):
|
|
796
|
+
nonlocal x
|
|
797
|
+
x = t
|
|
798
|
+
|
|
799
|
+
closure(n)
|
|
800
|
+
|
|
801
|
+
if x == 0:
|
|
802
|
+
res[0] = True
|
|
803
|
+
else:
|
|
804
|
+
res[0] = False
|
|
805
|
+
|
|
806
|
+
self.assert_prune(
|
|
807
|
+
impl,
|
|
808
|
+
(types.int64, types.Array(types.float64, 1, "C")),
|
|
809
|
+
[
|
|
810
|
+
None,
|
|
811
|
+
],
|
|
812
|
+
1,
|
|
813
|
+
)
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
class TestBranchPrunePredicates(TestBranchPruneBase):
|
|
817
|
+
# Really important thing to remember... the branch on predicates end up as
|
|
818
|
+
# POP_JUMP_IF_<bool> and the targets are backwards compared to normal, i.e.
|
|
819
|
+
# the true condition is far jump and the false the near i.e. `if x` would
|
|
820
|
+
# end up in Numba IR as e.g. `branch x 10, 6`.
|
|
821
|
+
|
|
822
|
+
_TRUTHY = (1, "String", True, 7.4, 3j)
|
|
823
|
+
_FALSEY = (0, "", False, 0.0, 0j, None)
|
|
824
|
+
|
|
825
|
+
def _literal_const_sample_generator(self, pyfunc, consts):
|
|
826
|
+
"""
|
|
827
|
+
This takes a python function, pyfunc, and manipulates its co_const
|
|
828
|
+
__code__ member to create a new function with different co_consts as
|
|
829
|
+
supplied in argument consts.
|
|
830
|
+
|
|
831
|
+
consts is a dict {index: value} of co_const tuple index to constant
|
|
832
|
+
value used to update a pyfunc clone's co_const.
|
|
833
|
+
"""
|
|
834
|
+
pyfunc_code = pyfunc.__code__
|
|
835
|
+
|
|
836
|
+
# translate consts spec to update the constants
|
|
837
|
+
co_consts = {k: v for k, v in enumerate(pyfunc_code.co_consts)}
|
|
838
|
+
for k, v in consts.items():
|
|
839
|
+
co_consts[k] = v
|
|
840
|
+
new_consts = tuple([v for _, v in sorted(co_consts.items())])
|
|
841
|
+
|
|
842
|
+
# create code object with mutation
|
|
843
|
+
new_code = pyfunc_code.replace(co_consts=new_consts)
|
|
844
|
+
|
|
845
|
+
# get function
|
|
846
|
+
return pytypes.FunctionType(new_code, globals())
|
|
847
|
+
|
|
848
|
+
def test_literal_const_code_gen(self):
|
|
849
|
+
def impl(x):
|
|
850
|
+
_CONST1 = "PLACEHOLDER1"
|
|
851
|
+
if _CONST1:
|
|
852
|
+
return 3.14159
|
|
853
|
+
else:
|
|
854
|
+
_CONST2 = "PLACEHOLDER2"
|
|
855
|
+
return _CONST2 + 4
|
|
856
|
+
|
|
857
|
+
new = self._literal_const_sample_generator(impl, {1: 0, 3: 20})
|
|
858
|
+
iconst = impl.__code__.co_consts
|
|
859
|
+
nconst = new.__code__.co_consts
|
|
860
|
+
self.assertEqual(
|
|
861
|
+
iconst, (None, "PLACEHOLDER1", 3.14159, "PLACEHOLDER2", 4)
|
|
862
|
+
)
|
|
863
|
+
self.assertEqual(nconst, (None, 0, 3.14159, 20, 4))
|
|
864
|
+
self.assertEqual(impl(None), 3.14159)
|
|
865
|
+
self.assertEqual(new(None), 24)
|
|
866
|
+
|
|
867
|
+
def test_single_if_const(self):
|
|
868
|
+
def impl(x):
|
|
869
|
+
_CONST1 = "PLACEHOLDER1"
|
|
870
|
+
if _CONST1:
|
|
871
|
+
return 3.14159
|
|
872
|
+
|
|
873
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
874
|
+
for const in c_inp:
|
|
875
|
+
func = self._literal_const_sample_generator(impl, {1: const})
|
|
876
|
+
self.assert_prune(
|
|
877
|
+
func, (types.NoneType("none"),), [prune], None
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
def test_single_if_negate_const(self):
|
|
881
|
+
def impl(x):
|
|
882
|
+
_CONST1 = "PLACEHOLDER1"
|
|
883
|
+
if not _CONST1:
|
|
884
|
+
return 3.14159
|
|
885
|
+
|
|
886
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
887
|
+
for const in c_inp:
|
|
888
|
+
func = self._literal_const_sample_generator(impl, {1: const})
|
|
889
|
+
self.assert_prune(
|
|
890
|
+
func, (types.NoneType("none"),), [prune], None
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
def test_single_if_else_const(self):
|
|
894
|
+
def impl(x):
|
|
895
|
+
_CONST1 = "PLACEHOLDER1"
|
|
896
|
+
if _CONST1:
|
|
897
|
+
return 3.14159
|
|
898
|
+
else:
|
|
899
|
+
return 1.61803
|
|
900
|
+
|
|
901
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
902
|
+
for const in c_inp:
|
|
903
|
+
func = self._literal_const_sample_generator(impl, {1: const})
|
|
904
|
+
self.assert_prune(
|
|
905
|
+
func, (types.NoneType("none"),), [prune], None
|
|
906
|
+
)
|
|
907
|
+
|
|
908
|
+
def test_single_if_else_negate_const(self):
|
|
909
|
+
def impl(x):
|
|
910
|
+
_CONST1 = "PLACEHOLDER1"
|
|
911
|
+
if not _CONST1:
|
|
912
|
+
return 3.14159
|
|
913
|
+
else:
|
|
914
|
+
return 1.61803
|
|
915
|
+
|
|
916
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
917
|
+
for const in c_inp:
|
|
918
|
+
func = self._literal_const_sample_generator(impl, {1: const})
|
|
919
|
+
self.assert_prune(
|
|
920
|
+
func, (types.NoneType("none"),), [prune], None
|
|
921
|
+
)
|
|
922
|
+
|
|
923
|
+
def test_single_if_freevar(self):
|
|
924
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
925
|
+
for const in c_inp:
|
|
926
|
+
|
|
927
|
+
def func(x):
|
|
928
|
+
if const:
|
|
929
|
+
return 3.14159, const
|
|
930
|
+
|
|
931
|
+
self.assert_prune(
|
|
932
|
+
func, (types.NoneType("none"),), [prune], None
|
|
933
|
+
)
|
|
934
|
+
|
|
935
|
+
def test_single_if_negate_freevar(self):
|
|
936
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
937
|
+
for const in c_inp:
|
|
938
|
+
|
|
939
|
+
def func(x):
|
|
940
|
+
if not const:
|
|
941
|
+
return 3.14159, const
|
|
942
|
+
|
|
943
|
+
self.assert_prune(
|
|
944
|
+
func, (types.NoneType("none"),), [prune], None
|
|
945
|
+
)
|
|
946
|
+
|
|
947
|
+
def test_single_if_else_negate_freevar(self):
|
|
948
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
949
|
+
for const in c_inp:
|
|
950
|
+
|
|
951
|
+
def func(x):
|
|
952
|
+
if not const:
|
|
953
|
+
return 3.14159, const
|
|
954
|
+
else:
|
|
955
|
+
return 1.61803, const
|
|
956
|
+
|
|
957
|
+
self.assert_prune(
|
|
958
|
+
func, (types.NoneType("none"),), [prune], None
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
# globals in this section have absurd names after their test usecase names
|
|
962
|
+
# so as to prevent collisions and permit tests to run in parallel
|
|
963
|
+
def test_single_if_global(self):
|
|
964
|
+
global c_test_single_if_global
|
|
965
|
+
|
|
966
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
967
|
+
for c in c_inp:
|
|
968
|
+
c_test_single_if_global = c
|
|
969
|
+
|
|
970
|
+
def func(x):
|
|
971
|
+
if c_test_single_if_global:
|
|
972
|
+
return 3.14159, c_test_single_if_global
|
|
973
|
+
|
|
974
|
+
self.assert_prune(
|
|
975
|
+
func, (types.NoneType("none"),), [prune], None
|
|
976
|
+
)
|
|
977
|
+
|
|
978
|
+
def test_single_if_negate_global(self):
|
|
979
|
+
global c_test_single_if_negate_global
|
|
980
|
+
|
|
981
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
982
|
+
for c in c_inp:
|
|
983
|
+
c_test_single_if_negate_global = c
|
|
984
|
+
|
|
985
|
+
def func(x):
|
|
986
|
+
if c_test_single_if_negate_global:
|
|
987
|
+
return 3.14159, c_test_single_if_negate_global
|
|
988
|
+
|
|
989
|
+
self.assert_prune(
|
|
990
|
+
func, (types.NoneType("none"),), [prune], None
|
|
991
|
+
)
|
|
992
|
+
|
|
993
|
+
def test_single_if_else_global(self):
|
|
994
|
+
global c_test_single_if_else_global
|
|
995
|
+
|
|
996
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
997
|
+
for c in c_inp:
|
|
998
|
+
c_test_single_if_else_global = c
|
|
999
|
+
|
|
1000
|
+
def func(x):
|
|
1001
|
+
if c_test_single_if_else_global:
|
|
1002
|
+
return 3.14159, c_test_single_if_else_global
|
|
1003
|
+
else:
|
|
1004
|
+
return 1.61803, c_test_single_if_else_global
|
|
1005
|
+
|
|
1006
|
+
self.assert_prune(
|
|
1007
|
+
func, (types.NoneType("none"),), [prune], None
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
def test_single_if_else_negate_global(self):
|
|
1011
|
+
global c_test_single_if_else_negate_global
|
|
1012
|
+
|
|
1013
|
+
for c_inp, prune in (self._TRUTHY, False), (self._FALSEY, True):
|
|
1014
|
+
for c in c_inp:
|
|
1015
|
+
c_test_single_if_else_negate_global = c
|
|
1016
|
+
|
|
1017
|
+
def func(x):
|
|
1018
|
+
if not c_test_single_if_else_negate_global:
|
|
1019
|
+
return 3.14159, c_test_single_if_else_negate_global
|
|
1020
|
+
else:
|
|
1021
|
+
return 1.61803, c_test_single_if_else_negate_global
|
|
1022
|
+
|
|
1023
|
+
self.assert_prune(
|
|
1024
|
+
func, (types.NoneType("none"),), [prune], None
|
|
1025
|
+
)
|
|
1026
|
+
|
|
1027
|
+
def test_issue_5618(self):
|
|
1028
|
+
@jit
|
|
1029
|
+
def foo(res):
|
|
1030
|
+
tmp = 666
|
|
1031
|
+
if tmp:
|
|
1032
|
+
res[0] = tmp
|
|
1033
|
+
|
|
1034
|
+
self.run_func(foo, ())
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
class TestBranchPrunePostSemanticConstRewrites(TestBranchPruneBase):
|
|
1038
|
+
# Tests that semantic constants rewriting works by virtue of branch pruning
|
|
1039
|
+
|
|
1040
|
+
def test_array_ndim_attr(self):
|
|
1041
|
+
def impl(array, res):
|
|
1042
|
+
if array.ndim == 2:
|
|
1043
|
+
if array.shape[1] == 2:
|
|
1044
|
+
res[0] = 1
|
|
1045
|
+
else:
|
|
1046
|
+
res[0] = 10
|
|
1047
|
+
|
|
1048
|
+
self.assert_prune(
|
|
1049
|
+
impl,
|
|
1050
|
+
(types.Array(types.float64, 2, "C"),),
|
|
1051
|
+
[False, None],
|
|
1052
|
+
np.zeros((2, 3)),
|
|
1053
|
+
)
|
|
1054
|
+
self.assert_prune(
|
|
1055
|
+
impl,
|
|
1056
|
+
(types.Array(types.float64, 1, "C"),),
|
|
1057
|
+
[True, "both"],
|
|
1058
|
+
np.zeros((2,)),
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
def test_tuple_len(self):
|
|
1062
|
+
def impl(tup, res):
|
|
1063
|
+
if len(tup) == 3:
|
|
1064
|
+
if tup[2] == 2:
|
|
1065
|
+
res[0] = 1
|
|
1066
|
+
else:
|
|
1067
|
+
res[0] = 0
|
|
1068
|
+
|
|
1069
|
+
self.assert_prune(
|
|
1070
|
+
impl,
|
|
1071
|
+
(types.UniTuple(types.int64, 3),),
|
|
1072
|
+
[False, None],
|
|
1073
|
+
tuple([1, 2, 3]),
|
|
1074
|
+
)
|
|
1075
|
+
self.assert_prune(
|
|
1076
|
+
impl,
|
|
1077
|
+
(types.UniTuple(types.int64, 2),),
|
|
1078
|
+
[True, "both"],
|
|
1079
|
+
tuple([1, 2]),
|
|
1080
|
+
)
|
|
1081
|
+
|
|
1082
|
+
def test_attr_not_len(self):
|
|
1083
|
+
# The purpose of this test is to make sure that the conditions guarding
|
|
1084
|
+
# the rewrite part do not themselves raise exceptions.
|
|
1085
|
+
# This produces an `ir.Expr` call node for `float.as_integer_ratio`,
|
|
1086
|
+
# which is a getattr() on `float`.
|
|
1087
|
+
|
|
1088
|
+
@jit
|
|
1089
|
+
def test():
|
|
1090
|
+
float.as_integer_ratio(1.23)
|
|
1091
|
+
|
|
1092
|
+
# this should raise a TypingError
|
|
1093
|
+
with self.assertRaises(errors.TypingError) as e:
|
|
1094
|
+
test[1, 1]()
|
|
1095
|
+
|
|
1096
|
+
self.assertIn("Unknown attribute 'as_integer_ratio'", str(e.exception))
|
|
1097
|
+
|
|
1098
|
+
def test_ndim_not_on_array(self):
|
|
1099
|
+
FakeArray = collections.namedtuple("FakeArray", ["ndim"])
|
|
1100
|
+
fa = FakeArray(ndim=2)
|
|
1101
|
+
|
|
1102
|
+
def impl(fa, res):
|
|
1103
|
+
if fa.ndim == 2:
|
|
1104
|
+
res[0] = fa.ndim
|
|
1105
|
+
|
|
1106
|
+
# check prune works for array ndim
|
|
1107
|
+
self.assert_prune(
|
|
1108
|
+
impl,
|
|
1109
|
+
(types.Array(types.float64, 2, "C"),),
|
|
1110
|
+
[False],
|
|
1111
|
+
np.zeros((2, 3)),
|
|
1112
|
+
)
|
|
1113
|
+
|
|
1114
|
+
# check prune fails for something with `ndim` attr that is not array
|
|
1115
|
+
FakeArrayType = types.NamedUniTuple(types.int64, 1, FakeArray)
|
|
1116
|
+
self.assert_prune(
|
|
1117
|
+
impl,
|
|
1118
|
+
(FakeArrayType,),
|
|
1119
|
+
[None],
|
|
1120
|
+
fa,
|
|
1121
|
+
flags={"nopython": False, "forceobj": True},
|
|
1122
|
+
)
|