Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions .github/workflows/daily-test-build-numpy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ jobs:
- { python-version: "3.11", numpy-version: "1.25.2" }
- { python-version: "3.11", numpy-version: "2.3.4" }
- { python-version: "3.12", numpy-version: "1.26.4" }
- { python-version: "3.12", numpy-version: "2.3.4" }
- { python-version: "3.12", numpy-version: "2.5.0" }
- { python-version: "3.13", numpy-version: "2.1.3" }
- { python-version: "3.13", numpy-version: "2.3.4" }
- { python-version: "3.14", numpy-version: "2.3.4" }
- { python-version: "3.13", numpy-version: "2.5.0" }
- { python-version: "3.14", numpy-version: "2.5.0" }
fail-fast: false
env:
TILEDB_VERSION: ${{ inputs.libtiledb_version }}
Expand Down
2 changes: 1 addition & 1 deletion tiledb/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ def set_query(self, serialized_query):
out = OrderedDict()
for name in results.keys():
arr = results[name][0]
arr.dtype = q.buffer_dtype(name)
arr = arr.view(q.buffer_dtype(name))
out[name] = arr
return out

Expand Down
4 changes: 2 additions & 2 deletions tiledb/core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1447,8 +1447,8 @@ class PyQuery {
auto arr = py::array(py::dtype("int8"), size, data_ptr);
o = py::memoryview(arr);
} else {
o = py::array(py::dtype("uint8"), size, data_ptr);
o.attr("dtype") = dtype;
// `size` is the cell's byte length, a multiple of the itemsize.
o = py::array(dtype, size / dtype.itemsize(), data_ptr);
}
Comment thread
kounelisagis marked this conversation as resolved.
Outdated

result_p[i - 1] = o;
Expand Down
17 changes: 13 additions & 4 deletions tiledb/dataframe_.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,13 @@ def create_dim(dtype, values, full_domain, tile, **kwargs):
if np.issubdtype(dtype, np.datetime64):
date_unit = np.datetime_data(dtype)[0]
dim_min = np.datetime64(dtype_min, date_unit)
tile_max = np.iinfo(np.uint64).max - tile
if np.uint64(dtype_max - dtype_min) > tile_max:
dim_max = np.datetime64(dtype_max - tile, date_unit)
# Subtract in Python ints; a full-domain datetime64 difference
# overflows int64.
dtype_min_i = int(dtype_min.astype(np.int64))
dtype_max_i = int(dtype_max.astype(np.int64))
tile_max = int(np.iinfo(np.uint64).max) - int(tile)
if (dtype_max_i - dtype_min_i) > tile_max:
dim_max = np.datetime64(dtype_max_i - int(tile), date_unit)
elif np.issubdtype(dtype, np.integer):
tile_max = np.iinfo(np.uint64).max - tile
if np.uint64(dtype_max - dtype_min) > tile_max:
Expand All @@ -383,9 +387,14 @@ def create_dim(dtype, values, full_domain, tile, **kwargs):
dim_min, dim_max = None, None

