9
9
#pragma once
10
10
11
11
#include < CL/sycl/access/access.hpp>
12
+ #include < CL/sycl/atomic.hpp>
12
13
#include < CL/sycl/context.hpp>
13
14
#include < CL/sycl/detail/cg.hpp>
14
15
#include < CL/sycl/detail/export.hpp>
@@ -366,6 +367,107 @@ class __SYCL_EXPORT handler {
366
367
return true ;
367
368
}
368
369
370
+ // / Handles some special cases of the copy operation from one accessor
371
+ // / to another accessor. Returns true if the copy is handled here.
372
+ // /
373
+ // / \param Src is a source SYCL accessor.
374
+ // / \param Dst is a destination SYCL accessor.
375
+ // TODO: support atomic accessor in Src or/and Dst.
376
+ template <typename TSrc, int DimSrc, access::mode ModeSrc,
377
+ access::target TargetSrc, typename TDst, int DimDst,
378
+ access::mode ModeDst, access::target TargetDst,
379
+ access::placeholder IsPHSrc, access::placeholder IsPHDst>
380
+ detail::enable_if_t <(DimSrc > 0 ) && (DimDst > 0 ), bool >
381
+ copyAccToAccHelper (accessor<TSrc, DimSrc, ModeSrc, TargetSrc, IsPHSrc> Src,
382
+ accessor<TDst, DimDst, ModeDst, TargetDst, IsPHDst> Dst) {
383
+ if (!MIsHost &&
384
+ IsCopyingRectRegionAvailable (Src.get_range (), Dst.get_range ()))
385
+ return false ;
386
+
387
+ range<1 > LinearizedRange (Src.get_count ());
388
+ parallel_for<class __copyAcc2Acc <TSrc, DimSrc, ModeSrc, TargetSrc,
389
+ TDst, DimDst, ModeDst, TargetDst,
390
+ IsPHSrc, IsPHDst>>
391
+ (LinearizedRange, [=](id<1 > Id) {
392
+ size_t Index = Id[0 ];
393
+ id<DimSrc> SrcIndex = getDelinearizedIndex (Src.get_range (), Index);
394
+ id<DimDst> DstIndex = getDelinearizedIndex (Dst.get_range (), Index);
395
+ Dst[DstIndex] = Src[SrcIndex];
396
+ });
397
+ return true ;
398
+ }
399
+
400
+ template <typename T, int Dim, access::mode Mode, access::target Target,
401
+ access::placeholder IsPH>
402
+ detail::enable_if_t <Dim == 0 && Mode == access::mode::atomic, T>
403
+ readFromFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Src) const {
404
+ atomic<T, access ::address_space::global_space> AtomicSrc = Src;
405
+ return AtomicSrc.load ();
406
+ }
407
+
408
+ template <typename T, int Dim, access::mode Mode, access::target Target,
409
+ access::placeholder IsPH>
410
+ detail::enable_if_t <(Dim > 0 ) && Mode == access::mode::atomic, T>
411
+ readFromFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Src) const {
412
+ id<Dim> Id = getDelinearizedIndex (Src.get_range (), 0 );
413
+ return Src[Id].load ();
414
+ }
415
+
416
+ template <typename T, int Dim, access::mode Mode, access::target Target,
417
+ access::placeholder IsPH>
418
+ detail::enable_if_t <Mode != access::mode::atomic, T>
419
+ readFromFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Src) const {
420
+ return *(Src.get_pointer ());
421
+ }
422
+
423
+ template <typename T, int Dim, access::mode Mode, access::target Target,
424
+ access::placeholder IsPH>
425
+ detail::enable_if_t <Dim == 0 && Mode == access::mode::atomic, void >
426
+ writeToFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
427
+ atomic<T, access ::address_space::global_space> AtomicDst = Dst;
428
+ AtomicDst.store (V);
429
+ }
430
+
431
+ template <typename T, int Dim, access::mode Mode, access::target Target,
432
+ access::placeholder IsPH>
433
+ detail::enable_if_t <(Dim > 0 ) && Mode == access::mode::atomic, void >
434
+ writeToFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
435
+ id<Dim> Id = getDelinearizedIndex (Dst.get_range (), 0 );
436
+ Dst[Id].store (V);
437
+ }
438
+
439
+ template <typename T, int Dim, access::mode Mode, access::target Target,
440
+ access::placeholder IsPH>
441
+ detail::enable_if_t <Mode != access::mode::atomic, void >
442
+ writeToFirstAccElement (accessor<T, Dim, Mode, Target, IsPH> Dst, T V) const {
443
+ *(Dst.get_pointer ()) = V;
444
+ }
445
+
446
+ // / Handles some special cases of the copy operation from one accessor
447
+ // / to another accessor. Returns true if the copy is handled here.
448
+ // /
449
+ // / Source must have at least as many bytes as the range accessed by Dst.
450
+ // /
451
+ // / \param Src is a source SYCL accessor.
452
+ // / \param Dst is a destination SYCL accessor.
453
+ template <typename TSrc, int DimSrc, access::mode ModeSrc,
454
+ access::target TargetSrc, typename TDst, int DimDst,
455
+ access::mode ModeDst, access::target TargetDst,
456
+ access::placeholder IsPHSrc, access::placeholder IsPHDst>
457
+ detail::enable_if_t <DimSrc == 0 || DimDst == 0 , bool >
458
+ copyAccToAccHelper (accessor<TSrc, DimSrc, ModeSrc, TargetSrc, IsPHSrc> Src,
459
+ accessor<TDst, DimDst, ModeDst, TargetDst, IsPHDst> Dst) {
460
+ if (!MIsHost)
461
+ return false ;
462
+
463
+ single_task<class __copyAcc2Acc <TSrc, DimSrc, ModeSrc, TargetSrc,
464
+ TDst, DimDst, ModeDst, TargetDst,
465
+ IsPHSrc, IsPHDst>> ([=]() {
466
+ writeToFirstAccElement (Dst, readFromFirstAccElement (Src));
467
+ });
468
+ return true ;
469
+ }
470
+
369
471
constexpr static bool isConstOrGlobal (access::target AccessTarget) {
370
472
return AccessTarget == access ::target::global_buffer ||
371
473
AccessTarget == access ::target::constant_buffer;
@@ -985,6 +1087,7 @@ class __SYCL_EXPORT handler {
985
1087
// /
986
1088
// / \param Src is a source SYCL accessor.
987
1089
// / \param Dst is a pointer to destination memory.
1090
+ // TODO: support 0-dimensional and atomic accessors.
988
1091
template <typename T_Src, typename T_Dst, int Dims, access::mode AccessMode,
989
1092
access::target AccessTarget,
990
1093
access::placeholder IsPlaceholder = access::placeholder::false_t >
@@ -1030,6 +1133,7 @@ class __SYCL_EXPORT handler {
1030
1133
// /
1031
1134
// / \param Src is a pointer to source memory.
1032
1135
// / \param Dst is a destination SYCL accessor.
1136
+ // TODO: support 0-dimensional and atomic accessors.
1033
1137
template <typename T_Src, typename T_Dst, int Dims, access::mode AccessMode,
1034
1138
access::target AccessTarget,
1035
1139
access::placeholder IsPlaceholder = access::placeholder::false_t >
@@ -1072,7 +1176,7 @@ class __SYCL_EXPORT handler {
1072
1176
// / Copies the contents of memory object accessed by Src to the memory
1073
1177
// / object accessed by Dst.
1074
1178
// /
1075
- // / Source must have at least as many bytes as the range accessed by Dst .
1179
+ // / Dst must have at least as many bytes as the range accessed by Src .
1076
1180
// /
1077
1181
// / \param Src is a source SYCL accessor.
1078
1182
// / \param Dst is a destination SYCL accessor.
@@ -1093,32 +1197,10 @@ class __SYCL_EXPORT handler {
1093
1197
" Invalid source accessor target for the copy method." );
1094
1198
static_assert (isValidTargetForExplicitOp (AccessTarget_Dst),
1095
1199
" Invalid destination accessor target for the copy method." );
1096
- // TODO replace to get_size() when it will provide correct values.
1097
- assert (
1098
- (Dst.get_range ().size () * sizeof (T_Dst) >=
1099
- Src.get_range ().size () * sizeof (T_Src)) &&
1100
- " dest must have at least as many bytes as the range accessed by src." );
1101
- if (MIsHost ||
1102
- !IsCopyingRectRegionAvailable (Src.get_range (), Dst.get_range ())) {
1103
- range<Dims_Src> CopyRange = Src.get_range ();
1104
- size_t Range = 1 ;
1105
- for (size_t I = 0 ; I < Dims_Src; ++I)
1106
- Range *= CopyRange[I];
1107
- range<1 > LinearizedRange (Range);
1108
- parallel_for< class __copyAcc2Acc < T_Src, Dims_Src, AccessMode_Src,
1109
- AccessTarget_Src, T_Dst, Dims_Dst,
1110
- AccessMode_Dst, AccessTarget_Dst,
1111
- IsPlaceholder_Src,
1112
- IsPlaceholder_Dst>>
1113
- (LinearizedRange, [=](id<1 > Id) {
1114
- size_t Index = Id[0 ];
1115
- id<Dims_Src> SrcIndex = getDelinearizedIndex (Src.get_range (), Index);
1116
- id<Dims_Dst> DstIndex = getDelinearizedIndex (Dst.get_range (), Index);
1117
- Dst[DstIndex] = Src[SrcIndex];
1118
- });
1119
-
1200
+ assert (Dst.get_size () >= Src.get_size () &&
1201
+ " The destination accessor does not fit the copied memory." );
1202
+ if (copyAccToAccHelper (Src, Dst))
1120
1203
return ;
1121
- }
1122
1204
MCGType = detail::CG::COPY_ACC_TO_ACC;
1123
1205
1124
1206
detail::AccessorBaseHost *AccBaseSrc = (detail::AccessorBaseHost *)&Src;
0 commit comments