diff --git a/doc/make_constants.py b/doc/make_constants.py index 91ce242a15689f8ca94d981b422d3b9b6983a105..07d140d93f6e4347a5343ecdd584ffd231172d18 100644 --- a/doc/make_constants.py +++ b/doc/make_constants.py @@ -1,24 +1,113 @@ import pyopencl as cl +devi = cl.device_info +ctxi = cl.context_info ctxp = cl.context_properties gl_ci = cl.gl_context_info -ext_lookup = { +fpc = cl.device_fp_config +cho = cl.channel_order +wgi = cl.kernel_work_group_info +iam = cl.addressing_mode +evi = cl.event_info +memi = cl.mem_info +ctype = cl.command_type + +def get_extra_lines(tup): + ext_name, pyopencl_ver = tup + if ext_name is not None: + if ext_name.startswith("CL_"): + # capital letters -> CL version, not extension + yield "" + yield " Available with OpenCL %s." % ( + ext_name[3:]) + yield "" + + else: + yield "" + yield " Available with the ``%s`` extension." % ext_name + yield "" + + if pyopencl_ver is not None: + yield "" + yield " .. versionadded:: %s" % pyopencl_ver + yield "" + + +const_ext_lookup = { + devi: { + devi.PREFERRED_VECTOR_WIDTH_HALF: ("CL_1.1", "0.92"), + devi.HOST_UNIFIED_MEMORY: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_CHAR: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_SHORT: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_INT: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_LONG: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_FLOAT: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_DOUBLE: ("CL_1.1", "0.92"), + devi.NATIVE_VECTOR_WIDTH_HALF: ("CL_1.1", "0.92"), + devi.OPENCL_C_VERSION: ("CL_1.1", "0.92"), + }, + ctxp: { - ctxp.GL_CONTEXT_KHR: "cl_khr_gl_sharing", - ctxp.EGL_DISPLAY_KHR: "cl_khr_gl_sharing", - ctxp.GLX_DISPLAY_KHR: "cl_khr_gl_sharing", - ctxp.WGL_HDC_KHR: "cl_khr_gl_sharing", - ctxp.CGL_SHAREGROUP_KHR: "cl_khr_gl_sharing", + ctxp.GL_CONTEXT_KHR: ("cl_khr_gl_sharing", "0.92"), + ctxp.EGL_DISPLAY_KHR: ("cl_khr_gl_sharing", "0.92"), + ctxp.GLX_DISPLAY_KHR: ("cl_khr_gl_sharing", "0.92"), + ctxp.WGL_HDC_KHR: ("cl_khr_gl_sharing", "0.92"), + ctxp.CGL_SHAREGROUP_KHR: ("cl_khr_gl_sharing", "0.92"), }, + gl_ci: { gl_ci.CURRENT_DEVICE_FOR_GL_CONTEXT_KHR: - "cl_khr_gl_sharing", + ("cl_khr_gl_sharing", "0.92"), gl_ci.DEVICES_FOR_GL_CONTEXT_KHR: - "cl_khr_gl_sharing", - } + ("cl_khr_gl_sharing", "0.92"), + }, + + fpc: { + fpc.SOFT_FLOAT: ("CL_1.1", "0.92"), + }, + + ctxi: { + ctxi.NUM_DEVICES: ("CL_1.1", "0.92"), + }, + + cho: { + cho.Rx: ("CL_1.1", "0.92"), + cho.RGx: ("CL_1.1", "0.92"), + cho.RGBx: ("CL_1.1", "0.92"), + }, + + wgi: { + wgi.PREFERRED_WORK_GROUP_SIZE_MULTIPLE: ("CL_1.1", "0.92"), + wgi.PRIVATE_MEM_SIZE: ("CL_1.1", "0.92"), + }, + + iam: { + iam.MIRRORED_REPEAT: ("CL_1.1", "0.92"), + }, + + evi: { + evi.CONTEXT: ("CL_1.1", "0.92"), + }, + + memi: { + memi.ASSOCIATED_MEMOBJECT: ("CL_1.1", "0.92"), + memi.OFFSET: ("CL_1.1", "0.92"), + }, + + ctype: { + ctype.READ_BUFFER_RECT: ("CL_1.1", "0.92"), + ctype.WRITE_BUFFER_RECT: ("CL_1.1", "0.92"), + ctype.COPY_BUFFER_RECT: ("CL_1.1", "0.92"), + ctype.USER: ("CL_1.1", "0.92"), + }, } +cls_ext_lookup = { + cl.buffer_create_type: ("CL_1.1", "0.92"), + } + + def doc_class(cls): print ".. class :: %s" % cls.__name__ print @@ -26,17 +115,19 @@ def doc_class(cls): print " Only available when PyOpenCL is compiled with GL support. See :func:`have_gl`." print - cls_ext = ext_lookup.get(cls, {}) + if cls in cls_ext_lookup: + for l in get_extra_lines(cls_ext_lookup[cls]): + print l + + cls_const_ext = const_ext_lookup.get(cls, {}) for i in sorted(dir(cls)): if not i.startswith("_") and not i == "to_string": print " .. attribute :: %s" % i value = getattr(cls, i) - if value in cls_ext: - print - print " Available with the ``%s`` extension." % ( - cls_ext[value]) - print + if value in cls_const_ext: + for l in get_extra_lines(cls_const_ext[value]): + print " "+l print " .. method :: to_string(value)" print diff --git a/doc/source/misc.rst b/doc/source/misc.rst index 2cb720d63e85f76a931c86fc51bbc8f13c7cc90f..9165d474224b7ec034f08bb1ee172e3af1373b8c 100644 --- a/doc/source/misc.rst +++ b/doc/source/misc.rst @@ -71,8 +71,9 @@ Version 0.92 Version 0.92 is currently under development. You can get snapshots from PyOpenCL's git version control. +* Add support for OpenCL 1.1. * Add support for the - `cl_khr_gl_sharin <ghttp://www.khronos.org/registry/cl/extensions/khr/cl_khr_gl_sharing.txt>`_ + `cl_khr_gl_sharing <ghttp://www.khronos.org/registry/cl/extensions/khr/cl_khr_gl_sharing.txt>`_ extension. Version 0.91.5 diff --git a/doc/source/reference.rst b/doc/source/reference.rst index 4c571896dfd7f0b98e9a39430d93e5e257e6cec2..349c6e06cb9eababa3a89afeca19a2e9f2742f50 100644 --- a/doc/source/reference.rst +++ b/doc/source/reference.rst @@ -11,7 +11,7 @@ Version Queries .. data:: VERSION - Gives the numeric version of PyCUDA as a variable-length tuple + Gives the numeric version of PyOpenCL as a variable-length tuple of integers. Enables easy version checks such as *VERSION >= (0, 93)*. @@ -24,6 +24,14 @@ Version Queries The full release name (such as `"0.93rc4"`) in string form. +.. function:: get_cl_header_version() + + Return a variable-length tuple of integers representing the + version of the OpenCL header against which PyOpenCL was + compiled. + + .. versionadded:: 0.92 + .. _errors: Error Reporting @@ -161,6 +169,8 @@ Command Queues and Events See :class:`command_queue_properties` for possible values of *prop*. *enable* is a :class:`bool`. + Unavailable in OpenCL 1.1 and newer. + .. method:: flush() .. method:: finish() diff --git a/pyopencl/version.py b/pyopencl/version.py index 87a3d294d62098126bac969831ec8c1225aa5ce0..107a527b90bf16dc012fb6c50b621fbe18b6867c 100644 --- a/pyopencl/version.py +++ b/pyopencl/version.py @@ -1,5 +1,5 @@ -VERSION = (0, 91, 5) -VERSION_STATUS = "" +VERSION = (0, 92) +VERSION_STATUS = "beta" VERSION_TEXT = ".".join(str(x) for x in VERSION) + VERSION_STATUS diff --git a/src/wrapper/wrap_cl.cpp b/src/wrapper/wrap_cl.cpp index 161bc16b553a98511607a1a35d74fc2c968c5bfe..1d37a053987957676807043cf545393791937083 100644 --- a/src/wrapper/wrap_cl.cpp +++ b/src/wrapper/wrap_cl.cpp @@ -66,6 +66,7 @@ namespace class command_type { }; class command_execution_status { }; class profiling_info { }; + class buffer_create_type { }; class gl_object_type { }; class gl_texture_info { }; @@ -171,6 +172,16 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(DEVICE_, VERSION); ADD_ATTR(DEVICE_, EXTENSIONS); ADD_ATTR(DEVICE_, PLATFORM); + ADD_ATTR(DEVICE_, PREFERRED_VECTOR_WIDTH_HALF); + ADD_ATTR(DEVICE_, HOST_UNIFIED_MEMORY); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_CHAR); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_SHORT); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_INT); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_LONG); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_FLOAT); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_DOUBLE); + ADD_ATTR(DEVICE_, NATIVE_VECTOR_WIDTH_HALF); + ADD_ATTR(DEVICE_, OPENCL_C_VERSION); } { @@ -181,6 +192,9 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(FP_, ROUND_TO_ZERO); ADD_ATTR(FP_, ROUND_TO_INF); ADD_ATTR(FP_, FMA); +#ifdef CL_VERSION_1_1 + ADD_ATTR(FP_, SOFT_FLOAT); +#endif } { @@ -213,6 +227,9 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(CONTEXT_, REFERENCE_COUNT); ADD_ATTR(CONTEXT_, DEVICES); ADD_ATTR(CONTEXT_, PROPERTIES); +#ifdef CL_VERSION_1_1 + ADD_ATTR(CONTEXT_, NUM_DEVICES); +#endif } { @@ -264,6 +281,11 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR( , BGRA); ADD_ATTR( , INTENSITY); ADD_ATTR( , LUMINANCE); +#ifdef CL_VERSION_1_1 + ADD_ATTR( , Rx); + ADD_ATTR( , RGx); + ADD_ATTR( , RGBx); +#endif } { @@ -301,6 +323,10 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(MEM_, MAP_COUNT); ADD_ATTR(MEM_, REFERENCE_COUNT); ADD_ATTR(MEM_, CONTEXT); +#ifdef CL_VERSION_1_1 + ADD_ATTR(MEM_, ASSOCIATED_MEMOBJECT); + ADD_ATTR(MEM_, OFFSET); +#endif } { @@ -320,6 +346,9 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(ADDRESS_, CLAMP_TO_EDGE); ADD_ATTR(ADDRESS_, CLAMP); ADD_ATTR(ADDRESS_, REPEAT); +#ifdef CL_VERSION_1_1 + ADD_ATTR(ADDRESS_, MIRRORED_REPEAT); +#endif } { @@ -375,6 +404,10 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(KERNEL_, WORK_GROUP_SIZE); ADD_ATTR(KERNEL_, COMPILE_WORK_GROUP_SIZE); ADD_ATTR(KERNEL_, LOCAL_MEM_SIZE); +#ifdef CL_VERSION_1_1 + ADD_ATTR(KERNEL_, PREFERRED_WORK_GROUP_SIZE_MULTIPLE); + ADD_ATTR(KERNEL_, PRIVATE_MEM_SIZE); +#endif } { @@ -383,6 +416,9 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(EVENT_, COMMAND_TYPE); ADD_ATTR(EVENT_, REFERENCE_COUNT); ADD_ATTR(EVENT_, COMMAND_EXECUTION_STATUS); +#ifdef CL_VERSION_1_1 + ADD_ATTR(EVENT_, CONTEXT); +#endif } { @@ -404,6 +440,12 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(COMMAND_, MARKER); ADD_ATTR(COMMAND_, ACQUIRE_GL_OBJECTS); ADD_ATTR(COMMAND_, RELEASE_GL_OBJECTS); +#ifdef CL_VERSION_1_1 + ADD_ATTR(COMMAND_, READ_BUFFER_RECT); + ADD_ATTR(COMMAND_, WRITE_BUFFER_RECT); + ADD_ATTR(COMMAND_, COPY_BUFFER_RECT); + ADD_ATTR(COMMAND_, USER); +#endif } { @@ -422,8 +464,17 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(PROFILING_COMMAND_, END); } +#ifdef CL_VERSION_1_1 + { + py::class_<buffer_create_type> cls("buffer_create_type", py::no_init); + ADD_ATTR(BUFFER_CREATE_TYPE_, REGION); + } +#endif + // }}} + py::def("get_cl_header_version", get_cl_header_version); + // {{{ platform DEF_SIMPLE_FUNCTION(get_platforms); @@ -482,7 +533,9 @@ BOOST_PYTHON_MODULE(_cl) const device *, cl_command_queue_properties> ((py::arg("context"), py::arg("device")=py::object(), py::arg("properties")=0))) .DEF_SIMPLE_METHOD(get_info) +#ifndef CL_VERSION_1_1 .DEF_SIMPLE_METHOD(set_property) +#endif .DEF_SIMPLE_METHOD(flush) .DEF_SIMPLE_METHOD(finish) .add_property("obj_ptr", &cls::obj_ptr) diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp index c9fb1eba9a11d5f6c546194305a0e6378b990e01..0dc5edf354b42139005f92bbfaa4ff4cd443f9da 100644 --- a/src/wrapper/wrap_cl.hpp +++ b/src/wrapper/wrap_cl.hpp @@ -316,13 +316,28 @@ namespace pyopencl case CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR: return "invalid gl sharegroup reference number"; #endif - default: return "invalid error code"; +#ifdef CL_VERSION_1_1 + case CL_MISALIGNED_SUB_BUFFER_OFFSET: return "misaligned sub-buffer offset"; + case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: return "exec status error for events in wait list"; + case CL_INVALID_GLOBAL_WORK_SIZE: return "invalid global work size"; +#endif + + default: return "invalid/unknown error code"; } } }; // }}} + py::tuple get_cl_header_version() + { +#if defined(CL_VERSION_1_1) + return py::make_tuple(1, 1); +#else + return py::make_tuple(1, 0); +#endif + } + // {{{ platform class platform : boost::noncopyable { @@ -446,6 +461,7 @@ namespace pyopencl case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: DEV_GET_INT_INF(cl_uint); case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: DEV_GET_INT_INF(cl_uint); case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_MAX_CLOCK_FREQUENCY: DEV_GET_INT_INF(cl_uint); case CL_DEVICE_ADDRESS_BITS: DEV_GET_INT_INF(cl_uint); case CL_DEVICE_MAX_READ_IMAGE_ARGS: DEV_GET_INT_INF(cl_uint); @@ -491,6 +507,22 @@ namespace pyopencl case CL_DEVICE_PLATFORM: PYOPENCL_GET_OPAQUE_INFO(Device, m_device, param_name, cl_platform_id, platform); +#ifdef CL_VERSION_1_1 + case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: DEV_GET_INT_INF(cl_uint); + + case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE: DEV_GET_INT_INF(cl_uint); + case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF: DEV_GET_INT_INF(cl_uint); + + case CL_DEVICE_HOST_UNIFIED_MEMORY: DEV_GET_INT_INF(cl_bool); + case CL_DEVICE_OPENCL_C_VERSION: + PYOPENCL_GET_STR_INFO(Device, m_device, param_name); +#endif + default: throw error("Platform.get_info", CL_INVALID_VALUE); } @@ -613,6 +645,12 @@ namespace pyopencl return py_result; } +#ifdef CL_VERSION_1_1 + case CL_CONTEXT_NUM_DEVICES: + PYOPENCL_GET_INTEGRAL_INFO( + Context, m_context, param_name, cl_uint); +#endif + default: throw error("Context.get_info", CL_INVALID_VALUE); } @@ -811,6 +849,7 @@ namespace pyopencl } } +#ifndef CL_VERSION_1_1 cl_command_queue_properties set_property( cl_command_queue_properties prop, bool enable) @@ -820,6 +859,7 @@ namespace pyopencl (m_queue, prop, PYOPENCL_CAST_BOOL(enable), &old_prop)); return old_prop; } +#endif void flush() { PYOPENCL_CALL_GUARDED(clFlush, (m_queue)); } @@ -879,6 +919,11 @@ namespace pyopencl case CL_EVENT_REFERENCE_COUNT: PYOPENCL_GET_INTEGRAL_INFO(Event, m_event, param_name, cl_uint); +#ifdef CL_VERSION_1_1 + 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); @@ -1017,35 +1062,7 @@ namespace pyopencl return param_value; } - py::object get_info(cl_mem_info param_name) const - { - switch (param_name) - { - case CL_MEM_TYPE: - PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, - cl_mem_object_type); - case CL_MEM_FLAGS: - PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, - cl_mem_flags); - case CL_MEM_SIZE: - PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, - size_t); - case CL_MEM_HOST_PTR: - return m_hostbuf; - case CL_MEM_MAP_COUNT: - PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, - cl_uint); - case CL_MEM_REFERENCE_COUNT: - PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, - cl_uint); - case CL_MEM_CONTEXT: - PYOPENCL_GET_OPAQUE_INFO(MemObject, m_mem, param_name, - cl_context, context); - - default: - throw error("MemoryObject.get_info", CL_INVALID_VALUE); - } - } + py::object get_info(cl_mem_info param_name) const; }; @@ -2271,9 +2288,19 @@ namespace pyopencl return py::list(result); } case CL_KERNEL_LOCAL_MEM_SIZE: +#ifdef CL_VERSION_1_1 + case CL_KERNEL_PRIVATE_MEM_SIZE: +#endif PYOPENCL_GET_INTEGRAL_INFO(KernelWorkGroup, PYOPENCL_FIRST_ARG, param_name, cl_ulong); + +#ifdef CL_VERSION_1_1 + 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 @@ -2610,6 +2637,70 @@ namespace pyopencl #endif // }}} + + // {{{ deferred implementation bits + + inline + py::object memory_object::get_info(cl_mem_info param_name) const + { + switch (param_name) + { + case CL_MEM_TYPE: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + cl_mem_object_type); + case CL_MEM_FLAGS: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + cl_mem_flags); + case CL_MEM_SIZE: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + size_t); + case CL_MEM_HOST_PTR: + return m_hostbuf; + case CL_MEM_MAP_COUNT: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + cl_uint); + case CL_MEM_REFERENCE_COUNT: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + cl_uint); + case CL_MEM_CONTEXT: + PYOPENCL_GET_OPAQUE_INFO(MemObject, m_mem, param_name, + cl_context, context); + +#ifdef CL_VERSION_1_1 + case CL_MEM_ASSOCIATED_MEMOBJECT: + { + cl_mem param_value; + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, \ + (m_mem, param_name, sizeof(param_value), ¶m_value, 0)); + cl_mem_object_type mem_obj_type; + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, \ + (m_mem, CL_MEM_TYPE, sizeof(mem_obj_type), &mem_obj_type, 0)); + + switch (mem_obj_type) + { + case CL_MEM_OBJECT_BUFFER: + return py::object(handle_from_new_ptr( + new buffer(param_value, /*retain*/ true))); + case CL_MEM_OBJECT_IMAGE2D: + case CL_MEM_OBJECT_IMAGE3D: + return py::object(handle_from_new_ptr( + new image(param_value, /*retain*/ true))); + default: + return py::object(handle_from_new_ptr( + new memory_object(param_value, /*retain*/ true))); + } + } + case CL_MEM_OFFSET: + PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name, + size_t); +#endif + + default: + throw error("MemoryObject.get_info", CL_INVALID_VALUE); + } + } + + // }}} }