Skip to content

Commit 1df6873

Browse files
authored
[SYCL] Add missing SYCL 2020 USM features (#3897)
- USM atomic allocation aspects (+ tests) - `handler::mem_advise` - `handler::copy` and `queue::copy` - `queue` class: overloads of `fill`, `memset`, `memcpy`, `copy`, `mem_advise`, `prefetch` with dependency event arguments - optional property list argument in USM allocation functions and `usm_allocator` constructors (+ tests)
1 parent 4170098 commit 1df6873

File tree

19 files changed

+656
-105
lines changed

19 files changed

+656
-105
lines changed

sycl/include/CL/sycl/aspects.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ enum class aspect {
3838
ext_intel_gpu_subslices_per_slice = 22,
3939
ext_intel_gpu_eu_count_per_subslice = 23,
4040
ext_intel_max_mem_bandwidth = 24,
41-
ext_intel_mem_channel = 25
41+
ext_intel_mem_channel = 25,
42+
usm_atomic_host_allocations = 26,
43+
usm_atomic_shared_allocations = 27,
4244
};
4345

4446
} // namespace sycl

sycl/include/CL/sycl/detail/cg.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ namespace detail {
9393
// Used to represent a type of an extended member
9494
enum class ExtendedMembersType : unsigned int {
9595
HANDLER_KERNEL_BUNDLE = 0,
96+
HANDLER_MEM_ADVICE,
9697
};
9798

9899
// Holds a pointer to an object of an arbitrary type and an ID value which
@@ -164,6 +165,7 @@ class CG {
164165
PREFETCH_USM = 12,
165166
CODEPLAY_INTEROP_TASK = 13,
166167
CODEPLAY_HOST_TASK = 14,
168+
ADVISE_USM = 15,
167169
};
168170

169171
CG(CGTYPE Type, vector_class<vector_class<char>> ArgsStorage,
@@ -414,6 +416,37 @@ class CGPrefetchUSM : public CG {
414416
size_t getLength() { return MLength; }
415417
};
416418

419+
/// "Advise USM" command group class.
420+
class CGAdviseUSM : public CG {
421+
void *MDst;
422+
size_t MLength;
423+
424+
public:
425+
CGAdviseUSM(void *DstPtr, size_t Length,
426+
vector_class<vector_class<char>> ArgsStorage,
427+
vector_class<detail::AccessorImplPtr> AccStorage,
428+
vector_class<shared_ptr_class<const void>> SharedPtrStorage,
429+
vector_class<Requirement *> Requirements,
430+
vector_class<detail::EventImplPtr> Events,
431+
detail::code_location loc = {})
432+
: CG(ADVISE_USM, std::move(ArgsStorage), std::move(AccStorage),
433+
std::move(SharedPtrStorage), std::move(Requirements),
434+
std::move(Events), std::move(loc)),
435+
MDst(DstPtr), MLength(Length) {}
436+
void *getDst() { return MDst; }
437+
size_t getLength() { return MLength; }
438+
439+
pi_mem_advice getAdvice() {
440+
auto ExtendedMembers = getExtendedMembers();
441+
if (!ExtendedMembers)
442+
return PI_MEM_ADVISE_UNKNOWN;
443+
for (const ExtendedMemberT &EM : *ExtendedMembers)
444+
if ((ExtendedMembersType::HANDLER_MEM_ADVICE == EM.MType) && EM.MData)
445+
return *std::static_pointer_cast<pi_mem_advice>(EM.MData);
446+
return PI_MEM_ADVISE_UNKNOWN;
447+
}
448+
};
449+
417450
class CGInteropTask : public CG {
418451
public:
419452
std::unique_ptr<InteropTask> MInteropTask;

sycl/include/CL/sycl/detail/memory_manager.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ class __SYCL_EXPORT MemoryManager {
151151
static void prefetch_usm(void *Ptr, QueueImplPtr Queue, size_t Len,
152152
std::vector<RT::PiEvent> DepEvents,
153153
RT::PiEvent &OutEvent);
154+
155+
static void advise_usm(const void *Ptr, QueueImplPtr Queue, size_t Len,
156+
pi_mem_advice Advice,
157+
std::vector<RT::PiEvent> DepEvents,
158+
RT::PiEvent &OutEvent);
154159
};
155160
} // namespace detail
156161
} // namespace sycl

sycl/include/CL/sycl/handler.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2194,6 +2194,19 @@ class __SYCL_EXPORT handler {
21942194
/// \param Count is a number of bytes to copy.
21952195
void memcpy(void *Dest, const void *Src, size_t Count);
21962196

2197+
/// Copies data from one memory region to another, both pointed by
2198+
/// USM pointers.
2199+
/// No operations is done if \param Count is zero. An exception is thrown
2200+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
2201+
/// if any of the pointer parameters is invalid.
2202+
///
2203+
/// \param Dest is a USM pointer to the destination memory.
2204+
/// \param Src is a USM pointer to the source memory.
2205+
/// \param Count is a number of elements of type T to copy.
2206+
template <typename T> void copy(T *Dest, const T *Src, size_t Count) {
2207+
this->memcpy(Dest, Src, Count * sizeof(T));
2208+
}
2209+
21972210
/// Fills the memory pointed by a USM pointer with the value specified.
21982211
/// No operations is done if \param Count is zero. An exception is thrown
21992212
/// if \param Dest is nullptr. The behavior is undefined if \param Dest
@@ -2212,6 +2225,14 @@ class __SYCL_EXPORT handler {
22122225
/// \param Count is a number of bytes to be prefetched.
22132226
void prefetch(const void *Ptr, size_t Count);
22142227

2228+
/// Provides additional information to the underlying runtime about how
2229+
/// different allocations are used.
2230+
///
2231+
/// \param Ptr is a USM pointer to the allocation.
2232+
/// \param Length is a number of bytes in the allocation.
2233+
/// \param Advice is a device-defined advice for the specified allocation.
2234+
void mem_advise(const void *Ptr, size_t Length, pi_mem_advice Advice);
2235+
22152236
private:
22162237
shared_ptr_class<detail::queue_impl> MQueue;
22172238
/// The storage for the arguments passed.

sycl/include/CL/sycl/queue.hpp

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,52 @@ class __SYCL_EXPORT queue {
320320

321321
/// Fills the specified memory with the specified pattern.
322322
///
323-
/// \param Ptr is the pointer to the memory to fill
323+
/// \param Ptr is the pointer to the memory to fill.
324324
/// \param Pattern is the pattern to fill into the memory. T should be
325325
/// trivially copyable.
326326
/// \param Count is the number of times to fill Pattern into Ptr.
327+
/// \return an event representing fill operation.
327328
template <typename T> event fill(void *Ptr, const T &Pattern, size_t Count) {
328329
return submit([&](handler &CGH) { CGH.fill<T>(Ptr, Pattern, Count); });
329330
}
330331

332+
/// Fills the specified memory with the specified pattern.
333+
///
334+
/// \param Ptr is the pointer to the memory to fill.
335+
/// \param Pattern is the pattern to fill into the memory. T should be
336+
/// trivially copyable.
337+
/// \param Count is the number of times to fill Pattern into Ptr.
338+
/// \param DepEvent is an event that specifies the kernel dependencies.
339+
/// \return an event representing fill operation.
340+
template <typename T>
341+
event fill(void *Ptr, const T &Pattern, size_t Count, event DepEvent) {
342+
return submit([&](handler &CGH) {
343+
CGH.depends_on(DepEvent);
344+
CGH.fill<T>(Ptr, Pattern, Count);
345+
});
346+
}
347+
348+
/// Fills the specified memory with the specified pattern.
349+
///
350+
/// \param Ptr is the pointer to the memory to fill.
351+
/// \param Pattern is the pattern to fill into the memory. T should be
352+
/// trivially copyable.
353+
/// \param Count is the number of times to fill Pattern into Ptr.
354+
/// \param DepEvents is a vector of events that specifies the kernel
355+
/// dependencies.
356+
/// \return an event representing fill operation.
357+
template <typename T>
358+
event fill(void *Ptr, const T &Pattern, size_t Count,
359+
const vector_class<event> &DepEvents) {
360+
return submit([&](handler &CGH) {
361+
CGH.depends_on(DepEvents);
362+
CGH.fill<T>(Ptr, Pattern, Count);
363+
});
364+
}
365+
331366
/// Fills the memory pointed by a USM pointer with the value specified.
332367
/// No operations is done if \param Count is zero. An exception is thrown
333-
/// if \param Dest is nullptr. The behavior is undefined if \param Ptr
368+
/// if \param Ptr is nullptr. The behavior is undefined if \param Ptr
334369
/// is invalid.
335370
///
336371
/// \param Ptr is a USM pointer to the memory to fill.
@@ -339,6 +374,32 @@ class __SYCL_EXPORT queue {
339374
/// \return an event representing fill operation.
340375
event memset(void *Ptr, int Value, size_t Count);
341376

377+
/// Fills the memory pointed by a USM pointer with the value specified.
378+
/// No operations is done if \param Count is zero. An exception is thrown
379+
/// if \param Ptr is nullptr. The behavior is undefined if \param Ptr
380+
/// is invalid.
381+
///
382+
/// \param Ptr is a USM pointer to the memory to fill.
383+
/// \param Value is a value to be set. Value is cast as an unsigned char.
384+
/// \param Count is a number of bytes to fill.
385+
/// \param DepEvent is an event that specifies the kernel dependencies.
386+
/// \return an event representing fill operation.
387+
event memset(void *Ptr, int Value, size_t Count, event DepEvent);
388+
389+
/// Fills the memory pointed by a USM pointer with the value specified.
390+
/// No operations is done if \param Count is zero. An exception is thrown
391+
/// if \param Ptr is nullptr. The behavior is undefined if \param Ptr
392+
/// is invalid.
393+
///
394+
/// \param Ptr is a USM pointer to the memory to fill.
395+
/// \param Value is a value to be set. Value is cast as an unsigned char.
396+
/// \param Count is a number of bytes to fill.
397+
/// \param DepEvents is a vector of events that specifies the kernel
398+
/// dependencies.
399+
/// \return an event representing fill operation.
400+
event memset(void *Ptr, int Value, size_t Count,
401+
const vector_class<event> &DepEvents);
402+
342403
/// Copies data from one memory region to another, both pointed by
343404
/// USM pointers.
344405
/// No operations is done if \param Count is zero. An exception is thrown
@@ -351,6 +412,81 @@ class __SYCL_EXPORT queue {
351412
/// \return an event representing copy operation.
352413
event memcpy(void *Dest, const void *Src, size_t Count);
353414

415+
/// Copies data from one memory region to another, both pointed by
416+
/// USM pointers.
417+
/// No operations is done if \param Count is zero. An exception is thrown
418+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
419+
/// if any of the pointer parameters is invalid.
420+
///
421+
/// \param Dest is a USM pointer to the destination memory.
422+
/// \param Src is a USM pointer to the source memory.
423+
/// \param Count is a number of bytes to copy.
424+
/// \param DepEvent is an event that specifies the kernel dependencies.
425+
/// \return an event representing copy operation.
426+
event memcpy(void *Dest, const void *Src, size_t Count, event DepEvent);
427+
428+
/// Copies data from one memory region to another, both pointed by
429+
/// USM pointers.
430+
/// No operations is done if \param Count is zero. An exception is thrown
431+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
432+
/// if any of the pointer parameters is invalid.
433+
///
434+
/// \param Dest is a USM pointer to the destination memory.
435+
/// \param Src is a USM pointer to the source memory.
436+
/// \param Count is a number of bytes to copy.
437+
/// \param DepEvents is a vector of events that specifies the kernel
438+
/// dependencies.
439+
/// \return an event representing copy operation.
440+
event memcpy(void *Dest, const void *Src, size_t Count,
441+
const vector_class<event> &DepEvents);
442+
443+
/// Copies data from one memory region to another, both pointed by
444+
/// USM pointers.
445+
/// No operations is done if \param Count is zero. An exception is thrown
446+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
447+
/// if any of the pointer parameters is invalid.
448+
///
449+
/// \param Dest is a USM pointer to the destination memory.
450+
/// \param Src is a USM pointer to the source memory.
451+
/// \param Count is a number of elements of type T to copy.
452+
/// \return an event representing copy operation.
453+
template <typename T> event copy(T *Dest, const T *Src, size_t Count) {
454+
return this->memcpy(Dest, Src, Count * sizeof(T));
455+
}
456+
457+
/// Copies data from one memory region to another, both pointed by
458+
/// USM pointers.
459+
/// No operations is done if \param Count is zero. An exception is thrown
460+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
461+
/// if any of the pointer parameters is invalid.
462+
///
463+
/// \param Dest is a USM pointer to the destination memory.
464+
/// \param Src is a USM pointer to the source memory.
465+
/// \param Count is a number of elements of type T to copy.
466+
/// \param DepEvent is an event that specifies the kernel dependencies.
467+
/// \return an event representing copy operation.
468+
template <typename T>
469+
event copy(T *Dest, const T *Src, size_t Count, event DepEvent) {
470+
return this->memcpy(Dest, Src, Count * sizeof(T), DepEvent);
471+
}
472+
473+
/// Copies data from one memory region to another, both pointed by
474+
/// USM pointers.
475+
/// No operations is done if \param Count is zero. An exception is thrown
476+
/// if either \param Dest or \param Src is nullptr. The behavior is undefined
477+
/// if any of the pointer parameters is invalid.
478+
///
479+
/// \param Dest is a USM pointer to the destination memory.
480+
/// \param Src is a USM pointer to the source memory.
481+
/// \param Count is a number of elements of type T to copy.
482+
/// \param DepEvents is a vector of events that specifies the kernel
483+
/// \return an event representing copy operation.
484+
template <typename T>
485+
event copy(T *Dest, const T *Src, size_t Count,
486+
const vector_class<event> &DepEvents) {
487+
return this->memcpy(Dest, Src, Count * sizeof(T), DepEvents);
488+
}
489+
354490
/// Provides additional information to the underlying runtime about how
355491
/// different allocations are used.
356492
///
@@ -360,16 +496,72 @@ class __SYCL_EXPORT queue {
360496
/// \return an event representing advice operation.
361497
event mem_advise(const void *Ptr, size_t Length, pi_mem_advice Advice);
362498

499+
/// Provides additional information to the underlying runtime about how
500+
/// different allocations are used.
501+
///
502+
/// \param Ptr is a USM pointer to the allocation.
503+
/// \param Length is a number of bytes in the allocation.
504+
/// \param Advice is a device-defined advice for the specified allocation.
505+
/// \param DepEvent is an event that specifies the kernel dependencies.
506+
/// \return an event representing advice operation.
507+
event mem_advise(const void *Ptr, size_t Length, pi_mem_advice Advice,
508+
event DepEvent);
509+
510+
/// Provides additional information to the underlying runtime about how
511+
/// different allocations are used.
512+
///
513+
/// \param Ptr is a USM pointer to the allocation.
514+
/// \param Length is a number of bytes in the allocation.
515+
/// \param Advice is a device-defined advice for the specified allocation.
516+
/// \param DepEvents is a vector of events that specifies the kernel
517+
/// dependencies.
518+
/// \return an event representing advice operation.
519+
event mem_advise(const void *Ptr, size_t Length, pi_mem_advice Advice,
520+
const vector_class<event> &DepEvents);
521+
363522
/// Provides hints to the runtime library that data should be made available
364523
/// on a device earlier than Unified Shared Memory would normally require it
365524
/// to be available.
366525
///
367526
/// \param Ptr is a USM pointer to the memory to be prefetched to the device.
368527
/// \param Count is a number of bytes to be prefetched.
528+
/// \return an event representing prefetch operation.
369529
event prefetch(const void *Ptr, size_t Count) {
370530
return submit([=](handler &CGH) { CGH.prefetch(Ptr, Count); });
371531
}
372532

533+
/// Provides hints to the runtime library that data should be made available
534+
/// on a device earlier than Unified Shared Memory would normally require it
535+
/// to be available.
536+
///
537+
/// \param Ptr is a USM pointer to the memory to be prefetched to the device.
538+
/// \param Count is a number of bytes to be prefetched.
539+
/// \param DepEvent is an event that specifies the kernel dependencies.
540+
/// \return an event representing prefetch operation.
541+
event prefetch(const void *Ptr, size_t Count, event DepEvent) {
542+
return submit([=](handler &CGH) {
543+
CGH.depends_on(DepEvent);
544+
CGH.prefetch(Ptr, Count);
545+
});
546+
}
547+
548+
/// Provides hints to the runtime library that data should be made available
549+
/// on a device earlier than Unified Shared Memory would normally require it
550+
/// to be available.
551+
///
552+
/// \param Ptr is a USM pointer to the memory to be prefetched to the device.
553+
/// \param Count is a number of bytes to be prefetched.
554+
/// \param DepEvents is a vector of events that specifies the kernel
555+
/// dependencies.
556+
/// \return an event representing prefetch operation.
557+
event prefetch(const void *Ptr, size_t Count,
558+
const vector_class<event> &DepEvents) {
559+
return submit([=](handler &CGH) {
560+
CGH.depends_on(DepEvents);
561+
CGH.prefetch(Ptr, Count);
562+
});
563+
}
564+
373565
/// single_task version with a kernel represented as a lambda.
374566
///
375567
/// \param KernelFunc is the Kernel functor or lambda

0 commit comments

Comments
 (0)