Skip to content

Commit

Permalink
update BIOMDXTC to use LinearQuantizer
Browse files Browse the repository at this point in the history
  • Loading branch information
ayzk committed Dec 11, 2024
1 parent 54d5a4b commit d3e0220
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 111 deletions.
98 changes: 50 additions & 48 deletions include/SZ3/api/impl/SZAlgoBioMD.hpp
Original file line number Diff line number Diff line change
@@ -1,59 +1,61 @@
#ifndef SZ3_SZ_BIOMD_HPP
#define SZ3_SZ_BIOMD_HPP

#include "SZ3/quantizer/LinearQuantizer.hpp"
#include "SZ3/decomposition/SZBioMDXtcDecomposition.hpp"
#include "SZ3/decomposition/SZBioMDDecomposition.hpp"
#include "SZ3/decomposition/SZBioMDXtcDecomposition.hpp"
#include "SZ3/def.hpp"
#include "SZ3/encoder/XtcBasedEncoder.hpp"
#include "SZ3/lossless/Lossless_zstd.hpp"
#include "SZ3/lossless/Lossless_bypass.hpp"
#include "SZ3/utils/Statistic.hpp"
#include "SZ3/lossless/Lossless_zstd.hpp"
#include "SZ3/quantizer/LinearQuantizer.hpp"
#include "SZ3/utils/Config.hpp"
#include "SZ3/def.hpp"
#include "SZ3/utils/Statistic.hpp"

namespace SZ3 {

template<class T, uint N>
size_t SZ_compress_bioMD(Config &conf, T *data, uchar *cmpData, size_t cmpCap) {
assert(N == conf.N);
assert(conf.cmprAlgo == ALGO_BIOMD);
calAbsErrorBound(conf, data);

auto quantizer = LinearQuantizer<T>(conf.absErrorBound, conf.quantbinCnt / 2);
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomd<T, N>(conf, quantizer), HuffmanEncoder<int>(),
Lossless_zstd());
return sz->compress(conf, data, cmpData, cmpCap);
}

template<class T, uint N>
void SZ_decompress_bioMD(const Config &conf, const uchar *cmpData, size_t cmpSize, T *decData) {
assert(conf.cmprAlgo == ALGO_BIOMD);

LinearQuantizer<T> quantizer;
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomd<T, N>(conf, quantizer),
HuffmanEncoder<int>(), Lossless_zstd());
sz->decompress(conf, cmpData, cmpSize, decData);
}

template<class T, uint N>
size_t SZ_compress_bioMDXtcBased(Config &conf, T *data, uchar *cmpData, size_t cmpCap) {
assert(N == conf.N);
assert(conf.cmprAlgo == ALGO_BIOMDXTC);
calAbsErrorBound(conf, data);

auto sz = make_compressor_sz_generic<T, N>(SZBioMDXtcDecomposition<T, N>(conf), XtcBasedEncoder<int>(),
Lossless_bypass());
return sz->compress(conf, data, cmpData, cmpCap);
}

template<class T, uint N>
void SZ_decompress_bioMDXtcBased(const Config &conf, const uchar *cmpData, size_t cmpSize, T *decData) {
assert(conf.cmprAlgo == ALGO_BIOMDXTC);

auto sz = make_compressor_sz_generic<T, N>(SZBioMDXtcDecomposition<T, N>(conf),
XtcBasedEncoder<int>(), Lossless_bypass());
sz->decompress(conf, cmpData, cmpSize, decData);
}


template <class T, uint N>
size_t SZ_compress_bioMD(Config &conf, T *data, uchar *cmpData, size_t cmpCap) {
assert(N == conf.N);
assert(conf.cmprAlgo == ALGO_BIOMD);
calAbsErrorBound(conf, data);

auto quantizer = LinearQuantizer<T>(conf.absErrorBound, conf.quantbinCnt / 2);
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomd<T, N>(conf, quantizer), HuffmanEncoder<int>(),
Lossless_zstd());
return sz->compress(conf, data, cmpData, cmpCap);
}

template <class T, uint N>
void SZ_decompress_bioMD(const Config &conf, const uchar *cmpData, size_t cmpSize, T *decData) {
assert(conf.cmprAlgo == ALGO_BIOMD);

LinearQuantizer<T> quantizer;
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomd<T, N>(conf, quantizer), HuffmanEncoder<int>(),
Lossless_zstd());
sz->decompress(conf, cmpData, cmpSize, decData);
}

