COOLJAPAN
← All posts

SciRS2 0.6.2 Released — Real HDF5, a Silent Data-Loss Fix, and Four C Dependencies Gone

SciRS2 0.6.2 replaces the C-linked hdf5 crate with pure-Rust oxih5, fixing a critical silent-data-loss bug in compressed HDF5 writes and a self-concealing dataspace-parsing bug along the way. libnuma, tracy-client, and opencl3 are gone from the dependency graph, plus a breaking TLS-provider hardening. Pure Rust, Apache-2.0.

release scirs2 rust scientific-computing pure-rust hdf5 security correctness

A compression code path that silently discarded every value handed to it, behind a comment conceding “actual dataset.write() calls would go here.” A dataspace parser that misread a four-byte header as three, and got away with it because its own test fixture was built to match the bug. SciRS2 0.6.2 found both, fixed both, and removed the C library that made the first one hard to see.

Today we released SciRS2 0.6.2 — a Pure Rust hardening release that retires the C-linked hdf5 crate in favor of a real pure-Rust backend, closes a critical silent-data-loss bug that shipped inside the code path it replaces, and drops libnuma, tracy-client, and opencl3 from the dependency graph entirely. A breaking TLS-provider change closes out the cycle.

No C. No Fortran. No CUDA Toolkit, no system BLAS, and — as of this release — no system libhdf5 either. SciRS2 0.6.2 compiles to a single static binary (or WASM) and runs everywhere, with four fewer native libraries standing between cargo build and a working binary than it had a week ago.

Why SciRS2 0.6.2 is a game changer

C dependencies in a Rust scientific stack don’t just cost you a system package install — they cost you visibility. The failure modes this release fixes were all hiding behind exactly that opacity:

SciRS2 0.6.2 ends all of that, concretely:

Technical Deep Dive: what “pure Rust” actually removes

The compression bug, precisely. create_dataset_with_compression had two branches: a “native” one that created the HDF5 dataset object and then matched on the value’s type with arms like let _data_size = array.len(); — computing a size, discarding the array, writing nothing — and a fallback create_fallback_dataset that was the only branch that actually stored anything. Because the native branch returned early, every caller that reached it (write_datasets_parallel, write_hdf5_enhanced) silently lost data while reporting fabricated compression statistics for the values it had just dropped. The fix deletes the native branch outright — the storing path is now the only path.

Why the dataspace bug survived. HDF5’s version-2 Dataspace message format specifies a type byte immediately after the flags byte in its header. The old parser read flags and then treated the next field as if type didn’t exist, shifting every subsequent dimension read one byte early. Bugs like this are usually caught by round-tripping against real files — but the module’s own test fixture was constructed by hand to match the parser’s expectations, not the HDF5 specification, so the bug and its test formed a closed, self-consistent loop that never touched reality. oxih5 parses the header correctly; the fixture — preserved as scirs2-io/tests/hdf5_conformance.rs — was corrected to emit spec-conformant bytes, with a regression test now pinning that the old truncated form is rejected.

The TLS change, and why it’s automatic. reqwest and ureq now build with rustls-no-provider instead of pulling in the default aws-lc-rs (C) backend — but that would normally push a manual CryptoProvider::install_default(...) call onto every downstream application. SciRS2 avoids that by installing a pure-Rust oxitls-rustcrypto-provider as the process-default on first use of its own networking code, and only if the process doesn’t already have one installed. It’s also preferred over the abandoned upstream rustls-rustcrypto 0.0.2-alpha because it fixes RUSTSEC-2026-0104, an unpatched CRL-parsing panic in rustls-webpki.

One exception, deliberately kept. scirs2-core’s mpsgraph feature (Apple MPSGraph GPU acceleration, macOS-only, off by default) still compiles a small Objective-C wrapper via the cc crate. There is no pure-Rust binding path to that framework yet, and the feature stays opt-in — everything else in this release moved off C entirely.

Getting Started

Two of 0.6.2’s headline changes, both usable without any extra Cargo feature now:

cargo add scirs2-io scirs2-core --features scirs2-core/tracy
use scirs2_core::profiling::tracy::TracyClient;

