blosc2 3.2.1__tar.gz → 3.3.0__tar.gz
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.
- {blosc2-3.2.1 → blosc2-3.3.0}/.pre-commit-config.yaml +1 -1
- {blosc2-3.2.1 → blosc2-3.3.0}/ANNOUNCE.rst +6 -10
- {blosc2-3.2.1 → blosc2-3.3.0}/PKG-INFO +2 -1
- {blosc2-3.2.1 → blosc2-3.3.0}/README.rst +1 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/RELEASE_NOTES.md +18 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/05.persistent-reductions.ipynb +9 -9
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/python-blosc2.rst +1 -1
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/linear_algebra.rst +1 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/pyproject.toml +1 -1
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/__init__.py +1 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/ndarray.py +160 -3
- blosc2-3.3.0/src/blosc2/version.py +1 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_matmul.py +42 -3
- blosc2-3.3.0/tests/ndarray/test_slice.py +93 -0
- blosc2-3.3.0/tests/ndarray/test_transpose.py +104 -0
- blosc2-3.2.1/src/blosc2/version.py +0 -1
- blosc2-3.2.1/tests/ndarray/test_slice.py +0 -56
- {blosc2-3.2.1 → blosc2-3.3.0}/.gitignore +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/.guix/modules/python-blosc2-package.scm +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/.guix-channel +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/CMakeLists.txt +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/CONTRIBUTING.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/LICENSE.txt +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/README_DEVELOPERS.md +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/RELEASING.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/code_of_conduct.md +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-favicon_32x32.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-favicon_64x64.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-logo_128.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-logo_256.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/css/custom.css +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/conf.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/code-of-conduct.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/contributing.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/index.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/index.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/installation.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/overview.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/01.ndarray-basics.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/02.lazyarray-expressions.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/03.lazyarray-udf.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/04.reductions.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/06.remote_proxy.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/07.schunk-basics.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/08.schunk-slicing_and_beyond.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/10.ucodecs-ufilters.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/11.prefilters.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/12.postfilters.ipynb +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/blosc2-pipeline.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/blosc2-pipeline.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/lazyexpr-broadcast.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/3D-cube-plane.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/3D-cube.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/memory-access-2D-x.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/memory-access-2D-y.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/remote_proxy.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/backward.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/backward.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/forward.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/forward.svg +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/index.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/array_operations.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__getitem__.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__init__.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__len__.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__setitem__.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.append_data.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.decompress_chunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.delete_chunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.fill_special.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.filler.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.get_chunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.get_slice.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.insert_chunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.insert_data.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.iterchunks.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.iterchunks_info.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.postfilter.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.prefilter.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.remove_postfilter.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.remove_prefilter.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.to_cframe.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.update_chunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.update_data.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/c2array.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/classes.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/decorators.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/index.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/lazy_functions.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/lazyarray.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/low_level.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/ndarray.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/ndfield.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxy.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxyndsource.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxysource.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/reduction_functions.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/save_load.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/schunk.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/storage.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/utilities.rst +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/doc/release_notes/index.md +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/btune.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/compress2_decompress2.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/compress_decompress.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/filler.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/gil.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/mmap-rw.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/arange-constructor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/asarray_.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/broadcast_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/buffer.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/bytedelta_filter.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/c2array_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_fields.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_udf_numba.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_where.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/copy_.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/empty_.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/eye-constructor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/filter_sort_fields.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/formats.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/fromiter-constructor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/general_expressions.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/getitem.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/iterchunks_info.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-numpy-funcs.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-reduc.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/linspace-constructor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/lists-vs-bools-idx.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/meta.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/ndarray_copy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/ndmean.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/persistency.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/proxy-carray.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/proxy-ndarray.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_and_enlarge.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_expr_save.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_string_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/resize_.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/work_with_numpy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/zfp_codec.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/pack_array.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/pack_tensor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter1.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter2.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter3.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/prefilter.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/save_tensor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/schunk.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/schunk_roundtrip.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ucodecs.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/ufilters.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/examples/vlmeta.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/generate_version.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/guix.scm +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/Complete-Write-Read-B2ND.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/M1-i386-vs-arm64-pack.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/M1-i386-vs-arm64-unpack.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/Read-Partial-Slices-B2ND.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/b2nd-2level-parts.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/eval-expr-full-mem-M2.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/eval-expr-scarce-mem-M2.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-dask-large.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-dask-small.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-expr-large.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-expr.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/linspace-compress.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/linspace-decompress.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/pack-array-cratios.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/reduc-float64-amd.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/images/reduc-float64-log-amd.png +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/pytest.ini +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/blosc2_ext.pyx +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/c2array.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/core.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/helpers.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/info.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/lazyexpr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/proxy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/schunk.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/storage.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/conftest.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_auto_parts.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_buffer.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_reductions.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_udf.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_copy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_empty.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_evaluate.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_full.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_get_slice_nchunks.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_getitem.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_iterchunks_info.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_jit.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyexpr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyexpr_fields.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyudf.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lossy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_metalayers.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_mode.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_nans.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_ndarray.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_numpy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_persistency.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy_c2array.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy_expr.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_reductions.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_resize.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_setitem.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_squeeze.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_struct_dtype.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_zeros.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_bytes_array.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_comp_info.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compress2.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compression_parameters.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compressors.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_decompress.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_iterchunks.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_mmap.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_open.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_open_c2array.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_pathlib.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_postfilters.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_prefilters.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_proxy_schunk.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_python_blosc.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_constructor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_delete.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_get_slice.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_get_slice_nchunks.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_insert.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_set_slice.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_update.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_storage.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_tensor.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_ucodecs.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_ufilters.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_vlmeta.py +0 -0
- {blosc2-3.2.1 → blosc2-3.3.0}/update_version.py +0 -0
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
Announcing Python-Blosc2 3.
|
|
1
|
+
Announcing Python-Blosc2 3.3.0
|
|
2
2
|
==============================
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
We are introducing a new blosc2.transpose() function for natively transposing
|
|
5
|
+
2D NDArray instances and a fast path for NDArray.slice() that delivers up to
|
|
6
|
+
40x speedup when slices align with underlying chunks. Documentation has also
|
|
7
|
+
been improved with several edits throughout.
|
|
8
8
|
|
|
9
|
-
See
|
|
10
|
-
See benchmarks at: https://github.com/Blosc/python-blosc2/blob/main/bench/ndarray/jit-numpy-funcs.py
|
|
11
|
-
|
|
12
|
-
We have also improved the performance of constructors like ``blosc2.linspace()``
|
|
13
|
-
or ``blosc2.arange()`` by a factor of up to 3x for large arrays.
|
|
9
|
+
See benchmarks at: https://github.com/Blosc/python-blosc2/blob/main/bench/ndarray/aligned_chunks.py
|
|
14
10
|
|
|
15
11
|
You can think of Python-Blosc2 3.x as an extension of NumPy/numexpr that:
|
|
16
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: blosc2
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: A fast & compressed ndarray library with a flexible compute engine.
|
|
5
5
|
Author-Email: Blosc Development Team <blosc@blosc.org>
|
|
6
6
|
Maintainer-Email: Blosc Development Team <blosc@blosc.org>
|
|
@@ -166,6 +166,7 @@ to the core development of the Blosc2 library:
|
|
|
166
166
|
- Juan David Ibáñez
|
|
167
167
|
- Ivan Vilata i Balaguer
|
|
168
168
|
- Oumaima Ech.Chdig
|
|
169
|
+
- Ricardo Sales Piquer
|
|
169
170
|
|
|
170
171
|
In addition, other people have participated to the project in different
|
|
171
172
|
aspects:
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Release notes
|
|
2
2
|
|
|
3
|
+
## Changes from 3.2.1 to 3.3.0
|
|
4
|
+
|
|
5
|
+
* New `blosc2.transpose()` function for transposing 2D NDArray instances
|
|
6
|
+
natively. See PR #375 and docs at
|
|
7
|
+
https://www.blosc.org/python-blosc2/reference/autofiles/operations_with_arrays/blosc2.transpose.html#blosc2.transpose
|
|
8
|
+
Thanks to Ricardo Sales Piquer (@ricardosp4) for the implementation.
|
|
9
|
+
|
|
10
|
+
* New fast path for `NDArray.slice()` for getting slices that are aligned with
|
|
11
|
+
underlying chunks. This is a common operation when working with NDArray
|
|
12
|
+
instances, and now it is up to 40x faster in our benchmarks (see PR #380).
|
|
13
|
+
|
|
14
|
+
* Returned `NDArray` object in `NDarray.slice()` now defaults to original
|
|
15
|
+
codec/clevel/filters. The previous behavior was to use the default
|
|
16
|
+
codec/clevel/filters. See PR #378. Thanks to Luke Shaw (@lshaw8317).
|
|
17
|
+
|
|
18
|
+
* Several English edits in the documentation. Thanks to Luke Shaw (@lshaw8317)
|
|
19
|
+
for his help in this area.
|
|
20
|
+
|
|
3
21
|
## Changes from 3.2.0 to 3.2.1
|
|
4
22
|
|
|
5
23
|
* The array containers are now using the `__array_interface__` protocol to
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"source": [
|
|
26
26
|
"## Operands as arrays of different shape\n",
|
|
27
27
|
"\n",
|
|
28
|
-
"We will now create the operands, using different shape for each of them,
|
|
28
|
+
"We will now create the operands, using a different shape for each of them, in order to flex the broadcasting capabilities of lazy expressions."
|
|
29
29
|
]
|
|
30
30
|
},
|
|
31
31
|
{
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"source": [
|
|
78
78
|
"## Creating, saving and loading a lazy expression\n",
|
|
79
79
|
"\n",
|
|
80
|
-
"First, let's build a string expression that sums the contents of array `a` and
|
|
80
|
+
"First, let's build a string expression that sums the contents of array `a` and performs a multiplication with `b` and `c`. In this context, creating a string version of the expression is critical; otherwise, reductions will be computed eagerly.\n",
|
|
81
81
|
"\n",
|
|
82
82
|
"Let's see how this works."
|
|
83
83
|
]
|
|
@@ -110,13 +110,13 @@
|
|
|
110
110
|
"id": "6226bf8d46ac7c32",
|
|
111
111
|
"metadata": {},
|
|
112
112
|
"source": [
|
|
113
|
-
"In the code above, an expression combining the arrays `a`, `b`, and `c` is expressed in string form: `a.sum() + b ∗ c`. Then, one builds a lazy expression and
|
|
113
|
+
"In the code above, an expression combining the arrays `a`, `b`, and `c` is expressed in string form: `a.sum() + b ∗ c`. Then, one builds a lazy expression and saves it for later. The chosen expression illustrates how operations automatically adapt to the dimensions of the operands via broadcasting.\n",
|
|
114
114
|
"\n",
|
|
115
|
-
"**Broadcasting** allows arrays of different shapes (dimensions) to align for mathematical operations, such as addition or multiplication, without the need to enlarge operands by replicating data. The main idea is that smaller dimensions are \"stretched\" to larger dimensions in such a way that
|
|
115
|
+
"**Broadcasting** allows arrays of different shapes (dimensions) to align for mathematical operations, such as addition or multiplication, without the need to enlarge operands by replicating data. The main idea is that smaller dimensions are \"stretched\" to larger dimensions in such a way that the operation may be performed consistently.\n",
|
|
116
116
|
"\n",
|
|
117
117
|
"<img src=\"images/lazyexpr-broadcast.png\" width=\"1000\"/>\n",
|
|
118
118
|
"\n",
|
|
119
|
-
"See [NumPy docs on broadcasting](https://numpy.org/doc/stable/user/basics.broadcasting.html) for more information.\n",
|
|
119
|
+
"See the [NumPy docs on broadcasting](https://numpy.org/doc/stable/user/basics.broadcasting.html) for more information.\n",
|
|
120
120
|
"\n",
|
|
121
121
|
"Now that we have saved the expression, we can open and compute it to obtain the result. Let's see how this is done."
|
|
122
122
|
]
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"id": "362cfd5eb88b9bb6",
|
|
168
168
|
"metadata": {},
|
|
169
169
|
"source": [
|
|
170
|
-
"As we can observe when printing the lazy expression and its shape, the time required to get the `shape` is significantly shorter. This is because `lazy_expression.shape` does not need to compute all the elements of the expression; instead, it only accesses the **metadata** of the operands, from which it
|
|
170
|
+
"As we can observe when printing the lazy expression and its shape, the time required to get the `shape` is significantly shorter. This is because `lazy_expression.shape` does not need to compute all the elements of the expression; instead, it only accesses the **metadata** of the operands, from which it infers the necessary information about the dimensions and type of the result.\n",
|
|
171
171
|
"\n",
|
|
172
172
|
"Thanks to this metadata, if we know the dimensions of the arrays involved in the operation (such as in the case of `a.sum() + b * c`), Blosc2 can **quickly infer the resulting shape** without performing intensive calculations. This allows for fast access to structural information (like the `shape` and `dtype`) without operating on the actual data.\n",
|
|
173
173
|
"\n",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"source": [
|
|
182
182
|
"## Resizing operands of persisted lazy expressions\n",
|
|
183
183
|
"\n",
|
|
184
|
-
"In this section, we will see how persisted lazy expressions automatically adapt to changes in the dimensions and values of the original operands, such as arrays `a` and `b`."
|
|
184
|
+
"In this section, we will see how persisted lazy expressions automatically adapt to changes in the dimensions and values of the original operands, such as the arrays `a` and `b`."
|
|
185
185
|
]
|
|
186
186
|
},
|
|
187
187
|
{
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
"id": "d82492bf518c5a39",
|
|
234
234
|
"metadata": {},
|
|
235
235
|
"source": [
|
|
236
|
-
"After increasing the dimensions of the original arrays by modifying the values of `a` and `b`, the lazy expression is reopened. This step is crucial as it allows us to observe how the computation of the expression adapts to the new dimensions. Upon re-opening the expression, we can check that the results now accurately reflect these changes in the dimensions of the array operands. Moreover, see how obtaining the structural information (the `shape`) of the expression is a quick process, requiring only a fraction of the time it takes for the complete computation.\n",
|
|
236
|
+
"After increasing the dimensions of the original arrays by modifying the values of `a` and `b`, the lazy expression is reopened. This step is crucial as it allows us to observe how the computation of the expression adapts to the new dimensions. Upon re-opening the expression, we can check that the results now accurately reflect these changes in the dimensions of the array operands. Moreover, see how obtaining the updated structural information (the `shape`) of the expression is a quick process, requiring only a fraction of the time it takes for the complete computation.\n",
|
|
237
237
|
"\n",
|
|
238
238
|
"This behavior highlights the ability of lazy expressions to adjust to operands using **metadata**, eliminating the need to re-compute each operation from the beginning. Thanks to this approach, notable flexibility and efficiency are achieved in handling arrays of various shapes and sizes."
|
|
239
239
|
]
|
|
@@ -249,7 +249,7 @@
|
|
|
249
249
|
"\n",
|
|
250
250
|
"Also, broadcasting support facilitates working with arrays of different sizes, making the process more powerful and intuitive.\n",
|
|
251
251
|
"\n",
|
|
252
|
-
"Understanding how operations are managed in this context enables developers and data scientists to make the most of reduction and broadcasting capabilities, thereby enhancing the efficiency and effectiveness of their analyses and calculations. The beauty of lazy expressions lies in
|
|
252
|
+
"Understanding how operations are managed in this context enables developers and data scientists to make the most of reduction and broadcasting capabilities, thereby enhancing the efficiency and effectiveness of their analyses and calculations. The beauty of lazy expressions lies in their ability to simplify the complex and empower our creativity!"
|
|
253
253
|
]
|
|
254
254
|
},
|
|
255
255
|
{
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<p style="text-align: center; color: black; background-color: rgba(230, 169, 9, 0.65);">
|
|
8
8
|
<a href="https://github.com/Blosc/python-blosc2/blob/main/RELEASE_NOTES.md"
|
|
9
|
-
style="font-size: 1.5em;">Version 3.2.
|
|
9
|
+
style="font-size: 1.5em;">Version 3.2.1 released on 2025-04-27!</a>
|
|
10
10
|
<span style="display: inline-block; width: 20px;"></span>
|
|
11
11
|
<span style="font-family: monospace;">pip install blosc2 -U</span>
|
|
12
12
|
</p>
|
|
@@ -13,6 +13,7 @@ import inspect
|
|
|
13
13
|
import math
|
|
14
14
|
from collections import OrderedDict, namedtuple
|
|
15
15
|
from functools import reduce
|
|
16
|
+
from itertools import product
|
|
16
17
|
from typing import TYPE_CHECKING, Any, NamedTuple
|
|
17
18
|
|
|
18
19
|
from numpy.exceptions import ComplexWarning
|
|
@@ -1029,6 +1030,82 @@ def extract_values(arr, indices: np.ndarray[np.int_], max_cache_size: int = 10)
|
|
|
1029
1030
|
return extracted_values
|
|
1030
1031
|
|
|
1031
1032
|
|
|
1033
|
+
def detect_aligned_chunks( # noqa: C901
|
|
1034
|
+
key: Sequence[slice], shape: Sequence[int], chunks: Sequence[int], consecutive: bool = False
|
|
1035
|
+
) -> list[int]:
|
|
1036
|
+
"""
|
|
1037
|
+
Detect whether a multidimensional slice is aligned with chunk boundaries.
|
|
1038
|
+
|
|
1039
|
+
Parameters
|
|
1040
|
+
----------
|
|
1041
|
+
key : Sequence of slice
|
|
1042
|
+
The multidimensional slice to check.
|
|
1043
|
+
shape : Sequence of int
|
|
1044
|
+
Shape of the NDArray.
|
|
1045
|
+
chunks : Sequence of int
|
|
1046
|
+
Chunk shape of the NDArray.
|
|
1047
|
+
consecutive : bool, default=False
|
|
1048
|
+
If True, check if the chunks are consecutive in storage order.
|
|
1049
|
+
If False, only check for chunk boundary alignment.
|
|
1050
|
+
|
|
1051
|
+
Returns
|
|
1052
|
+
-------
|
|
1053
|
+
list[int]
|
|
1054
|
+
List of chunk indices (in C-order) that the slice overlaps with.
|
|
1055
|
+
If the slice isn't aligned with chunk boundaries, returns an empty list.
|
|
1056
|
+
If consecutive=True and chunks aren't consecutive, returns an empty list.
|
|
1057
|
+
"""
|
|
1058
|
+
if len(key) != len(shape):
|
|
1059
|
+
return []
|
|
1060
|
+
|
|
1061
|
+
# Check that slice boundaries are exact multiple of chunk boundaries
|
|
1062
|
+
for i, s in enumerate(key):
|
|
1063
|
+
if s.start is not None and s.start % chunks[i] != 0:
|
|
1064
|
+
return []
|
|
1065
|
+
if s.stop is not None and s.stop % chunks[i] != 0:
|
|
1066
|
+
return []
|
|
1067
|
+
|
|
1068
|
+
# Parse the slice boundaries
|
|
1069
|
+
start_indices = []
|
|
1070
|
+
end_indices = []
|
|
1071
|
+
n_chunks = []
|
|
1072
|
+
|
|
1073
|
+
for i, s in enumerate(key):
|
|
1074
|
+
start = s.start if s.start is not None else 0
|
|
1075
|
+
stop = s.stop if s.stop is not None else shape[i]
|
|
1076
|
+
chunk_size = chunks[i]
|
|
1077
|
+
start_idx = start // chunk_size
|
|
1078
|
+
end_idx = stop // chunk_size
|
|
1079
|
+
start_indices.append(start_idx)
|
|
1080
|
+
end_indices.append(end_idx)
|
|
1081
|
+
n_chunks.append(shape[i] // chunk_size)
|
|
1082
|
+
|
|
1083
|
+
# Get all chunk combinations in the slice
|
|
1084
|
+
indices = [range(start, end) for start, end in zip(start_indices, end_indices, strict=False)]
|
|
1085
|
+
result = []
|
|
1086
|
+
|
|
1087
|
+
for combination in product(*indices):
|
|
1088
|
+
flat_index = 0
|
|
1089
|
+
multiplier = 1
|
|
1090
|
+
for idx, n in zip(reversed(range(len(n_chunks))), reversed(n_chunks), strict=False):
|
|
1091
|
+
flat_index += combination[idx] * multiplier
|
|
1092
|
+
multiplier *= n
|
|
1093
|
+
result.append(flat_index)
|
|
1094
|
+
|
|
1095
|
+
# Check if chunks are consecutive if requested
|
|
1096
|
+
if consecutive and result:
|
|
1097
|
+
sorted_result = sorted(result)
|
|
1098
|
+
if sorted_result[-1] - sorted_result[0] + 1 != len(sorted_result):
|
|
1099
|
+
return []
|
|
1100
|
+
|
|
1101
|
+
# The array of indices must be consecutive
|
|
1102
|
+
for i in range(len(sorted_result) - 1):
|
|
1103
|
+
if sorted_result[i + 1] - sorted_result[i] != 1:
|
|
1104
|
+
return []
|
|
1105
|
+
|
|
1106
|
+
return sorted(result)
|
|
1107
|
+
|
|
1108
|
+
|
|
1032
1109
|
class NDOuterIterator:
|
|
1033
1110
|
def __init__(self, ndarray: NDArray | NDField, cache_size=1):
|
|
1034
1111
|
self.ndarray = ndarray
|
|
@@ -1836,10 +1913,45 @@ class NDArray(blosc2_ext.NDArray, Operand):
|
|
|
1836
1913
|
(4, 10)
|
|
1837
1914
|
>>> print(type(c))
|
|
1838
1915
|
<class 'blosc2.ndarray.NDArray'>
|
|
1916
|
+
|
|
1917
|
+
Notes
|
|
1918
|
+
-----
|
|
1919
|
+
There is a fast path for slices that are aligned with underlying chunks.
|
|
1920
|
+
Aligned means that the slices are made entirely with complete chunks.
|
|
1839
1921
|
"""
|
|
1840
|
-
|
|
1922
|
+
if "cparams" not in kwargs:
|
|
1923
|
+
kwargs["cparams"] = {
|
|
1924
|
+
"codec": self.cparams.codec,
|
|
1925
|
+
"clevel": self.cparams.clevel,
|
|
1926
|
+
"filters": self.cparams.filters,
|
|
1927
|
+
}
|
|
1928
|
+
kwargs = _check_ndarray_kwargs(**kwargs) # sets cparams to defaults
|
|
1841
1929
|
key, mask = process_key(key, self.shape)
|
|
1842
1930
|
start, stop, step = get_ndarray_start_stop(self.ndim, key, self.shape)
|
|
1931
|
+
|
|
1932
|
+
# Fast path for slices made with consecutive chunks
|
|
1933
|
+
if step == (1,) * self.ndim:
|
|
1934
|
+
aligned_chunks = detect_aligned_chunks(key, self.shape, self.chunks, consecutive=False)
|
|
1935
|
+
if aligned_chunks:
|
|
1936
|
+
# print("Aligned chunks detected", aligned_chunks)
|
|
1937
|
+
# Create a new ndarray for the key slice
|
|
1938
|
+
new_shape = [
|
|
1939
|
+
sp - st for sp, st in zip([k.stop for k in key], [k.start for k in key], strict=False)
|
|
1940
|
+
]
|
|
1941
|
+
newarr = blosc2.empty(
|
|
1942
|
+
shape=new_shape,
|
|
1943
|
+
dtype=self.dtype,
|
|
1944
|
+
chunks=self.chunks,
|
|
1945
|
+
blocks=self.blocks,
|
|
1946
|
+
**kwargs,
|
|
1947
|
+
)
|
|
1948
|
+
# Get the chunks from the original array and update the new array
|
|
1949
|
+
# No need for chunks to decompress and compress again
|
|
1950
|
+
for order, nchunk in enumerate(aligned_chunks):
|
|
1951
|
+
chunk = self.schunk.get_chunk(nchunk)
|
|
1952
|
+
newarr.schunk.update_chunk(order, chunk)
|
|
1953
|
+
return newarr
|
|
1954
|
+
|
|
1843
1955
|
key = (start, stop)
|
|
1844
1956
|
ndslice = super().get_slice(key, mask, **kwargs)
|
|
1845
1957
|
|
|
@@ -3665,9 +3777,9 @@ def matmul(x1: NDArray, x2: NDArray, **kwargs: Any) -> NDArray:
|
|
|
3665
3777
|
|
|
3666
3778
|
Parameters
|
|
3667
3779
|
----------
|
|
3668
|
-
x1:
|
|
3780
|
+
x1: :ref:`NDArray`
|
|
3669
3781
|
The first input array.
|
|
3670
|
-
x2:
|
|
3782
|
+
x2: :ref:`NDArray`
|
|
3671
3783
|
The second input array.
|
|
3672
3784
|
kwargs: Any, optional
|
|
3673
3785
|
Keyword arguments that are supported by the :func:`empty` constructor.
|
|
@@ -3766,6 +3878,51 @@ def matmul(x1: NDArray, x2: NDArray, **kwargs: Any) -> NDArray:
|
|
|
3766
3878
|
return result.squeeze()
|
|
3767
3879
|
|
|
3768
3880
|
|
|
3881
|
+
def transpose(x, **kwargs: Any) -> NDArray:
|
|
3882
|
+
"""
|
|
3883
|
+
Returns a Blosc2 NDArray with axes transposed.
|
|
3884
|
+
|
|
3885
|
+
Only 2D arrays are supported for now. Other dimensions raise an error.
|
|
3886
|
+
|
|
3887
|
+
Parameters
|
|
3888
|
+
----------
|
|
3889
|
+
x: :ref:`NDArray`
|
|
3890
|
+
The input array.
|
|
3891
|
+
kwargs: Any, optional
|
|
3892
|
+
Keyword arguments that are supported by the :func:`empty` constructor.
|
|
3893
|
+
|
|
3894
|
+
Returns
|
|
3895
|
+
-------
|
|
3896
|
+
out: :ref:`NDArray`
|
|
3897
|
+
The Blosc2 NDArray with axes transposed.
|
|
3898
|
+
|
|
3899
|
+
References
|
|
3900
|
+
----------
|
|
3901
|
+
`numpy.transpose <https://numpy.org/doc/2.2/reference/generated/numpy.transpose.html>`_
|
|
3902
|
+
"""
|
|
3903
|
+
|
|
3904
|
+
# If arguments are dimension < 2 they are returned
|
|
3905
|
+
if np.isscalar(x) or x.ndim < 2:
|
|
3906
|
+
return x
|
|
3907
|
+
|
|
3908
|
+
# Validate arguments are dimension 2
|
|
3909
|
+
if x.ndim > 2:
|
|
3910
|
+
raise ValueError("Transposing arrays with dimension greater than 2 is not supported yet.")
|
|
3911
|
+
|
|
3912
|
+
n, m = x.shape
|
|
3913
|
+
p, q = x.chunks
|
|
3914
|
+
result = blosc2.zeros((m, n), dtype=np.result_type(x), **kwargs)
|
|
3915
|
+
|
|
3916
|
+
for row in range(0, n, p):
|
|
3917
|
+
row_end = (row + p) if (row + p) < n else n
|
|
3918
|
+
for col in range(0, m, q):
|
|
3919
|
+
col_end = (col + q) if (col + q) < m else m
|
|
3920
|
+
aux = x[row:row_end, col:col_end]
|
|
3921
|
+
result[col:col_end, row:row_end] = np.transpose(aux).copy()
|
|
3922
|
+
|
|
3923
|
+
return result
|
|
3924
|
+
|
|
3925
|
+
|
|
3769
3926
|
# Class for dealing with fields in an NDArray
|
|
3770
3927
|
# This will allow to access fields by name in the dtype of the NDArray
|
|
3771
3928
|
class NDField(Operand):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "3.3.0"
|
|
@@ -21,11 +21,50 @@ import blosc2
|
|
|
21
21
|
)
|
|
22
22
|
@pytest.mark.parametrize(
|
|
23
23
|
"dtype",
|
|
24
|
-
{np.float32, np.float64
|
|
24
|
+
{np.float32, np.float64},
|
|
25
25
|
)
|
|
26
26
|
def test_matmul(ashape, achunks, ablocks, bshape, bchunks, bblocks, dtype):
|
|
27
|
-
a = blosc2.linspace(0,
|
|
28
|
-
b = blosc2.linspace(0,
|
|
27
|
+
a = blosc2.linspace(0, 1, dtype=dtype, shape=ashape, chunks=achunks, blocks=ablocks)
|
|
28
|
+
b = blosc2.linspace(0, 1, dtype=dtype, shape=bshape, chunks=bchunks, blocks=bblocks)
|
|
29
|
+
c = blosc2.matmul(a, b)
|
|
30
|
+
|
|
31
|
+
na = a[:]
|
|
32
|
+
nb = b[:]
|
|
33
|
+
nc = np.matmul(na, nb)
|
|
34
|
+
|
|
35
|
+
np.testing.assert_allclose(c, nc, rtol=1e-6)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@pytest.mark.parametrize(
|
|
39
|
+
("ashape", "achunks", "ablocks"),
|
|
40
|
+
{
|
|
41
|
+
((12, 10), (7, 5), (3, 3)),
|
|
42
|
+
((10,), (9,), (7,)),
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
@pytest.mark.parametrize(
|
|
46
|
+
("bshape", "bchunks", "bblocks"),
|
|
47
|
+
{
|
|
48
|
+
((10,), (4,), (2,)),
|
|
49
|
+
((10, 5), (3, 4), (1, 3)),
|
|
50
|
+
((10, 12), (2, 4), (1, 2)),
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
@pytest.mark.parametrize(
|
|
54
|
+
"dtype",
|
|
55
|
+
{np.complex64, np.complex128},
|
|
56
|
+
)
|
|
57
|
+
def test_complex(ashape, achunks, ablocks, bshape, bchunks, bblocks, dtype):
|
|
58
|
+
real_part = blosc2.linspace(0, 1, shape=ashape, chunks=achunks, blocks=ablocks, dtype=dtype)
|
|
59
|
+
imag_part = blosc2.linspace(0, 1, shape=ashape, chunks=achunks, blocks=ablocks, dtype=dtype)
|
|
60
|
+
complex_matrix_a = real_part + 1j * imag_part
|
|
61
|
+
a = blosc2.asarray(complex_matrix_a)
|
|
62
|
+
|
|
63
|
+
real_part = blosc2.linspace(1, 2, shape=bshape, chunks=bchunks, blocks=bblocks, dtype=dtype)
|
|
64
|
+
imag_part = blosc2.linspace(1, 2, shape=bshape, chunks=bchunks, blocks=bblocks, dtype=dtype)
|
|
65
|
+
complex_matrix_b = real_part + 1j * imag_part
|
|
66
|
+
b = blosc2.asarray(complex_matrix_b)
|
|
67
|
+
|
|
29
68
|
c = blosc2.matmul(a, b)
|
|
30
69
|
|
|
31
70
|
na = a[:]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#######################################################################
|
|
2
|
+
# Copyright (c) 2019-present, Blosc Development Team <blosc@blosc.org>
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
#
|
|
5
|
+
# This source code is licensed under a BSD-style license (found in the
|
|
6
|
+
# LICENSE file in the root directory of this source tree)
|
|
7
|
+
#######################################################################
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
import blosc2
|
|
13
|
+
|
|
14
|
+
argnames = "shape, chunks, blocks, slices, dtype"
|
|
15
|
+
argvalues = [
|
|
16
|
+
([456], [258], [73], slice(0, 1), np.int32),
|
|
17
|
+
([77, 134, 13], [31, 13, 5], [7, 8, 3], (slice(3, 7), slice(50, 100), 7), np.float64),
|
|
18
|
+
([12, 13, 14, 15, 16], [5, 5, 5, 5, 5], [2, 2, 2, 2, 2], (slice(1, 3), ..., slice(3, 6)), np.float32),
|
|
19
|
+
# Consecutive slices
|
|
20
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 10), slice(0, 100), slice(0, 300)), np.int32),
|
|
21
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5), slice(0, 100), slice(0, 300)), np.int32),
|
|
22
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5), slice(0, 25), slice(0, 200)), np.int32),
|
|
23
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5), slice(0, 25), slice(0, 50)), np.int32),
|
|
24
|
+
# Aligned slices
|
|
25
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(10, 50), slice(25, 100), slice(50, 300)), np.int32),
|
|
26
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(10, 40), slice(25, 75), slice(100, 200)), np.int32),
|
|
27
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(20, 35), slice(50, 75), slice(100, 300)), np.int32),
|
|
28
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(20, 25), slice(25, 50), slice(50, 100)), np.int32),
|
|
29
|
+
# Non-consecutive slices
|
|
30
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 10), slice(0, 100), slice(0, 300 - 1)), np.int32),
|
|
31
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5), slice(0, 100 - 1), slice(0, 300)), np.int32),
|
|
32
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5 - 1), slice(0, 25), slice(0, 200)), np.int32),
|
|
33
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(0, 5), slice(0, 25), slice(0, 50 - 1)), np.int32),
|
|
34
|
+
# Non-aligned slices
|
|
35
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(10, 50 - 1), slice(25, 100), slice(50, 300)), np.int32),
|
|
36
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(10, 40), slice(25, 75 - 1), slice(100, 200)), np.int32),
|
|
37
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(20, 35), slice(50, 75), slice(100, 300 - 1)), np.int32),
|
|
38
|
+
((10, 100, 300), (5, 25, 50), (1, 5, 10), (slice(20 + 1, 25), slice(25, 50), slice(50, 100)), np.int32),
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.parametrize(argnames, argvalues)
|
|
43
|
+
def test_slice(shape, chunks, blocks, slices, dtype):
|
|
44
|
+
size = int(np.prod(shape))
|
|
45
|
+
nparray = np.arange(size, dtype=dtype).reshape(shape)
|
|
46
|
+
a = blosc2.asarray(nparray, chunks=chunks, blocks=blocks)
|
|
47
|
+
b = a.slice(slices)
|
|
48
|
+
np_slice = a[slices]
|
|
49
|
+
assert b.shape == np_slice.shape
|
|
50
|
+
np.testing.assert_almost_equal(b[...], np_slice)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@pytest.mark.parametrize(argnames, argvalues)
|
|
54
|
+
def test_slice_codec_and_clevel(shape, chunks, blocks, slices, dtype):
|
|
55
|
+
size = int(np.prod(shape))
|
|
56
|
+
nparray = np.arange(size, dtype=dtype).reshape(shape)
|
|
57
|
+
a = blosc2.asarray(
|
|
58
|
+
nparray,
|
|
59
|
+
chunks=chunks,
|
|
60
|
+
blocks=blocks,
|
|
61
|
+
cparams={"codec": blosc2.Codec.LZ4, "clevel": 6, "filters": [blosc2.Filter.BITSHUFFLE]},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
b = a.slice(slices)
|
|
65
|
+
assert b.cparams.codec == a.cparams.codec
|
|
66
|
+
assert b.cparams.clevel == a.cparams.clevel
|
|
67
|
+
assert b.cparams.filters == a.cparams.filters
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
argnames = "shape, chunks, blocks, slices, dtype, chunks2, blocks2"
|
|
71
|
+
argvalues = [
|
|
72
|
+
([456], [258], [73], slice(0, 1), np.int32, [1], [1]),
|
|
73
|
+
([77, 134, 13], [31, 13, 5], [7, 8, 3], (slice(3, 7), slice(50, 100), 7), np.float64, [3, 50], None),
|
|
74
|
+
(
|
|
75
|
+
[12, 13, 14, 15, 16],
|
|
76
|
+
[5, 5, 5, 5, 5],
|
|
77
|
+
[2, 2, 2, 2, 2],
|
|
78
|
+
(slice(1, 3), ..., slice(3, 6)),
|
|
79
|
+
np.float32,
|
|
80
|
+
None,
|
|
81
|
+
[2, 3, 3, 5, 2],
|
|
82
|
+
),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest.mark.parametrize(argnames, argvalues)
|
|
87
|
+
def test_slice_chunks_blocks(shape, chunks, blocks, chunks2, blocks2, slices, dtype):
|
|
88
|
+
size = int(np.prod(shape))
|
|
89
|
+
nparray = np.arange(size, dtype=dtype).reshape(shape)
|
|
90
|
+
a = blosc2.asarray(nparray, chunks=chunks, blocks=blocks)
|
|
91
|
+
b = a.slice(slices, chunks=chunks2, blocks=blocks2)
|
|
92
|
+
np_slice = a[slices]
|
|
93
|
+
np.testing.assert_almost_equal(b[...], np_slice)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import pytest
|
|
3
|
+
|
|
4
|
+
import blosc2
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture(
|
|
8
|
+
params=[
|
|
9
|
+
((3, 3), (2, 2), (1, 1)),
|
|
10
|
+
((12, 11), (7, 5), (6, 2)),
|
|
11
|
+
((1, 5), (1, 4), (1, 3)),
|
|
12
|
+
((51, 603), (22, 99), (13, 29)),
|
|
13
|
+
((10,), (5,), None),
|
|
14
|
+
((31,), (14,), (9,)),
|
|
15
|
+
]
|
|
16
|
+
)
|
|
17
|
+
def shape_chunks_blocks(request):
|
|
18
|
+
return request.param
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.mark.parametrize(
|
|
22
|
+
"dtype",
|
|
23
|
+
{np.int32, np.int64, np.float32, np.float64},
|
|
24
|
+
)
|
|
25
|
+
def test_transpose(shape_chunks_blocks, dtype):
|
|
26
|
+
shape, chunks, blocks = shape_chunks_blocks
|
|
27
|
+
a = blosc2.linspace(0, 1, shape=shape, chunks=chunks, blocks=blocks, dtype=dtype)
|
|
28
|
+
at = blosc2.transpose(a)
|
|
29
|
+
|
|
30
|
+
na = a[:]
|
|
31
|
+
nat = np.transpose(na)
|
|
32
|
+
|
|
33
|
+
np.testing.assert_allclose(at, nat)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.parametrize(
|
|
37
|
+
"dtype",
|
|
38
|
+
{np.complex64, np.complex128},
|
|
39
|
+
)
|
|
40
|
+
def test_complex(shape_chunks_blocks, dtype):
|
|
41
|
+
shape, chunks, blocks = shape_chunks_blocks
|
|
42
|
+
real_part = blosc2.linspace(0, 1, shape=shape, chunks=chunks, blocks=blocks, dtype=dtype)
|
|
43
|
+
imag_part = blosc2.linspace(1, 0, shape=shape, chunks=chunks, blocks=blocks, dtype=dtype)
|
|
44
|
+
complex_matrix = real_part + 1j * imag_part
|
|
45
|
+
|
|
46
|
+
a = blosc2.asarray(complex_matrix)
|
|
47
|
+
at = blosc2.transpose(a)
|
|
48
|
+
|
|
49
|
+
na = a[:]
|
|
50
|
+
nat = np.transpose(na)
|
|
51
|
+
|
|
52
|
+
np.testing.assert_allclose(at, nat)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.mark.parametrize(
|
|
56
|
+
"scalar",
|
|
57
|
+
{
|
|
58
|
+
1, # int
|
|
59
|
+
5.1, # float
|
|
60
|
+
1 + 2j, # complex
|
|
61
|
+
np.int8(2), # NumPy int8
|
|
62
|
+
np.int16(3), # NumPy int16
|
|
63
|
+
np.int32(4), # NumPy int32
|
|
64
|
+
np.int64(5), # NumPy int64
|
|
65
|
+
np.float32(5.2), # NumPy float32
|
|
66
|
+
np.float64(5.3), # NumPy float64
|
|
67
|
+
np.complex64(0 + 3j), # NumPy complex64
|
|
68
|
+
np.complex128(2 - 4j), # NumPy complex128
|
|
69
|
+
},
|
|
70
|
+
)
|
|
71
|
+
def test_scalars(scalar):
|
|
72
|
+
at = blosc2.transpose(scalar)
|
|
73
|
+
nat = np.transpose(scalar)
|
|
74
|
+
|
|
75
|
+
np.testing.assert_allclose(at, nat)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@pytest.mark.parametrize(
|
|
79
|
+
"shape",
|
|
80
|
+
[
|
|
81
|
+
(3, 3, 3),
|
|
82
|
+
(12, 10, 10),
|
|
83
|
+
(10, 10, 10, 11),
|
|
84
|
+
(5, 4, 3, 2, 1, 1),
|
|
85
|
+
],
|
|
86
|
+
)
|
|
87
|
+
def test_dims(shape):
|
|
88
|
+
a = blosc2.linspace(0, 1, shape=shape)
|
|
89
|
+
|
|
90
|
+
with pytest.raises(ValueError):
|
|
91
|
+
blosc2.transpose(a)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_disk():
|
|
95
|
+
a = blosc2.linspace(0, 1, shape=(3, 4), urlpath="a_test.b2nd", mode="w")
|
|
96
|
+
c = blosc2.transpose(a, urlpath="c_test.b2nd", mode="w")
|
|
97
|
+
|
|
98
|
+
na = a[:]
|
|
99
|
+
nc = np.transpose(na)
|
|
100
|
+
|
|
101
|
+
np.testing.assert_allclose(c, nc, rtol=1e-6)
|
|
102
|
+
|
|
103
|
+
blosc2.remove_urlpath("a_test.b2nd")
|
|
104
|
+
blosc2.remove_urlpath("c_test.b2nd")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "3.2.1"
|