예제 #1
0
 def wrapper(a, axis=None, dtype=None, keepdims=False):
     if not isinstance(axis, tuple):
         axis = (axis,)
     if axis[0] is None:
         # Special case for speed
         a_flat = a.flat
         s = func(a_flat, a_flat.d_array, pu.c2f(a_flat.shape, 0))
         if keepdims:
             shape = (1,)*a.ndim
         else:
             shape = ()
         ret = afnumpy.ndarray(tuple(shape), dtype=pu.typemap(s.dtype()),
                               af_array=s)
     else:
         shape = list(a.shape)
         s = a.d_array
         # Do in decreasing axis order to avoid problems with the pop
         for ax in sorted(axis)[::-1]:
             # Optimization
             if(a.shape[ax] > 1):
                 s = func(a, s, pu.c2f(a.shape, ax))
             if keepdims:
                 shape[ax] = 1
             else:
                 shape.pop(ax)
         ret = afnumpy.ndarray(tuple(shape), dtype=pu.typemap(s.dtype()),
                               af_array=s)
     if(dtype is not None):
         ret = ret.astype(dtype)
     if(len(shape) == 0):
         ret = ret[()]
     return ret
예제 #2
0
 def wrapper(a, axis=None, dtype=None, keepdims=False):
     if not isinstance(axis, tuple):
         axis = (axis, )
     if axis[0] is None:
         # Special case for speed
         a_flat = a.flat
         s = func(a_flat, a_flat.d_array, pu.c2f(a_flat.shape, 0))
         if keepdims:
             shape = (1, ) * a.ndim
         else:
             shape = ()
         ret = afnumpy.ndarray(tuple(shape),
                               dtype=pu.typemap(s.dtype()),
                               af_array=s)
     else:
         shape = list(a.shape)
         s = a.d_array
         # Do in decreasing axis order to avoid problems with the pop
         for ax in sorted(axis)[::-1]:
             # Optimization
             if (a.shape[ax] > 1):
                 s = func(a, s, pu.c2f(a.shape, ax))
             if keepdims:
                 shape[ax] = 1
             else:
                 shape.pop(ax)
         ret = afnumpy.ndarray(pu.af_shape(s),
                               dtype=pu.typemap(s.dtype()),
                               af_array=s).reshape(tuple(shape))
     if (dtype is not None):
         ret = ret.astype(dtype)
     if (len(shape) == 0):
         ret = ret[()]
     return ret
예제 #3
0
파일: linalg.py 프로젝트: syurkevi/afnumpy
def dot(a, b):
    # Arrayfire requires that the types match for dot and matmul
    res_dtype = numpy.result_type(a, b)
    a = a.astype(res_dtype, copy=False)
    b = b.astype(res_dtype, copy=False)
    if a.ndim == 1 and b.ndim == 1:
        s = arrayfire.dot(a.d_array, b.d_array)
        return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()]

    a_shape = a.shape
    b_shape = b.shape
    if a.ndim == 1:
        a = a.reshape((a.shape[0], 1))
    if b.ndim == 1:
        b = b.reshape((b.shape[0], 1))

    if a.ndim == 2 and b.ndim == 2:
        # Notice the order of the arguments to matmul. It's not a bug!
        s = arrayfire.matmul(b.d_array, a.d_array)
        return afnumpy.ndarray(pu.af_shape(s),
                               dtype=pu.typemap(s.dtype()),
                               af_array=s)

    # Multidimensional dot is done with loops

    # Calculate the shape of the result array
    a_shape = list(a_shape)
    a_shape.pop(-1)
    b_shape = list(b_shape)
    b_shape.pop(-2)
    res_shape = a_shape + b_shape

    # Make sure the arrays are at least 3D
    if a.ndim < 3:
        a = a.reshape((1, ) + a.shape)
    if b.ndim < 3:
        b = b.reshape((1, ) + b.shape)

    # We're going to flatten the regions over which we're going to loop over
    # to make our life easier and reduce the amount of indexing code
    a = a.reshape((-1, a.shape[-2], a.shape[-1]))
    b = b.reshape((-1, b.shape[-2], b.shape[-1]))

    # Initialize the output array. The shape matches the reshape a and b.
    res = afnumpy.empty((a.shape[0], a.shape[-2], b.shape[0], b.shape[-1]),
                        dtype=a.dtype)

    # Loop through the flattened indices and calculate the matmuls
    for i in range(0, a.shape[0]):
        for j in range(0, b.shape[0]):
            res[i, :, j, :] = afnumpy.dot(a[i], b[j])

    # Finally appropriately reshape the result array
    return res.reshape(res_shape)
