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