diff --git a/nntrainer/opencl/opencl_buffer.cpp b/nntrainer/opencl/opencl_buffer.cpp index 0fae39db2f..1614f3e622 100644 --- a/nntrainer/opencl/opencl_buffer.cpp +++ b/nntrainer/opencl/opencl_buffer.cpp @@ -32,7 +32,7 @@ Buffer::Buffer(ContextManager &context_manager, int size_in_bytes, cl_context context = context_manager.GetContext(); cl_mem_flags flags = read_only ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE; if (data) { - flags |= CL_MEM_COPY_HOST_PTR; + flags |= CL_MEM_USE_HOST_PTR; } cl_int error_code; @@ -105,6 +105,18 @@ bool Buffer::ReadData(CommandQueueManager &command_queue_inst, void *data) { return command_queue_inst.EnqueueReadBuffer(mem_buf_, size_, data); } +void *Buffer::MapBuffer(CommandQueueManager &command_queue_inst, + size_t offset_in_bytes, size_t size_in_bytes, + bool read_only, bool async) { + return command_queue_inst.EnqueueMapBuffer(mem_buf_, offset_in_bytes, + size_in_bytes, read_only, async); +} + +bool Buffer::UnMapBuffer(CommandQueueManager &command_queue_inst, + void *mapped_ptr) { + return command_queue_inst.EnqueueUnmapMemObject(mem_buf_, mapped_ptr); +} + /** * @brief Release OpenCL buffer * diff --git a/nntrainer/opencl/opencl_buffer.h b/nntrainer/opencl/opencl_buffer.h index 11e2e7c10b..031efe5cbf 100644 --- a/nntrainer/opencl/opencl_buffer.h +++ b/nntrainer/opencl/opencl_buffer.h @@ -114,6 +114,30 @@ class Buffer { * @return true if successful read or false otherwise */ bool ReadData(CommandQueueManager &command_queue_inst, void *data); + + /** + * @brief Mapping buffer to host memory + * + * @param command_queue_inst reference of command queue instance + * @param offset_in_bytes offset of the region in the buffer object that is + * being mapped + * @param size_in_bytes size of the buffer object that is being mapped + * @param read_only flag for read only mapping + * @param async flag for asynchronous operation + * @return void* pointer to the mapped region + */ + void *MapBuffer(CommandQueueManager &command_queue_inst, + size_t offset_in_bytes, size_t size_in_bytes, bool read_only, + bool async = false); + + /** + * @brief Un-mapping buffer from host memeory + * + * @param command_queue_inst reference of command queue instance + * @param mapped_ptr pointer to the mapped region + * @return true if unmap is successful + */ + bool UnMapBuffer(CommandQueueManager &command_queue_inst, void *mapped_ptr); }; } // namespace nntrainer::opencl #endif // __OPENCL_BUFFER_H__ diff --git a/nntrainer/opencl/opencl_command_queue_manager.cpp b/nntrainer/opencl/opencl_command_queue_manager.cpp index 109d83e78a..e1bffa9f28 100644 --- a/nntrainer/opencl/opencl_command_queue_manager.cpp +++ b/nntrainer/opencl/opencl_command_queue_manager.cpp @@ -160,6 +160,68 @@ bool CommandQueueManager::EnqueueWriteBuffer(cl_mem buffer, return true; } +/** + * @brief Mapping a region of a buffer object into the host address space + * + * @param buffer cl_mem buffer object + * @param offset_in_bytes offset of the region in the buffer object that is + * being mapped + * @param size_in_bytes size of the buffer object that is being mapped + * @param read_only flag for read only mapping + * @param async flag for asynchronous operation + * @param event Object that identifies this command and can be used to query + * or wait for this command to complete + * @return void* pointer to the mapped region + */ +void *CommandQueueManager::EnqueueMapBuffer(cl_mem buffer, + size_t offset_in_bytes, + size_t size_in_bytes, + bool read_only, bool async, + cl_event *event) { + // managing synchronization + const cl_bool blocking = async ? CL_FALSE : CL_TRUE; + // managing read/write flags + const cl_map_flags map_flag = read_only ? CL_MAP_READ : CL_MAP_WRITE; + + cl_int error_code; + + void *host_mem_buf = clEnqueueMapBuffer( + command_queue_, buffer, blocking, map_flag, offset_in_bytes, size_in_bytes, + 0, nullptr, event, &error_code); + + if (error_code != CL_SUCCESS) { + ml_loge( + "Failed to map buffer to host memory(clEnqueueMapBuffer). OpenCL error " + "code: %d", + error_code); + return nullptr; + } + return host_mem_buf; +} + +/** + * @brief Mapping a region of a buffer object into the host address space + * + * @param buffer cl_mem buffer object + * @param mapped_ptr pointer to the mapped region + * @param event Object that identifies this command and can be used to query + * or wait for this command to complete + * @return true if unmap is successful + */ +bool CommandQueueManager::EnqueueUnmapMemObject(cl_mem buffer, void *mapped_ptr, + cl_event *event) { + cl_int error_code = clEnqueueUnmapMemObject(command_queue_, buffer, + mapped_ptr, 0, nullptr, event); + if (error_code != CL_SUCCESS) { + ml_loge("Failed to unmap buffer from host memory(clEnqueueUnmapMemObject). " + "OpenCL error " + "code: %d", + error_code); + return false; + } + return true; +} + /** * @brief Function to initiate execution of the command queue. * diff --git a/nntrainer/opencl/opencl_command_queue_manager.h b/nntrainer/opencl/opencl_command_queue_manager.h index 1e98f202f5..8f9965e654 100644 --- a/nntrainer/opencl/opencl_command_queue_manager.h +++ b/nntrainer/opencl/opencl_command_queue_manager.h @@ -85,6 +85,35 @@ class CommandQueueManager { bool EnqueueWriteBuffer(cl_mem buffer, size_t size_in_bytes, const void *data, bool async = false); + /** + * @brief Mapping a region of a buffer object into the host address space + * + * @param buffer cl_mem buffer object + * @param offset_in_bytes offset of the region in the buffer object that is + * being mapped + * @param size_in_bytes size of the buffer object that is being mapped + * @param read_only flag for read only mapping + * @param async flag for asynchronous operation + * @param event Object that identifies this command and can be used to query + * or wait for this command to complete + * @return void* pointer to the mapped region + */ + void *EnqueueMapBuffer(cl_mem buffer, size_t offset_in_bytes, + size_t size_in_bytes, bool read_only, + bool async = false, cl_event *event = nullptr); + + /** + * @brief Un-mapping a buffer object from the host address space + * + * @param buffer cl_mem buffer object + * @param mapped_ptr pointer to the mapped region + * @param event Object that identifies this command and can be used to query + * or wait for this command to complete + * @return true if unmap is successful + */ + bool EnqueueUnmapMemObject(cl_mem buffer, void *mapped_ptr, + cl_event *event = nullptr); + /** * @brief Function to initiate execution of the command queue. * diff --git a/nntrainer/opencl/opencl_loader.cpp b/nntrainer/opencl/opencl_loader.cpp index 34101b6a4c..e3cf3e73c2 100644 --- a/nntrainer/opencl/opencl_loader.cpp +++ b/nntrainer/opencl/opencl_loader.cpp @@ -73,6 +73,8 @@ void LoadOpenCLFunctions(void *libopencl) { LoadFunction(clCreateBuffer); LoadFunction(clEnqueueWriteBuffer); LoadFunction(clEnqueueReadBuffer); + LoadFunction(clEnqueueMapBuffer); + LoadFunction(clEnqueueUnmapMemObject); LoadFunction(clCreateProgramWithSource); LoadFunction(clCreateProgramWithBinary); LoadFunction(clBuildProgram); @@ -98,6 +100,8 @@ PFN_clCreateCommandQueue clCreateCommandQueue; PFN_clCreateBuffer clCreateBuffer; PFN_clEnqueueWriteBuffer clEnqueueWriteBuffer; PFN_clEnqueueReadBuffer clEnqueueReadBuffer; +PFN_clEnqueueMapBuffer clEnqueueMapBuffer; +PFN_clEnqueueUnmapMemObject clEnqueueUnmapMemObject; PFN_clCreateProgramWithSource clCreateProgramWithSource; PFN_clCreateProgramWithBinary clCreateProgramWithBinary; PFN_clBuildProgram clBuildProgram; diff --git a/nntrainer/opencl/opencl_loader.h b/nntrainer/opencl/opencl_loader.h index 99142d5b12..0aa2a5cfd6 100644 --- a/nntrainer/opencl/opencl_loader.h +++ b/nntrainer/opencl/opencl_loader.h @@ -72,6 +72,21 @@ typedef cl_int(CL_API_CALL *PFN_clEnqueueReadBuffer)( void * /**< ptr */, cl_uint /**< num_events_in_wait_list */, const cl_event * /**< event_wait_list */, cl_event * /**< event */); +typedef void *(CL_API_CALL *PFN_clEnqueueMapBuffer)( + cl_command_queue /**< command_queue */, cl_mem /**< buffer */, + cl_bool /**< blocking_map */, cl_map_flags /**< map_flags */, + size_t /**< offset */, size_t /**< size */, + cl_uint /**< num_events_in_wait_list */, + const cl_event * /**< event_wait_list */, cl_event * /**< event */, + cl_int * /**< errcode_ret */ +); + +typedef cl_int(CL_API_CALL *PFN_clEnqueueUnmapMemObject)( + cl_command_queue /**< command_queue */, cl_mem /**< memobj */, + void * /**< mapped_ptr */, cl_uint /**< num_events_in_wait_list */, + const cl_event * /**< event_wait_list */, cl_event * /**< event */ +); + typedef cl_program(CL_API_CALL *PFN_clCreateProgramWithSource)( cl_context /**< context */, cl_uint /**< count */, const char ** /**< strings */, const size_t * /**< lengths */, @@ -144,6 +159,8 @@ extern PFN_clCreateCommandQueue clCreateCommandQueue; extern PFN_clCreateBuffer clCreateBuffer; extern PFN_clEnqueueWriteBuffer clEnqueueWriteBuffer; extern PFN_clEnqueueReadBuffer clEnqueueReadBuffer; +extern PFN_clEnqueueMapBuffer clEnqueueMapBuffer; +extern PFN_clEnqueueUnmapMemObject clEnqueueUnmapMemObject; extern PFN_clCreateProgramWithSource clCreateProgramWithSource; extern PFN_clCreateProgramWithBinary clCreateProgramWithBinary; extern PFN_clBuildProgram clBuildProgram;