From afaee8b060fb9261c1059127c5409b501e65b015 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Mon, 15 Jul 2013 15:47:54 -0400
Subject: [PATCH] Improve compatibility shims for
 enqueue_{fill_buffer,barrier,marker}.

---
 doc/runtime.rst                |  5 ----
 pyopencl/__init__.py           | 39 ++++++++++++++++++++++++++-
 src/wrapper/wrap_cl.hpp        | 49 +++++++++++++---------------------
 src/wrapper/wrap_cl_part_1.cpp | 20 ++++++++++----
 4 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/doc/runtime.rst b/doc/runtime.rst
index 905f06f1..20fceb24 100644
--- a/doc/runtime.rst
+++ b/doc/runtime.rst
@@ -278,11 +278,6 @@ Command Queues and Events
     .. versionchanged:: 2011.2
         Takes *wait_for*.
 
-.. function:: enqueue_wait_for_events(queue, events)
-
-    **Note:** This function is deprecated as of PyOpenCL 2011.2.
-        Use :func:`enqueue_marker` instead.
-
 .. class:: UserEvent(context)
 
     A subclass of :class:`Event`. Only available with OpenCL 1.1 and newer.
diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index ef39efc0..a7e3830e 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -458,8 +458,12 @@ def _add_functionality():
     def command_queue_exit(self, exc_type, exc_val, exc_tb):
         self.finish()
 
+    def command_queue_get_cl_version(self):
+        return self.context._get_cl_version()
+
     CommandQueue.__enter__ = command_queue_enter
     CommandQueue.__exit__ = command_queue_exit
+    CommandQueue._get_cl_version = memoize_method(command_queue_get_cl_version)
 
     # }}}
 
@@ -688,7 +692,8 @@ def _find_pyopencl_include_path():
 # }}}
 
 
-# {{{ convenience -------------------------------------------------------------
+# {{{ convenience
+
 def create_some_context(interactive=True, answers=None):
     import os
     if answers is None and "PYOPENCL_CTX" in os.environ:
@@ -1102,6 +1107,38 @@ def image_from_array(ctx, ary, num_channels=None, mode="r", norm_int=False):
 # }}}
 
 
+# {{{ enqueue_* compatibility shims
+
+def enqueue_marker(queue, wait_for=None):
+    if queue._get_cl_version() >= (1, 2) and get_cl_header_version() >= (1, 2):
+        return _cl._enqueue_marker_with_wait_list(queue, wait_for)
+    else:
+        if wait_for:
+            _cl._enqueue_wait_for_events(queue, wait_for)
+        return _cl._enqueue_marker(queue)
+
+
+def enqueue_barrier(queue, wait_for=None):
+    if queue._get_cl_version() >= (1, 2) and get_cl_header_version() >= (1, 2):
+        return _cl._enqueue_barrier_with_wait_list(queue, wait_for)
+    else:
+        _cl._enqueue_barrier(queue)
+        if wait_for:
+            _cl._enqueue_wait_for_events(queue, wait_for)
+        return _cl._enqueue_marker(queue)
+
+
+def enqueue_fill_buffer(queue, mem, pattern, offset, size, wait_for=None):
+    if not (queue._get_cl_version() >= (1, 2) and get_cl_header_version() >= (1, 2)):
+        from warnings import warn
+        warn("The context for this queue does not declare OpenCL 1.2 support, so "
+                "the next thing you might see is a crash")
+    return _cl.enqueue_fill_buffer(queue, mem, pattern, offset,
+            size, wait_for=None)
+
+
+
+# }}}
 
 
 # vim: foldmethod=marker
diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp
index b85cb6f0..14c01385 100644
--- a/src/wrapper/wrap_cl.hpp
+++ b/src/wrapper/wrap_cl.hpp
@@ -1377,68 +1377,51 @@ namespace pyopencl
 
 
 
+#if PYOPENCL_CL_VERSION >= 0x1020
   inline