예제 #4
0
def dot(a, b):
    # Arrayfire requires that the types match for dot and matmul
    res_dtype = numpy.result_type(a,b)
    a = a.astype(res_dtype, copy=False)
    b = b.astype(res_dtype, copy=False)
    if a.ndim == 1 and b.ndim == 1:
        s = arrayfire.dot(a.d_array, b.d_array)
        return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()]

    a_shape = a.shape
    b_shape = b.shape
    if a.ndim == 1:
        a = a.reshape((a.shape[0],1))
    if b.ndim == 1:
        b = b.reshape((b.shape[0],1))

    if a.ndim == 2 and b.ndim == 2:
        # Notice the order of the arguments to matmul. It's not a bug!
        s = arrayfire.matmul(b.d_array, a.d_array)
        return afnumpy.ndarray(pu.af_shape(s), dtype=pu.typemap(s.dtype()), 
                               af_array=s)

    # Multidimensional dot is done with loops    

    # Calculate the shape of the result array
    a_shape = list(a_shape)
    a_shape.pop(-1)
    b_shape = list(b_shape)
    b_shape.pop(-2)
    res_shape = a_shape + b_shape

    # Make sure the arrays are at least 3D
    if a.ndim < 3:
        a = a.reshape((1,)+a.shape)
    if b.ndim < 3:
        b = b.reshape((1,)+b.shape)

    # We're going to flatten the regions over which we're going to loop over
    # to make our life easier and reduce the amount of indexing code
    a = a.reshape((-1,a.shape[-2],a.shape[-1]))
    b = b.reshape((-1,b.shape[-2],b.shape[-1]))

    # Initialize the output array. The shape matches the reshape a and b.
    res = afnumpy.empty((a.shape[0], a.shape[-2], b.shape[0], 
                         b.shape[-1]), dtype=a.dtype)

    # Loop through the flattened indices and calculate the matmuls
    for i in range(0,a.shape[0]):
        for j in range(0,b.shape[0]):
            res[i,:,j,:] = afnumpy.dot(a[i],b[j])

    # Finally appropriately reshape the result array
    return res.reshape(res_shape)
예제 #5
0
def test_empty_ndarray():
    a = afnumpy.zeros(())
    b = numpy.zeros(())
    iassert(a, b)
    a = afnumpy.ndarray(0)
    b = numpy.ndarray(0)
    iassert(a, b)
    a = afnumpy.ndarray((0, ))
    b = numpy.ndarray((0, ))
    iassert(a, b)
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a[0:0], b[0:0])
예제 #6
0
def test_empty_ndarray():
    a = afnumpy.zeros(())
    b = numpy.zeros(())
    iassert(a,b)
    a = afnumpy.ndarray(0)
    b = numpy.ndarray(0)
    iassert(a,b)
    a = afnumpy.ndarray((0,))
    b = numpy.ndarray((0,))
    iassert(a,b)
    a = afnumpy.zeros(3)
    b = numpy.zeros(3)
    iassert(a[0:0],b[0:0])
예제 #7
0
def tile(A, reps):
    try:
        tup = tuple(reps)
    except TypeError:
        tup = (reps,)
    if(len(tup) > 4):
        raise NotImplementedError('Only up to 4 dimensions are supported')

    d = len(tup)
    shape = list(A.shape)
    n = max(A.size, 1)
    if (d < A.ndim):
        tup = (1,)*(A.ndim-d) + tup
    
    # Calculate final shape
    while len(shape) < len(tup):
        shape.insert(0,1)
    shape = tuple(numpy.array(shape) * numpy.array(tup))

    # Prepend ones to simplify calling
    if (d < 4):
        tup = (1,)*(4-d) + tup
    tup = pu.c2f(tup)
    s = arrayfire.tile(A.d_array, int(tup[0]), int(tup[1]), int(tup[2]), int(tup[3]))
    return afnumpy.ndarray(shape, dtype=pu.typemap(s.dtype()), af_array=s)
