Skip to content

Commit 617b19a

Browse files
committed
Getting ready for release 4.8.0
1 parent b163e6a commit 617b19a

4 files changed

Lines changed: 70 additions & 45 deletions

File tree

ANNOUNCE.rst

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,55 @@
1-
Announcing Python-Blosc2 4.7.0
1+
Announcing Python-Blosc2 4.8.0
22
==============================
33

4-
We are happy to announce this release, which brings a **DSL → JavaScript JIT
5-
backend** for running compute kernels under WebAssembly/Pyodide, a new helper to
6-
check whether your DSL kernels actually JIT-compile, and a batch of miniexpr
7-
fixes.
4+
We are happy to announce this release, which brings support for
5+
**sharing containers safely across processes** — opt-in file locking for
6+
``SChunk``/``NDArray``/``EmbedStore``/``DictStore``, atomic archive
7+
replacement, and readers that follow another process's writes — plus a
8+
couple of data-loss and data-correctness bug fixes worth upgrading for even
9+
if you don't touch any of the new locking API.
810

911
The main highlights are:
1012

11-
- **DSL → JavaScript backend (``jit_backend="js"``)**: under WebAssembly/Pyodide,
12-
``@blosc2.dsl_kernel`` kernels can now be transpiled to JavaScript and run via
13-
the browser's JIT. It is the **default there** for transpilable floating-point
14-
kernels (silently falling back to miniexpr for anything it can't handle), and
15-
beats the WASM TinyCC JIT on compute-heavy kernels (e.g. ~2.8x on a Newton
16-
fractal). It supports index/shape symbols (``_i0``/``_n0``/``_ndim``/
17-
``_flat_idx``) and integer inputs with a floating-point output. Request it
18-
explicitly with ``compute(jit_backend="js")``; outside WebAssembly that raises.
19-
Native builds are unaffected.
20-
21-
- **New ``blosc2.validate_dsl_jit()``**: an introspection helper that reports
22-
whether a DSL kernel actually JIT-compiles (vs. silently falling back to the
23-
interpreter) for given operand/output dtypes — without running it on real
24-
data.
25-
26-
- **miniexpr fixes**: clearer errors for ``;``-joined statements and for
27-
assigning to an input parameter, and a fix for a name collision where DSL
28-
variables named ``out``/``idx``/``nitems``/``inputs``/``output`` clashed with
29-
codegen-internal identifiers and silently fell back to the interpreter.
30-
31-
A quick taste — run a DSL kernel on the JS backend under Pyodide::
32-
33-
@blosc2.dsl_kernel
34-
def k(a, b):
35-
return a * a + b * b
36-
37-
out = k.compute(operands, jit_backend="js") # JS JIT under WebAssembly
13+
- **Cross-process locking**: a new ``locking`` storage parameter (and the
14+
``BLOSC_LOCKING`` env var to enable it fleet-wide) serializes accesses to an
15+
on-disk ``SChunk``/``NDArray``/``EmbedStore``/``DictStore`` against other
16+
handles and processes via a small sidecar lock file. ``holding_lock()``
17+
holds the exclusive lock across several operations and now auto-refreshes
18+
the handle right after acquiring it, so a decision made inside the block
19+
never acts on a stale in-memory read.
20+
21+
- **Cross-process writes for ``EmbedStore``/``DictStore``** (``.b2d``): under
22+
locking, one process can add or remove keys while another has the store
23+
open, and the other side's next lookup sees the change — no need to
24+
reopen the store.
25+
26+
- **Atomic ``.b2z`` archives**: writing a ``DictStore.to_b2z()`` file (which
27+
``TreeStore`` also uses) now swaps the new file in atomically. A process
28+
reading the archive concurrently always gets either the complete old
29+
version or the complete new one — never a partially-written file from a
30+
save that's still in progress. This needs no locking on the reader's side.
31+
32+
- **Growth-SWMR**: a reader ``NDArray`` handle opened before a ``resize()``
33+
made through another handle follows the new shape on its next data access,
34+
or via the new explicit ``NDArray.refresh()`` / ``SChunk.refresh()``.
35+
36+
- **Two bug fixes worth knowing about**: ``NDArray.append()`` could silently
37+
delete another writer's just-appended data under concurrent growth (fixed
38+
by refreshing the cached shape before computing the resize target); and
39+
``detect_aligned_chunks()`` could silently return the wrong chunk's data
40+
for an aligned slice on arrays whose shape isn't a multiple of the chunk
41+
shape (a floor-division bug that undercounted the chunk grid).
42+
43+
- New user guide page,
44+
`Sharing containers across processes
45+
<https://www.blosc.org/python-blosc2/getting_started/sharing_across_processes.html>`_,
46+
covering all of the above plus the caveats (NFS, ``mmap_mode``, Windows
47+
in-use-file rename).
48+
49+
A quick taste — hold the lock across a read-modify-write from two processes::
50+
51+
with ndarr.holding_lock():
52+
ndarr[:] = ndarr[:] + 1 # atomic w.r.t. other locked handles
3853

