DPC++ Runtime
Runtime libraries for oneAPI DPC++
image_impl.hpp
Go to the documentation of this file.
1 //==------------ image_impl.hpp --------------------------------------------==//
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 
9 #pragma once
10 
16 #include <CL/sycl/device.hpp>
17 #include <CL/sycl/event.hpp>
19 #include <CL/sycl/range.hpp>
20 #include <CL/sycl/stl.hpp>
21 
23 namespace sycl {
24 
25 // forward declarations
26 enum class image_channel_order : unsigned int;
27 enum class image_channel_type : unsigned int;
28 
29 template <int Dimensions, typename AllocatorT> class image;
30 template <typename DataT, int Dimensions, access::mode AccessMode,
31  access::target AccessTarget, access::placeholder IsPlaceholder,
32  typename property_listT>
33 class accessor;
34 class handler;
35 
36 namespace detail {
37 
38 // utility functions and typedefs for image_impl
40 
41 // utility function: Returns the Number of Channels for a given Order.
42 __SYCL_EXPORT uint8_t getImageNumberChannels(image_channel_order Order);
43 
44 // utility function: Returns the number of bytes per image element
45 __SYCL_EXPORT uint8_t getImageElementSize(uint8_t NumChannels,
46  image_channel_type Type);
47 
48 __SYCL_EXPORT RT::PiMemImageChannelOrder
50 
51 __SYCL_EXPORT image_channel_order
53 
54 __SYCL_EXPORT RT::PiMemImageChannelType
56 
57 __SYCL_EXPORT image_channel_type
59 
60 // validImageDataT: cl_int4, cl_uint4, cl_float4, cl_half4
61 template <typename T>
64 
65 template <typename DataT>
66 using EnableIfImgAccDataT =
68 
69 template <int Dimensions>
70 class __SYCL_EXPORT image_impl final : public SYCLMemObjT {
71  using BaseT = SYCLMemObjT;
72  using typename BaseT::MemObjType;
73 
74 private:
75  template <bool B>
76  using EnableIfPitchT = typename detail::enable_if_t<B, range<Dimensions - 1>>;
77  static_assert(Dimensions >= 1 || Dimensions <= 3,
78  "Dimensions of cl::sycl::image can be 1, 2 or 3");
79 
80  void setPitches() {
81  size_t WHD[3] = {1, 1, 1}; // Width, Height, Depth.
82  for (int I = 0; I < Dimensions; I++)
83  WHD[I] = MRange[I];
84 
85  MRowPitch = MElementSize * WHD[0];
86  MSlicePitch = MRowPitch * WHD[1];
87  BaseT::MSizeInBytes = MSlicePitch * WHD[2];
88  }
89 
90  template <bool B = (Dimensions > 1)>
91  void setPitches(const EnableIfPitchT<B> Pitch) {
92  MRowPitch = Pitch[0];
93  MSlicePitch =
94  (Dimensions == 3) ? Pitch[1] : MRowPitch; // Dimensions will be 2/3.
95  // NumSlices is depth when dim==3, and height when dim==2.
96  size_t NumSlices =
97  (Dimensions == 3) ? MRange[2] : MRange[1]; // Dimensions will be 2/3.
98 
99  BaseT::MSizeInBytes = MSlicePitch * NumSlices;
100  }
101 
102 public:
104  const range<Dimensions> &ImageRange,
105  std::unique_ptr<SYCLMemObjAllocator> Allocator,
106  const property_list &PropList = {})
107  : image_impl((void *)nullptr, Order, Type, ImageRange,
108  std::move(Allocator), PropList) {}
109 
110  template <bool B = (Dimensions > 1)>
112  const range<Dimensions> &ImageRange,
113  const EnableIfPitchT<B> &Pitch,
114  std::unique_ptr<SYCLMemObjAllocator> Allocator,
115  const property_list &PropList = {})
116  : image_impl((void *)nullptr, Order, Type, ImageRange, Pitch,
117  std::move(Allocator), PropList) {}
118 
120  const range<Dimensions> &ImageRange,
121  std::unique_ptr<SYCLMemObjAllocator> Allocator,
122  const property_list &PropList = {})
123  : BaseT(PropList, std::move(Allocator)), MRange(ImageRange),
124  MOrder(Order), MType(Type),
125  MNumChannels(getImageNumberChannels(MOrder)),
126  MElementSize(getImageElementSize(MNumChannels, MType)) {
127  setPitches();
128  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
129  }
130 
131  image_impl(const void *HData, image_channel_order Order,
132  image_channel_type Type, const range<Dimensions> &ImageRange,
133  std::unique_ptr<SYCLMemObjAllocator> Allocator,
134  const property_list &PropList = {})
135  : BaseT(PropList, std::move(Allocator)), MRange(ImageRange),
136  MOrder(Order), MType(Type),
137  MNumChannels(getImageNumberChannels(MOrder)),
138  MElementSize(getImageElementSize(MNumChannels, MType)) {
139  setPitches();
140  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
141  }
142 
143  template <bool B = (Dimensions > 1)>
145  const range<Dimensions> &ImageRange,
146  const EnableIfPitchT<B> &Pitch,
147  std::unique_ptr<SYCLMemObjAllocator> Allocator,
148  const property_list &PropList = {})
149  : BaseT(PropList, std::move(Allocator)), MRange(ImageRange),
150  MOrder(Order), MType(Type),
151  MNumChannels(getImageNumberChannels(MOrder)),
152  MElementSize(getImageElementSize(MNumChannels, MType)) {
153  setPitches(Pitch);
154  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
155  }
156 
157  image_impl(std::shared_ptr<void> &HData, image_channel_order Order,
158  image_channel_type Type, const range<Dimensions> &ImageRange,
159  std::unique_ptr<SYCLMemObjAllocator> Allocator,
160  const property_list &PropList = {})
161  : BaseT(PropList, std::move(Allocator)), MRange(ImageRange),
162  MOrder(Order), MType(Type),
163  MNumChannels(getImageNumberChannels(MOrder)),
164  MElementSize(getImageElementSize(MNumChannels, MType)) {
165  setPitches();
166  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
167  }
168 
169  /* Available only when: Dimensions > 1 */
170  template <bool B = (Dimensions > 1)>
171  image_impl(std::shared_ptr<void> &HData, image_channel_order Order,
172  image_channel_type Type, const range<Dimensions> &ImageRange,
173  const EnableIfPitchT<B> &Pitch,
174  std::unique_ptr<SYCLMemObjAllocator> Allocator,
175  const property_list &PropList = {})
176  : BaseT(PropList, std::move(Allocator)), MRange(ImageRange),
177  MOrder(Order), MType(Type),
178  MNumChannels(getImageNumberChannels(MOrder)),
179  MElementSize(getImageElementSize(MNumChannels, MType)) {
180  setPitches(Pitch);
181  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
182  }
183 
184  image_impl(cl_mem MemObject, const context &SyclContext, event AvailableEvent,
185  std::unique_ptr<SYCLMemObjAllocator> Allocator);
186 
187  // Return a range object representing the size of the image in terms of the
188  // number of elements in each dimension as passed to the constructor
189  range<Dimensions> get_range() const { return MRange; }
190 
191  // Return a range object representing the pitch of the image in bytes.
192  // Available only when: Dimensions == 2.
193  template <bool B = (Dimensions == 2)>
195  range<1> Temp = range<1>(MRowPitch);
196  return Temp;
197  }
198 
199  // Return a range object representing the pitch of the image in bytes.
200  // Available only when: Dimensions == 3.
201  template <bool B = (Dimensions == 3)>
203  range<2> Temp = range<2>(MRowPitch, MSlicePitch);
204  return Temp;
205  }
206 
207  // Returns the total number of elements in the image
208  size_t get_count() const { return size(); }
209  size_t size() const noexcept { return MRange.size(); }
210 
211  void *allocateMem(ContextImplPtr Context, bool InitFromUserData,
212  void *HostPtr, RT::PiEvent &OutEventToWait) override;
213 
214  MemObjType getType() const override { return MemObjType::Image; }
215 
216  // This utility api is currently used by accessor to get the element size of
217  // the image. Element size is dependent on num of channels and channel type.
218  // This information is not accessible from the image using any public API.
219  size_t getElementSize() const { return MElementSize; };
220 
221  image_channel_order getChannelOrder() const { return MOrder; }
222 
223  image_channel_type getChannelType() const { return MType; }
224 
225  size_t getRowPitch() const { return MRowPitch; }
226 
227  size_t getSlicePitch() const { return MSlicePitch; }
228 
230  try {
231  BaseT::updateHostMemory();
232  } catch (...) {
233  }
234  }
235 
236 private:
237  std::vector<device> getDevices(const ContextImplPtr Context);
238 
239  RT::PiMemObjectType getImageType() {
240  if (Dimensions == 1)
241  return (MIsArrayImage ? PI_MEM_TYPE_IMAGE1D_ARRAY : PI_MEM_TYPE_IMAGE1D);
242  if (Dimensions == 2)
243  return (MIsArrayImage ? PI_MEM_TYPE_IMAGE2D_ARRAY : PI_MEM_TYPE_IMAGE2D);
244  return PI_MEM_TYPE_IMAGE3D;
245  }
246 
247  RT::PiMemImageDesc getImageDesc(bool InitFromHostPtr) {
248  RT::PiMemImageDesc Desc;
249  Desc.image_type = getImageType();
250 
251  // MRange<> is [width], [width,height], or [width,height,depth] (which
252  // is different than MAccessRange, etc in bufffers)
253  static constexpr int XTermPos = 0, YTermPos = 1, ZTermPos = 2;
254  Desc.image_width = MRange[XTermPos];
255  Desc.image_height = Dimensions > 1 ? MRange[YTermPos] : 1;
256  Desc.image_depth = Dimensions > 2 ? MRange[ZTermPos] : 1;
257 
258  // TODO handle cases with IMAGE1D_ARRAY and IMAGE2D_ARRAY
259  Desc.image_array_size = 0;
260  // Pitches must be 0 if host ptr is not provided.
261  Desc.image_row_pitch = InitFromHostPtr ? MRowPitch : 0;
262  Desc.image_slice_pitch = InitFromHostPtr ? MSlicePitch : 0;
263  Desc.num_mip_levels = 0;
264  Desc.num_samples = 0;
265  Desc.buffer = nullptr;
266  return Desc;
267  }
268 
269  bool checkImageDesc(const RT::PiMemImageDesc &Desc, ContextImplPtr Context,
270  void *UserPtr);
271 
272  RT::PiMemImageFormat getImageFormat() {
273  RT::PiMemImageFormat Format;
276  return Format;
277  }
278 
279  bool checkImageFormat(const RT::PiMemImageFormat &Format,
280  ContextImplPtr Context);
281 
282  bool MIsArrayImage = false;
283  range<Dimensions> MRange;
284  image_channel_order MOrder;
285  image_channel_type MType;
286  uint8_t MNumChannels = 0; // Maximum Value - 4
287  size_t MElementSize = 0; // Maximum Value - 16
288  size_t MRowPitch = 0;
289  size_t MSlicePitch = 0;
290 };
291 } // namespace detail
292 } // namespace sycl
293 } // __SYCL_INLINE_NAMESPACE(cl)
_pi_image_desc::num_samples
pi_uint32 num_samples
Definition: pi.h:945
cl::sycl::detail::getImageElementSize
uint8_t getImageElementSize(uint8_t NumChannels, image_channel_type Type)
Definition: image_impl.cpp:71
cl::sycl::detail::image_impl::image_impl
image_impl(image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:103
cl::sycl::detail::image_impl::image_impl
image_impl(image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, const EnableIfPitchT< B > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:111
property_list.hpp
_pi_mem_type
_pi_mem_type
Definition: pi.h:449
_pi_image_desc::image_array_size
size_t image_array_size
Definition: pi.h:941
cl::sycl::detail::aligned_allocator
Definition: aligned_allocator.hpp:23
PI_MEM_TYPE_IMAGE1D
@ PI_MEM_TYPE_IMAGE1D
Definition: pi.h:454
cl::sycl::detail::ContextImplPtr
std::shared_ptr< detail::context_impl > ContextImplPtr
Definition: memory_manager.hpp:32
cl::sycl::detail::image_impl::getType
MemObjType getType() const override
Definition: image_impl.hpp:214
_pi_image_format::image_channel_data_type
pi_image_channel_type image_channel_data_type
Definition: pi.h:933
cl::sycl::event
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Definition: event.hpp:31
cl::sycl::detail::image_impl::getSlicePitch
size_t getSlicePitch() const
Definition: image_impl.hpp:227
stl.hpp
cl::sycl::detail::type_list
Definition: type_list.hpp:23
_pi_image_format::image_channel_order
pi_image_channel_order image_channel_order
Definition: pi.h:932
device.hpp
_pi_image_desc::image_type
pi_mem_type image_type
Definition: pi.h:937
cl::sycl::detail::image_impl::getChannelOrder
image_channel_order getChannelOrder() const
Definition: image_impl.hpp:221
cl::sycl::detail::is_contained
Definition: type_list.hpp:54
cl::sycl::detail::image_impl
Definition: image_impl.hpp:70
event.hpp
cl::sycl::detail::image_impl::image_impl
image_impl(std::shared_ptr< void > &HData, image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:157
sycl
Definition: invoke_simd.hpp:68
cl::sycl::property_list
Objects of the property_list class are containers for the SYCL properties.
Definition: property_list.hpp:26
cl::sycl::detail::image_impl::~image_impl
~image_impl()
Definition: image_impl.hpp:229
_pi_image_desc::image_height
size_t image_height
Definition: pi.h:939
cl::sycl::detail::image_impl::image_impl
image_impl(void *HData, image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:119
_pi_image_desc::image_slice_pitch
size_t image_slice_pitch
Definition: pi.h:943
cl::sycl::detail::image_impl::getChannelType
image_channel_type getChannelType() const
Definition: image_impl.hpp:223
cl::sycl::range
Defines the iteration domain of either a single work-group in a parallel dispatch,...
Definition: buffer.hpp:24
cl::sycl::detail::SYCLMemObjI::MemObjType
MemObjType
Definition: sycl_mem_obj_i.hpp:32
cl::sycl::detail::image_impl::get_range
range< Dimensions > get_range() const
Definition: image_impl.hpp:189
cl::sycl::detail::getImageNumberChannels
uint8_t getImageNumberChannels(image_channel_order Order)
Definition: image_impl.cpp:44
export.hpp
_pi_image_desc::image_depth
size_t image_depth
Definition: pi.h:940
PI_MEM_TYPE_IMAGE2D
@ PI_MEM_TYPE_IMAGE2D
Definition: pi.h:451
cl::sycl::detail::image_impl::getElementSize
size_t getElementSize() const
Definition: image_impl.hpp:219
generic_type_traits.hpp
range.hpp
_pi_image_channel_order
_pi_image_channel_order
Definition: pi.h:474
PI_MEM_TYPE_IMAGE1D_ARRAY
@ PI_MEM_TYPE_IMAGE1D_ARRAY
Definition: pi.h:455
cl::sycl::detail::image_impl::get_count
size_t get_count() const
Definition: image_impl.hpp:208
cl::sycl::detail::is_validImageDataT
typename detail::is_contained< T, type_list< cl_int4, cl_uint4, cl_float4, cl_half4 > >::type is_validImageDataT
Definition: image_impl.hpp:63
cl::sycl::accessor
Buffer accessor.
Definition: accessor.hpp:223
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::detail::EnableIfImgAccDataT
typename detail::enable_if_t< is_validImageDataT< DataT >::value, DataT > EnableIfImgAccDataT
Definition: image_impl.hpp:67
_pi_image_desc::buffer
pi_mem buffer
Definition: pi.h:946
aligned_allocator.hpp
cl::sycl::detail::image_impl::image_impl
image_impl(const void *HData, image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:131
cl::sycl::detail::getNextPowerOfTwo
constexpr size_t getNextPowerOfTwo(size_t Var)
Definition: common.hpp:324
cl::sycl::handler
Command group handler class.
Definition: handler.hpp:361
cl::sycl::image
Defines a shared image data.
Definition: image_impl.hpp:29
_pi_image_format
Definition: pi.h:931
cl::sycl::detail::image_impl::get_pitch
detail::enable_if_t< B, range< 2 > > get_pitch() const
Definition: image_impl.hpp:202
cl::sycl::detail::image_impl::image_impl
image_impl(void *HData, image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, const EnableIfPitchT< B > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:144
cl::sycl::detail::image_impl::getRowPitch
size_t getRowPitch() const
Definition: image_impl.hpp:225
_pi_image_desc::image_width
size_t image_width
Definition: pi.h:938
_pi_image_channel_type
_pi_image_channel_type
Definition: pi.h:492
cl::sycl::detail::image_impl::get_pitch
detail::enable_if_t< B, range< 1 > > get_pitch() const
Definition: image_impl.hpp:194
_pi_image_desc::image_row_pitch
size_t image_row_pitch
Definition: pi.h:942
_pi_image_desc
Definition: pi.h:936
cl::sycl::detail::image_impl::size
size_t size() const noexcept
Definition: image_impl.hpp:209
_pi_event
PI Event mapping to CUevent.
Definition: pi_cuda.hpp:458
cl::sycl::detail::convertChannelType
image_channel_type convertChannelType(RT::PiMemImageChannelType Type)
Definition: image_impl.cpp:218
PI_MEM_TYPE_IMAGE2D_ARRAY
@ PI_MEM_TYPE_IMAGE2D_ARRAY
Definition: pi.h:453
cl::sycl::detail::image_impl::image_impl
image_impl(std::shared_ptr< void > &HData, image_channel_order Order, image_channel_type Type, const range< Dimensions > &ImageRange, const EnableIfPitchT< B > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, const property_list &PropList={})
Definition: image_impl.hpp:171
cl::sycl::context
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:35
cl::sycl::detail::convertChannelOrder
image_channel_order convertChannelOrder(RT::PiMemImageChannelOrder Order)
Definition: image_impl.cpp:144
common.hpp
cl::sycl::image_channel_type
image_channel_type
Definition: image.hpp:41
cl::sycl::detail::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: stl_type_traits.hpp:24
cl::sycl::detail::SYCLMemObjT
Definition: sycl_mem_obj_t.hpp:43
_pi_image_desc::num_mip_levels
pi_uint32 num_mip_levels
Definition: pi.h:944
cl::sycl::Dimensions
Dimensions
Definition: backend.hpp:138
PI_MEM_TYPE_IMAGE3D
@ PI_MEM_TYPE_IMAGE3D
Definition: pi.h:452
sycl_mem_obj_t.hpp
cl::sycl::image_channel_order
image_channel_order
Definition: image.hpp:23
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12