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,1446 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
3
|
+
|
|
4
|
+
from functools import partial
|
|
5
|
+
from collections import deque
|
|
6
|
+
|
|
7
|
+
from llvmlite import ir
|
|
8
|
+
|
|
9
|
+
from numba.cuda.datamodel.registry import register_default
|
|
10
|
+
from numba.cuda import types
|
|
11
|
+
from numba.cuda import cgutils
|
|
12
|
+
from numba.cuda.np import numpy_support
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DataModel(object):
|
|
16
|
+
"""
|
|
17
|
+
DataModel describe how a FE type is represented in the LLVM IR at
|
|
18
|
+
different contexts.
|
|
19
|
+
|
|
20
|
+
Contexts are:
|
|
21
|
+
|
|
22
|
+
- value: representation inside function body. Maybe stored in stack.
|
|
23
|
+
The representation here are flexible.
|
|
24
|
+
|
|
25
|
+
- data: representation used when storing into containers (e.g. arrays).
|
|
26
|
+
|
|
27
|
+
- argument: representation used for function argument. All composite
|
|
28
|
+
types are unflattened into multiple primitive types.
|
|
29
|
+
|
|
30
|
+
- return: representation used for return argument.
|
|
31
|
+
|
|
32
|
+
Throughput the compiler pipeline, a LLVM value is usually passed around
|
|
33
|
+
in the "value" representation. All "as_" prefix function converts from
|
|
34
|
+
"value" representation. All "from_" prefix function converts to the
|
|
35
|
+
"value" representation.
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, dmm, fe_type):
|
|
40
|
+
self._dmm = dmm
|
|
41
|
+
self._fe_type = fe_type
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def fe_type(self):
|
|
45
|
+
return self._fe_type
|
|
46
|
+
|
|
47
|
+
def get_value_type(self):
|
|
48
|
+
raise NotImplementedError(self)
|
|
49
|
+
|
|
50
|
+
def get_data_type(self):
|
|
51
|
+
return self.get_value_type()
|
|
52
|
+
|
|
53
|
+
def get_argument_type(self):
|
|
54
|
+
"""Return a LLVM type or nested tuple of LLVM type"""
|
|
55
|
+
return self.get_value_type()
|
|
56
|
+
|
|
57
|
+
def get_return_type(self):
|
|
58
|
+
return self.get_value_type()
|
|
59
|
+
|
|
60
|
+
def as_data(self, builder, value):
|
|
61
|
+
raise NotImplementedError(self)
|
|
62
|
+
|
|
63
|
+
def as_argument(self, builder, value):
|
|
64
|
+
"""
|
|
65
|
+
Takes one LLVM value
|
|
66
|
+
Return a LLVM value or nested tuple of LLVM value
|
|
67
|
+
"""
|
|
68
|
+
raise NotImplementedError(self)
|
|
69
|
+
|
|
70
|
+
def as_return(self, builder, value):
|
|
71
|
+
raise NotImplementedError(self)
|
|
72
|
+
|
|
73
|
+
def from_data(self, builder, value):
|
|
74
|
+
raise NotImplementedError(self)
|
|
75
|
+
|
|
76
|
+
def from_argument(self, builder, value):
|
|
77
|
+
"""
|
|
78
|
+
Takes a LLVM value or nested tuple of LLVM value
|
|
79
|
+
Returns one LLVM value
|
|
80
|
+
"""
|
|
81
|
+
raise NotImplementedError(self)
|
|
82
|
+
|
|
83
|
+
def from_return(self, builder, value):
|
|
84
|
+
raise NotImplementedError(self)
|
|
85
|
+
|
|
86
|
+
def load_from_data_pointer(self, builder, ptr, align=None):
|
|
87
|
+
"""
|
|
88
|
+
Load value from a pointer to data.
|
|
89
|
+
This is the default implementation, sufficient for most purposes.
|
|
90
|
+
"""
|
|
91
|
+
return self.from_data(builder, builder.load(ptr, align=align))
|
|
92
|
+
|
|
93
|
+
def traverse(self, builder):
|
|
94
|
+
"""
|
|
95
|
+
Traverse contained members.
|
|
96
|
+
Returns a iterable of contained (types, getters).
|
|
97
|
+
Each getter is a one-argument function accepting a LLVM value.
|
|
98
|
+
"""
|
|
99
|
+
return []
|
|
100
|
+
|
|
101
|
+
def traverse_models(self):
|
|
102
|
+
"""
|
|
103
|
+
Recursively list all models involved in this model.
|
|
104
|
+
"""
|
|
105
|
+
return [self._dmm[t] for t in self.traverse_types()]
|
|
106
|
+
|
|
107
|
+
def traverse_types(self):
|
|
108
|
+
"""
|
|
109
|
+
Recursively list all frontend types involved in this model.
|
|
110
|
+
"""
|
|
111
|
+
types = [self._fe_type]
|
|
112
|
+
queue = deque([self])
|
|
113
|
+
while len(queue) > 0:
|
|
114
|
+
dm = queue.popleft()
|
|
115
|
+
|
|
116
|
+
for i_dm in dm.inner_models():
|
|
117
|
+
if i_dm._fe_type not in types:
|
|
118
|
+
queue.append(i_dm)
|
|
119
|
+
types.append(i_dm._fe_type)
|
|
120
|
+
|
|
121
|
+
return types
|
|
122
|
+
|
|
123
|
+
def inner_models(self):
|
|
124
|
+
"""
|
|
125
|
+
List all *inner* models.
|
|
126
|
+
"""
|
|
127
|
+
return []
|
|
128
|
+
|
|
129
|
+
def get_nrt_meminfo(self, builder, value):
|
|
130
|
+
"""
|
|
131
|
+
Returns the MemInfo object or None if it is not tracked.
|
|
132
|
+
It is only defined for types.meminfo_pointer
|
|
133
|
+
"""
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
def has_nrt_meminfo(self):
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
def contains_nrt_meminfo(self):
|
|
140
|
+
"""
|
|
141
|
+
Recursively check all contained types for need for NRT meminfo.
|
|
142
|
+
"""
|
|
143
|
+
return any(model.has_nrt_meminfo() for model in self.traverse_models())
|
|
144
|
+
|
|
145
|
+
def _compared_fields(self):
|
|
146
|
+
return (type(self), self._fe_type)
|
|
147
|
+
|
|
148
|
+
def __hash__(self):
|
|
149
|
+
return hash(tuple(self._compared_fields()))
|
|
150
|
+
|
|
151
|
+
def __eq__(self, other):
|
|
152
|
+
if type(self) is type(other):
|
|
153
|
+
return self._compared_fields() == other._compared_fields()
|
|
154
|
+
else:
|
|
155
|
+
return False
|
|
156
|
+
|
|
157
|
+
def __ne__(self, other):
|
|
158
|
+
return not self.__eq__(other)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@register_default(types.Omitted)
|
|
162
|
+
class OmittedArgDataModel(DataModel):
|
|
163
|
+
"""
|
|
164
|
+
A data model for omitted arguments. Only the "argument" representation
|
|
165
|
+
is defined, other representations raise a NotImplementedError.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
# Omitted arguments are using a dummy value type
|
|
169
|
+
def get_value_type(self):
|
|
170
|
+
return ir.LiteralStructType([])
|
|
171
|
+
|
|
172
|
+
# Omitted arguments don't produce any LLVM function argument.
|
|
173
|
+
def get_argument_type(self):
|
|
174
|
+
return ()
|
|
175
|
+
|
|
176
|
+
def as_argument(self, builder, val):
|
|
177
|
+
return ()
|
|
178
|
+
|
|
179
|
+
def from_argument(self, builder, val):
|
|
180
|
+
assert val == (), val
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@register_default(types.Boolean)
|
|
185
|
+
@register_default(types.BooleanLiteral)
|
|
186
|
+
class BooleanModel(DataModel):
|
|
187
|
+
_bit_type = ir.IntType(1)
|
|
188
|
+
_byte_type = ir.IntType(8)
|
|
189
|
+
|
|
190
|
+
def get_value_type(self):
|
|
191
|
+
return self._bit_type
|
|
192
|
+
|
|
193
|
+
def get_data_type(self):
|
|
194
|
+
return self._byte_type
|
|
195
|
+
|
|
196
|
+
def get_return_type(self):
|
|
197
|
+
return self.get_data_type()
|
|
198
|
+
|
|
199
|
+
def get_argument_type(self):
|
|
200
|
+
return self.get_data_type()
|
|
201
|
+
|
|
202
|
+
def as_data(self, builder, value):
|
|
203
|
+
return builder.zext(value, self.get_data_type())
|
|
204
|
+
|
|
205
|
+
def as_argument(self, builder, value):
|
|
206
|
+
return self.as_data(builder, value)
|
|
207
|
+
|
|
208
|
+
def as_return(self, builder, value):
|
|
209
|
+
return self.as_data(builder, value)
|
|
210
|
+
|
|
211
|
+
def from_data(self, builder, value):
|
|
212
|
+
ty = self.get_value_type()
|
|
213
|
+
resalloca = cgutils.alloca_once(builder, ty)
|
|
214
|
+
cond = builder.icmp_unsigned("==", value, value.type(0))
|
|
215
|
+
with builder.if_else(cond) as (then, otherwise):
|
|
216
|
+
with then:
|
|
217
|
+
builder.store(ty(0), resalloca)
|
|
218
|
+
with otherwise:
|
|
219
|
+
builder.store(ty(1), resalloca)
|
|
220
|
+
return builder.load(resalloca)
|
|
221
|
+
|
|
222
|
+
def from_argument(self, builder, value):
|
|
223
|
+
return self.from_data(builder, value)
|
|
224
|
+
|
|
225
|
+
def from_return(self, builder, value):
|
|
226
|
+
return self.from_data(builder, value)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class PrimitiveModel(DataModel):
|
|
230
|
+
"""A primitive type can be represented natively in the target in all
|
|
231
|
+
usage contexts.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
def __init__(self, dmm, fe_type, be_type):
|
|
235
|
+
super(PrimitiveModel, self).__init__(dmm, fe_type)
|
|
236
|
+
self.be_type = be_type
|
|
237
|
+
|
|
238
|
+
def get_value_type(self):
|
|
239
|
+
return self.be_type
|
|
240
|
+
|
|
241
|
+
def as_data(self, builder, value):
|
|
242
|
+
return value
|
|
243
|
+
|
|
244
|
+
def as_argument(self, builder, value):
|
|
245
|
+
return value
|
|
246
|
+
|
|
247
|
+
def as_return(self, builder, value):
|
|
248
|
+
return value
|
|
249
|
+
|
|
250
|
+
def from_data(self, builder, value):
|
|
251
|
+
return value
|
|
252
|
+
|
|
253
|
+
def from_argument(self, builder, value):
|
|
254
|
+
return value
|
|
255
|
+
|
|
256
|
+
def from_return(self, builder, value):
|
|
257
|
+
return value
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class ProxyModel(DataModel):
|
|
261
|
+
"""
|
|
262
|
+
Helper class for models which delegate to another model.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
def get_value_type(self):
|
|
266
|
+
return self._proxied_model.get_value_type()
|
|
267
|
+
|
|
268
|
+
def get_data_type(self):
|
|
269
|
+
return self._proxied_model.get_data_type()
|
|
270
|
+
|
|
271
|
+
def get_return_type(self):
|
|
272
|
+
return self._proxied_model.get_return_type()
|
|
273
|
+
|
|
274
|
+
def get_argument_type(self):
|
|
275
|
+
return self._proxied_model.get_argument_type()
|
|
276
|
+
|
|
277
|
+
def as_data(self, builder, value):
|
|
278
|
+
return self._proxied_model.as_data(builder, value)
|
|
279
|
+
|
|
280
|
+
def as_argument(self, builder, value):
|
|
281
|
+
return self._proxied_model.as_argument(builder, value)
|
|
282
|
+
|
|
283
|
+
def as_return(self, builder, value):
|
|
284
|
+
return self._proxied_model.as_return(builder, value)
|
|
285
|
+
|
|
286
|
+
def from_data(self, builder, value):
|
|
287
|
+
return self._proxied_model.from_data(builder, value)
|
|
288
|
+
|
|
289
|
+
def from_argument(self, builder, value):
|
|
290
|
+
return self._proxied_model.from_argument(builder, value)
|
|
291
|
+
|
|
292
|
+
def from_return(self, builder, value):
|
|
293
|
+
return self._proxied_model.from_return(builder, value)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@register_default(types.EnumMember)
|
|
297
|
+
@register_default(types.IntEnumMember)
|
|
298
|
+
class EnumModel(ProxyModel):
|
|
299
|
+
"""
|
|
300
|
+
Enum members are represented exactly like their values.
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
def __init__(self, dmm, fe_type):
|
|
304
|
+
super(EnumModel, self).__init__(dmm, fe_type)
|
|
305
|
+
self._proxied_model = dmm.lookup(fe_type.dtype)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@register_default(types.Opaque)
|
|
309
|
+
@register_default(types.PyObject)
|
|
310
|
+
@register_default(types.RawPointer)
|
|
311
|
+
@register_default(types.NoneType)
|
|
312
|
+
@register_default(types.StringLiteral)
|
|
313
|
+
@register_default(types.EllipsisType)
|
|
314
|
+
@register_default(types.Function)
|
|
315
|
+
@register_default(types.Type)
|
|
316
|
+
@register_default(types.Object)
|
|
317
|
+
@register_default(types.Module)
|
|
318
|
+
@register_default(types.Phantom)
|
|
319
|
+
@register_default(types.UndefVar)
|
|
320
|
+
@register_default(types.ContextManager)
|
|
321
|
+
@register_default(types.Dispatcher)
|
|
322
|
+
@register_default(types.ObjModeDispatcher)
|
|
323
|
+
@register_default(types.ExceptionClass)
|
|
324
|
+
@register_default(types.Dummy)
|
|
325
|
+
@register_default(types.ExceptionInstance)
|
|
326
|
+
@register_default(types.ExternalFunction)
|
|
327
|
+
@register_default(types.EnumClass)
|
|
328
|
+
@register_default(types.IntEnumClass)
|
|
329
|
+
@register_default(types.NumberClass)
|
|
330
|
+
@register_default(types.TypeRef)
|
|
331
|
+
@register_default(types.NamedTupleClass)
|
|
332
|
+
@register_default(types.DType)
|
|
333
|
+
@register_default(types.RecursiveCall)
|
|
334
|
+
@register_default(types.MakeFunctionLiteral)
|
|
335
|
+
@register_default(types.Poison)
|
|
336
|
+
class OpaqueModel(PrimitiveModel):
|
|
337
|
+
"""
|
|
338
|
+
Passed as opaque pointers
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
_ptr_type = ir.IntType(8).as_pointer()
|
|
342
|
+
|
|
343
|
+
def __init__(self, dmm, fe_type):
|
|
344
|
+
be_type = self._ptr_type
|
|
345
|
+
super(OpaqueModel, self).__init__(dmm, fe_type, be_type)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@register_default(types.MemInfoPointer)
|
|
349
|
+
class MemInfoModel(OpaqueModel):
|
|
350
|
+
def inner_models(self):
|
|
351
|
+
return [self._dmm.lookup(self._fe_type.dtype)]
|
|
352
|
+
|
|
353
|
+
def has_nrt_meminfo(self):
|
|
354
|
+
return True
|
|
355
|
+
|
|
356
|
+
def get_nrt_meminfo(self, builder, value):
|
|
357
|
+
return value
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
@register_default(types.Integer)
|
|
361
|
+
@register_default(types.IntegerLiteral)
|
|
362
|
+
class IntegerModel(PrimitiveModel):
|
|
363
|
+
def __init__(self, dmm, fe_type):
|
|
364
|
+
be_type = ir.IntType(fe_type.bitwidth)
|
|
365
|
+
super(IntegerModel, self).__init__(dmm, fe_type, be_type)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
@register_default(types.Float)
|
|
369
|
+
class FloatModel(PrimitiveModel):
|
|
370
|
+
def __init__(self, dmm, fe_type):
|
|
371
|
+
if fe_type == types.float32:
|
|
372
|
+
be_type = ir.FloatType()
|
|
373
|
+
elif fe_type == types.float64:
|
|
374
|
+
be_type = ir.DoubleType()
|
|
375
|
+
else:
|
|
376
|
+
raise NotImplementedError(fe_type)
|
|
377
|
+
super(FloatModel, self).__init__(dmm, fe_type, be_type)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
@register_default(types.CPointer)
|
|
381
|
+
class PointerModel(PrimitiveModel):
|
|
382
|
+
def __init__(self, dmm, fe_type):
|
|
383
|
+
self._pointee_model = dmm.lookup(fe_type.dtype)
|
|
384
|
+
self._pointee_be_type = self._pointee_model.get_data_type()
|
|
385
|
+
be_type = self._pointee_be_type.as_pointer()
|
|
386
|
+
super(PointerModel, self).__init__(dmm, fe_type, be_type)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@register_default(types.EphemeralPointer)
|
|
390
|
+
class EphemeralPointerModel(PointerModel):
|
|
391
|
+
def get_data_type(self):
|
|
392
|
+
return self._pointee_be_type
|
|
393
|
+
|
|
394
|
+
def as_data(self, builder, value):
|
|
395
|
+
value = builder.load(value)
|
|
396
|
+
return self._pointee_model.as_data(builder, value)
|
|
397
|
+
|
|
398
|
+
def from_data(self, builder, value):
|
|
399
|
+
raise NotImplementedError("use load_from_data_pointer() instead")
|
|
400
|
+
|
|
401
|
+
def load_from_data_pointer(self, builder, ptr, align=None):
|
|
402
|
+
return builder.bitcast(ptr, self.get_value_type())
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@register_default(types.EphemeralArray)
|
|
406
|
+
class EphemeralArrayModel(PointerModel):
|
|
407
|
+
def __init__(self, dmm, fe_type):
|
|
408
|
+
super(EphemeralArrayModel, self).__init__(dmm, fe_type)
|
|
409
|
+
self._data_type = ir.ArrayType(
|
|
410
|
+
self._pointee_be_type, self._fe_type.count
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
def get_data_type(self):
|
|
414
|
+
return self._data_type
|
|
415
|
+
|
|
416
|
+
def as_data(self, builder, value):
|
|
417
|
+
values = [
|
|
418
|
+
builder.load(cgutils.gep_inbounds(builder, value, i))
|
|
419
|
+
for i in range(self._fe_type.count)
|
|
420
|
+
]
|
|
421
|
+
return cgutils.pack_array(builder, values)
|
|
422
|
+
|
|
423
|
+
def from_data(self, builder, value):
|
|
424
|
+
raise NotImplementedError("use load_from_data_pointer() instead")
|
|
425
|
+
|
|
426
|
+
def load_from_data_pointer(self, builder, ptr, align=None):
|
|
427
|
+
return builder.bitcast(ptr, self.get_value_type())
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
@register_default(types.ExternalFunctionPointer)
|
|
431
|
+
class ExternalFuncPointerModel(PrimitiveModel):
|
|
432
|
+
def __init__(self, dmm, fe_type):
|
|
433
|
+
sig = fe_type.sig
|
|
434
|
+
# Since the function is non-Numba, there is no adaptation
|
|
435
|
+
# of arguments and return value, hence get_value_type().
|
|
436
|
+
retty = dmm.lookup(sig.return_type).get_value_type()
|
|
437
|
+
args = [dmm.lookup(t).get_value_type() for t in sig.args]
|
|
438
|
+
be_type = ir.PointerType(ir.FunctionType(retty, args))
|
|
439
|
+
super(ExternalFuncPointerModel, self).__init__(dmm, fe_type, be_type)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@register_default(types.UniTuple)
|
|
443
|
+
@register_default(types.NamedUniTuple)
|
|
444
|
+
@register_default(types.StarArgUniTuple)
|
|
445
|
+
class UniTupleModel(DataModel):
|
|
446
|
+
def __init__(self, dmm, fe_type):
|
|
447
|
+
super(UniTupleModel, self).__init__(dmm, fe_type)
|
|
448
|
+
self._elem_model = dmm.lookup(fe_type.dtype)
|
|
449
|
+
self._count = len(fe_type)
|
|
450
|
+
self._value_type = ir.ArrayType(
|
|
451
|
+
self._elem_model.get_value_type(), self._count
|
|
452
|
+
)
|
|
453
|
+
self._data_type = ir.ArrayType(
|
|
454
|
+
self._elem_model.get_data_type(), self._count
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
def get_value_type(self):
|
|
458
|
+
return self._value_type
|
|
459
|
+
|
|
460
|
+
def get_data_type(self):
|
|
461
|
+
return self._data_type
|
|
462
|
+
|
|
463
|
+
def get_return_type(self):
|
|
464
|
+
return self.get_value_type()
|
|
465
|
+
|
|
466
|
+
def get_argument_type(self):
|
|
467
|
+
return (self._elem_model.get_argument_type(),) * self._count
|
|
468
|
+
|
|
469
|
+
def as_argument(self, builder, value):
|
|
470
|
+
out = []
|
|
471
|
+
for i in range(self._count):
|
|
472
|
+
v = builder.extract_value(value, [i])
|
|
473
|
+
v = self._elem_model.as_argument(builder, v)
|
|
474
|
+
out.append(v)
|
|
475
|
+
return out
|
|
476
|
+
|
|
477
|
+
def from_argument(self, builder, value):
|
|
478
|
+
out = ir.Constant(self.get_value_type(), ir.Undefined)
|
|
479
|
+
for i, v in enumerate(value):
|
|
480
|
+
v = self._elem_model.from_argument(builder, v)
|
|
481
|
+
out = builder.insert_value(out, v, [i])
|
|
482
|
+
return out
|
|
483
|
+
|
|
484
|
+
def as_data(self, builder, value):
|
|
485
|
+
out = ir.Constant(self.get_data_type(), ir.Undefined)
|
|
486
|
+
for i in range(self._count):
|
|
487
|
+
val = builder.extract_value(value, [i])
|
|
488
|
+
dval = self._elem_model.as_data(builder, val)
|
|
489
|
+
out = builder.insert_value(out, dval, [i])
|
|
490
|
+
return out
|
|
491
|
+
|
|
492
|
+
def from_data(self, builder, value):
|
|
493
|
+
out = ir.Constant(self.get_value_type(), ir.Undefined)
|
|
494
|
+
for i in range(self._count):
|
|
495
|
+
val = builder.extract_value(value, [i])
|
|
496
|
+
dval = self._elem_model.from_data(builder, val)
|
|
497
|
+
out = builder.insert_value(out, dval, [i])
|
|
498
|
+
return out
|
|
499
|
+
|
|
500
|
+
def as_return(self, builder, value):
|
|
501
|
+
return value
|
|
502
|
+
|
|
503
|
+
def from_return(self, builder, value):
|
|
504
|
+
return value
|
|
505
|
+
|
|
506
|
+
def traverse(self, builder):
|
|
507
|
+
def getter(i, value):
|
|
508
|
+
return builder.extract_value(value, i)
|
|
509
|
+
|
|
510
|
+
return [
|
|
511
|
+
(self._fe_type.dtype, partial(getter, i))
|
|
512
|
+
for i in range(self._count)
|
|
513
|
+
]
|
|
514
|
+
|
|
515
|
+
def inner_models(self):
|
|
516
|
+
return [self._elem_model]
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
class CompositeModel(DataModel):
|
|
520
|
+
"""Any model that is composed of multiple other models should subclass from
|
|
521
|
+
this.
|
|
522
|
+
"""
|
|
523
|
+
|
|
524
|
+
pass
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
class StructModel(CompositeModel):
|
|
528
|
+
_value_type = None
|
|
529
|
+
_data_type = None
|
|
530
|
+
|
|
531
|
+
def __init__(self, dmm, fe_type, members):
|
|
532
|
+
super(StructModel, self).__init__(dmm, fe_type)
|
|
533
|
+
if members:
|
|
534
|
+
self._fields, self._members = zip(*members)
|
|
535
|
+
else:
|
|
536
|
+
self._fields = self._members = ()
|
|
537
|
+
self._models = tuple([self._dmm.lookup(t) for t in self._members])
|
|
538
|
+
|
|
539
|
+
def get_member_fe_type(self, name):
|
|
540
|
+
"""
|
|
541
|
+
StructModel-specific: get the Numba type of the field named *name*.
|
|
542
|
+
"""
|
|
543
|
+
pos = self.get_field_position(name)
|
|
544
|
+
return self._members[pos]
|
|
545
|
+
|
|
546
|
+
def get_value_type(self):
|
|
547
|
+
if self._value_type is None:
|
|
548
|
+
self._value_type = ir.LiteralStructType(
|
|
549
|
+
[t.get_value_type() for t in self._models]
|
|
550
|
+
)
|
|
551
|
+
return self._value_type
|
|
552
|
+
|
|
553
|
+
def get_data_type(self):
|
|
554
|
+
if self._data_type is None:
|
|
555
|
+
self._data_type = ir.LiteralStructType(
|
|
556
|
+
[t.get_data_type() for t in self._models]
|
|
557
|
+
)
|
|
558
|
+
return self._data_type
|
|
559
|
+
|
|
560
|
+
def get_argument_type(self):
|
|
561
|
+
return tuple([t.get_argument_type() for t in self._models])
|
|
562
|
+
|
|
563
|
+
def get_return_type(self):
|
|
564
|
+
return self.get_data_type()
|
|
565
|
+
|
|
566
|
+
def _as(self, methname, builder, value):
|
|
567
|
+
extracted = []
|
|
568
|
+
for i, dm in enumerate(self._models):
|
|
569
|
+
extracted.append(
|
|
570
|
+
getattr(dm, methname)(builder, self.get(builder, value, i))
|
|
571
|
+
)
|
|
572
|
+
return tuple(extracted)
|
|
573
|
+
|
|
574
|
+
def _from(self, methname, builder, value):
|
|
575
|
+
struct = ir.Constant(self.get_value_type(), ir.Undefined)
|
|
576
|
+
|
|
577
|
+
for i, (dm, val) in enumerate(zip(self._models, value)):
|
|
578
|
+
v = getattr(dm, methname)(builder, val)
|
|
579
|
+
struct = self.set(builder, struct, v, i)
|
|
580
|
+
|
|
581
|
+
return struct
|
|
582
|
+
|
|
583
|
+
def as_data(self, builder, value):
|
|
584
|
+
"""
|
|
585
|
+
Converts the LLVM struct in `value` into a representation suited for
|
|
586
|
+
storing into arrays.
|
|
587
|
+
|
|
588
|
+
Note
|
|
589
|
+
----
|
|
590
|
+
Current implementation rarely changes how types are represented for
|
|
591
|
+
"value" and "data". This is usually a pointless rebuild of the
|
|
592
|
+
immutable LLVM struct value. Luckily, LLVM optimization removes all
|
|
593
|
+
redundancy.
|
|
594
|
+
|
|
595
|
+
Sample usecase: Structures nested with pointers to other structures
|
|
596
|
+
that can be serialized into a flat representation when storing into
|
|
597
|
+
array.
|
|
598
|
+
"""
|
|
599
|
+
elems = self._as("as_data", builder, value)
|
|
600
|
+
struct = ir.Constant(self.get_data_type(), ir.Undefined)
|
|
601
|
+
for i, el in enumerate(elems):
|
|
602
|
+
struct = builder.insert_value(struct, el, [i])
|
|
603
|
+
return struct
|
|
604
|
+
|
|
605
|
+
def from_data(self, builder, value):
|
|
606
|
+
"""
|
|
607
|
+
Convert from "data" representation back into "value" representation.
|
|
608
|
+
Usually invoked when loading from array.
|
|
609
|
+
|
|
610
|
+
See notes in `as_data()`
|
|
611
|
+
"""
|
|
612
|
+
vals = [
|
|
613
|
+
builder.extract_value(value, [i]) for i in range(len(self._members))
|
|
614
|
+
]
|
|
615
|
+
return self._from("from_data", builder, vals)
|
|
616
|
+
|
|
617
|
+
def load_from_data_pointer(self, builder, ptr, align=None):
|
|
618
|
+
values = []
|
|
619
|
+
for i, model in enumerate(self._models):
|
|
620
|
+
elem_ptr = cgutils.gep_inbounds(builder, ptr, 0, i)
|
|
621
|
+
val = model.load_from_data_pointer(builder, elem_ptr, align)
|
|
622
|
+
values.append(val)
|
|
623
|
+
|
|
624
|
+
struct = ir.Constant(self.get_value_type(), ir.Undefined)
|
|
625
|
+
for i, val in enumerate(values):
|
|
626
|
+
struct = self.set(builder, struct, val, i)
|
|
627
|
+
return struct
|
|
628
|
+
|
|
629
|
+
def as_argument(self, builder, value):
|
|
630
|
+
return self._as("as_argument", builder, value)
|
|
631
|
+
|
|
632
|
+
def from_argument(self, builder, value):
|
|
633
|
+
return self._from("from_argument", builder, value)
|
|
634
|
+
|
|
635
|
+
def as_return(self, builder, value):
|
|
636
|
+
elems = self._as("as_data", builder, value)
|
|
637
|
+
struct = ir.Constant(self.get_data_type(), ir.Undefined)
|
|
638
|
+
for i, el in enumerate(elems):
|
|
639
|
+
struct = builder.insert_value(struct, el, [i])
|
|
640
|
+
return struct
|
|
641
|
+
|
|
642
|
+
def from_return(self, builder, value):
|
|
643
|
+
vals = [
|
|
644
|
+
builder.extract_value(value, [i]) for i in range(len(self._members))
|
|
645
|
+
]
|
|
646
|
+
return self._from("from_data", builder, vals)
|
|
647
|
+
|
|
648
|
+
def get(self, builder, val, pos):
|
|
649
|
+
"""Get a field at the given position or the fieldname
|
|
650
|
+
|
|
651
|
+
Args
|
|
652
|
+
----
|
|
653
|
+
builder:
|
|
654
|
+
LLVM IRBuilder
|
|
655
|
+
val:
|
|
656
|
+
value to be inserted
|
|
657
|
+
pos: int or str
|
|
658
|
+
field index or field name
|
|
659
|
+
|
|
660
|
+
Returns
|
|
661
|
+
-------
|
|
662
|
+
Extracted value
|
|
663
|
+
"""
|
|
664
|
+
if isinstance(pos, str):
|
|
665
|
+
pos = self.get_field_position(pos)
|
|
666
|
+
return builder.extract_value(
|
|
667
|
+
val, [pos], name="extracted." + self._fields[pos]
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
def set(self, builder, stval, val, pos):
|
|
671
|
+
"""Set a field at the given position or the fieldname
|
|
672
|
+
|
|
673
|
+
Args
|
|
674
|
+
----
|
|
675
|
+
builder:
|
|
676
|
+
LLVM IRBuilder
|
|
677
|
+
stval:
|
|
678
|
+
LLVM struct value
|
|
679
|
+
val:
|
|
680
|
+
value to be inserted
|
|
681
|
+
pos: int or str
|
|
682
|
+
field index or field name
|
|
683
|
+
|
|
684
|
+
Returns
|
|
685
|
+
-------
|
|
686
|
+
A new LLVM struct with the value inserted
|
|
687
|
+
"""
|
|
688
|
+
if isinstance(pos, str):
|
|
689
|
+
pos = self.get_field_position(pos)
|
|
690
|
+
return builder.insert_value(
|
|
691
|
+
stval, val, [pos], name="inserted." + self._fields[pos]
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
def get_field_position(self, field):
|
|
695
|
+
try:
|
|
696
|
+
return self._fields.index(field)
|
|
697
|
+
except ValueError:
|
|
698
|
+
raise KeyError(
|
|
699
|
+
"%s does not have a field named %r"
|
|
700
|
+
% (self.__class__.__name__, field)
|
|
701
|
+
)
|
|
702
|
+
|
|
703
|
+
@property
|
|
704
|
+
def field_count(self):
|
|
705
|
+
return len(self._fields)
|
|
706
|
+
|
|
707
|
+
def get_type(self, pos):
|
|
708
|
+
"""Get the frontend type (numba type) of a field given the position
|
|
709
|
+
or the fieldname
|
|
710
|
+
|
|
711
|
+
Args
|
|
712
|
+
----
|
|
713
|
+
pos: int or str
|
|
714
|
+
field index or field name
|
|
715
|
+
"""
|
|
716
|
+
if isinstance(pos, str):
|
|
717
|
+
pos = self.get_field_position(pos)
|
|
718
|
+
return self._members[pos]
|
|
719
|
+
|
|
720
|
+
def get_model(self, pos):
|
|
721
|
+
"""
|
|
722
|
+
Get the datamodel of a field given the position or the fieldname.
|
|
723
|
+
|
|
724
|
+
Args
|
|
725
|
+
----
|
|
726
|
+
pos: int or str
|
|
727
|
+
field index or field name
|
|
728
|
+
"""
|
|
729
|
+
return self._models[pos]
|
|
730
|
+
|
|
731
|
+
def traverse(self, builder):
|
|
732
|
+
def getter(k, value):
|
|
733
|
+
if value.type != self.get_value_type():
|
|
734
|
+
args = self.get_value_type(), value.type
|
|
735
|
+
raise TypeError("expecting {0} but got {1}".format(*args))
|
|
736
|
+
return self.get(builder, value, k)
|
|
737
|
+
|
|
738
|
+
return [(self.get_type(k), partial(getter, k)) for k in self._fields]
|
|
739
|
+
|
|
740
|
+
def inner_models(self):
|
|
741
|
+
return self._models
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
@register_default(types.Complex)
|
|
745
|
+
class ComplexModel(StructModel):
|
|
746
|
+
_element_type = NotImplemented
|
|
747
|
+
|
|
748
|
+
def __init__(self, dmm, fe_type):
|
|
749
|
+
members = [
|
|
750
|
+
("real", fe_type.underlying_float),
|
|
751
|
+
("imag", fe_type.underlying_float),
|
|
752
|
+
]
|
|
753
|
+
super(ComplexModel, self).__init__(dmm, fe_type, members)
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
@register_default(types.LiteralList)
|
|
757
|
+
@register_default(types.LiteralStrKeyDict)
|
|
758
|
+
@register_default(types.Tuple)
|
|
759
|
+
@register_default(types.NamedTuple)
|
|
760
|
+
@register_default(types.StarArgTuple)
|
|
761
|
+
class TupleModel(StructModel):
|
|
762
|
+
def __init__(self, dmm, fe_type):
|
|
763
|
+
members = [("f" + str(i), t) for i, t in enumerate(fe_type)]
|
|
764
|
+
super(TupleModel, self).__init__(dmm, fe_type, members)
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
@register_default(types.UnionType)
|
|
768
|
+
class UnionModel(StructModel):
|
|
769
|
+
def __init__(self, dmm, fe_type):
|
|
770
|
+
members = [
|
|
771
|
+
("tag", types.uintp),
|
|
772
|
+
# XXX: it should really be a MemInfoPointer(types.voidptr)
|
|
773
|
+
("payload", types.Tuple.from_types(fe_type.types)),
|
|
774
|
+
]
|
|
775
|
+
super(UnionModel, self).__init__(dmm, fe_type, members)
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
@register_default(types.Pair)
|
|
779
|
+
class PairModel(StructModel):
|
|
780
|
+
def __init__(self, dmm, fe_type):
|
|
781
|
+
members = [
|
|
782
|
+
("first", fe_type.first_type),
|
|
783
|
+
("second", fe_type.second_type),
|
|
784
|
+
]
|
|
785
|
+
super(PairModel, self).__init__(dmm, fe_type, members)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
@register_default(types.ListPayload)
|
|
789
|
+
class ListPayloadModel(StructModel):
|
|
790
|
+
def __init__(self, dmm, fe_type):
|
|
791
|
+
# The fields are mutable but the payload is always manipulated
|
|
792
|
+
# by reference. This scheme allows mutations of an array to
|
|
793
|
+
# be seen by its iterators.
|
|
794
|
+
members = [
|
|
795
|
+
("size", types.intp),
|
|
796
|
+
("allocated", types.intp),
|
|
797
|
+
# This member is only used only for reflected lists
|
|
798
|
+
("dirty", types.boolean),
|
|
799
|
+
# Actually an inlined var-sized array
|
|
800
|
+
("data", fe_type.container.dtype),
|
|
801
|
+
]
|
|
802
|
+
super(ListPayloadModel, self).__init__(dmm, fe_type, members)
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
@register_default(types.List)
|
|
806
|
+
class ListModel(StructModel):
|
|
807
|
+
def __init__(self, dmm, fe_type):
|
|
808
|
+
payload_type = types.ListPayload(fe_type)
|
|
809
|
+
members = [
|
|
810
|
+
# The meminfo data points to a ListPayload
|
|
811
|
+
("meminfo", types.MemInfoPointer(payload_type)),
|
|
812
|
+
# This member is only used only for reflected lists
|
|
813
|
+
("parent", types.pyobject),
|
|
814
|
+
]
|
|
815
|
+
super(ListModel, self).__init__(dmm, fe_type, members)
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
@register_default(types.ListIter)
|
|
819
|
+
class ListIterModel(StructModel):
|
|
820
|
+
def __init__(self, dmm, fe_type):
|
|
821
|
+
payload_type = types.ListPayload(fe_type.container)
|
|
822
|
+
members = [
|
|
823
|
+
# The meminfo data points to a ListPayload (shared with the
|
|
824
|
+
# original list object)
|
|
825
|
+
("meminfo", types.MemInfoPointer(payload_type)),
|
|
826
|
+
("index", types.EphemeralPointer(types.intp)),
|
|
827
|
+
]
|
|
828
|
+
super(ListIterModel, self).__init__(dmm, fe_type, members)
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
@register_default(types.SetEntry)
|
|
832
|
+
class SetEntryModel(StructModel):
|
|
833
|
+
def __init__(self, dmm, fe_type):
|
|
834
|
+
dtype = fe_type.set_type.dtype
|
|
835
|
+
members = [
|
|
836
|
+
# -1 = empty, -2 = deleted
|
|
837
|
+
("hash", types.intp),
|
|
838
|
+
("key", dtype),
|
|
839
|
+
]
|
|
840
|
+
super(SetEntryModel, self).__init__(dmm, fe_type, members)
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
@register_default(types.SetPayload)
|
|
844
|
+
class SetPayloadModel(StructModel):
|
|
845
|
+
def __init__(self, dmm, fe_type):
|
|
846
|
+
entry_type = types.SetEntry(fe_type.container)
|
|
847
|
+
members = [
|
|
848
|
+
# Number of active + deleted entries
|
|
849
|
+
("fill", types.intp),
|
|
850
|
+
# Number of active entries
|
|
851
|
+
("used", types.intp),
|
|
852
|
+
# Allocated size - 1 (size being a power of 2)
|
|
853
|
+
("mask", types.intp),
|
|
854
|
+
# Search finger
|
|
855
|
+
("finger", types.intp),
|
|
856
|
+
# This member is only used only for reflected sets
|
|
857
|
+
("dirty", types.boolean),
|
|
858
|
+
# Actually an inlined var-sized array
|
|
859
|
+
("entries", entry_type),
|
|
860
|
+
]
|
|
861
|
+
super(SetPayloadModel, self).__init__(dmm, fe_type, members)
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
@register_default(types.Set)
|
|
865
|
+
class SetModel(StructModel):
|
|
866
|
+
def __init__(self, dmm, fe_type):
|
|
867
|
+
payload_type = types.SetPayload(fe_type)
|
|
868
|
+
members = [
|
|
869
|
+
# The meminfo data points to a SetPayload
|
|
870
|
+
("meminfo", types.MemInfoPointer(payload_type)),
|
|
871
|
+
# This member is only used only for reflected sets
|
|
872
|
+
("parent", types.pyobject),
|
|
873
|
+
]
|
|
874
|
+
super(SetModel, self).__init__(dmm, fe_type, members)
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
@register_default(types.SetIter)
|
|
878
|
+
class SetIterModel(StructModel):
|
|
879
|
+
def __init__(self, dmm, fe_type):
|
|
880
|
+
payload_type = types.SetPayload(fe_type.container)
|
|
881
|
+
members = [
|
|
882
|
+
# The meminfo data points to a SetPayload (shared with the
|
|
883
|
+
# original set object)
|
|
884
|
+
("meminfo", types.MemInfoPointer(payload_type)),
|
|
885
|
+
# The index into the entries table
|
|
886
|
+
("index", types.EphemeralPointer(types.intp)),
|
|
887
|
+
]
|
|
888
|
+
super(SetIterModel, self).__init__(dmm, fe_type, members)
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
@register_default(types.Array)
|
|
892
|
+
@register_default(types.Buffer)
|
|
893
|
+
@register_default(types.ByteArray)
|
|
894
|
+
@register_default(types.Bytes)
|
|
895
|
+
@register_default(types.MemoryView)
|
|
896
|
+
@register_default(types.PyArray)
|
|
897
|
+
class ArrayModel(StructModel):
|
|
898
|
+
def __init__(self, dmm, fe_type):
|
|
899
|
+
ndim = fe_type.ndim
|
|
900
|
+
members = [
|
|
901
|
+
("meminfo", types.MemInfoPointer(fe_type.dtype)),
|
|
902
|
+
("parent", types.pyobject),
|
|
903
|
+
("nitems", types.intp),
|
|
904
|
+
("itemsize", types.intp),
|
|
905
|
+
("data", types.CPointer(fe_type.dtype)),
|
|
906
|
+
("shape", types.UniTuple(types.intp, ndim)),
|
|
907
|
+
("strides", types.UniTuple(types.intp, ndim)),
|
|
908
|
+
]
|
|
909
|
+
super(ArrayModel, self).__init__(dmm, fe_type, members)
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
@register_default(types.ArrayFlags)
|
|
913
|
+
class ArrayFlagsModel(StructModel):
|
|
914
|
+
def __init__(self, dmm, fe_type):
|
|
915
|
+
members = [
|
|
916
|
+
("parent", fe_type.array_type),
|
|
917
|
+
]
|
|
918
|
+
super(ArrayFlagsModel, self).__init__(dmm, fe_type, members)
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
@register_default(types.NestedArray)
|
|
922
|
+
class NestedArrayModel(ArrayModel):
|
|
923
|
+
def __init__(self, dmm, fe_type):
|
|
924
|
+
self._be_type = dmm.lookup(fe_type.dtype).get_data_type()
|
|
925
|
+
super(NestedArrayModel, self).__init__(dmm, fe_type)
|
|
926
|
+
|
|
927
|
+
def as_storage_type(self):
|
|
928
|
+
"""Return the LLVM type representation for the storage of
|
|
929
|
+
the nestedarray.
|
|
930
|
+
"""
|
|
931
|
+
ret = ir.ArrayType(self._be_type, self._fe_type.nitems)
|
|
932
|
+
return ret
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
@register_default(types.Optional)
|
|
936
|
+
class OptionalModel(StructModel):
|
|
937
|
+
def __init__(self, dmm, fe_type):
|
|
938
|
+
members = [
|
|
939
|
+
("data", fe_type.type),
|
|
940
|
+
("valid", types.boolean),
|
|
941
|
+
]
|
|
942
|
+
self._value_model = dmm.lookup(fe_type.type)
|
|
943
|
+
super(OptionalModel, self).__init__(dmm, fe_type, members)
|
|
944
|
+
|
|
945
|
+
def get_return_type(self):
|
|
946
|
+
return self._value_model.get_return_type()
|
|
947
|
+
|
|
948
|
+
def as_return(self, builder, value):
|
|
949
|
+
raise NotImplementedError
|
|
950
|
+
|
|
951
|
+
def from_return(self, builder, value):
|
|
952
|
+
return self._value_model.from_return(builder, value)
|
|
953
|
+
|
|
954
|
+
def traverse(self, builder):
|
|
955
|
+
def get_data(value):
|
|
956
|
+
valid = get_valid(value)
|
|
957
|
+
data = self.get(builder, value, "data")
|
|
958
|
+
return builder.select(valid, data, ir.Constant(data.type, None))
|
|
959
|
+
|
|
960
|
+
def get_valid(value):
|
|
961
|
+
return self.get(builder, value, "valid")
|
|
962
|
+
|
|
963
|
+
return [
|
|
964
|
+
(self.get_type("data"), get_data),
|
|
965
|
+
(self.get_type("valid"), get_valid),
|
|
966
|
+
]
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
@register_default(types.Record)
|
|
970
|
+
class RecordModel(CompositeModel):
|
|
971
|
+
def __init__(self, dmm, fe_type):
|
|
972
|
+
super(RecordModel, self).__init__(dmm, fe_type)
|
|
973
|
+
self._models = [self._dmm.lookup(t) for _, t in fe_type.members]
|
|
974
|
+
self._be_type = ir.ArrayType(ir.IntType(8), fe_type.size)
|
|
975
|
+
self._be_ptr_type = self._be_type.as_pointer()
|
|
976
|
+
|
|
977
|
+
def get_value_type(self):
|
|
978
|
+
"""Passed around as reference to underlying data"""
|
|
979
|
+
return self._be_ptr_type
|
|
980
|
+
|
|
981
|
+
def get_argument_type(self):
|
|
982
|
+
return self._be_ptr_type
|
|
983
|
+
|
|
984
|
+
def get_return_type(self):
|
|
985
|
+
return self._be_ptr_type
|
|
986
|
+
|
|
987
|
+
def get_data_type(self):
|
|
988
|
+
return self._be_type
|
|
989
|
+
|
|
990
|
+
def as_data(self, builder, value):
|
|
991
|
+
return builder.load(value)
|
|
992
|
+
|
|
993
|
+
def from_data(self, builder, value):
|
|
994
|
+
raise NotImplementedError("use load_from_data_pointer() instead")
|
|
995
|
+
|
|
996
|
+
def as_argument(self, builder, value):
|
|
997
|
+
return value
|
|
998
|
+
|
|
999
|
+
def from_argument(self, builder, value):
|
|
1000
|
+
return value
|
|
1001
|
+
|
|
1002
|
+
def as_return(self, builder, value):
|
|
1003
|
+
return value
|
|
1004
|
+
|
|
1005
|
+
def from_return(self, builder, value):
|
|
1006
|
+
return value
|
|
1007
|
+
|
|
1008
|
+
def load_from_data_pointer(self, builder, ptr, align=None):
|
|
1009
|
+
return builder.bitcast(ptr, self.get_value_type())
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
@register_default(types.UnicodeCharSeq)
|
|
1013
|
+
class UnicodeCharSeq(DataModel):
|
|
1014
|
+
def __init__(self, dmm, fe_type):
|
|
1015
|
+
super(UnicodeCharSeq, self).__init__(dmm, fe_type)
|
|
1016
|
+
charty = ir.IntType(numpy_support.sizeof_unicode_char * 8)
|
|
1017
|
+
self._be_type = ir.ArrayType(charty, fe_type.count)
|
|
1018
|
+
|
|
1019
|
+
def get_value_type(self):
|
|
1020
|
+
return self._be_type
|
|
1021
|
+
|
|
1022
|
+
def get_data_type(self):
|
|
1023
|
+
return self._be_type
|
|
1024
|
+
|
|
1025
|
+
def as_data(self, builder, value):
|
|
1026
|
+
return value
|
|
1027
|
+
|
|
1028
|
+
def from_data(self, builder, value):
|
|
1029
|
+
return value
|
|
1030
|
+
|
|
1031
|
+
def as_return(self, builder, value):
|
|
1032
|
+
return value
|
|
1033
|
+
|
|
1034
|
+
def from_return(self, builder, value):
|
|
1035
|
+
return value
|
|
1036
|
+
|
|
1037
|
+
def as_argument(self, builder, value):
|
|
1038
|
+
return value
|
|
1039
|
+
|
|
1040
|
+
def from_argument(self, builder, value):
|
|
1041
|
+
return value
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
@register_default(types.CharSeq)
|
|
1045
|
+
class CharSeq(DataModel):
|
|
1046
|
+
def __init__(self, dmm, fe_type):
|
|
1047
|
+
super(CharSeq, self).__init__(dmm, fe_type)
|
|
1048
|
+
charty = ir.IntType(8)
|
|
1049
|
+
self._be_type = ir.ArrayType(charty, fe_type.count)
|
|
1050
|
+
|
|
1051
|
+
def get_value_type(self):
|
|
1052
|
+
return self._be_type
|
|
1053
|
+
|
|
1054
|
+
def get_data_type(self):
|
|
1055
|
+
return self._be_type
|
|
1056
|
+
|
|
1057
|
+
def as_data(self, builder, value):
|
|
1058
|
+
return value
|
|
1059
|
+
|
|
1060
|
+
def from_data(self, builder, value):
|
|
1061
|
+
return value
|
|
1062
|
+
|
|
1063
|
+
def as_return(self, builder, value):
|
|
1064
|
+
return value
|
|
1065
|
+
|
|
1066
|
+
def from_return(self, builder, value):
|
|
1067
|
+
return value
|
|
1068
|
+
|
|
1069
|
+
def as_argument(self, builder, value):
|
|
1070
|
+
return value
|
|
1071
|
+
|
|
1072
|
+
def from_argument(self, builder, value):
|
|
1073
|
+
return value
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
class CContiguousFlatIter(StructModel):
|
|
1077
|
+
def __init__(self, dmm, fe_type, need_indices):
|
|
1078
|
+
assert fe_type.array_type.layout == "C"
|
|
1079
|
+
array_type = fe_type.array_type
|
|
1080
|
+
ndim = array_type.ndim
|
|
1081
|
+
members = [
|
|
1082
|
+
("array", array_type),
|
|
1083
|
+
("stride", types.intp),
|
|
1084
|
+
("index", types.EphemeralPointer(types.intp)),
|
|
1085
|
+
]
|
|
1086
|
+
if need_indices:
|
|
1087
|
+
# For ndenumerate()
|
|
1088
|
+
members.append(("indices", types.EphemeralArray(types.intp, ndim)))
|
|
1089
|
+
super(CContiguousFlatIter, self).__init__(dmm, fe_type, members)
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
class FlatIter(StructModel):
|
|
1093
|
+
def __init__(self, dmm, fe_type):
|
|
1094
|
+
array_type = fe_type.array_type
|
|
1095
|
+
dtype = array_type.dtype
|
|
1096
|
+
ndim = array_type.ndim
|
|
1097
|
+
members = [
|
|
1098
|
+
("array", array_type),
|
|
1099
|
+
("pointers", types.EphemeralArray(types.CPointer(dtype), ndim)),
|
|
1100
|
+
("indices", types.EphemeralArray(types.intp, ndim)),
|
|
1101
|
+
("exhausted", types.EphemeralPointer(types.boolean)),
|
|
1102
|
+
]
|
|
1103
|
+
super(FlatIter, self).__init__(dmm, fe_type, members)
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
@register_default(types.UniTupleIter)
|
|
1107
|
+
class UniTupleIter(StructModel):
|
|
1108
|
+
def __init__(self, dmm, fe_type):
|
|
1109
|
+
members = [
|
|
1110
|
+
("index", types.EphemeralPointer(types.intp)),
|
|
1111
|
+
(
|
|
1112
|
+
"tuple",
|
|
1113
|
+
fe_type.container,
|
|
1114
|
+
),
|
|
1115
|
+
]
|
|
1116
|
+
super(UniTupleIter, self).__init__(dmm, fe_type, members)
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
@register_default(types.misc.SliceLiteral)
|
|
1120
|
+
@register_default(types.SliceType)
|
|
1121
|
+
class SliceModel(StructModel):
|
|
1122
|
+
def __init__(self, dmm, fe_type):
|
|
1123
|
+
members = [
|
|
1124
|
+
("start", types.intp),
|
|
1125
|
+
("stop", types.intp),
|
|
1126
|
+
("step", types.intp),
|
|
1127
|
+
]
|
|
1128
|
+
super(SliceModel, self).__init__(dmm, fe_type, members)
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
@register_default(types.NPDatetime)
|
|
1132
|
+
@register_default(types.NPTimedelta)
|
|
1133
|
+
class NPDatetimeModel(PrimitiveModel):
|
|
1134
|
+
def __init__(self, dmm, fe_type):
|
|
1135
|
+
be_type = ir.IntType(64)
|
|
1136
|
+
super(NPDatetimeModel, self).__init__(dmm, fe_type, be_type)
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
@register_default(types.ArrayIterator)
|
|
1140
|
+
class ArrayIterator(StructModel):
|
|
1141
|
+
def __init__(self, dmm, fe_type):
|
|
1142
|
+
# We use an unsigned index to avoid the cost of negative index tests.
|
|
1143
|
+
members = [
|
|
1144
|
+
("index", types.EphemeralPointer(types.uintp)),
|
|
1145
|
+
("array", fe_type.array_type),
|
|
1146
|
+
]
|
|
1147
|
+
super(ArrayIterator, self).__init__(dmm, fe_type, members)
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
@register_default(types.EnumerateType)
|
|
1151
|
+
class EnumerateType(StructModel):
|
|
1152
|
+
def __init__(self, dmm, fe_type):
|
|
1153
|
+
members = [
|
|
1154
|
+
("count", types.EphemeralPointer(types.intp)),
|
|
1155
|
+
("iter", fe_type.source_type),
|
|
1156
|
+
]
|
|
1157
|
+
|
|
1158
|
+
super(EnumerateType, self).__init__(dmm, fe_type, members)
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
@register_default(types.ZipType)
|
|
1162
|
+
class ZipType(StructModel):
|
|
1163
|
+
def __init__(self, dmm, fe_type):
|
|
1164
|
+
members = [
|
|
1165
|
+
("iter%d" % i, source_type.iterator_type)
|
|
1166
|
+
for i, source_type in enumerate(fe_type.source_types)
|
|
1167
|
+
]
|
|
1168
|
+
super(ZipType, self).__init__(dmm, fe_type, members)
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
@register_default(types.RangeIteratorType)
|
|
1172
|
+
class RangeIteratorType(StructModel):
|
|
1173
|
+
def __init__(self, dmm, fe_type):
|
|
1174
|
+
int_type = fe_type.yield_type
|
|
1175
|
+
members = [
|
|
1176
|
+
("iter", types.EphemeralPointer(int_type)),
|
|
1177
|
+
("stop", int_type),
|
|
1178
|
+
("step", int_type),
|
|
1179
|
+
("count", types.EphemeralPointer(int_type)),
|
|
1180
|
+
]
|
|
1181
|
+
super(RangeIteratorType, self).__init__(dmm, fe_type, members)
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
@register_default(types.Generator)
|
|
1185
|
+
class GeneratorModel(CompositeModel):
|
|
1186
|
+
def __init__(self, dmm, fe_type):
|
|
1187
|
+
super(GeneratorModel, self).__init__(dmm, fe_type)
|
|
1188
|
+
# XXX Fold this in DataPacker?
|
|
1189
|
+
self._arg_models = [
|
|
1190
|
+
self._dmm.lookup(t)
|
|
1191
|
+
for t in fe_type.arg_types
|
|
1192
|
+
if not isinstance(t, types.Omitted)
|
|
1193
|
+
]
|
|
1194
|
+
self._state_models = [self._dmm.lookup(t) for t in fe_type.state_types]
|
|
1195
|
+
|
|
1196
|
+
self._args_be_type = ir.LiteralStructType(
|
|
1197
|
+
[t.get_data_type() for t in self._arg_models]
|
|
1198
|
+
)
|
|
1199
|
+
self._state_be_type = ir.LiteralStructType(
|
|
1200
|
+
[t.get_data_type() for t in self._state_models]
|
|
1201
|
+
)
|
|
1202
|
+
# The whole generator closure
|
|
1203
|
+
self._be_type = ir.LiteralStructType(
|
|
1204
|
+
[
|
|
1205
|
+
self._dmm.lookup(types.int32).get_value_type(),
|
|
1206
|
+
self._args_be_type,
|
|
1207
|
+
self._state_be_type,
|
|
1208
|
+
]
|
|
1209
|
+
)
|
|
1210
|
+
self._be_ptr_type = self._be_type.as_pointer()
|
|
1211
|
+
|
|
1212
|
+
def get_value_type(self):
|
|
1213
|
+
"""
|
|
1214
|
+
The generator closure is passed around as a reference.
|
|
1215
|
+
"""
|
|
1216
|
+
return self._be_ptr_type
|
|
1217
|
+
|
|
1218
|
+
def get_argument_type(self):
|
|
1219
|
+
return self._be_ptr_type
|
|
1220
|
+
|
|
1221
|
+
def get_return_type(self):
|
|
1222
|
+
return self._be_type
|
|
1223
|
+
|
|
1224
|
+
def get_data_type(self):
|
|
1225
|
+
return self._be_type
|
|
1226
|
+
|
|
1227
|
+
def as_argument(self, builder, value):
|
|
1228
|
+
return value
|
|
1229
|
+
|
|
1230
|
+
def from_argument(self, builder, value):
|
|
1231
|
+
return value
|
|
1232
|
+
|
|
1233
|
+
def as_return(self, builder, value):
|
|
1234
|
+
return self.as_data(builder, value)
|
|
1235
|
+
|
|
1236
|
+
def from_return(self, builder, value):
|
|
1237
|
+
return self.from_data(builder, value)
|
|
1238
|
+
|
|
1239
|
+
def as_data(self, builder, value):
|
|
1240
|
+
return builder.load(value)
|
|
1241
|
+
|
|
1242
|
+
def from_data(self, builder, value):
|
|
1243
|
+
stack = cgutils.alloca_once(builder, value.type)
|
|
1244
|
+
builder.store(value, stack)
|
|
1245
|
+
return stack
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
@register_default(types.ArrayCTypes)
|
|
1249
|
+
class ArrayCTypesModel(StructModel):
|
|
1250
|
+
def __init__(self, dmm, fe_type):
|
|
1251
|
+
# ndim = fe_type.ndim
|
|
1252
|
+
members = [
|
|
1253
|
+
("data", types.CPointer(fe_type.dtype)),
|
|
1254
|
+
("meminfo", types.MemInfoPointer(fe_type.dtype)),
|
|
1255
|
+
]
|
|
1256
|
+
super(ArrayCTypesModel, self).__init__(dmm, fe_type, members)
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
@register_default(types.RangeType)
|
|
1260
|
+
class RangeModel(StructModel):
|
|
1261
|
+
def __init__(self, dmm, fe_type):
|
|
1262
|
+
int_type = fe_type.iterator_type.yield_type
|
|
1263
|
+
members = [("start", int_type), ("stop", int_type), ("step", int_type)]
|
|
1264
|
+
super(RangeModel, self).__init__(dmm, fe_type, members)
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
# =============================================================================
|
|
1268
|
+
|
|
1269
|
+
|
|
1270
|
+
@register_default(types.NumpyNdIndexType)
|
|
1271
|
+
class NdIndexModel(StructModel):
|
|
1272
|
+
def __init__(self, dmm, fe_type):
|
|
1273
|
+
ndim = fe_type.ndim
|
|
1274
|
+
members = [
|
|
1275
|
+
("shape", types.UniTuple(types.intp, ndim)),
|
|
1276
|
+
("indices", types.EphemeralArray(types.intp, ndim)),
|
|
1277
|
+
("exhausted", types.EphemeralPointer(types.boolean)),
|
|
1278
|
+
]
|
|
1279
|
+
super(NdIndexModel, self).__init__(dmm, fe_type, members)
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
@register_default(types.NumpyFlatType)
|
|
1283
|
+
def handle_numpy_flat_type(dmm, ty):
|
|
1284
|
+
if ty.array_type.layout == "C":
|
|
1285
|
+
return CContiguousFlatIter(dmm, ty, need_indices=False)
|
|
1286
|
+
else:
|
|
1287
|
+
return FlatIter(dmm, ty)
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
@register_default(types.NumpyNdEnumerateType)
|
|
1291
|
+
def handle_numpy_ndenumerate_type(dmm, ty):
|
|
1292
|
+
if ty.array_type.layout == "C":
|
|
1293
|
+
return CContiguousFlatIter(dmm, ty, need_indices=True)
|
|
1294
|
+
else:
|
|
1295
|
+
return FlatIter(dmm, ty)
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
@register_default(types.BoundFunction)
|
|
1299
|
+
def handle_bound_function(dmm, ty):
|
|
1300
|
+
# The same as the underlying type
|
|
1301
|
+
return dmm[ty.this]
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
@register_default(types.NumpyNdIterType)
|
|
1305
|
+
class NdIter(StructModel):
|
|
1306
|
+
def __init__(self, dmm, fe_type):
|
|
1307
|
+
array_types = fe_type.arrays
|
|
1308
|
+
ndim = fe_type.ndim
|
|
1309
|
+
shape_len = ndim if fe_type.need_shaped_indexing else 1
|
|
1310
|
+
members = [
|
|
1311
|
+
("exhausted", types.EphemeralPointer(types.boolean)),
|
|
1312
|
+
("arrays", types.Tuple(array_types)),
|
|
1313
|
+
# The iterator's main shape and indices
|
|
1314
|
+
("shape", types.UniTuple(types.intp, shape_len)),
|
|
1315
|
+
("indices", types.EphemeralArray(types.intp, shape_len)),
|
|
1316
|
+
]
|
|
1317
|
+
# Indexing state for the various sub-iterators
|
|
1318
|
+
# XXX use a tuple instead?
|
|
1319
|
+
for i, sub in enumerate(fe_type.indexers):
|
|
1320
|
+
kind, start_dim, end_dim, _ = sub
|
|
1321
|
+
member_name = "index%d" % i
|
|
1322
|
+
if kind == "flat":
|
|
1323
|
+
# A single index into the flattened array
|
|
1324
|
+
members.append(
|
|
1325
|
+
(member_name, types.EphemeralPointer(types.intp))
|
|
1326
|
+
)
|
|
1327
|
+
elif kind in ("scalar", "indexed", "0d"):
|
|
1328
|
+
# Nothing required
|
|
1329
|
+
pass
|
|
1330
|
+
else:
|
|
1331
|
+
assert 0
|
|
1332
|
+
# Slots holding values of the scalar args
|
|
1333
|
+
# XXX use a tuple instead?
|
|
1334
|
+
for i, ty in enumerate(fe_type.arrays):
|
|
1335
|
+
if not isinstance(ty, types.Array):
|
|
1336
|
+
member_name = "scalar%d" % i
|
|
1337
|
+
members.append((member_name, types.EphemeralPointer(ty)))
|
|
1338
|
+
|
|
1339
|
+
super(NdIter, self).__init__(dmm, fe_type, members)
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
@register_default(types.DeferredType)
|
|
1343
|
+
class DeferredStructModel(CompositeModel):
|
|
1344
|
+
def __init__(self, dmm, fe_type):
|
|
1345
|
+
super(DeferredStructModel, self).__init__(dmm, fe_type)
|
|
1346
|
+
self.typename = "deferred.{0}".format(id(fe_type))
|
|
1347
|
+
self.actual_fe_type = fe_type.get()
|
|
1348
|
+
|
|
1349
|
+
def get_value_type(self):
|
|
1350
|
+
return ir.global_context.get_identified_type(self.typename + ".value")
|
|
1351
|
+
|
|
1352
|
+
def get_data_type(self):
|
|
1353
|
+
return ir.global_context.get_identified_type(self.typename + ".data")
|
|
1354
|
+
|
|
1355
|
+
def get_argument_type(self):
|
|
1356
|
+
return self._actual_model.get_argument_type()
|
|
1357
|
+
|
|
1358
|
+
def as_argument(self, builder, value):
|
|
1359
|
+
inner = self.get(builder, value)
|
|
1360
|
+
return self._actual_model.as_argument(builder, inner)
|
|
1361
|
+
|
|
1362
|
+
def from_argument(self, builder, value):
|
|
1363
|
+
res = self._actual_model.from_argument(builder, value)
|
|
1364
|
+
return self.set(builder, self.make_uninitialized(), res)
|
|
1365
|
+
|
|
1366
|
+
def from_data(self, builder, value):
|
|
1367
|
+
self._define()
|
|
1368
|
+
elem = self.get(builder, value)
|
|
1369
|
+
value = self._actual_model.from_data(builder, elem)
|
|
1370
|
+
out = self.make_uninitialized()
|
|
1371
|
+
return self.set(builder, out, value)
|
|
1372
|
+
|
|
1373
|
+
def as_data(self, builder, value):
|
|
1374
|
+
self._define()
|
|
1375
|
+
elem = self.get(builder, value)
|
|
1376
|
+
value = self._actual_model.as_data(builder, elem)
|
|
1377
|
+
out = self.make_uninitialized(kind="data")
|
|
1378
|
+
return self.set(builder, out, value)
|
|
1379
|
+
|
|
1380
|
+
def from_return(self, builder, value):
|
|
1381
|
+
return value
|
|
1382
|
+
|
|
1383
|
+
def as_return(self, builder, value):
|
|
1384
|
+
return value
|
|
1385
|
+
|
|
1386
|
+
def get(self, builder, value):
|
|
1387
|
+
return builder.extract_value(value, [0])
|
|
1388
|
+
|
|
1389
|
+
def set(self, builder, value, content):
|
|
1390
|
+
return builder.insert_value(value, content, [0])
|
|
1391
|
+
|
|
1392
|
+
def make_uninitialized(self, kind="value"):
|
|
1393
|
+
self._define()
|
|
1394
|
+
if kind == "value":
|
|
1395
|
+
ty = self.get_value_type()
|
|
1396
|
+
else:
|
|
1397
|
+
ty = self.get_data_type()
|
|
1398
|
+
return ir.Constant(ty, ir.Undefined)
|
|
1399
|
+
|
|
1400
|
+
def _define(self):
|
|
1401
|
+
valty = self.get_value_type()
|
|
1402
|
+
self._define_value_type(valty)
|
|
1403
|
+
datty = self.get_data_type()
|
|
1404
|
+
self._define_data_type(datty)
|
|
1405
|
+
|
|
1406
|
+
def _define_value_type(self, value_type):
|
|
1407
|
+
if value_type.is_opaque:
|
|
1408
|
+
value_type.set_body(self._actual_model.get_value_type())
|
|
1409
|
+
|
|
1410
|
+
def _define_data_type(self, data_type):
|
|
1411
|
+
if data_type.is_opaque:
|
|
1412
|
+
data_type.set_body(self._actual_model.get_data_type())
|
|
1413
|
+
|
|
1414
|
+
@property
|
|
1415
|
+
def _actual_model(self):
|
|
1416
|
+
return self._dmm.lookup(self.actual_fe_type)
|
|
1417
|
+
|
|
1418
|
+
def traverse(self, builder):
|
|
1419
|
+
return [
|
|
1420
|
+
(
|
|
1421
|
+
self.actual_fe_type,
|
|
1422
|
+
lambda value: builder.extract_value(value, [0]),
|
|
1423
|
+
)
|
|
1424
|
+
]
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
@register_default(types.StructRefPayload)
|
|
1428
|
+
class StructPayloadModel(StructModel):
|
|
1429
|
+
"""Model for the payload of a mutable struct"""
|
|
1430
|
+
|
|
1431
|
+
def __init__(self, dmm, fe_typ):
|
|
1432
|
+
members = tuple(fe_typ.field_dict.items())
|
|
1433
|
+
super().__init__(dmm, fe_typ, members)
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
class StructRefModel(StructModel):
|
|
1437
|
+
"""Model for a mutable struct.
|
|
1438
|
+
A reference to the payload
|
|
1439
|
+
"""
|
|
1440
|
+
|
|
1441
|
+
def __init__(self, dmm, fe_typ):
|
|
1442
|
+
dtype = fe_typ.get_data_type()
|
|
1443
|
+
members = [
|
|
1444
|
+
("meminfo", types.MemInfoPointer(dtype)),
|
|
1445
|
+
]
|
|
1446
|
+
super().__init__(dmm, fe_typ, members)
|