diff --git a/doc/array.rst b/doc/array.rst
index 2be1742f3fbf0d407b9f11114aa441fe89a7853d..8c83e6663f007560a744953e0439a875981e56ea 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 ea711642adb2212675014f429643b87c79768513..bf981109164d3a16f1edc83ccd5f20b7181dc674 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 e56830df8fa3f90dafe805b82f5e90adfaab7b4e..a3d3e638c2060834002bcb3b12f9fe1760263219 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/runtime_memory.rst b/doc/runtime_memory.rst
index e3312973ddd85aeabd55b48728ab6df8c3c04f49..f23a29ae4912173f1019b15fc53cc629fd78ab2f 100644
--- a/doc/runtime_memory.rst
+++ b/doc/runtime_memory.rst
@@ -96,7 +96,10 @@ Buffer
.. function:: enqueue_fill_buffer(queue, mem, pattern, offset, size, wait_for=None)
- :arg pattern: a buffer object (likely a :class:`numpy.ndarray`)
+ :arg mem: the on device :class:`Buffer`
+ :arg pattern: a buffer object (likely a :class:`numpy.ndarray`, eg. `np.uint32(0)`)
+
+ Fills a buffer with the provided pattern
|std-enqueue-blurb|
@@ -104,6 +107,16 @@ Buffer
.. versionadded:: 2011.2
+.. function:: enqueue_copy_buffer(queue, src, dst, byte_count=-1, src_offset=0, dst_offset=0, wait_for=None)
+
+ :arg src: the source :class:`Buffer`
+ :arg dst: the destination device :class:`Buffer`
+ :arg byte_count: the number of bytes to copy
+
+ Performs a device to device copy from `src` to `dst`.
+
+ |std-enqueue-blurb|
+
.. _svm:
Shared Virtual Memory (SVM)
diff --git a/doc/tools.rst b/doc/tools.rst
index 9c647b1992c6337cc58d73ec24d13e4ecb6a18af..967b8d34303f5fb6fbb86a697e3152baefd7d18b 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 0000000000000000000000000000000000000000..ccc96fdd355737bc90e6ec1112b876ba30f1e7cb
--- /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 f3957bb0f981fd59a176b4408609c9fa5695a1c2..f40cfbbcd65d27f776f1fd60e2c37d79d431f516 100644
--- a/pyopencl/array.py
+++ b/pyopencl/array.py
@@ -28,7 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
"""
import six
-from six.moves import range, zip, reduce
+from six.moves import range, reduce
import numpy as np
import pyopencl.elementwise as elementwise
@@ -42,11 +42,12 @@ 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 cltypes
def _get_common_dtype(obj1, obj2, queue):
return _get_common_dtype_base(obj1, obj2,
- has_double_support(queue.device))
+ has_double_support(queue.device))
# Work around PyPy not currently supporting the object dtype.
@@ -62,103 +63,20 @@ except:
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 [
- ('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),
- ]:
- 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()
+class VecLookupWarner(object):
+ def __getattr__(self, name):
+ from warnings import warn
+ warn("pyopencl.array.vec is deprecated. "
+ "Please use pyopencl.cltypes for OpenCL vector and scalar types",
+ DeprecationWarning, 2)
+ return getattr(cltypes, name)
-# }}}
+vec = VecLookupWarner()
# {{{ helper functionality
+
def splay(queue, n, kernel_specific_max_wg_size=None):
dev = queue.device
max_work_items = _builtin_min(128, dev.max_work_group_size)
diff --git a/pyopencl/cltypes.py b/pyopencl/cltypes.py
new file mode 100644
index 0000000000000000000000000000000000000000..c8ff35c378bd1eb395e54dc0efa5ce6a21ff9b85
--- /dev/null
+++ b/pyopencl/cltypes.py
@@ -0,0 +1,127 @@
+# 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
+half = np.float16
+float = np.float32
+double = np.float64
+
+
+# {{{ vector types
+
+
+def _create_vector_types():
+ _mapping = [(k, globals()[k]) for k in
+ ['char', 'uchar', 'short', 'ushort', 'int',
+ 'uint', 'long', 'ulong', 'float', 'double']]
+
+ 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 _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)
+
+ 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"
+ " cltypes.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, 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, eval(
+ "lambda val: make_%s(*[val]*%i)" % (name, count)))
+ set_global("zeros_" + name, eval("lambda: filled_%s(0)" % (name)))
+ set_global("ones_" + name, eval("lambda: filled_%s(1)" % (name)))
+
+ globals()['types'][np.dtype(base_type), count] = dtype
+ globals()['type_to_scalar_and_count'][dtype] = np.dtype(base_type), count
+
+
+_create_vector_types()
+# }}}