예제 #8
0
def tile(A, reps):
    try:
        tup = tuple(reps)
    except TypeError:
        tup = (reps,)
    if(len(tup) > 4):
        raise NotImplementedError('Only up to 4 dimensions are supported')

    d = len(tup)
    shape = list(A.shape)
    n = max(A.size, 1)
    if (d < A.ndim):
        tup = (1,)*(A.ndim-d) + tup
    
    # Calculate final shape
    while len(shape) < len(tup):
        shape.insert(0,1)
    shape = tuple(numpy.array(shape) * numpy.array(tup))

    # Prepend ones to simplify calling
    if (d < 4):
        tup = (1,)*(4-d) + tup
    tup = pu.c2f(tup)
    s = arrayfire.tile(A.d_array, int(tup[0]), int(tup[1]), int(tup[2]), int(tup[3]))
    return afnumpy.ndarray(shape, dtype=pu.typemap(s.dtype()), af_array=s)
예제 #9
0
def where(condition, x=pu.dummy, y=pu.dummy):
    a = condition
    s = arrayfire.where(a.d_array)
    # numpy uses int64 while arrayfire uses uint32
    s = afnumpy.ndarray(pu.af_shape(s), dtype=numpy.uint32, af_array=s).astype(numpy.int64)
    # Looks like where goes through the JIT??
    s.eval()
    if(x is pu.dummy and y is pu.dummy):
        idx = []
        mult = 1
        for i in a.shape[::-1]:
            mult = i
            idx = [s % mult] + idx
            s //= mult
        idx = tuple(idx)
        return idx
    elif(x is not pu.dummy and y is not pu.dummy):
        if(x.dtype != y.dtype):
            raise TypeError('x and y must have same dtype')
        if(x.shape != y.shape):
            raise ValueError('x and y must have same shape')
        ret = afnumpy.array(y)
        if(len(ret.shape) > 1):
            ret = ret.flatten()
            ret[s] = x.flatten()[s]
            ret = ret.reshape(x.shape)
        else:
            ret[s] = x[s]
        return ret;
    else:
        raise ValueError('either both or neither of x and y should be given')
예제 #10
0
def arctan2(x1, x2):
    if isinstance(x1, afnumpy.ndarray) and isinstance(x2, afnumpy.ndarray):
        s = arrayfire.atan2(x1.d_array, x2.d_array)
        return afnumpy.ndarray(x1.shape,
                               dtype=pu.typemap(s.dtype()),
                               af_array=s)
    else:
        return numpy.arctan(x1, x2)
예제 #11
0
def sin(x):
    if isinstance(x, afnumpy.ndarray):
        s = arrayfire.sin(x.d_array)
        return afnumpy.ndarray(x.shape,
                               dtype=pu.typemap(s.dtype()),
                               af_array=s)
    else:
        return numpy.sin(x)
예제 #12
0
def array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0):
    # We're going to ignore this for now
    # if(subok is not False):
    #     raise NotImplementedError
    if(order is not None and order is not 'K' and order is not 'C'):
        raise NotImplementedError

    # If it's not a numpy or afnumpy array first create a numpy array from it
    if(not isinstance(object, afnumpy.ndarray) and
       not isinstance(object, numpy.ndarray) and
       not isinstance(object, arrayfire.array.Array)):
        object = numpy.array(object, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin)

    if isinstance(object, arrayfire.array.Array):
        shape = pu.c2f(object.dims())
    else:
        shape = object.shape
    while(ndmin > len(shape)):
        shape = (1,)+shape
    if(dtype is None):
        if isinstance(object, arrayfire.array.Array):
            dtype = pu.typemap(object.dtype())
        else:
            dtype = object.dtype
    if(isinstance(object, afnumpy.ndarray)):
        if(copy):
            s = arrayfire.cast(object.d_array.copy(), pu.typemap(dtype))
        else:
            s = arrayfire.cast(object.d_array, pu.typemap(dtype))
        a = afnumpy.ndarray(shape, dtype=dtype, af_array=s)
        a._eval()
        return a
    elif(isinstance(object, arrayfire.array.Array)):
        if(copy):
            s = arrayfire.cast(object.copy(), pu.typemap(dtype))
        else:
            s = arrayfire.cast(object, pu.typemap(dtype))
        a = afnumpy.ndarray(shape, dtype=dtype, af_array=s)
        a._eval()
        return a
    elif(isinstance(object, numpy.ndarray)):
        return afnumpy.ndarray(shape, dtype=dtype, buffer=numpy.ascontiguousarray(object.astype(dtype, copy=copy)))
    else:
        raise AssertionError
