From 219e395ece9b603bbc6d2b40f754a58c2306c525 Mon Sep 17 00:00:00 2001
From: Marko Bencun <mbencun@gmail.com>
Date: Sat, 31 Aug 2013 12:27:10 +0200
Subject: [PATCH] some refactorings

---
 pyopencl/__init__.py             | 406 +++++++++++++++----------------
 pyopencl/cffi_cl.py              |  31 +--
 src/c_wrapper/wrap_cl.cpp        | 295 ++--------------------
 src/c_wrapper/wrap_cl_core.h     |  16 +-
 src/c_wrapper/wrap_constants.cpp |   5 +
 5 files changed, 240 insertions(+), 513 deletions(-)

diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py
index 628443b9..19e9f62b 100644
--- a/pyopencl/__init__.py
+++ b/pyopencl/__init__.py
@@ -38,8 +38,10 @@ except ImportError:
 # _ccl = _cl
 # import cffi_cl
 # _cl = cffi_cl
-    
-import numpy as np
+try:
+    import numpypy as np
+except:
+    import numpy as np
 #from pyopencl._cl import *  # noqa
 from pyopencl.cffi_cl import *
 import inspect as _inspect
@@ -240,10 +242,6 @@ def link_program(context, programs, options=[], devices=None):
 
 def _add_functionality():
     cls_to_info_cls = {
-            # PlatformZ:
-            #     (PlatformZ.get_info, platform_info),
-            # DeviceZ:
-            #     (DeviceZ.get_info, device_info),
             Platform:
                 (Platform.get_info, platform_info),
             Device:
@@ -256,14 +254,14 @@ def _add_functionality():
                 (Event.get_info, event_info),
             MemoryObjectHolder:
                 (MemoryObjectHolder.get_info, mem_info),
-            Image:
-                (Image.get_image_info, image_info),
+            # Image:
+            #     (Image.get_image_info, image_info),
             Program:
                 (Program.get_info, program_info),
             Kernel:
                 (Kernel.get_info, kernel_info),
-            Sampler:
-                (Sampler.get_info, sampler_info),
+            # Sampler:
+            #     (Sampler.get_info, sampler_info),
             }
 
     def to_string(cls, value, default_format=None):
@@ -540,187 +538,187 @@ def _add_functionality():
 
     # }}}
 
