Project
Loading...
Searching...
No Matches
test_ransPack.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
16#define BOOST_TEST_MODULE Utility test
17#define BOOST_TEST_MAIN
18#define BOOST_TEST_DYN_LINK
19
20#undef NDEBUG
21#include <cassert>
22
23#include <vector>
24#include <cstring>
25#include <random>
26#include <algorithm>
27
28#include <boost/test/unit_test.hpp>
29#include <boost/mp11.hpp>
30#include <fmt/core.h>
31
35
36using namespace o2::rans;
37using namespace o2::rans::internal;
38using namespace o2::rans::utils;
39
40inline constexpr size_t BufferSize = 257;
41
42template <typename source_T>
43std::vector<source_T>
44 makeRandomUniformVector(size_t nelems, source_T min = std::numeric_limits<source_T>::min(), source_T max = std::numeric_limits<source_T>::max())
45{
46 std::vector<source_T> result(nelems, 0);
47 std::mt19937 mt(0); // same seed we want always the same distrubution of random numbers;
48 std::uniform_int_distribution<source_T> dist(min, max);
49 std::generate(result.begin(), result.end(), [&dist, &mt]() { return dist(mt); });
50 return result;
51};
52
53using buffer_types = boost::mp11::mp_list<int8_t, int16_t, int32_t, int64_t>;
54
55using source_types = boost::mp11::mp_list<uint8_t, uint16_t, uint32_t, uint64_t>;
56
57BOOST_AUTO_TEST_CASE_TEMPLATE(test_computePackingBufferSize, buffer_T, buffer_types)
58{
59 size_t packingWidth = utils::toBits<packing_type>() - 3;
60
61 BOOST_CHECK_EQUAL(0, (computePackingBufferSize<buffer_T>(0, packingWidth)));
62 BOOST_CHECK_EQUAL(sizeof(packing_type) / sizeof(buffer_T), (computePackingBufferSize<buffer_T>(1, packingWidth))); // space it takes to pack 1 element takes 4 B
63 BOOST_CHECK_EQUAL(sizeof(packing_type) * 62 / sizeof(buffer_T), (computePackingBufferSize<buffer_T>(64, packingWidth))); // space it takes to pack 64 elements takes 62 * packingType = 496 B
64 BOOST_CHECK_EQUAL(sizeof(packing_type) * 22 / sizeof(buffer_T), (computePackingBufferSize<buffer_T>(23, packingWidth))); // space it takes to pack 23 elements takes 22 * packingType = 176 B
65}
66
67BOOST_AUTO_TEST_CASE(test_packUnpack)
68{
69 using source_type = uint64_t;
70
71 for (size_t packingWidth = 1; packingWidth <= 58; ++packingWidth) {
72 BOOST_TEST_MESSAGE(fmt::format("Checking {} Bit Packing", packingWidth));
73
74 auto source = makeRandomUniformVector<source_type>(BufferSize, 0, utils::pow2(packingWidth) - 1);
75 std::vector<uint8_t> packingBuffer(source.size() * sizeof(source_type), 0);
76
77 BitPtr packIter{packingBuffer.data()};
78 for (auto i : source) {
79 packIter = pack(packIter, i, packingWidth);
80 }
81
82 BitPtr unpackIter{packingBuffer.data()};
83 std::vector<source_type> result(source.size(), 0);
84 for (size_t i = 0; i < source.size(); ++i) {
85 result[i] = unpack<uint64_t>(unpackIter, packingWidth);
86 unpackIter += packingWidth;
87 }
88
89 // check if results are equal;
90 BOOST_CHECK_EQUAL(packIter, unpackIter);
91 BOOST_CHECK_EQUAL_COLLECTIONS(source.begin(), source.end(), result.begin(), result.end());
92 }
93};
94
95BOOST_AUTO_TEST_CASE(test_packUnpackLong)
96{
97 using source_type = uint64_t;
98
99 for (size_t packingWidth = 1; packingWidth <= 63; ++packingWidth) {
100 BOOST_TEST_MESSAGE(fmt::format("Checking {} Bit Packing", packingWidth));
101
102 auto source = makeRandomUniformVector<source_type>(BufferSize, 0, utils::pow2(packingWidth) - 1);
103 std::vector<uint8_t> packingBuffer(source.size() * sizeof(source_type), 0);
104
105 BitPtr packIter{packingBuffer.data()};
106 for (auto i : source) {
107 packIter = packLong(packIter, i, packingWidth);
108 }
109
110 BitPtr unpackIter{packingBuffer.data()};
111 std::vector<source_type> result(source.size(), 0);
112 for (size_t i = 0; i < source.size(); ++i) {
113 result[i] = unpackLong(unpackIter, packingWidth);
114 unpackIter += packingWidth;
115 }
116
117 // check if results are equal;
118 BOOST_CHECK_EQUAL(packIter, unpackIter);
119 BOOST_CHECK_EQUAL_COLLECTIONS(source.begin(), source.end(), result.begin(), result.end());
120 }
121};
122
123BOOST_AUTO_TEST_CASE(test_packUnpackStream)
124{
125 using source_type = uint64_t;
126
127 for (size_t packingWidth = 1; packingWidth <= 63; ++packingWidth) {
128 BOOST_TEST_MESSAGE(fmt::format("Checking {} Bit Packing", packingWidth));
129 auto source = makeRandomUniformVector<source_type>(BufferSize, 0, utils::pow2(packingWidth) - 1);
130 std::vector<uint8_t> packingBuffer(source.size() * sizeof(source_type), 0);
131
132 source_type min = *std::min_element(source.begin(), source.end());
133
134 [[maybe_unused]] auto packingBufferEnd = pack(source.data(), source.size(), packingBuffer.data(), packingWidth, min);
135
136 std::vector<source_type> unpackBuffer(source.size(), 0);
137 unpack(packingBuffer.data(), source.size(), unpackBuffer.data(), packingWidth, min);
138
139 // compare if both yield the correct result
140 BOOST_CHECK_EQUAL_COLLECTIONS(source.begin(), source.end(), unpackBuffer.begin(), unpackBuffer.end());
141 }
142};
143
144BOOST_AUTO_TEST_CASE(test_packRUnpackEliasDelta)
145{
146 using source_type = uint32_t;
147
148 for (size_t packingWidth = 1; packingWidth <= 32; ++packingWidth) {
149 BOOST_TEST_MESSAGE(fmt::format("Checking {} Bit Elias Delta Coder", packingWidth));
150 auto source = makeRandomUniformVector<source_type>(BufferSize, 1ull, utils::pow2(packingWidth) - 1);
151 std::vector<uint64_t> packingBuffer(source.size(), 0);
152
153 BitPtr iter{packingBuffer.data()};
154 for (auto i : source) {
155 iter = eliasDeltaEncode(iter, i);
156 };
157
158 BitPtr iterBegin{packingBuffer.data()};
159 std::vector<source_type> unpackBuffer(source.size(), 0);
160 for (size_t i = 0; i < source.size(); ++i) {
161 const size_t maxOffset = std::min(static_cast<size_t>(iter - iterBegin), EliasDeltaDecodeMaxBits);
162 unpackBuffer[i] = eliasDeltaDecode<source_type>(iter, maxOffset);
163 };
164
165 // compare if both yield the correct result
166 BOOST_CHECK_EQUAL_COLLECTIONS(source.begin(), source.end(), unpackBuffer.rbegin(), unpackBuffer.rend());
167 }
168};
Pointer type helper class for bitwise Packing.
int32_t i
uint32_t source_type
compress data stream using Elias-Delta coding.
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
packs data into a buffer
BitPtr pack(BitPtr pos, uint64_t data, size_t packingWidth)
Definition pack.h:68
BitPtr eliasDeltaEncode(BitPtr dst, uint32_t data)
Definition eliasDelta.h:30
constexpr size_t EliasDeltaDecodeMaxBits
Definition eliasDelta.h:47
uint64_t packing_type
Definition utils.h:33
uint64_t unpackLong(BitPtr pos, size_t packingWidth)
Definition pack.h:114
T unpack(BitPtr pos, size_t packingWidth)
Definition pack.h:101
BitPtr packLong(BitPtr pos, uint64_t data, size_t packingWidth)
Definition pack.h:73
boost::mp11::mp_list< uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t > source_types
constexpr size_t min
constexpr size_t max
BOOST_CHECK_EQUAL(triggersD.size(), triggers.size())
BOOST_AUTO_TEST_CASE_TEMPLATE(test_computePackingBufferSize, buffer_T, buffer_types)
std::vector< source_T > makeRandomUniformVector(size_t nelems, source_T min=std::numeric_limits< source_T >::min(), source_T max=std::numeric_limits< source_T >::max())
BOOST_AUTO_TEST_CASE(test_packUnpack)
constexpr size_t BufferSize
boost::mp11::mp_list< int8_t, int16_t, int32_t, int64_t > buffer_types