Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:12:24

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