Skip to content

Commit c9f845f

Browse files
authored
Merge branch 'main' into claude/zarr-python-issue-4174-77043e
2 parents d9d932f + 0de6077 commit c9f845f

62 files changed

Lines changed: 1315 additions & 804 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎changes/4351.bugfix.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Missing Zarr format 3 imagecodecs now name `imagecodecs-zarr` as a known provider, alongside `virtual-tiff` where both packages register the codec.

‎packages/zarr-indexing/CONTRIBUTING.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ just test # run the test suite (extra args go to pytest)
88
just lint # ruff, same invocation as CI
99
just typecheck # pyright, same invocation as CI
1010
just docs-check # strict build of the docs site
11-
just check # all of the above
11+
just check # the checks above plus TensorStore parity
1212
just docs-serve # serve the docs site locally
1313
```
1414

15-
Run them from this directory, or from anywhere in the repository as
15+
Run them from this directory, or from the repository root as
1616
`just packages/zarr-indexing/<recipe>`.
1717

18-
The test recipe runs against the workspace-root environment, because the
19-
chunk-resolution tests exercise this package against `zarr`'s chunk grids and
20-
`zarr` is deliberately not a dependency of this package.
18+
The test recipe layers this package into the repository-root environment.
19+
Chunk-resolution tests use this package’s own grids; the Dask example also
20+
uses `zarr`, which is not a dependency of the base indexing package.
2121

2222
## License
2323

‎packages/zarr-indexing/README.md‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ Composable, lazy coordinate transforms for Zarr array indexing.
55
Documentation: <https://zarr-indexing.readthedocs.io/>
66

77
This package implements TensorStore-inspired index transforms. The core idea:
8-
every indexing operation (slicing, fancy indexing, etc.) produces a coordinate
9-
mapping from user space to storage space. These mappings compose lazily — no
10-
I/O until you explicitly read or write.
8+
each supported indexing operation (slicing, fancy indexing, etc.) produces a coordinate
9+
mapping from user space to storage space. These mappings compose without reading selected source values. `LazyArray`
10+
materializes them on request; the transform algebra itself performs no source I/O.
1111

1212
Key types:
1313

1414
- `LazyArray` — wraps a system-memory/basic-indexing source and adds a `.lazy`
1515
accessor: `LazyArray.from_numpy(numpy_array).lazy[10:50, ::2].lazy.oindex[[3, 1, 1], :]`
1616
composes a transform and returns a new view without reading data, and
1717
`result()` materializes it into owned system memory. `LazyArray(source)` uses
18-
the conservative basic reader; `from_numpy` explicitly selects NumPy's
19-
optimized reader. Device arrays require an explicit custom reader responsible
20-
for transferring values into the supplied system-memory output buffer.
18+
the basic reader; `from_numpy` selects `numpy_reader`, which currently uses
19+
the same slab-and-gather implementation. Device sources that refuse NumPy
20+
conversion need a custom reader to transfer values into the output buffer.
2121
- `Reader` — the explicit backend execution boundary: transforms say which
2222
values belong in the result, while readers say how a backend obtains them
2323
- `IndexDomain` — a rectangular region of integer coordinates
@@ -32,9 +32,11 @@ Key types:
3232
dimension can depend on the input
3333
- `compose` — chain two transforms into one
3434

35-
The package depends only on NumPy and the standard library; it does not import
36-
`zarr`. It is developed in the [zarr-python](https://github.com/zarr-developers/zarr-python)
37-
repository and consumed by `zarr` to resolve array indexing operations.
35+
The base package depends on NumPy and the standard library; its optional testing
36+
module also requires Hypothesis. The package does not import `zarr`. It is developed
37+
in the [zarr-python](https://github.com/zarr-developers/zarr-python) repository,
38+
and its examples include reading Zarr arrays through Dask. Installing it does not
39+
replace Zarr's indexing implementation.
3840

3941
## Installation
4042

‎packages/zarr-indexing/benchmarks/README.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ whether input arrays and transform construction are included. Repeated local
2222
column access measures cache reuse, which trades allocation against retained
2323
memory. Bounded coordinate batches avoid constructing the full coordinate array.
2424

25+
The current script reports `peak_mib` as the incremental peak tracked by
26+
`tracemalloc` during a separate invocation after the timed calls. It is not
27+
process RSS or total retained memory. Inputs and most transforms are constructed
28+
before measurement. The case walks construct plans and consume projections
29+
without retaining them; `all_coordinates` materializes the complete coordinate
30+
array. There is no bounded-batch coordinate workload in this script.
31+
32+
`local_rows` reuses one prepared table: its first timed invocation populates the
33+
local-coordinate cache, while later timed invocations and the allocation probe
34+
reuse that cache. Its median mixes a cold first call with warm calls, and its
35+
reported peak excludes the already-retained cache. A separate fresh-table
36+
measurement would be needed to quantify cold cache construction.
37+
2538
These scripts measure planning rather than codec or storage throughput. Repeat
2639
measurements with alternating operation order before interpreting small timing
2740
differences. Preserve raw benchmark output as an experiment artifact rather than

‎packages/zarr-indexing/benchmarks/chunk_planning.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525

2626

2727
def measure(operation: Callable[[], Any], repeats: int) -> dict[str, float]:
28+
"""Time repeated calls, then trace one additional call's incremental peak.
29+
30+
State retained by earlier calls can affect the extra call; this is not a
31+
measurement of process RSS or all memory owned by the operation's inputs.
32+
"""
2833
samples = []
2934
for _ in range(repeats):
3035
start = time.perf_counter()
@@ -84,6 +89,8 @@ def read_local_rows() -> None:
8489
for row in range(len(table)):
8590
table.local[table.run(row)]
8691

92+
# The first timed call fills table.local; later calls, including the traced
93+
# allocation probe, reuse it. The table and retained cache are not re-created.
8794
results["local_rows"] = measure(read_local_rows, args.repeats)
8895
part = plan_chunks(
8996
IndexTransform.from_shape((100, 100, 100)),
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reject invalid wire index-array values and unrepresentable normalized bounds/ranks, and raise an explicit error for unsupported intersections sharing an affine and lookup input axis instead of returning incorrect coordinates. Group negative chunk-coordinate tuples without merging distinct chunks.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Correct indexing, reader, serialization, cache, and integration descriptions to match supported behavior; qualify NumPy/TensorStore compatibility and performance claims.
2+
3+
Describe current contracts in source and test docstrings instead of narrating prior implementations. Clarify that immutable index coordinates do not snapshot source values.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Expand planner property tests across signed origins and chunk IDs, custom grids, mixed affine and lookup dependencies, duplicate coordinates, and empty domains. Verify exact request coverage and storage mapping with an independent pointwise oracle.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Validate inclusive `index_array_bounds` against all raw index values when loading transforms and output maps from JSON. Accept valid finite and one-sided constraints, and reject out-of-bounds values eagerly before offset, stride, or map simplification. Validated immutable maps need not retain the constraints; message normalization preserves the original bounds.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Delegate LazyArray source tokenization to Dask, honoring its registered normalizers, source hooks, and deterministic-token requirements. Remove local content-hashing and UUID fallbacks. Dask remains optional for indexing and reading.

0 commit comments

Comments
 (0)