Skip to content

Commit

Permalink
Fix encoding/decoding of F-ordered numpy arrays
Browse files Browse the repository at this point in the history
Closes #63
  • Loading branch information
michaelosthege committed Oct 9, 2022
1 parent 2fa5f7d commit 7a22e59
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mcbackend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
pass


__version__ = "0.2.3"
__version__ = "0.2.4"
1 change: 1 addition & 0 deletions mcbackend/npproto/__init__.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions mcbackend/npproto/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def ndarray_from_numpy(arr: numpy.ndarray) -> Ndarray:
dtype=dt,
data=bytes(arr.data),
strides=list(arr.strides),
order="CF"[arr.flags.f_contiguous],
)


Expand All @@ -38,4 +39,12 @@ def ndarray_to_numpy(nda: Ndarray) -> numpy.ndarray:
dtype=numpy.dtype(nda.dtype),
strides=nda.strides,
)
# The code that reads the bytes(arr.data) always results in C-ordered data.
# Passing `to the `np.ndarray(order=...)` call has no effect.
# This is where below workaround comes into play:
# It reshapes arrays that were originally in Fortran order.
# F-ordered arrays that were encoded with mcbackend < 0.2.4 default
# to `nda.order == ""` and there is nothing we can do for these.
if nda.order == "F":
arr = arr.T.reshape(arr.shape)
return arr
12 changes: 12 additions & 0 deletions mcbackend/test_npproto.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ def test_conversion(self, arr: numpy.ndarray):
result = utils.ndarray_to_numpy(dec)
numpy.testing.assert_array_equal(result, arr)
pass

@pytest.mark.parametrize("shape", [(5,), (2, 3), (2, 3, 5), (5, 2, 1, 7)])
@pytest.mark.parametrize("order", "CF")
def test_byteorders(self, shape, order):
arr = numpy.arange(numpy.prod(shape)).reshape(shape, order=order)

nda = utils.ndarray_from_numpy(arr)
assert nda.order == "CF"[arr.flags.f_contiguous]

dec = utils.ndarray_to_numpy(nda)
numpy.testing.assert_array_equal(arr, dec)
pass
1 change: 1 addition & 0 deletions protobufs/npproto/ndarray.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ message ndarray {
string dtype = 2;
repeated int64 shape = 3;
repeated int64 strides = 4;
string order = 5;
}

0 comments on commit 7a22e59

Please sign in to comment.