aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGil Pitney <gil.pitney@linaro.org>2015-06-30 00:12:05 +0000
committerGil Pitney <gil.pitney@linaro.org>2015-06-30 00:12:05 +0000
commit11d99a456efb8a0f99090b7c183be20495b3c675 (patch)
treed1655cd91720e6a502155817d2024c894296c083
parentdc931e9a05042727d3dd2e82f18cd580e6680bb5 (diff)
Implement clEnqueueMigrateMemObjects() v1.2 API
This implementation passes the Khronos test_buffer_migrate test of the buffers test. However, a real test requires devices of different memory affinities, between which to migrate the buffers, which in the case of a CPUDevice only implementation on heterogenous cores, we don't currently have. Nevertheless, this patch implements the API, and the backend has a nominal implementation which will pre-allocate device buffers when called. Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
-rw-r--r--src/api/api_enqueue.cpp13
-rw-r--r--src/core/commandqueue.h3
-rw-r--r--src/core/cpu/worker.cpp19
-rw-r--r--src/core/events.cpp54
-rw-r--r--src/core/events.h24
5 files changed, 110 insertions, 3 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp
index 4195f43..6431cb8 100644
--- a/src/api/api_enqueue.cpp
+++ b/src/api/api_enqueue.cpp
@@ -911,5 +911,16 @@ clEnqueueMigrateMemObjects(cl_command_queue command_queue,
if (!command_queue->isA(Coal::Object::T_CommandQueue))
return CL_INVALID_COMMAND_QUEUE;
- return rs;
+ Coal::MigrateMemObjectsEvent *command = new Coal::MigrateMemObjectsEvent(
+ (Coal::CommandQueue *)command_queue,
+ num_mem_objects, (const Coal::MemObject **)mem_objects, flags,
+ num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs);
+
+ if (rs != CL_SUCCESS)
+ {
+ delete command;
+ return rs;
+ }
+
+ return queueEvent(command_queue, command, event, false);
}
diff --git a/src/core/commandqueue.h b/src/core/commandqueue.h
index dea1544..e8e9b74 100644
--- a/src/core/commandqueue.h
+++ b/src/core/commandqueue.h
@@ -260,8 +260,9 @@ class Event : public Object
WriteBufferRect = CL_COMMAND_WRITE_BUFFER_RECT,
CopyBufferRect = CL_COMMAND_COPY_BUFFER_RECT,
FillBuffer = CL_COMMAND_FILL_BUFFER,
+ MigrateMemObjects = CL_COMMAND_MIGRATE_MEM_OBJECTS,
User = CL_COMMAND_USER,
- Barrier,
+ Barrier = CL_COMMAND_BARRIER,
WaitForEvents
};
diff --git a/src/core/cpu/worker.cpp b/src/core/cpu/worker.cpp
index 3abfce3..482bd8a 100644
--- a/src/core/cpu/worker.cpp
+++ b/src/core/cpu/worker.cpp
@@ -246,6 +246,25 @@ void *worker(void *data)
break;
}
+ case Event::MigrateMemObjects:
+ {
+ MigrateMemObjectsEvent *e = (MigrateMemObjectsEvent *)event;
+ int num_mem_objects = e->num_mem_objects();
+ Coal::MemObject ** mem_objects = (Coal::MemObject **)e->mem_objects();
+ cl_mem_migration_flags flags = e->flags();
+
+ std::cout << "Event::MigrateMemObjects " << std::endl;
+
+ // Note: we don't handle the CL_MIGRATE_MEM_OBJECT_HOST or
+ // CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED flags, since the buffer allocations
+ // only migrate date from HOST to Device.
+ // Force pre-allocation (or copying) of the CPUBuffers for this device:
+ for (int i = 0; i < num_mem_objects; i++) {
+ mem_objects[i]->allocate(device);
+ }
+ break;
+ }
+
default:
break;
}
diff --git a/src/core/events.cpp b/src/core/events.cpp
index c7a945e..95433b7 100644
--- a/src/core/events.cpp
+++ b/src/core/events.cpp
@@ -1594,3 +1594,57 @@ Event::Type MarkerEvent::type() const
{
return Event::Marker;
}
+
+
+
+MigrateMemObjectsEvent::MigrateMemObjectsEvent(CommandQueue *parent,
+ cl_uint num_mem_objects,
+ const Coal::MemObject **mem_objects,
+ cl_mem_migration_flags flags,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret)
+: Event(parent, CL_QUEUED, num_events_in_wait_list, event_wait_list, errcode_ret),
+ p_num_mem_objects(num_mem_objects), p_mem_objects(mem_objects), p_flags(flags)
+{
+ if (*errcode_ret != CL_SUCCESS) return;
+
+ if (!num_mem_objects || !mem_objects) {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+
+ if (flags & ~(CL_MIGRATE_MEM_OBJECT_HOST | CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED)) {
+ *errcode_ret = CL_INVALID_VALUE;
+ return;
+ }
+
+ Context *ctx = (Context *)parent->parent();
+ for (int i = 0; i < num_mem_objects; i++)
+ {
+ if (!mem_objects[i]->isA(Coal::Object::T_MemObject))
+ { *errcode_ret = CL_INVALID_MEM_OBJECT; break; }
+ else if (ctx != (Context *)mem_objects[i]->parent())
+ { *errcode_ret = CL_INVALID_CONTEXT; break; }
+ }
+}
+
+cl_uint MigrateMemObjectsEvent::num_mem_objects() const
+{
+ return p_num_mem_objects;
+}
+
+const Coal::MemObject ** MigrateMemObjectsEvent::mem_objects() const
+{
+ return p_mem_objects;
+}
+
+cl_mem_migration_flags MigrateMemObjectsEvent::flags() const
+{
+ return p_flags;
+}
+
+Event::Type MigrateMemObjectsEvent::type() const
+{
+ return Event::MigrateMemObjects;
+}
diff --git a/src/core/events.h b/src/core/events.h
index 213d0ba..ceb4fc1 100644
--- a/src/core/events.h
+++ b/src/core/events.h
@@ -743,6 +743,28 @@ class MarkerEvent : public WaitForEventsEvent
Type type() const; /*!< \brief Say the event is a \c Coal::Event::Marker one */
};
-}
+class MigrateMemObjectsEvent: public Event
+{
+ public:
+ MigrateMemObjectsEvent(CommandQueue *parent,
+ cl_uint num_mem_objects,
+ const Coal::MemObject **mem_objects,
+ cl_mem_migration_flags flags,
+ cl_uint num_events_in_wait_list,
+ const Event **event_wait_list,
+ cl_int *errcode_ret);
+ Type type() const; /*!< \brief Say the event is a \c Coal::Event::MigrateMemObjects one */
+
+ cl_uint num_mem_objects() const; /*!< \brief Number of MemObjects to migrate */
+ const Coal::MemObject **mem_objects() const;/*!< \brief List of MemObjects to migrate */
+ cl_mem_migration_flags flags() const; /*!< \brief Migrate flags */
+
+ private:
+ cl_uint p_num_mem_objects;
+ const Coal::MemObject **p_mem_objects;
+ cl_mem_migration_flags p_flags;
+};
+
+}
#endif