-  event *enqueue_marker(command_queue &cq,
+  event *enqueue_marker_with_wait_list(command_queue &cq,
       py::object py_wait_for)
   {
     PYOPENCL_PARSE_WAIT_FOR;
     cl_event evt;
 
-#if PYOPENCL_CL_VERSION >= 0x1020
     PYOPENCL_CALL_GUARDED(clEnqueueMarkerWithWaitList, (
           cq.data(), PYOPENCL_WAITLIST_ARGS, &evt));
-#else
-    if (num_events_in_wait_list)
-    {
-      PYOPENCL_CALL_GUARDED(clEnqueueWaitForEvents, (
-            cq.data(), PYOPENCL_WAITLIST_ARGS));
-    }
-    PYOPENCL_CALL_GUARDED(clEnqueueMarker, (
-          cq.data(), &evt));
-#endif
 
     PYOPENCL_RETURN_NEW_EVENT(evt);
   }
 
-
-
-
-
   inline
-  event *enqueue_barrier(command_queue &cq,
+  event *enqueue_barrier_with_wait_list(command_queue &cq,
       py::object py_wait_for)
   {
     PYOPENCL_PARSE_WAIT_FOR;
     cl_event evt;
 
-#if PYOPENCL_CL_VERSION >= 0x1020
     PYOPENCL_CALL_GUARDED(clEnqueueBarrierWithWaitList,
         (cq.data(), PYOPENCL_WAITLIST_ARGS, &evt));
 
-#else
-    if (num_events_in_wait_list)
-    {
-      PYOPENCL_CALL_GUARDED(clEnqueueWaitForEvents, (
-            cq.data(), PYOPENCL_WAITLIST_ARGS));
-    }
+    PYOPENCL_RETURN_NEW_EVENT(evt);
+  }
+#endif
 
-    PYOPENCL_CALL_GUARDED(clEnqueueBarrier, (cq.data()));
+
+  // {{{ used internally for pre-OpenCL-1.2 contexts
+
+  inline
+  event *enqueue_marker(command_queue &cq)
+  {
+    cl_event evt;
 
     PYOPENCL_CALL_GUARDED(clEnqueueMarker, (
           cq.data(), &evt));
-#endif
 
     PYOPENCL_RETURN_NEW_EVENT(evt);
   }
 
-
-
-
   inline
   void enqueue_wait_for_events(command_queue &cq, py::object py_events)
   {
-    PYOPENCL_DEPRECATED("enqueue_wait_for_events", "2013.1", );
-
     cl_uint num_events = 0;
     std::vector<cl_event> event_list(len(py_events));
 
@@ -1450,7 +1433,13 @@ namespace pyopencl
           cq.data(), num_events, event_list.empty( ) ? NULL : &event_list.front()));
   }
 
+  inline
+  void enqueue_barrier(command_queue &cq)
+  {
+    PYOPENCL_CALL_GUARDED(clEnqueueBarrier, (cq.data()));
+  }
 
+  // }}}
 
 
 #if PYOPENCL_CL_VERSION >= 0x1010
diff --git a/src/wrapper/wrap_cl_part_1.cpp b/src/wrapper/wrap_cl_part_1.cpp
index b9f55a06..dba0dec7 100644
--- a/src/wrapper/wrap_cl_part_1.cpp
+++ b/src/wrapper/wrap_cl_part_1.cpp
@@ -118,14 +118,24 @@ void pyopencl_expose_part_1()
   }
 
   DEF_SIMPLE_FUNCTION(wait_for_events);
-  py::def("enqueue_marker", enqueue_marker,
+
+#if PYOPENCL_CL_VERSION >= 0x1020
+  py::def("_enqueue_marker_with_wait_list", enqueue_marker_with_wait_list,
       (py::arg("queue"), py::arg("wait_for")=py::object()),
       py::return_value_policy<py::manage_new_object>());
-  py::def("enqueue_barrier", enqueue_barrier,
-      (py::arg("queue"), py::arg("wait_for")=py::object()),
+#endif
+  py::def("_enqueue_marker", enqueue_marker,
+      (py::arg("queue")),
       py::return_value_policy<py::manage_new_object>());
+  py::def("_enqueue_wait_for_events", enqueue_wait_for_events,
+      (py::arg("queue"), py::arg("wait_for")=py::object()));
 
-  DEF_SIMPLE_FUNCTION(enqueue_wait_for_events);
+#if PYOPENCL_CL_VERSION >= 0x1020
+  py::def("_enqueue_barrier_with_wait_list", enqueue_barrier_with_wait_list,
+      (py::arg("queue"), py::arg("wait_for")=py::object()),
+      py::return_value_policy<py::manage_new_object>());
+#endif
+  py::def("_enqueue_barrier", enqueue_barrier, py::arg("queue"));
 
 #if PYOPENCL_CL_VERSION >= 0x1010
   {
@@ -273,7 +283,7 @@ void pyopencl_expose_part_1()
   // }}}
 
 #if PYOPENCL_CL_VERSION >= 0x1020
-  py::def("enqueue_fill_buffer", enqueue_fill_buffer,
+  py::def("_enqueue_fill_buffer", enqueue_fill_buffer,
       (py::args("queue", "mem", "pattern", "offset", "size"),
        py::arg("wait_for")=py::object()),
       py::return_value_policy<py::manage_new_object>());
-- 
GitLab