Skip to content

Introduce a flat option to ensure_contiguous_ndarray to switch off flatten for ZFPY codec #307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __getattr__(cls, name):
return Mock()


MOCK_MODULES = ['msgpack', 'zfpy']
MOCK_MODULES = ['msgpack']
sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES)


Expand Down
4 changes: 4 additions & 0 deletions docs/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Release notes

Unreleased
----------
* Fix a flatten array error for ZFPY, ZFPY codec is supported on Python 3.9
and 3.10 on Linux and MacOS, the docs about ZFPY is also available.
By :user:`Haiying Xu <halehawk>`, `John Kirkham <jakirkham>`, `Ryan Abernathey <rabernat>` :
issue:`303`.

.. _release_0.9.1:

Expand Down
8 changes: 5 additions & 3 deletions numcodecs/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def ensure_ndarray(buf):
return arr


def ensure_contiguous_ndarray(buf, max_buffer_size=None):
def ensure_contiguous_ndarray(buf, max_buffer_size=None, flatten=True):
"""Convenience function to coerce `buf` to a numpy array, if it is not already a
numpy array. Also ensures that the returned value exports fully contiguous memory,
and supports the new-style buffer interface. If the optional max_buffer_size is
Expand Down Expand Up @@ -91,8 +91,10 @@ def ensure_contiguous_ndarray(buf, max_buffer_size=None):

# check memory is contiguous, if so flatten
if arr.flags.c_contiguous or arr.flags.f_contiguous:
# can flatten without copy
arr = arr.reshape(-1, order='A')
# check if flatten flag is on or not
if flatten:
# can flatten without copy
arr = arr.reshape(-1, order='A')

else:
raise ValueError('an array with contiguous memory is required')
Expand Down
24 changes: 23 additions & 1 deletion numcodecs/tests/test_zfpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
np.random.normal(loc=1000, scale=1, size=(100, 10)),
np.random.normal(loc=1000, scale=1, size=(10, 10, 10)),
np.random.normal(loc=1000, scale=1, size=(2, 5, 10, 10)),
np.asfortranarray(np.random.normal(loc=1000, scale=1, size=(5, 10, 20))),
np.random.randint(-(2 ** 31), -(2 ** 31) + 20, size=1000, dtype="i4").reshape(
100, 10
),
Expand Down Expand Up @@ -84,3 +83,26 @@ def test_err_decode_object_buffer():

def test_err_encode_object_buffer():
check_err_encode_object_buffer(ZFPY())


def test_err_encode_list():
data = ['foo', 'bar', 'baz']
for codec in codecs:
with pytest.raises(TypeError):
codec.encode(data)


def test_err_encode_non_contiguous():
# non-contiguous memory
arr = np.arange(1000, dtype='i4')[::2]
for codec in codecs:
with pytest.raises(ValueError):
codec.encode(arr)


def test_err_encode_fortran_array():
# fortran array
arr = np.asfortranarray(np.random.normal(loc=1000, scale=1, size=(5, 10, 20)))
for codec in codecs:
with pytest.raises(ValueError):
codec.encode(arr)
13 changes: 11 additions & 2 deletions numcodecs/zfpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from .abc import Codec
from .compat import ndarray_copy, ensure_contiguous_ndarray, ensure_bytes
import numpy as np

# noinspection PyShadowingBuiltins
class ZFPY(Codec):
Expand Down Expand Up @@ -54,8 +55,16 @@ def __init__(

def encode(self, buf):

# normalise inputs
buf = ensure_contiguous_ndarray(buf)
# not flatten c-order array and raise exception for f-order array
if not isinstance(buf, np.ndarray):
raise TypeError("The zfp codec does not support none numpy arrays."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What other type would you expect here? I thought all Zarr array data would come into numcodecs as numpy arrays?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to repeat my answers here, I added test_err_encode_list, which caused buf.flags not raise a correct error. So I added check the instance first. Do you have any different recommendation?

f" Your buffers were {type(buf)}.")
if buf.flags.c_contiguous:
flatten = False
else:
raise ValueError("The zfp codec does not support F order arrays. "
f"Your arrays flags were {buf.flags}.")
buf = ensure_contiguous_ndarray(buf, flatten=flatten)

# do compression
return _zfpy.compress_numpy(
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ cython
numpy
msgpack
pytest
zfpy
3 changes: 2 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Cython==0.29.21
msgpack==1.0.2
numpy==1.21.0
zfpy==0.5.5; python_version < '3.9'
zfpy==0.5.5


2 changes: 1 addition & 1 deletion requirements_rtfd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ numpydoc
mock
numpy
cython
zfpy==0.5.5; python_version < '3.9'
zfpy==0.5.5