@@ -8363,17 +8363,55 @@ pi_result _pi_buffer::getZeHandle(char *&ZeHandle, access_mode_t AccessMode,
8363
8363
LastDeviceWithValidAllocation));
8364
8364
// Copy valid buffer data to this allocation.
8365
8365
// TODO: see if we should better use peer's device allocation used
8366
- // directly,
8367
- // if that capability is reported with zeDeviceCanAccessPeer,
8368
- // instead of maintaining a separate allocation and performing this
8369
- // explciit copy.
8366
+ // directly, if that capability is reported with zeDeviceCanAccessPeer,
8367
+ // instead of maintaining a separate allocation and performing
8368
+ // explciit copies.
8370
8369
//
8371
8370
// zeCommandListAppendMemoryCopy must not be called from simultaneous
8372
8371
// threads with the same command list handle, so we need exclusive lock.
8373
- std::scoped_lock Lock (Context->ImmediateCommandListMutex );
8374
- ZE_CALL (zeCommandListAppendMemoryCopy,
8375
- (Context->ZeCommandListInit , ZeHandle /* Dst */ , ZeHandleSrc,
8376
- Size, nullptr , 0 , nullptr ));
8372
+ ze_bool_t P2P;
8373
+ ZE_CALL (
8374
+ zeDeviceCanAccessPeer,
8375
+ (Device->ZeDevice , LastDeviceWithValidAllocation->ZeDevice , &P2P));
8376
+ if (!P2P) {
8377
+ // P2P copy is not possible, so copy through the host.
8378
+ auto &HostAllocation = Allocations[nullptr ];
8379
+ // The host allocation may already exists, e.g. with imported
8380
+ // host ptr, or in case of interop buffer.
8381
+ if (!HostAllocation.ZeHandle ) {
8382
+ void *ZeHandleHost;
8383
+ if (enableBufferPooling ()) {
8384
+ HostAllocation.ReleaseAction = allocation_t ::free;
8385
+ PI_CALL (piextUSMHostAlloc (&ZeHandleHost, Context, nullptr , Size,
8386
+ getAlignment ()));
8387
+ } else {
8388
+ HostAllocation.ReleaseAction = allocation_t ::free_native;
8389
+ PI_CALL (ZeHostMemAllocHelper (&ZeHandleHost, Context, Size));
8390
+ }
8391
+ HostAllocation.ZeHandle = pi_cast<char *>(ZeHandleHost);
8392
+ HostAllocation.Valid = false ;
8393
+ }
8394
+ std::scoped_lock Lock (Context->ImmediateCommandListMutex );
8395
+ if (!HostAllocation.Valid ) {
8396
+ ZE_CALL (zeCommandListAppendMemoryCopy,
8397
+ (Context->ZeCommandListInit ,
8398
+ HostAllocation.ZeHandle /* Dst */ , ZeHandleSrc, Size,
8399
+ nullptr , 0 , nullptr ));
8400
+ // Mark the host allocation data as valid so it can be reused.
8401
+ // It will be invalidated below if the current access is not
8402
+ // read-only.
8403
+ HostAllocation.Valid = true ;
8404
+ }
8405
+ ZE_CALL (zeCommandListAppendMemoryCopy,
8406
+ (Context->ZeCommandListInit , ZeHandle /* Dst */ ,
8407
+ HostAllocation.ZeHandle , Size, nullptr , 0 , nullptr ));
8408
+ } else {
8409
+ // Perform P2P copy.
8410
+ std::scoped_lock Lock (Context->ImmediateCommandListMutex );
8411
+ ZE_CALL (zeCommandListAppendMemoryCopy,
8412
+ (Context->ZeCommandListInit , ZeHandle /* Dst */ , ZeHandleSrc,
8413
+ Size, nullptr , 0 , nullptr ));
8414
+ }
8377
8415
}
8378
8416
}
8379
8417
0 commit comments