Project
Loading...
Searching...
No Matches
bench_ransDecode.cxx
Go to the documentation of this file.
1// Copyright 2019-2023 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
17
18#include <vector>
19#include <cstring>
20#include <random>
21#include <algorithm>
22#ifdef RANS_PARALLEL_STL
23#include <execution>
24#endif
25#include <iterator>
26
27#include <benchmark/benchmark.h>
28
29#include "rANS/factory.h"
30#include "rANS/histogram.h"
31
32#ifdef ENABLE_VTUNE_PROFILER
33#include <ittnotify.h>
34#endif
35
36#include "helpers.h"
37
38using namespace o2::rans;
39
40inline constexpr size_t MessageSize = 1ull << 22;
41
42// template <typename source_T>
43// class SourceMessageProxyBinomial
44// {
45// public:
46// SourceMessageProxyBinomial(size_t messageSize)
47// {
48// if (mSourceMessage.empty()) {
49// std::mt19937 mt(0); // same seed we want always the same distrubution of random numbers;
50// const size_t draws = std::min(1ul << 27, static_cast<size_t>(std::numeric_limits<source_T>::max()));
51// const double probability = 0.5;
52// std::binomial_distribution<source_T> dist(draws, probability);
53// const size_t sourceSize = messageSize / sizeof(source_T) + 1;
54// mSourceMessage.resize(sourceSize);
55// #ifdef RANS_PARALLEL_STL
56// std::generate(std::execution::par_unseq, mSourceMessage.begin(), mSourceMessage.end(), [&dist, &mt]() { return dist(mt); });
57// #else
58// std::generate(mSourceMessage.begin(), mSourceMessage.end(), [&dist, &mt]() { return dist(mt); });
59// #endif // RANS_PARALLEL_STL
60// }
61// }
62
63// const auto& get() const { return mSourceMessage; };
64
65// private:
66// std::vector<source_T> mSourceMessage{};
67// };
68
69// inline const SourceMessageProxyBinomial<uint8_t> sourceMessageBinomial8{MessageSize};
70// inline const SourceMessageProxyBinomial<uint16_t> sourceMessageBinomial16{MessageSize};
71// inline const SourceMessageProxyBinomial<uint32_t> sourceMessageBinomial32{MessageSize};
72
73template <typename source_T>
75{
76 public:
77 SourceMessageProxyUniform(size_t messageSize)
78 {
79 if (mSourceMessage.empty()) {
80 std::mt19937 mt(0); // same seed we want always the same distrubution of random numbers;
81 const size_t min = 0;
82 const double max = std::min(1ul << 27, static_cast<size_t>(std::numeric_limits<source_T>::max()));
83 std::uniform_int_distribution<source_T> dist(min, max);
84 const size_t sourceSize = messageSize / sizeof(source_T) + 1;
85 mSourceMessage.resize(sourceSize);
86#ifdef RANS_PARALLEL_STL
87 std::generate(std::execution::par_unseq, mSourceMessage.begin(), mSourceMessage.end(), [&dist, &mt]() { return dist(mt); });
88#else
89 std::generate(mSourceMessage.begin(), mSourceMessage.end(), [&dist, &mt]() { return dist(mt); });
90#endif // RANS_PARALLEL_STL
91 }
92 }
93
94 const auto& get() const { return mSourceMessage; };
95
96 private:
97 std::vector<source_T> mSourceMessage{};
98};
99
103
104template <class... Args>
105void ransDecodeBenchmark(benchmark::State& st, Args&&... args)
106{
107
108 auto args_tuple = std::make_tuple(std::move(args)...);
109
110 const auto& inputData = std::get<0>(args_tuple).get();
111
112 using input_data_type = std::remove_cv_t<std::remove_reference_t<decltype(inputData)>>;
113 using source_type = typename input_data_type::value_type;
114
115 EncodeBuffer<source_type> encodeBuffer{inputData.size()};
117
118 const auto histogram = makeDenseHistogram::fromSamples(gsl::span<const source_type>(inputData));
119 Metrics<source_type> metrics{histogram};
120 const auto renormedHistogram = renorm(histogram, metrics, RenormingPolicy::Auto, 10);
121
122 auto encoder = makeDenseEncoder<>::fromRenormed(renormedHistogram);
123 encodeBuffer.encodeBufferEnd = encoder.process(inputData.data(), inputData.data() + inputData.size(), encodeBuffer.buffer.data());
124
125 auto decoder = makeDecoder<>::fromRenormed(renormedHistogram);
126#ifdef ENABLE_VTUNE_PROFILER
127 __itt_resume();
128#endif
129 for (auto _ : st) {
130 decoder.process(encodeBuffer.encodeBufferEnd, decodeBuffer.buffer.data(), inputData.size(), encoder.getNStreams());
131 }
132#ifdef ENABLE_VTUNE_PROFILER
133 __itt_pause();
134#endif
135
136 if (!(decodeBuffer == inputData)) {
137 st.SkipWithError("Missmatch between encoded and decoded Message");
138 }
139
140 const auto& datasetProperties = metrics.getDatasetProperties();
141 st.SetItemsProcessed(static_cast<int64_t>(inputData.size()) * static_cast<int64_t>(st.iterations()));
142 st.SetBytesProcessed(static_cast<int64_t>(inputData.size()) * sizeof(source_type) * static_cast<int64_t>(st.iterations()));
143 st.counters["AlphabetRangeBits"] = datasetProperties.alphabetRangeBits;
144 st.counters["nUsedAlphabetSymbols"] = datasetProperties.nUsedAlphabetSymbols;
145 st.counters["SymbolTablePrecision"] = renormedHistogram.getRenormingBits();
146 st.counters["Entropy"] = datasetProperties.entropy;
147 st.counters["ExpectedCodewordLength"] = computeExpectedCodewordLength(histogram, renormedHistogram);
148 st.counters["SourceSize"] = inputData.size() * sizeof(source_type);
149 st.counters["CompressedSize"] = std::distance(encodeBuffer.buffer.data(), encodeBuffer.encodeBufferEnd) * sizeof(typename decltype(encoder)::stream_type);
150 st.counters["Compression"] = st.counters["SourceSize"] / static_cast<double>(st.counters["CompressedSize"]);
151 st.counters["LowerBound"] = inputData.size() * (static_cast<double>(st.counters["Entropy"]) / 8);
152 st.counters["CompressionWRTEntropy"] = st.counters["CompressedSize"] / st.counters["LowerBound"];
153};
154
155// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_8, sourceMessageBinomial8);
156// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_16, sourceMessageBinomial16);
157// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_32, sourceMessageBinomial32);
158
162
std::vector< o2::mid::ColumnData > inputData
const SourceMessageProxyUniform< uint32_t > sourceMessageUniform32
void ransDecodeBenchmark(benchmark::State &st, Args &&... args)
constexpr size_t MessageSize
const SourceMessageProxyUniform< uint8_t > sourceMessageUniform8
BENCHMARK_MAIN()
BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_uniform_8, sourceMessageUniform8)
const SourceMessageProxyUniform< uint16_t > sourceMessageUniform16
benchmark::State & st
uint32_t source_type
uint32_t stream_type
SourceMessageProxyUniform(size_t messageSize)
static constexpr decltype(auto) fromRenormed(const RenormedHistogramConcept< container_T > &renormed)
Definition factory.h:106
static constexpr decltype(auto) fromRenormed(const RenormedDenseHistogram< source_T > &renormed)
Definition factory.h:195
preprocessor defines to enable features based on CPU architecture
static factory classes for building histograms, encoders and decoders.
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
Definition glcorearb.h:5500
common functionality for rANS benchmarks.
public interface for building and renorming histograms from source data.
double_t computeExpectedCodewordLength(const DenseHistogram< source_T > &histogram, const RenormedDenseHistogram< source_T > &rescaledHistogram)
Definition utils.h:33
decltype(auto) renorm(histogram_T histogram, size_t newPrecision, RenormingPolicy renormingPolicy=RenormingPolicy::Auto, size_t lowProbabilityCutoffBits=0)
Definition renorm.h:203
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)
Definition factory.h:144
std::string decodeBuffer(int feeId, gsl::span< const std::byte > buffer)
constexpr size_t min
constexpr size_t max