Skip to main content

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}