diff options
author | Gil Pitney <gil.pitney@linaro.org> | 2015-06-30 00:12:05 +0000 |
---|---|---|
committer | Gil Pitney <gil.pitney@linaro.org> | 2015-06-30 00:12:05 +0000 |
commit | 11d99a456efb8a0f99090b7c183be20495b3c675 (patch) | |
tree | d1655cd91720e6a502155817d2024c894296c083 | |
parent | dc931e9a05042727d3dd2e82f18cd580e6680bb5 (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.cpp | 13 | ||||
-rw-r--r-- | src/core/commandqueue.h | 3 | ||||
-rw-r--r-- | src/core/cpu/worker.cpp | 19 | ||||
-rw-r--r-- | src/core/events.cpp | 54 | ||||
-rw-r--r-- | src/core/events.h | 24 |
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 |