summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Steckelmacher <steckdenis@yahoo.fr>2011-06-15 13:17:50 +0200
committerDenis Steckelmacher <steckdenis@yahoo.fr>2011-06-15 13:17:50 +0200
commit21d476ddf26082e334fa007ccc8857079b499857 (patch)
tree7de7ed4b07542589e79b345d49178301a8e5d214
parentce6b5986c64f785b34974fa82d8c6dd7e59eac24 (diff)
Implement clEnqueueMapBuffer(), add a hook to init device data
-rw-r--r--src/api/api_enqueue.cpp79
-rw-r--r--src/core/commandqueue.cpp11
-rw-r--r--src/core/commandqueue.h2
-rw-r--r--src/core/cpudevice.cpp49
-rw-r--r--src/core/cpudevice.h1
-rw-r--r--src/core/deviceinterface.h3
-rw-r--r--src/core/events.cpp47
-rw-r--r--src/core/events.h23
-rw-r--r--tests/test_commandqueue.cpp10
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;