diff --git a/doc/source/array.rst b/doc/source/array.rst index d747369c6489552561cc5a905d0a659aaacb8e76..cf0f080c70c5fa2e0a1d203d3dad842b67fbdf50 100644 --- a/doc/source/array.rst +++ b/doc/source/array.rst @@ -14,6 +14,8 @@ type system, as represented by :class:`numpy.dtype`, and the types available in OpenCL. All the simple scalar types map straightforwardly to their CL counterparts. +.. _vector-types: + Vector Types ^^^^^^^^^^^^ diff --git a/doc/source/runtime.rst b/doc/source/runtime.rst index a872fc1996302f0f6cf997b7d9d1d9637fffaf0d..f3f84867f71ec4fae91a6f9518c4206dff21194d 100644 --- a/doc/source/runtime.rst +++ b/doc/source/runtime.rst @@ -480,11 +480,13 @@ Images |comparable| -.. function:: image_from_array(ctx, ary, num_channels, mode="r", norm_int=False) +.. function:: image_from_array(ctx, ary, num_channels=None, mode="r", norm_int=False) Build a 2D or 3D :class:`Image` from the :class:`numpy.ndarray` *ary*. If *num_channels* is greater than one, the last dimension of *ary* must be - identical to *num_channels*. *ary* must be in C order. + identical to *num_channels*. *ary* must be in C order. If *num_channels* is + not given, it defaults to 1 for scalar types and the number of entries + for :ref:`vector-types`. The :class:`ImageFormat` is chosen as the first *num_channels* components of "RGBA". @@ -497,6 +499,9 @@ Images in the reverse order from what they would be when accessing *ary* from Python. + If *norm_int* is `True`, then the integer values are normalized to a floating + point scale of 0..1 when read. + .. versionadded:: 2011.2 .. function:: enqueue_fill_image(queue, mem, color, origin, region, wait_for=None) diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py index 95e9283c92473e9dbc1e842a926a4e9015007b78..70c5640946fbfcf1f0f25a02bb881e9bbec20d12 100644 --- a/pyopencl/__init__.py +++ b/pyopencl/__init__.py @@ -882,13 +882,24 @@ DTYPE_TO_CHANNEL_TYPE_NORM = { np.dtype(np.uint8): channel_type.UNORM_INT8, } -def image_from_array(ctx, ary, num_channels, mode="r", norm_int=False): - # FIXME what about vector types? - +def image_from_array(ctx, ary, num_channels=None, mode="r", norm_int=False): if not ary.flags.c_contiguous: raise ValueError("array must be C-contiguous") - if num_channels == 1: + dtype = ary.dtype + if num_channels is None: + + from pyopencl.array import vec + try: + dtype, num_channels = vec.type_to_scalar_and_count[dtype] + except KeyError: + # It must be a scalar type then. + pass + + shape = ary.shape + strides = ary.strides + + elif num_channels == 1: shape = ary.shape strides = ary.strides else: @@ -915,9 +926,9 @@ def image_from_array(ctx, ary, num_channels, mode="r", norm_int=False): assert ary.strides[-1] == ary.dtype.itemsize if norm_int: - channel_type = DTYPE_TO_CHANNEL_TYPE_NORM[ary.dtype] + channel_type = DTYPE_TO_CHANNEL_TYPE_NORM[dtype] else: - channel_type = DTYPE_TO_CHANNEL_TYPE[ary.dtype] + channel_type = DTYPE_TO_CHANNEL_TYPE[dtype] return Image(ctx, mode_flags | mem_flags.COPY_HOST_PTR, ImageFormat(img_format, channel_type), diff --git a/pyopencl/array.py b/pyopencl/array.py index 9e487988753ed20010c80aa00d721c3b82a51129..fd40e16cddc61b47388032964b9f604649bb54c6 100644 --- a/pyopencl/array.py +++ b/pyopencl/array.py @@ -62,7 +62,10 @@ def _create_vector_types(): 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), @@ -101,6 +104,7 @@ def _create_vector_types(): dict(array=np.array, my_dtype=dtype)))) vec.types[np.dtype(base_type), count] = dtype + vec.type_to_scalar_and_count[dtype] = np.dtype(base_type), count _create_vector_types()