QtBase  v6.3.1
qfloat16.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 The Qt Company Ltd.
4 ** Copyright (C) 2016 by Southwest Research Institute (R)
5 ** Contact: http://www.qt-project.org/legal
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qfloat16.h"
42 #include "private/qsimd_p.h"
43 #include <cmath> // for fpclassify()'s return values
44 
45 #include <QtCore/qdatastream.h>
46 
48 
50 
51 
165 int qfloat16::fpClassify() const noexcept
166 {
167  return isInf() ? FP_INFINITE : isNaN() ? FP_NAN
168  : !(b16 & 0x7fff) ? FP_ZERO : isNormal() ? FP_NORMAL : FP_SUBNORMAL;
169 }
170 
196 #if QT_COMPILER_SUPPORTS_HERE(F16C)
197 static inline bool hasFastF16()
198 {
199  // qsimd.cpp:detectProcessorFeatures() turns off this feature if AVX
200  // state-saving is not enabled by the OS
201  return qCpuHasFeature(F16C);
202 }
203 
204 QT_FUNCTION_TARGET(F16C)
205 static void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) noexcept
206 {
207  qsizetype i = 0;
208  int epilog_i;
209  for (; i < len - 7; i += 8)
210  _mm_storeu_si128((__m128i *)(out + i), _mm256_cvtps_ph(_mm256_loadu_ps(in + i), 0));
211  if (i < len - 3) {
212  _mm_storel_epi64((__m128i *)(out + i), _mm_cvtps_ph(_mm_loadu_ps(in + i), 0));
213  i += 4;
214  }
215  // Inlining "qfloat16::qfloat16(float f)":
216  for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
217  out[i] = _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(in[i]), 0), 0);
218 }
219 
220 QT_FUNCTION_TARGET(F16C)
221 static void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) noexcept
222 {
223  qsizetype i = 0;
224  int epilog_i;
225  for (; i < len - 7; i += 8)
226  _mm256_storeu_ps(out + i, _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)(in + i))));
227  if (i < len - 3) {
228  _mm_storeu_ps(out + i, _mm_cvtph_ps(_mm_loadl_epi64((const __m128i *)(in + i))));
229  i += 4;
230  }
231  // Inlining "qfloat16::operator float()":
232  for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
233  out[i] = _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(in[i])));
234 }
235 
236 #elif defined(__ARM_FP16_FORMAT_IEEE) && defined(__ARM_NEON__) && (__ARM_FP & 2)
237 static inline bool hasFastF16()
238 {
239  return true;
240 }
241 
242 static void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) noexcept
243 {
244  __fp16 *out_f16 = reinterpret_cast<__fp16 *>(out);
245  qsizetype i = 0;
246  for (; i < len - 3; i += 4)
247  vst1_f16(out_f16 + i, vcvt_f16_f32(vld1q_f32(in + i)));
248  SIMD_EPILOGUE(i, len, 3)
249  out_f16[i] = __fp16(in[i]);
250 }
251 
252 static void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) noexcept
253 {
254  const __fp16 *in_f16 = reinterpret_cast<const __fp16 *>(in);
255  qsizetype i = 0;
256  for (; i < len - 3; i += 4)
257  vst1q_f32(out + i, vcvt_f32_f16(vld1_f16(in_f16 + i)));
258  SIMD_EPILOGUE(i, len, 3)
259  out[i] = float(in_f16[i]);
260 }
261 #else
262 static inline bool hasFastF16()
263 {
264  return false;
265 }
266 
267 static void qFloatToFloat16_fast(quint16 *, const float *, qsizetype) noexcept
268 {
269  Q_UNREACHABLE();
270 }
271 
272 static void qFloatFromFloat16_fast(float *, const quint16 *, qsizetype) noexcept
273 {
274  Q_UNREACHABLE();
275 }
276 #endif
287 Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qsizetype len) noexcept
288 {
289  if (hasFastF16())
290  return qFloatToFloat16_fast(reinterpret_cast<quint16 *>(out), in, len);
291 
292  for (qsizetype i = 0; i < len; ++i)
293  out[i] = qfloat16(in[i]);
294 }
295 
306 Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qsizetype len) noexcept
307 {
308  if (hasFastF16())
309  return qFloatFromFloat16_fast(out, reinterpret_cast<const quint16 *>(in), len);
310 
311  for (qsizetype i = 0; i < len; ++i)
312  out[i] = float(in[i]);
313 }
314 
315 #ifndef QT_NO_DATASTREAM
328 {
329  return ds << f.b16;
330 }
331 
345 {
346  return ds >> f.b16;
347 }
348 #endif
349 
351 
352 #include "qfloat16tables.cpp"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
operator>>(QDataStream &ds, qfloat16 &f)
Definition: qfloat16.cpp:344
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
Provides 16-bit floating point support.
Definition: qfloat16.h:75
Q_CORE_EXPORT void qFloatFromFloat16(float *out, const qfloat16 *in, qsizetype len) noexcept
Definition: qfloat16.cpp:306
Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qsizetype len) noexcept
Definition: qfloat16.cpp:287
auto it unsigned count const
Definition: hb-iter.hh:848
#define Q_UNREACHABLE()
unsigned short quint16
Definition: qglobal.h:286
ptrdiff_t qsizetype
Definition: qglobal.h:308
#define QT_IMPL_METATYPE_EXTERN(TYPE)
Definition: qmetatype.h:1287
GLfloat GLfloat f
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint in
Definition: qopenglext.h:8870
#define QT_FUNCTION_TARGET(x)
Definition: qsimd_p.h:182
#define SIMD_EPILOGUE(i, length, max)
Definition: qsimd_p.h:457
QTextStream out(stdout)
[7]