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 
13 #include <sycl/detail/common.hpp>
14 #include <sycl/detail/export.hpp>
16 #include <sycl/device.hpp>
17 #include <sycl/event.hpp>
18 #include <sycl/image.hpp>
19 #include <sycl/property_list.hpp>
20 #include <sycl/range.hpp>
21 #include <sycl/stl.hpp>
22 
23 namespace sycl {
25 
26 // forward declarations
27 enum class image_channel_order : unsigned int;
28 enum class image_channel_type : unsigned int;
29 
30 template <int Dimensions, typename AllocatorT> class image;
31 template <typename DataT, int Dimensions, access::mode AccessMode,
32  access::target AccessTarget, access::placeholder IsPlaceholder,
33  typename property_listT>
34 class accessor;
35 class handler;
36 
37 namespace detail {
38 
39 // utility functions and typedefs for image_impl
41 
42 // utility function: Returns the Number of Channels for a given Order.
43 __SYCL_EXPORT uint8_t getImageNumberChannels(image_channel_order Order);
44 
45 // utility function: Returns the number of bytes per image element
46 __SYCL_EXPORT uint8_t getImageElementSize(uint8_t NumChannels,
47  image_channel_type Type);
48 
49 __SYCL_EXPORT RT::PiMemImageChannelOrder
51 
52 __SYCL_EXPORT image_channel_order
54 
55 __SYCL_EXPORT RT::PiMemImageChannelType
57 
58 __SYCL_EXPORT image_channel_type
60 
61 class __SYCL_EXPORT image_impl final : public SYCLMemObjT {
62  using BaseT = SYCLMemObjT;
63  using typename BaseT::MemObjType;
64 
65 private:
66  void setPitches() {
67  size_t WHD[3] = {1, 1, 1}; // Width, Height, Depth.
68  for (int I = 0; I < MDimensions; I++)
69  WHD[I] = MRange[I];
70 
71  MRowPitch = MElementSize * WHD[0];
72  MSlicePitch = MRowPitch * WHD[1];
73  BaseT::MSizeInBytes = MSlicePitch * WHD[2];
74  }
75 
76  void setPitches(const range<2> &Pitch) {
77  MRowPitch = Pitch[0];
78  MSlicePitch =
79  (MDimensions == 3) ? Pitch[1] : MRowPitch; // Dimensions will be 2/3.
80  // NumSlices is depth when dim==3, and height when dim==2.
81  size_t NumSlices =
82  (MDimensions == 3) ? MRange[2] : MRange[1]; // Dimensions will be 2/3.
83 
84  BaseT::MSizeInBytes = MSlicePitch * NumSlices;
85  }
86 
87 public:
89  const range<3> &ImageRange,
90  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
91  const property_list &PropList = {})
92  : image_impl((void *)nullptr, Order, Type, ImageRange,
93  std::move(Allocator), Dimensions, PropList) {}
94 
96  const range<3> &ImageRange, const range<2> &Pitch,
97  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
98  const property_list &PropList = {})
99  : image_impl((void *)nullptr, Order, Type, ImageRange, Pitch,
100  std::move(Allocator), Dimensions, PropList) {}
101 
103  const range<3> &ImageRange,
104  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
105  const property_list &PropList = {})
106  : BaseT(PropList, std::move(Allocator)), MDimensions(Dimensions),
107  MRange(ImageRange), MOrder(Order), MType(Type),
108  MNumChannels(getImageNumberChannels(MOrder)),
109  MElementSize(getImageElementSize(MNumChannels, MType)) {
110  setPitches();
111  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
112  }
113 
114  image_impl(const void *HData, image_channel_order Order,
115  image_channel_type Type, const range<3> &ImageRange,
116  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
117  const property_list &PropList = {})
118  : BaseT(PropList, std::move(Allocator)), MDimensions(Dimensions),
119  MRange(ImageRange), MOrder(Order), MType(Type),
120  MNumChannels(getImageNumberChannels(MOrder)),
121  MElementSize(getImageElementSize(MNumChannels, MType)) {
122  setPitches();
123  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
124  }
125 
127  const range<3> &ImageRange, const range<2> &Pitch,
128  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
129  const property_list &PropList = {})
130  : BaseT(PropList, std::move(Allocator)), MDimensions(Dimensions),
131  MRange(ImageRange), MOrder(Order), MType(Type),
132  MNumChannels(getImageNumberChannels(MOrder)),
133  MElementSize(getImageElementSize(MNumChannels, MType)) {
134  setPitches(Pitch);
135  BaseT::handleHostData(HData, detail::getNextPowerOfTwo(MElementSize));
136  }
137 
138  image_impl(const std::shared_ptr<const void> &HData,
140  const range<3> &ImageRange,
141  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
142  const property_list &PropList, bool IsConstPtr)
143  : BaseT(PropList, std::move(Allocator)), MDimensions(Dimensions),
144  MRange(ImageRange), MOrder(Order), MType(Type),
145  MNumChannels(getImageNumberChannels(MOrder)),
146  MElementSize(getImageElementSize(MNumChannels, MType)) {
147  setPitches();
148  BaseT::handleHostData(std::const_pointer_cast<void>(HData),
149  detail::getNextPowerOfTwo(MElementSize), IsConstPtr);
150  }
151 
152  image_impl(const std::shared_ptr<const void> &HData,
154  const range<3> &ImageRange, const range<2> &Pitch,
155  std::unique_ptr<SYCLMemObjAllocator> Allocator, uint8_t Dimensions,
156  const property_list &PropList, bool IsConstPtr)
157  : BaseT(PropList, std::move(Allocator)), MDimensions(Dimensions),
158  MRange(ImageRange), MOrder(Order), MType(Type),
159  MNumChannels(getImageNumberChannels(MOrder)),
160  MElementSize(getImageElementSize(MNumChannels, MType)) {
161  setPitches(Pitch);
162  BaseT::handleHostData(std::const_pointer_cast<void>(HData),
163  detail::getNextPowerOfTwo(MElementSize), IsConstPtr);
164  }
165 
166  image_impl(cl_mem MemObject, const context &SyclContext, event AvailableEvent,
167  std::unique_ptr<SYCLMemObjAllocator> Allocator,
168  uint8_t Dimensions);
169 
170  // Return a range object representing the size of the image in terms of the
171  // number of elements in each dimension as passed to the constructor
172  range<3> get_range() const { return MRange; }
173 
174  // Return a range object representing the pitch of the image in bytes.
175  range<2> get_pitch() const { return {MRowPitch, MSlicePitch}; }
176 
177  // Returns the total number of elements in the image
178  size_t get_count() const { return size(); }
179  size_t size() const noexcept { return MRange.size(); }
180 
181  void *allocateMem(ContextImplPtr Context, bool InitFromUserData,
182  void *HostPtr, RT::PiEvent &OutEventToWait) override;
183 
184  MemObjType getType() const override { return MemObjType::Image; }
185 
186  // This utility api is currently used by accessor to get the element size of
187  // the image. Element size is dependent on num of channels and channel type.
188  // This information is not accessible from the image using any public API.
189  size_t getElementSize() const { return MElementSize; };
190 
191  image_channel_order getChannelOrder() const { return MOrder; }
192 
193  image_channel_type getChannelType() const { return MType; }
194 
195  size_t getRowPitch() const { return MRowPitch; }
196 
197  size_t getSlicePitch() const { return MSlicePitch; }
198 
200  try {
201  BaseT::updateHostMemory();
202  } catch (...) {
203  }
204  }
205 
206 private:
207  std::vector<device> getDevices(const ContextImplPtr Context);
208 
209  RT::PiMemObjectType getImageType() {
210  if (MDimensions == 1)
211  return (MIsArrayImage ? PI_MEM_TYPE_IMAGE1D_ARRAY : PI_MEM_TYPE_IMAGE1D);
212  if (MDimensions == 2)
213  return (MIsArrayImage ? PI_MEM_TYPE_IMAGE2D_ARRAY : PI_MEM_TYPE_IMAGE2D);
214  return PI_MEM_TYPE_IMAGE3D;
215  }
216 
217  RT::PiMemImageDesc getImageDesc(bool InitFromHostPtr) {
218  RT::PiMemImageDesc Desc;
219  Desc.image_type = getImageType();
220 
221  // MRange<> is [width], [width,height], or [width,height,depth] (which
222  // is different than MAccessRange, etc in bufffers)
223  constexpr int XTermPos = 0, YTermPos = 1, ZTermPos = 2;
224  Desc.image_width = MRange[XTermPos];
225  Desc.image_height = MDimensions > 1 ? MRange[YTermPos] : 1;
226  Desc.image_depth = MDimensions > 2 ? MRange[ZTermPos] : 1;
227 
228  // TODO handle cases with IMAGE1D_ARRAY and IMAGE2D_ARRAY
229  Desc.image_array_size = 0;
230  // Pitches must be 0 if host ptr is not provided.
231  Desc.image_row_pitch = InitFromHostPtr ? MRowPitch : 0;
232  Desc.image_slice_pitch = InitFromHostPtr ? MSlicePitch : 0;
233  Desc.num_mip_levels = 0;
234  Desc.num_samples = 0;
235  Desc.buffer = nullptr;
236  return Desc;
237  }
238 
239  bool checkImageDesc(const RT::PiMemImageDesc &Desc, ContextImplPtr Context,
240  void *UserPtr);
241 
242  RT::PiMemImageFormat getImageFormat() {
243  RT::PiMemImageFormat Format;
245  Format.image_channel_data_type = detail::convertChannelType(MType);
246  return Format;
247  }
248 
249  bool checkImageFormat(const RT::PiMemImageFormat &Format,
250  ContextImplPtr Context);
251 
252  uint8_t MDimensions = 0;
253  bool MIsArrayImage = false;
254  range<3> MRange;
255  image_channel_order MOrder;
256  image_channel_type MType;
257  uint8_t MNumChannels = 0; // Maximum Value - 4
258  size_t MElementSize = 0; // Maximum Value - 16
259  size_t MRowPitch = 0;
260  size_t MSlicePitch = 0;
261 };
262 } // namespace detail
263 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
264 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:41
image_impl(image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, const range< 2 > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList={})
Definition: image_impl.hpp:95
image_impl(const std::shared_ptr< const void > &HData, image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList, bool IsConstPtr)
Definition: image_impl.hpp:138
image_channel_type getChannelType() const
Definition: image_impl.hpp:193
range< 3 > get_range() const
Definition: image_impl.hpp:172
image_impl(void *HData, image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList={})
Definition: image_impl.hpp:102
MemObjType getType() const override
Definition: image_impl.hpp:184
image_impl(const std::shared_ptr< const void > &HData, image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, const range< 2 > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList, bool IsConstPtr)
Definition: image_impl.hpp:152
range< 2 > get_pitch() const
Definition: image_impl.hpp:175
size_t size() const noexcept
Definition: image_impl.hpp:179
image_impl(void *HData, image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, const range< 2 > &Pitch, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList={})
Definition: image_impl.hpp:126
image_impl(const void *HData, image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList={})
Definition: image_impl.hpp:114
image_impl(image_channel_order Order, image_channel_type Type, const range< 3 > &ImageRange, std::unique_ptr< SYCLMemObjAllocator > Allocator, uint8_t Dimensions, const property_list &PropList={})
Definition: image_impl.hpp:88
image_channel_order getChannelOrder() const
Definition: image_impl.hpp:191
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Definition: event.hpp:40
Objects of the property_list class are containers for the SYCL properties.
Defines the iteration domain of either a single work-group in a parallel dispatch,...
Definition: range.hpp:24
#define __SYCL_INLINE_VER_NAMESPACE(X)
::pi_event PiEvent
Definition: pi.hpp:121
::pi_image_channel_type PiMemImageChannelType
Definition: pi.hpp:132
::pi_image_channel_order PiMemImageChannelOrder
Definition: pi.hpp:131
::pi_image_desc PiMemImageDesc
Definition: pi.hpp:128
::pi_mem_type PiMemObjectType
Definition: pi.hpp:130
::pi_image_format PiMemImageFormat
Definition: pi.hpp:127
RT::PiMemImageChannelOrder convertChannelOrder(image_channel_order Order)
Definition: image_impl.cpp:106
uint8_t getImageElementSize(uint8_t NumChannels, image_channel_type Type)
Definition: image_impl.cpp:70
std::shared_ptr< sycl::detail::context_impl > ContextImplPtr
Definition: event_impl.hpp:30
constexpr size_t getNextPowerOfTwo(size_t Var)
Definition: common.hpp:375
RT::PiMemImageChannelType convertChannelType(image_channel_type Type)
Definition: image_impl.cpp:180
uint8_t getImageNumberChannels(image_channel_order Order)
Definition: image_impl.cpp:43
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:2782
image_channel_order
Definition: image.hpp:27
image_channel_type
Definition: image.hpp:45
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
@ PI_MEM_TYPE_IMAGE1D
Definition: pi.h:424
@ PI_MEM_TYPE_IMAGE1D_ARRAY
Definition: pi.h:425
@ PI_MEM_TYPE_IMAGE2D
Definition: pi.h:421
@ PI_MEM_TYPE_IMAGE2D_ARRAY
Definition: pi.h:423
@ PI_MEM_TYPE_IMAGE3D
Definition: pi.h:422
pi_mem_type image_type
Definition: pi.h:928
pi_image_channel_order image_channel_order
Definition: pi.h:923