-    # {{{ ImageFormat
-
-    def image_format_repr(self):
-        return "ImageFormat(%s, %s)" % (
-                channel_order.to_string(self.channel_order,
-                    "<unknown channel order 0x%x>"),
-                channel_type.to_string(self.channel_data_type,
-                    "<unknown channel data type 0x%x>"))
-
-    def image_format_eq(self, other):
-        return (self.channel_order == other.channel_order
-                and self.channel_data_type == other.channel_data_type)
-
-    def image_format_ne(self, other):
-        return not image_format_eq(self, other)
-
-    def image_format_hash(self):
-        return hash((type(self), self.channel_order, self.channel_data_type))
-
-    ImageFormat.__repr__ = image_format_repr
-    ImageFormat.__eq__ = image_format_eq
-    ImageFormat.__ne__ = image_format_ne
-    ImageFormat.__hash__ = image_format_hash
-
-    # }}}
-
-    # {{{ Image
-
-    image_old_init = Image.__init__
-
-    def image_init(self, context, flags, format, shape=None, pitches=None,
-            hostbuf=None, is_array=False, buffer=None):
-
-        if shape is None and hostbuf is None:
-            raise Error("'shape' must be passed if 'hostbuf' is not given")
-
-        if shape is None and hostbuf is not None:
-            shape = hostbuf.shape
-
-        if hostbuf is not None and not \
-                (flags & (mem_flags.USE_HOST_PTR | mem_flags.COPY_HOST_PTR)):
-            from warnings import warn
-            warn("'hostbuf' was passed, but no memory flags to make use of it.")
-
-        if hostbuf is None and pitches is not None:
-            raise Error("'pitches' may only be given if 'hostbuf' is given")
-
-        if context._get_cl_version() >= (1, 2) and get_cl_header_version() >= (1, 2):
-            if buffer is not None and is_array:
-                    raise ValueError(
-                            "'buffer' and 'is_array' are mutually exclusive")
-
-            if len(shape) == 3:
-                if buffer is not None:
-                    raise TypeError(
-                            "'buffer' argument is not supported for 3D arrays")
-                elif is_array:
-                    image_type = mem_object_type.IMAGE2D_ARRAY
-                else:
-                    image_type = mem_object_type.IMAGE3D
-
-            elif len(shape) == 2:
-                if buffer is not None:
-                    raise TypeError(
-                            "'buffer' argument is not supported for 2D arrays")
-                elif is_array:
-                    image_type = mem_object_type.IMAGE1D_ARRAY
-                else:
-                    image_type = mem_object_type.IMAGE2D
-
-            elif len(shape) == 1:
-                if buffer is not None:
-                    image_type = mem_object_type.IMAGE1D_BUFFER
-                elif is_array:
-                    raise TypeError("array of zero-dimensional images not supported")
-                else:
-                    image_type = mem_object_type.IMAGE1D
-
-            else:
-                raise ValueError("images cannot have more than three dimensions")
-
-            desc = ImageDescriptor()
-
-            desc.image_type = image_type
-            desc.shape = shape  # also sets desc.array_size
-
-            if pitches is None:
-                desc.pitches = (0, 0)
-            else:
-                desc.pitches = pitches
-
-            desc.num_mip_levels = 0  # per CL 1.2 spec
-            desc.num_samples = 0  # per CL 1.2 spec
-            desc.buffer = buffer
-
-            image_old_init(self, context, flags, format, desc, hostbuf)
-        else:
-            # legacy init for CL 1.1 and older
-            if is_array:
-                raise TypeError("'is_array=True' is not supported for CL < 1.2")
-            #if num_mip_levels is not None:
-                #raise TypeError(
-                #      "'num_mip_levels' argument is not supported for CL < 1.2")
-            #if num_samples is not None:
-                #raise TypeError(
-                #       "'num_samples' argument is not supported for CL < 1.2")
-            if buffer is not None:
-                raise TypeError("'buffer' argument is not supported for CL < 1.2")
-
-            image_old_init(self, context, flags, format, shape,
-                    pitches, hostbuf)
-
-    class _ImageInfoGetter:
-        def __init__(self, event):
-            from warnings import warn
-            warn("Image.image.attr is deprecated. "
-                    "Use Image.attr directly, instead.")
-
-            self.event = event
-
-        def __getattr__(self, name):
-            try:
-                inf_attr = getattr(_cl.image_info, name.upper())
-            except AttributeError:
-                raise AttributeError("%s has no attribute '%s'"
-                        % (type(self), name))
-            else:
-                return self.event.get_image_info(inf_attr)
-
-    def image_shape(self):
-        if self.type == mem_object_type.IMAGE2D:
-            return (self.width, self.height)
-        elif self.type == mem_object_type.IMAGE3D:
-            return (self.width, self.height, self.depth)
-        else:
-            raise LogicError("only images have shapes")
-
-    Image.__init__ = image_init
-    Image.image = property(_ImageInfoGetter)
-    Image.shape = property(image_shape)
-
-    # }}}
-
-    # {{{ Error
-
-    def error_str(self):
-        val = self.args[0]
-        try:
-            val.routine
-        except AttributeError:
-            return str(val)
-        else:
-            result = "%s failed: %s" % (val.routine(),
-                    status_code.to_string(val.code(), "<unknown error %d>")
-                    .lower().replace("_", " "))
-            if val.what():
-                result += " - " + val.what()
-            return result
-
-    def error_code(self):
-        return self.args[0].code()
-
-    def error_routine(self):
-        return self.args[0].routine()
-
-    def error_what(self):
-        return self.args[0].what()
-
-    Error.__str__ = error_str
-    Error.code = property(error_code)
-    Error.routine = property(error_routine)
-    Error.what = property(error_what)
-
-    # }}}
-
-    if _cl.have_gl():
-        def gl_object_get_gl_object(self):
-            return self.get_gl_object_info()[1]
-
-        GLBuffer.gl_object = property(gl_object_get_gl_object)
-        GLTexture.gl_object = property(gl_object_get_gl_object)
+    # # {{{ ImageFormat
+
+    # def image_format_repr(self):
+    #     return "ImageFormat(%s, %s)" % (
+    #             channel_order.to_string(self.channel_order,
+    #                 "<unknown channel order 0x%x>"),
+    #             channel_type.to_string(self.channel_data_type,
+    #                 "<unknown channel data type 0x%x>"))
+
+    # def image_format_eq(self, other):
+    #     return (self.channel_order == other.channel_order
+    #             and self.channel_data_type == other.channel_data_type)
+
+    # def image_format_ne(self, other):
+    #     return not image_format_eq(self, other)
+
+    # def image_format_hash(self):
+    #     return hash((type(self), self.channel_order, self.channel_data_type))
+
+    # ImageFormat.__repr__ = image_format_repr
+    # ImageFormat.__eq__ = image_format_eq
+    # ImageFormat.__ne__ = image_format_ne
+    # ImageFormat.__hash__ = image_format_hash
+
+    # # }}}
+
+    # # {{{ Image
+
+    # image_old_init = Image.__init__
+
+    # def image_init(self, context, flags, format, shape=None, pitches=None,
+    #         hostbuf=None, is_array=False, buffer=None):
+
+    #     if shape is None and hostbuf is None:
+    #         raise Error("'shape' must be passed if 'hostbuf' is not given")
+
+    #     if shape is None and hostbuf is not None:
+    #         shape = hostbuf.shape
+
+    #     if hostbuf is not None and not \
+    #             (flags & (mem_flags.USE_HOST_PTR | mem_flags.COPY_HOST_PTR)):
+    #         from warnings import warn
+    #         warn("'hostbuf' was passed, but no memory flags to make use of it.")
+
+    #     if hostbuf is None and pitches is not None:
+    #         raise Error("'pitches' may only be given if 'hostbuf' is given")
+
+    #     if context._get_cl_version() >= (1, 2) and get_cl_header_version() >= (1, 2):
+    #         if buffer is not None and is_array:
+    #                 raise ValueError(
+    #                         "'buffer' and 'is_array' are mutually exclusive")
+
+    #         if len(shape) == 3:
+    #             if buffer is not None:
+    #                 raise TypeError(
+    #                         "'buffer' argument is not supported for 3D arrays")
+    #             elif is_array:
+    #                 image_type = mem_object_type.IMAGE2D_ARRAY
+    #             else:
+    #                 image_type = mem_object_type.IMAGE3D
+
+    #         elif len(shape) == 2:
+    #             if buffer is not None:
+    #                 raise TypeError(
+    #                         "'buffer' argument is not supported for 2D arrays")
+    #             elif is_array:
+    #                 image_type = mem_object_type.IMAGE1D_ARRAY
+    #             else:
+    #                 image_type = mem_object_type.IMAGE2D
+
+    #         elif len(shape) == 1:
+    #             if buffer is not None:
+    #                 image_type = mem_object_type.IMAGE1D_BUFFER
+    #             elif is_array:
+    #                 raise TypeError("array of zero-dimensional images not supported")
+    #             else:
+    #                 image_type = mem_object_type.IMAGE1D
+
+    #         else:
+    #             raise ValueError("images cannot have more than three dimensions")
+
+    #         desc = ImageDescriptor()
+
+    #         desc.image_type = image_type
+    #         desc.shape = shape  # also sets desc.array_size
+
+    #         if pitches is None:
+    #             desc.pitches = (0, 0)
+    #         else:
+    #             desc.pitches = pitches
+
+    #         desc.num_mip_levels = 0  # per CL 1.2 spec
+    #         desc.num_samples = 0  # per CL 1.2 spec
+    #         desc.buffer = buffer
+
+    #         image_old_init(self, context, flags, format, desc, hostbuf)
+    #     else:
+    #         # legacy init for CL 1.1 and older
+    #         if is_array:
+    #             raise TypeError("'is_array=True' is not supported for CL < 1.2")
+    #         #if num_mip_levels is not None:
+    #             #raise TypeError(
+    #             #      "'num_mip_levels' argument is not supported for CL < 1.2")
+    #         #if num_samples is not None:
+    #             #raise TypeError(
+    #             #       "'num_samples' argument is not supported for CL < 1.2")
+    #         if buffer is not None:
+    #             raise TypeError("'buffer' argument is not supported for CL < 1.2")
+
+    #         image_old_init(self, context, flags, format, shape,
+    #                 pitches, hostbuf)
+
+    # class _ImageInfoGetter:
+    #     def __init__(self, event):
+    #         from warnings import warn
+    #         warn("Image.image.attr is deprecated. "
+    #                 "Use Image.attr directly, instead.")
+
+    #         self.event = event
+
+    #     def __getattr__(self, name):
+    #         try:
+    #             inf_attr = getattr(_cl.image_info, name.upper())
+    #         except AttributeError:
+    #             raise AttributeError("%s has no attribute '%s'"
+    #                     % (type(self), name))
+    #         else:
+    #             return self.event.get_image_info(inf_attr)
+
+    # def image_shape(self):
+    #     if self.type == mem_object_type.IMAGE2D:
+    #         return (self.width, self.height)
+    #     elif self.type == mem_object_type.IMAGE3D:
+    #         return (self.width, self.height, self.depth)
+    #     else:
+    #         raise LogicError("only images have shapes")
+
+    # Image.__init__ = image_init
+    # Image.image = property(_ImageInfoGetter)
+    # Image.shape = property(image_shape)
+
+    # # }}}
+
+    # # {{{ Error
+
+    # def error_str(self):
+    #     val = self.args[0]
+    #     try:
+    #         val.routine
+    #     except AttributeError:
+    #         return str(val)
+    #     else:
+    #         result = "%s failed: %s" % (val.routine(),
+    #                 status_code.to_string(val.code(), "<unknown error %d>")
+    #                 .lower().replace("_", " "))
+    #         if val.what():
+    #             result += " - " + val.what()
+    #         return result
+
+    # def error_code(self):
+    #     return self.args[0].code()
+
+    # def error_routine(self):
+    #     return self.args[0].routine()
+
+    # def error_what(self):
+    #     return self.args[0].what()
+
+    # Error.__str__ = error_str
+    # Error.code = property(error_code)
+    # Error.routine = property(error_routine)
+    # Error.what = property(error_what)
+
+    # # }}}
+
+    # if _cl.have_gl():
+    #     def gl_object_get_gl_object(self):
+    #         return self.get_gl_object_info()[1]
+
+    #     GLBuffer.gl_object = property(gl_object_get_gl_object)
+    #     GLTexture.gl_object = property(gl_object_get_gl_object)
 
 _add_functionality()
 
