Showing 1 of 1 files from the diff.

@@ -23,107 +23,131 @@
Loading
23 23
24 24
namespace rawspeed {
25 25
26 -
// Expand IEEE-754-2008 binary16 into float32
27 -
inline uint32_t fp16ToFloat(uint16_t fp16) {
28 -
  // IEEE-754-2008: binary16:
29 -
  // bit 15 - sign
30 -
  // bits 14-10 - exponent (5 bit)
31 -
  // bits 9-0 - fraction (10 bit)
32 -
  //
33 -
  // exp = 0, fract = +-0: zero
34 -
  // exp = 0; fract != 0: subnormal numbers
35 -
  //                      equation: -1 ^ sign * 2 ^ -14 * 0.fraction
36 -
  // exp = 1..30: normalized value
37 -
  //              equation: -1 ^ sign * 2 ^ (exponent - 15) * 1.fraction
38 -
  // exp = 31, fract = +-0: +-infinity
39 -
  // exp = 31, fract != 0: NaN
40 -
41 -
  uint32_t sign = (fp16 >> 15) & 1;
42 -
  uint32_t fp16_exponent = (fp16 >> 10) & ((1 << 5) - 1);
43 -
  uint32_t fp16_fraction = fp16 & ((1 << 10) - 1);
26 +
namespace ieee_754_2008 {
44 27
45 -
  // Normalized or zero
46 -
  // binary32 equation: -1 ^ sign * 2 ^ (exponent - 127) * 1.fraction
47 -
  // => exponent32 - 127 = exponent16 - 15, exponent32 = exponent16 + 127 - 15
48 -
  uint32_t fp32_exponent = fp16_exponent + 127 - 15;
49 -
  uint32_t fp32_fraction = fp16_fraction
50 -
                           << (23 - 10); // 23 is binary32 fraction size
28 +
// Refer to "3.6 Interchange format parameters",
29 +
//          "Table 3.5—Binary interchange format parameters"
51 30
52 -
  if (fp16_exponent == 31) {
53 -
    // Infinity or NaN
54 -
    fp32_exponent = 255;
55 -
  } else if (fp16_exponent == 0) {
56 -
    if (fp16_fraction == 0) {
57 -
      // +-Zero
58 -
      fp32_exponent = 0;
59 -
      fp32_fraction = 0;
60 -
    } else {
61 -
      // Subnormal numbers
62 -
      // binary32 equation: -1 ^ sign * 2 ^ (exponent - 127) * 1.fraction
63 -
      // binary16 equation: -1 ^ sign * 2 ^ -14 * 0.fraction, we can represent
64 -
      // it as a normalized value in binary32, we have to shift fraction until
65 -
      // we get 1.new_fraction and decrement exponent for each shift
66 -
      fp32_exponent = -14 + 127;
67 -
      while (!(fp32_fraction & (1 << 23))) {
68 -
        fp32_exponent -= 1;
69 -
        fp32_fraction <<= 1;
70 -
      }
71 -
      fp32_fraction &= ((1 << 23) - 1);
72 -
    }
73 -
  }
74 -
  return (sign << 31) | (fp32_exponent << 23) | fp32_fraction;
75 -
}
31 +
// All formats are:
32 +
// MSB [Sign bit] [Exponent bits] [Fraction bits] LSB
76 33
77 -
// Expand binary24 (not part of IEEE-754-2008) into float32
78 -
inline uint32_t fp24ToFloat(uint32_t fp24) {
79 -
  // binary24: Not a part of IEEE754-2008, but format is obvious,
80 -
  // see https://en.wikipedia.org/wiki/Minifloat
81 -
  // bit 23 - sign
82 -
  // bits 22-16 - exponent (7 bit)
83 -
  // bits 15-0 - fraction (16 bit)
84 -
  //
85 -
  // exp = 0, fract = +-0: zero
86 -
  // exp = 0; fract != 0: subnormal numbers
87 -
  //                      equation: -1 ^ sign * 2 ^ -62 * 0.fraction
88 -
  // exp = 1..126: normalized value
89 -
  //              equation: -1 ^ sign * 2 ^ (exponent - 63) * 1.fraction
90 -
  // exp = 127, fract = +-0: +-infinity
91 -
  // exp = 127, fract != 0: NaN
92 -
93 -
  uint32_t sign = (fp24 >> 23) & 1;
94 -
  uint32_t fp24_exponent = (fp24 >> 16) & ((1 << 7) - 1);
95 -
  uint32_t fp24_fraction = fp24 & ((1 << 16) - 1);
34 +
template <int StorageWidth_, int FractionWidth_, int ExponentWidth_>
35 +
struct BinaryN {
36 +
  static constexpr uint32_t StorageWidth = StorageWidth_;
37 +
38 +
  // FIXME: if we had compile-time log2/round, we'd only need StorageWidth.
39 +
40 +
  static constexpr uint32_t FractionWidth = FractionWidth_;
41 +
  static constexpr uint32_t ExponentWidth = ExponentWidth_;
42 +
  // SignWidth is always 1.
43 +
  static_assert(FractionWidth + ExponentWidth + 1 == StorageWidth, "");
44 +
45 +
  static constexpr uint32_t Precision = FractionWidth + 1;
46 +
47 +
  static constexpr uint32_t ExponentMax = (1 << (ExponentWidth - 1)) - 1;
48 +
49 +
  static constexpr uint32_t Bias = ExponentMax;
50 +
51 +
  // FractionPos is always 0.
52 +
  static constexpr uint32_t ExponentPos = FractionWidth;
53 +
  static constexpr uint32_t SignBitPos = StorageWidth - 1;
54 +
};
55 +
56 +
// IEEE-754-2008: binary16:
57 +
// bits 9-0 - fraction (10 bit)
58 +
// bits 14-10 - exponent (5 bit)
59 +
// bit 15 - sign
60 +
struct Binary16 : public BinaryN</*StorageWidth=*/16, /*FractionWidth=*/10,
61 +
                                 /*ExponentWidth=*/5> {
62 +
  static_assert(Precision == 11, "");
63 +
  static_assert(ExponentMax == 15, "");
64 +
  static_assert(ExponentPos == 10, "");
65 +
  static_assert(SignBitPos == 15, "");
66 +
};
67 +
68 +
// IEEE-754-2008: binary24:
69 +
// bits 15-0 - fraction (16 bit)
70 +
// bits 22-16 - exponent (7 bit)
71 +
// bit 23 - sign
72 +
struct Binary24 : public BinaryN</*StorageWidth=*/24, /*FractionWidth=*/16,
73 +
                                 /*ExponentWidth=*/7> {
74 +
  static_assert(Precision == 17, "");
75 +
  static_assert(ExponentMax == 63, "");
76 +
  static_assert(ExponentPos == 16, "");
77 +
  static_assert(SignBitPos == 23, "");
78 +
};
79 +
80 +
// IEEE-754-2008: binary32:
81 +
// bits 22-0 - fraction (23 bit)
82 +
// bits 30-23 - exponent (8 bit)
83 +
// bit 31 - sign
84 +
struct Binary32 : public BinaryN</*StorageWidth=*/32, /*FractionWidth=*/23,
85 +
                                 /*ExponentWidth=*/8> {
86 +
  static_assert(Precision == 24, "");
87 +
  static_assert(ExponentMax == 127, "");
88 +
  static_assert(ExponentPos == 23, "");
89 +
  static_assert(SignBitPos == 31, "");
90 +
};
91 +
92 +
// exp = 0, fract  = +-0: zero
93 +
// exp = 0; fract !=   0: subnormal numbers
94 +
//                        equation: -1 ^ sign * 2 ^ (1 - Bias) * 0.fraction
95 +
// exp = 1..(2^ExponentWidth - 2): normalized value
96 +
//                     equation: -1 ^ sign * 2 ^ (exponent - Bias) * 1.fraction
97 +
// exp = 2^ExponentWidth - 1, fract  = +-0: +-infinity
98 +
// exp = 2^ExponentWidth - 1, fract !=   0: NaN
99 +
100 +
} // namespace ieee_754_2008
101 +
102 +
template <typename NarrowType, typename WideType>
103 +
inline uint32_t extendBinaryFloatingPoint(uint32_t narrow) {
104 +
  uint32_t sign = (narrow >> NarrowType::SignBitPos) & 1;
105 +
  uint32_t narrow_exponent = (narrow >> NarrowType::ExponentPos) &
106 +
                             ((1 << NarrowType::ExponentWidth) - 1);
107 +
  uint32_t narrow_fraction = narrow & ((1 << NarrowType::FractionWidth) - 1);
96 108
97 109
  // Normalized or zero
98 -
  // binary32 equation: -1 ^ sign * 2 ^ (exponent - 127) * 1.fraction
99 -
  // => exponent32 - 127 = exponent24 - 64, exponent32 = exponent16 + 127 - 63
100 -
  uint32_t fp32_exponent = fp24_exponent + 127 - 63;
101 -
  uint32_t fp32_fraction = fp24_fraction
102 -
                           << (23 - 16); // 23 is binary 32 fraction size
110 +
  uint32_t wide_exponent = narrow_exponent - NarrowType::Bias + WideType::Bias;
111 +
  uint32_t wide_fraction =
112 +
      narrow_fraction << (WideType::FractionWidth - NarrowType::FractionWidth);
103 113
104 -
  if (fp24_exponent == 127) {
114 +
  if (narrow_exponent == ((1 << NarrowType::ExponentWidth) - 1)) {
105 115
    // Infinity or NaN
106 -
    fp32_exponent = 255;
107 -
  } else if (fp24_exponent == 0) {
108 -
    if (fp24_fraction == 0) {
116 +
    wide_exponent = ((1 << WideType::ExponentWidth) - 1);
117 +
    // Narrow fraction is kept/widened!
118 +
  } else if (narrow_exponent == 0) {
119 +
    if (narrow_fraction == 0) {
109 120
      // +-Zero
110 -
      fp32_exponent = 0;
111 -
      fp32_fraction = 0;
121 +
      wide_exponent = 0;
122 +
      wide_fraction = 0;
112 123
    } else {
113 124
      // Subnormal numbers
114 -
      // binary32 equation: -1 ^ sign * 2 ^ (exponent - 127) * 1.fraction
115 -
      // binary24 equation: -1 ^ sign * 2 ^ -62 * 0.fraction, we can represent
116 -
      // it as a normalized value in binary32, we have to shift fraction until
117 -
      // we get 1.new_fraction and decrement exponent for each shift
118 -
      fp32_exponent = -62 + 127;
119 -
      while (!(fp32_fraction & (1 << 23))) {
120 -
        fp32_exponent -= 1;
121 -
        fp32_fraction <<= 1;
125 +
      // We can represent it as a normalized value in wider type,
126 +
      // we have to shift fraction until we get 1.new_fraction
127 +
      // and decrement exponent for each shift.
128 +
      // FIXME; what is the implicit precondition here?
129 +
      wide_exponent = 1 - NarrowType::Bias + WideType::Bias;
130 +
      while (!(wide_fraction & (1 << (WideType::FractionWidth)))) {
131 +
        wide_exponent -= 1;
132 +
        wide_fraction <<= 1;
122 133
      }
123 -
      fp32_fraction &= ((1 << 23) - 1);
134 +
      wide_fraction &= ((1 << WideType::FractionWidth) - 1);
124 135
    }
125 136
  }
126 -
  return (sign << 31) | (fp32_exponent << 23) | fp32_fraction;
137 +
  return (sign << WideType::SignBitPos) |
138 +
         (wide_exponent << WideType::ExponentPos) | wide_fraction;
139 +
}
140 +
141 +
// Expand IEEE-754-2008 binary16 into float32
142 +
inline uint32_t fp16ToFloat(uint16_t fp16) {
143 +
  return extendBinaryFloatingPoint<ieee_754_2008::Binary16,
144 +
                                   ieee_754_2008::Binary32>(fp16);
145 +
}
146 +
147 +
// Expand IEEE-754-2008 binary24 into float32
148 +
inline uint32_t fp24ToFloat(uint32_t fp24) {
149 +
  return extendBinaryFloatingPoint<ieee_754_2008::Binary24,
150 +
                                   ieee_754_2008::Binary32>(fp24);
127 151
}
128 152
129 153
} // namespace rawspeed
Files Coverage
fuzz 1.92%
src 56.52%
test/librawspeed 97.18%
Project Totals (235 files) 60.54%
linux.GNU.Coverage.Unittests
Build #381971744 -
CXX=GNU
ARCH=x86_64
OS=linux
unittests
macos-latest.XCode.Coverage.Unittests
Build #381971744 -
CXX=AppleXcode
ARCH=x86_64
OS=macOS
unittests
windows-latest.MINGW32.GNU.Coverage.Unittests
Build #381971744 -
CXX=GNU
ARCH=i686
OS=windows
unittests
linux.GNU.Coverage.Integration
Build #381971744 -
CXX=GNU
ARCH=x86_64
OS=linux
integration rpu_u
windows-latest.MINGW64.GNU.Coverage.Unittests
Build #381971744 -
CXX=GNU
ARCH=x86_64
OS=windows
unittests
1
codecov:
2
  notify:
3
    require_ci_to_pass: true
4
coverage:
5
  precision: 2
6
  range: "0...100"
7
  round: down
8
  status:
9
    changes: false
10
    patch: false
11
    project: false
12
  ignore:
13
    - test/.*
14
  notify:
15
    irc:
16
      default:
17
        server: "chat.freenode.net"
18
        channel: "#rawspeed"
19
parsers:
20
  gcov:
21
    branch_detection:
22
      conditional: true
23
      loop: true
24
      macro: false
25
      method: false
26
comment:
27
  behavior: default
28
  layout: header, diff
29
  require_changes: false
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading