FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
pack.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
9#include <kernel/util/string.hpp>
10
11// includes, system
12#include <cstdint>
13#include <ostream>
14#include <istream>
15
24namespace FEAT::Pack
25{
27 using i8 = std::int8_t;
29 using i16 = std::int16_t;
31 using i32 = std::int32_t;
33 using i64 = std::int64_t;
34
36 using u8 = std::uint8_t;
38 using u16 = std::uint16_t;
40 using u32 = std::uint32_t;
42 using u64 = std::uint64_t;
43
44#if defined(FEAT_HAVE_HALFMATH) || defined(DOXYGEN)
45#define FEAT_HAVE_PACK_TYPE_F16 1
47 using f16 = Half;
48 // make sure this really has only 16 bits; this may be violated by a stupid
49 // compiler
50 static_assert(sizeof(f16) == 2, "16-bit float is assumed to have exactly 16 bits");
51#endif
52
54 using f32 = float;
56 using f64 = double;
57
58#if defined(FEAT_HAVE_QUADMATH) || defined(DOYGEN)
59#define FEAT_HAVE_PACK_TYPE_F128 1
61 using f128 = __float128;
62 // make sure this really has only 16 bytes
63 static_assert(sizeof(f128) == 16, "128-bit float is assumed to have exactly 128 bits");
64#endif
65
74#ifdef FEAT_HAVE_ZFP
75 static constexpr uint zfp_header_mask = 7u;
76#endif // FEAT_HAVE_ZFP
80 enum class Type : u16
81 {
82 None = 0x0000, //< none (for comparison)
83 Mask_T = 0x0FFF, //< raw type mask
84 Mask_Z = 0x8000, //< zlib compression mask
85 Mask_P = 0x2000, //< zfp compression mask
86 // Mask_E = 0x4000, //< swap endianness mask
87
88 Type_I = 0x0010, //< signed integer type
89 Type_U = 0x0020, //< unsigend integer type
90 Type_F = 0x0030, //< floating point type
91
92 // raw signed integer types
93 I8 = 0x0011, //< 8-bit unsigned integer
94 I16 = 0x0012, //< 16-bit unsigned integer
95 I32 = 0x0013, //< 32-bit unsigned integer
96 I64 = 0x0014, //< 64-bit unsigned integer
97
98 // raw unsigned integer types
99 U8 = 0x0021, //< 8-bit unsigned integer
100 U16 = 0x0022, //< 16-bit unsigned integer
101 U32 = 0x0023, //< 32-bit unsigned integer
102 U64 = 0x0024, //< 64-bit unsigned integer
103
104 // raw floating point types
105 // F8 = 0x0031, //< 8-bit floating point (quarter precision)
106 F16 = 0x0032, //< 16-bit floating point (half precision)
107 F32 = 0x0033, //< 32-bit floating point (single precision)
108 F64 = 0x0034, //< 64-bit floating point (double precision)
109 F128 = 0x0035, //< 128-bit floating point (quadruple precision)
110
111 // zlib compressed signed integer types
112 ZI8 = 0x8011, //< 8-bit unsigned integer
113 ZI16 = 0x8012, //< 16-bit unsigned integer
114 ZI32 = 0x8013, //< 32-bit unsigned integer
115 ZI64 = 0x8014, //< 64-bit unsigned integer
116
117 // zlib compressed unsigned integer types
118 ZU8 = 0x8021, //< 8-bit unsigned integer
119 ZU16 = 0x8022, //< 16-bit unsigned integer
120 ZU32 = 0x8023, //< 32-bit unsigned integer
121 ZU64 = 0x8024, //< 64-bit unsigned integer
122
123 // zlib compressed floating point types
124 // ZF8 = 0x8031, //< 8-bit floating point (quarter precision)
125 ZF16 = 0x8032, //< 16-bit floating point (half precision)
126 ZF32 = 0x8033, //< 32-bit floating point (single precision)
127 ZF64 = 0x8034, //< 64-bit floating point (double precision)
128 ZF128 = 0x8035, //< 128-bit floating point (quadruple precision)
129
130 // zfp compressed floating point types
131 // PF8 = 0x2031, //< 8-bit floating point (quarter precision)
132 // PF16 = 0x2032, //< 16-bit floating point (half precision)
133 PF32 = 0x2033, //< 32-bit floating point (single precision)
134 PF64 = 0x2034 //< 64-bit floating point (double precision)
135 // PF128 = 0x2035 //< 128-bit floating point (quadruple precision)
136
137 }; // enum class Type
138
141 {
142 return (Pack::Type)(((Pack::u16)a) & ((Pack::u16)b));
143 }
144
147 {
148 return (Pack::Type)(((Pack::u16)a) | ((Pack::u16)b));
149 }
150
152 inline std::ostream& operator<<(std::ostream& os, Pack::Type t)
153 {
154 switch(t)
155 {
156 // case Pack::Type::F8: return os << "F8";
157 case Pack::Type::F16: return os << "F16";
158 case Pack::Type::F32: return os << "F32";
159 case Pack::Type::F64: return os << "F64";
160 case Pack::Type::F128: return os << "F128";
161 case Pack::Type::I8: return os << "I8";
162 case Pack::Type::I16: return os << "I16";
163 case Pack::Type::I32: return os << "I32";
164 case Pack::Type::I64: return os << "I64";
165 case Pack::Type::U8: return os << "U8";
166 case Pack::Type::U16: return os << "U16";
167 case Pack::Type::U32: return os << "U32";
168 case Pack::Type::U64: return os << "U64";
169 // case Pack::Type::ZF8: return os << "ZF8";
170 case Pack::Type::ZF16: return os << "ZF16";
171 case Pack::Type::ZF32: return os << "ZF32";
172 case Pack::Type::ZF64: return os << "ZF64";
173 case Pack::Type::ZF128: return os << "ZF128";
174 case Pack::Type::ZI8: return os << "ZI8";
175 case Pack::Type::ZI16: return os << "ZI16";
176 case Pack::Type::ZI32: return os << "ZI32";
177 case Pack::Type::ZI64: return os << "ZI64";
178 case Pack::Type::ZU8: return os << "ZU8";
179 case Pack::Type::ZU16: return os << "ZU16";
180 case Pack::Type::ZU32: return os << "ZU32";
181 case Pack::Type::ZU64: return os << "ZU64";
182 case Pack::Type::PF32: return os << "PF32";
183 case Pack::Type::PF64: return os << "PF64";
184 default: return os << "???";
185 }
186 }
187
189 inline std::istream& operator>>(std::istream& is, Pack::Type& t)
190 {
191 String s;
192 if((is >> s).fail())
193 {
194 return is;
195 }
196
197 // if(s.compare_no_case("F8") == 0) t = Pack::Type::F8; else
198 if(s.compare_no_case("F16") == 0)
199 t = Pack::Type::F16;
200 else if(s.compare_no_case("F32") == 0)
201 t = Pack::Type::F32;
202 else if(s.compare_no_case("F64") == 0)
203 t = Pack::Type::F64;
204 else if(s.compare_no_case("F128") == 0)
205 t = Pack::Type::F128;
206 else if(s.compare_no_case("I8") == 0)
207 t = Pack::Type::I8;
208 else if(s.compare_no_case("I16") == 0)
209 t = Pack::Type::I16;
210 else if(s.compare_no_case("I32") == 0)
211 t = Pack::Type::I32;
212 else if(s.compare_no_case("I64") == 0)
213 t = Pack::Type::I64;
214 else if(s.compare_no_case("U8") == 0)
215 t = Pack::Type::U8;
216 else if(s.compare_no_case("U16") == 0)
217 t = Pack::Type::U16;
218 else if(s.compare_no_case("U32") == 0)
219 t = Pack::Type::U32;
220 else if(s.compare_no_case("U64") == 0)
221 t = Pack::Type::U64;
222 else
223 // if(s.compare_no_case("ZF8") == 0) t = Pack::Type::ZF8; else
224 if(s.compare_no_case("ZF16") == 0)
225 t = Pack::Type::ZF16;
226 else if(s.compare_no_case("ZF32") == 0)
227 t = Pack::Type::ZF32;
228 else if(s.compare_no_case("ZF64") == 0)
229 t = Pack::Type::ZF64;
230 else if(s.compare_no_case("ZF128") == 0)
231 t = Pack::Type::ZF128;
232 else if(s.compare_no_case("ZI8") == 0)
233 t = Pack::Type::ZI8;
234 else if(s.compare_no_case("ZI16") == 0)
235 t = Pack::Type::ZI16;
236 else if(s.compare_no_case("ZI32") == 0)
237 t = Pack::Type::ZI32;
238 else if(s.compare_no_case("ZI64") == 0)
239 t = Pack::Type::ZI64;
240 else if(s.compare_no_case("ZU8") == 0)
241 t = Pack::Type::ZU8;
242 else if(s.compare_no_case("ZU16") == 0)
243 t = Pack::Type::ZU16;
244 else if(s.compare_no_case("ZU32") == 0)
245 t = Pack::Type::ZU32;
246 else if(s.compare_no_case("ZU64") == 0)
247 t = Pack::Type::ZU64;
248 else if(s.compare_no_case("PF32") == 0)
249 t = Pack::Type::PF32;
250 else if(s.compare_no_case("PF64") == 0)
251 t = Pack::Type::PF64;
252 else
253 is.setstate(std::ios_base::failbit);
254
255 return is;
256 }
257
267 inline std::size_t element_size(const Pack::Type type)
268 {
269 // Lower 4 bits contain the size of the data type.
270 // Upper bits contain the type of compression.
271 constexpr auto size_mask = 0xFULL;
272 return std::size_t(1) << ((static_cast<u16>(type) & size_mask) - 1);
273 }
274
287 template<typename T_>
289
302 std::size_t estimate_size(std::size_t count, Pack::Type type, double tolerance = 1e-16);
303
334 template<typename T_>
335 std::size_t encode(
336 void* buf,
337 const T_* src,
338 std::size_t buf_size,
339 std::size_t count,
340 Pack::Type pack_type,
341 bool swap_bytes,
342 double tolerance = 1e-16);
343
370 template<typename T_>
371 std::size_t decode(
372 T_* dst,
373 void* buf,
374 std::size_t count,
375 std::size_t buf_size,
376 Pack::Type pack_type,
377 bool swap_bytes);
378} // namespace FEAT::Pack
String class implementation.
Definition: string.hpp:46
int compare_no_case(const String &other) const
Compares two strings without regard to case.
Definition: string.hpp:679
Data Array Pack namespace.
Definition: pack.cpp:28
Pack::Type operator|(Pack::Type a, Pack::Type b)
bit-wise OR operator for Pack::Type
Definition: pack.hpp:146
std::int32_t i32
32-bit signed integer type
Definition: pack.hpp:31
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.
Definition: pack.cpp:566
std::uint64_t u64
64-bit unsigned integer type
Definition: pack.hpp:42
std::size_t element_size(const Pack::Type type)
Returns the size of a Pack::Type element in bytes.
Definition: pack.hpp:267
Pack::Type operator&(Pack::Type a, Pack::Type b)
bit-wise AND operator for Pack::Type
Definition: pack.hpp:140
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.
Definition: pack.cpp:543
std::istream & operator>>(std::istream &is, Pack::Type &t)
stream input operator for Pack::Type
Definition: pack.hpp:189
std::ostream & operator<<(std::ostream &os, Pack::Type t)
stream output operator for Pack::Type
Definition: pack.hpp:152
Half f16
16-bit floating point type
Definition: pack.hpp:47
float f32
32-bit floating point type
Definition: pack.hpp:54
Type
bitmask for zfp header
Definition: pack.hpp:81
std::int16_t i16
16-bit signed integer type
Definition: pack.hpp:29
std::uint32_t u32
32-bit unsigned integer type
Definition: pack.hpp:40
std::int64_t i64
64-bit signed integer type
Definition: pack.hpp:33
std::uint16_t u16
16-bit unsigned integer type
Definition: pack.hpp:38
std::int8_t i8
8-bit signed integer type
Definition: pack.hpp:27
double f64
64-bit floating point type
Definition: pack.hpp:56
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.
Definition: pack.cpp:680
std::uint8_t u8
8-bit unsigned integer type
Definition: pack.hpp:36
Pack::Type deduct_type()
Deduct the (raw) Pack::Type from a given data type T_.
Definition: pack.cpp:362
__half Half
Half data type.
Definition: half.hpp:25