From a915241965c3c3c6a338a67c5551d0480907c5bf Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sat, 24 May 2014 12:23:56 -0400 Subject: [PATCH] python object reference interface with c --- pyopencl/_cffi.py | 6 +++-- pyopencl/c_wrapper/wrap_cl_core.h | 1 + pyopencl/cffi_cl.py | 10 ++++---- setup.py | 1 + src/c_wrapper/pyhelper.cpp | 40 +++++++++++++++++++++++++++++++ src/c_wrapper/utils.h | 3 +++ src/c_wrapper/wrap_cl.cpp | 14 ----------- 7 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 src/c_wrapper/pyhelper.cpp diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py index c5e32568..eeeb7d84 100644 --- a/pyopencl/_cffi.py +++ b/pyopencl/_cffi.py @@ -168,7 +168,7 @@ _gc_collect = _ffi.callback('int(void)')(gc.collect) _lib.set_gc(_gc_collect) _pyrefs = {} -@_ffi.callback('void(int)') +@_ffi.callback('void(unsigned long)') def _py_deref(_id): try: del _pyrefs[_id] @@ -176,10 +176,12 @@ def _py_deref(_id): pass def _get_insert_func(obj): - @_ffi.callback('void(int)') + @_ffi.callback('void(unsigned long)') def _insert(_id): _pyref[_id] = obj return _insert def _find_obj(_id): return _pyref[_id] + +_lib.set_deref(_py_deref) diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h index 26b78dd7..af3088ba 100644 --- a/pyopencl/c_wrapper/wrap_cl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_core.h @@ -43,6 +43,7 @@ int get_cl_version(); void free_pointer(void*); void free_pointer_array(void**, uint32_t size); void set_gc(int (*func)()); +void set_deref(void (*func)(unsigned long)); int have_gl(); unsigned bitlog2(unsigned long v); diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index f8fe9c9b..9c286254 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -51,7 +51,7 @@ else: _bytes = str -def _convert_str(s): +def _to_cstring(s): if isinstance(s, _unicode): return s.encode() return s @@ -72,7 +72,7 @@ except AttributeError: class _CArray(object): def __init__(self, ptr): self.ptr = ptr - self.size = _ffi.new('uint32_t *') + self.size = _ffi.new('uint32_t*') def __del__(self): if self.ptr != _ffi.NULL: @@ -591,7 +591,7 @@ class _Program(_Common): def _init_source(self, context, src): ptr_program = _ffi.new('void **') _handle_error(_lib.create_program_with_source( - ptr_program, context.ptr, _convert_str(src))) + ptr_program, context.ptr, _to_cstring(src))) self.ptr = ptr_program[0] def _init_binary(self, context, devices, binaries): @@ -630,7 +630,7 @@ class _Program(_Common): _handle_error( _lib.program__build(self.ptr, - _convert_str(options), num_devices, + _to_cstring(options), num_devices, _ffi.cast('void**', ptr_devices))) def get_build_info(self, device, param): @@ -654,7 +654,7 @@ class Kernel(_Common): def __init__(self, program, name): ptr_kernel = _ffi.new('void **') _handle_error(_lib.create_kernel(ptr_kernel, program.ptr, - _convert_str(name))) + _to_cstring(name))) self.ptr = ptr_kernel[0] def set_arg(self, arg_index, arg): diff --git a/setup.py b/setup.py index 29bd7c0e..062681a2 100644 --- a/setup.py +++ b/setup.py @@ -234,6 +234,7 @@ def main(): ["src/c_wrapper/wrap_cl.cpp", "src/c_wrapper/wrap_constants.cpp", "src/c_wrapper/bitlog.cpp", + "src/c_wrapper/pyhelper.cpp", #"src/c_wrapper/wrap_mempool.cpp", ], include_dirs=( diff --git a/src/c_wrapper/pyhelper.cpp b/src/c_wrapper/pyhelper.cpp new file mode 100644 index 00000000..4ea2113e --- /dev/null +++ b/src/c_wrapper/pyhelper.cpp @@ -0,0 +1,40 @@ +#include "utils.h" +#include "error.h" +#include + +namespace pyopencl { + +static std::atomic pyobj_id = ATOMIC_VAR_INIT(0ul); +unsigned long +next_obj_id() +{ + return std::atomic_fetch_add(&pyobj_id, 1ul); +} + +static int +dummy_python_gc() +{ + return 0; +} + +static void +dummy_python_deref(unsigned long) +{ +} + +int (*python_gc)() = dummy_python_gc; +void (*python_deref)(unsigned long) = dummy_python_deref; + +} + +void +set_gc(int (*func)()) +{ + pyopencl::python_gc = func ? func : pyopencl::dummy_python_gc; +} + +void +set_deref(void (*func)(unsigned long)) +{ + pyopencl::python_deref = func ? func : pyopencl::dummy_python_deref; +} diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h index 57bdad79..adc414db 100644 --- a/src/c_wrapper/utils.h +++ b/src/c_wrapper/utils.h @@ -307,6 +307,9 @@ get_int_info(cl_int (*func)(ArgTypes...), const char *name, // }}} +unsigned long next_obj_id(); +extern void (*python_deref)(unsigned long); + } #endif diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index b6dd1bcc..7478675b 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -78,14 +78,6 @@ pyopencl_get_ext_fun(cl_platform_id, const char *name, const char *err) namespace pyopencl { -static int -dummy_python_gc() -{ - return 0; -} - -int (*python_gc)() = dummy_python_gc; - // {{{ platform class platform : public clobj { @@ -1830,12 +1822,6 @@ free_pointer_array(void **p, uint32_t size) } } -void -set_gc(int (*func)()) -{ - python_gc = func ? func : dummy_python_gc; -} - int have_gl() { -- GitLab