Skip to content

Commit

Permalink
[OpenCL] Add Command Buffer extension to OpenCL adapter.
Browse files Browse the repository at this point in the history
  • Loading branch information
martygrant committed Oct 19, 2023
1 parent f0de2f4 commit afbe0b9
Show file tree
Hide file tree
Showing 6 changed files with 308 additions and 78 deletions.
273 changes: 202 additions & 71 deletions source/adapters/opencl/command_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,116 @@
#include "command_buffer.hpp"
#include "common.hpp"

/// Stub implementations of UR experimental feature command-buffers

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferCreateExp(
[[maybe_unused]] ur_context_handle_t hContext,
[[maybe_unused]] ur_device_handle_t hDevice,
ur_context_handle_t hContext, ur_device_handle_t hDevice,
[[maybe_unused]] const ur_exp_command_buffer_desc_t *pCommandBufferDesc,
[[maybe_unused]] ur_exp_command_buffer_handle_t *phCommandBuffer) {
ur_exp_command_buffer_handle_t *phCommandBuffer) {

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
ur_queue_handle_t Queue = nullptr;
UR_RETURN_ON_FAILURE(urQueueCreate(hContext, hDevice, nullptr, &Queue));

cl_context CLContext = cl_adapter::cast<cl_context>(hContext);
cl_ext::clCreateCommandBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clCreateCommandBufferKHRCache,
cl_ext::CreateCommandBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

auto CLCommandBuffer =
F(1, cl_adapter::cast<cl_command_queue *>(&Queue), nullptr, &Res);
CL_RETURN_ON_FAILURE_AND_SET_NULL(Res, phCommandBuffer);

try {
auto URCommandBuffer = std::make_unique<ur_exp_command_buffer_handle_t_>(
Queue, hContext, CLCommandBuffer);
*phCommandBuffer = URCommandBuffer.release();
} catch (...) {
return UR_RESULT_ERROR_OUT_OF_RESOURCES;
}

CL_RETURN_ON_FAILURE(Res);
return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferRetainExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer) {
UR_APIEXPORT ur_result_t UR_APICALL
urCommandBufferRetainExp(ur_exp_command_buffer_handle_t hCommandBuffer) {
UR_RETURN_ON_FAILURE(urQueueRetain(hCommandBuffer->hInternalQueue));

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clRetainCommandBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clRetainCommandBufferKHRCache,
cl_ext::RetainCommandBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(F(hCommandBuffer->CLCommandBuffer));
return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferReleaseExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer) {
UR_APIEXPORT ur_result_t UR_APICALL
urCommandBufferReleaseExp(ur_exp_command_buffer_handle_t hCommandBuffer) {
UR_RETURN_ON_FAILURE(urQueueRelease(hCommandBuffer->hInternalQueue));

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clReleaseCommandBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clReleaseCommandBufferKHRCache,
cl_ext::ReleaseCommandBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(F(hCommandBuffer->CLCommandBuffer));
return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferFinalizeExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer) {
UR_APIEXPORT ur_result_t UR_APICALL
urCommandBufferFinalizeExp(ur_exp_command_buffer_handle_t hCommandBuffer) {
cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clFinalizeCommandBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clFinalizeCommandBufferKHRCache,
cl_ext::FinalizeCommandBufferName, &F);

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(F(hCommandBuffer->CLCommandBuffer));
return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendKernelLaunchExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer,
[[maybe_unused]] ur_kernel_handle_t hKernel,
[[maybe_unused]] uint32_t workDim,
[[maybe_unused]] const size_t *pGlobalWorkOffset,
[[maybe_unused]] const size_t *pGlobalWorkSize,
[[maybe_unused]] const size_t *pLocalWorkSize,
[[maybe_unused]] uint32_t numSyncPointsInWaitList,
[[maybe_unused]] const ur_exp_command_buffer_sync_point_t
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {
ur_exp_command_buffer_handle_t hCommandBuffer, ur_kernel_handle_t hKernel,
uint32_t workDim, const size_t *pGlobalWorkOffset,
const size_t *pGlobalWorkSize, const size_t *pLocalWorkSize,
uint32_t numSyncPointsInWaitList,
const ur_exp_command_buffer_sync_point_t *pSyncPointWaitList,
ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clCommandNDRangeKernelKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clCommandNDRangeKernelKHRCache,
cl_ext::CommandNRRangeKernelName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(
F(hCommandBuffer->CLCommandBuffer,
cl_adapter::cast<cl_command_queue>(hCommandBuffer->hInternalQueue),
nullptr, cl_adapter::cast<cl_kernel>(hKernel), workDim,
pGlobalWorkOffset, pGlobalWorkSize, pLocalWorkSize,
numSyncPointsInWaitList, pSyncPointWaitList, pSyncPoint, nullptr));

return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMemcpyUSMExp(
UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendUSMMemcpyExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer,
[[maybe_unused]] void *pDst, [[maybe_unused]] const void *pSrc,
[[maybe_unused]] size_t size,
Expand All @@ -74,43 +129,81 @@ UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMemcpyUSMExp(
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferCopyExp(
UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendUSMFillExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer,
[[maybe_unused]] ur_mem_handle_t hSrcMem,
[[maybe_unused]] ur_mem_handle_t hDstMem, [[maybe_unused]] size_t srcOffset,
[[maybe_unused]] size_t dstOffset, [[maybe_unused]] size_t size,
[[maybe_unused]] void *pMemory, [[maybe_unused]] const void *pPattern,
[[maybe_unused]] size_t patternSize, [[maybe_unused]] size_t size,
[[maybe_unused]] uint32_t numSyncPointsInWaitList,
[[maybe_unused]] const ur_exp_command_buffer_sync_point_t
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferCopyExp(
ur_exp_command_buffer_handle_t hCommandBuffer, ur_mem_handle_t hSrcMem,
ur_mem_handle_t hDstMem, size_t srcOffset, size_t dstOffset, size_t size,
uint32_t numSyncPointsInWaitList,
const ur_exp_command_buffer_sync_point_t *pSyncPointWaitList,
ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clCommandCopyBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clCommandCopyBufferKHRCache,
cl_ext::CommandCopyBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(
F(hCommandBuffer->CLCommandBuffer,
cl_adapter::cast<cl_command_queue>(hCommandBuffer->hInternalQueue),
cl_adapter::cast<cl_mem>(hSrcMem), cl_adapter::cast<cl_mem>(hDstMem),
srcOffset, dstOffset, size, numSyncPointsInWaitList, pSyncPointWaitList,
pSyncPoint, nullptr));

return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferCopyRectExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer,
[[maybe_unused]] ur_mem_handle_t hSrcMem,
[[maybe_unused]] ur_mem_handle_t hDstMem,
[[maybe_unused]] ur_rect_offset_t srcOrigin,
[[maybe_unused]] ur_rect_offset_t dstOrigin,
[[maybe_unused]] ur_rect_region_t region,
[[maybe_unused]] size_t srcRowPitch, [[maybe_unused]] size_t srcSlicePitch,
[[maybe_unused]] size_t dstRowPitch, [[maybe_unused]] size_t dstSlicePitch,
[[maybe_unused]] uint32_t numSyncPointsInWaitList,
[[maybe_unused]] const ur_exp_command_buffer_sync_point_t
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {
ur_exp_command_buffer_handle_t hCommandBuffer, ur_mem_handle_t hSrcMem,
ur_mem_handle_t hDstMem, ur_rect_offset_t srcOrigin,
ur_rect_offset_t dstOrigin, ur_rect_region_t region, size_t srcRowPitch,
size_t srcSlicePitch, size_t dstRowPitch, size_t dstSlicePitch,
uint32_t numSyncPointsInWaitList,
const ur_exp_command_buffer_sync_point_t *pSyncPointWaitList,
ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
size_t OpenCLOriginRect[3]{srcOrigin.x, srcOrigin.y, srcOrigin.z};
size_t OpenCLDstRect[3]{dstOrigin.x, dstOrigin.y, dstOrigin.z};
size_t OpenCLRegion[3]{region.width, region.height, region.depth};

cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clCommandCopyBufferRectKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clCommandCopyBufferRectKHRCache,
cl_ext::CommandCopyBufferRectName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(
F(hCommandBuffer->CLCommandBuffer,
cl_adapter::cast<cl_command_queue>(hCommandBuffer->hInternalQueue),
cl_adapter::cast<cl_mem>(hSrcMem), cl_adapter::cast<cl_mem>(hDstMem),
OpenCLOriginRect, OpenCLDstRect, OpenCLRegion, srcRowPitch,
srcSlicePitch, dstRowPitch, dstSlicePitch, numSyncPointsInWaitList,
pSyncPointWaitList, pSyncPoint, nullptr));

return UR_RESULT_SUCCESS;
}

UR_APIEXPORT
Expand All @@ -123,7 +216,7 @@ ur_result_t UR_APICALL urCommandBufferAppendMembufferWriteExp(
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
Expand All @@ -138,7 +231,7 @@ ur_result_t UR_APICALL urCommandBufferAppendMembufferReadExp(
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
Expand All @@ -159,7 +252,7 @@ ur_result_t UR_APICALL urCommandBufferAppendMembufferWriteRectExp(
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
Expand All @@ -180,19 +273,57 @@ ur_result_t UR_APICALL urCommandBufferAppendMembufferReadRectExp(
*pSyncPointWaitList,
[[maybe_unused]] ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_adapter::die("Experimental Command-buffer feature is not "
cl_adapter::die("Experimental Command-buffer entry point is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferAppendMembufferFillExp(
ur_exp_command_buffer_handle_t hCommandBuffer, ur_mem_handle_t hBuffer,
const void *pPattern, size_t patternSize, size_t offset, size_t size,
uint32_t numSyncPointsInWaitList,
const ur_exp_command_buffer_sync_point_t *pSyncPointWaitList,
ur_exp_command_buffer_sync_point_t *pSyncPoint) {

cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clCommandFillBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clCommandFillBufferKHRCache,
cl_ext::CommandFillBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

CL_RETURN_ON_FAILURE(
F(hCommandBuffer->CLCommandBuffer,
cl_adapter::cast<cl_command_queue>(hCommandBuffer->hInternalQueue),
cl_adapter::cast<cl_mem>(hBuffer), pPattern, patternSize, offset, size,
numSyncPointsInWaitList, pSyncPointWaitList, pSyncPoint, nullptr));

return UR_RESULT_SUCCESS;
}

UR_APIEXPORT ur_result_t UR_APICALL urCommandBufferEnqueueExp(
[[maybe_unused]] ur_exp_command_buffer_handle_t hCommandBuffer,
[[maybe_unused]] ur_queue_handle_t hQueue,
[[maybe_unused]] uint32_t numEventsInWaitList,
[[maybe_unused]] const ur_event_handle_t *phEventWaitList,
[[maybe_unused]] ur_event_handle_t *phEvent) {
ur_exp_command_buffer_handle_t hCommandBuffer, ur_queue_handle_t hQueue,
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
ur_event_handle_t *phEvent) {

cl_adapter::die("Experimental Command-buffer feature is not "
"implemented for OpenCL adapter.");
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
cl_context CLContext = cl_adapter::cast<cl_context>(hCommandBuffer->hContext);
cl_ext::clEnqueueCommandBufferKHR_fn F = nullptr;
cl_int Res = cl_ext::getExtFuncFromContext<decltype(F)>(
CLContext, cl_ext::ExtFuncPtrCache->clEnqueueCommandBufferKHRCache,
cl_ext::EnqueueCommandBufferName, &F);

if (!F || Res != CL_SUCCESS)
return UR_RESULT_ERROR_INVALID_OPERATION;

const uint32_t NumberOfQueues = 1;

CL_RETURN_ON_FAILURE(F(NumberOfQueues,
cl_adapter::cast<cl_command_queue *>(&hQueue),
hCommandBuffer->CLCommandBuffer, numEventsInWaitList,
cl_adapter::cast<const cl_event *>(phEventWaitList),
cl_adapter::cast<cl_event *>(phEvent)));

return UR_RESULT_SUCCESS;
}
13 changes: 11 additions & 2 deletions source/adapters/opencl/command_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@
//
//===----------------------------------------------------------------------===//

#include <CL/cl_ext.h>
#include <ur/ur.hpp>

/// Stub implementation of command-buffers for OpenCL
struct ur_exp_command_buffer_handle_t_ {
ur_queue_handle_t hInternalQueue;
ur_context_handle_t hContext;
cl_command_buffer_khr CLCommandBuffer;

struct ur_exp_command_buffer_handle_t_ {};
ur_exp_command_buffer_handle_t_(ur_queue_handle_t hQueue,
ur_context_handle_t hContext,
cl_command_buffer_khr CLCommandBuffer)
: hInternalQueue(hQueue), hContext(hContext),
CLCommandBuffer(CLCommandBuffer) {}
};
4 changes: 4 additions & 0 deletions source/adapters/opencl/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ ur_result_t mapCLErrorToUR(cl_int Result) {
return UR_RESULT_ERROR_OUT_OF_RESOURCES;
case CL_INVALID_MEM_OBJECT:
return UR_RESULT_ERROR_INVALID_MEM_OBJECT;
case CL_INVALID_COMMAND_BUFFER_KHR:
return UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_EXP;
case CL_INVALID_SYNC_POINT_WAIT_LIST_KHR:
return UR_RESULT_ERROR_INVALID_COMMAND_BUFFER_SYNC_POINT_WAIT_LIST_EXP;
default:
return UR_RESULT_ERROR_UNKNOWN;
}
Expand Down
Loading

0 comments on commit afbe0b9

Please sign in to comment.