Project
Loading...
Searching...
No Matches
DecoderConcept.h
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
16#ifndef RANS_INTERNAL_DECODE_DECODER_CONCEPT_H_
17#define RANS_INTERNAL_DECODE_DECODER_CONCEPT_H_
18
19#include <fairlogger/Logger.h>
20#include <gsl/span>
21#include <stdexcept>
22
25
26namespace o2::rans
27{
28
29template <class decoder_T, class symbolTable_T>
31{
32 public:
33 using symbolTable_type = symbolTable_T;
34 using symbol_type = typename symbolTable_type::symbol_type;
35 using coder_type = decoder_T;
36 using source_type = typename symbolTable_type::source_type;
37 using stream_type = typename coder_type::stream_type;
38 using size_type = std::size_t;
39 using difference_type = std::ptrdiff_t;
40
41 private:
42 using value_type = typename symbolTable_type::value_type;
43
44 public:
45 DecoderConcept() = default;
46
47 template <typename container_T>
48 explicit DecoderConcept(const RenormedHistogramConcept<container_T>& renormedHistogram) : mSymbolTable{renormedHistogram} {};
49
50 [[nodiscard]] inline const symbolTable_type& getSymbolTable() const noexcept { return this->mSymbolTable; };
51
52 template <typename stream_IT, typename source_IT, typename literals_IT = std::nullptr_t, std::enable_if_t<utils::isCompatibleIter_v<typename symbolTable_T::source_type, source_IT>, bool> = true>
53 void process(stream_IT inputEnd, source_IT outputBegin, size_t messageLength, size_t nStreams, literals_IT literalsEnd = nullptr) const
54 {
55 {
56
57 if (messageLength == 0) {
58 LOG(warning) << "Empty message passed to decoder, skipping decode process";
59 return;
60 }
61
62 if (!(nStreams > 1 && internal::isPow2(nStreams))) {
63 throw DecodingError(fmt::format("Invalid number of decoder streams {}", nStreams));
64 }
65
66 stream_IT inputIter = inputEnd;
67 --inputIter;
68 source_IT outputIter = outputBegin;
69 literals_IT literalsIter = literalsEnd;
70
71 auto lookupSymbol = [&literalsIter, this](uint32_t cumulativeFrequency) -> value_type {
72 if constexpr (!std::is_null_pointer_v<literals_IT>) {
73 if (this->mSymbolTable.isEscapeSymbol(cumulativeFrequency)) {
74 return value_type{*(--literalsIter), this->mSymbolTable.getEscapeSymbol()};
75 } else {
76 return this->mSymbolTable[cumulativeFrequency];
77 }
78 } else {
79 return this->mSymbolTable[cumulativeFrequency];
80 }
81 };
82
83 auto decode = [&, this](coder_type& decoder) {
84 const auto cumul = decoder.get();
85 const value_type symbol = lookupSymbol(cumul);
86#ifdef RANS_LOG_PROCESSED_DATA
87 arrayLogger << symbol.first;
88#endif
89 return std::make_tuple(symbol.first, decoder.advanceSymbol(inputIter, symbol.second));
90 };
91
92 std::vector<coder_type> decoders{nStreams, coder_type{this->mSymbolTable.getPrecision()}};
93 for (auto& decoder : decoders) {
94 inputIter = decoder.init(inputIter);
95 }
96
97 const size_t nLoops = messageLength / nStreams;
98 const size_t nLoopRemainder = messageLength % nStreams;
99
100 for (size_t i = 0; i < nLoops; ++i) {
101#if defined(RANS_OPENMP)
102#pragma omp unroll partial(2)
103#endif
104 for (auto& decoder : decoders) {
105 std::tie(*outputIter++, inputIter) = decode(decoder);
106 }
107 }
108
109 for (size_t i = 0; i < nLoopRemainder; ++i) {
110 std::tie(*outputIter++, inputIter) = decode(decoders[i]);
111 }
112
113#ifdef RANS_LOG_PROCESSED_DATA
114 LOG(info) << "decoderOutput:" << arrayLogger;
115#endif
116 }
117 }
118
119 template <typename literals_IT = std::nullptr_t>
120 inline void process(gsl::span<const stream_type> inputStream, gsl::span<source_type> outputStream, size_t messageLength, size_t nStreams, literals_IT literalsEnd = nullptr) const
121 {
122 process(inputStream.data() + inputStream.size(), outputStream.data(), nStreams, literalsEnd);
123 };
124
125 protected:
127
128 static_assert(coder_type::getNstreams() == 1, "implementation supports only single stream encoders");
129};
130
131} // namespace o2::rans
132
133#endif /* RANS_INTERNAL_DECODE_DECODER_CONCEPT_H_ */
int32_t i
Histogram renormed to sum of frequencies being 2^P for use in fast rans coding.
common helper classes and functions
typename symbolTable_type::symbol_type symbol_type
void process(gsl::span< const stream_type > inputStream, gsl::span< source_type > outputStream, size_t messageLength, size_t nStreams, literals_IT literalsEnd=nullptr) const
const symbolTable_type & getSymbolTable() const noexcept
typename symbolTable_type::source_type source_type
symbolTable_type mSymbolTable
std::ptrdiff_t difference_type
void process(stream_IT inputEnd, source_IT outputBegin, size_t messageLength, size_t nStreams, literals_IT literalsEnd=nullptr) const
typename coder_type::stream_type stream_type
DecoderConcept(const RenormedHistogramConcept< container_T > &renormedHistogram)
symbolTable_T symbolTable_type
constexpr bool isPow2(T x) noexcept
Definition utils.h:104
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
coder decode(ctfImage, triggersD, clustersD)