Skip to content

Commit aedd449

Browse files
authored
[SYCL] Support scalar accessor in handler::copy(acc,ptr) and copy(ptr,acc) (#1634)
Signed-off-by: Vyacheslav N Klochkov <[email protected]>
1 parent 16d866b commit aedd449

File tree

2 files changed

+128
-29
lines changed

2 files changed

+128
-29
lines changed

sycl/include/CL/sycl/handler.hpp

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,79 @@ class __SYCL_EXPORT handler {
522522
return true;
523523
}
524524

525+
#ifndef __SYCL_DEVICE_ONLY__
526+
/// Copies the content of memory object accessed by Src into the memory
527+
/// pointed by Dst.
528+
///
529+
/// \param Src is a source SYCL accessor.
530+
/// \param Dst is a pointer to destination memory.
531+
template <typename TSrc, typename TDst, int Dim, access::mode AccMode,
532+
access::target AccTarget, access::placeholder IsPH>
533+
detail::enable_if_t<(Dim > 0)>
534+
copyAccToPtrHost(accessor<TSrc, Dim, AccMode, AccTarget, IsPH> Src,
535+
TDst *Dst) {
536+
range<Dim> Range = Src.get_range();
537+
parallel_for<class __copyAcc2Ptr<TSrc, TDst, Dim, AccMode, AccTarget, IsPH>>
538+
(Range, [=](id<Dim> Index) {
539+
size_t LinearIndex = Index[0];
540+
for (int I = 1; I < Dim; ++I)
541+
LinearIndex += Range[I] * Index[I];
542+
(reinterpret_cast<TSrc *>(Dst))[LinearIndex] = Src[Index];
543+
});
544+
}
545+
546+
/// Copies 1 element accessed by 0-dimensional accessor Src into the memory
547+
/// pointed by Dst.
548+
///
549+
/// \param Src is a source SYCL accessor.
550+
/// \param Dst is a pointer to destination memory.
551+
template <typename TSrc, typename TDst, int Dim, access::mode AccMode,
552+
access::target AccTarget, access::placeholder IsPH>
553+
detail::enable_if_t<Dim == 0>
554+
copyAccToPtrHost(accessor<TSrc, Dim, AccMode, AccTarget, IsPH> Src,
555+
TDst *Dst) {
556+
single_task<class __copyAcc2Ptr<TSrc, TDst, Dim, AccMode, AccTarget, IsPH>>
557+
([=]() {
558+
*Dst = readFromFirstAccElement(Src);
559+
});
560+
}
561+
562+
/// Copies the memory pointed by Src into the memory accessed by Dst.
563+
///
564+
/// \param Src is a pointer to source memory.
565+
/// \param Dst is a destination SYCL accessor.
566+
template <typename TSrc, typename TDst, int Dim, access::mode AccMode,
567+
access::target AccTarget, access::placeholder IsPH>
568+
detail::enable_if_t<(Dim > 0)>
569+
copyPtrToAccHost(TDst *Src,
570+
accessor<TSrc, Dim, AccMode, AccTarget, IsPH> Dst) {
571+
range<Dim> Range = Dst.get_range();
572+
parallel_for<class __copyPtr2Acc<TSrc, TDst, Dim, AccMode, AccTarget, IsPH>>
573+
(Range, [=](id<Dim> Index) {
574+
size_t LinearIndex = Index[0];
575+
for (int I = 1; I < Dim; ++I)
576+
LinearIndex += Range[I] * Index[I];
577+
Dst[Index] = (reinterpret_cast<TDst *>(Src))[LinearIndex];
578+
});
579+
}
580+
581+
/// Copies 1 element pointed by Src to memory accessed by 0-dimensional
582+
/// accessor Dst.
583+
///
584+
/// \param Src is a pointer to source memory.
585+
/// \param Dst is a destination SYCL accessor.
586+
template <typename TSrc, typename TDst, int Dim, access::mode AccMode,
587+
access::target AccTarget, access::placeholder IsPH>
588+
detail::enable_if_t<Dim == 0>
589+
copyPtrToAccHost(TDst *Src,
590+
accessor<TSrc, Dim, AccMode, AccTarget, IsPH> Dst) {
591+
single_task<class __copyPtr2Acc<TSrc, TDst, Dim, AccMode, AccTarget, IsPH>>
592+
([=]() {
593+
writeToFirstAccElement(Dst, *Src);
594+
});
595+
}
596+
#endif // __SYCL_DEVICE_ONLY__
597+
525598
constexpr static bool isConstOrGlobal(access::target AccessTarget) {
526599
return AccessTarget == access::target::global_buffer ||
527600
AccessTarget == access::target::constant_buffer;
@@ -1206,7 +1279,7 @@ class __SYCL_EXPORT handler {
12061279

12071280
// Explicit copy operations API
12081281

1209-
/// Copies the contents of memory object accessed by Src into the memory
1282+
/// Copies the content of memory object accessed by Src into the memory
12101283
/// pointed by Dst.
12111284
///
12121285
/// Source must have at least as many bytes as the range accessed by Dst.
@@ -1228,7 +1301,7 @@ class __SYCL_EXPORT handler {
12281301
copy(Src, RawDstPtr);
12291302
}
12301303

1231-
/// Copies the contents of memory pointed by Src into the memory object
1304+
/// Copies the content of memory pointed by Src into the memory object
12321305
/// accessed by Dst.
12331306
///
12341307
/// Source must have at least as many bytes as the range accessed by Dst.
@@ -1251,14 +1324,13 @@ class __SYCL_EXPORT handler {
12511324
copy(RawSrcPtr, Dst);
12521325
}
12531326

1254-
/// Copies the contents of memory object accessed by Src into the memory
1327+
/// Copies the content of memory object accessed by Src into the memory
12551328
/// pointed by Dst.
12561329
///
12571330
/// Source must have at least as many bytes as the range accessed by Dst.
12581331
///
12591332
/// \param Src is a source SYCL accessor.
12601333
/// \param Dst is a pointer to destination memory.
1261-
// TODO: support 0-dimensional and atomic accessors.
12621334
template <typename T_Src, typename T_Dst, int Dims, access::mode AccessMode,
12631335
access::target AccessTarget,
12641336
access::placeholder IsPlaceholder = access::placeholder::false_t>
@@ -1270,17 +1342,8 @@ class __SYCL_EXPORT handler {
12701342
#ifndef __SYCL_DEVICE_ONLY__
12711343
if (MIsHost) {
12721344
// TODO: Temporary implementation for host. Should be handled by memory
1273-
// manger.
1274-
range<Dims> Range = Src.get_range();
1275-
parallel_for< class __copyAcc2Ptr< T_Src, T_Dst, Dims, AccessMode,
1276-
AccessTarget, IsPlaceholder>>
1277-
(Range, [=](id<Dims> Index) {
1278-
size_t LinearIndex = Index[0];
1279-
for (int I = 1; I < Dims; ++I)
1280-
LinearIndex += Range[I] * Index[I];
1281-
((T_Src *)Dst)[LinearIndex] = Src[Index];
1282-
});
1283-
1345+
// manager.
1346+
copyAccToPtrHost(Src, Dst);
12841347
return;
12851348
}
12861349
#endif
@@ -1297,14 +1360,13 @@ class __SYCL_EXPORT handler {
12971360
MAccStorage.push_back(std::move(AccImpl));
12981361
}
12991362

1300-
/// Copies the contents of memory pointed by Src into the memory object
1363+
/// Copies the content of memory pointed by Src into the memory object
13011364
/// accessed by Dst.
13021365
///
13031366
/// Source must have at least as many bytes as the range accessed by Dst.
13041367
///
13051368
/// \param Src is a pointer to source memory.
13061369
/// \param Dst is a destination SYCL accessor.
1307-
// TODO: support 0-dimensional and atomic accessors.
13081370
template <typename T_Src, typename T_Dst, int Dims, access::mode AccessMode,
13091371
access::target AccessTarget,
13101372
access::placeholder IsPlaceholder = access::placeholder::false_t>
@@ -1317,17 +1379,8 @@ class __SYCL_EXPORT handler {
13171379
#ifndef __SYCL_DEVICE_ONLY__
13181380
if (MIsHost) {
13191381
// TODO: Temporary implementation for host. Should be handled by memory
1320-
// manger.
1321-
range<Dims> Range = Dst.get_range();
1322-
parallel_for< class __copyPtr2Acc< T_Src, T_Dst, Dims, AccessMode,
1323-
AccessTarget, IsPlaceholder>>
1324-
(Range, [=](id<Dims> Index) {
1325-
size_t LinearIndex = Index[0];
1326-
for (int I = 1; I < Dims; ++I)
1327-
LinearIndex += Range[I] * Index[I];
1328-
1329-
Dst[Index] = ((T_Dst *)Src)[LinearIndex];
1330-
});
1382+
// manager.
1383+
copyPtrToAccHost(Src, Dst);
13311384
return;
13321385
}
13331386
#endif
@@ -1344,7 +1397,7 @@ class __SYCL_EXPORT handler {
13441397
MAccStorage.push_back(std::move(AccImpl));
13451398
}
13461399

1347-
/// Copies the contents of memory object accessed by Src to the memory
1400+
/// Copies the content of memory object accessed by Src to the memory
13481401
/// object accessed by Dst.
13491402
///
13501403
/// Dst must have at least as many bytes as the range accessed by Src.

sycl/test/basic_tests/handler/handler_mem_op.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,20 @@ template <typename T> void test_copy_ptr_acc() {
251251
for (size_t I = 0; I < Size; ++I) {
252252
assert(Data[I] == Values[I]);
253253
}
254+
255+
// Check copy from memory to 0-dimensional accessor.
256+
T SrcValue = 99;
257+
T DstValue = 0;
258+
{
259+
buffer<T, 1> DstBuf(&DstValue, range<1>(1));
260+
queue Queue;
261+
Queue.submit([&](handler &Cgh) {
262+
accessor<T, 0, access::mode::discard_write, access::target::global_buffer>
263+
DstAcc(DstBuf, Cgh);
264+
Cgh.copy(&SrcValue, DstAcc);
265+
});
266+
}
267+
assert(DstValue == 99);
254268
}
255269

256270
template <typename T> void test_copy_acc_ptr() {
@@ -272,6 +286,38 @@ template <typename T> void test_copy_acc_ptr() {
272286
for (size_t I = 0; I < Size; ++I) {
273287
assert(Data[I] == Values[I]);
274288
}
289+
290+
// Check copy from 0-dimensional accessor to memory
291+
T SrcValue = 99;
292+
T DstValue = 0;
293+
{
294+
buffer<T, 1> SrcBuf(&SrcValue, range<1>(1));
295+
queue Queue;
296+
Queue.submit([&](handler &Cgh) {
297+
accessor<T, 0, access::mode::read, access::target::global_buffer>
298+
SrcAcc(SrcBuf, Cgh);
299+
Cgh.copy(SrcAcc, &DstValue);
300+
});
301+
}
302+
assert(DstValue == 99);
303+
304+
// Check copy from 0-dimensional placeholder accessor to memory
305+
SrcValue = 77;
306+
DstValue = 0;
307+
{
308+
buffer<T, 1> SrcBuf(&SrcValue, range<1>(1));
309+
accessor<T, 0, access::mode::read, access::target::global_buffer,
310+
access::placeholder::true_t>
311+
SrcAcc(SrcBuf);
312+
{
313+
queue Queue;
314+
Queue.submit([&](handler &Cgh) {
315+
Cgh.require(SrcAcc);
316+
Cgh.copy(SrcAcc, &DstValue);
317+
});
318+
}
319+
}
320+
assert(DstValue == 77);
275321
}
276322

277323
template <typename T> void test_copy_shared_ptr_acc() {

0 commit comments

Comments
 (0)