3954
Install it with::
4055

RELEASE_NOTES.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,37 @@
88
variable to enable it fleet-wide) serializes accesses to an on-disk
99
`SChunk`/`NDArray`/`EmbedStore`/`DictStore` against other handles and other
1010
processes, via a small sidecar lock file (`.b2lock`). Advisory: every
11-
handle touching the container must opt in. Requires a c-blosc2 build with
12-
`blosc2_schunk_lock()` (bundled automatically; see the minimum-version
13-
notes below if linking a system c-blosc2).
14-
- `SChunk.holding_lock()`: a context manager to hold the exclusive lock
15-
across several operations, making a multi-step mutation atomic to other
16-
locked handles.
11+
handle touching the container must opt in.
12+
- `SChunk.holding_lock()` / `NDArray.holding_lock()`: a context manager to
13+
hold the exclusive lock across several operations, making a multi-step
14+
mutation atomic to other locked handles.
15+
- New `SChunk.refresh()`, mirroring the existing `NDArray.refresh()`.
16+
- Fixed a data-loss bug in `NDArray.append()`: it read the cached,
17+
unrefreshed shape before computing the resize target, so under
18+
concurrent growth/shrink — even inside `holding_lock()` — another writer's
19+
just-appended data could be silently deleted.
1720
- `EmbedStore` and `DictStore` (`.b2d`) now support cross-process writers
1821
under locking: transactional writes plus key-map re-sync, so readers
1922
follow keys added or removed by another process.
20-
- `DictStore.to_b2z()` (and `TreeStore`, built on it) now replaces the
21-
target file atomically, so concurrent readers always see either the old
22-
or the new archive, never a torn one. No locking needed for `.b2z` reads.
23+
- `DictStore.to_b2z()` (and `TreeStore`, which inherits from it) now replaces
24+
the target file atomically, so concurrent readers always see either the old
25+
or the new archive, never a torn one.
2326
- Growth-SWMR (single writer, multiple readers): a reader `NDArray` handle
2427
opened before a `resize()` made through another handle follows the new
25-
shape on its next data access, or via the new explicit
26-
`NDArray.refresh()`.
28+
shape on its next data access, or via the new explicit `NDArray.refresh()`.
2729
- New user guide page,
2830
[Sharing containers across processes](https://www.blosc.org/python-blosc2/getting_started/sharing_across_processes.html),
2931
covering all of the above plus the caveats (NFS, `mmap_mode`, Windows
3032
in-use-file rename).
3133

34+
### Bug fixes
35+
36+
- Fixed `detect_aligned_chunks()` (used internally to fast-path aligned
37+
slice reads/writes): a floor-division undercounted the chunk grid for
38+
arrays whose shape isn't a multiple of the chunk shape, which could
39+
silently return the wrong chunk's data for an otherwise-aligned slice
40+
with a nonzero start in an earlier dimension.
41+
3242
## Changes from 4.6.0 to 4.7.0
3343

3444
### DSL → JavaScript backend for WebAssembly (`jit_backend="js"`)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ dependencies = [
4141
"rich",
4242
"threadpoolctl; platform_machine != 'wasm32'",
4343
]
44-
version = "4.8.0.dev0"
44+
version = "4.8.0"
4545
[project.entry-points."array_api"]
4646
blosc2 = "blosc2"
4747

src/blosc2/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "4.8.0.dev0"
1+
__version__ = "4.8.0"
22
__array_api_version__ = "2024.12"

0 commit comments

Comments
 (0)