Skip to content

Commit bb96edb

Browse files
committed
another cusz-hi fix
1 parent 8e581a8 commit bb96edb

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Version numbers follow [Semantic Versioning](https://semver.org/).
1010
## [Unreleased] — 2.0.0
1111

1212
### Fixed
13+
- `examples/presets/cusz_hi_tp.toml` — set `code_type = "uint8"` + `quant_radius = 128` on the GInterp stage (was `uint16` / `32768`), matching cuSZ-Hi's actual spline ectrl (`ErrCtrlTrait<1> = u1`, `context.h` default `dict_size=256, radius=128`). Native's spline quant emits **1-byte** codes in `[0, 256)` and escapes any residual outside ±128 to the outlier compaction buffer (`spline3.inl:564`); our old preset used 2-byte codes with a wide radius that kept every residual inline, so the code stream was both twice as wide and higher-entropy. Halving the code width + tightening the radius roughly doubles TP CR at identical fidelity: **CLDHGH 7.68× → 12.47×** (native 13.33×), NYX 512³ 4.58× → 7.74×, CESM 4.11× → 7.65×; round-trip PSNR unchanged (CLDHGH 66.81 dB). This closes almost the entire TP-mode CR deficit vs native. Verified this was **not** an auto-tuning gap: enabling `auto_tuning = 3/4` on top adds < 0.5% CR (12.47× → 12.51×). Also confirmed not a BIT/RRE gap — our `RREStage` is the vendored LC `d_RRE`, and reimplementing bitshuffle as native's exact `d_BIT_1` gave zero change. (Supersedes the earlier `quant_radius = 32768` interim fix, which only reached 7.68×.)
1314
- **GInterp (cuSZ-Hi spline) produced non-deterministic, sometimes catastrophically wrong (~1e9 error) reconstructions on data with extreme values / sharp gradients — e.g. NYX/temperature, which round-tripped at PSNR ≈ −8 dB (garbage) instead of ~75 dB.** Three root causes, all fixed:
1415
1. `modules/fused/ginterp/ginterp_md.inl` `x_reset_scratch_data()` (decode) zeroed the reconstruction scratch `s_xdata` **only at anchor corners**, leaving every non-corner slot holding leftover shared memory from a previous block (the literal `TODO explicitly handle zero-padding`). Any interpolation position read before write returned non-deterministic garbage. Now zeros all of `s_xdata`, mirroring the encoder's `c_reset_scratch_data()` (which already zeros all of `s_data`). This alone made *decode* deterministic.
1516
2. `modules/fused/ginterp/ginterp_md.inl` `c_reset_scratch_data()` (encode) symmetrically initialized the quant-code scratch `s_ectrl` **only at anchor corners**; non-corner slots the interpolation stencil skipped serialized leftover shared memory into the blob. Now initializes all of `s_ectrl` to the zero-residual code (`radius`).

‎examples/presets/cusz_hi_tp.toml‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ memory_strategy = "MINIMAL"
1313
name = "gi"
1414
type = "GInterp"
1515
input_type = "float32"
16-
code_type = "uint16"
16+
code_type = "uint8" # match cuSZ-Hi's spline ectrl (ErrCtrlTrait<1> = u1).
17+
# 1 byte/code, half the code-stream bytes of uint16.
1718
error_bound = 1e-3
1819
error_bound_mode = "NOA"
19-
outlier_capacity = 0.2
20+
quant_radius = 128 # match cuSZ-Hi's spline default (dict_size=256, radius=128).
21+
# Codes live in [0,256) so they fit a single byte; residuals
22+
# outside +/-128 escape to the outlier buffer (compaction),
23+
# exactly as native does. Together with uint8 codes this ~2x's
24+
# the CR vs the old uint16/r32768 config (CLDHGH 7.68->12.47x,
25+
# native 13.33x) at identical fidelity. Auto-tuning adds <0.5%.
26+
outlier_capacity = 0.2 # radius-128 pushes more residuals to outliers than a wide
27+
# radius would; 20% capacity covers sharp fields (e.g. NYX).
2028

2129
# ── codes chain: TCMS1 -> BIT1 -> RRE1 ──
2230
[[stage]]

0 commit comments

Comments
 (0)