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#pragma GCC diagnostic push // TODO: Remove me when fixed in GCC
116#pragma GCC diagnostic ignored "-Walloc-size-larger-than="
117 EncodeBuffer<source_type> encodeBuffer{inputData.size()};
119#pragma GCC diagnostic pop
120
121 const auto histogram = makeDenseHistogram::fromSamples(gsl::span<const source_type>(inputData));
122 Metrics<source_type> metrics{histogram};
123 const auto renormedHistogram = renorm(histogram, metrics, RenormingPolicy::Auto, 10);
124
125 auto encoder = makeDenseEncoder<>::fromRenormed(renormedHistogram);
126 encodeBuffer.encodeBufferEnd = encoder.process(inputData.data(), inputData.data() + inputData.size(), encodeBuffer.buffer.data());
127
128 auto decoder = makeDecoder<>::fromRenormed(renormedHistogram);
129#ifdef ENABLE_VTUNE_PROFILER
130 __itt_resume();
131#endif
132 for (auto _ : st) {
133 decoder.process(encodeBuffer.encodeBufferEnd, decodeBuffer.buffer.data(), inputData.size(), encoder.getNStreams());
134 }
135#ifdef ENABLE_VTUNE_PROFILER
136 __itt_pause();
137#endif
138
139 if (!(decodeBuffer == inputData)) {
140 st.SkipWithError("Missmatch between encoded and decoded Message");
141 }
142
143 const auto& datasetProperties = metrics.getDatasetProperties();
144 st.SetItemsProcessed(static_cast<int64_t>(inputData.size()) * static_cast<int64_t>(st.iterations()));
145 st.SetBytesProcessed(static_cast<int64_t>(inputData.size()) * sizeof(source_type) * static_cast<int64_t>(st.iterations()));
146 st.counters["AlphabetRangeBits"] = datasetProperties.alphabetRangeBits;
147 st.counters["nUsedAlphabetSymbols"] = datasetProperties.nUsedAlphabetSymbols;
148 st.counters["SymbolTablePrecision"] = renormedHistogram.getRenormingBits();
149 st.counters["Entropy"] = datasetProperties.entropy;
150 st.counters["ExpectedCodewordLength"] = computeExpectedCodewordLength(histogram, renormedHistogram);
151 st.counters["SourceSize"] = inputData.size() * sizeof(source_type);
152 st.counters["CompressedSize"] = std::distance(encodeBuffer.buffer.data(), encodeBuffer.encodeBufferEnd) * sizeof(typename decltype(encoder)::stream_type);
153 st.counters["Compression"] = st.counters["SourceSize"] / static_cast<double>(st.counters["CompressedSize"]);
154 st.counters["LowerBound"] = inputData.size() * (static_cast<double>(st.counters["Entropy"]) / 8);
155 st.counters["CompressionWRTEntropy"] = st.counters["CompressedSize"] / st.counters["LowerBound"];
156};
157
158// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_8, sourceMessageBinomial8);
159// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_16, sourceMessageBinomial16);
160// BENCHMARK_CAPTURE(ransDecodeBenchmark, decode_binomial_32, sourceMessageBinomial32);
161
165
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