@@ -881,22 +879,22 @@ def _mark_copy_deprecated(func):
     return new_func
 
 
-enqueue_read_image = _mark_copy_deprecated(_cl._enqueue_read_image)
-enqueue_write_image = _mark_copy_deprecated(_cl._enqueue_write_image)
-enqueue_copy_image = _mark_copy_deprecated(_cl._enqueue_copy_image)
-enqueue_copy_image_to_buffer = _mark_copy_deprecated(
-        _cl._enqueue_copy_image_to_buffer)
-enqueue_copy_buffer_to_image = _mark_copy_deprecated(
-        _cl._enqueue_copy_buffer_to_image)
+# enqueue_read_image = _mark_copy_deprecated(_cl._enqueue_read_image)
+# enqueue_write_image = _mark_copy_deprecated(_cl._enqueue_write_image)
+# enqueue_copy_image = _mark_copy_deprecated(_cl._enqueue_copy_image)
+# enqueue_copy_image_to_buffer = _mark_copy_deprecated(
+#         _cl._enqueue_copy_image_to_buffer)
+# enqueue_copy_buffer_to_image = _mark_copy_deprecated(
+#         _cl._enqueue_copy_buffer_to_image)
 enqueue_read_buffer = _mark_copy_deprecated(_cl._enqueue_read_buffer)
