From a1a6cfd40bc1c16002ffa9137b8685e8faedcaba Mon Sep 17 00:00:00 2001 From: Marko Bencun <mbencun@gmail.com> Date: Sun, 1 Sep 2013 12:04:11 +0200 Subject: [PATCH] reduced number of c interface functions --- pyopencl/cffi_cl.py | 10 +- src/c_wrapper/wrap_cl.cpp | 1916 +++++++++++++++++----------------- src/c_wrapper/wrap_cl_core.h | 39 +- 3 files changed, 959 insertions(+), 1006 deletions(-) diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index c50cf3fb..48659487 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -172,16 +172,17 @@ class _Common(object): return hash(self) == hash(other) def __hash__(self): - return getattr(_lib, '%s__hash' % self._id)(self.ptr) + return _lib._hash(self.ptr, getattr(_lib, 'CLASS_%s' % self._id.upper())) @property def int_ptr(self): - return getattr(_lib, '%s__int_ptr' % self._id)(self.ptr) + return _lib._int_ptr(self.ptr, getattr(_lib, 'CLASS_%s' % self._id.upper())) @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) + _lib._from_int_ptr(ptr, int_ptr_value, getattr(_lib, 'CLASS_%s' % cls._id.upper())) + #getattr(_lib, '%s__from_int_ptr' % cls._id)(ptr, int_ptr_value) return _create_instance(cls, ptr[0]) class Device(_Common): @@ -257,9 +258,6 @@ class MemoryObjectHolder(_Common): _handle_error(_lib.memory_object_holder__get_info(self.ptr, param, info)) return _generic_info_to_python(info) - def __hash__(self): - return _lib.memory_object_holder__hash(self.ptr) - class MemoryObject(MemoryObjectHolder): pass diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index f0bf5989..ab511fd9 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -52,21 +52,21 @@ // }}} -#define PYOPENCL_GET_VEC_INFO(WHAT, FIRST_ARG, SECOND_ARG, RES_VEC) \ - { \ - size_t size; \ - PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ - (FIRST_ARG, SECOND_ARG, 0, 0, &size)); \ - \ - RES_VEC.resize(size / sizeof(RES_VEC.front())); \ - \ - PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ - (FIRST_ARG, SECOND_ARG, size, \ - RES_VEC.empty( ) ? NULL : &RES_VEC.front(), &size)); \ +#define PYOPENCL_GET_VEC_INFO(WHAT, FIRST_ARG, SECOND_ARG, RES_VEC) \ + { \ + size_t size; \ + PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ + (FIRST_ARG, SECOND_ARG, 0, 0, &size)); \ + \ + RES_VEC.resize(size / sizeof(RES_VEC.front())); \ + \ + PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ + (FIRST_ARG, SECOND_ARG, size, \ + RES_VEC.empty( ) ? NULL : &RES_VEC.front(), &size)); \ } -#define PYOPENCL_WAITLIST_ARGS \ - num_events_in_wait_list, event_wait_list.empty( ) ? NULL : &event_wait_list.front() +#define PYOPENCL_WAITLIST_ARGS \ + num_events_in_wait_list, event_wait_list.empty( ) ? NULL : &event_wait_list.front() #define PYOPENCL_GET_STR_INFO(WHAT, FIRST_ARG, SECOND_ARG) \ @@ -87,14 +87,14 @@ #define PYOPENCL_GET_INTEGRAL_INFO(WHAT, FIRST_ARG, SECOND_ARG, TYPE) \ { \ - TYPE param_value; \ - PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ - (FIRST_ARG, SECOND_ARG, sizeof(param_value), ¶m_value, 0)); \ - generic_info info; \ - info.type = generic_info_type_##TYPE; \ - info.value._##TYPE = param_value; \ - return info; \ -} + TYPE param_value; \ + PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ + (FIRST_ARG, SECOND_ARG, sizeof(param_value), ¶m_value, 0)); \ + generic_info info; \ + info.type = generic_info_type_##TYPE; \ + info.value._##TYPE = param_value; \ + return info; \ + } #define PYOPENCL_GET_ARRAY_INFO(TYPE, VEC) \ { \ @@ -107,7 +107,7 @@ info.value._array.array = ar; \ info.value._array.size = VEC.size(); \ info.array_element_type = #TYPE; \ - return info; \ + return info; \ } #define PYOPENCL_RETURN_NEW_EVENT(evt) \ @@ -123,13 +123,13 @@ // {{{ equality testing -#define PYOPENCL_EQUALITY_TESTS(cls) \ - bool operator==(cls const &other) const \ - { return data() == other.data(); } \ - bool operator!=(cls const &other) const \ - { return data() != other.data(); } \ - long hash() const \ - { return (long) (intptr_t) data(); } +#define PYOPENCL_EQUALITY_TESTS(cls) \ + bool operator==(cls const &other) const \ + { return data() == other.data(); } \ + bool operator!=(cls const &other) const \ + { return data() != other.data(); } \ + long hash() const \ + { return (long) (intptr_t) data(); } // }}} @@ -137,62 +137,98 @@ // {{{ tools #define PYOPENCL_CAST_BOOL(B) ((B) ? CL_TRUE : CL_FALSE) -#define PYOPENCL_PARSE_PY_DEVICES \ - std::vector<cl_device_id> devices_vec; \ - cl_uint num_devices; \ - cl_device_id *devices; \ - \ - if (py_devices.ptr() == Py_None) \ - { \ - num_devices = 0; \ - devices = 0; \ - } \ - else \ - { \ - PYTHON_FOREACH(py_dev, py_devices) \ - devices_vec.push_back( \ - py::extract<device &>(py_dev)().data()); \ - num_devices = devices_vec.size(); \ - devices = devices_vec.empty( ) ? NULL : &devices_vec.front(); \ +#define PYOPENCL_PARSE_PY_DEVICES \ + std::vector<cl_device_id> devices_vec; \ + cl_uint num_devices; \ + cl_device_id *devices; \ + \ + if (py_devices.ptr() == Py_None) \ + { \ + num_devices = 0; \ + devices = 0; \ + } \ + else \ + { \ + PYTHON_FOREACH(py_dev, py_devices) \ + devices_vec.push_back( \ + py::extract<device &>(py_dev)().data()); \ + num_devices = devices_vec.size(); \ + devices = devices_vec.empty( ) ? NULL : &devices_vec.front(); \ + } \ + + + +#define PYOPENCL_RETRY_IF_MEM_ERROR(OPERATION) \ + { \ + bool failed_with_mem_error = false; \ + try \ + { \ + OPERATION \ + } \ + catch (pyopencl::error &e) \ + { \ + failed_with_mem_error = true; \ + if (!e.is_out_of_memory()) \ + throw; \ + } \ + \ + if (failed_with_mem_error) \ + { \ + /* If we get here, we got an error from CL. + * We should run the Python GC to try and free up + * some memory references. */ \ +run_python_gc(); \ +\ +/* Now retry the allocation. If it fails again, + * let it fail. */ \ +{ \ + OPERATION \ } \ +} \ + } +// }}} -#define PYOPENCL_RETRY_IF_MEM_ERROR(OPERATION) \ - { \ - bool failed_with_mem_error = false; \ - try \ - { \ - OPERATION \ - } \ - catch (pyopencl::error &e) \ - { \ - failed_with_mem_error = true; \ - if (!e.is_out_of_memory()) \ - throw; \ - } \ - \ - if (failed_with_mem_error) \ - { \ - /* If we get here, we got an error from CL. - * We should run the Python GC to try and free up - * some memory references. */ \ - run_python_gc(); \ - \ - /* Now retry the allocation. If it fails again, - * let it fail. */ \ - { \ - OPERATION \ - } \ - } \ +#define SWITCHCLASS(OPERATION) \ + switch(class_) { \ + case ::CLASS_PLATFORM: OPERATION(PLATFORM, platform); break; \ + case ::CLASS_DEVICE: OPERATION(DEVICE, device); break; \ + case ::CLASS_KERNEL: OPERATION(KERNEL, kernel); break; \ + case ::CLASS_CONTEXT: OPERATION(CONTEXT, context); break; \ + case ::CLASS_COMMAND_QUEUE: OPERATION(COMMAND_QUEUE, command_queue); break; \ + case ::CLASS_BUFFER: OPERATION(BUFFER, buffer); break; \ + case ::CLASS_PROGRAM: OPERATION(PROGRAM, program); break; \ + case ::CLASS_EVENT: OPERATION(EVENT, event); break; \ + default: throw pyopencl::error("unknown class", CL_INVALID_VALUE); \ } -// }}} + +#define FORALLCLASSES(OPERATION) \ + OPERATION(PLATFORM, platform) \ + OPERATION(DEVICE, device) \ + OPERATION(KERNEL, kernel) \ + OPERATION(CONTEXT, context) \ + OPERATION(COMMAND_QUEUE, command_queue) \ + OPERATION(BUFFER, buffer) \ + OPERATION(PROGRAM, program) \ + OPERATION(EVENT, event) + +#define PYOPENCL_CL_PLATFORM cl_platform_id +#define PYOPENCL_CL_DEVICE cl_device_id +#define PYOPENCL_CL_KERNEL cl_kernel +#define PYOPENCL_CL_CONTEXT cl_context +#define PYOPENCL_CL_COMMAND_QUEUE cl_command_queue +#define PYOPENCL_CL_BUFFER cl_mem +#define PYOPENCL_CL_PROGRAM cl_program +#define PYOPENCL_CL_EVENT cl_event + -int get_cl_version(void) { - return PYOPENCL_CL_VERSION; -} + int get_cl_version(void) { + return PYOPENCL_CL_VERSION; + } + extern "C" namespace pyopencl @@ -238,91 +274,93 @@ namespace pyopencl //#define MAKE_INFO(name, type, value) { } + class _common { + }; // {{{ event/synchronization - class event // : boost::noncopyable + class event : public _common // : boost::noncopyable { - private: - cl_event m_event; + private: + cl_event m_event; - public: - event(cl_event event, bool retain) - : m_event(event) - { - if (retain) - PYOPENCL_CALL_GUARDED(clRetainEvent, (event)); - } + public: + event(cl_event event, bool retain) + : m_event(event) + { + if (retain) + PYOPENCL_CALL_GUARDED(clRetainEvent, (event)); + } - event(event const &src) - : m_event(src.m_event) - { PYOPENCL_CALL_GUARDED(clRetainEvent, (m_event)); } + event(event const &src) + : m_event(src.m_event) + { PYOPENCL_CALL_GUARDED(clRetainEvent, (m_event)); } - virtual ~event() - { - // todo - // PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseEvent, - // (m_event)); - } + virtual ~event() + { + // todo + // PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseEvent, + // (m_event)); + } - const cl_event data() const - { return m_event; } - - PYOPENCL_EQUALITY_TESTS(event); - - // py::object get_info(cl_event_info param_name) const -// { -// switch (param_name) -// { -// case CL_EVENT_COMMAND_QUEUE: -// PYOPENCL_GET_OPAQUE_INFO(Event, m_event, param_name, -// cl_command_queue, command_queue); -// case CL_EVENT_COMMAND_TYPE: -// PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, -// cl_command_type); -// case CL_EVENT_COMMAND_EXECUTION_STATUS: -// PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, -// cl_int); -// case CL_EVENT_REFERENCE_COUNT: -// PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, -// cl_uint); -// #if PYOPENCL_CL_VERSION >= 0x1010 -// case CL_EVENT_CONTEXT: -// PYOPENCL_GET_OPAQUE_INFO(Event, m_event, param_name, -// cl_context, context); -// #endif - -// default: -// throw error("Event.get_info", CL_INVALID_VALUE); -// } -// } - - // py::object get_profiling_info(cl_profiling_info param_name) const - // { - // switch (param_name) - // { - // case CL_PROFILING_COMMAND_QUEUED: - // case CL_PROFILING_COMMAND_SUBMIT: - // case CL_PROFILING_COMMAND_START: - // case CL_PROFILING_COMMAND_END: - // PYOPENCL_GET_INTEGRAL_INFO(EventProfiling, m_event, param_name, - // cl_ulong); - // default: - // throw error("Event.get_profiling_info", CL_INVALID_VALUE); - // } - // } - - virtual void wait() - { - PYOPENCL_CALL_GUARDED_THREADED(clWaitForEvents, (1, &m_event)); - } + const cl_event data() const + { return m_event; } + + PYOPENCL_EQUALITY_TESTS(event); + + // py::object get_info(cl_event_info param_name) const + // { + // switch (param_name) + // { + // case CL_EVENT_COMMAND_QUEUE: + // PYOPENCL_GET_OPAQUE_INFO(Event, m_event, param_name, + // cl_command_queue, command_queue); + // case CL_EVENT_COMMAND_TYPE: + // PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, + // cl_command_type); + // case CL_EVENT_COMMAND_EXECUTION_STATUS: + // PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, + // cl_int); + // case CL_EVENT_REFERENCE_COUNT: + // PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, + // cl_uint); + // #if PYOPENCL_CL_VERSION >= 0x1010 + // case CL_EVENT_CONTEXT: + // PYOPENCL_GET_OPAQUE_INFO(Event, m_event, param_name, + // cl_context, context); + // #endif + + // default: + // throw error("Event.get_info", CL_INVALID_VALUE); + // } + // } + + // py::object get_profiling_info(cl_profiling_info param_name) const + // { + // switch (param_name) + // { + // case CL_PROFILING_COMMAND_QUEUED: + // case CL_PROFILING_COMMAND_SUBMIT: + // case CL_PROFILING_COMMAND_START: + // case CL_PROFILING_COMMAND_END: + // PYOPENCL_GET_INTEGRAL_INFO(EventProfiling, m_event, param_name, + // cl_ulong); + // default: + // throw error("Event.get_profiling_info", CL_INVALID_VALUE); + // } + // } + + virtual void wait() + { + PYOPENCL_CALL_GUARDED_THREADED(clWaitForEvents, (1, &m_event)); + } }; - // }}} + // }}} // {{{ platform - class platform + class platform : public _common { private: cl_platform_id m_platform; @@ -382,7 +420,7 @@ namespace pyopencl // }}} // {{{ device - class device // : boost::noncopyable + class device : public _common // : boost::noncopyable { public: enum reference_type_t { @@ -750,7 +788,7 @@ namespace pyopencl // {{{ context - class context // : public boost::noncopyable + class context : public _common // : public boost::noncopyable { private: cl_context m_context; @@ -864,7 +902,7 @@ namespace pyopencl }; // {{{ command_queue - class command_queue + class command_queue : public _common { private: cl_command_queue m_queue; @@ -983,62 +1021,62 @@ namespace pyopencl //py::object create_mem_object_wrapper(cl_mem mem); - class memory_object_holder + class memory_object_holder : public _common { - public: - virtual const cl_mem data() const = 0; + public: + virtual const cl_mem data() const = 0; PYOPENCL_EQUALITY_TESTS(memory_object_holder); - size_t size() const - { - size_t param_value; - PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, - (data(), CL_MEM_SIZE, sizeof(param_value), ¶m_value, 0)); - return param_value; - } + size_t size() const + { + size_t param_value; + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + (data(), CL_MEM_SIZE, sizeof(param_value), ¶m_value, 0)); + return param_value; + } generic_info get_info(cl_mem_info param_name) { switch (param_name){ case CL_MEM_TYPE: PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, cl_mem_object_type); -// case CL_MEM_FLAGS: -// PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, -// cl_mem_flags); -// case CL_MEM_SIZE: -// PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, -// size_t); -// case CL_MEM_HOST_PTR: -// throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE, -// "Use MemoryObject.get_host_array to get host pointer."); -// case CL_MEM_MAP_COUNT: -// PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, -// cl_uint); -// case CL_MEM_REFERENCE_COUNT: -// PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, -// cl_uint); -// case CL_MEM_CONTEXT: -// PYOPENCL_GET_OPAQUE_INFO(MemObject, data(), param_name, -// cl_context, context); - -// #if PYOPENCL_CL_VERSION >= 0x1010 -// case CL_MEM_ASSOCIATED_MEMOBJECT: -// { -// cl_mem param_value; -// PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, (data(), param_name, sizeof(param_value), ¶m_value, 0)); -// if (param_value == 0) -// { -// // no associated memory object? no problem. -// return py::object(); -// } - -// return create_mem_object_wrapper(param_value); -// } -// case CL_MEM_OFFSET: -// PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, -// size_t); -// #endif + // case CL_MEM_FLAGS: + // PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, + // cl_mem_flags); + // case CL_MEM_SIZE: + // PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, + // size_t); + // case CL_MEM_HOST_PTR: + // throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE, + // "Use MemoryObject.get_host_array to get host pointer."); + // case CL_MEM_MAP_COUNT: + // PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, + // cl_uint); + // case CL_MEM_REFERENCE_COUNT: + // PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, + // cl_uint); + // case CL_MEM_CONTEXT: + // PYOPENCL_GET_OPAQUE_INFO(MemObject, data(), param_name, + // cl_context, context); + + // #if PYOPENCL_CL_VERSION >= 0x1010 + // case CL_MEM_ASSOCIATED_MEMOBJECT: + // { + // cl_mem param_value; + // PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, (data(), param_name, sizeof(param_value), ¶m_value, 0)); + // if (param_value == 0) + // { + // // no associated memory object? no problem. + // return py::object(); + // } + + // return create_mem_object_wrapper(param_value); + // } + // case CL_MEM_OFFSET: + // PYOPENCL_GET_INTEGRAL_INFO(MemObject, data(), param_name, + // size_t); + // #endif default: throw error("MemoryObjectHolder.get_info", CL_INVALID_VALUE); @@ -1049,125 +1087,125 @@ namespace pyopencl class memory_object : /*boost::noncopyable, */ public memory_object_holder { - private: - bool m_valid; - cl_mem m_mem; - void *m_hostbuf; - - public: - memory_object(cl_mem mem, bool retain, void *hostbuf=0) - : m_valid(true), m_mem(mem) - { - if (retain) - PYOPENCL_CALL_GUARDED(clRetainMemObject, (mem)); + private: + bool m_valid; + cl_mem m_mem; + void *m_hostbuf; - if (hostbuf) - m_hostbuf = hostbuf; - } + public: + memory_object(cl_mem mem, bool retain, void *hostbuf=0) + : m_valid(true), m_mem(mem) + { + if (retain) + PYOPENCL_CALL_GUARDED(clRetainMemObject, (mem)); - memory_object(memory_object const &src) - : m_valid(true), m_mem(src.m_mem), m_hostbuf(src.m_hostbuf) - { - PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem)); - } + if (hostbuf) + m_hostbuf = hostbuf; + } - memory_object(memory_object_holder const &src) - : m_valid(true), m_mem(src.data()) - { - PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem)); - } + memory_object(memory_object const &src) + : m_valid(true), m_mem(src.m_mem), m_hostbuf(src.m_hostbuf) + { + PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem)); + } - void release() - { - if (!m_valid) - throw error("MemoryObject.free", CL_INVALID_VALUE, - "trying to double-unref mem object"); - // TODO - //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseMemObject, (m_mem)); - m_valid = false; - } + memory_object(memory_object_holder const &src) + : m_valid(true), m_mem(src.data()) + { + PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem)); + } - virtual ~memory_object() - { - if (m_valid) - release(); - } + void release() + { + if (!m_valid) + throw error("MemoryObject.free", CL_INVALID_VALUE, + "trying to double-unref mem object"); + // TODO + //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseMemObject, (m_mem)); + m_valid = false; + } + + virtual ~memory_object() + { + if (m_valid) + release(); + } - void *hostbuf() - { return m_hostbuf; } + void *hostbuf() + { return m_hostbuf; } - const cl_mem data() const - { return m_mem; } + const cl_mem data() const + { return m_mem; } }; -// #if PYOPENCL_CL_VERSION >= 0x1020 -// inline -// event *enqueue_migrate_mem_objects( -// command_queue &cq, -// py::object py_mem_objects, -// cl_mem_migration_flags flags, -// py::object py_wait_for) -// { -// PYOPENCL_PARSE_WAIT_FOR; - -// std::vector<cl_mem> mem_objects; -// PYTHON_FOREACH(mo, py_mem_objects) -// mem_objects.push_back(py::extract<memory_object &>(mo)().data()); - -// cl_event evt; -// PYOPENCL_RETRY_IF_MEM_ERROR( -// PYOPENCL_CALL_GUARDED(clEnqueueMigrateMemObjects, ( -// cq.data(), -// mem_objects.size(), mem_objects.empty( ) ? NULL : &mem_objects.front(), -// flags, -// PYOPENCL_WAITLIST_ARGS, &evt -// )); -// ); -// PYOPENCL_RETURN_NEW_EVENT(evt); -// } -// #endif - -// #ifdef cl_ext_migrate_memobject -// inline -// event *enqueue_migrate_mem_object_ext( -// command_queue &cq, -// py::object py_mem_objects, -// cl_mem_migration_flags_ext flags, -// py::object py_wait_for) -// { -// PYOPENCL_PARSE_WAIT_FOR; - -// #if PYOPENCL_CL_VERSION >= 0x1020 -// // {{{ get platform -// cl_device_id dev; -// PYOPENCL_CALL_GUARDED(clGetCommandQueueInfo, (cq.data(), CL_QUEUE_DEVICE, -// sizeof(dev), &dev, NULL)); -// cl_platform_id plat; -// PYOPENCL_CALL_GUARDED(clGetDeviceInfo, (cq.data(), CL_DEVICE_PLATFORM, -// sizeof(plat), &plat, NULL)); -// // }}} -// #endif - -// PYOPENCL_GET_EXT_FUN(plat, -// clEnqueueMigrateMemObjectEXT, enqueue_migrate_fn); - -// std::vector<cl_mem> mem_objects; -// PYTHON_FOREACH(mo, py_mem_objects) -// mem_objects.push_back(py::extract<memory_object &>(mo)().data()); - -// cl_event evt; -// PYOPENCL_RETRY_IF_MEM_ERROR( -// PYOPENCL_CALL_GUARDED(enqueue_migrate_fn, ( -// cq.data(), -// mem_objects.size(), mem_objects.empty( ) ? NULL : &mem_objects.front(), -// flags, -// PYOPENCL_WAITLIST_ARGS, &evt -// )); -// ); -// PYOPENCL_RETURN_NEW_EVENT(evt); -// } -// #endif + // #if PYOPENCL_CL_VERSION >= 0x1020 + // inline + // event *enqueue_migrate_mem_objects( + // command_queue &cq, + // py::object py_mem_objects, + // cl_mem_migration_flags flags, + // py::object py_wait_for) + // { + // PYOPENCL_PARSE_WAIT_FOR; + + // std::vector<cl_mem> mem_objects; + // PYTHON_FOREACH(mo, py_mem_objects) + // mem_objects.push_back(py::extract<memory_object &>(mo)().data()); + + // cl_event evt; + // PYOPENCL_RETRY_IF_MEM_ERROR( + // PYOPENCL_CALL_GUARDED(clEnqueueMigrateMemObjects, ( + // cq.data(), + // mem_objects.size(), mem_objects.empty( ) ? NULL : &mem_objects.front(), + // flags, + // PYOPENCL_WAITLIST_ARGS, &evt + // )); + // ); + // PYOPENCL_RETURN_NEW_EVENT(evt); + // } + // #endif + + // #ifdef cl_ext_migrate_memobject + // inline + // event *enqueue_migrate_mem_object_ext( + // command_queue &cq, + // py::object py_mem_objects, + // cl_mem_migration_flags_ext flags, + // py::object py_wait_for) + // { + // PYOPENCL_PARSE_WAIT_FOR; + + // #if PYOPENCL_CL_VERSION >= 0x1020 + // // {{{ get platform + // cl_device_id dev; + // PYOPENCL_CALL_GUARDED(clGetCommandQueueInfo, (cq.data(), CL_QUEUE_DEVICE, + // sizeof(dev), &dev, NULL)); + // cl_platform_id plat; + // PYOPENCL_CALL_GUARDED(clGetDeviceInfo, (cq.data(), CL_DEVICE_PLATFORM, + // sizeof(plat), &plat, NULL)); + // // }}} + // #endif + + // PYOPENCL_GET_EXT_FUN(plat, + // clEnqueueMigrateMemObjectEXT, enqueue_migrate_fn); + + // std::vector<cl_mem> mem_objects; + // PYTHON_FOREACH(mo, py_mem_objects) + // mem_objects.push_back(py::extract<memory_object &>(mo)().data()); + + // cl_event evt; + // PYOPENCL_RETRY_IF_MEM_ERROR( + // PYOPENCL_CALL_GUARDED(enqueue_migrate_fn, ( + // cq.data(), + // mem_objects.size(), mem_objects.empty( ) ? NULL : &mem_objects.front(), + // flags, + // PYOPENCL_WAITLIST_ARGS, &evt + // )); + // ); + // PYOPENCL_RETURN_NEW_EVENT(evt); + // } + // #endif // }}} @@ -1175,10 +1213,10 @@ namespace pyopencl // {{{ buffer inline cl_mem create_buffer( - cl_context ctx, - cl_mem_flags flags, - size_t size, - void *host_ptr) + cl_context ctx, + cl_mem_flags flags, + size_t size, + void *host_ptr) { cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateBuffer"); @@ -1207,13 +1245,13 @@ namespace pyopencl #if PYOPENCL_CL_VERSION >= 0x1010 inline cl_mem create_sub_buffer( - cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type bct, - const void *buffer_create_info) + cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type bct, + const void *buffer_create_info) { cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateSubBuffer"); cl_mem mem = clCreateSubBuffer(buffer, flags, - bct, buffer_create_info, &status_code); + bct, buffer_create_info, &status_code); if (status_code != CL_SUCCESS) throw pyopencl::error("clCreateSubBuffer", status_code); @@ -1225,8 +1263,8 @@ namespace pyopencl inline cl_mem create_sub_buffer_gc( - cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type bct, - const void *buffer_create_info) + cl_mem buffer, cl_mem_flags flags, cl_buffer_create_type bct, + const void *buffer_create_info) { // TODO //PYOPENCL_RETRY_RETURN_IF_MEM_ERROR( @@ -1235,93 +1273,93 @@ namespace pyopencl } #endif -class buffer : public memory_object + class buffer : public memory_object { - public: - buffer(cl_mem mem, bool retain, void *hostbuf=0) - : memory_object(mem, retain, hostbuf) - { } - -// #if PYOPENCL_CL_VERSION >= 0x1010 -// buffer *get_sub_region( -// size_t origin, size_t size, cl_mem_flags flags) const -// { -// cl_buffer_region region = { origin, size}; - -// cl_mem mem = create_sub_buffer_gc( -// data(), flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion); - -// try -// { -// return new buffer(mem, false); -// } -// catch (...) -// { -// PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); -// throw; -// } -// } - -// buffer *getitem(py::slice slc) const -// { -// PYOPENCL_BUFFER_SIZE_T start, end, stride, length; - -// size_t my_length; -// PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, -// (data(), CL_MEM_SIZE, sizeof(my_length), &my_length, 0)); - -// #if PY_VERSION_HEX >= 0x03020000 -// if (PySlice_GetIndicesEx(slc.ptr(), -// #else -// if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject *>(slc.ptr()), -// #endif -// my_length, &start, &end, &stride, &length) != 0) -// throw py::error_already_set(); - -// if (stride != 1) -// throw pyopencl::error("Buffer.__getitem__", CL_INVALID_VALUE, -// "Buffer slice must have stride 1"); - -// cl_mem_flags my_flags; -// PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, -// (data(), CL_MEM_FLAGS, sizeof(my_flags), &my_flags, 0)); - -// return get_sub_region(start, end, my_flags); -// } -// #endif + public: + buffer(cl_mem mem, bool retain, void *hostbuf=0) + : memory_object(mem, retain, hostbuf) + { } + + // #if PYOPENCL_CL_VERSION >= 0x1010 + // buffer *get_sub_region( + // size_t origin, size_t size, cl_mem_flags flags) const + // { + // cl_buffer_region region = { origin, size}; + + // cl_mem mem = create_sub_buffer_gc( + // data(), flags, CL_BUFFER_CREATE_TYPE_REGION, ®ion); + + // try + // { + // return new buffer(mem, false); + // } + // catch (...) + // { + // PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); + // throw; + // } + // } + + // buffer *getitem(py::slice slc) const + // { + // PYOPENCL_BUFFER_SIZE_T start, end, stride, length; + + // size_t my_length; + // PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + // (data(), CL_MEM_SIZE, sizeof(my_length), &my_length, 0)); + + // #if PY_VERSION_HEX >= 0x03020000 + // if (PySlice_GetIndicesEx(slc.ptr(), + // #else + // if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject *>(slc.ptr()), + // #endif + // my_length, &start, &end, &stride, &length) != 0) + // throw py::error_already_set(); + + // if (stride != 1) + // throw pyopencl::error("Buffer.__getitem__", CL_INVALID_VALUE, + // "Buffer slice must have stride 1"); + + // cl_mem_flags my_flags; + // PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + // (data(), CL_MEM_FLAGS, sizeof(my_flags), &my_flags, 0)); + + // return get_sub_region(start, end, my_flags); + // } + // #endif }; // {{{ buffer creation inline buffer *create_buffer_py( - context &ctx, - cl_mem_flags flags, - size_t size, - void *py_hostbuf - ) + context &ctx, + cl_mem_flags flags, + size_t size, + void *py_hostbuf + ) { void *buf = py_hostbuf; void *retained_buf_obj = 0; if (py_hostbuf != NULL) - { - if (flags & CL_MEM_USE_HOST_PTR) - retained_buf_obj = py_hostbuf; + { + if (flags & CL_MEM_USE_HOST_PTR) + retained_buf_obj = py_hostbuf; - } + } cl_mem mem = create_buffer_gc(ctx.data(), flags, size, buf); try - { - return new buffer(mem, false, retained_buf_obj); - } + { + return new buffer(mem, false, retained_buf_obj); + } catch (...) - { - PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); - throw; - } + { + PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); + throw; + } } @@ -1330,36 +1368,36 @@ class buffer : public memory_object // {{{ program - class program //: boost::noncopyable + class program : public _common //: boost::noncopyable { - private: - cl_program m_program; - program_kind_type m_program_kind; + private: + cl_program m_program; + program_kind_type m_program_kind; - public: - program(cl_program prog, bool retain, program_kind_type progkind=KND_UNKNOWN) - : m_program(prog), m_program_kind(progkind) - { - if (retain) - PYOPENCL_CALL_GUARDED(clRetainProgram, (prog)); - } + public: + program(cl_program prog, bool retain, program_kind_type progkind=KND_UNKNOWN) + : m_program(prog), m_program_kind(progkind) + { + if (retain) + PYOPENCL_CALL_GUARDED(clRetainProgram, (prog)); + } - ~program() - { - // TODO - //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseProgram, (m_program)); - } + ~program() + { + // TODO + //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseProgram, (m_program)); + } - cl_program data() const - { - return m_program; - } + cl_program data() const + { + return m_program; + } - program_kind_type kind() const - { - return m_program_kind; - } + program_kind_type kind() const + { + return m_program_kind; + } PYOPENCL_EQUALITY_TESTS(program); @@ -1386,95 +1424,95 @@ class buffer : public memory_object (m_program, CL_PROGRAM_BINARIES, sizes.size()*sizeof(char *), result_ptrs, 0)); \ return result_ptrs; - } + } - generic_info get_info(cl_program_info param_name) const - { - switch (param_name) + generic_info get_info(cl_program_info param_name) const + { + switch (param_name) { - case CL_PROGRAM_REFERENCE_COUNT: - PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, - cl_uint); + case CL_PROGRAM_REFERENCE_COUNT: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + cl_uint); // case CL_PROGRAM_CONTEXT: // PYOPENCL_GET_OPAQUE_INFO(Program, m_program, param_name, // cl_context, context); - case CL_PROGRAM_NUM_DEVICES: - PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, - cl_uint); -// case CL_PROGRAM_DEVICES: -// { -// std::vector<cl_device_id> result; -// PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); - -// py::list py_result; -// BOOST_FOREACH(cl_device_id did, result) -// py_result.append(handle_from_new_ptr( -// new pyopencl::device(did))); -// return py_result; -// } - case CL_PROGRAM_SOURCE: - PYOPENCL_GET_STR_INFO(Program, m_program, param_name); - case CL_PROGRAM_BINARY_SIZES: - { - std::vector<size_t> result; - PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); - PYOPENCL_GET_ARRAY_INFO(size_t, result); - } -// case CL_PROGRAM_BINARIES: -// // {{{ -// { -// std::vector<size_t> sizes; -// PYOPENCL_GET_VEC_INFO(Program, m_program, CL_PROGRAM_BINARY_SIZES, sizes); - -// size_t total_size = std::accumulate(sizes.begin(), sizes.end(), 0); - -// boost::scoped_array<unsigned char> result( -// new unsigned char[total_size]); -// std::vector<unsigned char *> result_ptrs; - -// unsigned char *ptr = result.get(); -// for (unsigned i = 0; i < sizes.size(); ++i) -// { -// result_ptrs.push_back(ptr); -// ptr += sizes[i]; -// } - -// PYOPENCL_CALL_GUARDED(clGetProgramInfo, -// (m_program, param_name, sizes.size()*sizeof(unsigned char *), -// result_ptrs.empty( ) ? NULL : &result_ptrs.front(), 0)); - -// py::list py_result; -// ptr = result.get(); -// for (unsigned i = 0; i < sizes.size(); ++i) -// { -// py::handle<> binary_pyobj( -// #if PY_VERSION_HEX >= 0x03000000 -// PyBytes_FromStringAndSize( -// reinterpret_cast<char *>(ptr), sizes[i]) -// #else -// PyString_FromStringAndSize( -// reinterpret_cast<char *>(ptr), sizes[i]) -// #endif -// ); -// py_result.append(binary_pyobj); -// ptr += sizes[i]; -// } -// return py_result; -// } -// // }}} + case CL_PROGRAM_NUM_DEVICES: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + cl_uint); + // case CL_PROGRAM_DEVICES: + // { + // std::vector<cl_device_id> result; + // PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); + + // py::list py_result; + // BOOST_FOREACH(cl_device_id did, result) + // py_result.append(handle_from_new_ptr( + // new pyopencl::device(did))); + // return py_result; + // } + case CL_PROGRAM_SOURCE: + PYOPENCL_GET_STR_INFO(Program, m_program, param_name); + case CL_PROGRAM_BINARY_SIZES: + { + std::vector<size_t> result; + PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); + PYOPENCL_GET_ARRAY_INFO(size_t, result); + } + // case CL_PROGRAM_BINARIES: + // // {{{ + // { + // std::vector<size_t> sizes; + // PYOPENCL_GET_VEC_INFO(Program, m_program, CL_PROGRAM_BINARY_SIZES, sizes); + + // size_t total_size = std::accumulate(sizes.begin(), sizes.end(), 0); + + // boost::scoped_array<unsigned char> result( + // new unsigned char[total_size]); + // std::vector<unsigned char *> result_ptrs; + + // unsigned char *ptr = result.get(); + // for (unsigned i = 0; i < sizes.size(); ++i) + // { + // result_ptrs.push_back(ptr); + // ptr += sizes[i]; + // } + + // PYOPENCL_CALL_GUARDED(clGetProgramInfo, + // (m_program, param_name, sizes.size()*sizeof(unsigned char *), + // result_ptrs.empty( ) ? NULL : &result_ptrs.front(), 0)); + + // py::list py_result; + // ptr = result.get(); + // for (unsigned i = 0; i < sizes.size(); ++i) + // { + // py::handle<> binary_pyobj( + // #if PY_VERSION_HEX >= 0x03000000 + // PyBytes_FromStringAndSize( + // reinterpret_cast<char *>(ptr), sizes[i]) + // #else + // PyString_FromStringAndSize( + // reinterpret_cast<char *>(ptr), sizes[i]) + // #endif + // ); + // py_result.append(binary_pyobj); + // ptr += sizes[i]; + // } + // return py_result; + // } + // // }}} #if PYOPENCL_CL_VERSION >= 0x1020 - case CL_PROGRAM_NUM_KERNELS: - PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, - size_t); - case CL_PROGRAM_KERNEL_NAMES: - PYOPENCL_GET_STR_INFO(Program, m_program, param_name); + case CL_PROGRAM_NUM_KERNELS: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + size_t); + case CL_PROGRAM_KERNEL_NAMES: + PYOPENCL_GET_STR_INFO(Program, m_program, param_name); #endif - default: - throw error("Program.get_info", CL_INVALID_VALUE); + default: + throw error("Program.get_info", CL_INVALID_VALUE); } - } + } generic_info get_build_info(device const &dev, cl_program_build_info param_name) const @@ -1503,56 +1541,56 @@ class buffer : public memory_object } } - void build(char *options, cl_uint num_devices, void **ptr_devices) - { - // todo: this function should get a list of device instances, not raw pointers - // pointers are for the cffi interface and should not be here - std::vector<cl_device_id> devices(num_devices); - for(cl_uint i = 0; i < num_devices; ++i) { - devices[i] = static_cast<device*>(ptr_devices[i])->data(); - } - PYOPENCL_CALL_GUARDED_THREADED(clBuildProgram, - (m_program, num_devices, devices.empty( ) ? NULL : &devices.front(), - options, 0 ,0)); + void build(char *options, cl_uint num_devices, void **ptr_devices) + { + // todo: this function should get a list of device instances, not raw pointers + // pointers are for the cffi interface and should not be here + std::vector<cl_device_id> devices(num_devices); + for(cl_uint i = 0; i < num_devices; ++i) { + devices[i] = static_cast<device*>(ptr_devices[i])->data(); } + PYOPENCL_CALL_GUARDED_THREADED(clBuildProgram, + (m_program, num_devices, devices.empty( ) ? NULL : &devices.front(), + options, 0 ,0)); + } -// #if PYOPENCL_CL_VERSION >= 0x1020 -// void compile(std::string options, py::object py_devices, -// py::object py_headers) -// { -// PYOPENCL_PARSE_PY_DEVICES; - -// // {{{ pick apart py_headers -// // py_headers is a list of tuples *(name, program)* - -// std::vector<std::string> header_names; -// std::vector<cl_program> programs; -// PYTHON_FOREACH(name_hdr_tup, py_headers) -// { -// if (py::len(name_hdr_tup) != 2) -// throw error("Program.compile", CL_INVALID_VALUE, -// "epxected (name, header) tuple in headers list"); -// std::string name = py::extract<std::string const &>(name_hdr_tup[0]); -// program &prg = py::extract<program &>(name_hdr_tup[1]); - -// header_names.push_back(name); -// programs.push_back(prg.data()); -// } - -// std::vector<const char *> header_name_ptrs; -// BOOST_FOREACH(std::string const &name, header_names) -// header_name_ptrs.push_back(name.c_str()); - -// // }}} - -// PYOPENCL_CALL_GUARDED_THREADED(clCompileProgram, -// (m_program, num_devices, devices, -// options.c_str(), header_names.size(), -// programs.empty() ? NULL : &programs.front(), -// header_name_ptrs.empty() ? NULL : &header_name_ptrs.front(), -// 0, 0)); -// } -// #endif + // #if PYOPENCL_CL_VERSION >= 0x1020 + // void compile(std::string options, py::object py_devices, + // py::object py_headers) + // { + // PYOPENCL_PARSE_PY_DEVICES; + + // // {{{ pick apart py_headers + // // py_headers is a list of tuples *(name, program)* + + // std::vector<std::string> header_names; + // std::vector<cl_program> programs; + // PYTHON_FOREACH(name_hdr_tup, py_headers) + // { + // if (py::len(name_hdr_tup) != 2) + // throw error("Program.compile", CL_INVALID_VALUE, + // "epxected (name, header) tuple in headers list"); + // std::string name = py::extract<std::string const &>(name_hdr_tup[0]); + // program &prg = py::extract<program &>(name_hdr_tup[1]); + + // header_names.push_back(name); + // programs.push_back(prg.data()); + // } + + // std::vector<const char *> header_name_ptrs; + // BOOST_FOREACH(std::string const &name, header_names) + // header_name_ptrs.push_back(name.c_str()); + + // // }}} + + // PYOPENCL_CALL_GUARDED_THREADED(clCompileProgram, + // (m_program, num_devices, devices, + // options.c_str(), header_names.size(), + // programs.empty() ? NULL : &programs.front(), + // header_name_ptrs.empty() ? NULL : &header_name_ptrs.front(), + // 0, 0)); + // } + // #endif }; @@ -1560,226 +1598,226 @@ class buffer : public memory_object // {{{ kernel class local_memory { - private: - size_t m_size; + private: + size_t m_size; - public: - local_memory(size_t size) - : m_size(size) - { } + public: + local_memory(size_t size) + : m_size(size) + { } - size_t size() const - { return m_size; } + size_t size() const + { return m_size; } }; - class kernel // : boost::noncopyable + class kernel : public _common // : boost::noncopyable { - private: - cl_kernel m_kernel; + private: + cl_kernel m_kernel; - public: - kernel(cl_kernel knl, bool retain) - : m_kernel(knl) - { - if (retain) - PYOPENCL_CALL_GUARDED(clRetainKernel, (knl)); - } + public: + kernel(cl_kernel knl, bool retain) + : m_kernel(knl) + { + if (retain) + PYOPENCL_CALL_GUARDED(clRetainKernel, (knl)); + } - kernel(program const &prg, std::string const &kernel_name) - { - cl_int status_code; + kernel(program const &prg, std::string const &kernel_name) + { + cl_int status_code; - PYOPENCL_PRINT_CALL_TRACE("clCreateKernel"); - m_kernel = clCreateKernel(prg.data(), kernel_name.c_str(), - &status_code); - if (status_code != CL_SUCCESS) - throw pyopencl::error("clCreateKernel", status_code); - } + PYOPENCL_PRINT_CALL_TRACE("clCreateKernel"); + m_kernel = clCreateKernel(prg.data(), kernel_name.c_str(), + &status_code); + if (status_code != CL_SUCCESS) + throw pyopencl::error("clCreateKernel", status_code); + } - ~kernel() - { - // todo - //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseKernel, (m_kernel)); - } + ~kernel() + { + // todo + //PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseKernel, (m_kernel)); + } - cl_kernel data() const - { - return m_kernel; - } + cl_kernel data() const + { + return m_kernel; + } - PYOPENCL_EQUALITY_TESTS(kernel); + PYOPENCL_EQUALITY_TESTS(kernel); - void set_arg_null(cl_uint arg_index) - { - cl_mem m = 0; - PYOPENCL_CALL_GUARDED(clSetKernelArg, (m_kernel, arg_index, - sizeof(cl_mem), &m)); - } + void set_arg_null(cl_uint arg_index) + { + cl_mem m = 0; + PYOPENCL_CALL_GUARDED(clSetKernelArg, (m_kernel, arg_index, + sizeof(cl_mem), &m)); + } - void set_arg_mem(cl_uint arg_index, memory_object_holder &moh) - { - cl_mem m = moh.data(); - PYOPENCL_CALL_GUARDED(clSetKernelArg, - (m_kernel, arg_index, sizeof(cl_mem), &m)); - } + void set_arg_mem(cl_uint arg_index, memory_object_holder &moh) + { + cl_mem m = moh.data(); + PYOPENCL_CALL_GUARDED(clSetKernelArg, + (m_kernel, arg_index, sizeof(cl_mem), &m)); + } - void set_arg_local(cl_uint arg_index, local_memory const &loc) - { - PYOPENCL_CALL_GUARDED(clSetKernelArg, - (m_kernel, arg_index, loc.size(), 0)); - } + void set_arg_local(cl_uint arg_index, local_memory const &loc) + { + PYOPENCL_CALL_GUARDED(clSetKernelArg, + (m_kernel, arg_index, loc.size(), 0)); + } + + // void set_arg_sampler(cl_uint arg_index, sampler const &smp) + // { + // cl_sampler s = smp.data(); + // PYOPENCL_CALL_GUARDED(clSetKernelArg, + // (m_kernel, arg_index, sizeof(cl_sampler), &s)); + // } - // void set_arg_sampler(cl_uint arg_index, sampler const &smp) - // { - // cl_sampler s = smp.data(); - // PYOPENCL_CALL_GUARDED(clSetKernelArg, - // (m_kernel, arg_index, sizeof(cl_sampler), &s)); - // } - - // void set_arg_buf(cl_uint arg_index, py::object py_buffer) - // { - // const void *buf; - // PYOPENCL_BUFFER_SIZE_T len; - - // if (PyObject_AsReadBuffer(py_buffer.ptr(), &buf, &len)) - // { - // PyErr_Clear(); - // throw error("Kernel.set_arg", CL_INVALID_VALUE, - // "invalid kernel argument"); - // } - - // PYOPENCL_CALL_GUARDED(clSetKernelArg, - // (m_kernel, arg_index, len, buf)); - // } - - // void set_arg(cl_uint arg_index, py::object arg) - // { - // if (arg.ptr() == Py_None) - // { - // set_arg_null(arg_index); - // return; - // } - - // py::extract<memory_object_holder &> ex_mo(arg); - // if (ex_mo.check()) - // { - // set_arg_mem(arg_index, ex_mo()); - // return; - // } - - // py::extract<local_memory const &> ex_loc(arg); - // if (ex_loc.check()) - // { - // set_arg_local(arg_index, ex_loc()); - // return; - // } - - // py::extract<sampler const &> ex_smp(arg); - // if (ex_smp.check()) - // { - // set_arg_sampler(arg_index, ex_smp()); - // return; - // } - - // set_arg_buf(arg_index, arg); - // } + // void set_arg_buf(cl_uint arg_index, py::object py_buffer) + // { + // const void *buf; + // PYOPENCL_BUFFER_SIZE_T len; + + // if (PyObject_AsReadBuffer(py_buffer.ptr(), &buf, &len)) + // { + // PyErr_Clear(); + // throw error("Kernel.set_arg", CL_INVALID_VALUE, + // "invalid kernel argument"); + // } + + // PYOPENCL_CALL_GUARDED(clSetKernelArg, + // (m_kernel, arg_index, len, buf)); + // } + + // void set_arg(cl_uint arg_index, py::object arg) + // { + // if (arg.ptr() == Py_None) + // { + // set_arg_null(arg_index); + // return; + // } + + // py::extract<memory_object_holder &> ex_mo(arg); + // if (ex_mo.check()) + // { + // set_arg_mem(arg_index, ex_mo()); + // return; + // } + + // py::extract<local_memory const &> ex_loc(arg); + // if (ex_loc.check()) + // { + // set_arg_local(arg_index, ex_loc()); + // return; + // } + + // py::extract<sampler const &> ex_smp(arg); + // if (ex_smp.check()) + // { + // set_arg_sampler(arg_index, ex_smp()); + // return; + // } + + // set_arg_buf(arg_index, arg); + // } - generic_info get_info(cl_kernel_info param_name) const - { - switch (param_name) - { -// case CL_KERNEL_FUNCTION_NAME: -// PYOPENCL_GET_STR_INFO(Kernel, m_kernel, param_name); - case CL_KERNEL_NUM_ARGS: - case CL_KERNEL_REFERENCE_COUNT: - PYOPENCL_GET_INTEGRAL_INFO(Kernel, m_kernel, param_name, - cl_uint); -// case CL_KERNEL_CONTEXT: -// PYOPENCL_GET_OPAQUE_INFO(Kernel, m_kernel, param_name, -// cl_context, context); -// case CL_KERNEL_PROGRAM: -// PYOPENCL_GET_OPAQUE_INFO(Kernel, m_kernel, param_name, -// cl_program, program); -// #if PYOPENCL_CL_VERSION >= 0x1020 -// case CL_KERNEL_ATTRIBUTES: -// PYOPENCL_GET_STR_INFO(Kernel, m_kernel, param_name); -// #endif - default: - throw error("Kernel.get_info", CL_INVALID_VALUE); - } - } - -// py::object get_work_group_info( -// cl_kernel_work_group_info param_name, -// device const &dev -// ) const -// { -// switch (param_name) -// { -// #define PYOPENCL_FIRST_ARG m_kernel, dev.data() // hackety hack -// case CL_KERNEL_WORK_GROUP_SIZE: -// PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, -// PYOPENCL_FIRST_ARG, param_name, -// size_t); -// case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: -// { -// std::vector<size_t> result; -// PYOPENCL_GET_VEC_INFO(KernelWorkGroup, -// PYOPENCL_FIRST_ARG, param_name, result); - -// PYOPENCL_RETURN_VECTOR(size_t, result); -// } -// case CL_KERNEL_LOCAL_MEM_SIZE: -// #if PYOPENCL_CL_VERSION >= 0x1010 -// case CL_KERNEL_PRIVATE_MEM_SIZE: -// #endif -// PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, -// PYOPENCL_FIRST_ARG, param_name, -// cl_ulong); - -// #if PYOPENCL_CL_VERSION >= 0x1010 -// case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: -// PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, -// PYOPENCL_FIRST_ARG, param_name, -// size_t); -// #endif -// default: -// throw error("Kernel.get_work_group_info", CL_INVALID_VALUE); -// #undef PYOPENCL_FIRST_ARG -// } -// } - -// #if PYOPENCL_CL_VERSION >= 0x1020 -// py::object get_arg_info( -// cl_uint arg_index, -// cl_kernel_arg_info param_name -// ) const -// { -// switch (param_name) -// { -// #define PYOPENCL_FIRST_ARG m_kernel, arg_index // hackety hack -// case CL_KERNEL_ARG_ADDRESS_QUALIFIER: -// PYOPENCL_GET_INTEGRAL_INFO(KernelArg, -// PYOPENCL_FIRST_ARG, param_name, -// cl_kernel_arg_address_qualifier); - -// case CL_KERNEL_ARG_ACCESS_QUALIFIER: -// PYOPENCL_GET_INTEGRAL_INFO(KernelArg, -// PYOPENCL_FIRST_ARG, param_name, -// cl_kernel_arg_access_qualifier); - -// case CL_KERNEL_ARG_TYPE_NAME: -// case CL_KERNEL_ARG_NAME: -// PYOPENCL_GET_STR_INFO(KernelArg, PYOPENCL_FIRST_ARG, param_name); -// #undef PYOPENCL_FIRST_ARG -// default: -// throw error("Kernel.get_arg_info", CL_INVALID_VALUE); -// } -// } -// #endif + generic_info get_info(cl_kernel_info param_name) const + { + switch (param_name) + { + // case CL_KERNEL_FUNCTION_NAME: + // PYOPENCL_GET_STR_INFO(Kernel, m_kernel, param_name); + case CL_KERNEL_NUM_ARGS: + case CL_KERNEL_REFERENCE_COUNT: + PYOPENCL_GET_INTEGRAL_INFO(Kernel, m_kernel, param_name, + cl_uint); + // case CL_KERNEL_CONTEXT: + // PYOPENCL_GET_OPAQUE_INFO(Kernel, m_kernel, param_name, + // cl_context, context); + // case CL_KERNEL_PROGRAM: + // PYOPENCL_GET_OPAQUE_INFO(Kernel, m_kernel, param_name, + // cl_program, program); + // #if PYOPENCL_CL_VERSION >= 0x1020 + // case CL_KERNEL_ATTRIBUTES: + // PYOPENCL_GET_STR_INFO(Kernel, m_kernel, param_name); + // #endif + default: + throw error("Kernel.get_info", CL_INVALID_VALUE); + } + } + + // py::object get_work_group_info( + // cl_kernel_work_group_info param_name, + // device const &dev + // ) const + // { + // switch (param_name) + // { + // #define PYOPENCL_FIRST_ARG m_kernel, dev.data() // hackety hack + // case CL_KERNEL_WORK_GROUP_SIZE: + // PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, + // PYOPENCL_FIRST_ARG, param_name, + // size_t); + // case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: + // { + // std::vector<size_t> result; + // PYOPENCL_GET_VEC_INFO(KernelWorkGroup, + // PYOPENCL_FIRST_ARG, param_name, result); + + // PYOPENCL_RETURN_VECTOR(size_t, result); + // } + // case CL_KERNEL_LOCAL_MEM_SIZE: + // #if PYOPENCL_CL_VERSION >= 0x1010 + // case CL_KERNEL_PRIVATE_MEM_SIZE: + // #endif + // PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, + // PYOPENCL_FIRST_ARG, param_name, + // cl_ulong); + + // #if PYOPENCL_CL_VERSION >= 0x1010 + // case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: + // PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, + // PYOPENCL_FIRST_ARG, param_name, + // size_t); + // #endif + // default: + // throw error("Kernel.get_work_group_info", CL_INVALID_VALUE); + // #undef PYOPENCL_FIRST_ARG + // } + // } + + // #if PYOPENCL_CL_VERSION >= 0x1020 + // py::object get_arg_info( + // cl_uint arg_index, + // cl_kernel_arg_info param_name + // ) const + // { + // switch (param_name) + // { + // #define PYOPENCL_FIRST_ARG m_kernel, arg_index // hackety hack + // case CL_KERNEL_ARG_ADDRESS_QUALIFIER: + // PYOPENCL_GET_INTEGRAL_INFO(KernelArg, + // PYOPENCL_FIRST_ARG, param_name, + // cl_kernel_arg_address_qualifier); + + // case CL_KERNEL_ARG_ACCESS_QUALIFIER: + // PYOPENCL_GET_INTEGRAL_INFO(KernelArg, + // PYOPENCL_FIRST_ARG, param_name, + // cl_kernel_arg_access_qualifier); + + // case CL_KERNEL_ARG_TYPE_NAME: + // case CL_KERNEL_ARG_NAME: + // PYOPENCL_GET_STR_INFO(KernelArg, PYOPENCL_FIRST_ARG, param_name); + // #undef PYOPENCL_FIRST_ARG + // default: + // throw error("Kernel.get_arg_info", CL_INVALID_VALUE); + // } + // } + // #endif }; @@ -1787,13 +1825,13 @@ class buffer : public memory_object inline event *enqueue_read_buffer( - command_queue &cq, - memory_object_holder &mem, - void *buffer, - size_t size, - size_t device_offset, - /*py::object py_wait_for,*/ - bool is_blocking) + command_queue &cq, + memory_object_holder &mem, + void *buffer, + size_t size, + size_t device_offset, + /*py::object py_wait_for,*/ + bool is_blocking) { // TODO //PYOPENCL_PARSE_WAIT_FOR; @@ -1801,16 +1839,16 @@ class buffer : public memory_object cl_event evt; // TODO //PYOPENCL_RETRY_IF_MEM_ERROR( - PYOPENCL_CALL_GUARDED_THREADED(clEnqueueReadBuffer, - (cq.data(), - mem.data(), - PYOPENCL_CAST_BOOL(is_blocking), - device_offset, size, buffer, - 0, NULL, - //PYOPENCL_WAITLIST_ARGS, - &evt - )); - //); + PYOPENCL_CALL_GUARDED_THREADED(clEnqueueReadBuffer, + (cq.data(), + mem.data(), + PYOPENCL_CAST_BOOL(is_blocking), + device_offset, size, buffer, + 0, NULL, + //PYOPENCL_WAITLIST_ARGS, + &evt + )); + //); PYOPENCL_RETURN_NEW_EVENT(evt); } @@ -1851,23 +1889,23 @@ class buffer : public memory_object 0, NULL, //PYOPENCL_WAITLIST_ARGS, &evt )) - // ); + // ); - PYOPENCL_RETURN_NEW_EVENT(evt); + PYOPENCL_RETURN_NEW_EVENT(evt); } // }}} -inline event *enqueue_nd_range_kernel( - command_queue &cq, - kernel &knl, - cl_uint work_dim, - const size_t *global_work_offset, - const size_t *global_work_size, - const size_t *local_work_size //, - //py::object py_global_work_offset, - //py::object py_wait_for, - ) + inline event *enqueue_nd_range_kernel( + command_queue &cq, + kernel &knl, + cl_uint work_dim, + const size_t *global_work_offset, + const size_t *global_work_size, + const size_t *local_work_size //, + //py::object py_global_work_offset, + //py::object py_wait_for, + ) { // TODO // PYOPENCL_PARSE_WAIT_FOR; @@ -1894,8 +1932,8 @@ inline event *enqueue_nd_range_kernel( // }}} inline program *create_program_with_source( - context &ctx, - std::string const &src) + context &ctx, + std::string const &src) { const char *string = src.c_str(); size_t length = src.size(); @@ -1903,48 +1941,48 @@ inline event *enqueue_nd_range_kernel( cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateProgramWithSource"); cl_program result = clCreateProgramWithSource( - ctx.data(), 1, &string, &length, &status_code); + ctx.data(), 1, &string, &length, &status_code); if (status_code != CL_SUCCESS) throw pyopencl::error("clCreateProgramWithSource", status_code); try - { - return new program(result, false, KND_SOURCE); - } + { + return new program(result, false, KND_SOURCE); + } catch (...) - { - clReleaseProgram(result); - throw; - } + { + clReleaseProgram(result); + throw; + } } inline program *create_program_with_binary( - context &ctx, - cl_uint num_devices, - void **ptr_devices, - cl_uint num_binaries, - char **binaries) + context &ctx, + cl_uint num_devices, + void **ptr_devices, + cl_uint num_binaries, + char **binaries) { std::vector<cl_device_id> devices; std::vector<size_t> sizes; std::vector<cl_int> binary_statuses; for (cl_uint i = 0; i < num_devices; ++i) - { - devices.push_back(static_cast<device*>(ptr_devices[i])->data()); - sizes.push_back(strlen(const_cast<const char*>(binaries[i]))); - } + { + devices.push_back(static_cast<device*>(ptr_devices[i])->data()); + sizes.push_back(strlen(const_cast<const char*>(binaries[i]))); + } binary_statuses.resize(num_devices); cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateProgramWithBinary"); cl_program result = clCreateProgramWithBinary( - ctx.data(), num_devices, - devices.empty( ) ? NULL : &devices.front(), - sizes.empty( ) ? NULL : &sizes.front(), - reinterpret_cast<const unsigned char**>(const_cast<const char**>(binaries)), // todo: valid cast? - binary_statuses.empty( ) ? NULL : &binary_statuses.front(), - &status_code); + ctx.data(), num_devices, + devices.empty( ) ? NULL : &devices.front(), + sizes.empty( ) ? NULL : &sizes.front(), + reinterpret_cast<const unsigned char**>(const_cast<const char**>(binaries)), // todo: valid cast? + binary_statuses.empty( ) ? NULL : &binary_statuses.front(), + &status_code); if (status_code != CL_SUCCESS) throw pyopencl::error("clCreateProgramWithBinary", status_code); @@ -1952,14 +1990,14 @@ inline event *enqueue_nd_range_kernel( // std::cout << i << ":" << binary_statuses[i] << std::endl; try - { - return new program(result, false, KND_BINARY); - } + { + return new program(result, false, KND_BINARY); + } catch (...) - { - clReleaseProgram(result); - throw; - } + { + clReleaseProgram(result); + throw; + } } @@ -1969,21 +2007,21 @@ inline event *enqueue_nd_range_kernel( ::error *get_platforms(void **ptr_platforms, uint32_t *num_platforms) { C_HANDLE_ERROR( - *num_platforms = 0; - PYOPENCL_CALL_GUARDED(clGetPlatformIDs, (0, 0, num_platforms)); - - typedef std::vector<cl_platform_id> vec; - vec platforms(*num_platforms); - PYOPENCL_CALL_GUARDED(clGetPlatformIDs, - (*num_platforms, platforms.empty( ) ? NULL : &platforms.front(), num_platforms)); - - MALLOC(platform*, _ptr_platforms, *num_platforms); - for(vec::size_type i = 0; i < platforms.size(); ++i) { - _ptr_platforms[i] = new platform(platforms[i]); - } - *ptr_platforms = _ptr_platforms; + *num_platforms = 0; + PYOPENCL_CALL_GUARDED(clGetPlatformIDs, (0, 0, num_platforms)); + + typedef std::vector<cl_platform_id> vec; + vec platforms(*num_platforms); + PYOPENCL_CALL_GUARDED(clGetPlatformIDs, + (*num_platforms, platforms.empty( ) ? NULL : &platforms.front(), num_platforms)); + + MALLOC(platform*, _ptr_platforms, *num_platforms); + for(vec::size_type i = 0; i < platforms.size(); ++i) { + _ptr_platforms[i] = new platform(platforms[i]); + } + *ptr_platforms = _ptr_platforms; ) - return 0; + return 0; } void _free(void *p) { @@ -1998,102 +2036,98 @@ inline event *enqueue_nd_range_kernel( ::error *platform__get_info(void *ptr_platform, cl_platform_info param, generic_info *out) { C_HANDLE_ERROR( - *out = static_cast<platform*>(ptr_platform)->get_info(param); + *out = static_cast<platform*>(ptr_platform)->get_info(param); ) - return 0; + return 0; } ::error *platform__get_devices(void *ptr_platform, void **ptr_devices, uint32_t *num_devices, cl_device_type devtype) { typedef std::vector<cl_device_id> vec; C_HANDLE_ERROR( - vec devices = static_cast<platform*>(ptr_platform)->get_devices(devtype); - *num_devices = devices.size(); - - MALLOC(device*, _ptr_devices, *num_devices); - for(vec::size_type i = 0; i < devices.size(); ++i) { - _ptr_devices[i] = new device(devices[i]); - } - *ptr_devices = _ptr_devices; + vec devices = static_cast<platform*>(ptr_platform)->get_devices(devtype); + *num_devices = devices.size(); + + MALLOC(device*, _ptr_devices, *num_devices); + for(vec::size_type i = 0; i < devices.size(); ++i) { + _ptr_devices[i] = new device(devices[i]); + } + *ptr_devices = _ptr_devices; ) - return 0; - } - - long platform__hash(void *ptr_platform) { - return static_cast<platform*>(ptr_platform)->hash(); + return 0; } ::error *device__get_info(void *ptr_device, cl_device_info param, generic_info *out) { C_HANDLE_ERROR( - *out = static_cast<device*>(ptr_device)->get_info(param); + *out = static_cast<device*>(ptr_device)->get_info(param); ) - return 0; + return 0; } ::error *_create_context(void **ptr_ctx, cl_context_properties *properties, cl_uint num_devices, void **ptr_devices) { C_HANDLE_ERROR( - cl_int status_code; - std::vector<cl_device_id> devices(num_devices); - for(cl_uint i = 0; i < num_devices; ++i) { - devices[i] = static_cast<device*>(ptr_devices[i])->data(); - } - cl_context ctx = clCreateContext(properties, - num_devices, - devices.empty() ? NULL : &devices.front(), - 0, 0, &status_code); - if (status_code != CL_SUCCESS) { - throw pyopencl::error("Context", status_code); - } - *ptr_ctx = new context(ctx, false); + cl_int status_code; + std::vector<cl_device_id> devices(num_devices); + for(cl_uint i = 0; i < num_devices; ++i) { + devices[i] = static_cast<device*>(ptr_devices[i])->data(); + } + cl_context ctx = clCreateContext(properties, + num_devices, + devices.empty() ? NULL : &devices.front(), + 0, 0, &status_code); + if (status_code != CL_SUCCESS) { + throw pyopencl::error("Context", status_code); + } + *ptr_ctx = new context(ctx, false); ) - return 0; + return 0; } ::error *_create_command_queue(void **ptr_command_queue, void *ptr_context, void *ptr_device, cl_command_queue_properties properties) { context *ctx = static_cast<context*>(ptr_context); device *dev = static_cast<device*>(ptr_device); C_HANDLE_ERROR( - *ptr_command_queue = new command_queue(*ctx, dev, properties); + *ptr_command_queue = new command_queue(*ctx, dev, properties); ) - return 0; + return 0; } ::error *_create_buffer(void **ptr_buffer, void *ptr_context, cl_mem_flags flags, size_t size, void *hostbuf) { context *ctx = static_cast<context*>(ptr_context); C_HANDLE_ERROR( - *ptr_buffer = create_buffer_py(*ctx, flags, size, hostbuf); + *ptr_buffer = create_buffer_py(*ctx, flags, size, hostbuf); ) - return 0; + return 0; } ::error *_create_program_with_source(void **ptr_program, void *ptr_context, char *src) { context *ctx = static_cast<context*>(ptr_context); C_HANDLE_ERROR( - *ptr_program = create_program_with_source(*ctx, src); + *ptr_program = create_program_with_source(*ctx, src); ) - return 0; + return 0; } ::error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries) { context *ctx = static_cast<context*>(ptr_context); C_HANDLE_ERROR( - *ptr_program = create_program_with_binary(*ctx, num_devices, ptr_devices, num_binaries, binaries); + *ptr_program = create_program_with_binary(*ctx, num_devices, ptr_devices, num_binaries, binaries); ) - return 0; + return 0; } ::error *program__build(void *ptr_program, char *options, cl_uint num_devices, void **ptr_devices) { C_HANDLE_ERROR( static_cast<program*>(ptr_program)->build(options, num_devices, ptr_devices); ) - return 0; + return 0; } ::error *program__kind(void *ptr_program, int *kind) { C_HANDLE_ERROR( *kind = static_cast<program*>(ptr_program)->kind(); ) - return 0; + return 0; } @@ -2102,7 +2136,7 @@ inline event *enqueue_nd_range_kernel( *out = static_cast<program*>(ptr_program)->get_build_info(*static_cast<device*>(ptr_device), param); ) - return 0; + return 0; } ::error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices) { @@ -2110,178 +2144,106 @@ inline event *enqueue_nd_range_kernel( // todo: refactor, same as get_devices() C_HANDLE_ERROR( - vec devices = static_cast<program*>(ptr_program)->get_info__devices(); + vec devices = static_cast<program*>(ptr_program)->get_info__devices(); - *num_devices = devices.size(); + *num_devices = devices.size(); - MALLOC(device*, _ptr_devices, *num_devices); - for(vec::size_type i = 0; i < devices.size(); ++i) { - _ptr_devices[i] = new device(devices[i]); - } - *ptr_devices = _ptr_devices; - ) - return 0; + MALLOC(device*, _ptr_devices, *num_devices); + for(vec::size_type i = 0; i < devices.size(); ++i) { + _ptr_devices[i] = new device(devices[i]); + } + *ptr_devices = _ptr_devices; + ) + return 0; } ::error *program__get_info__binaries(void *ptr_program, char ***ptr_binaries, uint32_t *num_binaries) { C_HANDLE_ERROR( - *ptr_binaries = static_cast<program*>(ptr_program)->get_info__binaries(num_binaries); + *ptr_binaries = static_cast<program*>(ptr_program)->get_info__binaries(num_binaries); ) - return 0; + return 0; } ::error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out) { C_HANDLE_ERROR( - *out = static_cast<program*>(ptr_program)->get_info(param); + *out = static_cast<program*>(ptr_program)->get_info(param); ) - return 0; + return 0; } - - long device__hash(void *ptr_device) { - return static_cast<device*>(ptr_device)->hash(); - } - - long context__hash(void *ptr_context) { - return static_cast<context*>(ptr_context)->hash(); - } - - long command_queue__hash(void *ptr_command_queue) { - return static_cast<command_queue*>(ptr_command_queue)->hash(); - } - - long event__hash(void *ptr_event) { - return static_cast<event*>(ptr_event)->hash(); - } - - long memory_object_holder__hash(void *ptr_memory_object_holder) { - return static_cast<memory_object_holder*>(ptr_memory_object_holder)->hash(); - } - - long program__hash(void *ptr_program) { - return static_cast<program*>(ptr_program)->hash(); - } - - long kernel__hash(void *ptr_kernel) { - return static_cast<kernel*>(ptr_kernel)->hash(); - } - ::error *_create_kernel(void **ptr_kernel, void *ptr_program, char *name) { program *prg = static_cast<program*>(ptr_program); C_HANDLE_ERROR( - *ptr_kernel = new kernel(*prg, name); + *ptr_kernel = new kernel(*prg, name); ) - return 0; + return 0; } ::error *kernel__get_info(void *ptr_kernel, cl_kernel_info param, generic_info *out) { C_HANDLE_ERROR( - *out = static_cast<kernel*>(ptr_kernel)->get_info(param); + *out = static_cast<kernel*>(ptr_kernel)->get_info(param); ) - return 0; + return 0; } ::error *kernel__set_arg_mem_buffer(void *ptr_kernel, cl_uint arg_index, void *ptr_buffer) { buffer *buf = static_cast<buffer*>(ptr_buffer); C_HANDLE_ERROR( - static_cast<kernel*>(ptr_kernel)->set_arg_mem(arg_index, *buf); + static_cast<kernel*>(ptr_kernel)->set_arg_mem(arg_index, *buf); ) - return 0; + return 0; } ::error *_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) { C_HANDLE_ERROR( - *ptr_event = enqueue_nd_range_kernel(*static_cast<command_queue*>(ptr_command_queue), - *static_cast<kernel*>(ptr_kernel), - work_dim, - global_work_offset, - global_work_size, - local_work_size); + *ptr_event = enqueue_nd_range_kernel(*static_cast<command_queue*>(ptr_command_queue), + *static_cast<kernel*>(ptr_kernel), + work_dim, + global_work_offset, + global_work_size, + local_work_size); ) - return 0; + return 0; } ::error *_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) { C_HANDLE_ERROR( - *ptr_event = enqueue_read_buffer(*static_cast<command_queue*>(ptr_command_queue), - *static_cast<memory_object_holder*>(ptr_memory_object_holder), - buffer, size, device_offset, (bool)is_blocking); + *ptr_event = enqueue_read_buffer(*static_cast<command_queue*>(ptr_command_queue), + *static_cast<memory_object_holder*>(ptr_memory_object_holder), + buffer, size, device_offset, (bool)is_blocking); ) - return 0; + 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); - ) - 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); + ) + return 0; + } + + intptr_t _int_ptr(void* ptr, class_t class_) { +#define INT_PTR(CLSU, CLS) return (intptr_t)(static_cast<CLS*>(ptr)->data()); + SWITCHCLASS(INT_PTR); } + void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t class_) { +#define FROM_INT_PTR(CLSU, CLS) C_HANDLE_ERROR(*ptr_out = new CLS((PYOPENCL_CL_##CLSU)int_ptr_value, /* retain */ true);) + SWITCHCLASS(FROM_INT_PTR); + return 0; + } + + long _hash(void *ptr, class_t class_) { +#define HASH(CLSU, CLS) return static_cast<CLS*>(ptr)->hash(); + SWITCHCLASS(HASH); + } + -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 dad61b49..b51b9537 100644 --- a/src/c_wrapper/wrap_cl_core.h +++ b/src/c_wrapper/wrap_cl_core.h @@ -31,16 +31,22 @@ typedef struct { cl_int code; } error; +typedef enum { + CLASS_PLATFORM, + CLASS_DEVICE, + CLASS_KERNEL, + CLASS_CONTEXT, + CLASS_BUFFER, + CLASS_PROGRAM, + CLASS_EVENT, + CLASS_COMMAND_QUEUE +} class_t; + int get_cl_version(void); error *get_platforms(void **ptr_platforms, uint32_t *num_platforms); error *platform__get_info(void *ptr_platform, cl_platform_info param_name, generic_info *out); error *platform__get_devices(void *ptr_platform, void **ptr_devices, uint32_t *num_devices, cl_device_type devtype); -long platform__hash(void *ptr_platform); error *device__get_info(void *ptr_device, cl_device_info param_name, generic_info *out); -long device__hash(void *ptr_device); -long context__hash(void *ptr_context); -long command_queue__hash(void *ptr_command_queue); -long event__hash(void *ptr_event); error *_create_context(void **ptr_ctx, cl_context_properties *properties, cl_uint num_devices, void **ptr_devices); error *_create_command_queue(void **ptr_command_queue, void *ptr_context, void *ptr_device, cl_command_queue_properties properties); error *_create_buffer(void **ptr_buffer, void *ptr_context, cl_mem_flags flags, size_t size, void *hostbuf); @@ -52,32 +58,19 @@ error *program__get_build_info(void *ptr_program, void *ptr_device, cl_program_b error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out); error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices); error *program__get_info__binaries(void *ptr_program, char ***ptr_binaries, uint32_t *num_binaries); -long program__hash(void *ptr_program); + error *_create_kernel(void **ptr_kernel, void *ptr_program, char *name); error *kernel__get_info(void *ptr_kernel, cl_kernel_info param, generic_info *out); error *kernel__set_arg_mem_buffer(void *ptr_kernel, cl_uint arg_index, void *ptr_buffer); -long kernel__hash(void *ptr_kernel); +long _hash(void *ptr_platform, class_t); + error *_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); error *_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); 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); +intptr_t _int_ptr(void*, class_t); +void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t); void _free(void*); void _free2(void**, uint32_t size); -- GitLab