16#define BOOST_TEST_MODULE Test CTFEntropyCoder class
17#define BOOST_TEST_MAIN
18#define BOOST_TEST_DYN_LINK
29#include <boost/test/unit_test.hpp>
30#include <boost/mp11.hpp>
44using source_types = boost::mp11::mp_list<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t>;
46template <
typename source_T>
52 if (mSourceMessage.empty()) {
55 const size_t draws = (
max -
min) + 1;
56 const double probability = 0.5;
57 std::binomial_distribution<int64_t> dist(draws, probability);
58 mSourceMessage.resize(messageSize);
59 std::generate(mSourceMessage.begin(), mSourceMessage.end(), [&dist, &mt,
min]() ->
source_T { return static_cast<int64_t>(dist(mt)) + min; });
65 inline constexpr auto&
get() const noexcept {
return mSourceMessage; };
70 std::vector<source_T> mSourceMessage{};
81 if constexpr (std::is_same_v<uint8_t, T>) {
82 return sourceMessage8u.
get();
83 }
else if constexpr (std::is_same_v<int8_t, T>) {
84 return sourceMessage8.
get();
85 }
else if constexpr (std::is_same_v<uint16_t, T>) {
86 return sourceMessage16u.
get();
87 }
else if constexpr (std::is_same_v<int16_t, T>) {
88 return sourceMessage16.
get();
89 }
else if constexpr (std::is_same_v<uint32_t, T>) {
90 return sourceMessage32u.
get();
91 }
else if constexpr (std::is_same_v<int32_t, T>) {
92 return sourceMessage32.
get();
94 throw std::runtime_error{
"unsupported source type"};
110template <
typename source_IT>
113 using source_type =
typename std::iterator_traits<source_IT>::value_type;
117 entropyCoder.makeEncoder();
122 LOGP(info,
"dataset[{},{}], coder[{},{}]",
metrics.getDatasetProperties().min,
metrics.getDatasetProperties().max, *
metrics.getCoderProperties().min, *
metrics.getCoderProperties().max);
128 auto encoderEnd = entropyCoder.encode(begin,
end, encodeBuffer.data(), encodeBuffer.data() + encodeBuffer.size());
129 [[maybe_unused]]
auto literalsEnd = entropyCoder.writeIncompressible(literalSymbolsBuffer.data(), literalSymbolsBuffer.data() + literalSymbolsBuffer.size());
130 auto dictEnd = entropyCoder.writeDictionary(dictBuffer.data(), dictBuffer.data() + dictBuffer.size());
132 const auto& coderProperties =
metrics.getCoderProperties();
134 *coderProperties.min, *coderProperties.max,
135 *coderProperties.renormingPrecisionBits));
136 std::vector<source_type> literals(entropyCoder.getNIncompressibleSamples());
138 const auto& datasetPropterties =
metrics.getDatasetProperties();
139 rans::unpack(literalSymbolsBuffer.data(), literals.size(), literals.data(),
140 datasetPropterties.alphabetRangeBits, datasetPropterties.min);
142 size_t messageLength = std::distance(begin,
end);
143 std::vector<source_type> sourceBuffer(messageLength, 0);
145 decoder.process(encoderEnd, sourceBuffer.data(), messageLength, entropyCoder.getNStreams(), literals.end());
147 BOOST_CHECK_EQUAL_COLLECTIONS(sourceBuffer.begin(), sourceBuffer.end(), begin,
end);
152 std::vector<source_T> testMessage{};
153 encodeInplace(testMessage.data(), testMessage.data() + testMessage.size());
159 encodeInplace(testMessage.data(), testMessage.data() + testMessage.size());
168template <
typename value_T,
size_t shift>
173 template <
typename iterA_T,
typename iterB_T>
174 inline value_T
operator()(iterA_T iterA, iterB_T iterB)
const
176 return *iterB + (
static_cast<value_T
>(*iterA) << shift);
179 template <
typename iterA_T,
typename iterB_T>
182 *iterA =
value >> shift;
183 *iterB =
value & ((0x1 << shift) - 0x1);
187template <
typename iterA_T,
typename iterB_T,
typename F>
236 template <
typename T>
239 if constexpr (std::is_same_v<uint8_t, T>) {
241 }
else if constexpr (std::is_same_v<int8_t, T>) {
243 }
else if constexpr (std::is_same_v<uint16_t, T>) {
245 }
else if constexpr (std::is_same_v<int16_t, T>) {
247 }
else if constexpr (std::is_same_v<uint32_t, T>) {
249 }
else if constexpr (std::is_same_v<int32_t, T>) {
252 throw std::runtime_error{
"unsupported encoder type"};
256 template <
typename T>
259 if constexpr (std::is_same_v<uint8_t, T>) {
261 }
else if constexpr (std::is_same_v<int8_t, T>) {
263 }
else if constexpr (std::is_same_v<uint16_t, T>) {
265 }
else if constexpr (std::is_same_v<int16_t, T>) {
267 }
else if constexpr (std::is_same_v<uint32_t, T>) {
269 }
else if constexpr (std::is_same_v<int32_t, T>) {
272 throw std::runtime_error{
"unsupported encoder type"};
294template <
typename source_IT>
297 using source_type =
typename std::iterator_traits<source_IT>::value_type;
301 const size_t sourceExtent = std::distance(begin,
end);
302 std::vector<buffer_type> encodeBuffer(entropyCoder.template computePayloadSizeEstimate<buffer_type>(sourceExtent), 0);
303 auto encoderEnd = entropyCoder.encode(begin,
end, encodeBuffer.data(), encodeBuffer.data() + encodeBuffer.size());
305 std::vector<buffer_type> literalSymbolsBuffer(entropyCoder.template computePackedIncompressibleSize<buffer_type>(), 0);
306 [[maybe_unused]]
auto literalsEnd = entropyCoder.writeIncompressible(literalSymbolsBuffer.data(), literalSymbolsBuffer.data() + literalSymbolsBuffer.size());
310 std::vector<source_type> literals((entropyCoder.getNIncompressibleSamples()));
312 rans::unpack(literalSymbolsBuffer.data(), literals.size(), literals.data(),
313 entropyCoder.getIncompressibleSymbolPackingBits(), entropyCoder.getIncompressibleSymbolOffset());
315 size_t messageLength = std::distance(begin,
end);
316 std::vector<source_type> sourceBuffer(messageLength, 0);
318 decoder.process(encoderEnd, sourceBuffer.data(), messageLength, entropyCoder.getEncoder().getNStreams(), literals.end());
320 BOOST_CHECK_EQUAL_COLLECTIONS(sourceBuffer.begin(), sourceBuffer.end(), begin,
end);
325 std::vector<source_T> testMessage{};
326 encodeExternal(testMessage.data(), testMessage.data() + testMessage.size());
332 encodeExternal(testMessage.data(), testMessage.data() + testMessage.size());
Interfaces for BitPacking using librans.
constexpr size_t MessageSize
ExternalEncoderDecoderProxy()
const auto & getEncoder() const noexcept
const auto & getDecoder() const noexcept
value_T operator()(iterA_T iterA, iterB_T iterB) const
void operator()(iterA_T iterA, iterB_T iterB, value_T value) const
SourceMessageProxy()=default
const auto & getMessage() const noexcept
constexpr source_T getMin() const noexcept
constexpr auto & get() const noexcept
constexpr source_T getMax() const noexcept
SourceMessage(size_t messageSize, source_T max=std::numeric_limits< source_T >::max(), source_T min=std::numeric_limits< source_T >::min())
size_t getIncompressibleSize(double_t safetyFactor=1.2) const
size_t getCompressedDatasetSize(double_t safetyFactor=1.2) const
size_t getCompressedDictionarySize(double_t safetyFactor=2) const
static constexpr decltype(auto) fromRenormed(const RenormedHistogramConcept< container_T > &renormed)
static constexpr decltype(auto) fromRenormed(const RenormedDenseHistogram< source_T > &renormed)
static factory classes for building histograms, encoders and decoders.
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLsizei const GLfloat * value
public interface for building and renorming histograms from source data.
public interface for rANS iterators.
constexpr size_t pow2(size_t n) noexcept
decltype(makeDenseEncoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) denseEncoder_type
decltype(makeDecoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) defaultDecoder_type
void unpack(const input_T *__restrict inputBegin, size_t extent, output_IT outputBegin, size_t packingWidth, typename std::iterator_traits< output_IT >::value_type offset=static_cast< typename std::iterator_traits< output_IT >::value_type >(0))
RenormedDenseHistogram< source_T > readRenormedDictionary(buffer_IT begin, buffer_IT end, source_T min, source_T max, size_t renormingPrecision)
decltype(auto) renorm(histogram_T histogram, size_t newPrecision, RenormingPolicy renormingPolicy=RenormingPolicy::Auto, size_t lowProbabilityCutoffBits=0)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
BOOST_AUTO_TEST_CASE(FlatHisto)
static decltype(auto) fromSamples(source_IT begin, source_IT end, typename std::iterator_traits< source_IT >::value_type min, typename std::iterator_traits< source_IT >::value_type max)
boost::mp11::mp_list< uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t > source_types
ExternalEncoderDecoderProxy ExternalEncoders
void encodeInplace(source_IT begin, source_IT end)
void encodeExternal(source_IT begin, source_IT end)
const SourceMessageProxy MessageProxy
auto makeInputIterators(iterA_T iterA, iterB_T iterB, size_t nElements, F functor)
BOOST_AUTO_TEST_CASE_TEMPLATE(testInplaceEncoderEmpty, source_T, source_types)