template <class T, uint N>
size_t SZ_compress_bioMDXtcBased(Config &conf, T *data, uchar *cmpData, size_t cmpCap) {
assert(N == conf.N);
assert(conf.cmprAlgo == ALGO_BIOMDXTC);
calAbsErrorBound(conf, data);

auto quantizer = LinearQuantizer<T>(conf.absErrorBound, std::numeric_limits<int>::max() / 16);
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomdxtc<T, N>(conf, quantizer),
XtcBasedEncoder<int>(), Lossless_bypass());
return sz->compress(conf, data, cmpData, cmpCap);
}

template <class T, uint N>
void SZ_decompress_bioMDXtcBased(const Config &conf, const uchar *cmpData, size_t cmpSize, T *decData) {
assert(conf.cmprAlgo == ALGO_BIOMDXTC);

LinearQuantizer<T> quantizer;
auto sz = make_compressor_sz_generic<T, N>(make_decomposition_biomdxtc<T, N>(conf, quantizer),
XtcBasedEncoder<int>(), Lossless_bypass());
sz->decompress(conf, cmpData, cmpSize, decData);
}

} // namespace SZ3
#endif
13 changes: 4 additions & 9 deletions include/SZ3/decomposition/SZBioMDDecomposition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,10 @@ class SZBioMDDecomposition : public concepts::DecompositionInterface<T, int, N>
public:
SZBioMDDecomposition(const Config &conf, Quantizer quantizer) : quantizer(quantizer), conf(conf) {
if (N != 1 && N != 2 && N != 3) {
throw std::invalid_argument("SZBioFront only support 1D, 2D or 3D data");
throw std::invalid_argument("SZBioMDDecomposition only support 1D, 2D or 3D data");
}
}

~SZBioMDDecomposition() {
// clear();
}


