From cc8b9ab3d75bb7436242d47b0478aa35798332b0 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Sun, 23 Sep 2012 10:54:43 -0500 Subject: [PATCH] Make image_from_array() support vector types. --- doc/source/array.rst | 2 ++ doc/source/runtime.rst | 9 +++++++-- pyopencl/__init__.py | 23 +++++++++++++++++------ pyopencl/array.py | 4 ++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/doc/source/array.rst b/doc/source/array.rst index d747369c..cf0f080c 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 a872fc19..f3f84867 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 95e9283c..70c56409 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 9e487988..fd40e16c 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() -- GitLab