From acbdb5d1fd2bbb5912f48bf07a2623d93902e589 Mon Sep 17 00:00:00 2001 From: Jonathan Mackenzie Date: Thu, 15 Dec 2016 13:04:10 +1030 Subject: [PATCH] Fixed typos in docs, added new docs for cltypes, updated types --- doc/array.rst | 6 +-- doc/index.rst | 2 +- doc/misc.rst | 6 +-- doc/tools.rst | 2 +- doc/types.rst | 34 ++++++++++++ pyopencl/array.py | 87 +----------------------------- pyopencl/cltypes.py | 125 ++++++++++++++++++++++++++++++++++++++++++++ pyopencl/dtypes.py | 43 --------------- 8 files changed, 169 insertions(+), 136 deletions(-) create mode 100644 doc/types.rst create mode 100644 pyopencl/cltypes.py delete mode 100644 pyopencl/dtypes.py diff --git a/doc/array.rst b/doc/array.rst index 4f4b7ef6..6f35c046 100644 --- a/doc/array.rst +++ b/doc/array.rst @@ -126,7 +126,7 @@ never directly. * complex*complex * real+complex - *look* like they may do the right thing, but sliently do the wrong thing. + *look* like they may do the right thing, but silently do the wrong thing. The :class:`Array` Class ------------------------ @@ -179,8 +179,8 @@ Reductions See also :ref:`custom-reductions`. -Elementwise Functions on :class:`Arrray` Instances --------------------------------------------------- +Elementwise Functions on :class:`Array` Instances +------------------------------------------------- .. module:: pyopencl.clmath diff --git a/doc/index.rst b/doc/index.rst index ea711642..bf981109 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -45,7 +45,7 @@ Tutorials and `Tom Deakin `_'s course `Hands-on OpenCL `_ contains both `lecture slides `_ - and `excercises (with solutions) `_ + and `exercises (with solutions) `_ (The course covers PyOpenCL as well as OpenCL's C and C++ APIs.) * PyOpenCL course at `PASI `_: Parts `1 `_ diff --git a/doc/misc.rst b/doc/misc.rst index e56830df..a3d3e638 100644 --- a/doc/misc.rst +++ b/doc/misc.rst @@ -32,7 +32,7 @@ and then use the ``%%cl_kernel`` 'cell-magic' command. See `this notebook You can pass build options to be used for building the program executable by using the ``-o`` flag on the first line of the cell (next to the ``%%cl_kernel`` directive). For example: `%%cl_kernel -o "-cl-fast-relaxed-math"``. -There are also line magics: ``cl_load_edit_kernel`` which will load a file into the next cell (adding ``cl_kernel`` to the first line) and ``cl_kernel_from_file`` which will compile kernels from a file (as if you copy-and-pasted the contents of the file to a cell with ``cl_kernel``). Boths of these magics take options ``-f`` to specify the file and optionally ``-o`` for build options. +There are also line magics: ``cl_load_edit_kernel`` which will load a file into the next cell (adding ``cl_kernel`` to the first line) and ``cl_kernel_from_file`` which will compile kernels from a file (as if you copy-and-pasted the contents of the file to a cell with ``cl_kernel``). Both of these magics take options ``-f`` to specify the file and optionally ``-o`` for build options. .. versionadded:: 2014.1 @@ -164,7 +164,7 @@ Version 2015.2 * complex*complex * real+complex - *look* like they may do the right thing, but sliently do the wrong thing. + *look* like they may do the right thing, but silently do the wrong thing. * Rewrite of the wrapper layer to be based on CFFI * Pypy compatibility * Faster kernel invocation through Python launcher code generation @@ -331,7 +331,7 @@ Version 2011.1 * Add :ref:`memory-pools`. * Add vector types, see :class:`pyopencl.array.vec`. * Add :attr:`pyopencl.array.Array.strides`, :attr:`pyopencl.array.Array.flags`. - Allow the creation of arrys in C and Fortran order. + Allow the creation of arrays in C and Fortran order. * Add :func:`pyopencl.enqueue_copy`. Deprecate all other transfer functions. * Add support for numerous extensions, among them device fission. * Add a compiler cache. diff --git a/doc/tools.rst b/doc/tools.rst index 9c647b19..967b8d34 100644 --- a/doc/tools.rst +++ b/doc/tools.rst @@ -91,7 +91,7 @@ not complicated:: .. method:: __call__(size) - Synoynm for :meth:`allocate` to match :class:`CLAllocator` interface. + Synonym for :meth:`allocate` to match :class:`CLAllocator` interface. .. versionadded: 2011.2 diff --git a/doc/types.rst b/doc/types.rst new file mode 100644 index 00000000..ccc96fdd --- /dev/null +++ b/doc/types.rst @@ -0,0 +1,34 @@ +OpenCL Type Mapping +=================== + +.. module:: pyopencl.types + +.. _type-mappings: + +Scalar Types +------------ + +For ease of use, a the cltypes module provides convenient mapping from OpenCL type names +to their equivalent numpy types. This saves you from referring back to the OpenCL spec to +see that a cl_long is 64 bit unsigned integer. Use the module as follows: + +.. doctest:: + + >>> import numpy as np + >>> import pyopencl as cl + >>> import pyopencl.cltypes + >>> cl_uint = cl.cltypes.uint(42) # maps to numpy.uint32 + >>> cl_long = cl.cltypes.long(1235) # maps to numpy.int64 + >>> floats = np.empty((128,), dtype=cl.cltypes.float) # array of numpy.float32 + + +Vector Types +------------ +The corresponding vector types are also made available in the same package, allowing you to easily create +numpy arrays with the appropriate memory layout. + +.. doctest:: + + >>> import numpy as np + >>> array_of_float16 = np.empty((128,), dtype=cl.cltypes.float16) # array of float16 + diff --git a/pyopencl/array.py b/pyopencl/array.py index 479f5375..f5ad2ff7 100644 --- a/pyopencl/array.py +++ b/pyopencl/array.py @@ -42,7 +42,7 @@ from pyopencl.compyte.array import ( ArrayFlags as _ArrayFlags, get_common_dtype as _get_common_dtype_base) from pyopencl.characterize import has_double_support -from pyopencl import dtypes +from pyopencl import cltypes def _get_common_dtype(obj1, obj2, queue): return _get_common_dtype_base(obj1, obj2, @@ -61,90 +61,7 @@ except: def _dtype_is_object(t): return False - -# {{{ vector types - -class vec: # noqa - pass - - -def _create_vector_types(): - field_names = ["x", "y", "z", "w"] - - from pyopencl.tools import get_or_register_dtype - - vec.types = {} - vec.type_to_scalar_and_count = {} - - counts = [2, 3, 4, 8, 16] - - for base_name, base_type in cl.dtypes.cl2np_mapping: - for count in counts: - name = "%s%d" % (base_name, count) - - titles = field_names[:count] - - padded_count = count - if count == 3: - padded_count = 4 - - names = ["s%d" % i for i in range(count)] - while len(names) < padded_count: - names.append("padding%d" % (len(names)-count)) - - if len(titles) < len(names): - titles.extend((len(names)-len(titles))*[None]) - - try: - dtype = np.dtype(dict( - names=names, - formats=[base_type]*padded_count, - titles=titles)) - except NotImplementedError: - try: - dtype = np.dtype([((n, title), base_type) - for (n, title) in zip(names, titles)]) - except TypeError: - dtype = np.dtype([(n, base_type) for (n, title) - in zip(names, titles)]) - - get_or_register_dtype(name, dtype) - - setattr(vec, name, dtype) - - def create_array(dtype, count, padded_count, *args, **kwargs): - if len(args) < count: - from warnings import warn - warn("default values for make_xxx are deprecated;" - " instead specify all parameters or use" - " array.vec.zeros_xxx", DeprecationWarning) - padded_args = tuple(list(args)+[0]*(padded_count-len(args))) - array = eval("array(padded_args, dtype=dtype)", - dict(array=np.array, padded_args=padded_args, - dtype=dtype)) - for key, val in list(kwargs.items()): - array[key] = val - return array - - setattr(vec, "make_"+name, staticmethod(eval( - "lambda *args, **kwargs: create_array(dtype, %i, %i, " - "*args, **kwargs)" % (count, padded_count), - dict(create_array=create_array, dtype=dtype)))) - setattr(vec, "filled_"+name, staticmethod(eval( - "lambda val: vec.make_%s(*[val]*%i)" % (name, count)))) - setattr(vec, "zeros_"+name, - staticmethod(eval("lambda: vec.filled_%s(0)" % (name)))) - setattr(vec, "ones_"+name, - staticmethod(eval("lambda: vec.filled_%s(1)" % (name)))) - - vec.types[np.dtype(base_type), count] = dtype - vec.type_to_scalar_and_count[dtype] = np.dtype(base_type), count - - -_create_vector_types() - -# }}} - +vec = cltypes # {{{ helper functionality diff --git a/pyopencl/cltypes.py b/pyopencl/cltypes.py new file mode 100644 index 00000000..fc83e730 --- /dev/null +++ b/pyopencl/cltypes.py @@ -0,0 +1,125 @@ +# encoding: utf8 + +__copyright__ = "Copyright (C) 2016 Jonathan Mackenzie" + +__license__ = """ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +""" + +import numpy as __np +from pyopencl.tools import get_or_register_dtype +import warnings + +if __file__.endswith('array.py'): + warnings.warn("pyopencl.array.vec is deprecated. Please use pyopencl.cltypes") + +""" +This file provides a type mapping from OpenCl type names to their numpy equivalents +""" + +char = __np.int8 +uchar = __np.uint8 +short = __np.int16 +ushort = __np.uint16 +int = __np.int32 +uint = __np.uint32 +long = __np.int64 +ulong = __np.uint64 +float = __np.float32 +double = __np.float64 + +# {{{ vector types + + +def _create_vector_types(): + def set_global(key, val): + globals()[key] = val + field_names = ["x", "y", "z", "w"] + + set_global('types', {}) + set_global('type_to_scalar_and_count', {}) + + counts = [2, 3, 4, 8, 16] + + for base_name, base_type in [(k, v) for k, v in globals().items() if not k.startswith('__')]: + for count in counts: + name = "%s%d" % (base_name, count) + + titles = field_names[:count] + + padded_count = count + if count == 3: + padded_count = 4 + + names = ["s%d" % i for i in range(count)] + while len(names) < padded_count: + names.append("padding%d" % (len(names)-count)) + + if len(titles) < len(names): + titles.extend((len(names)-len(titles))*[None]) + + try: + dtype = __np.dtype(dict( + names=names, + formats=[base_type]*padded_count, + titles=titles)) + except NotImplementedError: + try: + dtype = __np.dtype([((n, title), base_type) + for (n, title) in zip(names, titles)]) + except TypeError: + dtype = __np.dtype([(n, base_type) for (n, title) + in zip(names, titles)]) + + get_or_register_dtype(name, dtype) + + set_global(name, dtype) + + def create_array(dtype, count, padded_count, *args, **kwargs): + if len(args) < count: + from warnings import warn + warn("default values for make_xxx are deprecated;" + " instead specify all parameters or use" + " array.vec.zeros_xxx", DeprecationWarning) + padded_args = tuple(list(args)+[0]*(padded_count-len(args))) + array = eval("array(padded_args, dtype=dtype)", + dict(array=__np.array, padded_args=padded_args, + dtype=dtype)) + for key, val in list(kwargs.items()): + array[key] = val + return array + + set_global("make_"+name, staticmethod(eval( + "lambda *args, **kwargs: create_array(dtype, %i, %i, " + "*args, **kwargs)" % (count, padded_count), + dict(create_array=create_array, dtype=dtype)))) + set_global("filled_"+name, staticmethod(eval( + "lambda val: vec.make_%s(*[val]*%i)" % (name, count)))) + set_global("zeros_"+name, + staticmethod(eval("lambda: vec.filled_%s(0)" % (name)))) + set_global("ones_"+name, + staticmethod(eval("lambda: vec.filled_%s(1)" % (name)))) + + globals()['types'][__np.dtype(base_type), count] = dtype + globals()['type_to_scalar_and_count'][dtype] = __np.dtype(base_type), count + + +# }}} + + +half = __np.float16 + diff --git a/pyopencl/dtypes.py b/pyopencl/dtypes.py deleted file mode 100644 index b7f32a55..00000000 --- a/pyopencl/dtypes.py +++ /dev/null @@ -1,43 +0,0 @@ -# encoding: utf8 -import numpy as __np - -__copyright__ = "Copyright (C) 2016 Jonathan Mackenzie" - -__license__ = """ -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -""" - -""" -This file provides a type mapping from OpenCl type names to their numpy equivalents -""" - -char = __np.int8 -uchar = __np.uint8 -short = __np.int16 -ushort = __np.uint16 -int = __np.int32 -uint = __np.uint32 -long = __np.int64 -ulong = __np.uint64 -float = __np.float32 -double = __np.float64 - -# {{{ cl -> np type mapping -cl2np_mapping = [ - (k, v) for k, v in globals().items() if not k.startswith('__') - ] -# }}} \ No newline at end of file -- GitLab