fn main() {
    // Pure-Rust Tracy-compatible profiling -- no C++ client linked,
    // even with the `tracy` feature enabled.
    let client = TracyClient::new();
    if client.is_active() {
        client.message("profiling enabled");
    }
    {
        let _span = client.span("my_operation");
        // work here
    } // span ends on drop

    // Export to Chrome Trace Event Format -- open in ui.perfetto.dev
    // or chrome://tracing. Valid even with the `tracy` feature off,
    // where it writes an empty-but-valid trace document.
    let _ = client.export_chrome_trace(std::env::temp_dir().join("trace.json"));
}
use scirs2_io::matlab::enhanced::{EnhancedMatFile, MatFileConfig};
use scirs2_io::matlab::MatType;
use scirs2_core::ndarray::{ArrayD, IxDyn};
use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // use_v73 no longer needs the `hdf5` feature or a system libhdf5 --
    // oxih5 backs it in default builds as of 0.6.2.
    let mat = EnhancedMatFile::new(MatFileConfig {
        use_v73: true,
        ..Default::default()
    });

    let data = ArrayD::from_shape_vec(IxDyn(&[2, 2]), vec![1.0, 2.0, 3.0, 4.0])?;
    let mut vars = HashMap::new();
    vars.insert("data".to_string(), MatType::Double(data));

    let path = std::env::temp_dir().join("example.mat");
    mat.write(&path, &vars)?;
    let loaded = mat.read(&path)?;
    assert!(loaded.contains_key("data"));
    Ok(())
}

What’s New in 0.6.2

Added

Removed

Changed

Fixed

See CHANGELOG.md [0.6.2] for the complete list.

Tips

  1. Drop the hdf5 feature flag from your Cargo.toml. MAT v7.3 and general HDF5 support work in default builds now — if you were enabling hdf5 just to unlock EnhancedMatFile/V73MatFile, that feature gate no longer exists to enable.
  2. If you use scirs2_io::hdf5_lite directly, migrate now. The module is deleted, not deprecated. Move to oxih5::File, which is a strict superset of what hdf5_lite could read — including files that used to fail with a format error.
  3. Re-check any get_compression_stats() call sites. The return type changed to Result<CompressionStats>, and the numbers are now real measurements — a ratio below 1.0 is an expected, honest answer for oxih5’s uncompressed writer output, not a regression.
  4. If your process installs a custom rustls::CryptoProvider, install it before first use of SciRS2 networking. SciRS2 only installs its own pure-Rust provider when nothing has claimed the process-default slot yet — an existing default is never overridden.
  5. Re-run anything that depends on NumaTopology::detect() output. Both the scirs2-core/libnuma path and scirs2-spatial’s independent implementation now report real topology instead of an estimate — code that special-cased the old “8 CPUs per node” heuristic should be re-verified against actual hardware.
  6. mpsgraph is still the one opt-in exception. If you’re on macOS and want Apple MPSGraph acceleration, that feature still compiles a small Objective-C wrapper — everything else in scirs2-core’s default build is C-free.

This is the foundation

SciRS2 0.6.2 is the sovereign scientific-computing layer of the COOLJAPAN ecosystem — and a release that removes silent data loss and four C dependencies in the same cycle matters precisely because so much builds on top of it:

Every one of these inherits SciRS2’s I/O layer along with everything else — a compressed HDF5 write that used to silently drop data is one less place a downstream training pipeline could lose a checkpoint without ever knowing it. Storage runs on OxiH5; the numeric core still rests on OxiBLAS and OxiFFT; verification on OxiZ; the NVIDIA performance path on OxiCUDA; TLS on OxiTLS. No C. No Fortran. No exceptions in the default build.

Repository: https://github.com/cool-japan/scirs

Star the repo if you’d rather a compression bug fail loudly at compile time than silently at runtime.

The era of “it probably wrote the file” is over. Pure Rust scientific computing is here — fast, safe, and honest about what actually made it to disk.

KitaSan at COOLJAPAN OÜ July 22, 2026

↑ Back to all posts