-enqueue_write_buffer = _mark_copy_deprecated(_cl._enqueue_write_buffer)
-enqueue_copy_buffer = _mark_copy_deprecated(_cl._enqueue_copy_buffer)
+# enqueue_write_buffer = _mark_copy_deprecated(_cl._enqueue_write_buffer)
+# enqueue_copy_buffer = _mark_copy_deprecated(_cl._enqueue_copy_buffer)
 
 
-if _cl.get_cl_header_version() >= (1, 1):
-    enqueue_read_buffer_rect = _mark_copy_deprecated(_cl._enqueue_read_buffer_rect)
-    enqueue_write_buffer_rect = _mark_copy_deprecated(_cl._enqueue_write_buffer_rect)
-    enqueue_copy_buffer_rect = _mark_copy_deprecated(_cl._enqueue_copy_buffer_rect)
+# if _cl.get_cl_header_version() >= (1, 1):
+#     enqueue_read_buffer_rect = _mark_copy_deprecated(_cl._enqueue_read_buffer_rect)
+#     enqueue_write_buffer_rect = _mark_copy_deprecated(_cl._enqueue_write_buffer_rect)
+#     enqueue_copy_buffer_rect = _mark_copy_deprecated(_cl._enqueue_copy_buffer_rect)
 
 
 def enqueue_copy(queue, dest, src, **kwargs):
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index b61409f0..753bb3d7 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -1,5 +1,4 @@
-
-from pyopencl._cl import context_info, command_queue_info, Event, event_info, Image, image_info, Kernel, ImageFormat, GLBuffer, kernel_info, sampler_info, Sampler, have_gl, _enqueue_read_image, _enqueue_write_image, GLTexture, channel_type, _enqueue_copy_image, _enqueue_copy_image_to_buffer, _enqueue_copy_buffer_to_image, _enqueue_write_buffer, _enqueue_copy_buffer, _enqueue_read_buffer_rect, _enqueue_write_buffer_rect, _enqueue_copy_buffer_rect, RuntimeError, program_kind, Error, LogicError
+from pyopencl._cl import RuntimeError
 
 import warnings
 
@@ -8,7 +7,6 @@ current_directory = os.path.dirname(__file__)
 
 
 
-
 from cffi import FFI
 _ffi = FFI()
 _cl_header = """
@@ -81,17 +79,6 @@ typedef cl_uint             cl_event_info;
 typedef cl_uint             cl_command_type;
 typedef cl_uint             cl_profiling_info;
 
-/* cl_mem_flags - bitfield */
-#define CL_MEM_READ_WRITE  ...
-#define CL_MEM_WRITE_ONLY  ...
-#define CL_MEM_READ_ONLY  ...
-#define CL_MEM_USE_HOST_PTR  ...
-#define CL_MEM_ALLOC_HOST_PTR  ...
-#define CL_MEM_COPY_HOST_PTR  ...
-#define CL_MEM_HOST_WRITE_ONLY  ...
-#define CL_MEM_HOST_READ_ONLY  ...
-#define CL_MEM_HOST_NO_ACCESS ...
-
 
 """
 
@@ -169,9 +156,9 @@ class Device(EQUALITY_TESTS):
     def get_info(self, param):
         if param == 4145:
             return self.__dict__["platform"] # TODO HACK
-        value = _ffi.new('char **')
-        _lib.device__get_info(self.ptr, param, value)
-        return _ffi.string(value[0])
+        info = _ffi.new('generic_info *')
+        _lib.device__get_info(self.ptr, param, info)
+        return _generic_info_to_python(info)
 
 def _create_device(ptr):
     device = Device()
@@ -241,7 +228,7 @@ class MemoryObject(MemoryObjectHolder):
         
 class Buffer(MemoryObjectHolder):
     def __init__(self, context, flags, size=0, hostbuf=None):
-        if hostbuf is not None and not (flags & (_lib.CL_MEM_USE_HOST_PTR | _lib.CL_MEM_COPY_HOST_PTR)):
+        if hostbuf is not None and not (flags & (mem_flags.USE_HOST_PTR | mem_flags.COPY_HOST_PTR)):
             warnings.warn("'hostbuf' was passed, but no memory flags to make use of it.")
         c_hostbuf = _ffi.NULL
         if hostbuf is not None:
@@ -326,9 +313,9 @@ class Platform(object):
     # todo: __del__
 
     def get_info(self, param):
-        value = _ffi.new('char **')
-        _lib.platform__get_info(self.ptr, param, value)
-        return _ffi.string(value[0])
+        info = _ffi.new('generic_info *')
+        _lib.platform__get_info(self.ptr, param, info)
+        return _generic_info_to_python(info)
     
     def get_devices(self, device_type=device_type.ALL):
         devices = PP(_ffi.new('void**'))
@@ -349,6 +336,8 @@ def _create_platform(ptr):
     return platform
 
 def _generic_info_to_python(info):
+    if info.type == _lib.generic_info_type_chars:
+        return _ffi.string(info.value._chars)
     for type_ in ('cl_uint',
                   'cl_mem_object_type',
                   ):
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index dc17f999..6322f237 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -64,12 +64,14 @@
     PYOPENCL_CALL_GUARDED(clGet##WHAT##Info,				\
 			  (FIRST_ARG, SECOND_ARG, 0, 0, &param_value_size)); \
 									\
-    std::vector<char> param_value(param_value_size);			\
+    MALLOC(char, param_value, param_value_size);			\
     PYOPENCL_CALL_GUARDED(clGet##WHAT##Info,				\
 			  (FIRST_ARG, SECOND_ARG, param_value_size,	\
-			   param_value.empty( ) ? NULL : &param_value.front(), &param_value_size)); \
-									\
-    return param_value.empty( ) ? "" : std::string(&param_value.front(), param_value_size-1); \
+			   param_value, &param_value_size));		\
+    generic_info info;							\
+    info.type = generic_info_type_chars;				\
+    info.value._chars = param_value;					\
+    return info;							\
   }
 
 #define PYOPENCL_GET_INTEGRAL_INFO(WHAT, FIRST_ARG, SECOND_ARG, TYPE)	\
