DPC++ Runtime
Runtime libraries for oneAPI DPC++
simd_view.hpp
Go to the documentation of this file.
1 //==------------ - simd_view.hpp - DPC++ Explicit SIMD API ---------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // Implement Explicit SIMD vector view APIs.
9 //===----------------------------------------------------------------------===//
10 
11 #pragma once
12 
15 
16 namespace sycl {
17 inline namespace _V1 {
18 namespace ext::intel::esimd {
19 
22 
34 template <typename BaseTy,
35  typename RegionTy =
36  region1d_t<typename BaseTy::element_type, BaseTy::length, 1>>
37 class simd_view : public detail::simd_view_impl<BaseTy, RegionTy> {
39  template <typename, int, class, class> friend class detail::simd_obj_impl;
40  template <typename, int> friend class detail::simd_mask_impl;
41  template <typename, typename> friend class simd_view;
42  template <typename, int> friend class simd;
43  template <typename, typename> friend class detail::simd_view_impl;
44 
45 protected:
47  // Deduce the corresponding value type from its region type.
48  using ShapeTy = typename shape_type<RegionTy>::type;
49  using base_type = BaseTy;
50  template <typename ElT, int N>
51  using get_simd_t = typename BaseClass::template get_simd_t<ElT, N>;
53 
54 public:
55  static_assert(detail::is_simd_obj_impl_derivative_v<BaseTy>);
56 
57  static constexpr int length = ShapeTy::Size_x * ShapeTy::Size_y;
58 
60  using region_type = RegionTy;
61 
64  using element_type = typename ShapeTy::element_type;
65 
67  using value_type = get_simd_t<element_type, length>;
68 
71  detail::vector_type_t<detail::__raw_t<element_type>, length>;
72 
73 protected:
75  simd_view(BaseTy &Base, RegionTy Region) : BaseClass(Base, Region) {}
76  simd_view(BaseTy &&Base, RegionTy Region) : BaseClass(Base, Region) {}
78 
79 public:
81  simd_view(const simd_view &Other) = default;
82  simd_view(simd_view &&Other) = default;
83 
86  simd_view(BaseTy &Base) : BaseClass(Base) {}
87 
89  simd_view &operator=(const simd_view &Other) {
90  BaseClass::operator=(Other);
91  return *this;
92  }
93 
94  using BaseClass::operator--;
95  using BaseClass::operator++;
96  using BaseClass::operator=;
97 };
98 
99 #define __ESIMD_DEF_SCALAR_SIMD_VIEW_RELOP(RELOP) \
100  /* simd_view RELOP simd_view */ \
101  ESIMD_INLINE friend bool operator RELOP(const simd_view &X, \
102  const simd_view &Y) { \
103  return (element_type)X RELOP(element_type) Y; \
104  } \
105  \
106  /* simd_view RELOP SCALAR */ \
107  template <typename T1, \
108  std::enable_if_t<detail::is_valid_simd_elem_type_v<T1>>> \
109  ESIMD_INLINE friend bool operator RELOP(const simd_view &X, T1 Y) { \
110  return (element_type)X RELOP Y; \
111  } \
112  \
113  /* SCALAR RELOP simd_view */ \
114  template <typename T1, \
115  std::enable_if_t<detail::is_valid_simd_elem_type_v<T1>>> \
116  ESIMD_INLINE friend bool operator RELOP(T1 X, const simd_view &Y) { \
117  return X RELOP(element_type) Y; \
118  }
119 
131 template <typename BaseTy, class ViewedElemT>
132 class simd_view<BaseTy, region1d_scalar_t<ViewedElemT>>
133  : public detail::simd_view_impl<BaseTy, region1d_scalar_t<ViewedElemT>> {
134  template <typename, int, class, class> friend class detail::simd_obj_impl;
135  template <typename, typename> friend class detail::simd_view_impl;
136 
137 public:
138  using RegionTy = region1d_scalar_t<ViewedElemT>;
140  using ShapeTy = typename shape_type<RegionTy>::type;
141  static constexpr int length = ShapeTy::Size_x * ShapeTy::Size_y;
142  static_assert(1 == length, "length of this view is not equal to 1");
143  static_assert(std::is_same_v<typename ShapeTy::element_type, ViewedElemT>);
146  using element_type = ViewedElemT;
147  using base_type = BaseTy;
148  template <typename ElT, int N>
149  using get_simd_t = typename BaseClass::template get_simd_t<ElT, N>;
152 
153 private:
154  simd_view(BaseTy &Base, RegionTy Region) : BaseClass(Base, Region) {}
155  simd_view(BaseTy &&Base, RegionTy Region) : BaseClass(Base, Region) {}
156 
157 public:
159  simd_view(BaseTy &Base) : BaseClass(Base) {}
160 
161  operator element_type() const {
162  const auto v = BaseClass::read().data();
163  return detail::bitcast_to_wrapper_type<element_type>(std::move(v)[0]);
164  }
165 
166  using BaseClass::operator--;
167  using BaseClass::operator++;
168  using BaseClass::operator=;
169 
176 };
177 
178 // TODO: remove code duplication in two class specializations for a simd_view
179 // with a single element
180 
186 template <typename BaseTy, typename NestedRegion, class ViewedElemT>
187 class simd_view<BaseTy, std::pair<region1d_scalar_t<ViewedElemT>, NestedRegion>>
188  : public detail::simd_view_impl<
189  BaseTy, std::pair<region1d_scalar_t<ViewedElemT>, NestedRegion>> {
190  template <typename, int> friend class simd;
191  template <typename, typename> friend class detail::simd_view_impl;
192 
193 public:
194  using RegionTy = std::pair<region1d_scalar_t<ViewedElemT>, NestedRegion>;
196  using ShapeTy = typename shape_type<RegionTy>::type;
197  static constexpr int length = ShapeTy::Size_x * ShapeTy::Size_y;
198  static_assert(1 == length, "length of this view is not equal to 1");
199  static_assert(std::is_same_v<typename ShapeTy::element_type, ViewedElemT>);
202  using element_type = ViewedElemT;
203 
204 private:
205  simd_view(BaseTy &Base, RegionTy Region) : BaseClass(Base, Region) {}
206  simd_view(BaseTy &&Base, RegionTy Region) : BaseClass(Base, Region) {}
207 
208 public:
209  using BaseClass::operator=;
210 
211  operator element_type() const {
212  const auto v = BaseClass::read();
213  return detail::convert_scalar<element_type>(v[0]);
214  }
215 
222 };
223 
224 #undef __ESIMD_DEF_SCALAR_SIMD_VIEW_RELOP
225 
227 
228 } // namespace ext::intel::esimd
229 } // namespace _V1
230 } // namespace sycl
This class is a simd_obj_impl specialization representing a simd mask, which is basically a simd_obj_...
This is a base class for all ESIMD simd classes with real storage (simd, simd_mask_impl).
get_simd_t< element_type, length > value_type
The simd type if reading the object.
Definition: simd_view.hpp:151
ViewedElemT element_type
The element type of this class, which could be different from the element type of the base object typ...
Definition: simd_view.hpp:146
ViewedElemT element_type
The element type of this class, which could be different from the element type of the base object typ...
Definition: simd_view.hpp:202
This class represents a reference to a sub-region of a base simd object.
Definition: simd_view.hpp:37
simd_view & operator=(const simd_view &Other)
Copy assignment operator.
Definition: simd_view.hpp:89
typename ShapeTy::element_type element_type
The element type of this class, which could be different from the element type of the base object typ...
Definition: simd_view.hpp:64
get_simd_t< element_type, length > value_type
The simd type if reading the object.
Definition: simd_view.hpp:67
RegionTy region_type
The region type of this class.
Definition: simd_view.hpp:60
detail::vector_type_t< detail::__raw_t< element_type >, length > raw_vector_type
The underlying builtin value type.
Definition: simd_view.hpp:71
simd_view(const simd_view &Other)=default
Default copy and move constructors for simd_view.
simd_view(BaseTy &Base)
Construct a complete view of a vector.
Definition: simd_view.hpp:86
simd_view(simd_view &&Other)=default
The main simd vector class.
Definition: simd.hpp:53
#define __ESIMD_DEF_SCALAR_SIMD_VIEW_RELOP(RELOP)
Definition: simd_view.hpp:99
annotated_arg & operator=(annotated_arg &)=default
Definition: access.hpp:18