MCPcopy Create free account
hub / github.com/bitsandbytes-foundation/bitsandbytes / float_to_fp16

Function float_to_fp16

csrc/cpu_ops.h:153–200  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

151}
152
153static inline fp16_t float_to_fp16(float x) {
154#if defined(__AVX2__)
155 // F16C is guaranteed on all AVX2 CPUs; matches CUDA round-to-nearest-even behavior
156 return fp16_t{
157 (uint16_t)_mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(x), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC), 0)
158 };
159#else
160 uint32_t bits;
161 std::memcpy(&bits, &x, 4);
162 uint32_t sign = (bits >> 31) & 0x1;
163 uint32_t exp = (bits >> 23) & 0xFF;
164 uint32_t mant = bits & 0x7FFFFF;
165
166 uint16_t h;
167 if (exp == 0xFF) { // Inf / NaN
168 uint16_t mant16 = mant ? 0x200 : 0; // quiet NaN: set MSB of mantissa
169 h = (sign << 15) | (0x1F << 10) | mant16;
170 } else if (exp > 0x70 + 0x1E) { // overflow: exp_f -127 +15 > 30 (exp_f > 142)
171 h = (sign << 15) | (0x1F << 10); // Inf
172 } else if (exp < 0x71) { // subnormal or zero (exp_f < 113)
173 if (exp < 0x67) { // too small -> zero (exp_f < 103)
174 h = (sign << 15);
175 } else {
176 // subnormal: implicit leading 1
177 uint32_t shift = 0x71 - exp;
178 uint32_t mant_with_hidden = mant | 0x800000;
179 // add rounding bias before shifting (23-10 =13 bits to drop + shift)
180 uint32_t rounded = (mant_with_hidden + (1u << (shift + 12))) >> (shift + 13);
181 h = (sign << 15) | (uint16_t)rounded;
182 }
183 } else {
184 // normalized
185 uint32_t exp_h = exp - 127 + 15;
186 // round mantissa: add 2^(23-10-1) = 0x1000
187 uint32_t mant_rounded = mant + 0x00001000;
188 if (mant_rounded & 0x00800000) { // mantissa overflow after rounding
189 mant_rounded = 0;
190 ++exp_h;
191 if (exp_h >= 0x1F) { // overflow to Inf
192 h = (sign << 15) | (0x1F << 10);
193 return fp16_t{h};
194 }
195 }
196 h = (sign << 15) | ((uint16_t)exp_h << 10) | ((uint16_t)(mant_rounded >> 13));
197 }
198 return fp16_t{h};
199#endif
200}
201
202static inline float fp16_to_float(uint16_t h) {
203#if defined(__AVX2__)

Callers 2

Calls

no outgoing calls

Tested by

no test coverage detected