Skip to content

Commit

Permalink
Fix write from array that is not row or column order (#2542)
Browse files Browse the repository at this point in the history
When writing to a dense array, if the input numpy array is neither row or column order, cast the array to row order.
  • Loading branch information
jp-dark authored May 10, 2024
1 parent 8c7863c commit 204f0c8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
14 changes: 9 additions & 5 deletions apis/python/src/tiledbsoma/_dense_nd_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,21 +265,25 @@ def write(

clib_dense_array = self._handle._handle

# Compute the coordinates for the dense array.
new_coords: List[Union[int, Slice[int], None]] = []
for c in coords:
if isinstance(c, slice) and isinstance(c.stop, int):
new_coords.append(slice(c.start, c.stop - 1, c.step))
else:
new_coords.append(c)

# Convert data to a numpy array.
dtype = self.schema.field("soma_data").type.to_pandas_dtype()
input = np.array(values, dtype=dtype)

order = (
clib.ResultOrder.colmajor
if input.flags.f_contiguous
else clib.ResultOrder.rowmajor
)
# Set the result order. If neither row nor col major, set to be row major.
if input.flags.f_contiguous:
order = clib.ResultOrder.colmajor
else:
if not input.flags.contiguous:
input = np.ascontiguousarray(input)
order = clib.ResultOrder.rowmajor
clib_dense_array.reset(result_order=order)

self._set_reader_coords(clib_dense_array, new_coords)
Expand Down
35 changes: 35 additions & 0 deletions apis/python/tests/test_regression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Testing module for regression tests"""


import numpy as np
import pyarrow as pa

import tiledbsoma as soma


def test_nd_dense_non_contiguous_write(tmp_path):
"""Test regression dected in GitHub Issue #2537"""
# Create data.
data = (
np.arange(np.product(24), dtype=np.uint8)
.reshape((4, 3, 2))
.transpose((2, 0, 1))
)
coords = tuple(slice(0, dim_len) for dim_len in data.shape)
tensor = pa.Tensor.from_numpy(data)

# Create array and write data to it.
with soma.DenseNDArray.create(
tmp_path.as_posix(), type=pa.uint8(), shape=data.shape
) as array:
array.write(coords, tensor)

# Check the data is correct when we read it back.
with soma.DenseNDArray.open(tmp_path.as_posix()) as array:
result = array.read(coords)
np.testing.assert_equal(data, result.to_numpy())

# Check the data is correct when we read it back.
with soma.DenseNDArray.open(tmp_path.as_posix()) as array:
result = array.read(coords, result_order="column-major")
np.testing.assert_equal(data.transpose(), result.to_numpy())

0 comments on commit 204f0c8

Please sign in to comment.