예제 #13
0
def concatenate(arrays, axis=0):
    if(len(arrays) < 1):
        raise ValueError('need at least one array to concatenate')
    if(axis > 3):
        raise NotImplementedError('only up to 4 axis as currently supported')
    arr = arrays[0].d_array.copy()
    axis = pu.c2f(arrays[0].shape, axis)
    for a in arrays[1:]:
        arr = arrayfire.join(axis, arr, a.d_array)
    return afnumpy.ndarray(pu.af_shape(arr), dtype=arrays[0].dtype, af_array=arr)
예제 #14
0
def concatenate(arrays, axis=0):
    if (len(arrays) < 1):
        raise ValueError('need at least one array to concatenate')
    if (axis > 3):
        raise NotImplementedError('only up to 4 axis as currently supported')
    arr = arrays[0].d_array.copy()
    axis = pu.c2f(arrays[0].shape, axis)
    for a in arrays[1:]:
        arr = arrayfire.join(axis, arr, a.d_array)
    return afnumpy.ndarray(pu.af_shape(arr),
                           dtype=arrays[0].dtype,
                           af_array=arr)
예제 #15
0
def test_ndarray_constructor():
    a = afnumpy.arrayfire.randu(3,2)
    with pytest.raises(ValueError):
        b = afnumpy.ndarray(a.dims(), dtype='f', af_array = a)
    # This one should be fine
    b = afnumpy.ndarray(a.dims()[::-1], dtype='f', af_array = a)

    c = afnumpy.ndarray(a.dims()[::-1], dtype='f', buffer=a.raw_ptr(),
                        buffer_type=afnumpy.arrayfire.get_active_backend())

    d = afnumpy.ndarray(a.dims()[::-1], dtype='f', buffer=a.raw_ptr(),
                        buffer_type=afnumpy.arrayfire.get_active_backend())
    # Make sure they share the same underlying data
    d[0,0] = 3
    assert d[0,0] == c[0,0]


    if afnumpy.arrayfire.get_active_backend() == 'cpu':
        c = numpy.ones((3,2))
        d = afnumpy.ndarray(c.shape, dtype=c.dtype, buffer=c.ctypes.data,
                            buffer_type=afnumpy.arrayfire.get_active_backend())
        # Make sure they share the same underlying data
        d[0,0] = -1
        assert d[0,0] == c[0,0]

        with pytest.raises(ValueError):
            # Check for wrong backend
            b = afnumpy.ndarray(c.shape, dtype=c.dtype, buffer=c.ctypes.data,
                                buffer_type='cuda')
예제 #16
0
def test_ndarray_constructor():
    a = afnumpy.arrayfire.randu(3,2)
    with pytest.raises(ValueError):
        b = afnumpy.ndarray(a.dims(), dtype='f', af_array = a)
    # This one should be fine
    b = afnumpy.ndarray(a.dims()[::-1], dtype='f', af_array = a)

    c = afnumpy.ndarray(a.dims()[::-1], dtype='f', buffer=a.raw_ptr(),
                        buffer_type=afnumpy.arrayfire.get_active_backend())

    d = afnumpy.ndarray(a.dims()[::-1], dtype='f', buffer=a.raw_ptr(),
                        buffer_type=afnumpy.arrayfire.get_active_backend())
    # Make sure they share the same underlying data
    d[0,0] = 3
    assert d[0,0] == c[0,0]


    if afnumpy.arrayfire.get_active_backend() == 'cpu':
        c = numpy.ones((3,2))
        d = afnumpy.ndarray(c.shape, dtype=c.dtype, buffer=c.ctypes.data,
                            buffer_type=afnumpy.arrayfire.get_active_backend())
        # Make sure they share the same underlying data
        d[0,0] = -1
        assert d[0,0] == c[0,0]

        with pytest.raises(ValueError):
            # Check for wrong backend
            b = afnumpy.ndarray(c.shape, dtype=c.dtype, buffer=c.ctypes.data,
                                buffer_type='cuda')