@@ -319,7 +321,7 @@ namespace pyopencl
     // TODO
     // PYOPENCL_EQUALITY_TESTS(platform);
 
-    std::string get_info(cl_platform_info param_name) const
+    generic_info get_info(cl_platform_info param_name) const
     {
       switch (param_name)
 	{
@@ -446,7 +448,7 @@ namespace pyopencl
 
     PYOPENCL_EQUALITY_TESTS(device);
 
-    std::string get_info(cl_device_info param_name) const
+    generic_info get_info(cl_device_info param_name) const
     {
 #define DEV_GET_INT_INF(TYPE) PYOPENCL_GET_INTEGRAL_INFO(Device, m_device, param_name, TYPE);
 
@@ -1307,9 +1309,7 @@ class buffer : public memory_object
   // {{{ program
 
   class program //: boost::noncopyable
-  {
-    public:
-      enum program_kind_type { KND_UNKNOWN, KND_SOURCE, KND_BINARY };
+  {   
 
     private:
       cl_program m_program;
@@ -1902,7 +1902,7 @@ inline event *enqueue_nd_range_kernel(
 
     try
     {
-      return new program(result, false, program::KND_SOURCE);
+      return new program(result, false, KND_SOURCE);
     }
     catch (...)
     {
@@ -1946,7 +1946,7 @@ inline event *enqueue_nd_range_kernel(
 
     try
     {
-      return new program(result, false, program::KND_BINARY);
+      return new program(result, false, KND_BINARY);
     }
     catch (...)
     {
@@ -1981,9 +1981,10 @@ inline event *enqueue_nd_range_kernel(
     free(p);
   }
 
-  void* platform__get_info(void* ptr_platform, cl_platform_info param_name, char** out) {
+  void* platform__get_info(void* ptr_platform, cl_platform_info param, generic_info* out) {
     // todo: catch error
-    *out = _copy_str(static_cast<platform*>(ptr_platform)->get_info(param_name));
+    *out = static_cast<platform*>(ptr_platform)->get_info(param);
+    //*out = _copy_str(static_cast<platform*>(ptr_platform)->get_info(param_name));
     return 0;
   }
 
@@ -2003,9 +2004,9 @@ inline event *enqueue_nd_range_kernel(
     return 0;
   }
 
-  void* device__get_info(void* ptr_device, cl_device_info param_name, char** out) {
+  void* device__get_info(void* ptr_device, cl_device_info param, generic_info* out) {
     // todo: catch error
-    *out = _copy_str(static_cast<device*>(ptr_device)->get_info(param_name));
+    *out = static_cast<device*>(ptr_device)->get_info(param);
     return 0;
   }
 
@@ -2147,270 +2148,6 @@ inline event *enqueue_nd_range_kernel(
     // todo error handling
     return 0;
   }
-
-  void get_constants(constant** out, uint32_t *num_constants, void(*callback)(const char*)) {
-    callback("hallo");
-#define ADD_ATTR(TYPE, PREFIX, NAME)					\
-    constants.push_back((constant){TYPE, #NAME, CL_##PREFIX##NAME});
-    
-    std::vector<constant> constants;
-    
-    // PLATFORM
-    ADD_ATTR("platform_info", PLATFORM_, PROFILE);
-    ADD_ATTR("platform_info", PLATFORM_, VERSION);
-    ADD_ATTR("platform_info", PLATFORM_, NAME);
-    ADD_ATTR("platform_info", PLATFORM_, VENDOR);
-#if !(defined(CL_PLATFORMNVIDIA) && CL_PLATFORMNVIDIA == 0x3001)
-    ADD_ATTR("platform_info", PLATFORM_, EXTENSIONS);
-#endif
-    
-    // DEVICE_TYPE
-    ADD_ATTR("device_type", DEVICE_TYPE_, DEFAULT);
-    ADD_ATTR("device_type", DEVICE_TYPE_, CPU);
-    ADD_ATTR("device_type", DEVICE_TYPE_, GPU);
-    ADD_ATTR("device_type", DEVICE_TYPE_, ACCELERATOR);
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("device_type", DEVICE_TYPE_, CUSTOM);
-#endif
-    ADD_ATTR("device_type", DEVICE_TYPE_, ALL);
-    
-    // DEVICE_INFO
-    ADD_ATTR("device_info", DEVICE_, TYPE);
-    ADD_ATTR("device_info", DEVICE_, VENDOR_ID);
-    ADD_ATTR("device_info", DEVICE_, MAX_COMPUTE_UNITS);
-    ADD_ATTR("device_info", DEVICE_, MAX_WORK_ITEM_DIMENSIONS);
-    ADD_ATTR("device_info", DEVICE_, MAX_WORK_GROUP_SIZE);
-    ADD_ATTR("device_info", DEVICE_, MAX_WORK_ITEM_SIZES);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_CHAR);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_SHORT);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_INT);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_LONG);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_FLOAT);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_DOUBLE);
-    ADD_ATTR("device_info", DEVICE_, MAX_CLOCK_FREQUENCY);
-    ADD_ATTR("device_info", DEVICE_, ADDRESS_BITS);
-    ADD_ATTR("device_info", DEVICE_, MAX_READ_IMAGE_ARGS);
-    ADD_ATTR("device_info", DEVICE_, MAX_WRITE_IMAGE_ARGS);
-    ADD_ATTR("device_info", DEVICE_, MAX_MEM_ALLOC_SIZE);
-    ADD_ATTR("device_info", DEVICE_, IMAGE2D_MAX_WIDTH);
-    ADD_ATTR("device_info", DEVICE_, IMAGE2D_MAX_HEIGHT);
-    ADD_ATTR("device_info", DEVICE_, IMAGE3D_MAX_WIDTH);
-    ADD_ATTR("device_info", DEVICE_, IMAGE3D_MAX_HEIGHT);
-    ADD_ATTR("device_info", DEVICE_, IMAGE3D_MAX_DEPTH);
-    ADD_ATTR("device_info", DEVICE_, IMAGE_SUPPORT);
-    ADD_ATTR("device_info", DEVICE_, MAX_PARAMETER_SIZE);
-    ADD_ATTR("device_info", DEVICE_, MAX_SAMPLERS);
-    ADD_ATTR("device_info", DEVICE_, MEM_BASE_ADDR_ALIGN);
-    ADD_ATTR("device_info", DEVICE_, MIN_DATA_TYPE_ALIGN_SIZE);
-    ADD_ATTR("device_info", DEVICE_, SINGLE_FP_CONFIG);
-#ifdef CL_DEVICEDOUBLE_FP_CONFIG
-    ADD_ATTR("device_info", DEVICE_, DOUBLE_FP_CONFIG);
-#endif
-#ifdef CL_DEVICEHALF_FP_CONFIG
-    ADD_ATTR("device_info", DEVICE_, HALF_FP_CONFIG);
-#endif
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CACHE_TYPE);
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CACHELINE_SIZE);
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CACHE_SIZE);
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_SIZE);
-    ADD_ATTR("device_info", DEVICE_, MAX_CONSTANT_BUFFER_SIZE);
-    ADD_ATTR("device_info", DEVICE_, MAX_CONSTANT_ARGS);
-    ADD_ATTR("device_info", DEVICE_, LOCAL_MEM_TYPE);
-    ADD_ATTR("device_info", DEVICE_, LOCAL_MEM_SIZE);
-    ADD_ATTR("device_info", DEVICE_, ERROR_CORRECTION_SUPPORT);
-    ADD_ATTR("device_info", DEVICE_, PROFILING_TIMER_RESOLUTION);
-    ADD_ATTR("device_info", DEVICE_, ENDIAN_LITTLE);
-    ADD_ATTR("device_info", DEVICE_, AVAILABLE);
-    ADD_ATTR("device_info", DEVICE_, COMPILER_AVAILABLE);
-    ADD_ATTR("device_info", DEVICE_, EXECUTION_CAPABILITIES);
-    ADD_ATTR("device_info", DEVICE_, QUEUE_PROPERTIES);
-    ADD_ATTR("device_info", DEVICE_, NAME);
-    ADD_ATTR("device_info", DEVICE_, VENDOR);
-    ADD_ATTR("device_info", , DRIVER_VERSION);
-    ADD_ATTR("device_info", DEVICE_, VERSION);
-    ADD_ATTR("device_info", DEVICE_, PROFILE);
-    ADD_ATTR("device_info", DEVICE_, VERSION);
-    ADD_ATTR("device_info", DEVICE_, EXTENSIONS);
-    ADD_ATTR("device_info", DEVICE_, PLATFORM);
-#if PYOPENCL_CL_VERSION >= 0x1010
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_VECTOR_WIDTH_HALF);
-    ADD_ATTR("device_info", DEVICE_, HOST_UNIFIED_MEMORY);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_CHAR);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_SHORT);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_INT);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_LONG);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_FLOAT);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_DOUBLE);
-    ADD_ATTR("device_info", DEVICE_, NATIVE_VECTOR_WIDTH_HALF);
-    ADD_ATTR("device_info", DEVICE_, OPENCL_C_VERSION);
-#endif
-    // support for cl_nv_DEVICEattribute_query
-#ifdef CL_DEVICECOMPUTE_CAPABILITY_MAJOR_NV
-    ADD_ATTR("device_info", DEVICE_, COMPUTE_CAPABILITY_MAJOR_NV);
-    ADD_ATTR("device_info", DEVICE_, COMPUTE_CAPABILITY_MINOR_NV);
-    ADD_ATTR("device_info", DEVICE_, REGISTERS_PER_BLOCK_NV);
-    ADD_ATTR("device_info", DEVICE_, WARP_SIZE_NV);
-    ADD_ATTR("device_info", DEVICE_, GPU_OVERLAP_NV);
-    ADD_ATTR("device_info", DEVICE_, KERNEL_EXEC_TIMEOUT_NV);
-    ADD_ATTR("device_info", DEVICE_, INTEGRATED_MEMORY_NV);
-#endif
-    // {{{ cl_amd_DEVICEattribute_query
-#ifdef CL_DEVICEPROFILING_TIMER_OFFSET_AMD
-    ADD_ATTR("device_info", DEVICE_, PROFILING_TIMER_OFFSET_AMD);
-#endif
-#ifdef CL_DEVICETOPOLOGY_AMD
-    ADD_ATTR("device_info", DEVICE_, TOPOLOGY_AMD);
-#endif
-#ifdef CL_DEVICEBOARD_NAME_AMD
-    ADD_ATTR("device_info", DEVICE_, BOARD_NAME_AMD);
-#endif
-#ifdef CL_DEVICEGLOBAL_FREE_MEMORY_AMD
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_FREE_MEMORY_AMD);
-#endif
-#ifdef CL_DEVICESIMD_PER_COMPUTE_UNIT_AMD
-    ADD_ATTR("device_info", DEVICE_, SIMD_PER_COMPUTE_UNIT_AMD);
-#endif
-#ifdef CL_DEVICESIMD_WIDTH_AMD
-    ADD_ATTR("device_info", DEVICE_, SIMD_WIDTH_AMD);
-#endif
-#ifdef CL_DEVICESIMD_INSTRUCTION_WIDTH_AMD
-    ADD_ATTR("device_info", DEVICE_, SIMD_INSTRUCTION_WIDTH_AMD);
-#endif
-#ifdef CL_DEVICEWAVEFRONT_WIDTH_AMD
-    ADD_ATTR("device_info", DEVICE_, WAVEFRONT_WIDTH_AMD);
-#endif
-#ifdef CL_DEVICEGLOBAL_MEM_CHANNELS_AMD
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CHANNELS_AMD);
-#endif
-#ifdef CL_DEVICEGLOBAL_MEM_CHANNEL_BANKS_AMD
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CHANNEL_BANKS_AMD);
-#endif
-#ifdef CL_DEVICEGLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
-    ADD_ATTR("device_info", DEVICE_, GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD);
-#endif
-#ifdef CL_DEVICELOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
-    ADD_ATTR("device_info", DEVICE_, LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD);
-#endif
-#ifdef CL_DEVICELOCAL_MEM_BANKS_AMD
-    ADD_ATTR("device_info", DEVICE_, LOCAL_MEM_BANKS_AMD);
-#endif
-    // }}}
-#ifdef CL_DEVICEMAX_ATOMIC_COUNTERS_EXT
-    ADD_ATTR("device_info", DEVICE_, MAX_ATOMIC_COUNTERS_EXT);
-#endif
-#if defined(cl_ext_DEVICEfission) && defined(PYOPENCL_USE_DEVICEFISSION)
-    ADD_ATTR("device_info", DEVICE_, PARENT_DEVICEEXT);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_TYPES_EXT);
-    ADD_ATTR("device_info", DEVICE_, AFFINITY_DOMAINS_EXT);
-    ADD_ATTR("device_info", DEVICE_, REFERENCE_COUNT_EXT);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_STYLE_EXT);
-#endif
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("device_info", DEVICE_, LINKER_AVAILABLE);
-    ADD_ATTR("device_info", DEVICE_, BUILT_IN_KERNELS);
-    ADD_ATTR("device_info", DEVICE_, IMAGE_MAX_BUFFER_SIZE);
-    ADD_ATTR("device_info", DEVICE_, IMAGE_MAX_ARRAY_SIZE);
-    ADD_ATTR("device_info", DEVICE_, PARENT_DEVICE);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_MAX_SUB_DEVICES);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_PROPERTIES);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_AFFINITY_DOMAIN);
-    ADD_ATTR("device_info", DEVICE_, PARTITION_TYPE);
-    ADD_ATTR("device_info", DEVICE_, REFERENCE_COUNT);
-    ADD_ATTR("device_info", DEVICE_, PREFERRED_INTEROP_USER_SYNC);
-    ADD_ATTR("device_info", DEVICE_, PRINTF_BUFFER_SIZE);
-#endif
-#ifdef cl_khr_image2d_from_buffer
-    ADD_ATTR("device_info", DEVICE_, IMAGE_PITCH_ALIGNMENT);
-    ADD_ATTR("device_info", DEVICE_, IMAGE_BASE_ADDRESS_ALIGNMENT);
-#endif
-
-    // mem_flags
-    ADD_ATTR("mem_flags", MEM_, READ_WRITE);
-    ADD_ATTR("mem_flags", MEM_, WRITE_ONLY);
-    ADD_ATTR("mem_flags", MEM_, READ_ONLY);
-    ADD_ATTR("mem_flags", MEM_, USE_HOST_PTR);
-    ADD_ATTR("mem_flags", MEM_, ALLOC_HOST_PTR);
-    ADD_ATTR("mem_flags", MEM_, COPY_HOST_PTR);
-#ifdef cl_amd_device_memory_flags
-    ADD_ATTR("mem_flags", MEM_, USE_PERSISTENT_MEM_AMD);
-#endif
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("mem_flags", MEM_, HOST_WRITE_ONLY);
-    ADD_ATTR("mem_flags", MEM_, HOST_READ_ONLY);
-    ADD_ATTR("mem_flags", MEM_, HOST_NO_ACCESS);
-#endif
-
-    // mem_info
-    ADD_ATTR("mem_info", MEM_, TYPE);
-    ADD_ATTR("mem_info", MEM_, FLAGS);
-    ADD_ATTR("mem_info", MEM_, SIZE);
-    ADD_ATTR("mem_info", MEM_, HOST_PTR);
-    ADD_ATTR("mem_info", MEM_, MAP_COUNT);
-    ADD_ATTR("mem_info", MEM_, REFERENCE_COUNT);
-    ADD_ATTR("mem_info", MEM_, CONTEXT);
-#if PYOPENCL_CL_VERSION >= 0x1010
-    ADD_ATTR("mem_info", MEM_, ASSOCIATED_MEMOBJECT);
-    ADD_ATTR("mem_info", MEM_, OFFSET);
-#endif
-
-    // mem_object_type
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, BUFFER);
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE2D);
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE3D);
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE2D_ARRAY);
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE1D);
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE1D_ARRAY);
-    ADD_ATTR("mem_object_type", MEM_OBJECT_, IMAGE1D_BUFFER);
-#endif
-
-    // program_info
-    ADD_ATTR("program_info", PROGRAM_, REFERENCE_COUNT);
-    ADD_ATTR("program_info", PROGRAM_, CONTEXT);
-    ADD_ATTR("program_info", PROGRAM_, NUM_DEVICES);
-    ADD_ATTR("program_info", PROGRAM_, DEVICES);
-    ADD_ATTR("program_info", PROGRAM_, SOURCE);
-    ADD_ATTR("program_info", PROGRAM_, BINARY_SIZES);
-    ADD_ATTR("program_info", PROGRAM_, BINARIES);
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("program_info", PROGRAM_, NUM_KERNELS);
-    ADD_ATTR("program_info", PROGRAM_, KERNEL_NAMES);
-#endif
-
-    // program_build_info
-    ADD_ATTR("program_build_info", PROGRAM_BUILD_, STATUS);
-    ADD_ATTR("program_build_info", PROGRAM_BUILD_, OPTIONS);
-    ADD_ATTR("program_build_info", PROGRAM_BUILD_, LOG);
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("program_build_info", PROGRAM_, BINARY_TYPE);
-#endif
-    
-    // program_binary_type    
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("program_binary_type", PROGRAM_BINARY_TYPE_, NONE);
-    ADD_ATTR("program_binary_type", PROGRAM_BINARY_TYPE_, COMPILED_OBJECT);
-    ADD_ATTR("program_binary_type", PROGRAM_BINARY_TYPE_, LIBRARY);
-    ADD_ATTR("program_binary_type", PROGRAM_BINARY_TYPE_, EXECUTABLE);
-#endif
-
-    // kernel_info
-    ADD_ATTR("kernel_info", KERNEL_, FUNCTION_NAME);
-    ADD_ATTR("kernel_info", KERNEL_, NUM_ARGS);
-    ADD_ATTR("kernel_info", KERNEL_, REFERENCE_COUNT);
-    ADD_ATTR("kernel_info", KERNEL_, CONTEXT);
-    ADD_ATTR("kernel_info", KERNEL_, PROGRAM);
-#if PYOPENCL_CL_VERSION >= 0x1020
-    ADD_ATTR("kernel_info", KERNEL_, ATTRIBUTES);
-#endif
-    
-    MALLOC(constant, c, constants.size());
-    for(std::vector<constant>::size_type i = 0; i < constants.size(); ++i) {
-      c[i] = constants[i];
-    }
-    *out = c;
-    *num_constants = constants.size();
-  }
-
   
 }
 
diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h
index 9ee058cb..b0f8d7fa 100644
--- a/src/c_wrapper/wrap_cl_core.h
+++ b/src/c_wrapper/wrap_cl_core.h
@@ -1,26 +1,25 @@
+typedef enum { KND_UNKNOWN, KND_SOURCE, KND_BINARY } program_kind_type;
+
 typedef enum {
   generic_info_type_cl_uint,
   generic_info_type_cl_mem_object_type,
+  generic_info_type_chars,
 } generic_info_type_t;
+
 typedef struct {
   generic_info_type_t type;
   union value_t {
     cl_uint _cl_uint;
     cl_mem_object_type _cl_mem_object_type;
+    char* _chars;
   } value;
 } generic_info;
 
-typedef struct {
-  const char* type;
-  const char* name;
-  unsigned int value;
-} constant;
-
 int get_cl_version(void);
 void* get_platforms(void** ptr_platforms, uint32_t* num_platforms);
-void* platform__get_info(void* ptr_platform, cl_platform_info param_name, char** out);
+void* platform__get_info(void* ptr_platform, cl_platform_info param_name, generic_info* out);
 void* platform__get_devices(void* ptr_platform, void** ptr_devices, uint32_t* num_devices, cl_device_type devtype);
-void* device__get_info(void* ptr_device, cl_device_info param_name, char** out);
+void* device__get_info(void* ptr_device, cl_device_info param_name, generic_info* out);
 long device__hash(void *ptr_device);
 void* _create_context(void** ptr_ctx, cl_context_properties* properties, cl_uint num_devices, void** ptr_devices);
 void* _create_command_queue(void** ptr_command_queue, void* ptr_context, void* ptr_device, cl_command_queue_properties properties);