# TODO: simplify this logic and/or move to DataType.cast_tile_extent
if np.issubdtype(dtype, np.integer) or np.issubdtype(dtype, np.datetime64):
if np.issubdtype(dtype, np.integer):
# we can't make a tile larger than the dimension range or lower than 1
tile = max(1, min(tile, 1 + np.uint64(dim_max - dim_min)))
elif np.issubdtype(dtype, np.datetime64):
# Clamp as for integers, computing the range in Python ints since a
# full-domain datetime64 difference overflows int64.
dim_range = int(dim_max.astype(np.int64)) - int(dim_min.astype(np.int64))
tile = max(1, min(tile, 1 + dim_range))
elif np.issubdtype(dtype, np.floating):
# this difference can be inf
with np.errstate(over="ignore"):
Expand Down
14 changes: 6 additions & 8 deletions tiledb/dense_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ def _read_dense_subarray(
# Note: fixed blobs are always 1 byte per cell
arr = arr.view("S1")
else:
arr.dtype = dtype
arr = arr.view(dtype)
if len(arr) == 0:
# special case: the C API returns 0 len for blank arrays
arr = np.zeros(output_shape, dtype=dtype)
Expand All @@ -357,13 +357,11 @@ def _read_dense_subarray(
)

if layout == lt.LayoutType.ROW_MAJOR:
arr.shape = output_shape
arr = np.require(arr, requirements="C")
arr = np.require(arr.reshape(output_shape), requirements="C")
elif layout == lt.LayoutType.COL_MAJOR:
arr.shape = output_shape
arr = np.require(arr, requirements="F")
arr = np.require(arr.reshape(output_shape), requirements="F")
else:
arr.shape = np.prod(output_shape)
arr = arr.reshape(np.prod(output_shape))

out[name] = arr

Expand Down Expand Up @@ -838,12 +836,12 @@ def read_subarray(self, subarray):
arr = pyquery.unpack_buffer(name, item[0], item[1])
else:
arr = item[0]
arr.dtype = (
arr = arr.view(
self.schema.attr_or_dim_dtype(name)
if not self.schema.has_dim_label(name)
else self.schema.dim_label(name).dtype
)
arr.shape = result_shape
arr = arr.reshape(result_shape)
result_dict[name if name != "__attr" else ""] = arr

return result_dict
Expand Down
4 changes: 2 additions & 2 deletions tiledb/multirange_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ def _run_query(self) -> Dict[str, np.ndarray]:
for name, arr in result_dict.items():
# TODO check/test layout
if not self.array.schema.has_dim_label(name):
arr.shape = self.result_shape
result_dict[name] = arr.reshape(self.result_shape)
return result_dict


Expand Down Expand Up @@ -826,7 +826,7 @@ def _get_pyquery_results(pyquery: PyQuery, array: Array) -> Dict[str, np.ndarray
arr = pyquery.unpack_buffer(name, item[0], item[1])
else:
arr = item[0]
arr.dtype = (
arr = arr.view(
schema.attr_or_dim_dtype(name)
if not schema.has_dim_label(name)
else schema.dim_label(name).dtype
Expand Down
25 changes: 10 additions & 15 deletions tiledb/npbuffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -471,22 +471,17 @@ class NumpyConvert {
NumpyConvert(py::array input) {
// require a flat buffer
if (input.ndim() != 1) {
// try to take a 1D view on the input
auto v = input.attr("view")();
// this will throw if the shape cannot be modified zero-copy,
// which is what we want
try {
v.attr("shape") = py::int_(input.size());
} catch (py::error_already_set& e) {
if (e.matches(PyExc_AttributeError)) {
use_iter_ = true;
} else {
throw;
}
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
// reshape(-1) yields a zero-copy view when the array can be
// flattened in place and a fresh copy otherwise; the bulk paths
// need the view, so compare buffer addresses and fall back to the
// element-wise iterator (which handles strided input) on a copy.
Comment thread
kounelisagis marked this conversation as resolved.
Outdated
py::array flat = input.attr("reshape")(py::int_(-1));
if (flat.data() == input.data()) {
input_ = flat;
} else {
use_iter_ = true;
input_ = input;
}
input_ = v;
} else {
input_ = input;
}
Expand Down
7 changes: 3 additions & 4 deletions tiledb/sparse_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ def read_subarray(self, subarray):
arr = pyquery.unpack_buffer(name, item[0], item[1])
else:
arr = item[0]
arr.dtype = (
arr = arr.view(
self.schema.attr_or_dim_dtype(name)
if not self.schema.has_dim_label(name)
else self.schema.dim_label(name).dtype
Expand Down Expand Up @@ -598,7 +598,7 @@ def _read_sparse_subarray(self, subarray, attr_names: list, cond, layout):
arr = q.unpack_buffer(name, results[name][0], results[name][1])
else:
arr = results[name][0]
arr.dtype = self.schema.attr_or_dim_dtype(name)
arr = arr.view(self.schema.attr_or_dim_dtype(name))
out[final_name] = arr
else:
arr = results[name][0]
Expand All @@ -623,8 +623,7 @@ def _read_sparse_subarray(self, subarray, attr_names: list, cond, layout):
elif el_dtype == np.dtype("U0"):
out[final_name] = ""
else:
arr.dtype = el_dtype
out[final_name] = arr
out[final_name] = arr.view(el_dtype)

if self.schema.has_attr(final_name) and self.attr(final_name).isnullable:
out[final_name] = np.ma.array(
Expand Down
2 changes: 1 addition & 1 deletion tiledb/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_pyquery_basic(self):
q2.set_subarray(subarray)
q2.submit()
res = q2.results()[""][0]
res.dtype = np.double
res = res.view(np.double)
assert_array_equal(res, a[:])

def test_pyquery_init(self):
Expand Down
18 changes: 15 additions & 3 deletions tiledb/tests/test_libtiledb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2697,7 +2697,11 @@ def test_dense_datetime_vector(self):
(np.datetime64("2010-11-01") - start) / np.timedelta64(1, "D")
)
read_ndays = int(
(np.datetime64("2011-01-31") - np.datetime64("2010-11-01") + 1)
(
np.datetime64("2011-01-31")
- np.datetime64("2010-11-01")
+ np.timedelta64(1, "D")
)
/ np.timedelta64(1, "D")
)
expected = a1_vals[read_offset : read_offset + read_ndays]
Expand All @@ -2712,7 +2716,11 @@ def test_dense_datetime_vector(self):
(np.datetime64("2010-01-01") - start) / np.timedelta64(1, "D")
)
read_ndays = int(
(np.datetime64("2011-01-01") - np.datetime64("2010-01-01") + 1)
(
np.datetime64("2011-01-01")
- np.datetime64("2010-01-01")
+ np.timedelta64(1, "D")
)
/ np.timedelta64(1, "D")
)
expected = a1_vals[read_offset : read_offset + read_ndays]
Expand All @@ -2725,7 +2733,11 @@ def test_dense_datetime_vector(self):
(np.datetime64("2010-01-01") - start) / np.timedelta64(1, "D")
)
read_ndays = int(
(np.datetime64("2011-01-31") - np.datetime64("2010-01-01") + 1)
(
np.datetime64("2011-01-31")
- np.datetime64("2010-01-01")
+ np.timedelta64(1, "D")
)
/ np.timedelta64(1, "D")
)
expected = a1_vals[read_offset : read_offset + read_ndays]
Expand Down
4 changes: 2 additions & 2 deletions tiledb/tests/test_subarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def test_add_fixed_sized_point_ranges(self):

results = q.results()
arr = results["a"][0]
arr.dtype = np.int32
arr = arr.view(np.int32)
assert arr.shape == (2,)
assert np.array_equal(arr, np.array([10, 30], dtype=np.int32))

Expand Down Expand Up @@ -235,6 +235,6 @@ def test_add_var_sized_point_ranges(self):

results = q.results()
arr = results["a"][0]
arr.dtype = np.int32
arr = arr.view(np.int32)
assert arr.shape == (2,)
assert np.array_equal(arr, np.array([10, 30], dtype=np.int32))
Loading