예제 #17
0
def roll(a, shift, axis=None):
    shape = a.shape
    if(axis is None):
        axis = 0
        a = a.flatten()
    axis = pu.c2f(a.shape, axis)
    if axis == 0:
        s = arrayfire.shift(a.d_array, shift, 0, 0, 0)
    elif axis == 1:
        s = arrayfire.shift(a.d_array, 0, shift, 0, 0)
    elif axis == 2:
        s = arrayfire.shift(a.d_array, 0, 0, shift, 0)
    elif axis == 3:
        s = arrayfire.shift(a.d_array, 0, 0, 0, shift)
    else:
        raise NotImplementedError
    return afnumpy.ndarray(shape, dtype=a.dtype, af_array=s)
예제 #18
0
def sort(a, axis=-1, kind='quicksort', order=None):
    try:
        if kind != 'quicksort':
            print( "sort 'kind' argument ignored" )
        if order is not None:
            raise ValueError('order argument is not supported')
        if(axis is None):            
            input = a.flatten()
            axis = 0
        else:
            input = a
        if(axis < 0):
            axis = a.ndim+axis
        s = arrayfire.sort(input.d_array, pu.c2f(input.shape, axis))
        return afnumpy.ndarray(input.shape, dtype=pu.typemap(s.dtype()), af_array=s)
    except AttributeError:
        return numpy.argsort(a, axis, kind, order)
예제 #19
0
def roll(a, shift, axis=None):
    shape = a.shape
    if (axis is None):
        axis = 0
        a = a.flatten()
    axis = pu.c2f(a.shape, axis)
    if axis == 0:
        s = arrayfire.shift(a.d_array, shift, 0, 0, 0)
    elif axis == 1:
        s = arrayfire.shift(a.d_array, 0, shift, 0, 0)
    elif axis == 2:
        s = arrayfire.shift(a.d_array, 0, 0, shift, 0)
    elif axis == 3:
        s = arrayfire.shift(a.d_array, 0, 0, 0, shift)
    else:
        raise NotImplementedError
    return afnumpy.ndarray(a.shape, dtype=a.dtype, af_array=s).reshape(shape)
예제 #20
0
def full(shape, fill_value, dtype=None, order='C'):
    """
    Return a new array of given shape and type, filled with `fill_value`.

    Parameters
    ----------
    shape : int or sequence of ints
        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
    fill_value : scalar
        Fill value.
    dtype : data-type, optional
        The desired data-type for the array  The default, `None`, means
         `np.array(fill_value).dtype`.
    order : {'C', 'F'}, optional
        Whether to store multidimensional data in C- or Fortran-contiguous
        (row- or column-wise) order in memory.

    Returns
    -------
    out : ndarray
        Array of `fill_value` with the given shape, dtype, and order.

    See Also
    --------
    full_like : Return a new array with shape of input filled with value.
    empty : Return a new uninitialized array.
    ones : Return a new array setting values to one.
    zeros : Return a new array setting values to zero.

    Examples
    --------
    >>> np.full((2, 2), np.inf)
    array([[ inf,  inf],
           [ inf,  inf]])
    >>> np.full((2, 2), 10)
    array([[10, 10],
           [10, 10]])

    """
    if dtype is None:
        dtype = array(fill_value).dtype
    s = arrayfire.constant(fill_value, *shape[::-1], dtype=pu.typemap(dtype))
    return afnumpy.ndarray(shape, dtype=pu.typemap(s.dtype()), af_array=s)
예제 #21
0
def ones(shape, dtype=float, order='C'):
    b = numpy.ones(shape, dtype, order)
    return afnumpy.ndarray(b.shape, b.dtype, buffer=b,order=order)
예제 #22
0
def isinf(x):
    if not isinstance(x, afnumpy.ndarray):
        return numpy.isinf(x)
    s = arrayfire.isinf(x.d_array)
    return afnumpy.ndarray(x.shape, dtype=pu.typemap(s.dtype()), af_array=s)
