Eigen  3.2.93
CUDA/TypeCasting.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2016 Benoit Steiner <benoit.steiner.goog@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_TYPE_CASTING_CUDA_H
11 #define EIGEN_TYPE_CASTING_CUDA_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<>
18 struct scalar_cast_op<float, Eigen::half> {
19  EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
20  typedef Eigen::half result_type;
21  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half operator() (const float& a) const {
22  #if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300
23  return __float2half(a);
24  #else
25  return Eigen::half(a);
26  #endif
27  }
28 };
29 
30 template<>
31 struct functor_traits<scalar_cast_op<float, Eigen::half> >
32 { enum { Cost = NumTraits<float>::AddCost, PacketAccess = false }; };
33 
34 
35 template<>
36 struct scalar_cast_op<int, Eigen::half> {
37  EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
38  typedef Eigen::half result_type;
39  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Eigen::half operator() (const int& a) const {
40  #if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300
41  return __float2half(static_cast<float>(a));
42  #else
43  return Eigen::half(static_cast<float>(a));
44  #endif
45  }
46 };
47 
48 template<>
49 struct functor_traits<scalar_cast_op<int, Eigen::half> >
50 { enum { Cost = NumTraits<float>::AddCost, PacketAccess = false }; };
51 
52 
53 template<>
54 struct scalar_cast_op<Eigen::half, float> {
55  EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
56  typedef float result_type;
57  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float operator() (const Eigen::half& a) const {
58  #if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300
59  return __half2float(a);
60  #else
61  return static_cast<float>(a);
62  #endif
63  }
64 };
65 
66 template<>
67 struct functor_traits<scalar_cast_op<Eigen::half, float> >
68 { enum { Cost = NumTraits<float>::AddCost, PacketAccess = false }; };
69 
70 
71 
72 #if defined(EIGEN_HAS_CUDA_FP16) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 300
73 
74 template <>
75 struct type_casting_traits<Eigen::half, float> {
76  enum {
77  VectorizedCast = 1,
78  SrcCoeffRatio = 2,
79  TgtCoeffRatio = 1
80  };
81 };
82 
83 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 pcast<half2, float4>(const half2& a, const half2& b) {
84  float2 r1 = __half22float2(a);
85  float2 r2 = __half22float2(b);
86  return make_float4(r1.x, r1.y, r2.x, r2.y);
87 }
88 
89 template <>
90 struct type_casting_traits<float, Eigen::half> {
91  enum {
92  VectorizedCast = 1,
93  SrcCoeffRatio = 1,
94  TgtCoeffRatio = 2
95  };
96 };
97 
98 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE half2 pcast<float4, half2>(const float4& a) {
99  // Simply discard the second half of the input
100  return __floats2half2_rn(a.x, a.y);
101 }
102 
103 #elif defined EIGEN_VECTORIZE_AVX
104 
105 template <>
106 struct type_casting_traits<Eigen::half, float> {
107  enum {
108  VectorizedCast = 1,
109  SrcCoeffRatio = 1,
110  TgtCoeffRatio = 1
111  };
112 };
113 
114 template<> EIGEN_STRONG_INLINE Packet8f pcast<Packet8h, Packet8f>(const Packet8h& a) {
115  return half2float(a);
116 }
117 
118 template <>
119 struct type_casting_traits<float, Eigen::half> {
120  enum {
121  VectorizedCast = 1,
122  SrcCoeffRatio = 1,
123  TgtCoeffRatio = 1
124  };
125 };
126 
127 template<> EIGEN_STRONG_INLINE Packet8h pcast<Packet8f, Packet8h>(const Packet8f& a) {
128  return float2half(a);
129 }
130 
131 // Disable the following code since it's broken on too many platforms / compilers.
132 //#elif defined(EIGEN_VECTORIZE_SSE) && (!EIGEN_ARCH_x86_64) && (!EIGEN_COMP_MSVC)
133 #elif 0
134 
135 template <>
136 struct type_casting_traits<Eigen::half, float> {
137  enum {
138  VectorizedCast = 1,
139  SrcCoeffRatio = 1,
140  TgtCoeffRatio = 1
141  };
142 };
143 
144 template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet4h, Packet4f>(const Packet4h& a) {
145  __int64_t a64 = _mm_cvtm64_si64(a.x);
146  Eigen::half h = raw_uint16_to_half(static_cast<unsigned short>(a64));
147  float f1 = static_cast<float>(h);
148  h = raw_uint16_to_half(static_cast<unsigned short>(a64 >> 16));
149  float f2 = static_cast<float>(h);
150  h = raw_uint16_to_half(static_cast<unsigned short>(a64 >> 32));
151  float f3 = static_cast<float>(h);
152  h = raw_uint16_to_half(static_cast<unsigned short>(a64 >> 48));
153  float f4 = static_cast<float>(h);
154  return _mm_set_ps(f4, f3, f2, f1);
155 }
156 
157 template <>
158 struct type_casting_traits<float, Eigen::half> {
159  enum {
160  VectorizedCast = 1,
161  SrcCoeffRatio = 1,
162  TgtCoeffRatio = 1
163  };
164 };
165 
166 template<> EIGEN_STRONG_INLINE Packet4h pcast<Packet4f, Packet4h>(const Packet4f& a) {
167  EIGEN_ALIGN16 float aux[4];
168  pstore(aux, a);
169  Eigen::half h0(aux[0]);
170  Eigen::half h1(aux[1]);
171  Eigen::half h2(aux[2]);
172  Eigen::half h3(aux[3]);
173 
174  Packet4h result;
175  result.x = _mm_set_pi16(h3.x, h2.x, h1.x, h0.x);
176  return result;
177 }
178 
179 #endif
180 
181 } // end namespace internal
182 
183 } // end namespace Eigen
184 
185 #endif // EIGEN_TYPE_CASTING_CUDA_H
Namespace containing all symbols from the Eigen library.
Definition: Core:271
Definition: Eigen_Colamd.h:50