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,744 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
3
|
+
|
|
4
|
+
from abc import abstractmethod, ABCMeta
|
|
5
|
+
import itertools
|
|
6
|
+
import numba
|
|
7
|
+
import os
|
|
8
|
+
import contextlib
|
|
9
|
+
import uuid
|
|
10
|
+
import pickle
|
|
11
|
+
import hashlib
|
|
12
|
+
import errno
|
|
13
|
+
import inspect
|
|
14
|
+
import tempfile
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
from numba.cuda.misc.appdirs import AppDirs
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from numba.cuda.core import config
|
|
21
|
+
from numba.cuda.serialize import dumps
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _cache_log(msg, *args):
|
|
25
|
+
if config.DEBUG_CACHE:
|
|
26
|
+
msg = msg % args
|
|
27
|
+
print(msg)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class _Cache(metaclass=ABCMeta):
|
|
31
|
+
@property
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def cache_path(self):
|
|
34
|
+
"""
|
|
35
|
+
The base filesystem path of this cache (for example its root folder).
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def load_overload(self, sig, target_context):
|
|
40
|
+
"""
|
|
41
|
+
Load an overload for the given signature using the target context.
|
|
42
|
+
The saved object must be returned if successful, None if not found
|
|
43
|
+
in the cache.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
def save_overload(self, sig, data):
|
|
48
|
+
"""
|
|
49
|
+
Save the overload for the given signature.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
@abstractmethod
|
|
53
|
+
def enable(self):
|
|
54
|
+
"""
|
|
55
|
+
Enable the cache.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
@abstractmethod
|
|
59
|
+
def disable(self):
|
|
60
|
+
"""
|
|
61
|
+
Disable the cache.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def flush(self):
|
|
66
|
+
"""
|
|
67
|
+
Flush the cache.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class NullCache(_Cache):
|
|
72
|
+
@property
|
|
73
|
+
def cache_path(self):
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
def load_overload(self, sig, target_context):
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
def save_overload(self, sig, data):
|
|
80
|
+
pass
|
|
81
|
+
|
|
82
|
+
def enable(self):
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
def disable(self):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
def flush(self):
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class IndexDataCacheFile(object):
|
|
93
|
+
"""
|
|
94
|
+
Implements the logic for the index file and data file used by a cache.
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(self, cache_path, filename_base, source_stamp):
|
|
98
|
+
self._cache_path = cache_path
|
|
99
|
+
self._index_name = "%s.nbi" % (filename_base,)
|
|
100
|
+
self._index_path = os.path.join(self._cache_path, self._index_name)
|
|
101
|
+
self._data_name_pattern = "%s.{number:d}.nbc" % (filename_base,)
|
|
102
|
+
self._source_stamp = source_stamp
|
|
103
|
+
self._version = numba.__version__
|
|
104
|
+
|
|
105
|
+
def flush(self):
|
|
106
|
+
self._save_index({})
|
|
107
|
+
|
|
108
|
+
def save(self, key, data):
|
|
109
|
+
"""
|
|
110
|
+
Save a new cache entry with *key* and *data*.
|
|
111
|
+
"""
|
|
112
|
+
overloads = self._load_index()
|
|
113
|
+
try:
|
|
114
|
+
# If key already exists, we will overwrite the file
|
|
115
|
+
data_name = overloads[key]
|
|
116
|
+
except KeyError:
|
|
117
|
+
# Find an available name for the data file
|
|
118
|
+
existing = set(overloads.values())
|
|
119
|
+
for i in itertools.count(1):
|
|
120
|
+
data_name = self._data_name(i)
|
|
121
|
+
if data_name not in existing:
|
|
122
|
+
break
|
|
123
|
+
overloads[key] = data_name
|
|
124
|
+
self._save_index(overloads)
|
|
125
|
+
self._save_data(data_name, data)
|
|
126
|
+
|
|
127
|
+
def load(self, key):
|
|
128
|
+
"""
|
|
129
|
+
Load a cache entry with *key*.
|
|
130
|
+
"""
|
|
131
|
+
overloads = self._load_index()
|
|
132
|
+
data_name = overloads.get(key)
|
|
133
|
+
if data_name is None:
|
|
134
|
+
return
|
|
135
|
+
try:
|
|
136
|
+
return self._load_data(data_name)
|
|
137
|
+
except OSError:
|
|
138
|
+
# File could have been removed while the index still refers it.
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
def _load_index(self):
|
|
142
|
+
"""
|
|
143
|
+
Load the cache index and return it as a dictionary (possibly
|
|
144
|
+
empty if cache is empty or obsolete).
|
|
145
|
+
"""
|
|
146
|
+
try:
|
|
147
|
+
with open(self._index_path, "rb") as f:
|
|
148
|
+
version = pickle.load(f)
|
|
149
|
+
data = f.read()
|
|
150
|
+
except FileNotFoundError:
|
|
151
|
+
# Index doesn't exist yet?
|
|
152
|
+
return {}
|
|
153
|
+
if version != self._version:
|
|
154
|
+
# This is another version. Avoid trying to unpickling the
|
|
155
|
+
# rest of the stream, as that may fail.
|
|
156
|
+
return {}
|
|
157
|
+
stamp, overloads = pickle.loads(data)
|
|
158
|
+
_cache_log("[cache] index loaded from %r", self._index_path)
|
|
159
|
+
if stamp != self._source_stamp:
|
|
160
|
+
# Cache is not fresh. Stale data files will be eventually
|
|
161
|
+
# overwritten, since they are numbered in incrementing order.
|
|
162
|
+
return {}
|
|
163
|
+
else:
|
|
164
|
+
return overloads
|
|
165
|
+
|
|
166
|
+
def _save_index(self, overloads):
|
|
167
|
+
data = self._source_stamp, overloads
|
|
168
|
+
data = self._dump(data)
|
|
169
|
+
with self._open_for_write(self._index_path) as f:
|
|
170
|
+
pickle.dump(self._version, f, protocol=-1)
|
|
171
|
+
f.write(data)
|
|
172
|
+
_cache_log("[cache] index saved to %r", self._index_path)
|
|
173
|
+
|
|
174
|
+
def _load_data(self, name):
|
|
175
|
+
path = self._data_path(name)
|
|
176
|
+
with open(path, "rb") as f:
|
|
177
|
+
data = f.read()
|
|
178
|
+
tup = pickle.loads(data)
|
|
179
|
+
_cache_log("[cache] data loaded from %r", path)
|
|
180
|
+
return tup
|
|
181
|
+
|
|
182
|
+
def _save_data(self, name, data):
|
|
183
|
+
data = self._dump(data)
|
|
184
|
+
path = self._data_path(name)
|
|
185
|
+
with self._open_for_write(path) as f:
|
|
186
|
+
f.write(data)
|
|
187
|
+
_cache_log("[cache] data saved to %r", path)
|
|
188
|
+
|
|
189
|
+
def _data_name(self, number):
|
|
190
|
+
return self._data_name_pattern.format(number=number)
|
|
191
|
+
|
|
192
|
+
def _data_path(self, name):
|
|
193
|
+
return os.path.join(self._cache_path, name)
|
|
194
|
+
|
|
195
|
+
def _dump(self, obj):
|
|
196
|
+
return dumps(obj)
|
|
197
|
+
|
|
198
|
+
@contextlib.contextmanager
|
|
199
|
+
def _open_for_write(self, filepath):
|
|
200
|
+
"""
|
|
201
|
+
Open *filepath* for writing in a race condition-free way (hopefully).
|
|
202
|
+
uuid4 is used to try and avoid name collisions on a shared filesystem.
|
|
203
|
+
"""
|
|
204
|
+
uid = uuid.uuid4().hex[:16] # avoid long paths
|
|
205
|
+
tmpname = "%s.tmp.%s" % (filepath, uid)
|
|
206
|
+
try:
|
|
207
|
+
with open(tmpname, "wb") as f:
|
|
208
|
+
yield f
|
|
209
|
+
os.replace(tmpname, filepath)
|
|
210
|
+
except Exception:
|
|
211
|
+
# In case of error, remove dangling tmp file
|
|
212
|
+
try:
|
|
213
|
+
os.unlink(tmpname)
|
|
214
|
+
except OSError:
|
|
215
|
+
pass
|
|
216
|
+
raise
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class Cache(_Cache):
|
|
220
|
+
"""
|
|
221
|
+
A per-function compilation cache. The cache saves data in separate
|
|
222
|
+
data files and maintains information in an index file.
|
|
223
|
+
|
|
224
|
+
There is one index file per function and Python version
|
|
225
|
+
("function_name-<lineno>.pyXY.nbi") which contains a mapping of
|
|
226
|
+
signatures and architectures to data files.
|
|
227
|
+
It is prefixed by a versioning key and a timestamp of the Python source
|
|
228
|
+
file containing the function.
|
|
229
|
+
|
|
230
|
+
There is one data file ("function_name-<lineno>.pyXY.<number>.nbc")
|
|
231
|
+
per function, function signature, target architecture and Python version.
|
|
232
|
+
|
|
233
|
+
Separate index and data files per Python version avoid pickle
|
|
234
|
+
compatibility problems.
|
|
235
|
+
|
|
236
|
+
Note:
|
|
237
|
+
This contains the driver logic only. The core logic is provided
|
|
238
|
+
by a subclass of ``CacheImpl`` specified as *_impl_class* in the subclass.
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
# The following class variables must be overridden by subclass.
|
|
242
|
+
_impl_class = None
|
|
243
|
+
|
|
244
|
+
def __init__(self, py_func):
|
|
245
|
+
self._name = repr(py_func)
|
|
246
|
+
self._py_func = py_func
|
|
247
|
+
self._impl = self._impl_class(py_func)
|
|
248
|
+
self._cache_path = self._impl.locator.get_cache_path()
|
|
249
|
+
# This may be a bit strict but avoids us maintaining a magic number
|
|
250
|
+
source_stamp = self._impl.locator.get_source_stamp()
|
|
251
|
+
filename_base = self._impl.filename_base
|
|
252
|
+
self._cache_file = IndexDataCacheFile(
|
|
253
|
+
cache_path=self._cache_path,
|
|
254
|
+
filename_base=filename_base,
|
|
255
|
+
source_stamp=source_stamp,
|
|
256
|
+
)
|
|
257
|
+
self.enable()
|
|
258
|
+
|
|
259
|
+
def __repr__(self):
|
|
260
|
+
return "<%s py_func=%r>" % (self.__class__.__name__, self._name)
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def cache_path(self):
|
|
264
|
+
return self._cache_path
|
|
265
|
+
|
|
266
|
+
def enable(self):
|
|
267
|
+
self._enabled = True
|
|
268
|
+
|
|
269
|
+
def disable(self):
|
|
270
|
+
self._enabled = False
|
|
271
|
+
|
|
272
|
+
def flush(self):
|
|
273
|
+
self._cache_file.flush()
|
|
274
|
+
|
|
275
|
+
def load_overload(self, sig, target_context):
|
|
276
|
+
"""
|
|
277
|
+
Load and recreate the cached object for the given signature,
|
|
278
|
+
using the *target_context*.
|
|
279
|
+
"""
|
|
280
|
+
# Refresh the context to ensure it is initialized
|
|
281
|
+
target_context.refresh()
|
|
282
|
+
with self._guard_against_spurious_io_errors():
|
|
283
|
+
return self._load_overload(sig, target_context)
|
|
284
|
+
# None returned if the `with` block swallows an exception
|
|
285
|
+
|
|
286
|
+
def _load_overload(self, sig, target_context):
|
|
287
|
+
if not self._enabled:
|
|
288
|
+
return
|
|
289
|
+
key = self._index_key(sig, target_context.codegen())
|
|
290
|
+
data = self._cache_file.load(key)
|
|
291
|
+
if data is not None:
|
|
292
|
+
data = self._impl.rebuild(target_context, data)
|
|
293
|
+
return data
|
|
294
|
+
|
|
295
|
+
def save_overload(self, sig, data):
|
|
296
|
+
"""
|
|
297
|
+
Save the data for the given signature in the cache.
|
|
298
|
+
"""
|
|
299
|
+
with self._guard_against_spurious_io_errors():
|
|
300
|
+
self._save_overload(sig, data)
|
|
301
|
+
|
|
302
|
+
def _save_overload(self, sig, data):
|
|
303
|
+
if not self._enabled:
|
|
304
|
+
return
|
|
305
|
+
if not self._impl.check_cachable(data):
|
|
306
|
+
return
|
|
307
|
+
self._impl.locator.ensure_cache_path()
|
|
308
|
+
key = self._index_key(sig, data.codegen)
|
|
309
|
+
data = self._impl.reduce(data)
|
|
310
|
+
self._cache_file.save(key, data)
|
|
311
|
+
|
|
312
|
+
@contextlib.contextmanager
|
|
313
|
+
def _guard_against_spurious_io_errors(self):
|
|
314
|
+
if os.name == "nt":
|
|
315
|
+
# Guard against permission errors due to accessing the file
|
|
316
|
+
# from several processes (see #2028)
|
|
317
|
+
try:
|
|
318
|
+
yield
|
|
319
|
+
except OSError as e:
|
|
320
|
+
if e.errno != errno.EACCES:
|
|
321
|
+
raise
|
|
322
|
+
else:
|
|
323
|
+
# No such conditions under non-Windows OSes
|
|
324
|
+
yield
|
|
325
|
+
|
|
326
|
+
def _index_key(self, sig, codegen):
|
|
327
|
+
"""
|
|
328
|
+
Compute index key for the given signature and codegen.
|
|
329
|
+
It includes a description of the OS, target architecture and hashes of
|
|
330
|
+
the bytecode for the function and, if the function has a __closure__,
|
|
331
|
+
a hash of the cell_contents.
|
|
332
|
+
"""
|
|
333
|
+
codebytes = self._py_func.__code__.co_code
|
|
334
|
+
if self._py_func.__closure__ is not None:
|
|
335
|
+
cvars = tuple([x.cell_contents for x in self._py_func.__closure__])
|
|
336
|
+
# Note: cloudpickle serializes a function differently depending
|
|
337
|
+
# on how the process is launched; e.g. multiprocessing.Process
|
|
338
|
+
cvarbytes = dumps(cvars)
|
|
339
|
+
else:
|
|
340
|
+
cvarbytes = b""
|
|
341
|
+
|
|
342
|
+
hasher = lambda x: hashlib.sha256(x).hexdigest()
|
|
343
|
+
return (
|
|
344
|
+
sig,
|
|
345
|
+
codegen.magic_tuple(),
|
|
346
|
+
(
|
|
347
|
+
hasher(codebytes),
|
|
348
|
+
hasher(cvarbytes),
|
|
349
|
+
),
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class _CacheLocator(metaclass=ABCMeta):
|
|
354
|
+
"""
|
|
355
|
+
A filesystem locator for caching a given function.
|
|
356
|
+
"""
|
|
357
|
+
|
|
358
|
+
def ensure_cache_path(self):
|
|
359
|
+
path = self.get_cache_path()
|
|
360
|
+
os.makedirs(path, exist_ok=True)
|
|
361
|
+
# Ensure the directory is writable by trying to write a temporary file
|
|
362
|
+
tempfile.TemporaryFile(dir=path).close()
|
|
363
|
+
|
|
364
|
+
@abstractmethod
|
|
365
|
+
def get_cache_path(self):
|
|
366
|
+
"""
|
|
367
|
+
Return the directory the function is cached in.
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
@abstractmethod
|
|
371
|
+
def get_source_stamp(self):
|
|
372
|
+
"""
|
|
373
|
+
Get a timestamp representing the source code's freshness.
|
|
374
|
+
Can return any picklable Python object.
|
|
375
|
+
"""
|
|
376
|
+
|
|
377
|
+
@abstractmethod
|
|
378
|
+
def get_disambiguator(self):
|
|
379
|
+
"""
|
|
380
|
+
Get a string disambiguator for this locator's function.
|
|
381
|
+
It should allow disambiguating different but similarly-named functions.
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
@classmethod
|
|
385
|
+
def from_function(cls, py_func, py_file):
|
|
386
|
+
"""
|
|
387
|
+
Create a locator instance for the given function located in the
|
|
388
|
+
given file.
|
|
389
|
+
"""
|
|
390
|
+
raise NotImplementedError
|
|
391
|
+
|
|
392
|
+
@classmethod
|
|
393
|
+
def get_suitable_cache_subpath(cls, py_file):
|
|
394
|
+
"""Given the Python file path, compute a suitable path inside the
|
|
395
|
+
cache directory.
|
|
396
|
+
|
|
397
|
+
This will reduce a file path that is too long, which can be a problem
|
|
398
|
+
on some operating system (i.e. Windows 7).
|
|
399
|
+
"""
|
|
400
|
+
path = os.path.abspath(py_file)
|
|
401
|
+
subpath = os.path.dirname(path)
|
|
402
|
+
parentdir = os.path.split(subpath)[-1]
|
|
403
|
+
# Use SHA1 to reduce path length.
|
|
404
|
+
# Note: windows doesn't like long path.
|
|
405
|
+
hashed = hashlib.sha1(subpath.encode()).hexdigest()
|
|
406
|
+
# Retain parent directory name for easier debugging
|
|
407
|
+
return "_".join([parentdir, hashed])
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
class _SourceFileBackedLocatorMixin(object):
|
|
411
|
+
"""
|
|
412
|
+
A cache locator mixin for functions which are backed by a well-known
|
|
413
|
+
Python source file.
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
def get_source_stamp(self):
|
|
417
|
+
if getattr(sys, "frozen", False):
|
|
418
|
+
st = os.stat(sys.executable)
|
|
419
|
+
else:
|
|
420
|
+
st = os.stat(self._py_file)
|
|
421
|
+
# We use both timestamp and size as some filesystems only have second
|
|
422
|
+
# granularity.
|
|
423
|
+
return st.st_mtime, st.st_size
|
|
424
|
+
|
|
425
|
+
def get_disambiguator(self):
|
|
426
|
+
return str(self._lineno)
|
|
427
|
+
|
|
428
|
+
@classmethod
|
|
429
|
+
def from_function(cls, py_func, py_file):
|
|
430
|
+
if not os.path.exists(py_file):
|
|
431
|
+
# Perhaps a placeholder (e.g. "<ipython-XXX>")
|
|
432
|
+
return
|
|
433
|
+
self = cls(py_func, py_file)
|
|
434
|
+
try:
|
|
435
|
+
self.ensure_cache_path()
|
|
436
|
+
except OSError:
|
|
437
|
+
# Cannot ensure the cache directory exists or is writable
|
|
438
|
+
return
|
|
439
|
+
return self
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
class _InTreeCacheLocator(_SourceFileBackedLocatorMixin, _CacheLocator):
|
|
443
|
+
"""
|
|
444
|
+
A locator for functions backed by a regular Python module with a
|
|
445
|
+
writable __pycache__ directory.
|
|
446
|
+
"""
|
|
447
|
+
|
|
448
|
+
def __init__(self, py_func, py_file):
|
|
449
|
+
self._py_file = py_file
|
|
450
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
451
|
+
self._cache_path = os.path.join(
|
|
452
|
+
os.path.dirname(self._py_file), "__pycache__"
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
def get_cache_path(self):
|
|
456
|
+
return self._cache_path
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
class _SourceFileBackedLocatorMixin(object):
|
|
460
|
+
"""
|
|
461
|
+
A cache locator mixin for functions which are backed by a well-known
|
|
462
|
+
Python source file.
|
|
463
|
+
"""
|
|
464
|
+
|
|
465
|
+
def get_source_stamp(self):
|
|
466
|
+
if getattr(sys, "frozen", False):
|
|
467
|
+
st = os.stat(sys.executable)
|
|
468
|
+
else:
|
|
469
|
+
st = os.stat(self._py_file)
|
|
470
|
+
# We use both timestamp and size as some filesystems only have second
|
|
471
|
+
# granularity.
|
|
472
|
+
return st.st_mtime, st.st_size
|
|
473
|
+
|
|
474
|
+
def get_disambiguator(self):
|
|
475
|
+
return str(self._lineno)
|
|
476
|
+
|
|
477
|
+
@classmethod
|
|
478
|
+
def from_function(cls, py_func, py_file):
|
|
479
|
+
if not os.path.exists(py_file):
|
|
480
|
+
# Perhaps a placeholder (e.g. "<ipython-XXX>")
|
|
481
|
+
return
|
|
482
|
+
self = cls(py_func, py_file)
|
|
483
|
+
try:
|
|
484
|
+
self.ensure_cache_path()
|
|
485
|
+
except OSError:
|
|
486
|
+
# Cannot ensure the cache directory exists or is writable
|
|
487
|
+
return
|
|
488
|
+
return self
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
class _UserProvidedCacheLocator(_SourceFileBackedLocatorMixin, _CacheLocator):
|
|
492
|
+
"""
|
|
493
|
+
A locator that always point to the user provided directory in
|
|
494
|
+
`numba.config.CACHE_DIR`
|
|
495
|
+
"""
|
|
496
|
+
|
|
497
|
+
def __init__(self, py_func, py_file):
|
|
498
|
+
self._py_file = py_file
|
|
499
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
500
|
+
cache_subpath = self.get_suitable_cache_subpath(py_file)
|
|
501
|
+
self._cache_path = os.path.join(config.CACHE_DIR, cache_subpath)
|
|
502
|
+
|
|
503
|
+
def get_cache_path(self):
|
|
504
|
+
return self._cache_path
|
|
505
|
+
|
|
506
|
+
@classmethod
|
|
507
|
+
def from_function(cls, py_func, py_file):
|
|
508
|
+
if not config.CACHE_DIR:
|
|
509
|
+
return
|
|
510
|
+
parent = super(_UserProvidedCacheLocator, cls)
|
|
511
|
+
return parent.from_function(py_func, py_file)
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
class _UserProvidedCacheLocator(_SourceFileBackedLocatorMixin, _CacheLocator):
|
|
515
|
+
"""
|
|
516
|
+
A locator that always point to the user provided directory in
|
|
517
|
+
`numba.config.CACHE_DIR`
|
|
518
|
+
"""
|
|
519
|
+
|
|
520
|
+
def __init__(self, py_func, py_file):
|
|
521
|
+
self._py_file = py_file
|
|
522
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
523
|
+
cache_subpath = self.get_suitable_cache_subpath(py_file)
|
|
524
|
+
self._cache_path = os.path.join(config.CACHE_DIR, cache_subpath)
|
|
525
|
+
|
|
526
|
+
def get_cache_path(self):
|
|
527
|
+
return self._cache_path
|
|
528
|
+
|
|
529
|
+
@classmethod
|
|
530
|
+
def from_function(cls, py_func, py_file):
|
|
531
|
+
if not config.CACHE_DIR:
|
|
532
|
+
return
|
|
533
|
+
parent = super(_UserProvidedCacheLocator, cls)
|
|
534
|
+
return parent.from_function(py_func, py_file)
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
class _UserWideCacheLocator(_SourceFileBackedLocatorMixin, _CacheLocator):
|
|
538
|
+
"""
|
|
539
|
+
A locator for functions backed by a regular Python module or a
|
|
540
|
+
frozen executable, cached into a user-wide cache directory.
|
|
541
|
+
"""
|
|
542
|
+
|
|
543
|
+
def __init__(self, py_func, py_file):
|
|
544
|
+
self._py_file = py_file
|
|
545
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
546
|
+
appdirs = AppDirs(appname="numba", appauthor=False)
|
|
547
|
+
cache_dir = appdirs.user_cache_dir
|
|
548
|
+
cache_subpath = self.get_suitable_cache_subpath(py_file)
|
|
549
|
+
self._cache_path = os.path.join(cache_dir, cache_subpath)
|
|
550
|
+
|
|
551
|
+
def get_cache_path(self):
|
|
552
|
+
return self._cache_path
|
|
553
|
+
|
|
554
|
+
@classmethod
|
|
555
|
+
def from_function(cls, py_func, py_file):
|
|
556
|
+
if not (os.path.exists(py_file) or getattr(sys, "frozen", False)):
|
|
557
|
+
# Perhaps a placeholder (e.g. "<ipython-XXX>")
|
|
558
|
+
# stop function exit if frozen, since it uses a temp placeholder
|
|
559
|
+
return
|
|
560
|
+
self = cls(py_func, py_file)
|
|
561
|
+
try:
|
|
562
|
+
self.ensure_cache_path()
|
|
563
|
+
except OSError:
|
|
564
|
+
# Cannot ensure the cache directory exists or is writable
|
|
565
|
+
return
|
|
566
|
+
return self
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
class _IPythonCacheLocator(_CacheLocator):
|
|
570
|
+
"""
|
|
571
|
+
A locator for functions entered at the IPython prompt (notebook or other).
|
|
572
|
+
"""
|
|
573
|
+
|
|
574
|
+
def __init__(self, py_func, py_file):
|
|
575
|
+
self._py_file = py_file
|
|
576
|
+
# Note IPython enhances the linecache module to be able to
|
|
577
|
+
# inspect source code of functions defined on the interactive prompt.
|
|
578
|
+
source = inspect.getsource(py_func)
|
|
579
|
+
if isinstance(source, bytes):
|
|
580
|
+
self._bytes_source = source
|
|
581
|
+
else:
|
|
582
|
+
self._bytes_source = source.encode("utf-8")
|
|
583
|
+
|
|
584
|
+
def get_cache_path(self):
|
|
585
|
+
# We could also use jupyter_core.paths.jupyter_runtime_dir()
|
|
586
|
+
# In both cases this is a user-wide directory, so we need to
|
|
587
|
+
# be careful when disambiguating if we don't want too many
|
|
588
|
+
# conflicts (see below).
|
|
589
|
+
try:
|
|
590
|
+
from IPython.paths import get_ipython_cache_dir
|
|
591
|
+
except ImportError:
|
|
592
|
+
# older IPython version
|
|
593
|
+
from IPython.utils.path import get_ipython_cache_dir
|
|
594
|
+
return os.path.join(get_ipython_cache_dir(), "numba_cache")
|
|
595
|
+
|
|
596
|
+
def get_source_stamp(self):
|
|
597
|
+
return hashlib.sha256(self._bytes_source).hexdigest()
|
|
598
|
+
|
|
599
|
+
def get_disambiguator(self):
|
|
600
|
+
# Heuristic: we don't want too many variants being saved, but
|
|
601
|
+
# we don't want similar named functions (e.g. "f") to compete
|
|
602
|
+
# for the cache, so we hash the first two lines of the function
|
|
603
|
+
# source (usually this will be the @jit decorator + the function
|
|
604
|
+
# signature).
|
|
605
|
+
firstlines = b"".join(self._bytes_source.splitlines(True)[:2])
|
|
606
|
+
return hashlib.sha256(firstlines).hexdigest()[:10]
|
|
607
|
+
|
|
608
|
+
@classmethod
|
|
609
|
+
def from_function(cls, py_func, py_file):
|
|
610
|
+
if not (
|
|
611
|
+
py_file.startswith("<ipython-")
|
|
612
|
+
or os.path.basename(os.path.dirname(py_file)).startswith(
|
|
613
|
+
"ipykernel_"
|
|
614
|
+
)
|
|
615
|
+
):
|
|
616
|
+
return
|
|
617
|
+
self = cls(py_func, py_file)
|
|
618
|
+
try:
|
|
619
|
+
self.ensure_cache_path()
|
|
620
|
+
except OSError:
|
|
621
|
+
# Cannot ensure the cache directory exists
|
|
622
|
+
return
|
|
623
|
+
return self
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
class _ZipCacheLocator(_SourceFileBackedLocatorMixin, _CacheLocator):
|
|
627
|
+
"""
|
|
628
|
+
A locator for functions backed by Python modules within a zip archive.
|
|
629
|
+
"""
|
|
630
|
+
|
|
631
|
+
def __init__(self, py_func, py_file):
|
|
632
|
+
self._py_file = py_file
|
|
633
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
634
|
+
self._zip_path, self._internal_path = self._split_zip_path(py_file)
|
|
635
|
+
# We use AppDirs at the moment. A more advanced version of this could also allow
|
|
636
|
+
# a provided `cache_dir`, though that starts to create (cache location x source
|
|
637
|
+
# type) number of cache classes.
|
|
638
|
+
appdirs = AppDirs(appname="numba", appauthor=False)
|
|
639
|
+
cache_dir = appdirs.user_cache_dir
|
|
640
|
+
cache_subpath = self.get_suitable_cache_subpath(py_file)
|
|
641
|
+
self._cache_path = os.path.join(cache_dir, cache_subpath)
|
|
642
|
+
|
|
643
|
+
@staticmethod
|
|
644
|
+
def _split_zip_path(py_file):
|
|
645
|
+
path = Path(py_file)
|
|
646
|
+
for i, part in enumerate(path.parts):
|
|
647
|
+
if part.endswith(".zip"):
|
|
648
|
+
zip_path = str(Path(*path.parts[: i + 1]))
|
|
649
|
+
internal_path = str(Path(*path.parts[i + 1 :]))
|
|
650
|
+
return zip_path, internal_path
|
|
651
|
+
raise ValueError("No zip file found in path")
|
|
652
|
+
|
|
653
|
+
def get_cache_path(self):
|
|
654
|
+
return self._cache_path
|
|
655
|
+
|
|
656
|
+
def get_source_stamp(self):
|
|
657
|
+
st = os.stat(self._zip_path)
|
|
658
|
+
return st.st_mtime, st.st_size
|
|
659
|
+
|
|
660
|
+
@classmethod
|
|
661
|
+
def from_function(cls, py_func, py_file):
|
|
662
|
+
if ".zip" not in py_file:
|
|
663
|
+
return None
|
|
664
|
+
return cls(py_func, py_file)
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
class CacheImpl(metaclass=ABCMeta):
|
|
668
|
+
"""
|
|
669
|
+
Provides the core machinery for caching.
|
|
670
|
+
- implement how to serialize and deserialize the data in the cache.
|
|
671
|
+
- control the filename of the cache.
|
|
672
|
+
- provide the cache locator
|
|
673
|
+
"""
|
|
674
|
+
|
|
675
|
+
_locator_classes = [
|
|
676
|
+
_UserProvidedCacheLocator,
|
|
677
|
+
_InTreeCacheLocator,
|
|
678
|
+
_UserWideCacheLocator,
|
|
679
|
+
_IPythonCacheLocator,
|
|
680
|
+
_ZipCacheLocator,
|
|
681
|
+
]
|
|
682
|
+
|
|
683
|
+
def __init__(self, py_func):
|
|
684
|
+
self._lineno = py_func.__code__.co_firstlineno
|
|
685
|
+
# Get qualname
|
|
686
|
+
try:
|
|
687
|
+
qualname = py_func.__qualname__
|
|
688
|
+
except AttributeError:
|
|
689
|
+
qualname = py_func.__name__
|
|
690
|
+
# Find a locator
|
|
691
|
+
source_path = inspect.getfile(py_func)
|
|
692
|
+
for cls in self._locator_classes:
|
|
693
|
+
locator = cls.from_function(py_func, source_path)
|
|
694
|
+
if locator is not None:
|
|
695
|
+
break
|
|
696
|
+
else:
|
|
697
|
+
raise RuntimeError(
|
|
698
|
+
"cannot cache function %r: no locator available "
|
|
699
|
+
"for file %r" % (qualname, source_path)
|
|
700
|
+
)
|
|
701
|
+
self._locator = locator
|
|
702
|
+
# Use filename base name as module name to avoid conflict between
|
|
703
|
+
# foo/__init__.py and foo/foo.py
|
|
704
|
+
filename = inspect.getfile(py_func)
|
|
705
|
+
modname = os.path.splitext(os.path.basename(filename))[0]
|
|
706
|
+
fullname = "%s.%s" % (modname, qualname)
|
|
707
|
+
abiflags = getattr(sys, "abiflags", "")
|
|
708
|
+
self._filename_base = self.get_filename_base(fullname, abiflags)
|
|
709
|
+
|
|
710
|
+
def get_filename_base(self, fullname, abiflags):
|
|
711
|
+
# '<' and '>' can appear in the qualname (e.g. '<locals>') but
|
|
712
|
+
# are forbidden in Windows filenames
|
|
713
|
+
fixed_fullname = fullname.replace("<", "").replace(">", "")
|
|
714
|
+
fmt = "%s-%s.py%d%d%s"
|
|
715
|
+
return fmt % (
|
|
716
|
+
fixed_fullname,
|
|
717
|
+
self.locator.get_disambiguator(),
|
|
718
|
+
sys.version_info[0],
|
|
719
|
+
sys.version_info[1],
|
|
720
|
+
abiflags,
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
@property
|
|
724
|
+
def filename_base(self):
|
|
725
|
+
return self._filename_base
|
|
726
|
+
|
|
727
|
+
@property
|
|
728
|
+
def locator(self):
|
|
729
|
+
return self._locator
|
|
730
|
+
|
|
731
|
+
@abstractmethod
|
|
732
|
+
def reduce(self, data):
|
|
733
|
+
"Returns the serialized form the data"
|
|
734
|
+
pass
|
|
735
|
+
|
|
736
|
+
@abstractmethod
|
|
737
|
+
def rebuild(self, target_context, reduced_data):
|
|
738
|
+
"Returns the de-serialized form of the *reduced_data*"
|
|
739
|
+
pass
|
|
740
|
+
|
|
741
|
+
@abstractmethod
|
|
742
|
+
def check_cachable(self, data):
|
|
743
|
+
"Returns True if the given data is cachable; otherwise, returns False."
|
|
744
|
+
pass
|