예제 #23
0
def sinh(x):
    if isinstance(x, afnumpy.ndarray):
        s = arrayfire.sinh(x.d_array)
        return afnumpy.ndarray(x.shape, dtype=pu.typemap(s.dtype()), af_array=s)
    else:
        return numpy.sinh(x)
예제 #24
0
def arctan2(x1, x2):
    if isinstance(x1, afnumpy.ndarray) and isinstance(x2, afnumpy.ndarray):
        s = arrayfire.atan2(x1.d_array, x2.d_array)
        return afnumpy.ndarray(x1.shape, dtype=pu.typemap(s.dtype()), af_array=s)
    else:
        return numpy.arctan(x1, x2)
예제 #25
0
#! /usr/bin/env python

import gnufft
import numpy as np
import afnumpy as afnp
import arrayfire as af
import time
from matplotlib import pyplot as plt

pts = afnp.ndarray((512, 128),
                   dtype=np.complex64,
                   af_array=af.randu(128, 512, dtype=af.Dtype.c32))
cplx = afnp.ndarray((512, 512),
                    dtype=np.complex64,
                    af_array=af.randu(512, 512, dtype=af.Dtype.c32))
kblut = afnp.ndarray((128, 1),
                     dtype=np.float32,
                     af_array=af.randu(1, 128, dtype=af.Dtype.f32))
grid = [512, 512]
scale = 12
k_r = 5
t0 = time.time()
res = gnufft.polarsample_transpose(pts, cplx, grid, kblut, scale, k_r)
t1 = time.time() - t0
print "walltime: " + str(t1)
print res.shape
print res.size
print res.dtype
예제 #26
0
def zeros(shape, dtype=float, order='C'):
    b = numpy.zeros(shape, dtype, order)
    return afnumpy.ndarray(b.shape, b.dtype, buffer=b,order=order)
예제 #27
0
#! /usr/bin/env python

import numpy as np
import afnumpy as afnp
import afnumpy.fft as fft
import arrayfire as af
import gnufft

a = af.randu(512)
real = afnp.ndarray((512, 1), dtype=np.float32, af_array=a)
a = af.randu(512)
imag = afnp.ndarray((512, 1), dtype=np.float32, af_array=a)
cplx = real + 1j * imag
a = af.constant(1, 512, dtype=af.Dtype.f32)
ones = afnp.ndarray((512, 1), dtype=np.float32, af_array=a)
res = gnufft.debug(real, imag)
t1 = res * ones
t2 = fft.ifft(t1)
예제 #28
0
def vdot(a, b):
    s = arrayfire.dot(arrayfire.conjg(a.flat.d_array), b.flat.d_array)
    return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()]
예제 #29
0
def ceil(x, out=None):
    s = arrayfire.ceil(x.d_array)
    a = afnumpy.ndarray(x.shape, dtype=pu.typemap(s.dtype()), af_array=s)
    if out is not None:
        out[:] = a[:]
    return a
예제 #30
0
def empty(shape, dtype=float, order='C'):
    return afnumpy.ndarray(shape, dtype=dtype, order=order)
예제 #31
0
def ceil(x, out=None):
    s = arrayfire.ceil(x.d_array)
    a = afnumpy.ndarray(x.shape, dtype=pu.typemap(s.dtype()), af_array=s)
    if out is not None:
        out[:] = a[:]
    return a
예제 #32
0
 def __mul__(self, other):
     other = afnp.asarray(other).astype(self.dtype)
     s = arrayfire.matmul(self.d_array, other.d_array)
     a = afnp.ndarray(pu.af_shape(s), dtype=pu.typemap(s.dtype()), af_array=s)
     a._eval()
     return a
예제 #33
0
def isinf(x):
    if not isinstance(x, afnumpy.ndarray):
        return numpy.isinf(x)
    s = arrayfire.isinf(x.d_array)
    return afnumpy.ndarray(x.shape, dtype=pu.typemap(s.dtype()), af_array=s)
예제 #34
0
파일: linalg.py 프로젝트: syurkevi/afnumpy
def vdot(a, b):
    s = arrayfire.dot(arrayfire.conjg(a.flat.d_array), b.flat.d_array)
    return afnumpy.ndarray((), dtype=a.dtype, af_array=s)[()]