From 54f435d64746e8550e4391cf0834f0208093fce6 Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Tue, 24 Jun 2014 12:23:35 +0800
Subject: [PATCH] handle void and null ArgBuffer

---
 src/c_wrapper/debug.cpp  | 13 +++++++++++
 src/c_wrapper/debug.h    |  1 +
 src/c_wrapper/kernel.cpp |  3 ++-
 src/c_wrapper/utils.h    | 50 ++++++++++++++++++++++++++++++++--------
 4 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/src/c_wrapper/debug.cpp b/src/c_wrapper/debug.cpp
index c5806891..75d109fa 100644
--- a/src/c_wrapper/debug.cpp
+++ b/src/c_wrapper/debug.cpp
@@ -1,5 +1,7 @@
 #include "debug.h"
 #include <iostream>
+#include <ios>
+#include <iomanip>
 #include <stdlib.h>
 
 namespace pyopencl {
@@ -39,6 +41,17 @@ dbg_print_str(std::ostream &stm, const char *str, size_t len)
     stm << '"';
 }
 
+void
+dbg_print_bytes(std::ostream &stm, const unsigned char *bytes, size_t len)
+{
+    stm << '"';
+    for (size_t i = 0;i < len;i++) {
+        stm << "\\x" << std::hex << std::setfill('0')
+            << std::setw(2) << bytes[i];
+    }
+    stm << std::dec << '"';
+}
+
 static PYOPENCL_INLINE bool
 _get_debug_env()
 {
diff --git a/src/c_wrapper/debug.h b/src/c_wrapper/debug.h
index 34491481..777dc680 100644
--- a/src/c_wrapper/debug.h
+++ b/src/c_wrapper/debug.h
@@ -25,6 +25,7 @@ dbg_print_str(std::ostream &stm, const char *str)
 {
     return dbg_print_str(stm, str, strlen(str));
 }
+void dbg_print_bytes(std::ostream &stm, const unsigned char *bytes, size_t len);
 
 }
 
diff --git a/src/c_wrapper/kernel.cpp b/src/c_wrapper/kernel.cpp
index 3e94cdbf..0d367a83 100644
--- a/src/c_wrapper/kernel.cpp
+++ b/src/c_wrapper/kernel.cpp
@@ -142,7 +142,8 @@ kernel__set_arg_buf(clobj_t _knl, cl_uint arg_index,
 {
     auto knl = static_cast<kernel*>(_knl);
     return c_handle_error([&] {
-            pyopencl_call_guarded(clSetKernelArg, knl, arg_index, size, buffer);
+            pyopencl_call_guarded(clSetKernelArg, knl, arg_index,
+                                  size_arg(buffer, size));
         });
 }
 
diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h
index ea7ebafd..6f4f2732 100644
--- a/src/c_wrapper/utils.h
+++ b/src/c_wrapper/utils.h
@@ -62,6 +62,12 @@ enum class ArgType {
     Length,
 };
 
+template<typename T, class = void>
+struct type_size : std::integral_constant<size_t, sizeof(T)> {};
+template<typename T>
+struct type_size<T, enable_if_t<std::is_same<rm_const_t<T>, void>::value> > :
+        std::integral_constant<size_t, 1> {};
+
 template<typename T>
 static PYOPENCL_INLINE void
 _print_buf_content(std::ostream &stm, const T *p, size_t len)
@@ -87,20 +93,43 @@ _print_buf_content<char>(std::ostream &stm, const char *p, size_t len)
     dbg_print_str(stm, p, len);
 }
 
+template<>
+PYOPENCL_INLINE void
+_print_buf_content<unsigned char>(std::ostream &stm,
+                                  const unsigned char *p, size_t len)
+{
+    dbg_print_bytes(stm, p, len);
+}
+
+template<>
+PYOPENCL_INLINE void
+_print_buf_content<void>(std::ostream &stm, const void *p, size_t len)
+{
+    dbg_print_bytes(stm, static_cast<const unsigned char*>(p), len);
+}
+
 template<typename T>
 void
 print_buf(std::ostream &stm, const T *p, size_t len,
           ArgType arg_type, bool content, bool out)
 {
-    const size_t ele_size = sizeof(T);
+    const size_t ele_size = type_size<T>::value;
     if (out) {
         stm << "*(" << (const void*)p << "): ";
-        _print_buf_content(stm, p, len);
+        if (p) {
+            _print_buf_content(stm, p, len);
+        } else {
+            stm << "NULL";
+        }
     } else {
         bool need_quote = content || arg_type != ArgType::None;
         if (content) {
-            _print_buf_content(stm, p, len);
-            stm << " ";
+            if (p) {
+                _print_buf_content(stm, p, len);
+                stm << " ";
+            } else {
+                stm << "NULL ";
+            }
         }
         if (need_quote) {
             stm << "<";
@@ -231,7 +260,8 @@ public:
     {
         return const_cast<rm_const_t<T>*>(m_buf);
     }
-    PYOPENCL_INLINE T&
+    template<typename T2 = T>
+    PYOPENCL_INLINE T2&
     operator[](int i) const
     {
         return m_buf[i];
@@ -300,11 +330,11 @@ struct _ArgBufferConverter<Buff,
                            enable_if_t<Buff::arg_type == ArgType::SizeOf> > {
     static PYOPENCL_INLINE auto
     convert(Buff &buff)
-        -> decltype(std::make_tuple(sizeof(typename Buff::type) * buff.len(),
-                                    buff.get()))
+        -> decltype(std::make_tuple(type_size<typename Buff::type>::value *
+                                    buff.len(), buff.get()))
     {
-        return std::make_tuple(sizeof(typename Buff::type) * buff.len(),
-                               buff.get());
+        return std::make_tuple(type_size<typename Buff::type>::value *
+                               buff.len(), buff.get());
     }
 };
 
@@ -357,7 +387,7 @@ public:
         : ArgBuffer<const T, AT>(buf, n)
     {
         if (l < n) {
-            memcpy(m_intern_buf, buf, sizeof(T) * l);
+            memcpy(m_intern_buf, buf, type_size<T>::value * l);
             if (content) {
                 for (size_t i = l;i < n;i++) {
                     m_intern_buf[i] = content;
-- 
GitLab