diff options
author | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-06-15 13:17:50 +0200 |
---|---|---|
committer | Denis Steckelmacher <steckdenis@yahoo.fr> | 2011-06-15 13:17:50 +0200 |
commit | 21d476ddf26082e334fa007ccc8857079b499857 (patch) | |
tree | 7de7ed4b07542589e79b345d49178301a8e5d214 | |
parent | ce6b5986c64f785b34974fa82d8c6dd7e59eac24 (diff) |
Implement clEnqueueMapBuffer(), add a hook to init device data
-rw-r--r-- | src/api/api_enqueue.cpp | 79 | ||||
-rw-r--r-- | src/core/commandqueue.cpp | 11 | ||||
-rw-r--r-- | src/core/commandqueue.h | 2 | ||||
-rw-r--r-- | src/core/cpudevice.cpp | 49 | ||||
-rw-r--r-- | src/core/cpudevice.h | 1 | ||||
-rw-r--r-- | src/core/deviceinterface.h | 3 | ||||
-rw-r--r-- | src/core/events.cpp | 47 | ||||
-rw-r--r-- | src/core/events.h | 23 | ||||
-rw-r--r-- | tests/test_commandqueue.cpp | 10 |
9 files changed, 179 insertions, 46 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp index a5342e4..6186ace 100644 --- a/src/api/api_enqueue.cpp +++ b/src/api/api_enqueue.cpp @@ -19,10 +19,10 @@ clEnqueueReadBuffer(cl_command_queue command_queue, if (!command_queue) return CL_INVALID_COMMAND_QUEUE; - Coal::RWBufferEvent *command = new Coal::RWBufferEvent( + Coal::BufferEvent *command = new Coal::BufferEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)buffer, - offset, cb, ptr, Coal::Event::ReadBuffer, + offset, cb, ptr, 0, Coal::Event::ReadBuffer, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); @@ -32,7 +32,13 @@ clEnqueueReadBuffer(cl_command_queue command_queue, return rs; } - command_queue->queueEvent(command); + rs = command_queue->queueEvent(command); + + if (rs != CL_SUCCESS) + { + delete command; + return rs; + } if (event) { @@ -63,11 +69,12 @@ clEnqueueWriteBuffer(cl_command_queue command_queue, if (!command_queue) return CL_INVALID_COMMAND_QUEUE; - Coal::RWBufferEvent *command = new Coal::RWBufferEvent( + Coal::BufferEvent *command = new Coal::BufferEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)buffer, - offset, cb, (void *)ptr, Coal::Event::WriteBuffer, - num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs); + offset, cb, (void *)ptr, 0, Coal::Event::WriteBuffer, + num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs + ); if (rs != CL_SUCCESS) { @@ -75,7 +82,13 @@ clEnqueueWriteBuffer(cl_command_queue command_queue, return rs; } - command_queue->queueEvent(command); + rs = command_queue->queueEvent(command); + + if (rs != CL_SUCCESS) + { + delete command; + return rs; + } if (event) { @@ -189,7 +202,57 @@ clEnqueueMapBuffer(cl_command_queue command_queue, cl_event * event, cl_int * errcode_ret) { - return 0; + cl_int rs; + + if (!errcode_ret) + errcode_ret = &rs; + + *errcode_ret = CL_SUCCESS; + + if (!command_queue) + { + *errcode_ret = CL_INVALID_COMMAND_QUEUE; + return 0; + } + + Coal::BufferEvent *command = new Coal::BufferEvent( + (Coal::CommandQueue *)command_queue, + (Coal::MemObject *)buffer, + offset, cb, 0, map_flags, Coal::Event::MapBuffer, + num_events_in_wait_list, (const Coal::Event **)event_wait_list, errcode_ret + ); + + if (*errcode_ret != CL_SUCCESS) + { + delete command; + return 0; + } + + *errcode_ret = command_queue->queueEvent(command); + + if (*errcode_ret != CL_SUCCESS) + { + delete command; + return 0; + } + + if (event) + { + *event = (cl_event)command; + command->reference(); + } + + if (blocking_map) + { + *errcode_ret = clWaitForEvents(1, (cl_event *)&command); + + if (*errcode_ret != CL_SUCCESS) + { + clReleaseEvent((cl_event)command); + } + } + + return command->ptr(); } void * diff --git a/src/core/commandqueue.cpp b/src/core/commandqueue.cpp index 272daf0..47ed445 100644 --- a/src/core/commandqueue.cpp +++ b/src/core/commandqueue.cpp @@ -150,8 +150,15 @@ cl_int CommandQueue::checkProperties() const return CL_SUCCESS; } -void CommandQueue::queueEvent(Event *event) +cl_int CommandQueue::queueEvent(Event *event) { + // Let the device initialize the event (for instance, a pointer at which + // memory would be mapped) + cl_int rs = p_device->initEventDeviceData(event); + + if (rs != CL_SUCCESS) + return rs; + // Append the event at the end of the list pthread_mutex_lock(&p_event_list_mutex); @@ -165,6 +172,8 @@ void CommandQueue::queueEvent(Event *event) // Explore the list for events we can push on the device pushEventsOnDevice(); + + return CL_SUCCESS; } void CommandQueue::cleanEvents() diff --git a/src/core/commandqueue.h b/src/core/commandqueue.h index 93afc86..ba8e291 100644 --- a/src/core/commandqueue.h +++ b/src/core/commandqueue.h @@ -26,7 +26,7 @@ class CommandQueue void reference(); bool dereference(); /*!< @return true if reference becomes 0 */ - void queueEvent(Event *event); + cl_int queueEvent(Event *event); cl_int info(cl_context_info param_name, size_t param_value_size, diff --git a/src/core/cpudevice.cpp b/src/core/cpudevice.cpp index 75990b4..48cbfb6 100644 --- a/src/core/cpudevice.cpp +++ b/src/core/cpudevice.cpp @@ -51,18 +51,29 @@ static void *worker(void *data) event->updateTiming(Event::Start); // Execute the action - if (t == Event::ReadBuffer || t == Event::WriteBuffer) + switch (t) { - RWBufferEvent *e = (RWBufferEvent *)event; - CPUBuffer *buf = (CPUBuffer *)e->buffer()->deviceBuffer(device); - char *data = (char *)buf->data(); - - data += e->offset(); - - if (t == Event::ReadBuffer) - memcpy(e->ptr(), data, e->cb()); - else - memcpy(data, e->ptr(), e->cb()); + case Event::ReadBuffer: + case Event::WriteBuffer: + { + BufferEvent *e = (BufferEvent *)event; + CPUBuffer *buf = (CPUBuffer *)e->buffer()->deviceBuffer(device); + char *data = (char *)buf->data(); + + data += e->offset(); + + if (t == Event::ReadBuffer) + memcpy(e->ptr(), data, e->cb()); + else + memcpy(data, e->ptr(), e->cb()); + + break; + } + case Event::MapBuffer: + // All was already done in CPUBuffer::initEventDeviceData() + break; + default: + break; } // Cleanups @@ -129,6 +140,22 @@ DeviceBuffer *CPUDevice::createDeviceBuffer(MemObject *buffer, cl_int *rs) return (DeviceBuffer *)new CPUBuffer(this, buffer, rs); } +cl_int CPUDevice::initEventDeviceData(Event *event) +{ + if (event->type() == Event::MapBuffer) + { + BufferEvent *e = (BufferEvent *)event; + CPUBuffer *buf = (CPUBuffer *)e->buffer()->deviceBuffer(this); + char *data = (char *)buf->data(); + + data += e->offset(); + + e->setPtr((void *)data); + } + + return CL_SUCCESS; +} + void CPUDevice::pushEvent(Event *event) { // Add an event in the list diff --git a/src/core/cpudevice.h b/src/core/cpudevice.h index 2648571..25f4ddb 100644 --- a/src/core/cpudevice.h +++ b/src/core/cpudevice.h @@ -23,6 +23,7 @@ class CPUDevice : public DeviceInterface void *param_value, size_t *param_value_size_ret); DeviceBuffer *createDeviceBuffer(MemObject *buffer, cl_int *rs); + cl_int initEventDeviceData(Event *event); void pushEvent(Event *event); Event *getEvent(bool &stop); diff --git a/src/core/deviceinterface.h b/src/core/deviceinterface.h index aebdbf4..aa0feb3 100644 --- a/src/core/deviceinterface.h +++ b/src/core/deviceinterface.h @@ -23,6 +23,9 @@ class DeviceInterface virtual DeviceBuffer *createDeviceBuffer(MemObject *buffer, cl_int *rs) = 0; virtual void pushEvent(Event *event) = 0; + + /** @note must set mapping address of MapBuffer events */ + virtual cl_int initEventDeviceData(Event *event) = 0; }; class DeviceBuffer diff --git a/src/core/events.cpp b/src/core/events.cpp index a2d984b..59af616 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -9,17 +9,19 @@ using namespace Coal; * Read/Write buffers */ -RWBufferEvent::RWBufferEvent(CommandQueue *parent, - MemObject *buffer, - size_t offset, - size_t cb, - void *ptr, - EventType type, - cl_uint num_events_in_wait_list, - const Event **event_wait_list, - cl_int *errcode_ret) +BufferEvent::BufferEvent(CommandQueue *parent, + MemObject *buffer, + size_t offset, + size_t cb, + void *ptr, + cl_map_flags map_flags, + EventType type, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret) : Event(parent, Queued, num_events_in_wait_list, event_wait_list, errcode_ret), - p_buffer(buffer), p_offset(offset), p_cb(cb), p_ptr(ptr), p_type(type) + p_buffer(buffer), p_offset(offset), p_cb(cb), p_ptr(ptr), + p_map_flags(map_flags), p_type(type) { // Correct buffer if (!buffer) @@ -53,6 +55,16 @@ RWBufferEvent::RWBufferEvent(CommandQueue *parent, return; } + // Map flags + if (type == Event::MapBuffer) + { + if (map_flags | ~(CL_MAP_READ | CL_MAP_WRITE)) + { + *errcode_ret = CL_INVALID_VALUE; + return; + } + } + // Alignment of SubBuffers DeviceInterface *device = 0; cl_uint align; @@ -88,27 +100,32 @@ RWBufferEvent::RWBufferEvent(CommandQueue *parent, } } -MemObject *RWBufferEvent::buffer() const +MemObject *BufferEvent::buffer() const { return p_buffer; } -size_t RWBufferEvent::offset() const +size_t BufferEvent::offset() const { return p_offset; } -size_t RWBufferEvent::cb() const +size_t BufferEvent::cb() const { return p_cb; } -void *RWBufferEvent::ptr() const +void *BufferEvent::ptr() const { return p_ptr; } -Event::EventType RWBufferEvent::type() const +void BufferEvent::setPtr(void *ptr) +{ + p_ptr = ptr; +} + +Event::EventType BufferEvent::type() const { return p_type; } diff --git a/src/core/events.h b/src/core/events.h index 729492f..383b5a5 100644 --- a/src/core/events.h +++ b/src/core/events.h @@ -10,18 +10,19 @@ namespace Coal class MemObject; -class RWBufferEvent : public Event +class BufferEvent : public Event { public: - RWBufferEvent(CommandQueue *parent, - MemObject *buffer, - size_t offset, - size_t cb, - void *ptr, - EventType type, - cl_uint num_events_in_wait_list, - const Event **event_wait_list, - cl_int *errcode_ret); + BufferEvent(CommandQueue *parent, + MemObject *buffer, + size_t offset, + size_t cb, + void *ptr, + cl_map_flags map_flags, + EventType type, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret); EventType type() const; @@ -29,11 +30,13 @@ class RWBufferEvent : public Event size_t offset() const; size_t cb() const; void *ptr() const; + void setPtr(void *ptr); private: MemObject *p_buffer; size_t p_offset, p_cb; void *p_ptr; + cl_map_flags p_map_flags; EventType p_type; }; diff --git a/tests/test_commandqueue.cpp b/tests/test_commandqueue.cpp index 49f24a3..dba684a 100644 --- a/tests/test_commandqueue.cpp +++ b/tests/test_commandqueue.cpp @@ -299,6 +299,16 @@ START_TEST (test_events) "we cannot call clSetUserEventStatus two times for an event" ); + // Queue a map buffer + char *data; + + data = (char *) clEnqueueMapBuffer(queue, buf, 1, CL_MAP_READ, 0, sizeof(s), + 0, 0, 0, &result); + fail_if( + result != CL_SUCCESS || !data || strncmp(data, s, sizeof(s)), + "unable to map a buffer containing what the buffer contains" + ); + // Get timing information about the event cl_ulong timing_queued, timing_submit, timing_start, timing_end; |