Skip to content

Commit

Permalink
[GPU/Optimization] Adding map/unmap feature for buffer
Browse files Browse the repository at this point in the history
Implementing map and unmap buffer options to re-use host memory

Signed-off-by: Debadri Samaddar <[email protected]>
  • Loading branch information
s-debadri committed Oct 29, 2024
1 parent aa5fabc commit 9342de4
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 1 deletion.
14 changes: 13 additions & 1 deletion nntrainer/opencl/opencl_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
*
Expand Down
24 changes: 24 additions & 0 deletions nntrainer/opencl/opencl_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
62 changes: 62 additions & 0 deletions nntrainer/opencl/opencl_command_queue_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
29 changes: 29 additions & 0 deletions nntrainer/opencl/opencl_command_queue_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,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.
*
Expand Down
4 changes: 4 additions & 0 deletions nntrainer/opencl/opencl_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ void LoadOpenCLFunctions(void *libopencl) {
LoadFunction(clCreateBuffer);
LoadFunction(clEnqueueWriteBuffer);
LoadFunction(clEnqueueReadBuffer);
LoadFunction(clEnqueueMapBuffer);
LoadFunction(clEnqueueUnmapMemObject);
LoadFunction(clCreateProgramWithSource);
LoadFunction(clCreateProgramWithBinary);
LoadFunction(clBuildProgram);
Expand All @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions nntrainer/opencl/opencl_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 9342de4

Please sign in to comment.