From 9aa48a7fc407d9f16dc60e8dea2c92c8114a82ea Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Sun, 22 Jun 2014 15:27:55 +0800
Subject: [PATCH] enqueue_migrate_mem_object*

---
 TODOs                             |  2 -
 pyopencl/c_wrapper/wrap_cl_core.h |  8 ++++
 pyopencl/cffi_cl.py               | 25 +++++++++++-
 src/c_wrapper/memory_object.cpp   | 51 +++++++++++++++++++++++
 src/c_wrapper/memory_object.h     | 68 -------------------------------
 5 files changed, 83 insertions(+), 71 deletions(-)

diff --git a/TODOs b/TODOs
index 22ae0413..df683851 100644
--- a/TODOs
+++ b/TODOs
@@ -5,8 +5,6 @@
 - enqueue_nd_range_kernel size/offset mess
 
 - CommandQueue.set_property
-- enqueue_migrate_mem_objects
-- enqueue_migrate_mem_objects_ext
 - _enqueue_copy_image_to_buffer
 - _enqueue_copy_buffer_to_image
 - _Program.create_with_built_in_kernels
diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h
index f2b92603..c22738b8 100644
--- a/pyopencl/c_wrapper/wrap_cl_core.h
+++ b/pyopencl/c_wrapper/wrap_cl_core.h
@@ -170,6 +170,14 @@ error *enqueue_wait_for_events(clobj_t _queue, const clobj_t *_wait_for,
                                uint32_t num_wait_for);
 error *enqueue_marker(clobj_t *event, clobj_t queue);
 error *enqueue_barrier(clobj_t queue);
+error *enqueue_migrate_mem_objects(clobj_t *evt, clobj_t _queue,
+                                   const clobj_t *_mem_obj, uint32_t,
+                                   cl_mem_migration_flags flags,
+                                   const clobj_t *_wait_for, uint32_t);
+error *enqueue_migrate_mem_object_ext(clobj_t *evt, clobj_t _queue,
+                                      const clobj_t *_mem_obj, uint32_t,
+                                      cl_mem_migration_flags_ext flags,
+                                      const clobj_t *_wait_for, uint32_t);
 // enqueue_*_buffer*
 error *enqueue_read_buffer(clobj_t *event, clobj_t queue, clobj_t mem,
                            void *buffer, size_t size, size_t device_offset,
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index ca7d20ef..7145b6de 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -1057,6 +1057,29 @@ def _enqueue_barrier(queue):
 
 # }}}
 
+# {{{ enqueue_migrate_mem_object*
+
+def enqueue_migrate_mem_objects(queue, mem_objects, flags, wait_for=None):
+    _event = _ffi.new('clobj_t*')
+    c_wait_for, num_wait_for = _clobj_list(wait_for)
+    c_mem_objs, num_mem_objs = _clobj_list(mem_objects)
+    _handle_error(_lib.enqueue_migrate_mem_objects(
+        _event, queue.ptr, c_mem_objs, num_mem_objs, flags,
+        c_wait_for, num_wait_for))
+    return Event._create(_event[0])
+
+
+def enqueue_migrate_mem_object_ext(queue, mem_objects, flags, wait_for=None):
+    _event = _ffi.new('clobj_t*')
+    c_wait_for, num_wait_for = _clobj_list(wait_for)
+    c_mem_objs, num_mem_objs = _clobj_list(mem_objects)
+    _handle_error(_lib.enqueue_migrate_mem_object_ext(
+        _event, queue.ptr, c_mem_objs, num_mem_objs, flags,
+        c_wait_for, num_wait_for))
+    return Event._create(_event[0])
+
+# }}}
+
 # {{{ _enqueue_wait_for_events
 
 def _enqueue_wait_for_events(queue, wait_for=None):
@@ -1093,7 +1116,7 @@ def _enqueue_write_buffer(queue, mem, hostbuf, device_offset=0,
 
 
 def _enqueue_copy_buffer(queue, src, dst, byte_count=-1, src_offset=0,
-        dst_offset=0, wait_for=None):
+                         dst_offset=0, wait_for=None):
     ptr_event = _ffi.new('clobj_t*')
     c_wait_for, num_wait_for = _clobj_list(wait_for)
     _handle_error(_lib.enqueue_copy_buffer(
diff --git a/src/c_wrapper/memory_object.cpp b/src/c_wrapper/memory_object.cpp
index 103de78a..4670a4a5 100644
--- a/src/c_wrapper/memory_object.cpp
+++ b/src/c_wrapper/memory_object.cpp
@@ -1,5 +1,7 @@
 #include "memory_object.h"
 #include "context.h"
+#include "event.h"
+#include "command_queue.h"
 #include "clhelper.h"
 
 namespace pyopencl {
@@ -88,3 +90,52 @@ memory_object__get_host_array(clobj_t _obj, void **hostptr, size_t *size)
                                   size_arg(*size), nullptr);
         });
 }
