17#define BOOST_TEST_MODULE HuffmanCodec unit test
18#define BOOST_TEST_MAIN
19#define BOOST_TEST_DYN_LINK
20#include <boost/test/unit_test.hpp>
29#include "../include/DataCompression/dc_primitives.h"
30#include "../include/DataCompression/HuffmanCodec.h"
37namespace data_compression
42template <
class RandvalStreamT,
class EncodedStreamT,
class CodecT>
43void decoderProcess(RandvalStreamT& fifoRandvals, EncodedStreamT& fifoEncoded, CodecT& codec)
46 typename CodecT::model_type::value_type decodedValue;
48 }
while (fifoEncoded.pull([&](
typename EncodedStreamT::value_type
c) {
49 codec.Decode(decodedValue, c, decodedLen);
50 return fifoRandvals.pull([&](typename RandvalStreamT::value_type v) {
51 if (decodedValue != v) {
52 throw std::runtime_error(
"decoding mismatch");
65template <
typename CodecT,
typename GeneratorT>
68 using ValueT =
typename CodecT::value_type;
69 using CodeT =
typename CodecT::code_type;
70 auto const& huffmanmodel = codec.getCodingModel();
81 FifoBuffer_t fifoEncoded;
84 std::cout << std::endl
85 <<
"Testing encoding-decoding with " <<
nRolls <<
" random value(s) ..." << std::endl;
87 std::thread decoderThread([&]() {
decoderProcess(fifoRandvals, fifoEncoded, codec); });
92 ValueT
value = generator();
93 codec.Encode(
value, code, codeLen);
95 if (huffmanmodel.OrderMSB) {
96 code <<= (code.size() - codeLen);
98 fifoEncoded.push(code.to_ulong(),
n == 0);
102 decoderThread.join();
104 std::cout <<
"... done" << std::endl;
115 DataGenerator_t dg(-7, 10, 1, 0., 1.);
116 using SimpleRangeAlphabet_t =
ContiguousAlphabet<DataGenerator_t::value_type, -7, 10>;
117 SimpleRangeAlphabet_t alphabet;
126 using HuffmanModel_t =
128 HuffmanModel_t huffmanmodel;
130 huffmanmodel.
init(0.);
132 std::cout << std::endl
133 <<
"Huffman probability model after initialization: " << std::endl;
134 for (
auto s : alphabet) {
135 std::cout <<
"val = " << std::setw(2) <<
s <<
" --> weight = " << huffmanmodel[
s] << std::endl;
140 for (
auto s : alphabet) {
141 huffmanmodel.addWeight(
s, dg.getProbability(
s));
146 huffmanmodel.normalize();
148 std::cout << std::endl
149 <<
"Probabilities from DataGenerator:" << std::endl;
150 for (
auto i : huffmanmodel) {
151 std::cout <<
"val = " << std::setw(2) <<
i.first <<
" --> weight = " <<
i.second << std::endl;
158 huffmanmodel.GenerateHuffmanTree();
160 std::cout << std::endl
161 <<
"Generating binary tree and Huffman codes" << std::endl;
162 huffmanmodel.print();
164 return std::pair<HuffmanCodec<HuffmanModel_t>, DataGenerator_t>(huffmanmodel, dg);
170 auto& codec = setup.first;
171 auto& dg = setup.second;
172 auto const& huffmanmodel = codec.getCodingModel();
173 using ValueT =
decltype(setup.first)::value_type;
174 using CodeT =
decltype(setup.first)::code_type;
179 std::cout << std::endl
180 <<
"Huffman code summary: " << (huffmanmodel.OrderMSB ?
"MSB to LSB" :
"LSB to MSB") << std::endl;
181 for (
auto const&
i : huffmanmodel) {
184 codec.Encode(
i.first, code, codeLen);
185 std::cout <<
"value: " << std::setw(4) <<
i.first <<
" code length: " << std::setw(3) << codeLen <<
" code: ";
186 if (not huffmanmodel.OrderMSB) {
187 std::cout << std::setw(code.size() - codeLen);
189 for (
int k = 0; k < codeLen; k++) {
190 std::cout << code[codeLen - 1 - k];
192 std::cout << std::endl;
193 if (huffmanmodel.OrderMSB) {
194 code <<= (code.size() - codeLen);
198 codec.Decode(
value, code, decodedLen);
199 if (codeLen != decodedLen ||
value !=
i.first) {
200 std::cout <<
"mismatch in decoded value: " <<
value <<
"(" << decodedLen <<
")" << std::endl;
210 auto& codec = setup.first;
211 auto& dg = setup.second;
212 auto const& huffmanmodel = codec.getCodingModel();
213 using ValueT =
decltype(setup.first)::value_type;
214 using CodeT =
decltype(setup.first)::code_type;
220 auto nNodes = codec.writeConfiguration(
filename.str().c_str(),
"zlib");
222 auto result = codec.loadConfiguration(
filename.str().c_str(),
"zlib");
224 std::filesystem::remove(
filename.str());
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
void push(T something, bool isLast=false)
specialization of std::normal_distribution which implements also the analytic formula.
GLsizei const GLfloat * value
void decoderProcess(RandvalStreamT &fifoRandvals, EncodedStreamT &fifoEncoded, CodecT &codec)
void checkRandom(CodecT &codec, GeneratorT &generator, int nRolls=1000000)
auto setupCodec(int verbosity=0)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
BOOST_AUTO_TEST_CASE(FlatHisto)
static std::string create_unique_path(const std::string_view prefix="", int length=16)