Caffe2 - C++ API
A deep learning, cross platform ML framework
cvtsh_ss_bugfix.h
1 #pragma once
2 
3 // Apple clang was fixed in 8.1
4 #if defined(__apple_build_version__) && ((__clang_major__ < 8) || ((__clang_major__ == 8) && (__clang_minor__ < 1)))
5 #define __APPLE_NEED_FIX 1
6 #endif
7 
8 // Regular clang was fixed in 3.9
9 #if defined(__clang__) && (__clang_major__ < 4) && (__clang_minor__ < 9)
10 #define __CLANG_NEED_FIX 1
11 #endif
12 
13 #if __APPLE_NEED_FIX || __CLANG_NEED_FIX
14 
15 #include <c10/util/Half.h>
16 #include <emmintrin.h>
17 
18 // This version of clang has a bug that _cvtsh_ss is not defined, see
19 // https://reviews.llvm.org/D16177
20 static __inline float
21  __attribute__((__always_inline__, __nodebug__, __target__("f16c")))
22 _cvtsh_ss(unsigned short a)
23 {
24  __v8hi v = {(short)a, 0, 0, 0, 0, 0, 0, 0};
25  __v4sf r = __builtin_ia32_vcvtph2ps(v);
26  return r[0];
27 }
28 
29 static __inline unsigned short
30  __attribute__((__always_inline__, __nodebug__, __target__("f16c")))
31 _cvtss_sh(float a, int imm8) {
32  unsigned short ret;
33  *reinterpret_cast<at::Half*>(&ret) = a;
34  return ret;
35 }
36 
37 #endif // __APPLE_NEED_FIX || __CLANG_NEED_FIX
38 
39 #undef __APPLE_NEED_FIX
40 #undef __CLANG_NEED_FIX
41 
42 #ifdef _MSC_VER
43 
44 #include <c10/util/Half.h>
45 #include <cstdint>
46 
47 // It seems that microsoft msvc does not have a _cvtsh_ss implementation so
48 // we will add a dummy version to it.
49 
50 static inline float _cvtsh_ss(unsigned short x) {
51  union {
52  std::uint32_t intval;
53  float floatval;
54  } t1;
55  std::uint32_t t2, t3;
56  t1.intval = x & 0x7fff; // Non-sign bits
57  t2 = x & 0x8000; // Sign bit
58  t3 = x & 0x7c00; // Exponent
59  t1.intval <<= 13; // Align mantissa on MSB
60  t2 <<= 16; // Shift sign bit into position
61  t1.intval += 0x38000000; // Adjust bias
62  t1.intval = (t3 == 0 ? 0 : t1.intval); // Denormals-as-zero
63  t1.intval |= t2; // Re-insert sign bit
64  return t1.floatval;
65 }
66 
67 static inline unsigned short _cvtss_sh(float x, int imm8) {
68  unsigned short ret;
69  *reinterpret_cast<at::Half*>(&ret) = x;
70  return ret;
71 }
72 
73 #endif // _MSC_VER