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.
Files changed (256) hide show
  1. {blosc2-3.2.1 → blosc2-3.3.0}/.pre-commit-config.yaml +1 -1
  2. {blosc2-3.2.1 → blosc2-3.3.0}/ANNOUNCE.rst +6 -10
  3. {blosc2-3.2.1 → blosc2-3.3.0}/PKG-INFO +2 -1
  4. {blosc2-3.2.1 → blosc2-3.3.0}/README.rst +1 -0
  5. {blosc2-3.2.1 → blosc2-3.3.0}/RELEASE_NOTES.md +18 -0
  6. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/05.persistent-reductions.ipynb +9 -9
  7. {blosc2-3.2.1 → blosc2-3.3.0}/doc/python-blosc2.rst +1 -1
  8. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/linear_algebra.rst +1 -0
  9. {blosc2-3.2.1 → blosc2-3.3.0}/pyproject.toml +1 -1
  10. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/__init__.py +1 -0
  11. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/ndarray.py +160 -3
  12. blosc2-3.3.0/src/blosc2/version.py +1 -0
  13. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_matmul.py +42 -3
  14. blosc2-3.3.0/tests/ndarray/test_slice.py +93 -0
  15. blosc2-3.3.0/tests/ndarray/test_transpose.py +104 -0
  16. blosc2-3.2.1/src/blosc2/version.py +0 -1
  17. blosc2-3.2.1/tests/ndarray/test_slice.py +0 -56
  18. {blosc2-3.2.1 → blosc2-3.3.0}/.gitignore +0 -0
  19. {blosc2-3.2.1 → blosc2-3.3.0}/.guix/modules/python-blosc2-package.scm +0 -0
  20. {blosc2-3.2.1 → blosc2-3.3.0}/.guix-channel +0 -0
  21. {blosc2-3.2.1 → blosc2-3.3.0}/CMakeLists.txt +0 -0
  22. {blosc2-3.2.1 → blosc2-3.3.0}/CONTRIBUTING.rst +0 -0
  23. {blosc2-3.2.1 → blosc2-3.3.0}/LICENSE.txt +0 -0
  24. {blosc2-3.2.1 → blosc2-3.3.0}/README_DEVELOPERS.md +0 -0
  25. {blosc2-3.2.1 → blosc2-3.3.0}/RELEASING.rst +0 -0
  26. {blosc2-3.2.1 → blosc2-3.3.0}/code_of_conduct.md +0 -0
  27. {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-favicon_32x32.png +0 -0
  28. {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-favicon_64x64.png +0 -0
  29. {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-logo_128.png +0 -0
  30. {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/blosc-logo_256.png +0 -0
  31. {blosc2-3.2.1 → blosc2-3.3.0}/doc/_static/css/custom.css +0 -0
  32. {blosc2-3.2.1 → blosc2-3.3.0}/doc/conf.py +0 -0
  33. {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/code-of-conduct.rst +0 -0
  34. {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/contributing.rst +0 -0
  35. {blosc2-3.2.1 → blosc2-3.3.0}/doc/development/index.rst +0 -0
  36. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/index.rst +0 -0
  37. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/installation.rst +0 -0
  38. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/overview.rst +0 -0
  39. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/01.ndarray-basics.ipynb +0 -0
  40. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/02.lazyarray-expressions.ipynb +0 -0
  41. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/03.lazyarray-udf.ipynb +0 -0
  42. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/04.reductions.ipynb +0 -0
  43. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/06.remote_proxy.ipynb +0 -0
  44. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/07.schunk-basics.ipynb +0 -0
  45. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/08.schunk-slicing_and_beyond.ipynb +0 -0
  46. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/10.ucodecs-ufilters.ipynb +0 -0
  47. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/11.prefilters.ipynb +0 -0
  48. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/12.postfilters.ipynb +0 -0
  49. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/blosc2-pipeline.png +0 -0
  50. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/blosc2-pipeline.svg +0 -0
  51. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/lazyexpr-broadcast.png +0 -0
  52. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/3D-cube-plane.png +0 -0
  53. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/3D-cube.png +0 -0
  54. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/memory-access-2D-x.png +0 -0
  55. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/reductions/memory-access-2D-y.png +0 -0
  56. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/remote_proxy.png +0 -0
  57. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/backward.png +0 -0
  58. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/backward.svg +0 -0
  59. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.png +0 -0
  60. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.svg +0 -0
  61. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.png +0 -0
  62. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.svg +0 -0
  63. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.png +0 -0
  64. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.svg +0 -0
  65. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.png +0 -0
  66. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.svg +0 -0
  67. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/forward.png +0 -0
  68. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials/images/ucodecs-filters/forward.svg +0 -0
  69. {blosc2-3.2.1 → blosc2-3.3.0}/doc/getting_started/tutorials.rst +0 -0
  70. {blosc2-3.2.1 → blosc2-3.3.0}/doc/index.rst +0 -0
  71. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/array_operations.rst +0 -0
  72. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__getitem__.rst +0 -0
  73. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__init__.rst +0 -0
  74. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__len__.rst +0 -0
  75. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.__setitem__.rst +0 -0
  76. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.append_data.rst +0 -0
  77. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.decompress_chunk.rst +0 -0
  78. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.delete_chunk.rst +0 -0
  79. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.fill_special.rst +0 -0
  80. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.filler.rst +0 -0
  81. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.get_chunk.rst +0 -0
  82. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.get_slice.rst +0 -0
  83. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.insert_chunk.rst +0 -0
  84. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.insert_data.rst +0 -0
  85. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.iterchunks.rst +0 -0
  86. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.iterchunks_info.rst +0 -0
  87. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.postfilter.rst +0 -0
  88. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.prefilter.rst +0 -0
  89. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.remove_postfilter.rst +0 -0
  90. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.remove_prefilter.rst +0 -0
  91. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.to_cframe.rst +0 -0
  92. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.update_chunk.rst +0 -0
  93. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/autofiles/schunk/blosc2.schunk.SChunk.update_data.rst +0 -0
  94. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/c2array.rst +0 -0
  95. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/classes.rst +0 -0
  96. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/decorators.rst +0 -0
  97. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/index.rst +0 -0
  98. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/lazy_functions.rst +0 -0
  99. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/lazyarray.rst +0 -0
  100. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/low_level.rst +0 -0
  101. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/ndarray.rst +0 -0
  102. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/ndfield.rst +0 -0
  103. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxy.rst +0 -0
  104. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxyndsource.rst +0 -0
  105. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/proxysource.rst +0 -0
  106. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/reduction_functions.rst +0 -0
  107. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/save_load.rst +0 -0
  108. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/schunk.rst +0 -0
  109. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/storage.rst +0 -0
  110. {blosc2-3.2.1 → blosc2-3.3.0}/doc/reference/utilities.rst +0 -0
  111. {blosc2-3.2.1 → blosc2-3.3.0}/doc/release_notes/index.md +0 -0
  112. {blosc2-3.2.1 → blosc2-3.3.0}/examples/btune.py +0 -0
  113. {blosc2-3.2.1 → blosc2-3.3.0}/examples/compress2_decompress2.py +0 -0
  114. {blosc2-3.2.1 → blosc2-3.3.0}/examples/compress_decompress.py +0 -0
  115. {blosc2-3.2.1 → blosc2-3.3.0}/examples/filler.py +0 -0
  116. {blosc2-3.2.1 → blosc2-3.3.0}/examples/gil.py +0 -0
  117. {blosc2-3.2.1 → blosc2-3.3.0}/examples/mmap-rw.py +0 -0
  118. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/arange-constructor.py +0 -0
  119. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/asarray_.py +0 -0
  120. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/broadcast_expr.py +0 -0
  121. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/buffer.py +0 -0
  122. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/bytedelta_filter.py +0 -0
  123. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/c2array_expr.py +0 -0
  124. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_expr.py +0 -0
  125. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_fields.py +0 -0
  126. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_udf_numba.py +0 -0
  127. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/compute_where.py +0 -0
  128. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/copy_.py +0 -0
  129. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/empty_.py +0 -0
  130. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/eye-constructor.py +0 -0
  131. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/filter_sort_fields.py +0 -0
  132. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/formats.py +0 -0
  133. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/fromiter-constructor.py +0 -0
  134. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/general_expressions.py +0 -0
  135. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/getitem.py +0 -0
  136. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/iterchunks_info.py +0 -0
  137. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-expr.py +0 -0
  138. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-numpy-funcs.py +0 -0
  139. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/jit-reduc.py +0 -0
  140. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/linspace-constructor.py +0 -0
  141. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/lists-vs-bools-idx.py +0 -0
  142. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/meta.py +0 -0
  143. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/ndarray_copy.py +0 -0
  144. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/ndmean.py +0 -0
  145. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/persistency.py +0 -0
  146. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/proxy-carray.py +0 -0
  147. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/proxy-ndarray.py +0 -0
  148. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_and_enlarge.py +0 -0
  149. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_expr.py +0 -0
  150. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_expr_save.py +0 -0
  151. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/reduce_string_expr.py +0 -0
  152. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/resize_.py +0 -0
  153. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/work_with_numpy.py +0 -0
  154. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ndarray/zfp_codec.py +0 -0
  155. {blosc2-3.2.1 → blosc2-3.3.0}/examples/pack_array.py +0 -0
  156. {blosc2-3.2.1 → blosc2-3.3.0}/examples/pack_tensor.py +0 -0
  157. {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter1.py +0 -0
  158. {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter2.py +0 -0
  159. {blosc2-3.2.1 → blosc2-3.3.0}/examples/postfilter3.py +0 -0
  160. {blosc2-3.2.1 → blosc2-3.3.0}/examples/prefilter.py +0 -0
  161. {blosc2-3.2.1 → blosc2-3.3.0}/examples/save_tensor.py +0 -0
  162. {blosc2-3.2.1 → blosc2-3.3.0}/examples/schunk.py +0 -0
  163. {blosc2-3.2.1 → blosc2-3.3.0}/examples/schunk_roundtrip.py +0 -0
  164. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ucodecs.py +0 -0
  165. {blosc2-3.2.1 → blosc2-3.3.0}/examples/ufilters.py +0 -0
  166. {blosc2-3.2.1 → blosc2-3.3.0}/examples/vlmeta.py +0 -0
  167. {blosc2-3.2.1 → blosc2-3.3.0}/generate_version.py +0 -0
  168. {blosc2-3.2.1 → blosc2-3.3.0}/guix.scm +0 -0
  169. {blosc2-3.2.1 → blosc2-3.3.0}/images/Complete-Write-Read-B2ND.png +0 -0
  170. {blosc2-3.2.1 → blosc2-3.3.0}/images/M1-i386-vs-arm64-pack.png +0 -0
  171. {blosc2-3.2.1 → blosc2-3.3.0}/images/M1-i386-vs-arm64-unpack.png +0 -0
  172. {blosc2-3.2.1 → blosc2-3.3.0}/images/Read-Partial-Slices-B2ND.png +0 -0
  173. {blosc2-3.2.1 → blosc2-3.3.0}/images/b2nd-2level-parts.png +0 -0
  174. {blosc2-3.2.1 → blosc2-3.3.0}/images/eval-expr-full-mem-M2.png +0 -0
  175. {blosc2-3.2.1 → blosc2-3.3.0}/images/eval-expr-scarce-mem-M2.png +0 -0
  176. {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-dask-large.png +0 -0
  177. {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-dask-small.png +0 -0
  178. {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-expr-large.png +0 -0
  179. {blosc2-3.2.1 → blosc2-3.3.0}/images/lazyarray-expr.png +0 -0
  180. {blosc2-3.2.1 → blosc2-3.3.0}/images/linspace-compress.png +0 -0
  181. {blosc2-3.2.1 → blosc2-3.3.0}/images/linspace-decompress.png +0 -0
  182. {blosc2-3.2.1 → blosc2-3.3.0}/images/pack-array-cratios.png +0 -0
  183. {blosc2-3.2.1 → blosc2-3.3.0}/images/reduc-float64-amd.png +0 -0
  184. {blosc2-3.2.1 → blosc2-3.3.0}/images/reduc-float64-log-amd.png +0 -0
  185. {blosc2-3.2.1 → blosc2-3.3.0}/pytest.ini +0 -0
  186. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/blosc2_ext.pyx +0 -0
  187. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/c2array.py +0 -0
  188. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/core.py +0 -0
  189. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/helpers.py +0 -0
  190. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/info.py +0 -0
  191. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/lazyexpr.py +0 -0
  192. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/proxy.py +0 -0
  193. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/schunk.py +0 -0
  194. {blosc2-3.2.1 → blosc2-3.3.0}/src/blosc2/storage.py +0 -0
  195. {blosc2-3.2.1 → blosc2-3.3.0}/tests/conftest.py +0 -0
  196. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_auto_parts.py +0 -0
  197. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_buffer.py +0 -0
  198. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_expr.py +0 -0
  199. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_reductions.py +0 -0
  200. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_c2array_udf.py +0 -0
  201. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_copy.py +0 -0
  202. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_empty.py +0 -0
  203. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_evaluate.py +0 -0
  204. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_full.py +0 -0
  205. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_get_slice_nchunks.py +0 -0
  206. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_getitem.py +0 -0
  207. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_iterchunks_info.py +0 -0
  208. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_jit.py +0 -0
  209. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyexpr.py +0 -0
  210. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyexpr_fields.py +0 -0
  211. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lazyudf.py +0 -0
  212. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_lossy.py +0 -0
  213. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_metalayers.py +0 -0
  214. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_mode.py +0 -0
  215. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_nans.py +0 -0
  216. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_ndarray.py +0 -0
  217. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_numpy.py +0 -0
  218. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_persistency.py +0 -0
  219. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy.py +0 -0
  220. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy_c2array.py +0 -0
  221. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_proxy_expr.py +0 -0
  222. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_reductions.py +0 -0
  223. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_resize.py +0 -0
  224. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_setitem.py +0 -0
  225. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_squeeze.py +0 -0
  226. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_struct_dtype.py +0 -0
  227. {blosc2-3.2.1 → blosc2-3.3.0}/tests/ndarray/test_zeros.py +0 -0
  228. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_bytes_array.py +0 -0
  229. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_comp_info.py +0 -0
  230. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compress2.py +0 -0
  231. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compression_parameters.py +0 -0
  232. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_compressors.py +0 -0
  233. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_decompress.py +0 -0
  234. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_iterchunks.py +0 -0
  235. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_mmap.py +0 -0
  236. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_open.py +0 -0
  237. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_open_c2array.py +0 -0
  238. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_pathlib.py +0 -0
  239. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_postfilters.py +0 -0
  240. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_prefilters.py +0 -0
  241. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_proxy_schunk.py +0 -0
  242. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_python_blosc.py +0 -0
  243. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk.py +0 -0
  244. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_constructor.py +0 -0
  245. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_delete.py +0 -0
  246. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_get_slice.py +0 -0
  247. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_get_slice_nchunks.py +0 -0
  248. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_insert.py +0 -0
  249. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_set_slice.py +0 -0
  250. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_schunk_update.py +0 -0
  251. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_storage.py +0 -0
  252. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_tensor.py +0 -0
  253. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_ucodecs.py +0 -0
  254. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_ufilters.py +0 -0
  255. {blosc2-3.2.1 → blosc2-3.3.0}/tests/test_vlmeta.py +0 -0
  256. {blosc2-3.2.1 → blosc2-3.3.0}/update_version.py +0 -0
@@ -16,7 +16,7 @@ repos:
16
16
  - id: trailing-whitespace
17
17
 
18
18
  - repo: https://github.com/astral-sh/ruff-pre-commit
19
- rev: v0.9.9
19
+ rev: v0.11.4
20
20
  hooks:
21
21
  - id: ruff
22
22
  args: ["--fix", "--show-fixes"]
@@ -1,16 +1,12 @@
1
- Announcing Python-Blosc2 3.2.1
1
+ Announcing Python-Blosc2 3.3.0
2
2
  ==============================
3
3
 
4
- Here, all array containers in Blosc2 implement the ``__array_interface__``
5
- protocol to expose the data in the array. This allows for better
6
- interoperability with other libraries like NumPy, CuPy, etc. Now, the range
7
- of functions spans to most of NumPy functions, including reductions.
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 examples at: https://github.com/Blosc/python-blosc2/blob/main/examples/ndarray/jit-numpy-funcs.py
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.2.1
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:
@@ -108,6 +108,7 @@ to the core development of the Blosc2 library:
108
108
  - Juan David Ibáñez
109
109
  - Ivan Vilata i Balaguer
110
110
  - Oumaima Ech.Chdig
111
+ - Ricardo Sales Piquer
111
112
 
112
113
  In addition, other people have participated to the project in different
113
114
  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, just for flexing the broadcasting capabilities of lazy expressions."
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 operates with the values of `b` by `c`. In this context, creating a string version of the expression is critical; otherwise, reductions should be computed eagerly.\n",
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 save it for later. The expression chosen illustrates how operations automatically adapt to the dimensions of the operands through the concept of broadcasting.\n",
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 allows the operation to be performed consistently.\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 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 is inferred the basic information about the dimensions and type of the result.\n",
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 its ability to simplify the complex and empower our creativity!"
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.0 released on 2025-02-27!</a>
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>
@@ -12,3 +12,4 @@ The next functions can be used for computing linear algebra operations with :ref
12
12
  :nosignatures:
13
13
 
14
14
  matmul
15
+ transpose
@@ -40,7 +40,7 @@ dependencies = [
40
40
  "py-cpuinfo; platform_machine != 'wasm32'",
41
41
  "requests",
42
42
  ]
43
- version = "3.2.1"
43
+ version = "3.3.0"
44
44
 
45
45
 
46
46
  [project.optional-dependencies]
@@ -248,6 +248,7 @@ from .ndarray import (
248
248
  full,
249
249
  save,
250
250
  matmul,
251
+ transpose,
251
252
  )
252
253
 
253
254
  from .c2array import c2context, C2Array, URLPath
@@ -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
- kwargs = _check_ndarray_kwargs(**kwargs)
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: `NDArray`
3780
+ x1: :ref:`NDArray`
3669
3781
  The first input array.
3670
- x2: `NDArray`
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, np.complex64, np.complex128},
24
+ {np.float32, np.float64},
25
25
  )
26
26
  def test_matmul(ashape, achunks, ablocks, bshape, bchunks, bblocks, dtype):
27
- a = blosc2.linspace(0, 10, dtype=dtype, shape=ashape, chunks=achunks, blocks=ablocks)
28
- b = blosc2.linspace(0, 10, dtype=dtype, shape=bshape, chunks=bchunks, blocks=bblocks)
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"