tensogram_sz3_sys/lib.rs
1// (C) Copyright 2026- ECMWF and individual contributors.
2//
3// This software is licensed under the terms of the Apache Licence Version 2.0
4// which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5// In applying this licence, ECMWF does not waive the privileges and immunities
6// granted to it by virtue of its status as an intergovernmental organisation nor
7// does it submit to any jurisdiction.
8
9//! Clean-room FFI bindings for the SZ3 lossy compression library.
10//!
11//! This crate provides low-level C FFI bindings to the SZ3 header-only C++
12//! library via a thin C++ shim (`cpp/sz3_ffi.cpp`).
13
14#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
15
16/// Flat C-compatible configuration struct mirroring the SZ3 C++ `Config` class.
17///
18/// The `dims` pointer is heap-allocated on the C++ side when returned from
19/// [`sz3_decompress_config`]; the caller must free it with [`sz3_dealloc_size_t`].
20#[repr(C)]
21#[derive(Clone, Copy)]
22pub struct SZ3_Config {
23 pub N: u8,
24 pub dims: *mut usize,
25 pub num: usize,
26 pub errorBoundMode: u8,
27 pub absErrorBound: f64,
28 pub relErrorBound: f64,
29 pub l2normErrorBound: f64,
30 pub psnrErrorBound: f64,
31 pub cmprAlgo: u8,
32 pub lorenzo: bool,
33 pub lorenzo2: bool,
34 pub regression: bool,
35 pub openmp: bool,
36 pub dataType: u8,
37 pub blockSize: i32,
38 pub quantbinCnt: i32,
39}
40
41// ---------------------------------------------------------------------------
42// Per-type modules – each exposes compress_size_bound, compress, decompress
43// ---------------------------------------------------------------------------
44
45macro_rules! impl_sz3_type {
46 ($mod_name:ident, $rust_ty:ty, $data_type:expr_2021, $suffix:ident) => {
47 pub mod $mod_name {
48 use super::SZ3_Config;
49
50 /// The Rust primitive type this module operates on.
51 pub type ty = $rust_ty;
52
53 /// SZ3 `dataType` discriminant for this type.
54 pub const DATA_TYPE_TYPE: u8 = $data_type;
55
56 unsafe extern "C" {
57 #[link_name = concat!("sz3_compress_size_bound_", stringify!($suffix))]
58 pub fn compress_size_bound(config: SZ3_Config) -> usize;
59
60 #[link_name = concat!("sz3_compress_", stringify!($suffix))]
61 pub fn compress(
62 config: SZ3_Config,
63 data: *const ty,
64 compressed_data: *mut i8,
65 compressed_capacity: usize,
66 ) -> usize;
67
68 #[link_name = concat!("sz3_decompress_", stringify!($suffix))]
69 pub fn decompress(
70 compressed_data: *const i8,
71 compressed_len: usize,
72 decompressed_data: *mut ty,
73 );
74 }
75 }
76 };
77}
78
79impl_sz3_type!(impl_f32, f32, 0, f32);
80impl_sz3_type!(impl_f64, f64, 1, f64);
81impl_sz3_type!(impl_u8, u8, 2, u8);
82impl_sz3_type!(impl_i8, i8, 3, i8);
83impl_sz3_type!(impl_u16, u16, 4, u16);
84impl_sz3_type!(impl_i16, i16, 5, i16);
85impl_sz3_type!(impl_u32, u32, 6, u32);
86impl_sz3_type!(impl_i32, i32, 7, i32);
87impl_sz3_type!(impl_u64, u64, 8, u64);
88impl_sz3_type!(impl_i64, i64, 9, i64);
89
90// ---------------------------------------------------------------------------
91// Top-level helpers
92// ---------------------------------------------------------------------------
93
94unsafe extern "C" {
95 /// Parse a compressed SZ3 blob and return its configuration **without**
96 /// decompressing the payload. The returned `SZ3_Config::dims` pointer is
97 /// heap-allocated; free it with [`sz3_dealloc_size_t`].
98 pub fn sz3_decompress_config(data: *const i8, len: usize) -> SZ3_Config;
99
100 /// Free a `size_t[]` pointer that was allocated on the C++ side (e.g. the
101 /// `dims` field of [`SZ3_Config`]).
102 pub fn sz3_dealloc_size_t(ptr: *mut usize);
103}
104
105// ---------------------------------------------------------------------------
106// Constants
107// ---------------------------------------------------------------------------
108
109/// SZ3 algorithm and error-bound mode constants.
110///
111/// Named to match the C++ `SZ3::` namespace; the `ALGO_` and `EB_` prefixes
112/// distinguish compression-algorithm IDs from error-bound mode IDs.
113#[allow(non_snake_case)]
114pub mod SZ3 {
115 // Compression algorithms
116 pub const ALGO_ALGO_LORENZO_REG: u32 = 0;
117 pub const ALGO_ALGO_INTERP_LORENZO: u32 = 1;
118 pub const ALGO_ALGO_INTERP: u32 = 2;
119 pub const ALGO_ALGO_NOPRED: u32 = 3;
120 pub const ALGO_ALGO_LOSSLESS: u32 = 4;
121 pub const ALGO_ALGO_BIOMD: u32 = 5;
122 pub const ALGO_ALGO_BIOMDXTC: u32 = 6;
123
124 // Error-bound modes
125 pub const EB_EB_ABS: u32 = 0;
126 pub const EB_EB_REL: u32 = 1;
127 pub const EB_EB_PSNR: u32 = 2;
128 pub const EB_EB_L2NORM: u32 = 3;
129 pub const EB_EB_ABS_AND_REL: u32 = 4;
130 pub const EB_EB_ABS_OR_REL: u32 = 5;
131}