Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
582a8e2
Checkpoint 0.7.4 batch and GPU refactor WIP
jcwal1516 Jul 21, 2026
2151e4c
Split HT decode statistics ownership
jcwal1516 Jul 21, 2026
3e32310
Refocus J2K ML benchmark support
jcwal1516 Jul 21, 2026
a7b8ac6
Resolve Metal benchmark instrumentation module
jcwal1516 Jul 21, 2026
0b1ef07
Follow split coverage evidence modules
jcwal1516 Jul 21, 2026
cefb162
Share coverage module resolution helpers
jcwal1516 Jul 21, 2026
0d8e8cc
Format checkpointed Metal refactor
jcwal1516 Jul 21, 2026
d7db62a
fix: close remaining J2K release gate drift
jcwal1516 Jul 21, 2026
7b98dae
docs: remove stale unsafe audit entries
jcwal1516 Jul 21, 2026
09dfb5a
docs: complete unsafe audit inventory
jcwal1516 Jul 21, 2026
bef4f11
test: replace decoder line-count ratchet with AST policy
jcwal1516 Jul 21, 2026
e63fbc3
feat: add high-throughput batched J2K decoding
jcwal1516 Jul 21, 2026
b185921
fix: repair release CI validation
jcwal1516 Jul 21, 2026
0c9f46a
fix: preserve Metal batch module imports
jcwal1516 Jul 21, 2026
9fb1dd2
fix: expose Arc to Metal batch plan cache
jcwal1516 Jul 21, 2026
87d624a
fix: complete cross-platform release validation
jcwal1516 Jul 22, 2026
e44d563
fix: make release gates reproducible on Linux
jcwal1516 Jul 22, 2026
25ee3fa
fix: complete Linux Metal validation
jcwal1516 Jul 22, 2026
7a7c90b
fix: close remaining Linux release checks
jcwal1516 Jul 22, 2026
eb0095e
fix: classify pinned GPU interop sources
jcwal1516 Jul 22, 2026
b22f3e4
fix: audit vendored GPU coverage exclusions
jcwal1516 Jul 22, 2026
65c98ee
fix: preserve binary codec fixtures on Windows
jcwal1516 Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.ppm binary
*.pgm binary
*.raw binary
*.gray binary
*.j2k binary
*.j2c binary
*.jp2 binary
*.jph binary
17 changes: 5 additions & 12 deletions Cargo.lock

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

23 changes: 22 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ members = [
"crates/j2k-cli",
"xtask",
]
exclude = ["third_party/block-0.1.6-patched"]
exclude = [
"third_party/block-0.1.6-patched",
"third_party/cubecl-cuda-0.10.0-patched",
"third_party/cubecl-runtime-0.10.0-patched",
"third_party/wgpu-29.0.4-patched",
"third_party/wgpu-core-29.0.4-patched",
"third_party/wgpu-hal-29.0.4-patched",
]

[workspace.package]
version = "0.7.4"
Expand Down Expand Up @@ -80,6 +87,20 @@ burn-ir = { version = "0.21.0", default-features = false, features = ["std"] }
# Rust hard error. Keep this patch minimal and remove it when `metal` publishes
# a fixed dependency path.
block = { path = "third_party/block-0.1.6-patched" }
# Burn 0.21 / CubeCL 0.10 does not expose the owning CUDA stream required to
# register event dependencies around an external codec write. These patches
# add one hidden, binding-resolving stream hook; the raw token remains confined
# to j2k-ml's guarded interop module.
cubecl-cuda = { path = "third_party/cubecl-cuda-0.10.0-patched" }
cubecl-runtime = { path = "third_party/cubecl-runtime-0.10.0-patched" }
# Burn 0.21 uses wgpu 29, whose Metal HAL does not expose an ownership-safe
# MTLBuffer/MTLDevice bridge and whose lazy buffer initialization tracker
# cannot otherwise learn about completed external GPU writes. These local
# patches add retained raw-handle accessors plus one guarded, range-scoped
# initialization handoff used inside j2k-ml's external-write boundary.
wgpu = { path = "third_party/wgpu-29.0.4-patched" }
wgpu-core = { path = "third_party/wgpu-core-29.0.4-patched" }
wgpu-hal = { path = "third_party/wgpu-hal-29.0.4-patched" }

