InteropHeaders.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Mehdi Goli Codeplay Software Ltd.
5 // Ralph Potter Codeplay Software Ltd.
6 // Luke Iwanski Codeplay Software Ltd.
7 // Contact: <eigen@codeplay.com>
8 //
9 // This Source Code Form is subject to the terms of the Mozilla
10 // Public License v. 2.0. If a copy of the MPL was not distributed
11 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 
13 
21 #ifndef EIGEN_INTEROP_HEADERS_SYCL_H
22 #define EIGEN_INTEROP_HEADERS_SYCL_H
23 
24 #include "../../InternalHeaderCheck.h"
25 
26 namespace Eigen {
27 
28 #if !defined(EIGEN_DONT_VECTORIZE_SYCL)
29 
30 namespace internal {
31 
32 template <int has_blend, int lengths>
33 struct sycl_packet_traits : default_packet_traits {
34  enum {
35  Vectorizable = 1,
36  AlignedOnScalar = 1,
37  size = lengths,
38  HasDiv = 1,
39  HasLog = 1,
40  HasExp = 1,
41  HasSqrt = 1,
42  HasRsqrt = 1,
43  HasSin = 1,
44  HasCos = 1,
45  HasTan = 1,
46  HasASin = 1,
47  HasACos = 1,
48  HasATan = 1,
49  HasSinh = 1,
50  HasCosh = 1,
51  HasTanh = 1,
52  HasLGamma = 0,
53  HasDiGamma = 0,
54  HasZeta = 0,
55  HasPolygamma = 0,
56  HasErf = 0,
57  HasErfc = 0,
58  HasNdtri = 0,
59  HasIGamma = 0,
60  HasIGammac = 0,
61  HasBetaInc = 0,
62  HasBlend = has_blend,
63  // This flag is used to indicate whether packet comparison is supported.
64  // pcmp_eq, pcmp_lt and pcmp_le should be defined for it to be true.
65  HasCmp = 1,
66  HasMax = 1,
67  HasMin = 1,
68  HasMul = 1,
69  HasAdd = 1,
70  HasFloor = 1,
71  HasRound = 1,
72  HasRint = 1,
73  HasLog1p = 1,
74  HasExpm1 = 1,
75  HasCeil = 1,
76  };
77 };
78 
79 #ifdef SYCL_DEVICE_ONLY
80 #define SYCL_PACKET_TRAITS(packet_type, has_blend, unpacket_type, lengths) \
81  template <> \
82  struct packet_traits<unpacket_type> \
83  : sycl_packet_traits<has_blend, lengths> { \
84  typedef packet_type type; \
85  typedef packet_type half; \
86  };
87 
88 SYCL_PACKET_TRAITS(cl::sycl::cl_float4, 1, float, 4)
89 SYCL_PACKET_TRAITS(cl::sycl::cl_float4, 1, const float, 4)
90 SYCL_PACKET_TRAITS(cl::sycl::cl_double2, 0, double, 2)
91 SYCL_PACKET_TRAITS(cl::sycl::cl_double2, 0, const double, 2)
92 #undef SYCL_PACKET_TRAITS
93 
94 // Make sure this is only available when targeting a GPU: we don't want to
95 // introduce conflicts between these packet_traits definitions and the ones
96 // we'll use on the host side (SSE, AVX, ...)
97 #define SYCL_ARITHMETIC(packet_type) \
98  template <> \
99  struct is_arithmetic<packet_type> { \
100  enum { value = true }; \
101  };
102 SYCL_ARITHMETIC(cl::sycl::cl_float4)
103 SYCL_ARITHMETIC(cl::sycl::cl_double2)
104 #undef SYCL_ARITHMETIC
105 
106 #define SYCL_UNPACKET_TRAITS(packet_type, unpacket_type, lengths) \
107  template <> \
108  struct unpacket_traits<packet_type> { \
109  typedef unpacket_type type; \
110  enum { size = lengths, vectorizable = true, alignment = Aligned16 }; \
111  typedef packet_type half; \
112  };
113 SYCL_UNPACKET_TRAITS(cl::sycl::cl_float4, float, 4)
114 SYCL_UNPACKET_TRAITS(cl::sycl::cl_double2, double, 2)
115 
116 #undef SYCL_UNPACKET_TRAITS
117 #endif
118 
119 } // end namespace internal
120 
121 #endif
122 
123 namespace TensorSycl {
124 namespace internal {
125 
126 template <typename PacketReturnType, int PacketSize>
127 struct PacketWrapper;
128 // This function should never get called on the device
129 #ifndef SYCL_DEVICE_ONLY
130 template <typename PacketReturnType, int PacketSize>
131 struct PacketWrapper {
132  typedef typename ::Eigen::internal::unpacket_traits<PacketReturnType>::type
133  Scalar;
134  template <typename Index>
135  EIGEN_DEVICE_FUNC static Scalar scalarize(Index, PacketReturnType &) {
136  eigen_assert(false && "THERE IS NO PACKETIZE VERSION FOR THE CHOSEN TYPE");
137  abort();
138  }
139  EIGEN_DEVICE_FUNC static PacketReturnType convert_to_packet_type(Scalar in,
140  Scalar) {
141  return ::Eigen::internal::template plset<PacketReturnType>(in);
142  }
143  EIGEN_DEVICE_FUNC static void set_packet(PacketReturnType, Scalar *) {
144  eigen_assert(false && "THERE IS NO PACKETIZE VERSION FOR THE CHOSEN TYPE");
145  abort();
146  }
147 };
148 
149 #elif defined(SYCL_DEVICE_ONLY)
150 template <typename PacketReturnType>
151 struct PacketWrapper<PacketReturnType, 4> {
152  typedef typename ::Eigen::internal::unpacket_traits<PacketReturnType>::type
153  Scalar;
154  template <typename Index>
155  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static Scalar scalarize(Index index, PacketReturnType &in) {
156  switch (index) {
157  case 0:
158  return in.x();
159  case 1:
160  return in.y();
161  case 2:
162  return in.z();
163  case 3:
164  return in.w();
165  default:
166  //INDEX MUST BE BETWEEN 0 and 3.There is no abort function in SYCL kernel. so we cannot use abort here.
167  // The code will never reach here
168  __builtin_unreachable();
169  }
170  __builtin_unreachable();
171  }
172 
173  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static PacketReturnType convert_to_packet_type(
174  Scalar in, Scalar other) {
175  return PacketReturnType(in, other, other, other);
176  }
177  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static void set_packet(PacketReturnType &lhs, Scalar *rhs) {
178  lhs = PacketReturnType(rhs[0], rhs[1], rhs[2], rhs[3]);
179  }
180 };
181 
182 template <typename PacketReturnType>
183 struct PacketWrapper<PacketReturnType, 1> {
184  typedef typename ::Eigen::internal::unpacket_traits<PacketReturnType>::type
185  Scalar;
186  template <typename Index>
187  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static Scalar scalarize(Index, PacketReturnType &in) {
188  return in;
189  }
190  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static PacketReturnType convert_to_packet_type(Scalar in,
191  Scalar) {
192  return PacketReturnType(in);
193  }
194  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static void set_packet(PacketReturnType &lhs, Scalar *rhs) {
195  lhs = rhs[0];
196  }
197 };
198 
199 template <typename PacketReturnType>
200 struct PacketWrapper<PacketReturnType, 2> {
201  typedef typename ::Eigen::internal::unpacket_traits<PacketReturnType>::type
202  Scalar;
203  template <typename Index>
204  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static Scalar scalarize(Index index, PacketReturnType &in) {
205  switch (index) {
206  case 0:
207  return in.x();
208  case 1:
209  return in.y();
210  default:
211  //INDEX MUST BE BETWEEN 0 and 1.There is no abort function in SYCL kernel. so we cannot use abort here.
212  // The code will never reach here
213  __builtin_unreachable();
214  }
215  __builtin_unreachable();
216  }
217 
218  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static PacketReturnType convert_to_packet_type(
219  Scalar in, Scalar other) {
220  return PacketReturnType(in, other);
221  }
222  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static void set_packet(PacketReturnType &lhs, Scalar *rhs) {
223  lhs = PacketReturnType(rhs[0], rhs[1]);
224  }
225 };
226 
227 #endif
228 
229 } // end namespace internal
230 } // end namespace TensorSycl
231 } // end namespace Eigen
232 
233 #endif // EIGEN_INTEROP_HEADERS_SYCL_H
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define eigen_assert(x)
Definition: Macros.h:902
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82