From 19974a277e8412d50ea5d70884f4f5ed0ab15105 Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Sun, 22 Jun 2014 06:38:21 +0800
Subject: [PATCH] UserEvent

---
 pyopencl/c_wrapper/wrap_cl_core.h |  3 +++
 pyopencl/cffi_cl.py               |  9 +++++++-
 src/c_wrapper/event.cpp           | 35 +++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h
index 1445cb7e..879abcbb 100644
--- a/pyopencl/c_wrapper/wrap_cl_core.h
+++ b/pyopencl/c_wrapper/wrap_cl_core.h
@@ -145,6 +145,9 @@ error *event__set_callback(clobj_t _evt, cl_int type, void *pyobj);
 error *wait_for_events(const clobj_t *_wait_for, uint32_t num_wait_for);
 // Nanny Event
 void *nanny_event__get_ward(clobj_t evt);
+// User Event
+error *create_user_event(clobj_t *_evt, clobj_t _ctx);
+error *user_event__set_status(clobj_t _evt, cl_int status);
 // enqueue_*
 error *enqueue_nd_range_kernel(clobj_t *event, clobj_t queue,
                                clobj_t kernel, cl_uint work_dim,
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index aaeb9ebe..5980453c 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -930,8 +930,15 @@ class NannyEvent(Event):
             return
         return _ffi.from_handle(_handle).ward
 
+class UserEvent(Event):
+    def __init__(self, ctx):
+        _evt = _ffi.new('clobj_t*')
+        _handle_error(_lib.create_user_event(_evt, ctx.ptr))
+        self.ptr = _evt[0]
+    def set_status(self, status):
+        _handle_error(_lib.user_event__set_status(self.ptr, status))
+
 # TODO
-#   UserEvent
 #   enqueue_migrate_mem_objects
 #   enqueue_migrate_mem_objects_ext
 
diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp
index add96393..f577bfdb 100644
--- a/src/c_wrapper/event.cpp
+++ b/src/c_wrapper/event.cpp
@@ -189,6 +189,18 @@ nanny_event::get_ward() const noexcept
             nullptr);
 }
 
+#if PYOPENCL_CL_VERSION >= 0x1010
+class user_event : public event {
+public:
+    using event::event;
+    PYOPENCL_INLINE void
+    set_status(cl_int status)
+    {
+        pyopencl_call_guarded(clSetUserEventStatus, this, status);
+    }
+};
+#endif
+
 }
 
 // c wrapper
@@ -266,3 +278,26 @@ enqueue_wait_for_events(clobj_t _queue, const clobj_t *_wait_for,
             pyopencl_call_guarded(clEnqueueWaitForEvents, queue, wait_for);
         });
 }
+
+#if PYOPENCL_CL_VERSION >= 0x1010
+
+error*
+create_user_event(clobj_t *_evt, clobj_t _ctx)
+{
+    auto ctx = static_cast<context*>(_ctx);
+    return c_handle_error([&] {
+            auto evt = pyopencl_call_guarded(clCreateUserEvent, ctx);
+            *_evt = pyopencl_convert_obj(user_event, clReleaseEvent, evt);
+        });
+}
+
+error*
+user_event__set_status(clobj_t _evt, cl_int status)
+{
+    auto evt = static_cast<user_event*>(_evt);
+    return c_handle_error([&] {
+            evt->set_status(status);
+        });
+}
+
+#endif
-- 
GitLab