# Shared strict-lint policy for safe crates. Crates with genuinely different
# needs (SIMD/FFI crates that use `unsafe`, crates with documented temporary
Expand Down
61 changes: 44 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,39 @@ CUDA paths use J2K-owned CUDA Oxide device kernels through `cuda-runtime`.
NVIDIA performance claims require self-hosted benchmark evidence; hosted CI is
not treated as NVIDIA performance evidence.

## High-throughput owned batches

The additive owned-batch API accepts `EncodedImage` values containing an
`Arc<[u8]>` and one of `Full`, `Region`, `Reduced`, or `RegionReduced`. It
prepares inputs concurrently, keeps unlike output shapes in separate groups
without padding, and returns source indices, indexed preparation failures, and
homogeneous group execution failures. Representable Gray, RGB, and RGBA groups
use exact native `U8`, `U16`, or `I16` storage in NCHW or NHWC order; float
conversion and normalization are deliberately not codec operations.

Preparation can retain either a `PreparedHtj2kPlan` or a
`PreparedClassicPlan` with per-tile packet, code-block, and destination
geometry. Both plans reference compressed payload ranges inside the original
`Arc<[u8]>`; neither duplicates the codestream. `CpuBatchDecoder` consumes
single- and multi-tile plans without reparsing. Inputs outside the retained-plan
boundary can remain metadata-only and use the broader CPU codec when that path
supports them.

`j2k-cuda` and `j2k-metal` own persistent accelerator sessions, resident
output, and validated caller-owned destinations. Their direct final stores
produce the requested native dtype and layout in the destination allocation,
so decoded pixels do not make a GPU-to-CPU-to-GPU round trip. The codec-wide
support boundary is maintained in
[docs/public-support.md](docs/public-support.md); the exact experimental Burn
adapter boundary is maintained in [docs/j2k-ml.md](docs/j2k-ml.md). Dated
hardware validation and performance results live only in
[docs/benchmark-evidence.md](docs/benchmark-evidence.md).

`j2k-ml` is only the thin Burn allocation and synchronization adapter over
these codec sessions. Readers such as `wsi-rs` remain responsible for finding
and supplying encoded image bytes. Codec support and correctness do not by
themselves constitute a speedup claim.

## Which crate should I use?

Use `cargo add j2k` for JPEG 2000 / HTJ2K application code. Lower-level
Expand All @@ -139,26 +172,20 @@ Use lower-level crates only when you need a specific integration point:
| JPEG-to-HTJ2K coefficient-domain transcode | `j2k-transcode` |
| CUDA adapters | `j2k-jpeg-cuda`, `j2k-cuda`, `j2k-transcode-cuda` |
| Metal adapters | `j2k-jpeg-metal`, `j2k-metal`, `j2k-transcode-metal` |
| Experimental Burn 0.21 tensor decode integration | `j2k-ml` (unpublished) |
| Experimental Burn 0.21 native integer batch adapter | `j2k-ml` (unpublished) |
| Tile compression codecs | `j2k-tilecodec` |
| Command-line inspection and JPEG-to-HTJ2K smoke transcode | `j2k-cli` |

The names `statumen` and `wsi-dicom` are not current package names.

## Support Matrix

