DPC++ Runtime
Runtime libraries for oneAPI DPC++
accessor.hpp
Go to the documentation of this file.
1 //==------------ accessor.hpp - SYCL standard header file ------------------==//
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 
11 #include <sycl/access/access.hpp> // for target, mode
12 #include <sycl/aliases.hpp> // for float4, int4
13 #include <sycl/aspects.hpp> // for aspect
14 #include <sycl/atomic.hpp> // for atomic
15 #include <sycl/buffer.hpp> // for range
16 #include <sycl/detail/accessor_iterator.hpp> // for accessor_iterator
17 #include <sycl/detail/common.hpp> // for code_location
18 #include <sycl/detail/defines.hpp> // for __SYCL_SPECIAL...
19 #include <sycl/detail/defines_elementary.hpp> // for __SYCL2020_DEP...
20 #include <sycl/detail/export.hpp> // for __SYCL_EXPORT
21 #include <sycl/detail/generic_type_traits.hpp> // for is_genint, Try...
22 #include <sycl/detail/handler_proxy.hpp> // for associateWithH...
23 #include <sycl/detail/helpers.hpp> // for loop
24 #include <sycl/detail/owner_less_base.hpp> // for OwnerLessBase
25 #include <sycl/detail/property_helper.hpp> // for PropWithDataKind
26 #include <sycl/detail/property_list_base.hpp> // for PropertyListBase
27 #include <sycl/detail/type_list.hpp> // for is_contained
28 #include <sycl/detail/type_traits.hpp> // for const_if_const_AS
29 #include <sycl/exception.hpp> // for make_error_code
30 #include <sycl/ext/oneapi/accessor_property_list.hpp> // for accessor_prope...
31 #include <sycl/ext/oneapi/weak_object_base.hpp> // for getSyclWeakObj...
32 #include <sycl/id.hpp> // for id
33 #include <sycl/multi_ptr.hpp> // for multi_ptr
34 #include <sycl/pointers.hpp> // for local_ptr, glo...
35 #include <sycl/properties/accessor_properties.hpp> // for buffer_location
36 #include <sycl/properties/buffer_properties.hpp> // for buffer, buffer...
37 #include <sycl/property_list.hpp> // for property_list
38 #include <sycl/range.hpp> // for range
39 #include <sycl/sampler.hpp> // for addressing_mode
40 #include <ur_api.h> // for UR_RESULT_ERRO...
41 
42 #include <cstddef> // for size_t
43 #include <functional> // for hash
44 #include <iterator> // for reverse_iterator
45 #include <limits> // for numeric_limits
46 #include <memory> // for shared_ptr
47 #include <optional> // for nullopt, optional
48 #include <stdint.h> // for uint32_t
49 #include <tuple> // for _Swallow_assign
50 #include <type_traits> // for enable_if_t
51 #include <typeinfo> // for type_info
52 #include <variant> // for hash
53 
113 // +------------------+ +-----------------+ +-----------------------+
114 // | | | | | |
115 // | AccessorBaseHost | | accessor_common | | LocalAccessorBaseHost |
116 // | | | | | |
117 // +------------------+ +-----+-----------+ +--------+--------------+
118 // | | | | |
119 // | +-----------+ +----+ +---------+ +------+
120 // | | | | |
121 // v v v v v
122 // +----------------+ +-----------------+ +-------------+
123 // | | | accessor(1) | | accessor(3) |
124 // | image_accessor | +-----------------| +-------------+
125 // | | | for targets: | | for target: |
126 // +---+---+---+----+ | | | |
127 // | | | | host_buffer | | local |
128 // | | | | global_buffer | +-------------+
129 // | | | | constant_buffer |
130 // | | | +-----------------+
131 // | | |
132 // | | +------------------------------------+
133 // | | |
134 // | +----------------------+ |
135 // v v v
136 // +-----------------+ +--------------+ +-------------+
137 // | acessor(2) | | accessor(4) | | accessor(5) |
138 // +-----------------+ +--------------+ +-------------+
139 // | for targets: | | for targets: | | for target: |
140 // | | | | | |
141 // | host_image | | image | | image_array |
142 // +-----------------+ +--------------+ +-------------+
143 //
168 //
169 // +-----------------+
170 // | |
171 // | accessor_common |
172 // | |
173 // +-----+-------+---+
174 // | |
175 // +----+ +-----+
176 // | |
177 // v v
178 // +----------------+ +-----------------+ +-------------+
179 // | | | accessor(1) | | accessor(3) |
180 // | image_accessor | +-----------------| +-------------+
181 // | | | for targets: | | for target: |
182 // +---+---+---+----+ | | | |
183 // | | | | host_buffer | | local |
184 // | | | | global_buffer | +-------------+
185 // | | | | constant_buffer |
186 // | | | +-----------------+
187 // | | | |
188 // | | | v
189 // | | | +-----------------+
190 // | | | | |
191 // | | | | host_accessor |
192 // | | | | |
193 // | | | +-----------------+
194 // | | |
195 // | | +------------------------------------+
196 // | | |
197 // | +----------------------+ |
198 // v v v
199 // +-----------------+ +--------------+ +-------------+
200 // | acessor(2) | | accessor(4) | | accessor(5) |
201 // +-----------------+ +--------------+ +-------------+
202 // | for targets: | | for targets: | | for target: |
203 // | | | | | |
204 // | host_image | | image | | image_array |
205 // +-----------------+ +--------------+ +-------------+
206 //
224 
225 namespace sycl {
226 inline namespace _V1 {
227 class stream;
228 namespace ext::intel::esimd::detail {
229 // Forward declare a "back-door" access class to support ESIMD.
230 class AccessorPrivateProxy;
231 } // namespace ext::intel::esimd::detail
232 
233 template <typename DataT, int Dimensions = 1,
235  access::target AccessTarget = access::target::device,
237  typename PropertyListT = ext::oneapi::accessor_property_list<>>
238 class accessor;
239 
240 namespace detail {
241 
242 // A helper structure which is shared between buffer accessor and accessor_impl
243 // TODO: Unify with AccessorImplDevice?
244 struct AccHostDataT {
245  AccHostDataT(const sycl::id<3> &Offset, const sycl::range<3> &Range,
246  const sycl::range<3> &MemoryRange, void *Data = nullptr)
247  : MOffset(Offset), MAccessRange(Range), MMemoryRange(MemoryRange),
248  MData(Data) {}
249 
253  void *MData = nullptr;
254  void *Reserved = nullptr;
255 };
256 
257 void __SYCL_EXPORT constructorNotification(void *BufferObj, void *AccessorObj,
258  access::target Target,
260  const code_location &CodeLoc);
261 
262 template <typename T>
263 using IsPropertyListT = typename std::is_base_of<PropertyListBase, T>;
264 
265 template <typename T>
267  typename std::is_same<ext::oneapi::accessor_property_list<>, T>;
268 
269 template <typename T> struct IsCxPropertyList {
270  constexpr static bool value = false;
271 };
272 
273 template <typename... Props>
274 struct IsCxPropertyList<ext::oneapi::accessor_property_list<Props...>> {
275  constexpr static bool value = true;
276 };
277 
278 template <> struct IsCxPropertyList<ext::oneapi::accessor_property_list<>> {
279  constexpr static bool value = false;
280 };
281 
282 // Zero-dimensional accessors references at-most a single element, so the range
283 // is either 0 if the associated buffer is empty or 1 otherwise.
284 template <typename BufferT>
286  return std::min(Buffer.size(), size_t{1});
287 }
288 
289 __SYCL_EXPORT device getDeviceFromHandler(handler &CommandGroupHandlerRef);
290 
291 template <typename DataT, int Dimensions, access::mode AccessMode,
293  typename PropertyListT = ext::oneapi::accessor_property_list<>>
295 protected:
297 
298  constexpr static bool IsHostBuf = AccessTarget == access::target::host_buffer;
299  constexpr static bool IsHostTask = AccessTarget == access::target::host_task;
300  // SYCL2020 4.7.6.9.4.3
301  // IsPlaceHolder template parameter has no bearing on whether the accessor
302  // instance is a placeholder. This is determined solely by the constructor.
303  // The rule seems to be: if the constructor receives a CommandGroupHandler
304  // it is NOT a placeholder. Otherwise, it is a placeholder.
305  // However, according to 4.7.6.9.4.6. accessor specialization with
306  // target::host_buffer is never a placeholder. So, if the constructor
307  // used receives a CommandGroupHandler, the accessor will never be a
308  // placeholder. If it doesn't, but IsHostBuf is true, it won't be a
309  // placeholder either. Otherwise, the accessor is a placeholder.
310  constexpr static bool IsPlaceH = !IsHostBuf;
311 
312  // TODO: SYCL 2020 deprecates four of the target enum values
313  // and replaces them with 2 (device and host_task). May want
314  // to change these constexpr.
315  constexpr static bool IsGlobalBuf =
316  AccessTarget == access::target::global_buffer;
317 
318  constexpr static bool IsConstantBuf =
319  AccessTarget == access::target::constant_buffer;
320 
321  constexpr static bool IsAccessAnyWrite =
326 
327  constexpr static bool IsAccessReadOnly = AccessMode == access::mode::read;
328  static constexpr bool IsConst = std::is_const_v<DataT>;
329 
330  constexpr static bool IsAccessReadWrite =
332 
333  constexpr static bool IsAccessAtomic = AccessMode == access::mode::atomic;
334 
336  using ConstRefType = const DataT &;
338 
339  // The class which allows to access value of N dimensional accessor using N
340  // subscript operators, e.g. accessor[2][2][3]
341  template <int SubDims,
342  typename AccType =
343  accessor<DataT, Dimensions, AccessMode, AccessTarget,
344  IsPlaceholder, PropertyListT>>
346  static constexpr int Dims = Dimensions;
347 
348  mutable id<Dims> MIDs;
349  AccType MAccessor;
350 
351  public:
353  : MIDs(IDs), MAccessor(Accessor) {}
354 
355  // Only accessor class is supposed to use this c'tor for the first
356  // operator[].
357  AccessorSubscript(AccType Accessor, size_t Index) : MAccessor(Accessor) {
358  MIDs[0] = Index;
359  }
360 
361  template <int CurDims = SubDims, typename = std::enable_if_t<(CurDims > 1)>>
362  auto operator[](size_t Index) {
363  MIDs[Dims - CurDims] = Index;
364  return AccessorSubscript<CurDims - 1, AccType>(MAccessor, MIDs);
365  }
366 
367  template <int CurDims = SubDims,
368  typename = std::enable_if_t<CurDims == 1 && (IsAccessReadOnly ||
370  typename AccType::reference operator[](size_t Index) const {
371  MIDs[Dims - CurDims] = Index;
372  return MAccessor[MIDs];
373  }
374 
375  template <int CurDims = SubDims>
376  typename std::enable_if_t<CurDims == 1 && IsAccessAtomic, atomic<DataT, AS>>
377  operator[](size_t Index) const {
378  MIDs[Dims - CurDims] = Index;
379  return MAccessor[MIDs];
380  }
381  };
382 };
383 
384 template <typename DataT> constexpr access::mode accessModeFromConstness() {
385  if constexpr (std::is_const_v<DataT>)
386  return access::mode::read;
387  else
389 }
390 
391 template <typename MayBeTag1, typename MayBeTag2>
393  // property_list = {} is not properly detected by deduction guide,
394  // when parameter is passed without curly braces: access(buffer, no_init)
395  // thus simplest approach is to check 2 last arguments for being a tag
396  if constexpr (std::is_same_v<MayBeTag1, mode_tag_t<access::mode::read>> ||
397  std::is_same_v<MayBeTag2, mode_tag_t<access::mode::read>>) {
398  return access::mode::read;
399  }
400 
401  if constexpr (std::is_same_v<MayBeTag1, mode_tag_t<access::mode::write>> ||
402  std::is_same_v<MayBeTag2, mode_tag_t<access::mode::write>>) {
403  return access::mode::write;
404  }
405 
406  if constexpr (std::is_same_v<
407  MayBeTag1,
409  access::target::constant_buffer>> ||
410  std::is_same_v<
411  MayBeTag2,
413  access::target::constant_buffer>>) {
414  return access::mode::read;
415  }
416 
417  if constexpr (std::is_same_v<MayBeTag1,
420  std::is_same_v<MayBeTag2,
423  return access::mode::read;
424  }
425 
426  if constexpr (std::is_same_v<MayBeTag1,
429  std::is_same_v<MayBeTag2,
432  return access::mode::write;
433  }
434 
436 }
437 
438 template <typename MayBeTag1, typename MayBeTag2>
440  if constexpr (std::is_same_v<
441  MayBeTag1,
443  access::target::constant_buffer>> ||
444  std::is_same_v<
445  MayBeTag2,
447  access::target::constant_buffer>>) {
448  return access::target::constant_buffer;
449  }
450 
451  if constexpr (
452  std::is_same_v<MayBeTag1, mode_target_tag_t<access::mode::read,
454  std::is_same_v<MayBeTag2, mode_target_tag_t<access::mode::read,
456  std::is_same_v<MayBeTag1, mode_target_tag_t<access::mode::write,
458  std::is_same_v<MayBeTag2, mode_target_tag_t<access::mode::write,
460  std::is_same_v<MayBeTag1, mode_target_tag_t<access::mode::read_write,
462  std::is_same_v<MayBeTag2, mode_target_tag_t<access::mode::read_write,
465  }
466 
467  return defaultTarget;
468 }
469 
470 template <int Dims> class LocalAccessorBaseDevice {
471 public:
473  : AccessRange(Size),
474  MemRange(InitializedVal<Dims, range>::template get<0>()) {}
475  // TODO: Actually we need only one field here, but currently compiler requires
476  // all of them.
480 
481  bool operator==(const LocalAccessorBaseDevice &Rhs) const {
482  return (AccessRange == Rhs.AccessRange);
483  }
484 };
485 
486 // The class describes a requirement to access a SYCL memory object such as
487 // sycl::buffer and sycl::image. For example, each accessor used in a kernel,
488 // except one with access target "local", adds such requirement for the command
489 // group.
490 
491 template <int Dims> class AccessorImplDevice {
492 public:
493  AccessorImplDevice() = default;
495  range<Dims> MemoryRange)
496  : Offset(Offset), AccessRange(AccessRange), MemRange(MemoryRange) {}
497 
501 
502  bool operator==(const AccessorImplDevice &Rhs) const {
503  return (Offset == Rhs.Offset && AccessRange == Rhs.AccessRange &&
504  MemRange == Rhs.MemRange);
505  }
506 };
507 
508 class AccessorImplHost;
509 
510 void __SYCL_EXPORT addHostAccessorAndWait(AccessorImplHost *Req);
511 
512 class SYCLMemObjI;
513 
514 using AccessorImplPtr = std::shared_ptr<AccessorImplHost>;
515 
516 class __SYCL_EXPORT AccessorBaseHost {
517 protected:
518  AccessorBaseHost(const AccessorImplPtr &Impl) : impl{Impl} {}
519 
520 public:
521  AccessorBaseHost(id<3> Offset, range<3> AccessRange, range<3> MemoryRange,
522  access::mode AccessMode, void *SYCLMemObject, int Dims,
523  int ElemSize, size_t OffsetInBytes = 0,
524  bool IsSubBuffer = false,
525  const property_list &PropertyList = {});
526 
527  AccessorBaseHost(id<3> Offset, range<3> AccessRange, range<3> MemoryRange,
528  access::mode AccessMode, void *SYCLMemObject, int Dims,
529  int ElemSize, bool IsPlaceH, size_t OffsetInBytes = 0,
530  bool IsSubBuffer = false,
531  const property_list &PropertyList = {});
532 
533 public:
534  id<3> &getOffset();
535  range<3> &getAccessRange();
536  range<3> &getMemoryRange();
537  void *getPtr() noexcept;
538  unsigned int getElemSize() const;
539 
540  const id<3> &getOffset() const;
541  const range<3> &getAccessRange() const;
542  const range<3> &getMemoryRange() const;
543  void *getPtr() const noexcept;
544  bool isPlaceholder() const;
545  bool isMemoryObjectUsedByGraph() const;
546 
547  detail::AccHostDataT &getAccData();
548 
549  const property_list &getPropList() const;
550 
551  void *getMemoryObject() const;
552 
553  template <class Obj>
554  friend const decltype(Obj::impl) &getSyclObjImpl(const Obj &SyclObject);
555 
556  template <class T>
557  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
558 
559  template <typename, int, access::mode, access::target, access::placeholder,
560  typename>
561  friend class accessor;
562 
564 
565 private:
566  friend class sycl::ext::intel::esimd::detail::AccessorPrivateProxy;
567 };
568 
571 
572 class __SYCL_EXPORT LocalAccessorBaseHost {
573 protected:
574  LocalAccessorBaseHost(const LocalAccessorImplPtr &Impl) : impl{Impl} {}
575 
576 public:
577  LocalAccessorBaseHost(sycl::range<3> Size, int Dims, int ElemSize,
578  const property_list &PropertyList = {});
579  sycl::range<3> &getSize();
580  const sycl::range<3> &getSize() const;
581  void *getPtr();
582  void *getPtr() const;
583  int getNumOfDims();
584  int getElementSize();
585  const property_list &getPropList() const;
586 
587 protected:
588  template <class Obj>
589  friend const decltype(Obj::impl) &
590  detail::getSyclObjImpl(const Obj &SyclObject);
591 
592  template <class T>
593  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
594 
596 };
597 } // namespace detail
598 
604 template <typename DataT, int Dimensions, access::mode AccessMode,
606  typename PropertyListT>
608 #ifndef __SYCL_DEVICE_ONLY__
610 #endif
611  public detail::accessor_common<DataT, Dimensions, AccessMode, AccessTarget,
612  IsPlaceholder, PropertyListT>,
613  public detail::OwnerLessBase<
614  accessor<DataT, Dimensions, AccessMode, AccessTarget, IsPlaceholder,
615  PropertyListT>> {
616 protected:
617  static_assert((AccessTarget == access::target::global_buffer ||
618  AccessTarget == access::target::constant_buffer ||
619  AccessTarget == access::target::host_buffer ||
620  AccessTarget == access::target::host_task),
621  "Expected buffer type");
622 
623  static_assert((AccessTarget == access::target::global_buffer ||
624  AccessTarget == access::target::host_buffer ||
625  AccessTarget == access::target::host_task) ||
626  (AccessTarget == access::target::constant_buffer &&
628  "Access mode can be only read for constant buffers");
629 
631  "PropertyListT must be accessor_property_list");
632 
633  using AccessorCommonT =
634  detail::accessor_common<DataT, Dimensions, AccessMode, AccessTarget,
635  IsPlaceholder, PropertyListT>;
636 
637  constexpr static int AdjustedDim = Dimensions == 0 ? 1 : Dimensions;
638 
639  using AccessorCommonT::AS;
640  // Cannot do "using AccessorCommonT::Flag" as it doesn't work with g++ as host
641  // compiler, for some reason.
642  static constexpr bool IsAccessAnyWrite = AccessorCommonT::IsAccessAnyWrite;
643  static constexpr bool IsAccessReadOnly = AccessorCommonT::IsAccessReadOnly;
644  static constexpr bool IsConstantBuf = AccessorCommonT::IsConstantBuf;
645  static constexpr bool IsGlobalBuf = AccessorCommonT::IsGlobalBuf;
646  static constexpr bool IsHostBuf = AccessorCommonT::IsHostBuf;
647  static constexpr bool IsPlaceH = AccessorCommonT::IsPlaceH;
648  static constexpr bool IsConst = AccessorCommonT::IsConst;
649  static constexpr bool IsHostTask = AccessorCommonT::IsHostTask;
650  template <int Dims>
651  using AccessorSubscript =
652  typename AccessorCommonT::template AccessorSubscript<Dims>;
653 
654  static_assert(
655  !IsConst || IsAccessReadOnly,
656  "A const qualified DataT is only allowed for a read-only accessor");
657 
658  using ConcreteASPtrType = typename detail::DecoratedType<
659  typename std::conditional_t<IsAccessReadOnly && !IsConstantBuf,
660  const DataT, DataT>,
661  AS>::type *;
662 
663  using RefType = detail::const_if_const_AS<AS, DataT> &;
664  using ConstRefType = const DataT &;
665  using PtrType = detail::const_if_const_AS<AS, DataT> *;
666 
667  template <int Dims = Dimensions> size_t getLinearIndex(id<Dims> Id) const {
668 
669  size_t Result = 0;
670  detail::loop<Dims>([&, this](size_t I) {
671  Result = Result * getMemoryRange()[I] + Id[I];
672  // We've already adjusted for the accessor's offset in the __init, so
673  // don't include it here in case of device.
674 #ifndef __SYCL_DEVICE_ONLY__
675  if constexpr (!(PropertyListT::template has_property<
677  Result += getOffset()[I];
678  }
679 #endif // __SYCL_DEVICE_ONLY__
680  });
681 
682  return Result;
683  }
684 
685  template <typename T, int Dims>
686  struct IsSameAsBuffer
687  : std::bool_constant<std::is_same_v<T, DataT> && (Dims > 0) &&
688  (Dims == Dimensions)> {};
689 
690  static access::mode getAdjustedMode(const PropertyListT &PropertyList) {
691  access::mode AdjustedMode = AccessMode;
692 
693  if (PropertyList.template has_property<property::no_init>() ||
694  PropertyList.template has_property<property::noinit>()) {
695  if (AdjustedMode == access::mode::write) {
696  AdjustedMode = access::mode::discard_write;
697  } else if (AdjustedMode == access::mode::read_write) {
698  AdjustedMode = access::mode::discard_read_write;
699  }
700  }
701 
702  return AdjustedMode;
703  }
704 
705  template <typename TagT>
706  struct IsValidTag
707  : std::disjunction<
708  std::is_same<TagT, mode_tag_t<AccessMode>>,
709  std::is_same<TagT, mode_target_tag_t<AccessMode, AccessTarget>>> {};
710 
711  template <typename DataT_, int Dimensions_, access::mode AccessMode_,
712  access::target AccessTarget_, access::placeholder IsPlaceholder_,
713  typename PropertyListT_>
714  friend class accessor;
715 
716 #ifdef __SYCL_DEVICE_ONLY__
717 
718  id<AdjustedDim> &getOffset() { return impl.Offset; }
719  range<AdjustedDim> &getAccessRange() { return impl.AccessRange; }
720  range<AdjustedDim> &getMemoryRange() { return impl.MemRange; }
721 
722  const id<AdjustedDim> &getOffset() const { return impl.Offset; }
723  const range<AdjustedDim> &getAccessRange() const { return impl.AccessRange; }
724  const range<AdjustedDim> &getMemoryRange() const { return impl.MemRange; }
725 
726  detail::AccessorImplDevice<AdjustedDim> impl;
727 
728  union {
729  ConcreteASPtrType MData;
730  };
731 
732  void __init(ConcreteASPtrType Ptr, range<AdjustedDim> AccessRange,
733  range<AdjustedDim> MemRange, id<AdjustedDim> Offset) {
734  MData = Ptr;
735  detail::loop<AdjustedDim>([&, this](size_t I) {
736  if constexpr (!(PropertyListT::template has_property<
738  getOffset()[I] = Offset[I];
739  }
740  getAccessRange()[I] = AccessRange[I];
741  getMemoryRange()[I] = MemRange[I];
742  });
743 
744  // Adjust for offsets as that part is invariant for all invocations of
745  // operator[]. Will have to re-adjust in get_pointer.
746  MData += getTotalOffset();
747  }
748 
749  // __init variant used by the device compiler for ESIMD kernels.
750  // TODO: In ESIMD accessors usage is limited for now - access range, mem
751  // range and offset are not supported.
752  void __init_esimd(ConcreteASPtrType Ptr) {
753  MData = Ptr;
754 #ifdef __ESIMD_FORCE_STATELESS_MEM
755  detail::loop<AdjustedDim>([&, this](size_t I) {
756  getOffset()[I] = 0;
757  getAccessRange()[I] = 0;
758  getMemoryRange()[I] = 0;
759  });
760 #endif
761  }
762 
763  ConcreteASPtrType getQualifiedPtr() const noexcept { return MData; }
764 
765 #ifndef __SYCL_DEVICE_ONLY__
767 #endif
768 
769 public:
770  // Default constructor for objects later initialized with __init member.
771  accessor()
772  : impl({}, detail::InitializedVal<AdjustedDim, range>::template get<0>(),
773  detail::InitializedVal<AdjustedDim, range>::template get<0>()) {}
774 
775 #else
776  accessor(const detail::AccessorImplPtr &Impl)
777  : detail::AccessorBaseHost{Impl} {}
778 
779  void *getPtr() { return AccessorBaseHost::getPtr(); }
780 
781  const id<3> getOffset() const {
782  if constexpr (IsHostBuf)
783  return MAccData ? MAccData->MOffset : id<3>();
784  else
786  }
787  const range<3> &getAccessRange() const {
789  }
790  const range<3> getMemoryRange() const {
791  if constexpr (IsHostBuf)
792  return MAccData ? MAccData->MMemoryRange : range(0, 0, 0);
793  else
795  }
796 
797  void *getPtr() const { return AccessorBaseHost::getPtr(); }
798 
799  void initHostAcc() { MAccData = &getAccData(); }
800 
801  // The function references helper methods required by GDB pretty-printers
802  void GDBMethodsAnchor() {
803 #ifndef NDEBUG
804  const auto *this_const = this;
805  (void)getMemoryRange();
806  (void)this_const->getMemoryRange();
807  (void)getOffset();
808  (void)this_const->getOffset();
809  (void)getPtr();
810  (void)this_const->getPtr();
811  (void)getAccessRange();
812  (void)this_const->getAccessRange();
813 #endif
814  }
815 
816  detail::AccHostDataT *MAccData = nullptr;
817 
818  char padding[sizeof(detail::AccessorImplDevice<AdjustedDim>) +
819  sizeof(PtrType) - sizeof(detail::AccessorBaseHost) -
820  sizeof(MAccData)];
821 
822  PtrType getQualifiedPtr() const noexcept {
823  if constexpr (IsHostBuf)
824  return MAccData ? reinterpret_cast<PtrType>(MAccData->MData) : nullptr;
825  else
826  return reinterpret_cast<PtrType>(AccessorBaseHost::getPtr());
827  }
828 
829 public:
830  accessor()
831  : AccessorBaseHost(
832  /*Offset=*/{0, 0, 0}, /*AccessRange=*/{0, 0, 0},
833  /*MemoryRange=*/{0, 0, 0},
834  /*AccessMode=*/getAdjustedMode({}),
835  /*SYCLMemObject=*/nullptr, /*Dims=*/0, /*ElemSize=*/0,
836  /*IsPlaceH=*/false,
837  /*OffsetInBytes=*/0, /*IsSubBuffer=*/false, /*PropertyList=*/{}){};
838 
839  template <typename, int, access_mode> friend class host_accessor;
840 
841 #endif // __SYCL_DEVICE_ONLY__
842 
843 private:
844  friend class sycl::stream;
845  friend class sycl::ext::intel::esimd::detail::AccessorPrivateProxy;
846 
847  template <class Obj>
848  friend const decltype(Obj::impl) &
849  detail::getSyclObjImpl(const Obj &SyclObject);
850 
851  template <class T>
852  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
853 
854 public:
855  // 4.7.6.9.1. Interface for buffer command accessors
856  // value_type is defined as const DataT for read_only accessors, DataT
857  // otherwise
858  using value_type =
859  std::conditional_t<AccessMode == access_mode::read, const DataT, DataT>;
860  using reference = value_type &;
861  using const_reference = const DataT &;
862 
863  template <access::decorated IsDecorated>
864  using accessor_ptr =
865  std::conditional_t<AccessTarget == access::target::device,
866  global_ptr<value_type, IsDecorated>, value_type *>;
867 
868  using iterator = typename detail::accessor_iterator<value_type, AdjustedDim>;
869  using const_iterator =
870  typename detail::accessor_iterator<const value_type, AdjustedDim>;
871  using reverse_iterator = std::reverse_iterator<iterator>;
872  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
873  using difference_type =
875  using size_type = std::size_t;
876 
879  void throwIfUsedByGraph() const {
880 #ifndef __SYCL_DEVICE_ONLY__
881  if (IsHostBuf && AccessorBaseHost::isMemoryObjectUsedByGraph()) {
883  "Host accessors cannot be created for buffers "
884  "which are currently in use by a command graph.");
885  }
886 #endif
887  }
888 
889  // The list of accessor constructors with their arguments
890  // -------+---------+-------+----+-----+--------------
891  // Dimensions = 0
892  // -------+---------+-------+----+-----+--------------
893  // buffer | | | | | property_list
894  // buffer | handler | | | | property_list
895  // -------+---------+-------+----+-----+--------------
896  // Dimensions >= 1
897  // -------+---------+-------+----+-----+--------------
898  // buffer | | | | | property_list
899  // buffer | | | | tag | property_list
900  // buffer | handler | | | | property_list
901  // buffer | handler | | | tag | property_list
902  // buffer | | range | | | property_list
903  // buffer | | range | | tag | property_list
904  // buffer | handler | range | | | property_list
905  // buffer | handler | range | | tag | property_list
906  // buffer | | range | id | | property_list
907  // buffer | | range | id | tag | property_list
908  // buffer | handler | range | id | | property_list
909  // buffer | handler | range | id | tag | property_list
910  // -------+---------+-------+----+-----+--------------
911 
912 public:
913  // implicit conversion between const / non-const types for read only accessors
914  template <typename DataT_,
915  typename = std::enable_if_t<
916  IsAccessReadOnly && !std::is_same_v<DataT_, DataT> &&
917  std::is_same_v<std::remove_const_t<DataT_>,
918  std::remove_const_t<DataT>>>>
919  accessor(const accessor<DataT_, Dimensions, AccessMode, AccessTarget,
920  IsPlaceholder, PropertyListT> &other)
921 #ifdef __SYCL_DEVICE_ONLY__
922  : impl(other.impl), MData(other.MData) {
923 #else
924  : accessor(other.impl) {
925 #endif // __SYCL_DEVICE_ONLY__
926  }
927 
928  // implicit conversion from read_write T accessor to read only T (const)
929  // accessor
930  template <typename DataT_, access::mode AccessMode_,
931  typename = std::enable_if_t<
932  (AccessMode_ == access_mode::read_write) && IsAccessReadOnly &&
933  std::is_same_v<std::remove_const_t<DataT_>,
934  std::remove_const_t<DataT>>>>
935  accessor(const accessor<DataT_, Dimensions, AccessMode_, AccessTarget,
936  IsPlaceholder, PropertyListT> &other)
937 #ifdef __SYCL_DEVICE_ONLY__
938  : impl(other.impl), MData(other.MData) {
939 #else
940  : accessor(other.impl) {
941 #endif // __SYCL_DEVICE_ONLY__
942  }
943 
944  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
945  typename std::enable_if_t<
946  detail::IsRunTimePropertyListT<PropertyListT>::value &&
947  std::is_same_v<T, DataT> && Dims == 0 &&
948  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))> * =
949  nullptr>
950  accessor(
951  buffer<T, 1, AllocatorT> &BufferRef,
952  const property_list &PropertyList = {},
953  const detail::code_location CodeLoc = detail::code_location::current())
954 #ifdef __SYCL_DEVICE_ONLY__
955  : impl(id<AdjustedDim>(), detail::GetZeroDimAccessRange(BufferRef),
956  BufferRef.get_range()) {
957  (void)PropertyList;
958  (void)CodeLoc;
959 #else
960  : AccessorBaseHost(
961  /*Offset=*/{0, 0, 0},
962  detail::convertToArrayOfN<3, 1>(
963  detail::GetZeroDimAccessRange(BufferRef)),
964  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
965  getAdjustedMode(PropertyList),
966  detail::getSyclObjImpl(BufferRef).get(), AdjustedDim, sizeof(DataT),
967  IsPlaceH, BufferRef.OffsetInBytes, BufferRef.IsSubBuffer,
968  PropertyList) {
969  throwIfUsedByGraph();
970  preScreenAccessor(PropertyList);
973  initHostAcc();
976  AccessTarget, AccessMode, CodeLoc);
977  GDBMethodsAnchor();
978 #endif
979  }
980 
981  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
982  typename... PropTypes,
983  typename std::enable_if_t<
985  // VS2019 can't compile sycl/test/regression/bit_cast_win.cpp
986  // if std::is_same_v is used here.
987  std::is_same<T, DataT>::value && Dims == 0 &&
988  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))> * =
989  nullptr>
990  accessor(
991  buffer<T, 1, AllocatorT> &BufferRef,
992  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
993  {},
994  const detail::code_location CodeLoc = detail::code_location::current())
995 #ifdef __SYCL_DEVICE_ONLY__
996  : impl(id<AdjustedDim>(), detail::GetZeroDimAccessRange(BufferRef),
997  BufferRef.get_range()) {
998  (void)PropertyList;
999  (void)CodeLoc;
1000 #else
1001  : AccessorBaseHost(
1002  /*Offset=*/{0, 0, 0},
1003  detail::convertToArrayOfN<3, 1>(
1004  detail::GetZeroDimAccessRange(BufferRef)),
1005  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1006  getAdjustedMode(PropertyList),
1007  detail::getSyclObjImpl(BufferRef).get(), AdjustedDim, sizeof(DataT),
1008  IsPlaceH, BufferRef.OffsetInBytes, BufferRef.IsSubBuffer,
1009  PropertyList) {
1010  throwIfUsedByGraph();
1011  preScreenAccessor(PropertyList);
1014  initHostAcc();
1017  AccessTarget, AccessMode, CodeLoc);
1018  GDBMethodsAnchor();
1019 #endif
1020  }
1021 
1022  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1023  typename = typename std::enable_if_t<
1024  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1025  std::is_same_v<T, DataT> && (Dims == 0) &&
1026  (IsGlobalBuf || IsHostBuf || IsConstantBuf || IsHostTask)>>
1027  accessor(
1028  buffer<T, 1, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1029  const property_list &PropertyList = {},
1030  const detail::code_location CodeLoc = detail::code_location::current())
1031 #ifdef __SYCL_DEVICE_ONLY__
1032  : impl(id<AdjustedDim>(), detail::GetZeroDimAccessRange(BufferRef),
1033  BufferRef.get_range()) {
1034  (void)CommandGroupHandler;
1035  (void)PropertyList;
1036  (void)CodeLoc;
1037  }
1038 #else
1039  : AccessorBaseHost(
1040  /*Offset=*/{0, 0, 0},
1041  detail::convertToArrayOfN<3, 1>(
1042  detail::GetZeroDimAccessRange(BufferRef)),
1043  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1044  getAdjustedMode(PropertyList),
1045  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1046  BufferRef.OffsetInBytes, BufferRef.IsSubBuffer, PropertyList) {
1047  throwIfUsedByGraph();
1048  preScreenAccessor(PropertyList);
1049  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1050  initHostAcc();
1053  AccessTarget, AccessMode, CodeLoc);
1054  GDBMethodsAnchor();
1055  }
1056 #endif
1057 
1058  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1059  typename... PropTypes,
1060  typename = typename std::enable_if_t<
1062  std::is_same_v<T, DataT> && (Dims == 0) &&
1063  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1064  accessor(
1065  buffer<T, 1, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1066  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1067  {},
1068  const detail::code_location CodeLoc = detail::code_location::current())
1069 #ifdef __SYCL_DEVICE_ONLY__
1070  : impl(id<AdjustedDim>(), detail::GetZeroDimAccessRange(BufferRef),
1071  BufferRef.get_range()) {
1072  (void)CommandGroupHandler;
1073  (void)PropertyList;
1074  (void)CodeLoc;
1075  }
1076 #else
1077  : AccessorBaseHost(
1078  /*Offset=*/{0, 0, 0},
1079  detail::convertToArrayOfN<3, 1>(
1080  detail::GetZeroDimAccessRange(BufferRef)),
1081  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1082  getAdjustedMode(PropertyList),
1083  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1084  BufferRef.OffsetInBytes, BufferRef.IsSubBuffer, PropertyList) {
1085  throwIfUsedByGraph();
1086  preScreenAccessor(PropertyList);
1087  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1088  initHostAcc();
1091  AccessTarget, AccessMode, CodeLoc);
1092  GDBMethodsAnchor();
1093  }
1094 #endif
1095 
1096  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1097  typename = std::enable_if_t<
1098  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1099  IsSameAsBuffer<T, Dims>::value &&
1100  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1101  accessor(
1102  buffer<T, Dims, AllocatorT> &BufferRef,
1103  const property_list &PropertyList = {},
1104  const detail::code_location CodeLoc = detail::code_location::current())
1105 #ifdef __SYCL_DEVICE_ONLY__
1106  : impl(id<Dimensions>(), BufferRef.get_range(), BufferRef.get_range()) {
1107  (void)PropertyList;
1108  (void)CodeLoc;
1109  }
1110 #else
1111  : AccessorBaseHost(
1112  /*Offset=*/{0, 0, 0},
1113  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1114  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1115  getAdjustedMode(PropertyList),
1116  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1117  IsPlaceH, BufferRef.OffsetInBytes, BufferRef.IsSubBuffer,
1118  PropertyList) {
1119  throwIfUsedByGraph();
1120  preScreenAccessor(PropertyList);
1123  initHostAcc();
1126  AccessTarget, AccessMode, CodeLoc);
1127  GDBMethodsAnchor();
1128  }
1129 #endif
1130 
1131  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1132  typename... PropTypes,
1133  typename = std::enable_if_t<
1135  IsSameAsBuffer<T, Dims>::value &&
1136  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1137  accessor(
1138  buffer<T, Dims, AllocatorT> &BufferRef,
1139  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1140  {},
1141  const detail::code_location CodeLoc = detail::code_location::current())
1142 #ifdef __SYCL_DEVICE_ONLY__
1143  : impl(id<Dimensions>(), BufferRef.get_range(), BufferRef.get_range()) {
1144  (void)PropertyList;
1145  (void)CodeLoc;
1146  }
1147 #else
1148  : AccessorBaseHost(
1149  /*Offset=*/{0, 0, 0},
1150  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1151  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1152  getAdjustedMode(PropertyList),
1153  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1154  IsPlaceH, BufferRef.OffsetInBytes, BufferRef.IsSubBuffer,
1155  PropertyList) {
1156  throwIfUsedByGraph();
1157  preScreenAccessor(PropertyList);
1160  initHostAcc();
1163  AccessTarget, AccessMode, CodeLoc);
1164  GDBMethodsAnchor();
1165  }
1166 #endif
1167 
1168  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1169  typename TagT,
1170  typename = std::enable_if_t<
1171  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1172  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1173  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1174  accessor(
1175  buffer<T, Dims, AllocatorT> &BufferRef, TagT,
1176  const property_list &PropertyList = {},
1177  const detail::code_location CodeLoc = detail::code_location::current())
1178  : accessor(BufferRef, PropertyList, CodeLoc) {
1179  adjustAccPropsInBuf(BufferRef);
1180  }
1181 
1182  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1183  typename TagT, typename... PropTypes,
1184  typename = std::enable_if_t<
1186  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1187  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1188  accessor(
1189  buffer<T, Dims, AllocatorT> &BufferRef, TagT,
1190  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1191  {},
1192  const detail::code_location CodeLoc = detail::code_location::current())
1193  : accessor(BufferRef, PropertyList, CodeLoc) {
1194  adjustAccPropsInBuf(BufferRef);
1195  }
1196 
1197  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1198  typename = std::enable_if_t<
1199  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1200  IsSameAsBuffer<T, Dims>::value &&
1201  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1202  accessor(
1203  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1204  const property_list &PropertyList = {},
1205  const detail::code_location CodeLoc = detail::code_location::current())
1206 #ifdef __SYCL_DEVICE_ONLY__
1207  : impl(id<AdjustedDim>(), BufferRef.get_range(), BufferRef.get_range()) {
1208  (void)CommandGroupHandler;
1209  (void)PropertyList;
1210  (void)CodeLoc;
1211  }
1212 #else
1213  : AccessorBaseHost(
1214  /*Offset=*/{0, 0, 0},
1215  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1216  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1217  getAdjustedMode(PropertyList),
1218  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1219  BufferRef.OffsetInBytes, BufferRef.IsSubBuffer, PropertyList) {
1220  throwIfUsedByGraph();
1221  preScreenAccessor(PropertyList);
1222  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1223  initHostAcc();
1226  AccessTarget, AccessMode, CodeLoc);
1227  GDBMethodsAnchor();
1228  }
1229 #endif
1230 
1231  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1232  typename... PropTypes,
1233  typename = std::enable_if_t<
1235  IsSameAsBuffer<T, Dims>::value &&
1236  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1237  accessor(
1238  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1239  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1240  {},
1241  const detail::code_location CodeLoc = detail::code_location::current())
1242 #ifdef __SYCL_DEVICE_ONLY__
1243  : impl(id<AdjustedDim>(), BufferRef.get_range(), BufferRef.get_range()) {
1244  (void)CommandGroupHandler;
1245  (void)PropertyList;
1246  (void)CodeLoc;
1247  }
1248 #else
1249  : AccessorBaseHost(
1250  /*Offset=*/{0, 0, 0},
1251  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1252  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1253  getAdjustedMode(PropertyList),
1254  detail::getSyclObjImpl(BufferRef).get(), Dimensions, sizeof(DataT),
1255  BufferRef.OffsetInBytes, BufferRef.IsSubBuffer, PropertyList) {
1256  throwIfUsedByGraph();
1257  preScreenAccessor(PropertyList);
1258  initHostAcc();
1259  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1262  AccessTarget, AccessMode, CodeLoc);
1263  GDBMethodsAnchor();
1264  }
1265 #endif
1266 
1267  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1268  typename TagT,
1269  typename = std::enable_if_t<
1270  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1271  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1272  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1273  accessor(
1274  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1275  TagT, const property_list &PropertyList = {},
1276  const detail::code_location CodeLoc = detail::code_location::current())
1277  : accessor(BufferRef, CommandGroupHandler, PropertyList, CodeLoc) {
1278  adjustAccPropsInBuf(BufferRef);
1279  }
1280 
1281  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1282  typename TagT, typename... PropTypes,
1283  typename = std::enable_if_t<
1285  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1286  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1287  accessor(
1288  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1289  TagT,
1290  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1291  {},
1292  const detail::code_location CodeLoc = detail::code_location::current())
1293  : accessor(BufferRef, CommandGroupHandler, PropertyList, CodeLoc) {
1294  adjustAccPropsInBuf(BufferRef);
1295  }
1296 
1297  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1298  typename = std::enable_if_t<
1299  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1300  IsSameAsBuffer<T, Dims>::value &&
1301  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1302  accessor(
1303  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1304  const property_list &PropertyList = {},
1305  const detail::code_location CodeLoc = detail::code_location::current())
1306  : accessor(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {}
1307 
1308  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1309  typename... PropTypes,
1310  typename = std::enable_if_t<
1312  IsSameAsBuffer<T, Dims>::value &&
1313  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1314  accessor(
1315  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1316  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1317  {},
1318  const detail::code_location CodeLoc = detail::code_location::current())
1319  : accessor(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {}
1320 
1321  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1322  typename TagT,
1323  typename = std::enable_if_t<
1324  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1325  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1326  (IsGlobalBuf || IsConstantBuf || IsHostTask)>>
1327  accessor(
1328  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1329  TagT, const property_list &PropertyList = {},
1330  const detail::code_location CodeLoc = detail::code_location::current())
1331  : accessor(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {
1332  adjustAccPropsInBuf(BufferRef);
1333  }
1334 
1335  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1336  typename TagT, typename... PropTypes,
1337  typename = std::enable_if_t<
1339  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1340  (IsGlobalBuf || IsConstantBuf || IsHostTask)>>
1341  accessor(
1342  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1343  TagT,
1344  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1345  {},
1346  const detail::code_location CodeLoc = detail::code_location::current())
1347  : accessor(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {
1348  adjustAccPropsInBuf(BufferRef);
1349  }
1350 
1351  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1352  typename = std::enable_if_t<
1353  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1354  IsSameAsBuffer<T, Dims>::value &&
1355  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1356  accessor(
1357  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1358  range<Dimensions> AccessRange, const property_list &PropertyList = {},
1359  const detail::code_location CodeLoc = detail::code_location::current())
1360  : accessor(BufferRef, CommandGroupHandler, AccessRange, {}, PropertyList,
1361  CodeLoc) {}
1362 
1363  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1364  typename... PropTypes,
1365  typename = std::enable_if_t<
1367  IsSameAsBuffer<T, Dims>::value &&
1368  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1369  accessor(
1370  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1371  range<Dimensions> AccessRange,
1372  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1373  {},
1374  const detail::code_location CodeLoc = detail::code_location::current())
1375  : accessor(BufferRef, CommandGroupHandler, AccessRange, {}, PropertyList,
1376  CodeLoc) {}
1377 
1378  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1379  typename TagT,
1380  typename = std::enable_if_t<
1381  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1382  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1383  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1384  accessor(
1385  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1386  range<Dimensions> AccessRange, TagT,
1387  const property_list &PropertyList = {},
1388  const detail::code_location CodeLoc = detail::code_location::current())
1389  : accessor(BufferRef, CommandGroupHandler, AccessRange, {}, PropertyList,
1390  CodeLoc) {
1391  adjustAccPropsInBuf(BufferRef);
1392  }
1393 
1394  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1395  typename TagT, typename... PropTypes,
1396  typename = std::enable_if_t<
1398  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1399  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1400  accessor(
1401  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1402  range<Dimensions> AccessRange, TagT,
1403  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1404  {},
1405  const detail::code_location CodeLoc = detail::code_location::current())
1406  : accessor(BufferRef, CommandGroupHandler, AccessRange, {}, PropertyList,
1407  CodeLoc) {
1408  adjustAccPropsInBuf(BufferRef);
1409  }
1410 
1411  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1412  typename = std::enable_if_t<
1413  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1414  IsSameAsBuffer<T, Dims>::value &&
1415  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1416  accessor(
1417  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1418  id<Dimensions> AccessOffset, const property_list &PropertyList = {},
1419  const detail::code_location CodeLoc = detail::code_location::current())
1420 #ifdef __SYCL_DEVICE_ONLY__
1421  : impl(AccessOffset, AccessRange, BufferRef.get_range()) {
1422  (void)PropertyList;
1423  (void)CodeLoc;
1424  }
1425 #else
1426  : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset),
1427  detail::convertToArrayOfN<3, 1>(AccessRange),
1428  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1429  getAdjustedMode(PropertyList),
1430  detail::getSyclObjImpl(BufferRef).get(), Dimensions,
1431  sizeof(DataT), IsPlaceH, BufferRef.OffsetInBytes,
1432  BufferRef.IsSubBuffer, PropertyList) {
1433  throwIfUsedByGraph();
1434  preScreenAccessor(PropertyList);
1437  if (BufferRef.isOutOfBounds(AccessOffset, AccessRange,
1438  BufferRef.get_range()))
1440  "accessor with requested offset and range would "
1441  "exceed the bounds of the buffer");
1442 
1443  initHostAcc();
1446  AccessTarget, AccessMode, CodeLoc);
1447  GDBMethodsAnchor();
1448  }
1449 #endif
1450 
1451  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1452  typename... PropTypes,
1453  typename = std::enable_if_t<
1455  IsSameAsBuffer<T, Dims>::value &&
1456  (IsHostBuf || IsHostTask || (IsGlobalBuf || IsConstantBuf))>>
1457  accessor(
1458  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1459  id<Dimensions> AccessOffset,
1460  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1461  {},
1462  const detail::code_location CodeLoc = detail::code_location::current())
1463 #ifdef __SYCL_DEVICE_ONLY__
1464  : impl(AccessOffset, AccessRange, BufferRef.get_range()) {
1465  (void)PropertyList;
1466  (void)CodeLoc;
1467  }
1468 #else
1469  : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset),
1470  detail::convertToArrayOfN<3, 1>(AccessRange),
1471  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1472  getAdjustedMode(PropertyList),
1473  detail::getSyclObjImpl(BufferRef).get(), Dimensions,
1474  sizeof(DataT), IsPlaceH, BufferRef.OffsetInBytes,
1475  BufferRef.IsSubBuffer, PropertyList) {
1476  throwIfUsedByGraph();
1477  preScreenAccessor(PropertyList);
1480  if (BufferRef.isOutOfBounds(AccessOffset, AccessRange,
1481  BufferRef.get_range()))
1483  "accessor with requested offset and range would "
1484  "exceed the bounds of the buffer");
1485 
1486  initHostAcc();
1489  AccessTarget, AccessMode, CodeLoc);
1490  GDBMethodsAnchor();
1491  }
1492 #endif
1493 
1494  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1495  typename TagT,
1496  typename = std::enable_if_t<
1497  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1498  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1499  (IsGlobalBuf || IsConstantBuf || IsHostTask)>>
1500  accessor(
1501  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1502  id<Dimensions> AccessOffset, TagT, const property_list &PropertyList = {},
1503  const detail::code_location CodeLoc = detail::code_location::current())
1504  : accessor(BufferRef, AccessRange, AccessOffset, PropertyList, CodeLoc) {
1505  adjustAccPropsInBuf(BufferRef);
1506  }
1507 
1508  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1509  typename TagT, typename... PropTypes,
1510  typename = std::enable_if_t<
1512  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1513  (IsGlobalBuf || IsConstantBuf || IsHostTask)>>
1514  accessor(
1515  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
1516  id<Dimensions> AccessOffset, TagT,
1517  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1518  {},
1519  const detail::code_location CodeLoc = detail::code_location::current())
1520  : accessor(BufferRef, AccessRange, AccessOffset, PropertyList, CodeLoc) {
1521  adjustAccPropsInBuf(BufferRef);
1522  }
1523 
1524  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1525  typename = std::enable_if_t<
1526  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1527  IsSameAsBuffer<T, Dims>::value &&
1528  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1529  accessor(
1530  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1531  range<Dimensions> AccessRange, id<Dimensions> AccessOffset,
1532  const property_list &PropertyList = {},
1533  const detail::code_location CodeLoc = detail::code_location::current())
1534 #ifdef __SYCL_DEVICE_ONLY__
1535  : impl(AccessOffset, AccessRange, BufferRef.get_range()) {
1536  (void)CommandGroupHandler;
1537  (void)PropertyList;
1538  (void)CodeLoc;
1539  }
1540 #else
1541  : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset),
1542  detail::convertToArrayOfN<3, 1>(AccessRange),
1543  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1544  getAdjustedMode(PropertyList),
1545  detail::getSyclObjImpl(BufferRef).get(), Dimensions,
1546  sizeof(DataT), BufferRef.OffsetInBytes,
1547  BufferRef.IsSubBuffer, PropertyList) {
1548  throwIfUsedByGraph();
1549  preScreenAccessor(PropertyList);
1550  if (BufferRef.isOutOfBounds(AccessOffset, AccessRange,
1551  BufferRef.get_range()))
1553  "accessor with requested offset and range would "
1554  "exceed the bounds of the buffer");
1555 
1556  initHostAcc();
1557  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1560  AccessTarget, AccessMode, CodeLoc);
1561  GDBMethodsAnchor();
1562  }
1563 #endif
1564 
1565  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1566  typename... PropTypes,
1567  typename = std::enable_if_t<
1569  IsSameAsBuffer<T, Dims>::value &&
1570  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1571  accessor(
1572  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1573  range<Dimensions> AccessRange, id<Dimensions> AccessOffset,
1574  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1575  {},
1576  const detail::code_location CodeLoc = detail::code_location::current())
1577 #ifdef __SYCL_DEVICE_ONLY__
1578  : impl(AccessOffset, AccessRange, BufferRef.get_range()) {
1579  (void)CommandGroupHandler;
1580  (void)PropertyList;
1581  (void)CodeLoc;
1582  }
1583 #else
1584  : AccessorBaseHost(detail::convertToArrayOfN<3, 0>(AccessOffset),
1585  detail::convertToArrayOfN<3, 1>(AccessRange),
1586  detail::convertToArrayOfN<3, 1>(BufferRef.get_range()),
1587  getAdjustedMode(PropertyList),
1588  detail::getSyclObjImpl(BufferRef).get(), Dimensions,
1589  sizeof(DataT), BufferRef.OffsetInBytes,
1590  BufferRef.IsSubBuffer, PropertyList) {
1591  throwIfUsedByGraph();
1592  preScreenAccessor(PropertyList);
1593  if (BufferRef.isOutOfBounds(AccessOffset, AccessRange,
1594  BufferRef.get_range()))
1596  "accessor with requested offset and range would "
1597  "exceed the bounds of the buffer");
1598 
1599  initHostAcc();
1600  detail::associateWithHandler(CommandGroupHandler, this, AccessTarget);
1603  AccessTarget, AccessMode, CodeLoc);
1604  GDBMethodsAnchor();
1605  }
1606 #endif
1607 
1608  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1609  typename TagT,
1610  typename = std::enable_if_t<
1611  detail::IsRunTimePropertyListT<PropertyListT>::value &&
1612  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1613  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1614  accessor(
1615  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1616  range<Dimensions> AccessRange, id<Dimensions> AccessOffset, TagT,
1617  const property_list &PropertyList = {},
1618  const detail::code_location CodeLoc = detail::code_location::current())
1619  : accessor(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
1620  PropertyList, CodeLoc) {
1621  adjustAccPropsInBuf(BufferRef);
1622  }
1623 
1624  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
1625  typename TagT, typename... PropTypes,
1626  typename = std::enable_if_t<
1628  IsSameAsBuffer<T, Dims>::value && IsValidTag<TagT>::value &&
1629  (IsGlobalBuf || IsConstantBuf || IsHostBuf || IsHostTask)>>
1630  accessor(
1631  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
1632  range<Dimensions> AccessRange, id<Dimensions> AccessOffset, TagT,
1633  const ext::oneapi::accessor_property_list<PropTypes...> &PropertyList =
1634  {},
1635  const detail::code_location CodeLoc = detail::code_location::current())
1636  : accessor(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
1637  PropertyList, CodeLoc) {
1638  adjustAccPropsInBuf(BufferRef);
1639  }
1640 
1641  template <typename... NewPropsT>
1642  accessor(
1643  const accessor<DataT, Dimensions, AccessMode, AccessTarget, IsPlaceholder,
1644  ext::oneapi::accessor_property_list<NewPropsT...>> &Other,
1645  const detail::code_location CodeLoc = detail::code_location::current())
1646 #ifdef __SYCL_DEVICE_ONLY__
1647  : impl(Other.impl), MData(Other.MData)
1648 #else
1649  : detail::AccessorBaseHost(Other), MAccData(Other.MAccData)
1650 #endif
1651  {
1653  "Conversion is only available for accessor_property_list");
1654  static_assert(
1655  PropertyListT::template areSameCompileTimeProperties<NewPropsT...>(),
1656  "Compile-time-constant properties must be the same");
1657  (void)CodeLoc;
1658 #ifndef __SYCL_DEVICE_ONLY__
1659  detail::constructorNotification(getMemoryObject(), impl.get(), AccessTarget,
1660  AccessMode, CodeLoc);
1661 #endif
1662  }
1663 
1664  void swap(accessor &other) {
1665  std::swap(impl, other.impl);
1666 #ifdef __SYCL_DEVICE_ONLY__
1667  std::swap(MData, other.MData);
1668 #else
1669  std::swap(MAccData, other.MAccData);
1670 #endif
1671  }
1672 
1673  bool is_placeholder() const {
1674 #ifdef __SYCL_DEVICE_ONLY__
1675  return false;
1676 #else
1678 #endif
1679  }
1680 
1681  size_t get_size() const { return getAccessRange().size() * sizeof(DataT); }
1682 
1683  __SYCL2020_DEPRECATED("get_count() is deprecated, please use size() instead")
1684  size_t get_count() const { return size(); }
1685  size_type size() const noexcept { return getAccessRange().size(); }
1686 
1687  size_type byte_size() const noexcept { return size() * sizeof(DataT); }
1688 
1689  size_type max_size() const noexcept {
1691  }
1692 
1693  bool empty() const noexcept { return size() == 0; }
1694 
1695  template <int Dims = Dimensions,
1696  typename = std::enable_if_t<Dims == Dimensions && (Dims > 0)>>
1697  range<Dimensions> get_range() const {
1698  return getRange<Dims>();
1699  }
1700 
1701  template <int Dims = Dimensions,
1702  typename = std::enable_if_t<Dims == Dimensions && (Dims > 0)>>
1703  id<Dimensions> get_offset() const {
1704  return getOffset<Dims>();
1705  }
1706 
1707  template <int Dims = Dimensions, typename RefT = RefType,
1708  typename = std::enable_if_t<Dims == 0 &&
1709  (IsAccessAnyWrite || IsAccessReadOnly)>>
1710  operator reference() const {
1711  const size_t LinearIndex = getLinearIndex(id<AdjustedDim>());
1712  return *(getQualifiedPtr() + LinearIndex);
1713  }
1714 
1715  template <int Dims = Dimensions,
1716  typename = std::enable_if_t<AccessMode != access_mode::atomic &&
1717  !IsAccessReadOnly && Dims == 0>>
1718  const accessor &operator=(const value_type &Other) const {
1719  *getQualifiedPtr() = Other;
1720  return *this;
1721  }
1722 
1723  template <int Dims = Dimensions,
1724  typename = std::enable_if_t<AccessMode != access_mode::atomic &&
1725  !IsAccessReadOnly && Dims == 0>>
1726  const accessor &operator=(value_type &&Other) const {
1727  *getQualifiedPtr() = std::move(Other);
1728  return *this;
1729  }
1730 
1731  template <int Dims = Dimensions,
1732  typename = std::enable_if_t<(Dims > 0) &&
1733  (IsAccessAnyWrite || IsAccessReadOnly)>>
1734  reference operator[](id<Dimensions> Index) const {
1735  const size_t LinearIndex = getLinearIndex(Index);
1736  return getQualifiedPtr()[LinearIndex];
1737  }
1738 
1739  template <int Dims = Dimensions>
1740  operator typename std::enable_if_t<Dims == 0 &&
1742 #ifdef __ENABLE_USM_ADDR_SPACE__
1743  atomic<DataT>
1744 #else
1745  atomic<DataT, AS>
1746 #endif
1747  >() const {
1748  const size_t LinearIndex = getLinearIndex(id<AdjustedDim>());
1749  return atomic<DataT, AS>(multi_ptr<DataT, AS, access::decorated::yes>(
1750  getQualifiedPtr() + LinearIndex));
1751  }
1752 
1753  template <int Dims = Dimensions>
1754  typename std::enable_if_t<(Dims > 0) && AccessMode == access::mode::atomic,
1755  atomic<DataT, AS>>
1756  operator[](id<Dimensions> Index) const {
1757  const size_t LinearIndex = getLinearIndex(Index);
1758  return atomic<DataT, AS>(multi_ptr<DataT, AS, access::decorated::yes>(
1759  getQualifiedPtr() + LinearIndex));
1760  }
1761 
1762  template <int Dims = Dimensions>
1763  typename std::enable_if_t<Dims == 1 && AccessMode == access::mode::atomic,
1764  atomic<DataT, AS>>
1765  operator[](size_t Index) const {
1766  const size_t LinearIndex = getLinearIndex(id<AdjustedDim>(Index));
1767  return atomic<DataT, AS>(multi_ptr<DataT, AS, access::decorated::yes>(
1768  getQualifiedPtr() + LinearIndex));
1769  }
1770  template <int Dims = Dimensions, typename = std::enable_if_t<(Dims > 1)>>
1771  auto operator[](size_t Index) const {
1772  return AccessorSubscript<Dims - 1>(*this, Index);
1773  }
1774 
1775  template <access::target AccessTarget_ = AccessTarget,
1776  typename = std::enable_if_t<
1777  (AccessTarget_ == access::target::host_buffer) ||
1778  (AccessTarget_ == access::target::host_task)>>
1779  std::add_pointer_t<value_type> get_pointer() const noexcept {
1780  return getPointerAdjusted();
1781  }
1782 
1783  template <
1784  access::target AccessTarget_ = AccessTarget,
1785  typename = std::enable_if_t<(AccessTarget_ == access::target::device)>>
1787  "accessor::get_pointer() is deprecated, please use get_multi_ptr()")
1788  global_ptr<value_type> get_pointer() const noexcept {
1789  return global_ptr<value_type>(
1790  const_cast<typename detail::DecoratedType<value_type, AS>::type *>(
1791  getPointerAdjusted()));
1792  }
1793 
1794  template <access::target AccessTarget_ = AccessTarget,
1795  typename = std::enable_if_t<AccessTarget_ ==
1796  access::target::constant_buffer>>
1797  constant_ptr<DataT> get_pointer() const {
1798  return constant_ptr<DataT>(getPointerAdjusted());
1799  }
1800 
1801  template <access::decorated IsDecorated,
1802  access::target AccessTarget_ = AccessTarget,
1803  std::enable_if_t<AccessTarget_ == access::target::device, int> = 0>
1804  accessor_ptr<IsDecorated> get_multi_ptr() const noexcept {
1805  return accessor_ptr<IsDecorated>(getPointerAdjusted());
1806  }
1807 
1808  template <access::decorated IsDecorated,
1809  access::target AccessTarget_ = AccessTarget,
1810  std::enable_if_t<AccessTarget_ != access::target::device, int> = 0>
1812  "accessor::get_multi_ptr() is deprecated for non-device accessors")
1813  accessor_ptr<IsDecorated> get_multi_ptr() const noexcept {
1814  return accessor_ptr<IsDecorated>(getPointerAdjusted());
1815  }
1816 
1817  // accessor::has_property for runtime properties is only available in host
1818  // code. This restriction is not listed in the core spec and will be added in
1819  // future versions.
1820  template <typename Property>
1821  typename std::enable_if_t<
1822  !ext::oneapi::is_compile_time_property<Property>::value, bool>
1823  has_property() const noexcept {
1824 #ifndef __SYCL_DEVICE_ONLY__
1825  return getPropList().template has_property<Property>();
1826 #else
1827  return false;
1828 #endif
1829  }
1830 
1831  // accessor::get_property for runtime properties is only available in host
1832  // code. This restriction is not listed in the core spec and will be added in
1833  // future versions.
1834  template <typename Property,
1835  typename = typename std::enable_if_t<
1836  !ext::oneapi::is_compile_time_property<Property>::value>>
1837  Property get_property() const {
1838 #ifndef __SYCL_DEVICE_ONLY__
1839  return getPropList().template get_property<Property>();
1840 #else
1841  return Property();
1842 #endif
1843  }
1844 
1845  template <typename Property>
1846  static constexpr bool has_property(
1847  typename std::enable_if_t<
1848  ext::oneapi::is_compile_time_property<Property>::value> * = 0) {
1849  return PropertyListT::template has_property<Property>();
1850  }
1851 
1852  template <typename Property>
1853  static constexpr auto get_property(
1854  typename std::enable_if_t<
1855  ext::oneapi::is_compile_time_property<Property>::value> * = 0) {
1856  return PropertyListT::template get_property<Property>();
1857  }
1858 
1859  bool operator==(const accessor &Rhs) const { return impl == Rhs.impl; }
1860  bool operator!=(const accessor &Rhs) const { return !(*this == Rhs); }
1861 
1862  iterator begin() const noexcept {
1863  return iterator::getBegin(
1864  get_pointer(),
1865  detail::convertToArrayOfN<AdjustedDim, 1>(getMemoryRange()),
1866  getRange<AdjustedDim>(), getOffset<AdjustedDim>());
1867  }
1868 
1869  iterator end() const noexcept {
1870  return iterator::getEnd(
1871  get_pointer(),
1872  detail::convertToArrayOfN<AdjustedDim, 1>(getMemoryRange()),
1873  getRange<AdjustedDim>(), getOffset<AdjustedDim>());
1874  }
1875 
1876  const_iterator cbegin() const noexcept {
1877  return const_iterator::getBegin(
1878  get_pointer(),
1879  detail::convertToArrayOfN<AdjustedDim, 1>(getMemoryRange()),
1880  getRange<AdjustedDim>(), getOffset<AdjustedDim>());
1881  }
1882 
1883  const_iterator cend() const noexcept {
1884  return const_iterator::getEnd(
1885  get_pointer(),
1886  detail::convertToArrayOfN<AdjustedDim, 1>(getMemoryRange()),
1887  getRange<AdjustedDim>(), getOffset<AdjustedDim>());
1888  }
1889 
1890  reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
1891  reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
1892 
1893  const_reverse_iterator crbegin() const noexcept {
1894  return const_reverse_iterator(cend());
1895  }
1896  const_reverse_iterator crend() const noexcept {
1897  return const_reverse_iterator(cbegin());
1898  }
1899 
1900 private:
1901  template <int Dims, typename = std::enable_if_t<(Dims > 0)>>
1902  range<Dims> getRange() const {
1903  return detail::convertToArrayOfN<AdjustedDim, 1>(getAccessRange());
1904  }
1905 
1906  template <int Dims = Dimensions, typename = std::enable_if_t<(Dims > 0)>>
1907  id<Dims> getOffset() const {
1908  static_assert(
1909  !(PropertyListT::template has_property<
1911  "Accessor has no_offset property, get_offset() can not be used");
1912  return detail::convertToArrayOfN<Dims, 0>(getOffset());
1913  }
1914 
1915 #ifdef __SYCL_DEVICE_ONLY__
1916  size_t getTotalOffset() const noexcept {
1917  size_t TotalOffset = 0;
1918  detail::loop<Dimensions>([&, this](size_t I) {
1919  TotalOffset = TotalOffset * impl.MemRange[I];
1920  if constexpr (!(PropertyListT::template has_property<
1922  TotalOffset += impl.Offset[I];
1923  }
1924  });
1925 
1926  return TotalOffset;
1927  }
1928 #endif
1929 
1930  // supporting function for get_pointer()
1931  // MData has been preadjusted with offset for faster access with []
1932  // but for get_pointer() we must return the original pointer.
1933  // On device, getQualifiedPtr() returns MData, so we need to backjust it.
1934  // On host, getQualifiedPtr() does not return MData, no need to adjust.
1935  auto getPointerAdjusted() const noexcept {
1936 #ifdef __SYCL_DEVICE_ONLY__
1937  return getQualifiedPtr() - getTotalOffset();
1938 #else
1939  return getQualifiedPtr();
1940 #endif
1941  }
1942 
1943  void preScreenAccessor(const PropertyListT &PropertyList) {
1944  // check that no_init property is compatible with access mode
1945  if (PropertyList.template has_property<property::no_init>() &&
1948  "accessor cannot be both read_only and no_init");
1949  }
1950  }
1951 
1952  template <typename BufT, typename... PropTypes>
1953  void adjustAccPropsInBuf(BufT &Buffer) {
1954  if constexpr (PropertyListT::template has_property<
1956  auto location = (PropertyListT::template get_property<
1958  .get_location();
1959  property_list PropList{
1961  Buffer.addOrReplaceAccessorProperties(PropList);
1962  } else {
1963  deleteAccPropsFromBuf(Buffer);
1964  }
1965  }
1966 
1967  template <typename BufT> void deleteAccPropsFromBuf(BufT &Buffer) {
1968  Buffer.deleteAccProps(
1970  }
1971 };
1972 
1973 template <typename DataT, int Dimensions, typename AllocatorT>
1975  -> accessor<DataT, Dimensions, access::mode::read_write, target::device,
1977 
1978 template <typename DataT, int Dimensions, typename AllocatorT,
1979  typename... PropsT>
1982  -> accessor<DataT, Dimensions, access::mode::read_write, target::device,
1985 
1986 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1>
1989  detail::deduceAccessTarget<Type1, Type1>(target::device),
1991 
1992 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
1993  typename... PropsT>
1997  detail::deduceAccessTarget<Type1, Type1>(target::device),
2000 
2001 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2002  typename Type2>
2005  detail::deduceAccessTarget<Type1, Type2>(target::device),
2007 
2008 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2009  typename Type2, typename... PropsT>
2013  detail::deduceAccessTarget<Type1, Type2>(target::device),
2016 
2017 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2018  typename Type2, typename Type3>
2021  detail::deduceAccessTarget<Type2, Type3>(target::device),
2023 
2024 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2025  typename Type2, typename Type3, typename... PropsT>
2029  detail::deduceAccessTarget<Type2, Type3>(target::device),
2032 
2033 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2034  typename Type2, typename Type3, typename Type4>
2037  detail::deduceAccessTarget<Type3, Type4>(target::device),
2039 
2040 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2041  typename Type2, typename Type3, typename Type4, typename... PropsT>
2045  detail::deduceAccessTarget<Type3, Type4>(target::device),
2048 
2049 template <typename DataT, int Dimensions, typename AllocatorT>
2051  -> accessor<DataT, Dimensions, access::mode::read_write, target::device,
2053 
2054 template <typename DataT, int Dimensions, typename AllocatorT,
2055  typename... PropsT>
2058  -> accessor<DataT, Dimensions, access::mode::read_write, target::device,
2061 
2062 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1>
2065  detail::deduceAccessTarget<Type1, Type1>(target::device),
2067 
2068 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2069  typename... PropsT>
2073  detail::deduceAccessTarget<Type1, Type1>(target::device),
2076 
2077 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2078  typename Type2>
2081  detail::deduceAccessTarget<Type1, Type2>(target::device),
2083 
2084 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2085  typename Type2, typename... PropsT>
2089  detail::deduceAccessTarget<Type1, Type2>(target::device),
2092 
2093 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2094  typename Type2, typename Type3>
2097  detail::deduceAccessTarget<Type2, Type3>(target::device),
2099 
2100 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2101  typename Type2, typename Type3, typename... PropsT>
2105  detail::deduceAccessTarget<Type2, Type3>(target::device),
2108 
2109 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2110  typename Type2, typename Type3, typename Type4>
2112  Type4)
2114  detail::deduceAccessTarget<Type3, Type4>(target::device),
2116 
2117 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2118  typename Type2, typename Type3, typename Type4, typename... PropsT>
2122  detail::deduceAccessTarget<Type3, Type4>(target::device),
2125 
2129 template <typename DataT, int Dimensions, access::mode AccessMode,
2132 #ifndef __SYCL_DEVICE_ONLY__
2134 #endif
2135  public detail::accessor_common<DataT, Dimensions, AccessMode,
2136  access::target::local, IsPlaceholder> {
2137 protected:
2138  constexpr static int AdjustedDim = Dimensions == 0 ? 1 : Dimensions;
2139 
2142  access::target::local, IsPlaceholder>;
2143 
2144  using AccessorCommonT::AS;
2145 
2146  // Cannot do "using AccessorCommonT::Flag" as it doesn't work with g++ as host
2147  // compiler, for some reason.
2148  static constexpr bool IsAccessAnyWrite = AccessorCommonT::IsAccessAnyWrite;
2149  static constexpr bool IsAccessReadOnly = AccessorCommonT::IsAccessReadOnly;
2150  static constexpr bool IsConst = AccessorCommonT::IsConst;
2151 
2152  template <int Dims>
2154  typename AccessorCommonT::template AccessorSubscript<
2155  Dims,
2157 
2159 
2162 
2163 #ifdef __SYCL_DEVICE_ONLY__
2165 
2166  sycl::range<AdjustedDim> &getSize() { return impl.MemRange; }
2167  const sycl::range<AdjustedDim> &getSize() const { return impl.MemRange; }
2168 
2169  void __init(ConcreteASPtrType Ptr, range<AdjustedDim> AccessRange,
2171  MData = Ptr;
2172  detail::loop<AdjustedDim>(
2173  [&, this](size_t I) { getSize()[I] = AccessRange[I]; });
2174  }
2175 
2176  // __init variant used by the device compiler for ESIMD kernels.
2177  // TODO: In ESIMD accessors usage is limited for now - access range, mem
2178  // range and offset are not supported.
2179  void __init_esimd(ConcreteASPtrType Ptr) {
2180  MData = Ptr;
2181  detail::loop<AdjustedDim>([&, this](size_t I) { getSize()[I] = 0; });
2182  }
2183 
2184 public:
2185  // Default constructor for objects later initialized with __init member.
2186  local_accessor_base()
2187  : impl(detail::InitializedVal<AdjustedDim, range>::template get<0>()) {}
2188 
2189 protected:
2190  ConcreteASPtrType getQualifiedPtr() const { return MData; }
2191 
2192  ConcreteASPtrType MData;
2193 
2194 #else
2195 public:
2197  : detail::LocalAccessorBaseHost{/*Size*/ sycl::range<3>{0, 0, 0},
2198  /*Dims*/ 0, /*ElemSize*/ sizeof(DataT)} {}
2199 
2200 protected:
2202  : detail::LocalAccessorBaseHost{Impl} {}
2203 
2205  sizeof(PtrType) - sizeof(detail::LocalAccessorBaseHost)];
2207 
2209  return reinterpret_cast<PtrType>(LocalAccessorBaseHost::getPtr());
2210  }
2211 
2213  void *getPtr() const { return detail::LocalAccessorBaseHost::getPtr(); }
2214  const range<3> &getSize() const {
2216  }
2218 
2219  // The function references helper methods required by GDB pretty-printers
2221 #ifndef NDEBUG
2222  const auto *this_const = this;
2223  (void)getSize();
2224  (void)this_const->getSize();
2225  (void)getPtr();
2226  (void)this_const->getPtr();
2227 #endif
2228  }
2229 
2230 #endif // __SYCL_DEVICE_ONLY__
2231 
2232  // Method which calculates linear offset for the ID using Range and Offset.
2233  template <int Dims = AdjustedDim> size_t getLinearIndex(id<Dims> Id) const {
2234  size_t Result = 0;
2235  detail::loop<Dims>(
2236  [&, this](size_t I) { Result = Result * getSize()[I] + Id[I]; });
2237  return Result;
2238  }
2239 
2240  template <class Obj>
2241  friend const decltype(Obj::impl) &
2242  detail::getSyclObjImpl(const Obj &SyclObject);
2243 
2244  template <class T>
2245  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
2246 
2247  template <typename DataT_, int Dimensions_> friend class local_accessor;
2248 
2249 public:
2250  using value_type = DataT;
2251  using reference = DataT &;
2252  using const_reference = const DataT &;
2253 
2254  template <int Dims = Dimensions, typename = std::enable_if_t<Dims == 0>>
2257 #ifdef __SYCL_DEVICE_ONLY__
2258  : impl(range<AdjustedDim>{1}) {
2259  (void)CodeLoc;
2260  }
2261 #else
2262  : LocalAccessorBaseHost(range<3>{1, 1, 1}, AdjustedDim, sizeof(DataT)) {
2264  access::target::local, AccessMode, CodeLoc);
2265  GDBMethodsAnchor();
2266  }
2267 #endif
2268 
2269  template <int Dims = Dimensions, typename = std::enable_if_t<Dims == 0>>
2271  const detail::code_location CodeLoc =
2273 #ifdef __SYCL_DEVICE_ONLY__
2274  : impl(range<AdjustedDim>{1}) {
2275  (void)propList;
2276  (void)CodeLoc;
2277  }
2278 #else
2279  : LocalAccessorBaseHost(range<3>{1, 1, 1}, AdjustedDim, sizeof(DataT),
2280  propList) {
2282  access::target::local, AccessMode, CodeLoc);
2283  GDBMethodsAnchor();
2284  }
2285 #endif
2286 
2287  template <int Dims = Dimensions, typename = std::enable_if_t<(Dims > 0)>>
2289  range<Dimensions> AllocationSize, handler &,
2291 #ifdef __SYCL_DEVICE_ONLY__
2292  : impl(AllocationSize) {
2293  (void)CodeLoc;
2294  }
2295 #else
2296  : LocalAccessorBaseHost(detail::convertToArrayOfN<3, 1>(AllocationSize),
2297  AdjustedDim, sizeof(DataT)) {
2299  access::target::local, AccessMode, CodeLoc);
2300  GDBMethodsAnchor();
2301  }
2302 #endif
2303 
2304  template <int Dims = Dimensions,
2305  typename = std::enable_if_t<(Dims > 0)>>
2307  const property_list &propList,
2308  const detail::code_location CodeLoc =
2310 #ifdef __SYCL_DEVICE_ONLY__
2311  : impl(AllocationSize) {
2312  (void)propList;
2313  (void)CodeLoc;
2314  }
2315 #else
2316  : LocalAccessorBaseHost(detail::convertToArrayOfN<3, 1>(AllocationSize),
2317  AdjustedDim, sizeof(DataT), propList) {
2319  access::target::local, AccessMode, CodeLoc);
2320  GDBMethodsAnchor();
2321  }
2322 #endif
2323 
2324  size_t get_size() const { return getSize().size() * sizeof(DataT); }
2325 
2326  __SYCL2020_DEPRECATED("get_count() is deprecated, please use size() instead")
2327  size_t get_count() const { return size(); }
2328  size_t size() const noexcept { return getSize().size(); }
2329 
2330  template <int Dims = Dimensions, typename = std::enable_if_t<(Dims > 0)>>
2332  return detail::convertToArrayOfN<Dims, 1>(getSize());
2333  }
2334 
2335  template <int Dims = Dimensions,
2336  typename = std::enable_if_t<Dims == 0 &&
2337  (IsAccessAnyWrite || IsAccessReadOnly)>>
2338  operator RefType() const {
2339  return *getQualifiedPtr();
2340  }
2341 
2342  template <int Dims = Dimensions,
2343  typename = std::enable_if_t<(Dims > 0) &&
2344  (IsAccessAnyWrite || IsAccessReadOnly)>>
2346  const size_t LinearIndex = getLinearIndex(Index);
2347  return getQualifiedPtr()[LinearIndex];
2348  }
2349 
2350  template <int Dims = Dimensions,
2351  typename = std::enable_if_t<Dims == 1 &&
2352  (IsAccessAnyWrite || IsAccessReadOnly)>>
2353  RefType operator[](size_t Index) const {
2354  return getQualifiedPtr()[Index];
2355  }
2356 
2357  template <int Dims = Dimensions>
2358  operator typename std::enable_if_t<
2359  Dims == 0 && AccessMode == access::mode::atomic, atomic<DataT, AS>>()
2360  const {
2361  return atomic<DataT, AS>(
2363  }
2364 
2365  template <int Dims = Dimensions>
2366  typename std::enable_if_t<(Dims > 0) && AccessMode == access::mode::atomic,
2367  atomic<DataT, AS>>
2368  operator[](id<Dimensions> Index) const {
2369  const size_t LinearIndex = getLinearIndex(Index);
2370  return atomic<DataT, AS>(multi_ptr<DataT, AS, access::decorated::yes>(
2371  getQualifiedPtr() + LinearIndex));
2372  }
2373 
2374  template <int Dims = Dimensions>
2375  typename std::enable_if_t<Dims == 1 && AccessMode == access::mode::atomic,
2376  atomic<DataT, AS>>
2377  operator[](size_t Index) const {
2378  return atomic<DataT, AS>(multi_ptr<DataT, AS, access::decorated::yes>(
2379  getQualifiedPtr() + Index));
2380  }
2381 
2382  template <int Dims = Dimensions, typename = std::enable_if_t<(Dims > 1)>>
2383  typename AccessorCommonT::template AccessorSubscript<
2384  Dims - 1,
2386  operator[](size_t Index) const {
2387  return AccessorSubscript<Dims - 1>(*this, Index);
2388  }
2389 
2390  bool operator==(const local_accessor_base &Rhs) const {
2391  return impl == Rhs.impl;
2392  }
2393  bool operator!=(const local_accessor_base &Rhs) const {
2394  return !(*this == Rhs);
2395  }
2396 };
2397 
2398 // TODO: Remove deprecated specialization once no longer needed
2399 template <typename DataT, int Dimensions, access::mode AccessMode,
2402  DataT, Dimensions, AccessMode, access::target::local, IsPlaceholder>
2403  : public local_accessor_base<DataT, Dimensions, AccessMode, IsPlaceholder>,
2404  public detail::OwnerLessBase<
2405  accessor<DataT, Dimensions, AccessMode, access::target::local,
2406  IsPlaceholder>> {
2407 
2408  using local_acc =
2410 
2411  static_assert(
2412  !local_acc::IsConst || local_acc::IsAccessReadOnly,
2413  "A const qualified DataT is only allowed for a read-only accessor");
2414 
2415  // Use base classes constructors
2416  using local_acc::local_acc;
2417 
2418 public:
2420  return local_ptr<DataT>(local_acc::getQualifiedPtr());
2421  }
2422 
2423 #ifdef __SYCL_DEVICE_ONLY__
2424 
2425  // __init needs to be defined within the class not through inheritance.
2426  // Map this function to inherited func.
2427  void __init(typename local_acc::ConcreteASPtrType Ptr,
2428  range<local_acc::AdjustedDim> AccessRange,
2431  local_acc::__init(Ptr, AccessRange, range, id);
2432  }
2433 
2434  // __init variant used by the device compiler for ESIMD kernels.
2435  // TODO: In ESIMD accessors usage is limited for now - access range, mem
2436  // range and offset are not supported.
2437  void __init_esimd(typename local_acc::ConcreteASPtrType Ptr) {
2438  local_acc::__init_esimd(Ptr);
2439  }
2440 
2441 public:
2442  // Default constructor for objects later initialized with __init member.
2443  accessor() {
2444  local_acc::impl = detail::InitializedVal<local_acc::AdjustedDim,
2445  range>::template get<0>();
2446  }
2447 
2448 #else
2449 private:
2450  accessor(const detail::AccessorImplPtr &Impl) : local_acc{Impl} {}
2451 #endif
2452 };
2453 
2454 template <typename DataT, int Dimensions = 1>
2455 class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor
2456  : public local_accessor_base<DataT, Dimensions,
2457  detail::accessModeFromConstness<DataT>(),
2458  access::placeholder::false_t>,
2459  public detail::OwnerLessBase<local_accessor<DataT, Dimensions>> {
2460 
2461  using local_acc =
2462  local_accessor_base<DataT, Dimensions,
2463  detail::accessModeFromConstness<DataT>(),
2465 
2466  static_assert(
2467  !local_acc::IsConst || local_acc::IsAccessReadOnly,
2468  "A const qualified DataT is only allowed for a read-only accessor");
2469 
2470  // Use base classes constructors
2471  using local_acc::local_acc;
2472 
2473 #ifdef __SYCL_DEVICE_ONLY__
2474 
2475  // __init needs to be defined within the class not through inheritance.
2476  // Map this function to inherited func.
2477  void __init(typename local_acc::ConcreteASPtrType Ptr,
2478  range<local_acc::AdjustedDim> AccessRange,
2479  range<local_acc::AdjustedDim> range,
2480  id<local_acc::AdjustedDim> id) {
2481  local_acc::__init(Ptr, AccessRange, range, id);
2482  }
2483 
2484  // __init variant used by the device compiler for ESIMD kernels.
2485  // TODO: In ESIMD accessors usage is limited for now - access range, mem
2486  // range and offset are not supported.
2487  void __init_esimd(typename local_acc::ConcreteASPtrType Ptr) {
2488  local_acc::__init_esimd(Ptr);
2489  }
2490 
2491 public:
2492  // Default constructor for objects later initialized with __init member.
2493  local_accessor() {
2494  local_acc::impl = detail::InitializedVal<local_acc::AdjustedDim,
2495  range>::template get<0>();
2496  }
2497 
2498 #else
2499  local_accessor(const detail::AccessorImplPtr &Impl) : local_acc{Impl} {}
2500 #endif
2501 
2502  // implicit conversion between non-const read-write accessor to const
2503  // read-only accessor
2504 public:
2505  template <typename DataT_,
2506  typename = std::enable_if_t<
2507  std::is_const_v<DataT> &&
2508  std::is_same_v<DataT_, std::remove_const_t<DataT>>>>
2509  local_accessor(const local_accessor<DataT_, Dimensions> &other) {
2510  local_acc::impl = other.impl;
2511 #ifdef __SYCL_DEVICE_ONLY__
2512  local_acc::MData = other.MData;
2513 #endif
2514  }
2515 
2516  using value_type = DataT;
2517  using iterator = value_type *;
2518  using const_iterator = const value_type *;
2519  using reverse_iterator = std::reverse_iterator<iterator>;
2520  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
2521  using difference_type =
2523  using size_type = std::size_t;
2524 
2525  template <access::decorated IsDecorated>
2526  using accessor_ptr = local_ptr<value_type, IsDecorated>;
2527 
2528  template <typename DataT_>
2529  bool operator==(const local_accessor<DataT_, Dimensions> &Rhs) const {
2530  return local_acc::impl == Rhs.impl;
2531  }
2532 
2533  template <typename DataT_>
2534  bool operator!=(const local_accessor<DataT_, Dimensions> &Rhs) const {
2535  return !(*this == Rhs);
2536  }
2537 
2538  void swap(local_accessor &other) { std::swap(this->impl, other.impl); }
2539 
2540  size_type byte_size() const noexcept { return this->size() * sizeof(DataT); }
2541 
2542  size_type max_size() const noexcept {
2544  }
2545 
2546  bool empty() const noexcept { return this->size() == 0; }
2547 
2548  iterator begin() const noexcept {
2549  if constexpr (Dimensions == 0)
2550  return local_acc::getQualifiedPtr();
2551  else
2552  return &this->operator[](id<Dimensions>());
2553  }
2554  iterator end() const noexcept {
2555  if constexpr (Dimensions == 0)
2556  return begin() + 1;
2557  else
2558  return begin() + this->size();
2559  }
2560 
2561  const_iterator cbegin() const noexcept { return const_iterator(begin()); }
2562  const_iterator cend() const noexcept { return const_iterator(end()); }
2563 
2564  reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
2565  reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
2566 
2567  const_reverse_iterator crbegin() const noexcept {
2568  return const_reverse_iterator(end());
2569  }
2570  const_reverse_iterator crend() const noexcept {
2571  return const_reverse_iterator(begin());
2572  }
2573 
2575  "local_accessor::get_pointer() is deprecated, please use get_multi_ptr()")
2576  local_ptr<DataT> get_pointer() const noexcept {
2577 #ifndef __SYCL_DEVICE_ONLY__
2578  throw sycl::exception(
2580  "get_pointer must not be called on the host for a local accessor");
2581 #endif
2582  return local_ptr<DataT>(local_acc::getQualifiedPtr());
2583  }
2584 
2585  template <access::decorated IsDecorated>
2586  accessor_ptr<IsDecorated> get_multi_ptr() const noexcept {
2587 #ifndef __SYCL_DEVICE_ONLY__
2588  throw sycl::exception(
2590  "get_multi_ptr must not be called on the host for a local accessor");
2591 #endif
2592  return accessor_ptr<IsDecorated>(local_acc::getQualifiedPtr());
2593  }
2594 
2595  template <typename Property> bool has_property() const noexcept {
2596 #ifndef __SYCL_DEVICE_ONLY__
2597  return this->getPropList().template has_property<Property>();
2598 #else
2599  return false;
2600 #endif
2601  }
2602 
2603  template <typename Property> Property get_property() const {
2604 #ifndef __SYCL_DEVICE_ONLY__
2605  return this->getPropList().template get_property<Property>();
2606 #else
2607  return Property();
2608 #endif
2609  }
2610 
2611  template <int Dims = Dimensions,
2612  typename = std::enable_if_t<!std::is_const_v<DataT> && Dims == 0>>
2613  const local_accessor &operator=(const value_type &Other) const {
2614  *local_acc::getQualifiedPtr() = Other;
2615  return *this;
2616  }
2617 
2618  template <int Dims = Dimensions,
2619  typename = std::enable_if_t<!std::is_const_v<DataT> && Dims == 0>>
2620  const local_accessor &operator=(value_type &&Other) const {
2621  *local_acc::getQualifiedPtr() = std::move(Other);
2622  return *this;
2623  }
2624 
2625 private:
2626  friend class sycl::ext::intel::esimd::detail::AccessorPrivateProxy;
2627 };
2628 
2629 template <typename DataT, int Dimensions = 1,
2632  : public accessor<DataT, Dimensions, AccessMode, target::host_buffer,
2633  access::placeholder::false_t> {
2634 protected:
2635  using AccessorT = accessor<DataT, Dimensions, AccessMode, target::host_buffer,
2637 
2638  constexpr static int AdjustedDim = Dimensions == 0 ? 1 : Dimensions;
2639  constexpr static bool IsAccessReadOnly = AccessMode == access::mode::read;
2640 
2641  template <typename T, int Dims>
2643  : std::bool_constant<std::is_same_v<T, DataT> && (Dims > 0) &&
2644  (Dims == Dimensions)> {};
2645 
2646  void
2647  __init(typename accessor<DataT, Dimensions, AccessMode, target::host_buffer,
2648  access::placeholder::false_t>::ConcreteASPtrType Ptr,
2649  range<AdjustedDim> AccessRange, range<AdjustedDim> MemRange,
2650  id<AdjustedDim> Offset) {
2651  AccessorT::__init(Ptr, AccessRange, MemRange, Offset);
2652  }
2653 
2654 #ifndef __SYCL_DEVICE_ONLY__
2656  : accessor<DataT, Dimensions, AccessMode, target::host_buffer,
2657  access::placeholder::false_t>{Impl} {}
2658 
2659  template <class Obj>
2660  friend const decltype(Obj::impl) &getSyclObjImpl(const Obj &SyclObject);
2661 
2662  template <class T>
2663  friend T detail::createSyclObjFromImpl(decltype(T::impl) ImplObj);
2664 #endif // __SYCL_DEVICE_ONLY__
2665 
2666 public:
2668 
2669  // The list of host_accessor constructors with their arguments
2670  // -------+---------+-------+----+----------+--------------
2671  // Dimensions = 0
2672  // -------+---------+-------+----+----------+--------------
2673  // buffer | | | | | property_list
2674  // buffer | handler | | | | property_list
2675  // -------+---------+-------+----+----------+--------------
2676  // Dimensions >= 1
2677  // -------+---------+-------+----+----------+--------------
2678  // buffer | | | | | property_list
2679  // buffer | | | | mode_tag | property_list
2680  // buffer | handler | | | | property_list
2681  // buffer | handler | | | mode_tag | property_list
2682  // buffer | | range | | | property_list
2683  // buffer | | range | | mode_tag | property_list
2684  // buffer | handler | range | | | property_list
2685  // buffer | handler | range | | mode_tag | property_list
2686  // buffer | | range | id | | property_list
2687  // buffer | | range | id | mode_tag | property_list
2688  // buffer | handler | range | id | | property_list
2689  // buffer | handler | range | id | mode_tag | property_list
2690  // -------+---------+-------+----+----------+--------------
2691 
2692  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2693  typename = typename std::enable_if_t<std::is_same_v<T, DataT> &&
2694  Dims == 0>>
2696  buffer<T, 1, AllocatorT> &BufferRef,
2697  const property_list &PropertyList = {},
2699  : AccessorT(BufferRef, PropertyList, CodeLoc) {}
2700 
2701  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2702  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2704  buffer<T, Dims, AllocatorT> &BufferRef,
2705  const property_list &PropertyList = {},
2707  : AccessorT(BufferRef, PropertyList, CodeLoc) {}
2708 
2709  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2710  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2713  const property_list &PropertyList = {},
2715  : host_accessor(BufferRef, PropertyList, CodeLoc) {}
2716 
2717  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2718  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2720  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2721  const property_list &PropertyList = {},
2723  : AccessorT(BufferRef, CommandGroupHandler, PropertyList, CodeLoc) {}
2724 
2725  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2726  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2728  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2729  mode_tag_t<AccessMode>, const property_list &PropertyList = {},
2731  : host_accessor(BufferRef, CommandGroupHandler, PropertyList, CodeLoc) {}
2732 
2733  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2734  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2736  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
2737  const property_list &PropertyList = {},
2739  : AccessorT(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {}
2740 
2741  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2742  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2744  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
2745  mode_tag_t<AccessMode>, const property_list &PropertyList = {},
2747  : host_accessor(BufferRef, AccessRange, {}, PropertyList, CodeLoc) {}
2748 
2749  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2750  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2752  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2753  range<Dimensions> AccessRange, const property_list &PropertyList = {},
2755  : AccessorT(BufferRef, CommandGroupHandler, AccessRange, {}, PropertyList,
2756  CodeLoc) {}
2757 
2758  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2759  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2761  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2763  const property_list &PropertyList = {},
2765  : host_accessor(BufferRef, CommandGroupHandler, AccessRange, {},
2766  PropertyList, CodeLoc) {}
2767 
2768  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2769  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2771  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
2772  id<Dimensions> AccessOffset, const property_list &PropertyList = {},
2774  : AccessorT(BufferRef, AccessRange, AccessOffset, PropertyList, CodeLoc) {
2775  }
2776 
2777  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2778  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2780  buffer<T, Dims, AllocatorT> &BufferRef, range<Dimensions> AccessRange,
2781  id<Dimensions> AccessOffset, mode_tag_t<AccessMode>,
2782  const property_list &PropertyList = {},
2784  : host_accessor(BufferRef, AccessRange, AccessOffset, PropertyList,
2785  CodeLoc) {}
2786 
2787  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2788  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2790  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2791  range<Dimensions> AccessRange, id<Dimensions> AccessOffset,
2792  const property_list &PropertyList = {},
2794  : AccessorT(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
2795  PropertyList, CodeLoc) {}
2796 
2797  template <typename T = DataT, int Dims = Dimensions, typename AllocatorT,
2798  typename = std::enable_if_t<IsSameAsBuffer<T, Dims>::value>>
2800  buffer<T, Dims, AllocatorT> &BufferRef, handler &CommandGroupHandler,
2801  range<Dimensions> AccessRange, id<Dimensions> AccessOffset,
2802  mode_tag_t<AccessMode>, const property_list &PropertyList = {},
2804  : host_accessor(BufferRef, CommandGroupHandler, AccessRange, AccessOffset,
2805  PropertyList, CodeLoc) {}
2806 
2807  template <int Dims = Dimensions,
2808  typename = std::enable_if_t<AccessMode != access_mode::atomic &&
2809  !IsAccessReadOnly && Dims == 0>>
2810  const host_accessor &
2811  operator=(const typename AccessorT::value_type &Other) const {
2812  *AccessorT::getQualifiedPtr() = Other;
2813  return *this;
2814  }
2815 
2816  template <int Dims = Dimensions,
2817  typename = std::enable_if_t<AccessMode != access_mode::atomic &&
2818  !IsAccessReadOnly && Dims == 0>>
2819  const host_accessor &operator=(typename AccessorT::value_type &&Other) const {
2820  *AccessorT::getQualifiedPtr() = std::move(Other);
2821  return *this;
2822  }
2823 
2824  // implicit conversion between const / non-const types for read only accessors
2825  template <typename DataT_,
2826  typename = std::enable_if_t<
2827  IsAccessReadOnly && !std::is_same_v<DataT_, DataT> &&
2828  std::is_same_v<std::remove_const_t<DataT_>,
2829  std::remove_const_t<DataT>>>>
2831 #ifndef __SYCL_DEVICE_ONLY__
2832  : host_accessor(other.impl) {
2833  AccessorT::MAccData = other.MAccData;
2834 #else
2835  {
2836  (void)other;
2837 #endif // __SYCL_DEVICE_ONLY__
2838  }
2839 
2840  // implicit conversion from read_write T accessor to read only T (const)
2841  // accessor
2842  template <typename DataT_, access::mode AccessMode_,
2843  typename = std::enable_if_t<
2844  (AccessMode_ == access_mode::read_write) && IsAccessReadOnly &&
2845  std::is_same_v<DataT_, std::remove_const_t<DataT>>>>
2847 #ifndef __SYCL_DEVICE_ONLY__
2848  : host_accessor(other.impl) {
2849  AccessorT::MAccData = other.MAccData;
2850 #else
2851  {
2852  (void)other;
2853 #endif // __SYCL_DEVICE_ONLY__
2854  }
2855 
2856  // host_accessor needs to explicitly define the owner_before member functions
2857  // as inheriting from OwnerLessBase causes base class conflicts.
2858  // TODO: Once host_accessor is detached from accessor, inherit from
2859  // OwnerLessBase instead.
2860 #ifndef __SYCL_DEVICE_ONLY__
2863  const noexcept {
2864  return this->impl.owner_before(
2866  }
2867 
2869  return this->impl.owner_before(Other.impl);
2870  }
2871 #else
2872  bool ext_oneapi_owner_before(
2874  const noexcept;
2875  bool ext_oneapi_owner_before(const host_accessor &Other) const noexcept;
2876 #endif
2877 };
2878 
2879 template <typename DataT, int Dimensions, typename AllocatorT>
2882 
2883 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1>
2885  -> host_accessor<DataT, Dimensions,
2886  detail::deduceAccessMode<Type1, Type1>()>;
2887 
2888 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2889  typename Type2>
2891  -> host_accessor<DataT, Dimensions,
2892  detail::deduceAccessMode<Type1, Type2>()>;
2893 
2894 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2895  typename Type2, typename Type3>
2897  -> host_accessor<DataT, Dimensions,
2898  detail::deduceAccessMode<Type2, Type3>()>;
2899 
2900 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2901  typename Type2, typename Type3, typename Type4>
2903  -> host_accessor<DataT, Dimensions,
2904  detail::deduceAccessMode<Type3, Type4>()>;
2905 
2906 template <typename DataT, int Dimensions, typename AllocatorT, typename Type1,
2907  typename Type2, typename Type3, typename Type4, typename Type5>
2909  Type5) -> host_accessor<DataT, Dimensions,
2910  detail::deduceAccessMode<Type4, Type5>()>;
2911 
2912 } // namespace _V1
2913 } // namespace sycl
2914 
2915 namespace std {
2916 template <typename DataT, int Dimensions, sycl::access::mode AccessMode,
2917  sycl::access::target AccessTarget,
2919 struct hash<sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget,
2920  IsPlaceholder>> {
2921  using AccType = sycl::accessor<DataT, Dimensions, AccessMode, AccessTarget,
2922  IsPlaceholder>;
2923 
2924  size_t operator()(const AccType &A) const {
2925 #ifdef __SYCL_DEVICE_ONLY__
2926  // Hash is not supported on DEVICE. Just return 0 here.
2927  (void)A;
2928  return 0;
2929 #else
2930  // getSyclObjImpl() here returns a pointer to either AccessorImplHost
2931  // or LocalAccessorImplHost depending on the AccessTarget.
2932  auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2933  return hash<decltype(AccImplPtr)>()(AccImplPtr);
2934 #endif
2935  }
2936 };
2937 
2938 template <typename DataT, int Dimensions, sycl::access_mode AccessMode>
2939 struct hash<sycl::host_accessor<DataT, Dimensions, AccessMode>> {
2941 
2942  size_t operator()(const AccType &A) const {
2943 #ifdef __SYCL_DEVICE_ONLY__
2944  // Hash is not supported on DEVICE. Just return 0 here.
2945  (void)A;
2946  return 0;
2947 #else
2948  // getSyclObjImpl() here returns a pointer to AccessorImplHost.
2949  auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2950  return hash<decltype(AccImplPtr)>()(AccImplPtr);
2951 #endif
2952  }
2953 };
2954 
2955 template <typename DataT, int Dimensions>
2956 struct hash<sycl::local_accessor<DataT, Dimensions>> {
2958 
2959  size_t operator()(const AccType &A) const {
2960 #ifdef __SYCL_DEVICE_ONLY__
2961  // Hash is not supported on DEVICE. Just return 0 here.
2962  (void)A;
2963  return 0;
2964 #else
2965  // getSyclObjImpl() here returns a pointer to LocalAccessorImplHost.
2966  auto AccImplPtr = sycl::detail::getSyclObjImpl(A);
2967  return hash<decltype(AccImplPtr)>()(AccImplPtr);
2968 #endif
2969  }
2970 };
2971 
2972 } // namespace std
The file contains implementation of accessor iterator class.
Defines a shared array that can be used by kernels in queues.
Definition: buffer.hpp:173
AccessorBaseHost(const AccessorImplPtr &Impl)
Definition: accessor.hpp:518
AccessorImplDevice(id< Dims > Offset, range< Dims > AccessRange, range< Dims > MemoryRange)
Definition: accessor.hpp:494
bool operator==(const AccessorImplDevice &Rhs) const
Definition: accessor.hpp:502
LocalAccessorBaseDevice(sycl::range< Dims > Size)
Definition: accessor.hpp:472
bool operator==(const LocalAccessorBaseDevice &Rhs) const
Definition: accessor.hpp:481
LocalAccessorBaseHost(const LocalAccessorImplPtr &Impl)
Definition: accessor.hpp:574
std::enable_if_t< CurDims==1 &&IsAccessAtomic, atomic< DataT, AS > > operator[](size_t Index) const
Definition: accessor.hpp:377
AccessorSubscript(AccType Accessor, size_t Index)
Definition: accessor.hpp:357
AccessorSubscript(AccType Accessor, id< Dims > IDs)
Definition: accessor.hpp:352
constexpr static access::address_space AS
Definition: accessor.hpp:296
constexpr static bool IsAccessReadWrite
Definition: accessor.hpp:330
static constexpr bool IsConst
Definition: accessor.hpp:328
constexpr static bool IsAccessAtomic
Definition: accessor.hpp:333
constexpr static bool IsHostBuf
Definition: accessor.hpp:298
constexpr static bool IsHostTask
Definition: accessor.hpp:299
constexpr static bool IsAccessReadOnly
Definition: accessor.hpp:327
constexpr static bool IsAccessAnyWrite
Definition: accessor.hpp:321
constexpr static bool IsPlaceH
Definition: accessor.hpp:310
detail::const_if_const_AS< AS, DataT > * PtrType
Definition: accessor.hpp:337
detail::const_if_const_AS< AS, DataT > & RefType
Definition: accessor.hpp:335
constexpr static bool IsConstantBuf
Definition: accessor.hpp:318
constexpr static bool IsGlobalBuf
Definition: accessor.hpp:315
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
Command group handler class.
Definition: handler.hpp:467
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2727
host_accessor(buffer< T, 1, AllocatorT > &BufferRef, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2695
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, range< Dimensions > AccessRange, id< Dimensions > AccessOffset, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2789
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, range< Dimensions > AccessRange, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2751
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2711
bool ext_oneapi_owner_before(const ext::oneapi::detail::weak_object_base< host_accessor > &Other) const noexcept
Definition: accessor.hpp:2861
void __init(typename accessor< DataT, Dimensions, AccessMode, target::host_buffer, access::placeholder::false_t >::ConcreteASPtrType Ptr, range< AdjustedDim > AccessRange, range< AdjustedDim > MemRange, id< AdjustedDim > Offset)
Definition: accessor.hpp:2647
host_accessor(const host_accessor< DataT_, Dimensions, AccessMode > &other)
Definition: accessor.hpp:2830
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, range< Dimensions > AccessRange, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2760
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, range< Dimensions > AccessRange, id< Dimensions > AccessOffset, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2770
const host_accessor & operator=(typename AccessorT::value_type &&Other) const
Definition: accessor.hpp:2819
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2719
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, range< Dimensions > AccessRange, id< Dimensions > AccessOffset, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2779
bool ext_oneapi_owner_before(const host_accessor &Other) const noexcept
Definition: accessor.hpp:2868
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, handler &CommandGroupHandler, range< Dimensions > AccessRange, id< Dimensions > AccessOffset, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2799
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, range< Dimensions > AccessRange, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2735
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, range< Dimensions > AccessRange, mode_tag_t< AccessMode >, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2743
host_accessor(const detail::AccessorImplPtr &Impl)
Definition: accessor.hpp:2655
host_accessor(buffer< T, Dims, AllocatorT > &BufferRef, const property_list &PropertyList={}, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2703
host_accessor(const host_accessor< DataT_, Dimensions, AccessMode_ > &other)
Definition: accessor.hpp:2846
const host_accessor & operator=(const typename AccessorT::value_type &Other) const
Definition: accessor.hpp:2811
frienddecltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
A unique identifier of an item in an index space.
Definition: id.hpp:36
detail::const_if_const_AS< AS, DataT > & RefType
Definition: accessor.hpp:2160
const range< 3 > & getSize() const
Definition: accessor.hpp:2214
bool operator!=(const local_accessor_base &Rhs) const
Definition: accessor.hpp:2393
AccessorCommonT::template AccessorSubscript< Dims - 1, local_accessor_base< DataT, Dimensions, AccessMode, IsPlaceholder > > operator[](size_t Index) const
Definition: accessor.hpp:2386
local_accessor_base(range< Dimensions > AllocationSize, handler &, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2288
range< Dims > get_range() const
Definition: accessor.hpp:2331
local_accessor_base(handler &, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2255
typename detail::DecoratedType< DataT, AS >::type * ConcreteASPtrType
Definition: accessor.hpp:2158
typename AccessorCommonT::template AccessorSubscript< Dims, local_accessor_base< DataT, Dimensions, AccessMode, IsPlaceholder > > AccessorSubscript
Definition: accessor.hpp:2156
size_t getLinearIndex(id< Dims > Id) const
Definition: accessor.hpp:2233
local_accessor_base(range< Dimensions > AllocationSize, handler &, const property_list &propList, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2306
local_accessor_base(handler &, const property_list &propList, const detail::code_location CodeLoc=detail::code_location::current())
Definition: accessor.hpp:2270
bool operator==(const local_accessor_base &Rhs) const
Definition: accessor.hpp:2390
__SYCL2020_DEPRECATED("get_count() is deprecated, please use size() instead") size_t get_count() const
Definition: accessor.hpp:2326
detail::const_if_const_AS< AS, DataT > * PtrType
Definition: accessor.hpp:2161
size_t size() const noexcept
Definition: accessor.hpp:2328
std::enable_if_t< Dims==1 &&AccessMode==access::mode::atomic, atomic< DataT, AS > > operator[](size_t Index) const
Definition: accessor.hpp:2377
RefType operator[](id< Dimensions > Index) const
Definition: accessor.hpp:2345
PtrType getQualifiedPtr() const
Definition: accessor.hpp:2208
local_accessor_base(const detail::LocalAccessorImplPtr &Impl)
Definition: accessor.hpp:2201
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:26
#define __SYCL_SPECIAL_CLASS
Definition: defines.hpp:29
#define __SYCL_EBO
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor< DataT
Image accessors.
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(accessor) accessor accessor(buffer< DataT, Dimensions, AllocatorT >) -> accessor< DataT, Dimensions, access::mode::read_write, target::device, access::placeholder::true_t >
Buffer accessor.
decltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
Definition: impl_utils.hpp:31
void addHostAccessorAndWait(AccessorImplHost *Req)
device getDeviceFromHandler(handler &CommandGroupHandlerRef)
Definition: accessor.cpp:17
size_t getLinearIndex(const T< Dims > &Index, const U< Dims > &Range)
Definition: common.hpp:286
sycl::range< 1 > GetZeroDimAccessRange(BufferT Buffer)
Definition: accessor.hpp:285
constexpr access::mode accessModeFromConstness()
Definition: accessor.hpp:384
typename std::is_same< ext::oneapi::accessor_property_list<>, T > IsRunTimePropertyListT
Definition: accessor.hpp:267
void constructorNotification(void *BufferObj, void *AccessorObj, access::target Target, access::mode Mode, const code_location &CodeLoc)
T createSyclObjFromImpl(decltype(T::impl) ImplObj)
Definition: impl_utils.hpp:40
std::shared_ptr< LocalAccessorImplHost > LocalAccessorImplPtr
Definition: accessor.hpp:570
struct __SYCL2020_DEPRECATED("This type isn't device copyable in SYCL 2020") IsDeprecatedDeviceCopyable< T
constexpr access::target deduceAccessTarget(access::target defaultTarget)
Definition: accessor.hpp:439
typename std::is_base_of< PropertyListBase, T > IsPropertyListT
Definition: accessor.hpp:263
constexpr access::mode deduceAccessMode()
Definition: accessor.hpp:392
constexpr register_alloc_mode_key::value_t< Mode > register_alloc_mode __SYCL_DEPRECATED("register_alloc_mode is deprecated, " "use sycl::ext::intel::experimental::grf_size or " "sycl::ext::intel::experimental::grf_size_automatic")
void associateWithHandler(handler &, AccessorBaseHost *, access::target)
std::shared_ptr< AccessorImplHost > AccessorImplPtr
Definition: accessor.hpp:514
constexpr buffer_location_key::value_t< N > buffer_location
bool operator==(const cache_config &lhs, const cache_config &rhs)
bool operator!=(const cache_config &lhs, const cache_config &rhs)
decltype(weak_object_base< SYCLObjT >::MObjWeakPtr) getSyclWeakObjImpl(const weak_object_base< SYCLObjT > &WeakObj)
static constexpr bool has_property()
sycl::ext::oneapi::experimental::annotated_ref< T, property_list_t > reference
static constexpr auto get_property()
T & operator[](std::ptrdiff_t idx) const noexcept
access::mode access_mode
Definition: access.hpp:72
host_accessor(buffer< DataT, Dimensions, AllocatorT >) -> host_accessor< DataT, Dimensions, access::mode::read_write >
class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
multi_ptr< ElementType, access::address_space::global_space, IsDecorated > global_ptr
Definition: pointers.hpp:29
return(x >> one)+(y >> one)+((y &x) &one)
constexpr mode_tag_t< access_mode::read_write > read_write
Definition: access.hpp:85
pointer get() const
Definition: multi_ptr.hpp:544
std::ptrdiff_t difference_type
Definition: multi_ptr.hpp:460
class __SYCL_EBO __SYCL_SPECIAL_CLASS IsPlaceholder
PropertyListT int access::address_space multi_ptr & operator=(multi_ptr &&)=default
PropertyListT Accessor
Definition: multi_ptr.hpp:510
accessor(buffer< DataT, Dimensions, AllocatorT >, handler &, Type1, Type2, Type3, Type4, const ext::oneapi::accessor_property_list< PropsT... > &) -> accessor< DataT, Dimensions, detail::deduceAccessMode< Type3, Type4 >(), detail::deduceAccessTarget< Type3, Type4 >(target::device), access::placeholder::false_t, ext::oneapi::accessor_property_list< PropsT... >>
class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:65
multi_ptr< ElementType, access::address_space::local_space, IsDecorated > local_ptr
Definition: pointers.hpp:34
const void value_type
Definition: multi_ptr.hpp:457
Definition: access.hpp:18
static size_t get_offset(sycl::id< 3 > id, size_t slice, size_t pitch)
Definition: memory.hpp:329
_Abi const simd< _Tp, _Abi > & noexcept
Definition: simd.hpp:1324
sycl::range< 3 > MMemoryRange
Definition: accessor.hpp:252
sycl::range< 3 > MAccessRange
Definition: accessor.hpp:251
AccHostDataT(const sycl::id< 3 > &Offset, const sycl::range< 3 > &Range, const sycl::range< 3 > &MemoryRange, void *Data=nullptr)
Definition: accessor.hpp:245
constexpr static bool value
Definition: accessor.hpp:270
static constexpr code_location current(const char *fileName=__CODELOC_FILE_NAME, const char *funcName=__CODELOC_FUNCTION, unsigned long lineNo=__CODELOC_LINE, unsigned long columnNo=__CODELOC_COLUMN) noexcept
Definition: common.hpp:68