ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
CxxUtils
Root
FloatCompressor.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
// $Id: FloatCompressor.cxx 789425 2016-12-13 10:50:12Z krasznaa $
6
7
8
9
// Local include(s):
10
#include "
CxxUtils/FloatCompressor.h
"
11
// System include(s):
12
#include <cmath>
13
#include <bit>
14
15
namespace
CxxUtils
{
16
18
constexpr
unsigned
int
NMANTISSA
= 23;
19
20
FloatCompressor::FloatCompressor
(
unsigned
int
mantissaBits )
21
:
m_mantissaBits
( mantissaBits ),
m_mantissaBitmask
( 0 ) {
22
23
// IEEE754 single-precision float
24
// SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
25
// F F 8 0 0 0 7 F
26
27
// Definition:
28
//
29
// Assume that we'd like to keep only 7 bits in the mantissa
30
// In this case the memory layout of the bits will be:
31
//
32
// Sign | Exp (8 bits) | Frac (23 bits)
33
// S EEEEEEEE FFFFFFLRTTTTTTTTTTTTTTT
34
//
35
// where
36
//
37
// S : Sign bit
38
// E : Exponent bits
39
// F : Fraction bits
40
// L : Least significant bit (lsb) for 7 bits mantissa precision
41
// R : Rounding bit
42
// T : Sticky bits (i.e any bit after lsb + 1)
43
//
44
// In the current implementation there are essentially 4 cases:
45
//
46
// Case 1: L = 0 and R = 0
47
// In this case there'll be rounding down
48
//
49
// Case 2: L = 1 and R = 0
50
// In this case there'll be rounding down
51
//
52
// Case 3: L = 0 and R = 1
53
// In this case there'll be rounding up
54
//
55
// Note: This scenario can be different than bfloat16 implementation
56
// of TensorFlow, where they round down if all the Ts are zero.
57
// Otherwise, they also round up.
58
//
59
// Case 4: L = 1 and R = 1
60
// In this case there'll be rounding up
61
//
62
// In all cases, we do an extra check to avoid overflow.
63
//
64
// From a technical point of view, the rounding is computed
65
// to be the half of the lsb(=1) and added to the original value
66
// as long as the new value doesn't overflow. Then the
67
// undesired bits are masked. We never go below 5 bits in the
68
// mantissa.
69
70
// Adjust the received bit number to some reasonable value:
71
if
(
m_mantissaBits
< 5 ) {
72
m_mantissaBits
= 5;
73
}
74
if
(
m_mantissaBits
>
NMANTISSA
) {
75
m_mantissaBits
=
NMANTISSA
;
76
}
77
78
// Fill up the lower N bits:
79
for
(
unsigned
int
i = 0; i < (
NMANTISSA
-
m_mantissaBits
); ++i ) {
80
m_mantissaBitmask
|= ( 0x1 << i );
81
}
82
// And now negate it to get the correct mask:
83
m_mantissaBitmask
=
~m_mantissaBitmask
;
84
85
// Set the Magic numbers
86
if
(
m_mantissaBits
==
NMANTISSA
) {
87
m_rounding
= 0;
88
}
89
else
{
90
m_rounding
= 0x1 << ( 32 - (1 + 8 +
m_mantissaBits
) - 1 );
91
}
92
// The part below is taken from AthenaPoolCnvSvc/Compressor
93
// and would work the same as long as the user doesn't
94
// compress lower than 3 mantissa bits, which is not allowed
95
// in any case.
96
m_vmax
= 0x7f7 << 20;
97
m_vmax
|= 0x000fffff xor (
m_rounding
);
98
}
99
100
float
FloatCompressor::reduceFloatPrecision
(
float
value )
const
{
101
102
// Check if any compression is to be made:
103
if
(
m_mantissaBits
==
NMANTISSA
) {
104
return
value;
105
}
106
107
// Check for NaN, etc:
108
if
( ! std::isfinite( value ) ) {
109
return
value;
110
}
111
112
auto
ivalue = std::bit_cast<std::uint32_t>( value );
113
114
//safety-check if value (omitting the sign-bit) is lower than vmax
115
//(avoid overflow)
116
if
( ( ivalue & std::uint32_t{0x7fffffff} ) <
m_vmax
) {
117
ivalue +=
m_rounding
;
118
}
119
120
// Do the compression:
121
ivalue &=
m_mantissaBitmask
;
122
return
std::bit_cast<float>( ivalue );
123
}
124
125
}
// namespace CxxUtils
FloatCompressor.h
CxxUtils::FloatCompressor::m_mantissaBits
unsigned int m_mantissaBits
Number of mantissa bits to keep.
Definition
FloatCompressor.h:43
CxxUtils::FloatCompressor::m_vmax
uint32_t m_vmax
Largest possible positive 32bit float minus the rounding.
Definition
FloatCompressor.h:53
CxxUtils::FloatCompressor::m_rounding
uint32_t m_rounding
Definition
FloatCompressor.h:51
CxxUtils::FloatCompressor::m_mantissaBitmask
uint32_t m_mantissaBitmask
Bitmask for zeroing out the non-interesting bits.
Definition
FloatCompressor.h:45
CxxUtils::FloatCompressor::reduceFloatPrecision
float reduceFloatPrecision(float value) const
Function returning a reduced precision float value.
Definition
FloatCompressor.cxx:100
CxxUtils::FloatCompressor::FloatCompressor
FloatCompressor(unsigned int mantissaBits=7)
Constructor with the number of mantissa bits to retain.
Definition
FloatCompressor.cxx:20
CxxUtils
Definition
aligned_vector.h:29
CxxUtils::NMANTISSA
constexpr unsigned int NMANTISSA
Total number of total mantissa bits.
Definition
FloatCompressor.cxx:18
Generated on
for ATLAS Offline Software by
1.17.0