6#include <kernel/util/pack.hpp>
11#include <kernel/util/math.hpp>
12#include <kernel/util/type_traits.hpp>
36 static void swap(
void* )
45 static void swap(
void* x)
47 u16& v = *
reinterpret_cast<u16*
>(x);
48 v =
u16(((v & 0x00FFULL) << 8) | ((v & 0xFF00ULL) >> 8));
55 static void swap(
void* x)
57 u32& v = *
reinterpret_cast<u32*
>(x);
58 v =
u32(((v & 0x000000FFULL) << 24) | ((v & 0x0000FF00ULL) << 8) |
59 ((v & 0x00FF0000ULL) >> 8) | ((v & 0xFF000000ULL) >> 24));
66 static void swap(
void* x)
68 u64& v = *
reinterpret_cast<u64*
>(x);
69 v = ((v & 0x00000000000000FFULL) << 56) | ((v & 0x000000000000FF00ULL) << 40) |
70 ((v & 0x0000000000FF0000ULL) << 24) | ((v & 0x00000000FF000000ULL) << 8) |
71 ((v & 0x000000FF00000000ULL) >> 8) | ((v & 0x0000FF0000000000ULL) >> 24) |
72 ((v & 0x00FF000000000000ULL) >> 40) | ((v & 0xFF00000000000000ULL) >> 56);
79 static void swap(
void* x)
82 u64* vv =
reinterpret_cast<u64*
>(x);
132 template<
typename X_,
typename T_>
133 static std::size_t
xencode(
void* buf,
const T_* src,
const std::size_t count,
bool swap_bytes)
135 X_* x =
reinterpret_cast<X_*
>(buf);
138 for(std::size_t i(0); i < count; ++i)
140 x[i] =
xswap(
static_cast<X_
>(src[i]));
145 for(std::size_t i(0); i < count; ++i)
147 x[i] =
static_cast<X_
>(src[i]);
150 return count *
sizeof(X_);
183 template<
typename X_,
typename T_>
184 static std::size_t
xdecode(T_* dest,
const void* buf,
const std::size_t count,
bool swap_bytes)
186 const X_* x =
reinterpret_cast<const X_*
>(buf);
189 for(std::size_t i(0); i < count; ++i)
191 dest[i] =
static_cast<T_
>(
xswap(x[i]));
196 for(std::size_t i(0); i < count; ++i)
198 dest[i] =
static_cast<T_
>(x[i]);
201 return count *
sizeof(X_);
204 template<
typename T
class_,
bool signed_>
207 template<
typename T_>
210 return Pack::Type::None;
218 template<
typename T_>
224 case 2:
return Pack::Type::F16;
225 case 4:
return Pack::Type::F32;
226 case 8:
return Pack::Type::F64;
227 case 16:
return Pack::Type::F128;
228 default:
return Pack::Type::None;
232 template<
typename T_>
234 encode(
void* buf,
const T_* t,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
238#ifdef FEAT_HAVE_PACK_TYPE_F16
239 case Pack::Type::F16:
return xencode<Pack::f16>(buf, t, count, swap_bytes);
241 case Pack::Type::F32:
return xencode<Pack::f32>(buf, t, count, swap_bytes);
242 case Pack::Type::F64:
return xencode<Pack::f64>(buf, t, count, swap_bytes);
243#ifdef FEAT_HAVE_PACK_TYPE_F128
244 case Pack::Type::F128:
return xencode<Pack::f128>(buf, t, count, swap_bytes);
246 default:
XABORTM(
"invalid data type conversion");
250 template<
typename T_>
252 decode(T_* t,
const void* buf,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
256#ifdef FEAT_HAVE_PACK_TYPE_F16
257 case Pack::Type::F16:
return xdecode<Pack::f16>(t, buf, count, swap_bytes);
259 case Pack::Type::F32:
return xdecode<Pack::f32>(t, buf, count, swap_bytes);
260 case Pack::Type::F64:
return xdecode<Pack::f64>(t, buf, count, swap_bytes);
261#ifdef FEAT_HAVE_PACK_TYPE_F128
262 case Pack::Type::F128:
return xdecode<Pack::f128>(t, buf, count, swap_bytes);
264 default:
XABORTM(
"invalid data type conversion");
273 template<
typename T_>
278 case 1:
return Pack::Type::I8;
279 case 2:
return Pack::Type::I16;
280 case 4:
return Pack::Type::I32;
281 case 8:
return Pack::Type::I64;
282 default:
return Pack::Type::None;
286 template<
typename T_>
288 encode(
void* buf,
const T_* t,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
292 case Pack::Type::I8:
return xencode<Pack::i8>(buf, t, count, swap_bytes);
293 case Pack::Type::I16:
return xencode<Pack::i16>(buf, t, count, swap_bytes);
294 case Pack::Type::I32:
return xencode<Pack::i32>(buf, t, count, swap_bytes);
295 case Pack::Type::I64:
return xencode<Pack::i64>(buf, t, count, swap_bytes);
296 default:
XABORTM(
"invalid data type conversion");
300 template<
typename T_>
302 decode(T_* t,
const void* buf,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
306 case Pack::Type::I8:
return xdecode<Pack::i8>(t, buf, count, swap_bytes);
307 case Pack::Type::I16:
return xdecode<Pack::i16>(t, buf, count, swap_bytes);
308 case Pack::Type::I32:
return xdecode<Pack::i32>(t, buf, count, swap_bytes);
309 case Pack::Type::I64:
return xdecode<Pack::i64>(t, buf, count, swap_bytes);
310 default:
XABORTM(
"invalid data type conversion");
319 template<
typename T_>
324 case 1:
return Pack::Type::U8;
325 case 2:
return Pack::Type::U16;
326 case 4:
return Pack::Type::U32;
327 case 8:
return Pack::Type::U64;
328 default:
return Pack::Type::None;
332 template<
typename T_>
334 encode(
void* buf,
const T_* t,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
338 case Pack::Type::U8:
return xencode<Pack::u8>(buf, t, count, swap_bytes);
339 case Pack::Type::U16:
return xencode<Pack::u16>(buf, t, count, swap_bytes);
340 case Pack::Type::U32:
return xencode<Pack::u32>(buf, t, count, swap_bytes);
341 case Pack::Type::U64:
return xencode<Pack::u64>(buf, t, count, swap_bytes);
342 default:
XABORTM(
"invalid data type conversion");
346 template<
typename T_>
348 decode(T_* t,
const void* buf,
const std::size_t count,
const Pack::Type pack_type,
bool swap_bytes)
352 case Pack::Type::U8:
return xdecode<Pack::u8>(t, buf, count, swap_bytes);
353 case Pack::Type::U16:
return xdecode<Pack::u16>(t, buf, count, swap_bytes);
354 case Pack::Type::U32:
return xdecode<Pack::u32>(t, buf, count, swap_bytes);
355 case Pack::Type::U64:
return xdecode<Pack::u64>(t, buf, count, swap_bytes);
356 default:
XABORTM(
"invalid data type conversion");
361 template<
typename T_>
392 template<
typename T_>
396 if(count <= std::size_t(0))
398 return std::size_t(0);
404 XASSERTM((pack_type & Pack::Type::Mask_T) != Pack::Type::None,
"invalid pack type");
405 XASSERTM((pack_type & Pack::Type::Mask_Z) != Pack::Type::Mask_Z,
"cannot encode compressed type");
441 template<
typename T_>
445 if(count <= std::size_t(0))
447 return std::size_t(0);
453 XASSERTM((pack_type & Pack::Type::Mask_T) != Pack::Type::None,
"invalid pack type");
454 XASSERTM((pack_type & Pack::Type::Mask_Z) != Pack::Type::Mask_Z,
"cannot decode compressed type");
488 if(count <= std::size_t(0))
490 return std::size_t(0);
494 zfp_type t = zfp_type::zfp_type_none;
497 case Pack::Type::PF32: t = zfp_type::zfp_type_float;
break;
498 case Pack::Type::PF64: t = zfp_type::zfp_type_double;
break;
499 default:
XABORTM(
"cannot encode compressed type; data typ not available");
501 XASSERT(t != zfp_type::zfp_type_none);
507 std::size_t x_size, y_size;
508 void* temp_arr =
nullptr;
512 y_size = count / x_size + 1;
515 if((
sizeof(std::size_t) >
sizeof(uint)) && (count > std::numeric_limits<uint>::max()))
516 XABORTM(
"cannot encode compressed type; array size to big for internal data");
520 field = zfp_field_2d(temp_arr, t, (uint)x_size, (uint)y_size);
522 zfp = zfp_stream_open(NULL);
524 zfp_stream_set_accuracy(zfp, tolerance);
526 bytes = zfp_stream_maximum_size(zfp, field);
529 zfp_field_free(field);
530 zfp_stream_close(zfp);
538 XABORTM(
"cannot encode compressed type; zfp not available");
539 return std::size_t(0);
545 if((type & Pack::Type::Mask_P) != Pack::Type::None)
553 if((type & Pack::Type::Mask_Z) != Pack::Type::None)
555 return std::size_t(::compressBound(uLong(raw_size)));
558 XASSERTM((type & Pack::Type::Mask_Z) == Pack::Type::None,
"cannot estimate compressed size; zlib not available");
565 template<
typename T_>
569 const std::size_t buf_size,
570 const std::size_t count,
575 if(count <= std::size_t(0))
577 return std::size_t(0);
584 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
587 if((pack_type & (Pack::Type::Mask_Z | Pack::Type::Mask_P)) == Pack::Type::None)
589 return encode_raw(buf, src, count, raw_type, swap_bytes);
593 if((pack_type & Pack::Type::Mask_Z) == Pack::Type::Mask_Z)
595 return lossless_encode(buf, src, buf_size, count, pack_type, swap_bytes);
599 if((pack_type & Pack::Type::Mask_P) == Pack::Type::Mask_P)
601 return lossy_encode(buf, src, buf_size, count, pack_type, swap_bytes, tolerance);
604 return std::size_t(0);
632 template<
typename T_>
636 const std::size_t buf_size,
637 const std::size_t count,
642 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
647 std::vector<char> tmp(raw_size);
650 encode_raw(tmp.data(), src, count, raw_type, swap_bytes);
653 uLongf dl =
static_cast<uLongf
>(buf_size);
654 uLong sl =
static_cast<uLong
>(raw_size);
657 Bytef* dbuf =
reinterpret_cast<Bytef*
>(buf);
658 const Bytef* sbuf =
reinterpret_cast<const Bytef*
>(tmp.data());
661 if(::compress(dbuf, &dl, sbuf, sl) != Z_OK)
662 XABORTM(
"zlib compression error");
665 return static_cast<std::size_t
>(dl);
674 XABORTM(
"cannot encode compressed type; zlib not available");
675 return std::size_t(0);
679 template<
typename T_>
683 const std::size_t count,
684 const std::size_t buf_size,
688 if(count <= std::size_t(0))
690 return std::size_t(0);
697 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
700 if((pack_type & (Pack::Type::Mask_Z | Pack::Type::Mask_P)) == Pack::Type::None)
702 return decode_raw(dst, buf, count, raw_type, swap_bytes);
706 if((pack_type & Pack::Type::Mask_Z) == Pack::Type::Mask_Z)
708 return lossless_decode(dst, buf, count, buf_size, pack_type, swap_bytes);
712 if((pack_type & Pack::Type::Mask_P) == Pack::Type::Mask_P)
714 return lossy_decode(dst, buf, count, buf_size, pack_type, swap_bytes);
717 return std::size_t(0);
744 template<
typename T_>
748 const std::size_t count,
749 const std::size_t buf_size,
754 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
758 std::size_t raw_size =
element_size(raw_type) * count + 1024u;
759 std::vector<char> tmp(raw_size);
762 uLongf dl =
static_cast<uLongf
>(raw_size);
763 uLong sl =
static_cast<uLong
>(buf_size);
766 Bytef* dbuf =
reinterpret_cast<Bytef*
>(tmp.data());
767 const Bytef* sbuf =
reinterpret_cast<const Bytef*
>(buf);
770 if(::uncompress2(dbuf, &dl, sbuf, &sl) != Z_OK)
771 XABORTM(
"zlib decompression error");
774 decode_raw(dst, tmp.data(), count, raw_type, swap_bytes);
777 return static_cast<std::size_t
>(sl);
786 XABORTM(
"cannot decode compressed type; zlib not available");
787 return std::size_t(0);
824 template<
typename T_>
828 const std::size_t buf_size,
829 const std::size_t count,
832 const double tolerance)
835 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
839 zfp_type t = zfp_type::zfp_type_none;
842 case Pack::Type::PF32: t = zfp_type::zfp_type_float;
break;
843 case Pack::Type::PF64: t = zfp_type::zfp_type_double;
break;
844 default:
XABORTM(
"cannot encode compressed type; data typ not available");
846 XASSERT(t != zfp_type::zfp_type_none);
856 std::vector<char> tmp(raw_size);
859 encode_raw(tmp.data(), src, count, raw_type, swap_bytes);
864 std::size_t real_bytes;
866 std::size_t x_size, y_size;
869 if((
sizeof(std::size_t) >
sizeof(uint)) && (count > std::numeric_limits<uint>::max()))
870 XABORTM(
"cannot encode compressed type; array size to big for internal "
875 y_size = count / x_size;
877 y_size = count / x_size + 1;
880 field = zfp_field_2d(tmp.data(), t, (uint)x_size, (uint)y_size);
881 zfp = zfp_stream_open(NULL);
882 zfp_stream_set_accuracy(zfp, tolerance);
883 stream = stream_open(buf, buf_size);
884 zfp_stream_set_bit_stream(zfp, stream);
885 stream_rewind(stream);
887 zfp_write_header(zfp, field, zfp_header_mask);
889 real_bytes = zfp_compress(zfp, field);
892 zfp_field_free(field);
893 zfp_stream_close(zfp);
894 stream_close(stream);
906 XABORTM(
"cannot encode compressed type; zfp not available");
907 return std::size_t(0);
936 template<
typename T_>
940 const std::size_t count,
941 const std::size_t buf_size,
946 const Pack::Type raw_type = pack_type & Pack::Type::Mask_T;
949 zfp_type t = zfp_type::zfp_type_none;
952 case Pack::Type::PF32: t = zfp_type::zfp_type_float;
break;
953 case Pack::Type::PF64: t = zfp_type::zfp_type_double;
break;
954 default:
XABORTM(
"cannot encode compressed type; data typ not available");
956 XASSERT(t != zfp_type::zfp_type_none);
959 std::size_t raw_size =
element_size(raw_type) * count + 1024u;
960 std::vector<char> tmp(raw_size);
966 std::size_t array_size;
967 std::size_t real_bytes;
969 field = zfp_field_alloc();
970 zfp = zfp_stream_open(NULL);
972 stream = stream_open(buf, buf_size);
974 stream_rseek(stream, 24u);
975 uint codec = (uint)stream_read_bits(stream, 8u);
977 codec == zfp_codec_version,
978 "cannot decode compressed type; zfp version not compatible \n "
979 "zfp_Systemcodec: " +
981 stream_rewind(stream);
983 zfp_stream_set_bit_stream(zfp, stream);
985 zfp_read_header(zfp, field, zfp_header_mask);
986 array_size = zfp_field_size(field, NULL);
989 XABORTM(
"cannot decode compressed type; given array and saved data do not "
990 "have the same type");
992 if(array_size - 3 > count)
993 XABORTM(
"cannot decode compressed data; given count is too small for "
994 "decompressed data!");
996 field->data = tmp.data();
998 real_bytes = zfp_decompress(zfp, field);
1001 decode_raw(dst, tmp.data(), count, raw_type, swap_bytes);
1004 zfp_field_free(field);
1005 zfp_stream_close(zfp);
1006 stream_close(stream);
1017 XABORTM(
"cannot decode compressed type; zfp not available");
1018 return std::size_t(0);
1036#if defined(FEAT_HAVE_PACK_TYPE_F16)
1042#if defined(FEAT_HAVE_PACK_TYPE_F128)
1046 template std::size_t encode<i8>(
void*,
const i8*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1047 template std::size_t encode<i16>(
void*,
const i16*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1048 template std::size_t encode<i32>(
void*,
const i32*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1049 template std::size_t encode<i64>(
void*,
const i64*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1051 template std::size_t encode<u8>(
void*,
const u8*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1052 template std::size_t encode<u16>(
void*,
const u16*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1053 template std::size_t encode<u32>(
void*,
const u32*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1054 template std::size_t encode<u64>(
void*,
const u64*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1056 template std::size_t encode<long long>(
void*,
const long long*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1058#if defined(FEAT_HAVE_PACK_TYPE_F16)
1059 template std::size_t encode<f16>(
void*,
const f16*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1061 template std::size_t encode<f32>(
void*,
const f32*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1062 template std::size_t encode<f64>(
void*,
const f64*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1064#if defined(FEAT_HAVE_PACK_TYPE_F128)
1065 template std::size_t encode<f128>(
void*,
const f128*, std::size_t, std::size_t,
Pack::Type,
bool,
double);
1068 template std::size_t decode<i8>(
i8*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1069 template std::size_t decode<i16>(
i16*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1070 template std::size_t decode<i32>(
i32*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1071 template std::size_t decode<i64>(
i64*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1073 template std::size_t decode<u8>(
u8*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1074 template std::size_t decode<u16>(
u16*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1075 template std::size_t decode<u32>(
u32*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1076 template std::size_t decode<u64>(
u64*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1078 template std::size_t decode<long long>(
long long*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1080#if defined(FEAT_HAVE_PACK_TYPE_F16)
1081 template std::size_t decode<f16>(
f16*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1083 template std::size_t decode<f32>(
f32*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1084 template std::size_t decode<f64>(
f64*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
1086#if defined(FEAT_HAVE_PACK_TYPE_F128)
1087 template std::size_t decode<f128>(f128*,
void*, std::size_t, std::size_t,
Pack::Type,
bool);
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Tag class for floating data types.
Tag class for integral data types.
Data Array Pack namespace.
static std::size_t xdecode(T_ *dest, const void *buf, const std::size_t count, bool swap_bytes)
Encodes an array by converting each of its elements to a desired type.
static std::size_t lossy_estimate_size(const std::size_t count, const Pack::Type type, const double tolerance)
Computes the estimated (upper bound) pack buffer size for an array for lossy compression.
std::int32_t i32
32-bit signed integer type
std::size_t encode(void *buf, const T_ *src, const std::size_t buf_size, const std::size_t count, const Pack::Type pack_type, bool swap_bytes, double tolerance)
Encodes an array into a packed buffer.
std::uint64_t u64
64-bit unsigned integer type
static std::size_t lossless_encode(void *buf, const T_ *src, const std::size_t buf_size, const std::size_t count, const Pack::Type pack_type, bool swap_bytes)
Encodes an array into a packed buffer.
std::size_t element_size(const Pack::Type type)
Returns the size of a Pack::Type element in bytes.
std::size_t estimate_size(const std::size_t count, const Pack::Type type, const double tolerance)
Computes the estimated (upper bound) pack buffer size for an array.
static std::size_t lossless_decode(T_ *dst, const void *buf, const std::size_t count, const std::size_t buf_size, const Pack::Type pack_type, bool swap_bytes)
Decodes an array from a packed buffer.
static std::size_t decode_raw(T_ *dst, const void *buf, const std::size_t count, const Pack::Type pack_type, bool swap_bytes)
Decodes an array from a packed buffer without compression support.
Half f16
16-bit floating point type
float f32
32-bit floating point type
Type
bitmask for zfp header
std::int16_t i16
16-bit signed integer type
std::uint32_t u32
32-bit unsigned integer type
std::int64_t i64
64-bit signed integer type
std::uint16_t u16
16-bit unsigned integer type
static std::size_t lossy_decode(T_ *dst, void *buf, const std::size_t count, const std::size_t buf_size, const Pack::Type pack_type, bool swap_bytes)
Decodes an array from a packed buffer with lossy saved compression data.
static std::size_t encode_raw(void *buf, const T_ *src, const std::size_t count, const Pack::Type pack_type, bool swap_bytes)
Encodes an array into a packed buffer without compression support.
std::int8_t i8
8-bit signed integer type
static std::size_t lossy_encode(void *buf, T_ *src, const std::size_t buf_size, const std::size_t count, const Pack::Type pack_type, bool swap_bytes, const double tolerance)
Encodes an array into a packed buffer.
double f64
64-bit floating point type
std::size_t decode(T_ *dst, void *buf, const std::size_t count, const std::size_t buf_size, const Pack::Type pack_type, bool swap_bytes)
Decodes an array from a packed buffer.
std::uint8_t u8
8-bit unsigned integer type
Pack::Type deduct_type()
Deduct the (raw) Pack::Type from a given data type T_.
X_ xswap(X_ x)
Swaps the bytes of an object.
static std::size_t xencode(void *buf, const T_ *src, const std::size_t count, bool swap_bytes)
Encodes an array by converting each of its elements to a desired type.
String stringify(const T_ &item)
Converts an item into a String.
auxiliary helper class: swaps the bytes of an 8/16/32/64/128 byte type