+
+#if PYOPENCL_CL_VERSION >= 0x1020
+error*
+enqueue_migrate_mem_objects(clobj_t *evt, clobj_t _queue,
+                            const clobj_t *_mem_obj, uint32_t num_mem_obj,
+                            cl_mem_migration_flags flags,
+                            const clobj_t *_wait_for, uint32_t num_wait_for)
+{
+    const auto wait_for = buf_from_class<event>(_wait_for, num_wait_for);
+    const auto mem_obj = buf_from_class<memory_object>(_mem_obj, num_mem_obj);
+    auto queue = static_cast<command_queue*>(_queue);
+    return c_handle_retry_mem_error([&] {
+            pyopencl_call_guarded(clEnqueueMigrateMemObjects, queue,
+                                  mem_obj, flags, wait_for, event_out(evt));
+        });
+}
+#endif
+
+#ifdef cl_ext_migrate_memobject
+error*
+enqueue_migrate_mem_object_ext(clobj_t *evt, clobj_t _queue,
+                               const clobj_t *_mem_obj, uint32_t num_mem_obj,
+                               cl_mem_migration_flags_ext flags,
+                               const clobj_t *_wait_for, uint32_t num_wait_for)
+{
+    const auto wait_for = buf_from_class<event>(_wait_for, num_wait_for);
+    const auto mem_obj = buf_from_class<memory_object>(_mem_obj, num_mem_obj);
+    auto queue = static_cast<command_queue*>(_queue);
+    return c_handle_error([&] {
+#if PYOPENCL_CL_VERSION >= 0x1020
+            // {{{ get platform
+            cl_device_id dev;
+            pyopencl_call_guarded(clGetCommandQueueInfo, queue, CL_QUEUE_DEVICE,
+                                  size_arg(dev), nullptr);
+            cl_platform_id plat;
+            pyopencl_call_guarded(clGetDeviceInfo, dev, CL_DEVICE_PLATFORM,
+                                  size_arg(plat), nullptr);
+            // }}}
+#endif
+            auto clEnqueueMigrateMemObjectEXT =
+                pyopencl_get_ext_fun(plat, clEnqueueMigrateMemObjectEXT);
+            retry_mem_error([&] {
+                    pyopencl_call_guarded(clEnqueueMigrateMemObjectsEXT, queue,
+                                          mem_obj, flags, wait_for,
+                                          event_out(evt));
+                });
+        });
+}
+#endif
diff --git a/src/c_wrapper/memory_object.h b/src/c_wrapper/memory_object.h
index 650de5b8..65228f9f 100644
--- a/src/c_wrapper/memory_object.h
+++ b/src/c_wrapper/memory_object.h
@@ -53,74 +53,6 @@ public:
 #endif
 };
 
-// #if PYOPENCL_CL_VERSION >= 0x1020
-//   PYOPENCL_INLINE
-//   event *enqueue_migrate_mem_objects(
-//       command_queue &cq,
-//       py::object py_mem_objects,
-//       cl_mem_migration_flags flags,
-//       py::object py_wait_for)
-//   {
-//     PYOPENCL_PARSE_WAIT_FOR;
-
-//     std::vector<cl_mem> mem_objects;
-//     PYTHON_FOREACH(mo, py_mem_objects)
-//       mem_objects.push_back(py::extract<memory_object &>(mo)().data());
-
-//     cl_event evt;
-//     PYOPENCL_RETRY_IF_MEM_ERROR(
-//       PYOPENCL_CALL_GUARDED(clEnqueueMigrateMemObjects, (
-//             cq.data(),
-//             mem_objects.size(), mem_objects.empty( ) ? nullptr : &mem_objects.front(),
-//             flags,
-//             PYOPENCL_WAITLIST_ARGS, &evt
-//             ));
-//       );
-//     PYOPENCL_RETURN_NEW_EVENT(evt);
-//   }
-// #endif
-
-// #ifdef cl_ext_migrate_memobject
-//   PYOPENCL_INLINE
-//   event *enqueue_migrate_mem_object_ext(
-//       command_queue &cq,
-//       py::object py_mem_objects,
-//       cl_mem_migration_flags_ext flags,
-//       py::object py_wait_for)
-//   {
-//     PYOPENCL_PARSE_WAIT_FOR;
-
-// #if PYOPENCL_CL_VERSION >= 0x1020
-//     // {{{ get platform
-//     cl_device_id dev;
-//     PYOPENCL_CALL_GUARDED(clGetCommandQueueInfo, (cq.data(), CL_QUEUE_DEVICE,
-//           sizeof(dev), &dev, nullptr));
-//     cl_platform_id plat;
-//     PYOPENCL_CALL_GUARDED(clGetDeviceInfo, (cq.data(), CL_DEVICE_PLATFORM,
-//           sizeof(plat), &plat, nullptr));
-//     // }}}
-// #endif
-
-//     PYOPENCL_GET_EXT_FUN(plat,
-//         clEnqueueMigrateMemObjectEXT, enqueue_migrate_fn);
-
-//     std::vector<cl_mem> mem_objects;
-//     PYTHON_FOREACH(mo, py_mem_objects)
-//       mem_objects.push_back(py::extract<memory_object &>(mo)().data());
-
-//     cl_event evt;
-//     PYOPENCL_RETRY_IF_MEM_ERROR(
-//       PYOPENCL_CALL_GUARDED(enqueue_migrate_fn, (
-//             cq.data(),
-//             mem_objects.size(), mem_objects.empty( ) ? nullptr : &mem_objects.front(),
-//             flags,
-//             PYOPENCL_WAITLIST_ARGS, &evt
-//             ));
-//       );
-//     PYOPENCL_RETURN_NEW_EVENT(evt);
-//   }
-// #endif
-
 // }}}
 
 }
-- 
GitLab