diff --git a/pyopencl/array.py b/pyopencl/array.py index 7f955687f8937c16de2066aaef526aaf3ecaf45a..0bede1e689ece1f1208d8aedf4639f3193a59cf6 100644 --- a/pyopencl/array.py +++ b/pyopencl/array.py @@ -1573,7 +1573,7 @@ def arange(queue, *args, **kwargs): # }}} -# {{{ take/put +# {{{ take/put/concatenate/diff @elwise_kernel_runner def _take(result, ary, indices): @@ -1840,6 +1840,29 @@ def concatenate(arrays, axis=0, queue=None, allocator=None): return result + +@elwise_kernel_runner +def _diff(result, array): + return elementwise.get_diff_kernel(array.context, array.dtype) + + +def diff(array, queue=None, allocator=None): + """ + .. versionadded:: 2013.2 + """ + + if len(array.shape) != 1: + raise ValueError("multi-D arrays are not supported") + + n, = array.shape + + queue = queue or array.queue + allocator = allocator or array.allocator + + result = empty(queue, (n-1,), array.dtype, allocator=allocator) + _diff(result, array, queue=queue) + return result + # }}} @@ -1864,7 +1887,7 @@ def if_positive(criterion, then_, else_, out=None, queue=None): if out is None: out = empty_like(then_) - _if_positive(out, criterion, then_, else_) + _if_positive(out, criterion, then_, else_, queue=queue) return out diff --git a/pyopencl/elementwise.py b/pyopencl/elementwise.py index 8d6941d5c9847abb804e2b806362e74643fbd457..5878b89cf9b557c2c65bb2b9e061b5cd29813f74 100644 --- a/pyopencl/elementwise.py +++ b/pyopencl/elementwise.py @@ -883,6 +883,16 @@ def get_binary_func_kernel(context, func_name, x_dtype, y_dtype, out_dtype): name="%s_kernel" % func_name) +@context_dependent_memoize +def get_diff_kernel(context, dtype): + return get_elwise_kernel(context, [ + VectorArg(dtype, "result", with_offset=True), + VectorArg(dtype, "array", with_offset=True), + ], + "result[i] = array[i+1] - array[i]", + name="diff") + + @context_dependent_memoize def get_if_positive_kernel(context, crit_dtype, dtype): return get_elwise_kernel(context, [ diff --git a/test/test_array.py b/test/test_array.py index e3258fb9ae01751f93d438b52d039885013b7ecd..3125ac69a1d8d3cb8619f77518ba8df7c37140dd 100644 --- a/test/test_array.py +++ b/test/test_array.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division __copyright__ = "Copyright (C) 2009 Andreas Kloeckner" @@ -528,6 +529,21 @@ def test_view(ctx_factory): view = a_dev.view(np.int16) assert view.shape == (8, 32) and view.dtype == np.int16 + +def test_diff(ctx_factory): + context = ctx_factory() + queue = cl.CommandQueue(context) + + from pyopencl.clrandom import rand as clrand + + l = 20000 + a_dev = clrand(queue, (l,), dtype=np.float32) + a = a_dev.get() + + err = la.norm( + (cl.array.diff(a_dev).get() - np.diff(a))) + assert err < 1e-4 + # }}}