| Area | Current support | Notes |
| --- | --- | --- |
| JPEG 2000 Part 1 inspect | Raw J2K/J2C codestreams and JP2 still-image files | Unsupported or malformed input fails explicitly. |
| JPEG 2000 Part 1 decode | Full-frame, ROI, scaled, row, tile-batch, and component-plane API surfaces | CPU is the portable correctness baseline. |
| JPEG 2000 Part 1 encode | Native Rust encode APIs for codestream and JP2 output, including component-plane metadata | Stable public API is centered on `j2k`; adapter SPI remains experimental. |
| HTJ2K Part 15 inspect/decode/encode | Raw HT codestreams and JPH still-image files, including cleanup and refinement paths | HT requests beyond the Part 15 coded-bitplane limit reject explicitly. |
| JP2/JPH metadata | IHDR/COLR/BPCC/PCLR/CMAP/CDEF/ICC still-image metadata paths covered by repo-local tests | Broader external JP2/JPH metadata parity remains publication evidence. |
| Recode | J2K-to-HTJ2K coefficient recode where valid, pixel-preserving fallback otherwise | Palette/component-mapped fallbacks intentionally drop mapping metadata after resolving pixels. |
| JPEG input | JPEG inspect/decode through `j2k-jpeg` | Used by transcode and fixture workflows. |
| JPEG-to-HTJ2K coefficient-domain transcode | CPU transcode primitives plus CUDA/Metal stage adapters | The public workflow requires HT block coding. |
| CUDA acceleration | J2K-owned CUDA kernels with CUDA Oxide as the target device-kernel backend | Requires self-hosted CUDA validation before performance claims. |
| Metal acceleration | macOS Metal adapters for selected decode, encode-stage, and transcode stages | Auto routing stays conservative and benchmark-gated. |
## Support and evidence

The living codec support matrix is
[docs/public-support.md](docs/public-support.md). The experimental Burn batch
adapter has a narrower, explicit boundary in
[docs/j2k-ml.md](docs/j2k-ml.md). Hardware measurements and their publication
qualifications are recorded separately in
[docs/benchmark-evidence.md](docs/benchmark-evidence.md).

## Fast Path For LLM-Assisted Use

Expand Down Expand Up @@ -231,8 +258,8 @@ Reference files:
environment variables
- [docs/public-support.md](docs/public-support.md) - exact J2K Part 1,
HTJ2K Part 15, JP2/JPH, and out-of-scope support boundary
- [docs/j2k-ml.md](docs/j2k-ml.md) - Burn tensor layouts, normalization,
batching, and accelerator route guarantees
- [docs/j2k-ml.md](docs/j2k-ml.md) - Burn native integer batch groups,
prepared reuse, and direct accelerator destination guarantees
- [docs/release.md](docs/release.md) - release and package validation policy
- [docs/stable-api-1.0.md](docs/stable-api-1.0.md) - stable API snapshot policy
- [CHANGELOG.md](CHANGELOG.md) - current release notes
Expand Down
13 changes: 13 additions & 0 deletions crates/j2k-core/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{backend::BackendRequest, pixel::PixelFormat, scale::Downscale, types

mod allocation;
mod collection;
mod gpu_job_chunk;

#[doc(hidden)]
pub use allocation::{
Expand All @@ -15,6 +16,12 @@ pub use allocation::{
pub use collection::{
try_collect_indexed_batch_results, try_collect_ordered_batch_results_with_limits,
};
#[doc(hidden)]
pub use gpu_job_chunk::{
plan_ht_gpu_job_chunks, HtGpuJobChunk, HtGpuJobChunkEntry, HtGpuJobChunkLimit,
HtGpuJobChunkLimits, HtGpuJobChunkPlan, HtGpuJobChunkPlanError, HtGpuJobChunkRequest,
HtGpuJobPassBucket,
};

/// Worker configuration for CPU tile batches.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
Expand Down Expand Up @@ -132,6 +139,12 @@ pub enum BatchInfrastructureError {
/// An internal planning boundary was invoked without any submitted jobs.
#[error("batch plan requires at least one job")]
EmptyBatchPlan,
/// A newer shared batch contract cannot be represented by this consumer.
#[error("unsupported batch contract: {what}")]
UnsupportedContract {
/// Contract element that the current consumer cannot represent.
what: &'static str,
},
/// Batch-owned metadata would exceed the operation's host-memory budget.
#[error("{what} is too large: requested {requested} bytes, cap {cap}")]
AllocationTooLarge {
Expand Down
Loading
Loading