diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index fb156d60f185d..ec6bccf05b6b9 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -6129,6 +6129,19 @@ pi_result piextUSMEnqueueMemset(pi_queue Queue, void *Ptr, pi_int32 Value, Count, NumEventsInWaitlist, EventsWaitlist, Event); } +// Helper function to check if a pointer is a device pointer. +static bool IsDevicePointer(pi_context Context, const void *Ptr) { + ze_device_handle_t ZeDeviceHandle; + ze_memory_allocation_properties_t ZeMemoryAllocationProperties = {}; + + // Query memory type of the pointer + ZE_CALL(zeMemGetAllocProperties, + (Context->ZeContext, Ptr, &ZeMemoryAllocationProperties, + &ZeDeviceHandle)); + + return (ZeMemoryAllocationProperties.type == ZE_MEMORY_TYPE_DEVICE); +} + pi_result piextUSMEnqueueMemcpy(pi_queue Queue, pi_bool Blocking, void *DstPtr, const void *SrcPtr, size_t Size, pi_uint32 NumEventsInWaitlist, @@ -6141,10 +6154,14 @@ pi_result piextUSMEnqueueMemcpy(pi_queue Queue, pi_bool Blocking, void *DstPtr, PI_ASSERT(Queue, PI_INVALID_QUEUE); + // Device to Device copies are found to execute slower on copy engine + // (versus compute engine). + bool PreferCopyEngine = !IsDevicePointer(Queue->Context, SrcPtr) || + !IsDevicePointer(Queue->Context, DstPtr); return enqueueMemCopyHelper( // TODO: do we need a new command type for this? PI_COMMAND_TYPE_MEM_BUFFER_COPY, Queue, DstPtr, Blocking, Size, SrcPtr, - NumEventsInWaitlist, EventsWaitlist, Event); + NumEventsInWaitlist, EventsWaitlist, Event, PreferCopyEngine); } /// Hint to migrate memory to the device