From ae6a730b9aa6d2203e39bad421973ec580042b49 Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Fri, 20 Jun 2014 23:09:48 +0800
Subject: [PATCH] create_sub_devices, c api

---
 pyopencl/c_wrapper/wrap_cl_core.h |  4 ++++
 src/c_wrapper/device.cpp          | 34 +++++++++++++++++++++++++++
 src/c_wrapper/device.h            | 38 +++++--------------------------
 3 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h
index b9f5f30c..fb4770c0 100644
--- a/pyopencl/c_wrapper/wrap_cl_core.h
+++ b/pyopencl/c_wrapper/wrap_cl_core.h
@@ -62,6 +62,10 @@ error *get_platforms(clobj_t **ptr_platforms, uint32_t *num_platforms);
 error *platform__get_devices(clobj_t platform, clobj_t **ptr_devices,
                              uint32_t *num_devices, cl_device_type devtype);
 error *platform__unload_compiler(clobj_t plat);
+// Device
+error *device__create_sub_devices(clobj_t _dev, clobj_t **_devs,
+                                  const cl_device_partition_property *props,
+                                  uint32_t *num_devices);
 // Context
 error *create_context(clobj_t *ctx, const cl_context_properties *props,
                       cl_uint num_devices, const clobj_t *ptr_devices);
diff --git a/src/c_wrapper/device.cpp b/src/c_wrapper/device.cpp
index 8041a581..b4ba4575 100644
--- a/src/c_wrapper/device.cpp
+++ b/src/c_wrapper/device.cpp
@@ -249,4 +249,38 @@ device::get_info(cl_uint param_name) const
     }
 }
 
+#if PYOPENCL_CL_VERSION >= 0x1020
+PYOPENCL_USE_RESULT pyopencl_buf<clobj_t>
+device::create_sub_devices(const cl_device_partition_property *props)
+{
+    // TODO debug print cl_device_partition_property
+    cl_uint num_devices;
+    pyopencl_call_guarded(clCreateSubDevices, this, props, 0, nullptr,
+                          buf_arg(num_devices));
+    pyopencl_buf<cl_device_id> devices(num_devices);
+    pyopencl_call_guarded(clCreateSubDevices, this, props, devices,
+                          buf_arg(num_devices));
+    return buf_to_base<device>(devices);
+}
+#endif
+
 }
+
+// c wrapper
+// Import all the names in pyopencl namespace for c wrappers.
+using namespace pyopencl;
+
+#if PYOPENCL_CL_VERSION >= 0x1020
+error*
+device__create_sub_devices(clobj_t _dev, clobj_t **_devs,
+                           const cl_device_partition_property *props,
+                           uint32_t *num_devices)
+{
+    auto dev = static_cast<device*>(_dev);
+    return c_handle_error([&] {
+            auto devs = dev->create_sub_devices(props);
+            *num_devices = (uint32_t)devs.len();
+            *_devs = devs.release();
+        });
+}
+#endif
diff --git a/src/c_wrapper/device.h b/src/c_wrapper/device.h
index ffa363ce..c3a622fa 100644
--- a/src/c_wrapper/device.h
+++ b/src/c_wrapper/device.h
@@ -64,38 +64,12 @@ public:
     ~device();
 
     generic_info get_info(cl_uint param_name) const;
-    // TODO: sub-devices
-    // #if PYOPENCL_CL_VERSION >= 0x1020
-    //       py::list create_sub_devices(py::object py_properties)
-    //       {
-    //         std::vector<cl_device_partition_property> properties;
-
-    //         COPY_PY_LIST(cl_device_partition_property, properties);
-    //         properties.push_back(0);
-
-    //         cl_device_partition_property *props_ptr
-    //           = properties.empty( ) ? nullptr : &properties.front();
-
-    //         cl_uint num_entries;
-    //         PYOPENCL_CALL_GUARDED(clCreateSubDevices,
-    //             (m_device, props_ptr, 0, nullptr, &num_entries));
-
-    //         std::vector<cl_device_id> result;
-    //         result.resize(num_entries);
-
-    //         PYOPENCL_CALL_GUARDED(clCreateSubDevices,
-    //             (m_device, props_ptr, num_entries, &result.front(), nullptr));
-
-    //         py::list py_result;
-    //         BOOST_FOREACH(cl_device_id did, result)
-    //           py_result.append(handle_from_new_ptr(
-    //                 new pyopencl::device(did, /*retain*/true,
-    //                   device::REF_CL_1_2)));
-    //         return py_result;
-    //       }
-    // #endif
+#if PYOPENCL_CL_VERSION >= 0x1020
+    PYOPENCL_USE_RESULT pyopencl_buf<clobj_t>
+    create_sub_devices(const cl_device_partition_property *props);
+#endif
 
-    // #if defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION)
+#if defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION)
     //       py::list create_sub_devices_ext(py::object py_properties)
     //       {
     //         std::vector<cl_device_partition_property_ext> properties;
@@ -131,7 +105,7 @@ public:
     //                   device::REF_FISSION_EXT)));
     //         return py_result;
     //       }
-    // #endif
+#endif
 };
 
 extern template void print_clobj<device>(std::ostream&, const device*);
-- 
GitLab