File indexing completed on 2024-10-29 06:08:31
0001 #include <cassert>
0002
0003 #include "L1Trigger/L1THGCal/interface/HGCalVFECompressionImpl.h"
0004
0005 #include "FWCore/Utilities/interface/Exception.h"
0006
0007 HGCalVFECompressionImpl::HGCalVFECompressionImpl(const edm::ParameterSet& conf)
0008 : exponentBits_(conf.getParameter<uint32_t>("exponentBits")),
0009 mantissaBits_(conf.getParameter<uint32_t>("mantissaBits")),
0010 truncationBits_(conf.getParameter<uint32_t>("truncationBits")),
0011 rounding_(conf.getParameter<bool>("rounding")) {
0012 if (((1 << exponentBits_) + mantissaBits_ - 1) >= 64) {
0013 throw cms::Exception("CodespaceCannotFit") << "The code space cannot fit into the unsigned 64-bit space.\n";
0014 }
0015 saturationCode_ = (1 << (exponentBits_ + mantissaBits_)) - 1;
0016 saturationValue_ = (exponentBits_ == 0)
0017 ? saturationCode_
0018 : ((1ULL << (mantissaBits_ + truncationBits_ + 1)) - 1) << ((1 << exponentBits_) - 2);
0019 }
0020
0021 void HGCalVFECompressionImpl::compressSingle(const uint64_t value,
0022 uint32_t& compressedCode,
0023 uint64_t& compressedValue) const {
0024
0025 if (value > saturationValue_) {
0026 compressedCode = saturationCode_;
0027 compressedValue = saturationValue_;
0028 return;
0029 }
0030
0031
0032 uint32_t bitlen;
0033 uint64_t shifted_value = value >> truncationBits_;
0034 uint64_t valcopy = shifted_value;
0035 for (bitlen = 0; valcopy != 0; valcopy >>= 1, bitlen++) {
0036 }
0037 if (bitlen <= mantissaBits_) {
0038 compressedCode = shifted_value;
0039 compressedValue = shifted_value << truncationBits_;
0040 return;
0041 }
0042
0043
0044 const uint32_t exponent = bitlen - mantissaBits_;
0045 assert(exponent - 1 < 64);
0046 const uint64_t mantissa = (shifted_value >> (exponent - 1)) & ~(1ULL << mantissaBits_);
0047
0048
0049 const uint32_t floatval = (exponent << mantissaBits_) | mantissa;
0050
0051
0052
0053
0054 if (!rounding_ || floatval == saturationCode_ || exponent <= 1) {
0055 compressedCode = floatval;
0056 compressedValue = ((1ULL << mantissaBits_) | mantissa) << (exponent - 1);
0057 } else {
0058 const bool roundup = ((shifted_value >> (exponent - 2)) & 1ULL) == 1ULL;
0059 if (!roundup) {
0060 compressedCode = floatval;
0061 compressedValue = ((1ULL << mantissaBits_) | mantissa) << (exponent - 1);
0062 } else {
0063 compressedCode = floatval + 1;
0064 uint64_t rmantissa = mantissa + 1;
0065 uint32_t rexponent = exponent;
0066 if (rmantissa >= (1ULL << mantissaBits_)) {
0067 rexponent++;
0068 rmantissa &= ~(1ULL << mantissaBits_);
0069 }
0070 compressedValue = ((1ULL << mantissaBits_) | rmantissa) << (rexponent - 1);
0071 }
0072 }
0073 compressedValue <<= truncationBits_;
0074 }
0075
0076 void HGCalVFECompressionImpl::compress(const std::unordered_map<uint32_t, uint32_t>& payload,
0077 std::unordered_map<uint32_t, std::array<uint64_t, 2> >& compressed_payload) {
0078 for (const auto& item : payload) {
0079 const uint64_t value = static_cast<uint64_t>(item.second);
0080 uint32_t code(0);
0081 uint64_t compressed_value(0);
0082 compressSingle(value, code, compressed_value);
0083 std::array<uint64_t, 2> compressed_item = {{static_cast<uint64_t>(code), compressed_value}};
0084 compressed_payload.emplace(item.first, compressed_item);
0085 }
0086 }