P4 to Git Change 1421208 by gandryey@gera-w8 on 2017/06/12 13:15:22
SWDEV-124171 - adding support for p2p OCL in rocm stack - Add cl_amd_copy_buffer_p2p extension for P2P transfers. The extension adds a new API entry - clEnqueueCopyBufferP2PAMD() which allows to transfer CL buffers between different CL contexts on different GPUs. If P2P isn't possible, then double copy performed - Also the app can query the P2P support capabilities for the device. A list of P2P accessible devices can be returned for the current device http://ocltc.amd.com/reviews/r/12913/ Affected files ... ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_context.cpp#54 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_device.cpp#62 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_p2p_amd.cpp#1 add ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_p2p_amd.h#1 add ... //depot/stg/opencl/drivers/opencl/api/opencl/khronos/headers/opencl2.0/CL/cl_ext.h#29 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuvirtual.hpp#14 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#287 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#141 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.hpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.cpp#19 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#54 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#22 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.cpp#24 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.cpp#19 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.cpp#39 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.cpp#79 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.hpp#84 edit
This commit is contained in:
@@ -1024,6 +1024,88 @@ void VirtualGPU::submitCopyMemory(amd::CopyMemoryCommand& cmd) {
|
||||
profilingEnd(cmd);
|
||||
}
|
||||
|
||||
void VirtualGPU::submitCopyMemoryP2P(amd::CopyMemoryP2PCommand& cmd) {
|
||||
// Wait on a kernel if one is outstanding
|
||||
releaseGpuMemoryFence();
|
||||
|
||||
profilingBegin(cmd);
|
||||
|
||||
Memory* srcDevMem = static_cast<roc::Memory*>(
|
||||
cmd.source().getDeviceMemory(*cmd.source().getContext().devices()[0]));
|
||||
Memory* dstDevMem = static_cast<roc::Memory*>(
|
||||
cmd.destination().getDeviceMemory(*cmd.destination().getContext().devices()[0]));
|
||||
|
||||
bool p2pAllowed = false;
|
||||
// Loop through all available P2P devices for the destination buffer
|
||||
for (auto agent: dstDevMem->dev().p2pAgents()) {
|
||||
// Find the device, which is matching the current
|
||||
if (agent.handle == dev().getBackendDevice().handle) {
|
||||
p2pAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Synchronize source and destination memory
|
||||
device::Memory::SyncFlags syncFlags;
|
||||
syncFlags.skipEntire_ = cmd.isEntireMemory();
|
||||
amd::Coord3D size = cmd.size();
|
||||
|
||||
bool result = false;
|
||||
switch (cmd.type()) {
|
||||
case CL_COMMAND_COPY_BUFFER: {
|
||||
amd::Coord3D srcOrigin(cmd.srcOrigin()[0]);
|
||||
amd::Coord3D dstOrigin(cmd.dstOrigin()[0]);
|
||||
|
||||
if (p2pAllowed) {
|
||||
result = blitMgr().copyBuffer(*srcDevMem, *dstDevMem, srcOrigin, dstOrigin,
|
||||
size, cmd.isEntireMemory());
|
||||
}
|
||||
else {
|
||||
size_t copy_size = Device::kP2PStagingSize;
|
||||
size_t left_size = size[0];
|
||||
result = true;
|
||||
do {
|
||||
if (left_size <= copy_size) {
|
||||
copy_size = left_size;
|
||||
}
|
||||
left_size -= copy_size;
|
||||
amd::Coord3D stageOffset(0);
|
||||
amd::Coord3D cpSize(copy_size);
|
||||
|
||||
// Perform 2 step transfer with staging buffer
|
||||
// todo: optimization can be done with double buffering if events tracking
|
||||
// will be propagated outside of the device transfers object
|
||||
result &= dev().xferMgr().copyBuffer(*srcDevMem, *(dev().P2PStages()[0]), srcOrigin,
|
||||
stageOffset, cpSize, cmd.isEntireMemory());
|
||||
srcOrigin.c[0] += copy_size;
|
||||
result &= dstDevMem->dev().xferMgr().copyBuffer(*dstDevMem->dev().P2PStages()[0],
|
||||
*dstDevMem, stageOffset, dstOrigin,
|
||||
copy_size, cmd.isEntireMemory());
|
||||
dstOrigin.c[0] += copy_size;
|
||||
} while (left_size > 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CL_COMMAND_COPY_BUFFER_RECT:
|
||||
case CL_COMMAND_COPY_IMAGE:
|
||||
case CL_COMMAND_COPY_IMAGE_TO_BUFFER:
|
||||
case CL_COMMAND_COPY_BUFFER_TO_IMAGE:
|
||||
LogError("Unsupported P2P type!");
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
LogError("submitCopyMemoryP2P failed!");
|
||||
cmd.setStatus(CL_OUT_OF_RESOURCES);
|
||||
}
|
||||
|
||||
cmd.destination().signalWrite(&dstDevMem->dev());
|
||||
|
||||
profilingEnd(cmd);
|
||||
}
|
||||
|
||||
void VirtualGPU::submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd) {
|
||||
// No fence is needed since this is a no-op: the
|
||||
// command will be completed only after all the
|
||||
|
||||
Viittaa uudesa ongelmassa
Block a user