17#ifndef ALICEO2_ENCODED_BLOCKS_H
18#define ALICEO2_ENCODED_BLOCKS_H
53template <
class,
class Enable =
void>
59 std::is_base_of_v<std::input_iterator_tag, typename std::iterator_traits<T>::iterator_category> ||
60 std::is_same_v<std::output_iterator_tag, typename std::iterator_traits<T>::iterator_category>>>
99 return (
ptr !=
nullptr) ?
reinterpret_cast<T*
>(newBase + (
reinterpret_cast<const char*
>(
ptr) - oldBase)) :
nullptr;
102template <
typename source_T,
typename dest_T, std::enable_if_t<(sizeof(dest_T) >= sizeof(source_T)),
bool> =
true>
105 const size_t srcBufferSize = nElems *
sizeof(
source_T);
106 return srcBufferSize /
sizeof(dest_T) + (srcBufferSize %
sizeof(dest_T) != 0);
109template <
typename source_T,
typename dest_T, std::enable_if_t<(sizeof(dest_T) >= sizeof(source_T)),
bool> =
true>
112 const size_t sizeOfSourceT =
sizeof(
source_T);
113 const size_t sizeOfDestT =
sizeof(dest_T);
116 return (sizeOfDestT / sizeOfSourceT) * calculateNDestTElements<source_T, dest_T>(nElems);
151template <
typename W = u
int32_t>
235 throw std::runtime_error(
"trying to write in occupied block");
239 assert(sz <= registry->getFreeSize());
240 assert((_ndict > 0) == (_dict !=
nullptr));
252 throw std::runtime_error(
"trying to write in occupied block");
257 assert(sz <= registry->getFreeSize());
258 assert((_ndata > 0) == (_data !=
nullptr));
270 throw std::runtime_error(
"trying to write in occupied block");
275 assert(sz <= registry->getFreeSize());
294 void store(
int _ndict,
int _ndata,
int _nliterals,
const W* _dict,
const W* _data,
const W* _literals)
298 assert(sz <= registry->getFreeSize());
299 assert((_ndict > 0) == (_dict !=
nullptr));
300 assert((_ndata > 0) == (_data !=
nullptr));
322 void relocate(
const char* oldHead,
char* newHeadData,
char* newHeadRegistry)
333template <
typename H,
int N,
typename W = u
int32_t>
340 template <
typename source_T>
369 template <
typename source_T>
376 assert(
static_cast<int64_t
>(std::numeric_limits<source_T>::min()) <=
static_cast<int64_t
>(metadata.max));
377 assert(
static_cast<int64_t
>(std::numeric_limits<source_T>::max()) >=
static_cast<int64_t
>(metadata.min));
381 const int64_t sourceMin = std::numeric_limits<source_T>::min();
382 const int64_t sourceMax = std::numeric_limits<source_T>::max();
385 const int64_t dictMin = view.getMin();
386 const int64_t dictMax = view.getMax();
387 assert(dictMin >= metadata.min);
388 assert(dictMax <= metadata.max);
390 if ((dictMin < sourceMin) || (dictMax > sourceMax)) {
392 LOGP(warn,
"value range of dictionary and target datatype are incompatible: target type [{},{}] vs dictionary [{},{}], tolerate in compat mode for old dictionaries", sourceMin, sourceMax, dictMin, dictMax);
394 throw std::runtime_error(fmt::format(
"value range of dictionary and target datatype are incompatible: target type [{},{}] vs dictionary [{},{}]", sourceMin, sourceMax, dictMin, dictMax));
407 LOG_IF(
debug, renormingBits != metadata.probabilityBits)
408 << fmt::format(
"While reading metadata from external dictionary, rANSV1 is rounding renorming precision from {} to {}", metadata.probabilityBits, renormingBits);
412 if constexpr (
sizeof(
source_T) > 2) {
415 metadata.probabilityBits);
419 metadata.probabilityBits);
423 throw std::runtime_error(fmt::format(
"Failed to load serialized Dictionary. Unsupported ANS Version: {}",
static_cast<std::string
>(ansVersion)));
447 static auto create(
void* head,
size_t sz);
450 template <
typename VD>
475 template <
typename buffer_T>
479 template <
typename V>
492 template <
typename VD>
496 template <
typename VE,
typename buffer_T>
499 return encode(std::begin(
src), std::end(
src), slot, symbolTablePrecision, opt,
buffer, encoderExt, memfc);
503 template <
typename input_IT,
typename buffer_T>
507 template <
class container_T,
class container_IT =
typename container_T::iterator>
511 template <
typename D_IT, std::enable_if_t<detail::is_iterator_v<D_IT>,
bool> = true>
521 void dump(
const std::string& prefix =
"",
int ncol = 20)
const;
524 static_assert(N > 0,
"number of encoded blocks < 1");
541 static void relocate(
const char* oldHead,
char* newHead,
char* wrapper,
size_t newsize = 0);
554 template <
typename D>
555 static size_t fillTreeBranch(TTree&
tree,
const std::string& brname, D& dt,
int compLevel,
int splitLevel = 99);
558 template <
typename D>
561 template <
typename T>
569 const bool isEqual{ansVersion == ctfANSHeader};
573 if (isHeaderUnspecified) {
574 throw std::runtime_error{fmt::format(
"Missmatch of ANSVersions, trying to encode/decode CTF with ANS Version Header {} with ANS Version {}",
575 static_cast<std::string
>(ctfANSHeader),
576 static_cast<std::string
>(ansVersion))};
581 if (isHeaderUnspecified) {
591 template <
typename input_IT,
typename buffer_T>
594 template <
typename input_IT,
typename buffer_T>
597 template <
typename input_IT,
typename buffer_T>
600 template <
typename input_IT,
typename buffer_T>
604 template <
typename input_IT,
typename buffer_T>
607 template <
typename input_IT,
typename buffer_T>
610 using source_type =
typename std::iterator_traits<input_IT>::value_type;
615 if (
metrics.getDatasetProperties().numSamples != 0) {
616 const auto [minIter, maxIter] = std::minmax_element(srcBegin, srcEnd);
617 metrics.getDatasetProperties().min = *minIter;
618 metrics.getDatasetProperties().max = *maxIter;
621 metrics.getDatasetProperties().alphabetRangeBits =
623 metrics.getDatasetProperties().max);
630 template <
typename input_IT,
typename buffer_T>
634 template <
typename dst_IT>
637 template <
typename dst_IT>
640 template <
typename dst_IT>
643 template <
typename dst_IT>
651template <
typename H,
int N,
typename W>
655 for (
int i = 0;
i < N;
i++) {
662template <
typename H,
int N,
typename W>
663template <
typename VD>
666 auto tmp = create(
vec);
668 throw std::runtime_error(fmt::format(
"Failed to read CTF header for {}",
name));
670 tmp = tmp->expand(
vec, tmp->estimateSizeFromMetadata());
671 const auto& meta = tmp->getMetadata();
672 for (
int i = 0;
i < N;
i++) {
675 assert(meta[
i].nDictWords == bl.
getNDict());
676 assert(meta[
i].nDataWords == bl.
getNData());
684template <
typename H,
int N,
typename W>
689 for (
int i = 0;
i < N;
i++) {
693 tree.SetEntries(
tree.GetEntries() + 1);
699template <
typename H,
int N,
typename W>
703 auto* br =
tree.GetBranch(brname.c_str());
705 LOG(
debug) <<
"Branch " << brname <<
" is absent";
709 br->SetAddress(&
ptr);
717template <
typename H,
int N,
typename W>
721 auto* br =
tree.GetBranch(brname.c_str());
723 br =
tree.Branch(brname.c_str(), &dt, 512, splitLevel);
724 br->SetCompressionLevel(compLevel);
731template <
typename H,
int N,
typename W>
738 for (
int i = 0;
i < N;
i++) {
739 dest.
mBlocks[
i].store(mBlocks[
i].getNDict(), mBlocks[
i].getNData(), mBlocks[
i].getDict(), mBlocks[
i].
getData());
745template <
typename H,
int N,
typename W>
749 auto vtsz =
sizeof(
typename std::remove_reference<
decltype(
vec)>::type::value_type), sz =
estimateSize();
750 vec.resize(sz / vtsz);
751 copyToFlat(
vec.data());
757template <
typename H,
int N,
typename W>
762 for (
int i = 0;
i < N;
i++) {
763 sz +=
alignSize(mBlocks[
i].nStored *
sizeof(W));
771template <
typename H,
int N,
typename W>
775 for (
int i = 0;
i < N;
i++) {
776 sz +=
alignSize((mMetadata[
i].nDictWords + mMetadata[
i].nDataWords + mMetadata[
i].nLiteralWords) *
sizeof(W));
783template <
typename H,
int N,
typename W>
784template <
typename buffer_T>
787 auto buftypesize =
sizeof(
typename std::remove_reference<
decltype(
buffer)>::type::value_type);
788 auto* oldHead = get(
buffer.data())->mRegistry.head;
790 relocate(oldHead,
reinterpret_cast<char*
>(
buffer.data()),
reinterpret_cast<char*
>(
buffer.data()), newsizeBytes);
791 return get(
buffer.data());
799template <
typename H,
int N,
typename W>
802 auto newStr = get(wrapper);
803 for (
int i = 0;
i < N;
i++) {
804 newStr->mBlocks[
i].relocate(oldHead, newHead, wrapper);
806 newStr->mRegistry.head = newHead;
809 assert(newStr->estimateSize() <= newsize);
810 newStr->mRegistry.size = newsize;
816template <
typename H,
int N,
typename W>
819 mRegistry.
head =
reinterpret_cast<char*
>(
this);
822 for (
int i = 0;
i < N;
i++) {
823 mMetadata[
i].clear();
824 mBlocks[
i].registry = &mRegistry;
831template <
typename H,
int N,
typename W>
834 for (
int i = 0;
i < N;
i++) {
836 mMetadata[
i].clear();
843template <
typename H,
int N,
typename W>
847 auto image(*get(newHead));
850 relocate(
image.mRegistry.head,
const_cast<char*
>(
reinterpret_cast<const char*
>(newHead)),
reinterpret_cast<char*
>(&
image));
857template <
typename H,
int N,
typename W>
869template <
typename H,
int N,
typename W>
870template <
typename VD>
873 size_t vsz =
sizeof(
typename std::remove_reference<
decltype(
v)>::type::value_type);
874 auto baseSize = getMinAlignedSize() / vsz;
875 if (
v.size() < baseSize) {
878 return create(
v.data(),
v.size() * vsz);
883template <
typename H,
int N,
typename W>
887 LOG(info) << prefix <<
"Container of " << N <<
" blocks, size: " <<
size() <<
" bytes, unused: " << getFreeSize();
888 for (
int i = 0;
i < N;
i++) {
889 LOG(info) <<
"Block " <<
i <<
" for " <<
static_cast<uint32_t
>(mMetadata[
i].messageLength) <<
" message words of "
890 <<
static_cast<uint32_t
>(mMetadata[
i].messageWordSize) <<
" bytes |"
891 <<
" NDictWords: " << mBlocks[
i].getNDict() <<
" NDataWords: " << mBlocks[
i].getNData()
892 <<
" NLiteralWords: " << mBlocks[
i].getNLiterals();
895 size_t inpSize = 0, ndict = 0, ndata = 0, nlit = 0;
896 for (
int i = 0;
i < N;
i++) {
897 inpSize += mMetadata[
i].messageLength * mMetadata[
i].messageWordSize;
898 ndict += mBlocks[
i].getNDict();
899 ndata += mBlocks[
i].getNData();
900 nlit += mBlocks[
i].getNLiterals();
902 LOG(info) << prefix << N <<
" blocks, input size: " << inpSize <<
", output size: " <<
size()
903 <<
" NDictWords: " << ndict <<
" NDataWords: " << ndata <<
" NLiteralWords: " << nlit;
908template <
typename H,
int N,
typename W>
909template <
class container_T,
class container_IT>
912 const std::any& decoderExt)
const
914 dest.resize(mMetadata[slot].messageLength);
915 return decode(std::begin(dest), slot, decoderExt);
919template <
typename H,
int N,
typename W>
920template <
typename D_IT, std::enable_if_t<detail::is_iterator_v<D_IT>,
bool>>
923 const std::any& decoderExt)
const
927 const auto& ansVersion = getANSHeader();
928 const auto& block = mBlocks[slot];
929 const auto& md = mMetadata[slot];
930 LOGP(
debug,
"Slot{} | NStored={} Ndict={} nData={}, MD: messageLength:{} opt:{} min:{} max:{} offs:{} width:{} ", slot, block.getNStored(), block.getNDict(), block.getNData(), md.messageLength, (
int)md.opt, md.min, md.max, md.literalsPackingOffset, md.literalsPackingWidth);
932 constexpr size_t word_size =
sizeof(W);
935 if (!block.getNStored()) {
936 return {0, md.getUncompressedSize(), md.getCompressedSize() * word_size};
939 return decodeCompatImpl(dest, slot, decoderExt);
941 return decodeCopyImpl(dest, slot);
945 return decodeUnpackImpl(dest, slot);
947 if (!block.getNStored()) {
948 return {0, md.getUncompressedSize(), md.getCompressedSize() * word_size};
951 return decodeRansV1Impl(dest, slot, decoderExt);
953 return decodeCopyImpl(dest, slot);
956 throw std::runtime_error(
"unsupported ANS Version");
961template <
typename H,
int N,
typename W>
962template <
typename dst_IT>
967 const auto& block = mBlocks[slot];
968 const auto& md = mMetadata[slot];
970 using dst_type =
typename std::iterator_traits<dst_IT>::value_type;
973 std::optional<decoder_type> inplaceDecoder{};
974 if (md.nDictWords > 0) {
975 inplaceDecoder = decoder_type{std::get<rans::RenormedDenseHistogram<dst_type>>(this->getDictionary<dst_type>(slot))};
976 }
else if (!decoderExt.has_value()) {
977 throw std::runtime_error(
"neither dictionary nor external decoder provided");
980 auto getDecoder = [&]() ->
const decoder_type& {
981 if (inplaceDecoder.has_value()) {
982 return inplaceDecoder.value();
984 return std::any_cast<const decoder_type&>(decoderExt);
990 if (block.getNLiterals()) {
991 auto* literalsEnd =
reinterpret_cast<const dst_type*
>(block.getLiterals()) + md.nLiterals;
992 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, NDecoderStreams, literalsEnd);
994 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, NDecoderStreams);
996 return {0, md.getUncompressedSize(), md.getCompressedSize() *
sizeof(W)};
999template <
typename H,
int N,
typename W>
1000template <
typename dst_IT>
1005 const auto& block = mBlocks[slot];
1006 const auto& md = mMetadata[slot];
1008 using dst_type =
typename std::iterator_traits<dst_IT>::value_type;
1011 std::optional<decoder_type> inplaceDecoder{};
1012 if (md.nDictWords > 0) {
1013 std::visit([&](
auto&& arg) { inplaceDecoder = decoder_type{arg}; }, this->getDictionary<dst_type>(slot));
1014 }
else if (!decoderExt.has_value()) {
1015 throw std::runtime_error(
"no dictionary nor external decoder provided");
1018 auto getDecoder = [&]() ->
const decoder_type& {
1019 if (inplaceDecoder.has_value()) {
1020 return inplaceDecoder.value();
1022 return std::any_cast<const decoder_type&>(decoderExt);
1028 const decoder_type& decoder = getDecoder();
1029 const size_t decoderSymbolTablePrecision = decoder.getSymbolTablePrecision();
1031 if (md.probabilityBits != decoderSymbolTablePrecision) {
1032 throw std::runtime_error(fmt::format(
1033 "Missmatch in decoder renorming precision vs metadata:{} Bits vs {} Bits.",
1034 md.probabilityBits, decoderSymbolTablePrecision));
1037 if (md.streamSize != rans::utils::getStreamingLowerBound_v<typename decoder_type::coder_type>) {
1038 throw std::runtime_error(
"Streaming lower bound of dataset and decoder do not match");
1043 if (block.getNLiterals()) {
1044 std::vector<dst_type> literals(md.nLiterals);
1045 rans::unpack(block.getLiterals(), md.nLiterals, literals.data(), md.literalsPackingWidth, md.literalsPackingOffset);
1046 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, md.nStreams, literals.end());
1048 getDecoder().process(block.getData() + block.getNData(), dstBegin, md.messageLength, md.nStreams);
1050 return {0, md.getUncompressedSize(), md.getCompressedSize() *
sizeof(W)};
1053template <
typename H,
int N,
typename W>
1054template <
typename dst_IT>
1057 using dest_t =
typename std::iterator_traits<dst_IT>::value_type;
1059 const auto& block = mBlocks[slot];
1060 const auto& md = mMetadata[slot];
1062 const size_t messageLength = md.messageLength;
1063 const size_t packingWidth = md.probabilityBits;
1064 const dest_t
offset = md.min;
1065 const auto* srcIt = block.getData();
1067 if (packingWidth == 0) {
1068 const dest_t
value = [&]() -> dest_t {
1070 if (md.nDataWords > 0) {
1071 LOGP(
debug,
"packing bug recovery: MD nStreams:{} messageLength:{} nLiterals:{} messageWordSize:{} coderType:{} streamSize:{} probabilityBits:{} (int)opt:{} min:{} max:{} literalsPackingOffset:{} literalsPackingWidth:{} nDictWords:{} nDataWords:{} nLiteralWords:{}",
1072 value, md.nStreams, md.messageLength, md.nLiterals, md.messageWordSize, md.coderType, md.streamSize, md.probabilityBits, (
int)md.opt, md.min, md.max, md.literalsPackingOffset, md.literalsPackingWidth, md.nDictWords, md.nDataWords, md.nLiteralWords);
1073 return offset +
static_cast<dest_t
>(*srcIt);
1078 for (
size_t i = 0;
i < messageLength; ++
i) {
1084 return {0, md.getUncompressedSize(), md.getCompressedSize() *
sizeof(W)};
1087template <
typename H,
int N,
typename W>
1088template <
typename dst_IT>
1092 const auto& block = mBlocks[slot];
1093 const auto& md = mMetadata[slot];
1095 using dest_t =
typename std::iterator_traits<dst_IT>::value_type;
1097 using destPtr_t =
typename std::iterator_traits<dst_IT>::pointer;
1099 destPtr_t srcBegin =
reinterpret_cast<destPtr_t
>(block.payload);
1100 destPtr_t srcEnd = srcBegin + md.messageLength *
sizeof(dest_t);
1101 std::copy(srcBegin, srcEnd, dest);
1103 return {0, md.getUncompressedSize(), md.getCompressedSize() *
sizeof(W)};
1107template <
typename H,
int N,
typename W>
1108template <
typename input_IT,
typename buffer_T>
1110 const input_IT srcEnd,
1112 uint8_t symbolTablePrecision,
1115 const std::any& encoderExt,
1122 const size_t messageLength = std::distance(srcBegin, srcEnd);
1129 if (messageLength == 0) {
1135 const ANSHeader& ansVersion = getANSHeader();
1137 return entropyCodeRANSCompat(srcBegin, srcEnd, slot, symbolTablePrecision,
buffer, encoderExt, memfc);
1139 return entropyCodeRANSV1(srcBegin, srcEnd, slot, opt,
buffer, encoderExt, memfc);
1141 throw std::runtime_error(fmt::format(
"Unsupported ANS Coder Version: {}.{}", ansVersion.
majorVersion, ansVersion.
minorVersion));
1146 return store(srcBegin, srcEnd, slot, opt,
buffer);
1150template <
typename H,
int N,
typename W>
1151template <
typename T>
1155 auto* old = get(
buffer->data());
1156 auto* thisBlock = &(old->mBlocks[slot]);
1157 auto* thisMetadata = &(old->mMetadata[slot]);
1160 auto*
const blockHead = get(thisBlock->registry->head);
1161 const size_t additionalSize = blockHead->estimateBlockSize(nElements);
1162 if (additionalSize >= thisBlock->registry->getFreeSize()) {
1163 LOGP(
debug,
"Slot {} with {} available words needs to allocate {} bytes for a total of {} words.", slot, thisBlock->registry->getFreeSize(), additionalSize, nElements);
1165 blockHead->expand(*
buffer, blockHead->size() + (additionalSize - blockHead->getFreeSize()));
1166 thisMetadata = &(get(
buffer->data())->mMetadata[slot]);
1167 thisBlock = &(get(
buffer->data())->mBlocks[slot]);
1169 throw std::runtime_error(
"failed to allocate additional space in provided external buffer");
1172 return std::make_pair(thisBlock, thisMetadata);
1175template <
typename H,
int N,
typename W>
1176template <
typename input_IT,
typename buffer_T>
1179 using storageBuffer_t = W;
1180 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1182 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1183 using ransStream_t =
typename ransEncoder_t::stream_type;
1186 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1187 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1189 auto* thisBlock = &mBlocks[slot];
1190 auto* thisMetadata = &mMetadata[slot];
1193 constexpr size_t SizeEstMarginAbs = 10 * 1024;
1194 const float SizeEstMarginRel = 1.5 * memfc;
1196 const size_t messageLength = std::distance(srcBegin, srcEnd);
1201 std::tie(inplaceEncoder, frequencyTable) = [&]() {
1202 if (encoderExt.has_value()) {
1207 return std::make_tuple(std::move(encoder), std::move(histogram));
1211 LOGP(warning,
"Failed to build Dictionary for rANS encoding, using fallback option");
1212 return store(srcBegin, srcEnd, slot, this->FallbackStorageType,
buffer);
1214 const ransEncoder_t& encoder = encoderExt.has_value() ? std::any_cast<const ransEncoder_t&>(encoderExt) : inplaceEncoder;
1219 dataSize = SizeEstMarginAbs +
int(SizeEstMarginRel * (
dataSize /
sizeof(storageBuffer_t))) + (
sizeof(input_t) <
sizeof(storageBuffer_t));
1222 std::tie(thisBlock, thisMetadata) = expandStorage(slot, view.size() +
dataSize,
buffer);
1226 if (!view.empty()) {
1227 thisBlock->storeDict(view.size(), view.data());
1228 LOGP(
debug,
"StoreDict {} bytes, offs: {}:{}", view.size() *
sizeof(W), thisBlock->getOffsDict(), thisBlock->getOffsDict() + view.size() *
sizeof(W));
1231 std::vector<input_t> literals;
1233 storageBuffer_t*
const blockBufferBegin = thisBlock->getCreateData();
1234 const size_t maxBufferSize = thisBlock->registry->getFreeSize();
1235 const auto [encodedMessageEnd, literalsEnd] = encoder.process(srcBegin, srcEnd, blockBufferBegin, std::back_inserter(literals));
1237 dataSize = encodedMessageEnd - thisBlock->getDataPointer();
1239 thisBlock->realignBlock();
1240 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(W), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(W));
1244 const size_t nLiteralSymbols = literals.size();
1245 const size_t nLiteralWords = [&]() {
1246 if (!literals.empty()) {
1247 const size_t nSymbols = literals.size();
1249 const size_t nLiteralSymbolsPadded = calculatePaddedSize<input_t, storageBuffer_t>(nSymbols);
1250 literals.resize(nLiteralSymbolsPadded, {});
1252 const size_t nLiteralStorageElems = calculateNDestTElements<input_t, storageBuffer_t>(nSymbols);
1253 std::tie(thisBlock, thisMetadata) = expandStorage(slot, nLiteralStorageElems,
buffer);
1254 thisBlock->storeLiterals(nLiteralStorageElems,
reinterpret_cast<const storageBuffer_t*
>(literals.data()));
1255 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", nLiteralStorageElems *
sizeof(W), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + nLiteralStorageElems *
sizeof(W));
1256 return nLiteralStorageElems;
1261 LOGP(
debug,
"Min, {} Max, {}, size, {}, nSamples {}", view.getMin(), view.getMax(), view.size(), frequencyTable.getNumSamples());
1263 *thisMetadata = detail::makeMetadataRansCompat<input_t, ransState_t, ransStream_t>(encoder.getNStreams(),
1266 encoder.getSymbolTable().getPrecision(),
1273 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize() *
sizeof(W)};
1276template <
typename H,
int N,
typename W>
1277template <
typename input_IT,
typename buffer_T>
1282 const size_t nSamples = std::distance(srcBegin, srcEnd);
1284 encoderStatistics =
pack(srcBegin, srcEnd, slot,
buffer);
1287 if (encoderExt.has_value()) {
1288 encoderStatistics = encodeRANSV1External(srcBegin, srcEnd, slot, encoderExt,
buffer, memfc);
1290 encoderStatistics = encodeRANSV1Inplace(srcBegin, srcEnd, slot, opt,
buffer, memfc);
1293 return encoderStatistics;
1296template <
typename H,
int N,
typename W>
1297template <
typename input_IT,
typename buffer_T>
1300 using storageBuffer_t = W;
1301 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1303 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1304 using ransStream_t =
typename ransEncoder_t::stream_type;
1307 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1308 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1310 auto* thisBlock = &mBlocks[slot];
1311 auto* thisMetadata = &mMetadata[slot];
1313 const size_t messageLength = std::distance(srcBegin, srcEnd);
1316 const size_t payloadSizeWords = encoder.template computePayloadSizeEstimate<storageBuffer_t>(messageLength);
1317 std::tie(thisBlock, thisMetadata) = expandStorage(slot, payloadSizeWords,
buffer);
1320 auto encodedMessageEnd = encoder.encode(srcBegin, srcEnd, thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1321 const size_t dataSize = std::distance(thisBlock->getCreateData(), encodedMessageEnd);
1323 thisBlock->realignBlock();
1324 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(storageBuffer_t));
1328 size_t literalsSize = 0;
1329 if (encoder.getNIncompressibleSamples() > 0) {
1330 const size_t literalsBufferSizeWords = encoder.template computePackedIncompressibleSize<storageBuffer_t>();
1331 std::tie(thisBlock, thisMetadata) = expandStorage(slot, literalsBufferSizeWords,
buffer);
1332 auto literalsEnd = encoder.writeIncompressible(thisBlock->getCreateLiterals(), thisBlock->getEndOfBlock());
1333 literalsSize = std::distance(thisBlock->getCreateLiterals(), literalsEnd);
1334 thisBlock->setNLiterals(literalsSize);
1335 thisBlock->realignBlock();
1336 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", literalsSize *
sizeof(storageBuffer_t), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + literalsSize *
sizeof(storageBuffer_t));
1340 const auto& symbolTable = encoder.getEncoder().getSymbolTable();
1341 *thisMetadata = detail::makeMetadataRansV1<input_t, ransState_t, ransStream_t>(encoder.getEncoder().getNStreams(),
1342 rans::utils::getStreamingLowerBound_v<typename ransEncoder_t::coder_type>,
1344 encoder.getNIncompressibleSamples(),
1345 symbolTable.getPrecision(),
1346 symbolTable.getOffset(),
1347 symbolTable.getOffset() + symbolTable.size(),
1348 encoder.getIncompressibleSymbolOffset(),
1349 encoder.getIncompressibleSymbolPackingBits(),
1354 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize() *
sizeof(W)};
1357template <
typename H,
int N,
typename W>
1358template <
typename input_IT,
typename buffer_T>
1361 using storageBuffer_t = W;
1362 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1364 using ransState_t =
typename ransEncoder_t::coder_type::state_type;
1365 using ransStream_t =
typename ransEncoder_t::stream_type;
1368 static_assert(std::is_same_v<storageBuffer_t, ransStream_t>);
1369 static_assert(std::is_same_v<storageBuffer_t, typename rans::count_t>);
1371 auto* thisBlock = &mBlocks[slot];
1372 auto* thisMetadata = &mMetadata[slot];
1376 const size_t nSamples = std::distance(begin,
end);
1381 if (proxy.isCached()) {
1387 LOGP(warning,
"Failed to build Dictionary for rANS encoding, using fallback option");
1388 if (proxy.isCached()) {
1389 return store(proxy.beginCache(), proxy.endCache(), slot, this->FallbackStorageType,
buffer);
1391 return store(proxy.beginIter(), proxy.endIter(), slot, this->FallbackStorageType,
buffer);
1403 if (proxy.isCached()) {
1410 encoder.makeEncoder();
1416 sizeEstimateSafetyFactor);
1417 std::tie(thisBlock, thisMetadata) = expandStorage(slot, bufferSizeWords,
buffer);
1420 auto encodedDictEnd = encoder.writeDictionary(thisBlock->getCreateDict(), thisBlock->getEndOfBlock());
1421 const size_t dictSize = std::distance(thisBlock->getCreateDict(), encodedDictEnd);
1422 thisBlock->setNDict(dictSize);
1423 thisBlock->realignBlock();
1424 LOGP(
debug,
"StoreDict {} bytes, offs: {}:{}", dictSize *
sizeof(storageBuffer_t), thisBlock->getOffsDict(), thisBlock->getOffsDict() + dictSize *
sizeof(storageBuffer_t));
1427 auto encodedMessageEnd = thisBlock->getCreateData();
1428 if (proxy.isCached()) {
1429 encodedMessageEnd = encoder.encode(proxy.beginCache(), proxy.endCache(), thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1431 encodedMessageEnd = encoder.encode(proxy.beginIter(), proxy.endIter(), thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1433 const size_t dataSize = std::distance(thisBlock->getCreateData(), encodedMessageEnd);
1435 thisBlock->realignBlock();
1436 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}",
dataSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() +
dataSize *
sizeof(storageBuffer_t));
1440 size_t literalsSize{};
1441 if (encoder.getNIncompressibleSamples() > 0) {
1442 auto literalsEnd = encoder.writeIncompressible(thisBlock->getCreateLiterals(), thisBlock->getEndOfBlock());
1443 literalsSize = std::distance(thisBlock->getCreateLiterals(), literalsEnd);
1444 thisBlock->setNLiterals(literalsSize);
1445 thisBlock->realignBlock();
1446 LOGP(
debug,
"StoreLiterals {} bytes, offs: {}:{}", literalsSize *
sizeof(storageBuffer_t), thisBlock->getOffsLiterals(), thisBlock->getOffsLiterals() + literalsSize *
sizeof(storageBuffer_t));
1450 *thisMetadata = detail::makeMetadataRansV1<input_t, ransState_t, ransStream_t>(encoder.getNStreams(),
1451 rans::utils::getStreamingLowerBound_v<typename ransEncoder_t::coder_type>,
1452 std::distance(srcBegin, srcEnd),
1453 encoder.getNIncompressibleSamples(),
1454 encoder.getSymbolTablePrecision(),
1455 *
metrics.getCoderProperties().min,
1456 *
metrics.getCoderProperties().max,
1457 metrics.getDatasetProperties().min,
1458 metrics.getDatasetProperties().alphabetRangeBits,
1463 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize() *
sizeof(W)};
1466template <
typename H,
int N,
typename W>
1467template <
typename input_IT,
typename buffer_T>
1470 using storageBuffer_t = W;
1471 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1473 const size_t messageLength =
metrics.getDatasetProperties().numSamples;
1474 const auto alphabetRangeBits =
metrics.getDatasetProperties().alphabetRangeBits;
1476 auto* thisBlock = &mBlocks[slot];
1477 auto* thisMetadata = &mMetadata[slot];
1478 size_t packedSize = 0;
1480 if (messageLength == 0) {
1481 *thisMetadata = detail::makeMetadataPack<input_t>(0, 0, 0, 0);
1482 }
else if (
metrics.getDatasetProperties().alphabetRangeBits == 0) {
1483 *thisMetadata = detail::makeMetadataPack<input_t>(messageLength, 0, *srcBegin, 0);
1486 size_t packingBufferWords = packer.template getPackingBufferSize<storageBuffer_t>(messageLength);
1487 std::tie(thisBlock, thisMetadata) = expandStorage(slot, packingBufferWords,
buffer);
1488 auto packedMessageEnd = packer.pack(srcBegin, srcEnd, thisBlock->getCreateData(), thisBlock->getEndOfBlock());
1489 packedSize = std::distance(thisBlock->getCreateData(), packedMessageEnd);
1490 *thisMetadata = detail::makeMetadataPack<input_t>(messageLength, packer.getPackingWidth(), packer.getOffset(), packedSize);
1491 thisBlock->setNData(packedSize);
1492 thisBlock->realignBlock();
1495 LOGP(
debug,
"StoreData {} bytes, offs: {}:{}", packedSize *
sizeof(storageBuffer_t), thisBlock->getOffsData(), thisBlock->getOffsData() + packedSize *
sizeof(storageBuffer_t));
1496 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize() *
sizeof(W)};
1499template <
typename H,
int N,
typename W>
1500template <
typename input_IT,
typename buffer_T>
1503 using storageBuffer_t = W;
1504 using input_t =
typename std::iterator_traits<input_IT>::value_type;
1506 const size_t messageLength = std::distance(srcBegin, srcEnd);
1508 const size_t nSourceElemsPadded = calculatePaddedSize<input_t, storageBuffer_t>(messageLength);
1509 std::vector<input_t> tmp(nSourceElemsPadded, {});
1510 std::copy(srcBegin, srcEnd, std::begin(tmp));
1512 const size_t nBufferElems = calculateNDestTElements<input_t, storageBuffer_t>(messageLength);
1513 auto [thisBlock, thisMetadata] = expandStorage(slot, nBufferElems,
buffer);
1514 thisBlock->storeData(nBufferElems,
reinterpret_cast<const storageBuffer_t*
>(tmp.data()));
1516 *thisMetadata = detail::makeMetadataStore<input_t, storageBuffer_t>(messageLength, opt, nBufferElems);
1518 return {0, thisMetadata->getUncompressedSize(), thisMetadata->getCompressedSize() *
sizeof(W)};
1522template <
typename H,
int N,
typename W>
1526 if (vfreq.size() != N) {
1527 throw std::runtime_error(fmt::format(
"mismatch between the size of frequencies vector {} and number of blocks {}", vfreq.size(), N));
1530 for (
int ib = 0; ib < N; ib++) {
1533 std::vector<char> vdict(sz);
1534 auto dictBlocks = create(vdict.data(), sz);
1535 for (
int ib = 0; ib < N; ib++) {
1536 const auto& thisHistogram = vfreq[ib];
1539 if (!view.empty()) {
1540 LOG(info) <<
"adding dictionary of " << view.size() <<
" words for block " << ib <<
", min/max= " << view.getMin() <<
"/" << view.getMax();
1541 dictBlocks->mBlocks[ib].storeDict(view.size(), view.data());
1542 dictBlocks = get(vdict.data());
1543 dictBlocks->mMetadata[ib] = vmd[ib];
1545 dictBlocks->mBlocks[ib].realignBlock();
1549 dictBlocks->mRegistry.nFilledBlocks++;
1555template <
typename H,
int N,
typename W>
1558 for (
int ibl = 0; ibl < getNBlocks(); ibl++) {
1559 const auto& blc = getBlock(ibl);
1561 LOGP(info,
"{} Bloc:{} Dict: {} words", prefix, ibl, blc.getNDict());
1562 const auto*
ptr = blc.getDict();
1563 for (
int i = 0;
i < blc.getNDict();
i++) {
1564 if (
i && (
i % ncol) == 0) {
1568 ss += fmt::format(
" {:#010x}",
ptr[
i]);
1575 LOGP(info,
"{} Bloc:{} Data: {} words", prefix, ibl, blc.getNData());
1576 ptr = blc.getData();
1577 for (
int i = 0;
i < blc.getNData();
i++) {
1578 if (
i && (
i % ncol) == 0) {
1582 ss += fmt::format(
" {:#010x}",
ptr[
i]);
1589 LOGP(info,
"{} Bloc:{} Literals: {} words", prefix, ibl, blc.getNLiterals());
1590 ptr = blc.getData();
1591 for (
int i = 0;
i < blc.getNLiterals();
i++) {
1592 if (
i && (
i % 20) == 0) {
1596 ss += fmt::format(
" {:#010x}",
ptr[
i]);
Interfaces for BitPacking using librans.
useful public helper functions.
Class for time synchronization of RawReader instances.
<<======================== Auxiliary classes =======================<<
CTFIOSize decodeCopyImpl(dst_IT dest, int slot) const
static constexpr Metadata::OptStore FallbackStorageType
this is in fact stored, but to overcome TBuffer limits we have to define the branches per block!...
void readFromTree(TTree &tree, const std::string &name, int ev=0)
read from tree to non-flat object
o2::ctf::CTFIOSize entropyCodeRANSV1(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
static auto get(void *head)
cast arbitrary buffer head to container class. Head is supposed to respect the alignment
ClassDefNV(EncodedBlocks, 3)
static size_t estimateBlockSize(int n)
estimate free size needed to add new block
CTFIOSize decodeCompatImpl(dst_IT dest, int slot, const std::any &decoderExt) const
o2::ctf::CTFIOSize decode(container_T &dest, int slot, const std::any &decoderExt={}) const
decode block at provided slot to destination vector (will be resized as needed)
static auto get(const void *head)
size_t estimateSize() const
size_t estimateSizeFromMetadata() const
do the same using metadata info
static void relocate(const char *oldHead, char *newHead, char *wrapper, size_t newsize=0)
auto expandStorage(size_t slot, size_t nElemets, T *buffer=nullptr) -> decltype(auto)
void setHeader(const H &h)
o2::ctf::CTFIOSize encodeRANSV1External(const input_IT srcBegin, const input_IT srcEnd, int slot, const std::any &encoderExt, buffer_T *buffer=nullptr, double_t sizeEstimateSafetyFactor=1)
static void readFromTree(VD &vec, TTree &tree, const std::string &name, int ev=0)
read from tree to destination buffer vector
void dump(const std::string &prefix="", int ncol=20) const
CTFIOSize decodeRansV1Impl(dst_IT dest, int slot, const std::any &decoderExt) const
ANSHeader checkANSVersion(ANSHeader ansVersion) const
void fillFlatCopy(EncodedBlocks &dest) const
Create its own flat copy in the destination empty flat object.
void copyToFlat(void *base)
copy itself to flat buffer created on the fly at the provided pointer. The destination block should b...
std::array< Block< W >, N > mBlocks
const H & getHeader() const
static size_t fillTreeBranch(TTree &tree, const std::string &brname, D &dt, int compLevel, int splitLevel=99)
add and fill single branch
auto & getMetadata(int i) const
static size_t getMinAlignedSize()
o2::ctf::CTFIOSize pack(const input_IT srcBegin, const input_IT srcEnd, int slot, buffer_T *buffer=nullptr)
static auto expand(buffer_T &buffer, size_t newsizeBytes)
expand the storage to new size in bytes
void print(const std::string &prefix="", int verbosity=1) const
print itself
o2::ctf::CTFIOSize encodeRANSV1Inplace(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr, double_t sizeEstimateSafetyFactor=1)
dictionaryType< source_T > getDictionary(int i, ANSHeader ansVersion=ANSVersionUnspecified) const
bool flat() const
check if flat and valid
static std::vector< char > createDictionaryBlocks(const std::vector< rans::DenseHistogram< int32_t > > &vfreq, const std::vector< Metadata > &prbits)
create a special EncodedBlocks containing only dictionaries made from provided vector of frequency ta...
const auto & getMetadata() const
static constexpr int getNBlocks()
const ANSHeader & getANSHeader() const
auto & getBlock(int i) const
bool empty() const
check if empty and valid
static auto getImage(const void *newHead)
get const image of the container wrapper, with pointers in the image relocated to new head
static bool readTreeBranch(TTree &tree, const std::string &brname, D &dt, int ev=0)
read single branch
size_t compactify()
Compactify by eliminating empty space.
CTFIOSize decodeUnpackImpl(dst_IT dest, int slot) const
std::variant< rans::RenormedSparseHistogram< source_T >, rans::RenormedDenseHistogram< source_T > > dictionaryType
o2::ctf::CTFIOSize decode(D_IT dest, int slot, const std::any &decoderExt={}) const
decode block at provided slot to destination pointer, the needed space assumed to be available
size_t size() const
total allocated size in bytes
EncodedBlocks< H, N, W > base
static auto create(VD &v)
create container from vector. Head is supposed to respect the alignment
void setANSHeader(const ANSHeader &h)
o2::ctf::CTFIOSize store(const input_IT srcBegin, const input_IT srcEnd, int slot, Metadata::OptStore opt, buffer_T *buffer=nullptr)
o2::ctf::CTFIOSize encode(const input_IT srcBegin, const input_IT srcEnd, int slot, uint8_t symbolTablePrecision, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
encode vector src to bloc at provided slot
size_t getFreeSize() const
size remaining for additional data
o2::ctf::CTFIOSize encode(const VE &src, int slot, uint8_t symbolTablePrecision, Metadata::OptStore opt, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
encode vector src to bloc at provided slot
const auto & getRegistry() const
static auto create(void *head, size_t sz)
create container from arbitrary buffer of predefined size (in bytes!!!). Head is supposed to respect ...
std::shared_ptr< H > cloneHeader() const
ANSHeader & getANSHeader()
void init(size_t sz)
setup internal structure and registry for given buffer size (in bytes!!!)
void copyToFlat(V &vec)
copy itself to flat buffer created on the fly from the vector
size_t appendToTree(TTree &tree, const std::string &name) const
attach to tree
o2::ctf::CTFIOSize entropyCodeRANSCompat(const input_IT srcBegin, const input_IT srcEnd, int slot, uint8_t symbolTablePrecision, buffer_T *buffer=nullptr, const std::any &encoderExt={}, float memfc=1.f)
std::array< Metadata, N > mMetadata
o2::ctf::CTFIOSize pack(const input_IT srcBegin, const input_IT srcEnd, int slot, rans::Metrics< typename std::iterator_traits< input_IT >::value_type > metrics, buffer_T *buffer=nullptr)
typename rans::denseEncoder_type< source_type > encoder_type
const DatasetProperties< source_type > & getDatasetProperties() const noexcept
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 decltype(auto) fromHistogram(DenseHistogram< source_T > histogram, size_t renormingPrecision=0)
functionality to maintain compatibility with previous version of this library
static factory classes for building histograms, encoders and decoders.
GLuint const GLchar * name
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
public interface for building and renorming histograms from source data.
constexpr bool mayPack(Metadata::OptStore opt) noexcept
constexpr bool is_iterator_v
constexpr bool mayEEncode(Metadata::OptStore opt) noexcept
constexpr size_t calculateNDestTElements(size_t nElems) noexcept
constexpr size_t PackingThreshold
constexpr int WrappersCompressionLevel
uint8_t BufferType
This is the type of the vector to be used for the EncodedBlocks buffer allocation.
constexpr ANSHeader ANSVersionCompat
constexpr ANSHeader ANSVersion1
constexpr ANSHeader ANSVersionUnspecified
size_t calculatePaddedSize(size_t nElems) noexcept
constexpr size_t Alignment
constexpr int WrappersSplitLevel
size_t alignSize(size_t sizeBytes)
align size to given diven number of bytes
T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
relocate pointer by the difference of addresses
decltype(makeEncoder::fromRenormed(RenormedDenseHistogram< source_T >{})) encoder_type
RenormedDenseHistogram< source_T > renorm(DenseHistogram< source_T > histogram, size_t newPrecision=0)
size_t getAlphabetRangeBits(const DenseHistogram< source_T > &histogram) noexcept
size_t calculateMaxBufferSizeB(size_t nElements, size_t rangeBits)
decltype(makeDecoder::fromRenormed(RenormedDenseHistogram< source_T >{})) decoder_type
constexpr uint32_t getRangeBits(T min, T max) noexcept
constexpr size_t pow2(size_t n) noexcept
void checkBounds(IT iteratorPosition, IT upperBound)
size_t sanitizeRenormingBitRange(size_t renormPrecision)
decltype(makeDenseEncoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) denseEncoder_type
decltype(makeDecoder<>::fromRenormed(RenormedDenseHistogram< source_T >{})) defaultDecoder_type
auto makeHistogramView(container_T &container, std::ptrdiff_t offset) noexcept -> HistogramView< decltype(std::begin(container))>
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))
HistogramView< Hist_IT > trim(const HistogramView< Hist_IT > &buffer)
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)
RenormedSparseHistogram< source_T > readRenormedSetDictionary(buffer_IT begin, buffer_IT end, source_T min, source_T max, size_t renormingPrecision)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
std::string to_string(gsl::span< T, Size > span)
public interface for serializing histograms (dictionaries) to JSON or compressed binary.
binary blob for single entropy-compressed column: metadata + (optional) dictionary and data buffer + ...
const W * getData() const
const W * getDict() const
const W * getDataPointer() const
void storeDict(int _ndict, const W *_dict)
void storeLiterals(int _nliterals, const W *_literals)
const W * getLiterals() const
int nDict
non-persistent info for in-memory ops
const W * getEndOfBlock() const
void storeData(int _ndata, const W *_data)
void setNData(int _ndata)
void store(int _ndict, int _ndata, int _nliterals, const W *_dict, const W *_data, const W *_literals)
store binary blob data (buffer filled from head to tail)
void setNDict(int _ndict)
void setNLiterals(int _nliterals)
static size_t estimateSize(int n)
estimate free size needed to add new block
void relocate(const char *oldHead, char *newHeadData, char *newHeadRegistry)
relocate to different head position
>======================== Auxiliary classes =======================>>
int nFilledBlocks
pointer on the head of the CTF
char * getFreeBlockEnd() const
size_t getFreeSize() const
size in bytes available to fill data
size_t size
offset of the start of the writable space (wrt head), in bytes!!!
char * getFreeBlockStart() const
calculate the pointer of the head of the writable space
static constexpr size_t nStreams
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)
static std::string concat_string(Ts const &... ts)
int estimateSize(bool withHB=false)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
coder decode(ctfImage, triggersD, clustersD)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))