#include <SZ3/api/sz.hpp>
#include <cstring>
#include <cstdlib>
#include <cstdint>
#include <vector>
struct SZ3_Config_C {
uint8_t N;
size_t* dims;
size_t num;
uint8_t errorBoundMode;
double absErrorBound;
double relErrorBound;
double l2normErrorBound;
double psnrErrorBound;
uint8_t cmprAlgo;
bool lorenzo;
bool lorenzo2;
bool regression;
bool openmp;
uint8_t dataType;
int32_t blockSize;
int32_t quantbinCnt;
};
static SZ3::Config config_c_to_cpp(SZ3_Config_C c) {
std::vector<size_t> dims_vec(c.dims, c.dims + c.N);
SZ3::Config cfg;
cfg.setDims(dims_vec.begin(), dims_vec.end());
cfg.errorBoundMode = c.errorBoundMode;
cfg.absErrorBound = c.absErrorBound;
cfg.relErrorBound = c.relErrorBound;
cfg.l2normErrorBound = c.l2normErrorBound;
cfg.psnrErrorBound = c.psnrErrorBound;
cfg.cmprAlgo = c.cmprAlgo;
cfg.lorenzo = c.lorenzo;
cfg.lorenzo2 = c.lorenzo2;
cfg.regression = c.regression;
cfg.openmp = c.openmp;
cfg.dataType = c.dataType;
cfg.blockSize = c.blockSize;
cfg.quantbinCnt = c.quantbinCnt;
return cfg;
}
static SZ3_Config_C config_cpp_to_c(const SZ3::Config& cfg) {
SZ3_Config_C c{};
c.N = static_cast<uint8_t>(cfg.N);
c.dims = new size_t[cfg.dims.size()];
std::memcpy(c.dims, cfg.dims.data(), cfg.dims.size() * sizeof(size_t));
c.num = cfg.num;
c.errorBoundMode = cfg.errorBoundMode;
c.absErrorBound = cfg.absErrorBound;
c.relErrorBound = cfg.relErrorBound;
c.l2normErrorBound = cfg.l2normErrorBound;
c.psnrErrorBound = cfg.psnrErrorBound;
c.cmprAlgo = cfg.cmprAlgo;
c.lorenzo = cfg.lorenzo;
c.lorenzo2 = cfg.lorenzo2;
c.regression = cfg.regression;
c.openmp = cfg.openmp;
c.dataType = cfg.dataType;
c.blockSize = cfg.blockSize;
c.quantbinCnt = cfg.quantbinCnt;
return c;
}
#define SZ3_FFI_IMPL(T, suffix) \
\
extern "C" size_t sz3_compress_size_bound_##suffix(SZ3_Config_C config) { \
auto cfg = config_c_to_cpp(config); \
using namespace SZ3; \
return SZ_compress_size_bound<T>(cfg); \
} \
\
extern "C" size_t sz3_compress_##suffix( \
SZ3_Config_C config, \
const T* data, \
char* compressed_data, \
size_t compressed_capacity) { \
auto cfg = config_c_to_cpp(config); \
return SZ_compress<T>(cfg, data, compressed_data, compressed_capacity); \
} \
\
extern "C" void sz3_decompress_##suffix( \
const char* compressed_data, \
size_t compressed_len, \
T* decompressed_data) { \
using namespace SZ3; \
Config cfg; \
SZ_decompress<T>(cfg, compressed_data, compressed_len, decompressed_data);\
}
SZ3_FFI_IMPL(float, f32)
SZ3_FFI_IMPL(double, f64)
SZ3_FFI_IMPL(uint8_t, u8)
SZ3_FFI_IMPL(int8_t, i8)
SZ3_FFI_IMPL(uint16_t, u16)
SZ3_FFI_IMPL(int16_t, i16)
SZ3_FFI_IMPL(uint32_t, u32)
SZ3_FFI_IMPL(int32_t, i32)
SZ3_FFI_IMPL(uint64_t, u64)
SZ3_FFI_IMPL(int64_t, i64)
extern "C" SZ3_Config_C sz3_decompress_config(const char* data, size_t len) {
using namespace SZ3;
auto pos = reinterpret_cast<const unsigned char*>(data);
Config cfg;
read(cfg.sz3MagicNumber, pos);
read(cfg.sz3DataVer, pos);
uint64_t cmpDataSize = 0;
read(cmpDataSize, pos);
auto confPos = pos + cmpDataSize;
cfg.load(confPos);
return config_cpp_to_c(cfg);
}
extern "C" void sz3_dealloc_size_t(size_t* ptr) {
delete[] ptr;
}