std::vector<int> compress(const Config &conf, T *data) override {
if (N == 1) {
return compress_1d(data);
Expand Down Expand Up @@ -353,9 +348,9 @@ class SZBioMDDecomposition : public concepts::DecompositionInterface<T, int, N>
T fillValue_;
};

template <class T, uint N, class Predictor>
SZBioMDDecomposition<T, N, Predictor> make_decomposition_biomd(const Config &conf, Predictor predictor) {
return SZBioMDDecomposition<T, N, Predictor>(conf, predictor);
template <class T, uint N, class Quantizer>
SZBioMDDecomposition<T, N, Quantizer> make_decomposition_biomd(const Config &conf, Quantizer quantizer) {
return SZBioMDDecomposition<T, N, Quantizer>(conf, quantizer);
}
} // namespace SZ3

Expand Down
77 changes: 23 additions & 54 deletions include/SZ3/decomposition/SZBioMDXtcDecomposition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

namespace SZ3 {

template <class T, uint N>
template <class T, uint N, class Quantizer>
class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int, N> {
public:
SZBioMDXtcDecomposition(const Config &conf) : conf(conf) {
SZBioMDXtcDecomposition(const Config &conf, Quantizer quantizer) : quantizer(quantizer), conf(conf) {
if (N != 1 && N != 2 && N != 3) {
throw std::invalid_argument("SZBioFront only support 1D, 2D or 3D data");
throw std::invalid_argument("SZBioMDXtcDecomposition only support 1D, 2D or 3D data");
}
}

Expand All @@ -41,20 +41,18 @@ class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int,
void save(uchar *&c) override {
write(firstFillFrame_, c);
write(fillValue_, c);
quantizer.save(c);
}

void load(const uchar *&c, size_t &remaining_length) override {
clear();
// const uchar *c_pos = c;
read(firstFillFrame_, c, remaining_length);
read(fillValue_, c, remaining_length);
quantizer.load(c, remaining_length);
}

void clear() {}

size_t size_est() override { return 0; }

std::pair<int, int> get_out_range() override { return {0, 0}; }
std::pair<int, int> get_out_range() override { return quantizer.get_out_range(); }

size_t get_num_elements() const {
if (N == 3) {
Expand All @@ -66,35 +64,18 @@ class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int,
private:
std::vector<int> compressSingleFrame(T *data) {
std::vector<int> quantData(conf.num);

/* To prevent that potential rounding errors make the error slightly larger than the
* absolute error bound, scale down the error limit slightly.
* The precision is twice the required maximum error. */
double reciprocalPrecision = 1.0 / (conf.absErrorBound * 0.99999 * 2.0);
// Define the range limits for int as double
const auto INT_MIN_D = static_cast<double>(std::numeric_limits<int>::min())/4;
const auto INT_MAX_D = static_cast<double>(std::numeric_limits<int>::max())/4;
for (size_t i = 0; i < conf.num; i++) {
double quant = std::floor(data[i] * reciprocalPrecision + 0.5);
// Range checking
if (quant < INT_MIN_D || quant > INT_MAX_D) {
throw std::out_of_range("Quantization value out of int range in SZBioMDXtcDecomposition, consider "
"increasing the error bound");
}
quantData[i] = static_cast<int>(quant);
quantData[i] = quantizer.quantize_and_overwrite(data[i], 0);
}
quantizer.postcompress_data();
return quantData;
}

T *decompressSingleFrame(std::vector<int> &quantData, T *decData) {
/* To prevent that potential rounding errors make the error slightly larger than the
* absolute error bound, scale down the error limit slightly.
* The precision is twice the required maximum error. */
double precision = conf.absErrorBound * 0.99999 * 2.0;

for (size_t i = 0; i < conf.num; i++) {
decData[i] = quantData[i] * precision;
decData[i] = quantizer.recover(0, quantData[i]);
}
quantizer.postdecompress_data();
return decData;
}

Expand Down Expand Up @@ -147,29 +128,15 @@ class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int,
size_t lastFrame = std::min(dims[0], firstFillFrame_);
std::vector<int> quantData(lastFrame * dims[1] * dims[2]);

/* To prevent that potential rounding errors make the error slightly larger than the
* absolute error bound, scale down the error limit slightly.
* The precision is twice the required maximum error. */
double reciprocalPrecision = 1.0 / (conf.absErrorBound * 0.99999 * 2.0);
const auto INT_MIN_D = static_cast<double>(std::numeric_limits<int>::min())/4;
const auto INT_MAX_D = static_cast<double>(std::numeric_limits<int>::max())/4;

for (size_t i = 0; i < lastFrame; i++) // time
{
for (size_t j = 0; j < dims[1]; j++) // atoms
{
for (size_t k = 0; k < dims[2]; k++) // xyz
{
for (size_t i = 0; i < lastFrame; i++) { // time
for (size_t j = 0; j < dims[1]; j++) { // atoms
for (size_t k = 0; k < dims[2]; k++) { // xyz
size_t idx = i * stride[0] + j * stride[1] + k;
double quant = std::floor(data[idx] * reciprocalPrecision + 0.5);
if (quant < INT_MIN_D || quant > INT_MAX_D) {
throw std::out_of_range("Quantization value out of int range in SZBioMDXtcDecomposition, consider "
"increasing the error bound");
}
quantData[idx] = static_cast<int>(quant);
quantData[idx] = quantizer.quantize_and_overwrite(data[idx], 0);
}
}
}
quantizer.postcompress_data();

return quantData;
}
Expand All @@ -182,19 +149,15 @@ class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int,

size_t lastFrame = std::min(dims[0], firstFillFrame_);

/* To prevent that potential rounding errors make the error slightly larger than the
* absolute error bound, scale down the error limit slightly.
* The precision is twice the required maximum error. */
double precision = conf.absErrorBound * 0.99999 * 2.0;

for (size_t i = 0; i < lastFrame; i++) { // time
for (size_t j = 0; j < dims[1]; j++) { // atoms
for (size_t k = 0; k < dims[2]; k++) { // xyz
size_t idx = i * stride[0] + j * stride[1] + k;
decData[idx] = quantData[idx] * precision;
decData[idx] = quantizer.recover(0, quantData[idx]);
}
}
}
quantizer.postdecompress_data();

/* Fill frames at the end with the fill value. */
for (size_t i = firstFillFrame_; i < dims[0]; i++) {
Expand All @@ -210,8 +173,14 @@ class SZBioMDXtcDecomposition : public concepts::DecompositionInterface<T, int,
Config conf;
size_t firstFillFrame_;
T fillValue_;
Quantizer quantizer;
};

template <class T, uint N, class Quantizer>
SZBioMDXtcDecomposition<T, N, Quantizer> make_decomposition_biomdxtc(const Config &conf, Quantizer quantizer) {
return SZBioMDXtcDecomposition<T, N, Quantizer>(conf, quantizer);
}

} // namespace SZ3

#endif

0 comments on commit d3e0220

Please sign in to comment.