diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 1198b1c10531b6f8395fc5bd2736881686628068..c50cf3fb2a8e86d107f28e4f3419dc1c519baf29 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -167,16 +167,25 @@ def _handle_error(error): raise klass(_ffi.string(error.routine), error.code, _ffi.string(error.msg)) # }}} -class EQUALITY_TESTS(object): +class _Common(object): def __eq__(self, other): return hash(self) == hash(other) -class Device(EQUALITY_TESTS): - def __init__(self): - pass - def __hash__(self): - return _lib.device__hash(self.ptr) + return getattr(_lib, '%s__hash' % self._id)(self.ptr) + + @property + def int_ptr(self): + return getattr(_lib, '%s__int_ptr' % self._id)(self.ptr) + + @classmethod + def from_int_ptr(cls, int_ptr_value): + ptr = _ffi.new('void **') + getattr(_lib, '%s__from_int_ptr' % cls._id)(ptr, int_ptr_value) + return _create_instance(cls, ptr[0]) + +class Device(_Common): + _id = 'device' # todo: __del__ @@ -187,11 +196,6 @@ class Device(EQUALITY_TESTS): _handle_error(_lib.device__get_info(self.ptr, param, info)) return _generic_info_to_python(info) -def _create_device(ptr): - device = Device() - device.ptr = ptr - return device - def _parse_context_properties(properties): props = [] if properties is None: @@ -211,7 +215,9 @@ def _parse_context_properties(properties): return _ffi.new('cl_context_properties[]', props) -class Context(EQUALITY_TESTS): +class Context(_Common): + _id = 'context' + def __init__(self, devices=None, properties=None, dev_type=None): c_props = _parse_context_properties(properties) status_code = _ffi.new('cl_int *') @@ -228,14 +234,12 @@ class Context(EQUALITY_TESTS): raise NotImplementedError() self.ptr = ptr_ctx[0] - - def __hash__(self): - return _lib.context__hash(self.ptr) def get_info(self, param): return 'TODO' -class CommandQueue(EQUALITY_TESTS): +class CommandQueue(_Common): + _id = 'command_queue' def __init__(self, context, device=None, properties=None): if properties is None: properties = 0 @@ -243,14 +247,11 @@ class CommandQueue(EQUALITY_TESTS): _handle_error(_lib._create_command_queue(ptr_command_queue, context.ptr, _ffi.NULL if device is None else device.ptr, properties)) self.ptr = ptr_command_queue[0] - def __hash__(self): - return _lib.command_queue__hash(self.ptr) - def get_info(self, param): print param raise NotImplementedError() -class MemoryObjectHolder(EQUALITY_TESTS): +class MemoryObjectHolder(_Common): def get_info(self, param): info = _ffi.new('generic_info *') _handle_error(_lib.memory_object_holder__get_info(self.ptr, param, info)) @@ -263,6 +264,8 @@ class MemoryObject(MemoryObjectHolder): pass class Buffer(MemoryObjectHolder): + _id = 'buffer' + @classmethod def _c_buffer_from_obj(cls, obj): # assume numpy array for now @@ -285,22 +288,14 @@ class Buffer(MemoryObjectHolder): _handle_error(_lib._create_buffer(ptr_buffer, context.ptr, flags, size, c_hostbuf)) self.ptr = ptr_buffer[0] -class _Program(object): +class _Program(_Common): + _id = 'program' def __init__(self, *args): if len(args) == 2: self._init_source(*args) else: self._init_binary(*args) - def __hash__(self): - return _lib.program__hash(self.ptr) - - def int_ptr(self): - raise NotImplementedError() - - def from_int_ptr(self, int_ptr_value): - raise NotImplementedError() - def _init_source(self, context, src): ptr_program = _ffi.new('void **') _handle_error(_lib._create_program_with_source(ptr_program, context.ptr, _ffi.new('char[]', src))) @@ -348,7 +343,7 @@ class _Program(object): for i in xrange(devices.size[0]): # TODO why is the cast needed? device_ptr = _ffi.cast('void**', devices.ptr[0])[i] - result.append(_create_device(device_ptr)) + result.append(_create_instance(Device, device_ptr)) return result elif param == program_info.BINARIES: ptr_binaries = _CArrays(_ffi.new('char***')) @@ -361,13 +356,8 @@ class _Program(object): return _generic_info_to_python(info) -class Platform(EQUALITY_TESTS): - def __init__(self): - pass - - def __hash__(self): - return _lib.platform__hash(self.ptr) - +class Platform(_Common): + _id = 'platform' # todo: __del__ def get_info(self, param): @@ -382,17 +372,13 @@ class Platform(EQUALITY_TESTS): for i in xrange(devices.size[0]): # TODO why is the cast needed? device_ptr = _ffi.cast('void**', devices.ptr[0])[i] - result.append(_create_device(device_ptr)) + result.append(_create_instance(Device, device_ptr)) # TODO remove, should be done via get_info(PLATFORM) for r in result: r.__dict__["platform"] = self return result -def _create_platform(ptr): - platform = Platform() - platform.ptr = ptr - return platform - + def _generic_info_to_python(info): if info.type == _lib.generic_info_type_chars: return _ffi.string(info.value._chars) @@ -411,13 +397,12 @@ def _generic_info_to_python(info): raise NotImplementedError(info.type) class Kernel(object): + _id = 'kernel' + def __init__(self, program, name): ptr_kernel = _ffi.new('void **') _handle_error(_lib._create_kernel(ptr_kernel, program.ptr, name)) self.ptr = ptr_kernel[0] - - def __hash__(self): - return _lib.kernel__hash(self.ptr) def get_info(self, param): info = _ffi.new('generic_info *') @@ -438,25 +423,18 @@ def get_platforms(): for i in xrange(platforms.size[0]): # TODO why is the cast needed? platform_ptr = _ffi.cast('void**', platforms.ptr[0])[i] - result.append(_create_platform(platform_ptr)) + result.append(_create_instance(Platform, platform_ptr)) return result -class Event(EQUALITY_TESTS): +class Event(_Common): + _id = 'event' def __init__(self): pass - def __hash__(self): - return _lib.event__hash(self.ptr) - def get_info(self, param): print param raise NotImplementedError() - -def _create_event(ptr): - event = Event() - event.ptr = ptr - return event def enqueue_nd_range_kernel(queue, kernel, global_work_size, local_work_size, global_work_offset=None, wait_for=None, g_times_l=False): @@ -502,7 +480,7 @@ def enqueue_nd_range_kernel(queue, kernel, global_work_size, local_work_size, gl c_global_work_size, c_local_work_size )) - return _create_event(ptr_event[0]) + return _create_instance(Event, ptr_event[0]) def _enqueue_read_buffer(cq, mem, buf, device_offset=0, is_blocking=True): # assume numpy @@ -518,4 +496,10 @@ def _enqueue_read_buffer(cq, mem, buf, device_offset=0, is_blocking=True): device_offset, bool(is_blocking) )) - return _create_event(ptr_event[0]) + return _create_instance(Event, ptr_event[0]) + +def _create_instance(cls, ptr): + ins = cls.__new__(cls) + ins.ptr = ptr + return ins + diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index eb0dea0ac3d06ecfade28910d1851c9ce3edfa5a..f0bf5989a9f89978654ed68cc48ecc9423e27056 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -2214,12 +2214,71 @@ inline event *enqueue_nd_range_kernel( return 0; } - ::error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out) { - C_HANDLE_ERROR( - *out = static_cast<memory_object_holder*>(ptr_memory_object_holder)->get_info(param); - ) +::error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out) { + C_HANDLE_ERROR( + *out = static_cast<memory_object_holder*>(ptr_memory_object_holder)->get_info(param); + ) return 0; } + + +intptr_t platform__int_ptr(void* ptr) { + return (intptr_t)(static_cast<platform*>(ptr)->data()); +} +intptr_t kernel__int_ptr(void* ptr) { + return (intptr_t)(static_cast<kernel*>(ptr)->data()); +} +intptr_t context__int_ptr(void* ptr) { + return (intptr_t)(static_cast<context*>(ptr)->data()); +} +intptr_t command_queue__int_ptr(void* ptr) { + return (intptr_t)(static_cast<command_queue*>(ptr)->data()); +} +intptr_t buffer__int_ptr(void* ptr) { + return (intptr_t)(static_cast<buffer*>(ptr)->data()); +} +intptr_t program__int_ptr(void* ptr) { + return (intptr_t)(static_cast<program*>(ptr)->data()); +} +intptr_t event__int_ptr(void* ptr) { + return (intptr_t)(static_cast<event*>(ptr)->data()); +} + +void *platform__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new platform((cl_platform_id)int_ptr_value, /* retain */ true);) + return 0; +} + +void *kernel__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new kernel((cl_kernel)int_ptr_value, /* retain */ true);) + return 0; +} + +void *context__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new context((cl_context)int_ptr_value, /* retain */ true);) + return 0; +} + +void *command_queue__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new command_queue((cl_command_queue)int_ptr_value, /* retain */ true);) + return 0; +} + +void *buffer__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new buffer((cl_mem)int_ptr_value, /* retain */ true);) + return 0; +} + +void *program__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new program((cl_program)int_ptr_value, /* retain */ true);) + return 0; +} + +void *event__from_int_ptr(void **ptr_out, intptr_t int_ptr_value) { + C_HANDLE_ERROR(*ptr_out = new event((cl_event)int_ptr_value, /* retain */ true);) + return 0; +} + } diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h index fd68f5ea70e55a3e66beb0646e8bdcfe39591c8d..dad61b49716f58ceef1f92871171873b98b70048 100644 --- a/src/c_wrapper/wrap_cl_core.h +++ b/src/c_wrapper/wrap_cl_core.h @@ -62,6 +62,23 @@ error *_enqueue_read_buffer(void **ptr_event, void *ptr_command_queue, void *ptr error *memory_object_holder__get_info(void *ptr_memory_object_holder, cl_mem_info param, generic_info *out); long memory_object_holder__hash(void *ptr_memory_object_holder); void populate_constants(void(*add)(const char*, const char*, long value)); + +intptr_t platform__int_ptr(void*); +intptr_t kernel__int_ptr(void*); +intptr_t context__int_ptr(void*); +intptr_t command_queue__int_ptr(void*); +intptr_t buffer__int_ptr(void*); +intptr_t program__int_ptr(void*); +intptr_t event__int_ptr(void*); + +void *platform__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *kernel__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *context__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *command_queue__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *buffer__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *program__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); +void *event__from_int_ptr(void **ptr_out, intptr_t int_ptr_value); + void _free(void*); void _free2(void**, uint32_t size);