@@ -37,7 +36,6 @@ void* kernel__set_arg_mem_buffer(void* ptr_kernel, cl_uint arg_index, void* ptr_
 void* _enqueue_nd_range_kernel(void **ptr_event, void* ptr_command_queue, void* ptr_kernel, cl_uint work_dim, const size_t* global_work_offset, const size_t* global_work_size, const size_t* local_work_size);
 void* _enqueue_read_buffer(void **ptr_event, void* ptr_command_queue, void* ptr_memory_object_holder, void* buffer, size_t size, size_t device_offset, int is_blocking);
 void* memory_object_holder__get_info(void* ptr_memory_object_holder, cl_mem_info param, generic_info* out);
-void get_constants(constant** out, uint32_t *num_constants, void(*)(const char*));
 void populate_constants(void(*add)(const char*, const char*, unsigned int value));
 void freem(void*);
 
diff --git a/src/c_wrapper/wrap_constants.cpp b/src/c_wrapper/wrap_constants.cpp
index c4f0e1f7..a994a7c5 100644
--- a/src/c_wrapper/wrap_constants.cpp
+++ b/src/c_wrapper/wrap_constants.cpp
@@ -5,6 +5,11 @@ namespace pyopencl {
   void populate_constants(void(*add)(const char*, const char*, unsigned int value)) {
 #define ADD_ATTR(TYPE, PREFIX, NAME)		\
     add(TYPE, #NAME, CL_##PREFIX##NAME)
+
+    // program_kind
+    add("program_kind", "UNKNOWN", KND_UNKNOWN);
+    add("program_kind", "SOURCE", KND_SOURCE);
+    add("program_kind", "BINARY", KND_BINARY);
     
     // status_code
     ADD_ATTR("status_code", , SUCCESS);
-- 
GitLab