[python-arrayfire] 93/250: Adding documentation for array.py

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Mon Mar 28 22:59:35 UTC 2016


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch debian/master
in repository python-arrayfire.

commit 200566295e7a88734b4189ef44e7086808cddd97
Author: Pavan Yalamanchili <pavan at arrayfire.com>
Date:   Tue Sep 1 17:58:28 2015 -0400

    Adding documentation for array.py
    
    - Minor fixes to handle empty array creation
---
 arrayfire/array.py | 467 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 462 insertions(+), 5 deletions(-)

diff --git a/arrayfire/array.py b/arrayfire/array.py
index a2038e4..f5ebe55 100644
--- a/arrayfire/array.py
+++ b/arrayfire/array.py
@@ -7,6 +7,10 @@
 # http://arrayfire.com/licenses/BSD-3-Clause
 ########################################################
 
+"""
+Functions to create and operate on af.Array
+"""
+
 import inspect
 from .library import *
 from .util import *
@@ -18,10 +22,20 @@ def _create_array(buf, numdims, idims, dtype):
     out_arr = ct.c_void_p(0)
     c_dims = dim4(idims[0], idims[1], idims[2], idims[3])
     safe_call(backend.get().af_create_array(ct.pointer(out_arr), ct.c_void_p(buf),
-                                   numdims, ct.pointer(c_dims), dtype))
+                                            numdims, ct.pointer(c_dims), dtype))
+    return out_arr
+
+def _create_empty_array(numdims, idims, dtype):
+    out_arr = ct.c_void_p(0)
+    c_dims = dim4(idims[0], idims[1], idims[2], idims[3])
+    safe_call(backend.get().af_create_handle(ct.pointer(out_arr),
+                                            numdims, ct.pointer(c_dims), dtype))
     return out_arr
 
 def constant_array(val, d0, d1=None, d2=None, d3=None, dtype=f32):
+    """
+    Internal function to create a C array. Should not be used externall.
+    """
 
     if not isinstance(dtype, ct.c_int):
         if isinstance(dtype, int):
@@ -87,11 +101,45 @@ def _binary_funcr(lhs, rhs, c_func):
     return out
 
 def transpose(a, conj=False):
+    """
+    Perform the transpose on an input.
+
+    Parameters
+    -----------
+    a : af.Array
+        Multi dimensional arrayfire array.
+
+    conj : optional: bool. default: False.
+           Flag to specify if a complex conjugate needs to applied for complex inputs.
+
+    Returns
+    --------
+    out : af.Array
+          Containing the tranpose of `a` for all batches.
+
+    """
     out = Array()
     safe_call(backend.get().af_transpose(ct.pointer(out.arr), a.arr, conj))
     return out
 
 def transpose_inplace(a, conj=False):
+    """
+    Perform inplace transpose on an input.
+
+    Parameters
+    -----------
+    a : af.Array
+        - Multi dimensional arrayfire array.
+        - Contains transposed values on exit.
+
+    conj : optional: bool. default: False.
+           Flag to specify if a complex conjugate needs to applied for complex inputs.
+
+    Note
+    -------
+    Input `a` needs to be a square matrix or a batch of square matrices.
+
+    """
     safe_call(backend.get().af_transpose_inplace(a.arr, conj))
 
 def _ctype_to_lists(ctype_arr, dim, shape, offset=0):
@@ -126,12 +174,112 @@ def _get_info(dims, buf_len):
 
 class Array(BaseArray):
 
-    def __init__(self, src=None, dims=(0,), type_char=None):
+    """
+    A multi dimensional array container.
+
+    Parameters
+    ----------
+    src : optional: array.array, list or C buffer. default: None.
+         - When `src` is `array.array` or `list`, the data is copied to create the Array()
+         - When `src` is None, an empty buffer is created.
+
+    dims : optional: tuple of ints. default: (0,)
+         - When using the default values of `dims`, the dims are caclulated as `len(src)`
+
+    dtype: optional: str or ctypes.c_int. default: None.
+           - if str, must be one of the following:
+               - 'f' for float
+               - 'd' for double
+               - 'b' for bool
+               - 'B' for unsigned char
+               - 'i' for signed 32 bit integer
+               - 'I' for unsigned 32 bit integer
+               - 'l' for signed 64 bit integer
+               - 'L' for unsigned 64 bit integer
+               - 'F' for 32 bit complex number
+               - 'D' for 64 bit complex number
+           - if ctypes.c_int, must be one of the following:
+               - f32 for float
+               - f64 for double
+               - b8  for bool
+               - u8  for unsigned char
+               - s32 for signed 32 bit integer
+               - u32 for unsigned 32 bit integer
+               - s64 for signed 64 bit integer
+               - u64 for unsigned 64 bit integer
+               - c32 for 32 bit complex number
+               - c64 for 64 bit complex number
+            - if None, f32 is assumed
+
+    Attributes
+    -----------
+    arr: ctypes.c_void_p
+         ctypes variable containing af_array from arrayfire library.
+
+    Examples
+    --------
+
+    Creating an af.Array() from array.array()
+
+    >>> import arrayfire as af
+    >>> import array
+    >>> a = array.array('f', (1, 2, 3, 4))
+    >>> b = af.Array(a, (2,2))
+    >>> af.display(b)
+    [2 2 1 1]
+        1.0000     3.0000
+        2.0000     4.0000
+
+    Creating an af.Array() from a list
+
+    >>> import arrayfire as af
+    >>> import array
+    >>> a = [1, 2, 3, 4]
+    >>> b = af.Array(a)
+    >>> af.display(b)
+    [4 1 1 1]
+        1.0000
+        2.0000
+        3.0000
+        4.0000
+
+    Creating an af.Array() from numpy.array()
+
+    >>> import numpy as np
+    >>> import arrayfire as af
+    >>> a = np.random.random((2,2))
+    >>> a
+    array([[ 0.33042524,  0.36135449],
+           [ 0.86748649,  0.42199135]])
+    >>> b = af.Array(a.ctypes.data, a.shape, a.dtype.char)
+    >>> af.display(b)
+    [2 2 1 1]
+        0.3304     0.8675
+        0.3614     0.4220
+
+    Note
+    -----
+    - The class is currently limited to 4 dimensions.
+    - arrayfire.Array() uses column major format.
+    - numpy uses row major format by default which can cause issues during conversion
+
+    """
+
+    def __init__(self, src=None, dims=(0,), dtype=None):
 
         super(Array, self).__init__()
 
         buf=None
         buf_len=0
+
+        if dtype is not None:
+            if isinstance(dtype, str):
+                type_char = dtype
+            else:
+                type_char = to_typecode[dtype.value]
+        else:
+            type_char = None
+
         _type_char='f'
         dtype = f32
 
@@ -154,7 +302,7 @@ class Array(BaseArray):
                 buf,buf_len = tmp.buffer_info()
                 _type_char = tmp.typecode
                 numdims, idims = _get_info(dims, buf_len)
-            elif isinstance(src, int) or isinstance(src, ct.c_ulonglong):
+            elif isinstance(src, int) or isinstance(src, ct.c_void_p):
                 buf = src
                 numdims, idims = _get_info(dims, buf_len)
 
@@ -170,6 +318,8 @@ class Array(BaseArray):
 
                 _type_char = type_char
 
+                print(_type_char)
+
             else:
                 raise TypeError("src is an object of unsupported class")
 
@@ -179,34 +329,82 @@ class Array(BaseArray):
 
             self.arr = _create_array(buf, numdims, idims, to_dtype[_type_char])
 
+        else:
+
+            if type_char is None:
+                type_char = 'f'
+
+            numdims = len(dims)
+            idims = [1] * 4
+            for n in range(numdims):
+                idims[n] = dims[n]
+            self.arr = _create_empty_array(numdims, idims, to_dtype[type_char])
+
+
     def copy(self):
+        """
+        Performs a deep copy of the array.
+
+        Returns
+        -------
+        out: af.Array()
+             An identical copy of self.
+        """
         out = Array()
         safe_call(backend.get().af_copy_array(ct.pointer(out.arr), self.arr))
         return out
 
     def __del__(self):
+        """
+        Release the C array when going out of scope
+        """
         if self.arr.value:
             backend.get().af_release_array(self.arr)
 
     def device_ptr(self):
+        """
+        Return the device pointer held by the array.
+
+        Returns
+        ------
+        ptr : int
+              Contains location of the device pointer
+
+        Note
+        ----
+        - This can be used to integrate with custom C code and / or PyCUDA or PyOpenCL.
+        - No mem copy is peformed, this function returns the raw device pointer.
+        """
         ptr = ct.c_void_p(0)
         backend.get().af_get_device_ptr(ct.pointer(ptr), self.arr)
         return ptr.value
 
     def elements(self):
+        """
+        Return the number of elements in the array.
+        """
         num = ct.c_ulonglong(0)
         safe_call(backend.get().af_get_elements(ct.pointer(num), self.arr))
         return num.value
 
     def dtype(self):
+        """
+        Return the data type as a ctypes.c_int value.
+        """
         dty = ct.c_int(f32.value)
         safe_call(backend.get().af_get_type(ct.pointer(dty), self.arr))
         return dty
 
     def type(self):
+        """
+        Return the data type as an int.
+        """
         return self.dtype().value
 
     def dims(self):
+        """
+        Return the shape of the array as a tuple.
+        """
         d0 = ct.c_longlong(0)
         d1 = ct.c_longlong(0)
         d2 = ct.c_longlong(0)
@@ -217,206 +415,371 @@ class Array(BaseArray):
         return dims[:self.numdims()]
 
     def numdims(self):
+        """
+        Return the number of dimensions of the array.
+        """
         nd = ct.c_uint(0)
         safe_call(backend.get().af_get_numdims(ct.pointer(nd), self.arr))
         return nd.value
 
     def is_empty(self):
+        """
+        Check if the array is empty i.e. it has no elements.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_empty(ct.pointer(res), self.arr))
         return res.value
 
     def is_scalar(self):
+        """
+        Check if the array is scalar i.e. it has only one element.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_scalar(ct.pointer(res), self.arr))
         return res.value
 
     def is_row(self):
+        """
+        Check if the array is a row i.e. it has a shape of (1, cols).
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_row(ct.pointer(res), self.arr))
         return res.value
 
     def is_column(self):
+        """
+        Check if the array is a column i.e. it has a shape of (rows, 1).
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_column(ct.pointer(res), self.arr))
         return res.value
 
     def is_vector(self):
+        """
+        Check if the array is a vector i.e. it has a shape of one of the following:
+        - (rows, 1)
+        - (1, cols)
+        - (1, 1, vols)
+        - (1, 1, 1, batch)
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_vector(ct.pointer(res), self.arr))
         return res.value
 
     def is_complex(self):
+        """
+        Check if the array is of complex type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_complex(ct.pointer(res), self.arr))
         return res.value
 
     def is_real(self):
+        """
+        Check if the array is not of complex type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_real(ct.pointer(res), self.arr))
         return res.value
 
     def is_double(self):
+        """
+        Check if the array is of double precision floating point type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_double(ct.pointer(res), self.arr))
         return res.value
 
     def is_single(self):
+        """
+        Check if the array is of single precision floating point type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_single(ct.pointer(res), self.arr))
         return res.value
 
     def is_real_floating(self):
+        """
+        Check if the array is real and of floating point type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_realfloating(ct.pointer(res), self.arr))
         return res.value
 
     def is_floating(self):
+        """
+        Check if the array is of floating point type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_floating(ct.pointer(res), self.arr))
         return res.value
 
     def is_integer(self):
+        """
+        Check if the array is of integer type.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_integer(ct.pointer(res), self.arr))
         return res.value
 
     def is_bool(self):
+        """
+        Check if the array is of type b8.
+        """
         res = ct.c_bool(False)
         safe_call(backend.get().af_is_bool(ct.pointer(res), self.arr))
         return res.value
 
     def __add__(self, other):
+        """
+        Return self + other.
+        """
         return _binary_func(self, other, backend.get().af_add)
 
     def __iadd__(self, other):
+        """
+        Perform self += other.
+        """
         self = _binary_func(self, other, backend.get().af_add)
         return self
 
     def __radd__(self, other):
+        """
+        Return other + self.
+        """
         return _binary_funcr(other, self, backend.get().af_add)
 
     def __sub__(self, other):
+        """
+        Return self - other.
+        """
         return _binary_func(self, other, backend.get().af_sub)
 
     def __isub__(self, other):
+        """
+        Perform self -= other.
+        """
         self = _binary_func(self, other, backend.get().af_sub)
         return self
 
     def __rsub__(self, other):
+        """
+        Return other - self.
+        """
         return _binary_funcr(other, self, backend.get().af_sub)
 
     def __mul__(self, other):
+        """
+        Return self * other.
+        """
         return _binary_func(self, other, backend.get().af_mul)
 
     def __imul__(self, other):
+        """
+        Perform self *= other.
+        """
         self = _binary_func(self, other, backend.get().af_mul)
         return self
 
     def __rmul__(self, other):
+        """
+        Return other * self.
+        """
         return _binary_funcr(other, self, backend.get().af_mul)
 
-    # Necessary for python3
     def __truediv__(self, other):
+        """
+        Return self / other.
+        """
         return _binary_func(self, other, backend.get().af_div)
 
     def __itruediv__(self, other):
+        """
+        Perform self /= other.
+        """
         self =  _binary_func(self, other, backend.get().af_div)
         return self
 
     def __rtruediv__(self, other):
+        """
+        Return other / self.
+        """
         return _binary_funcr(other, self, backend.get().af_div)
 
     def __div__(self, other):
+        """
+        Return self / other.
+        """
         return _binary_func(self, other, backend.get().af_div)
 
     def __idiv__(self, other):
+        """
+        Perform other / self.
+        """
         self =  _binary_func(self, other, backend.get().af_div)
         return self
 
     def __rdiv__(self, other):
+        """
+        Return other / self.
+        """
         return _binary_funcr(other, self, backend.get().af_div)
 
     def __mod__(self, other):
+        """
+        Return self % other.
+        """
         return _binary_func(self, other, backend.get().af_mod)
 
     def __imod__(self, other):
+        """
+        Perform self %= other.
+        """
         self =  _binary_func(self, other, backend.get().af_mod)
         return self
 
     def __rmod__(self, other):
+        """
+        Return other % self.
+        """
         return _binary_funcr(other, self, backend.get().af_mod)
 
     def __pow__(self, other):
+        """
+        Return self ** other.
+        """
         return _binary_func(self, other, backend.get().af_pow)
 
     def __ipow__(self, other):
+        """
+        Perform self **= other.
+        """
         self =  _binary_func(self, other, backend.get().af_pow)
         return self
 
     def __rpow__(self, other):
+        """
+        Return other ** self.
+        """
         return _binary_funcr(other, self, backend.get().af_pow)
 
     def __lt__(self, other):
+        """
+        Return self < other.
+        """
         return _binary_func(self, other, backend.get().af_lt)
 
     def __gt__(self, other):
+        """
+        Return self > other.
+        """
         return _binary_func(self, other, backend.get().af_gt)
 
     def __le__(self, other):
+        """
+        Return self <= other.
+        """
         return _binary_func(self, other, backend.get().af_le)
 
     def __ge__(self, other):
+        """
+        Return self >= other.
+        """
         return _binary_func(self, other, backend.get().af_ge)
 
     def __eq__(self, other):
+        """
+        Return self == other.
+        """
         return _binary_func(self, other, backend.get().af_eq)
 
     def __ne__(self, other):
+        """
+        Return self != other.
+        """
         return _binary_func(self, other, backend.get().af_neq)
 
     def __and__(self, other):
+        """
+        Return self & other.
+        """
         return _binary_func(self, other, backend.get().af_bitand)
 
     def __iand__(self, other):
+        """
+        Perform self &= other.
+        """
         self = _binary_func(self, other, backend.get().af_bitand)
         return self
 
     def __or__(self, other):
+        """
+        Return self | other.
+        """
         return _binary_func(self, other, backend.get().af_bitor)
 
     def __ior__(self, other):
+        """
+        Perform self |= other.
+        """
         self = _binary_func(self, other, backend.get().af_bitor)
         return self
 
     def __xor__(self, other):
+        """
+        Return self ^ other.
+        """
         return _binary_func(self, other, backend.get().af_bitxor)
 
     def __ixor__(self, other):
+        """
+        Perform self ^= other.
+        """
         self = _binary_func(self, other, backend.get().af_bitxor)
         return self
 
     def __lshift__(self, other):
+        """
+        Return self << other.
+        """
         return _binary_func(self, other, backend.get().af_bitshiftl)
 
     def __ilshift__(self, other):
+        """
+        Perform self <<= other.
+        """
         self = _binary_func(self, other, backend.get().af_bitshiftl)
         return self
 
     def __rshift__(self, other):
+        """
+        Return self >> other.
+        """
         return _binary_func(self, other, backend.get().af_bitshiftr)
 
     def __irshift__(self, other):
+        """
+        Perform self >>= other.
+        """
         self = _binary_func(self, other, backend.get().af_bitshiftr)
         return self
 
     def __neg__(self):
+        """
+        Return -self
+        """
         return 0 - self
 
     def __pos__(self):
+        """
+        Return +self
+        """
         return self
 
     def __invert__(self):
+        """
+        Return ~self
+        """
         return self == 0
 
     def __nonzero__(self):
@@ -427,6 +790,13 @@ class Array(BaseArray):
     #     return self
 
     def __getitem__(self, key):
+        """
+        Return self[key]
+
+        Note
+        ----
+        Ellipsis not supported as key
+        """
         try:
             out = Array()
             n_dims = self.numdims()
@@ -440,6 +810,13 @@ class Array(BaseArray):
 
 
     def __setitem__(self, key, val):
+        """
+        Perform self[key] = val
+
+        Note
+        ----
+        Ellipsis not supported as key
+        """
         try:
             n_dims = self.numdims()
 
@@ -462,7 +839,27 @@ class Array(BaseArray):
             raise IndexError(str(e))
 
     def to_ctype(self, row_major=False, return_shape=False):
+        """
+        Return the data as a ctype C array after copying to host memory
+
+        Parameters
+        ---------
+
+        row_major: optional: bool. default: False.
+            Specifies if a transpose needs to occur before copying to host memory.
 
+        return_shape: optional: bool. default: False.
+            Specifies if the shape of the array needs to be returned.
+
+        Returns
+        -------
+
+        If return_shape is False:
+            res: The ctypes array of the appropriate type and length.
+        else :
+            (res, dims): tuple of the ctypes array and the shape of the array
+
+        """
         if (self.arr.value == 0):
             raise RuntimeError("Can not call to_ctype on empty array")
 
@@ -476,7 +873,27 @@ class Array(BaseArray):
             return res
 
     def to_array(self, row_major=False, return_shape=False):
+        """
+        Return the data as array.array
+
+        Parameters
+        ---------
+
+        row_major: optional: bool. default: False.
+            Specifies if a transpose needs to occur before copying to host memory.
 
+        return_shape: optional: bool. default: False.
+            Specifies if the shape of the array needs to be returned.
+
+        Returns
+        -------
+
+        If return_shape is False:
+            res: array.array of the appropriate type and length.
+        else :
+            (res, dims): array.array and the shape of the array
+
+        """
         if (self.arr.value == 0):
             raise RuntimeError("Can not call to_array on empty array")
 
@@ -491,22 +908,62 @@ class Array(BaseArray):
             return host.array(h_type, res)
 
     def to_list(self, row_major=False):
+        """
+        Return the data as list
+
+        Parameters
+        ---------
+
+        row_major: optional: bool. default: False.
+            Specifies if a transpose needs to occur before copying to host memory.
+
+        return_shape: optional: bool. default: False.
+            Specifies if the shape of the array needs to be returned.
+
+        Returns
+        -------
+
+        If return_shape is False:
+            res: list of the appropriate type and length.
+        else :
+            (res, dims): list and the shape of the array
+
+        """
         ct_array, shape = self.to_ctype(row_major, True)
         return _ctype_to_lists(ct_array, len(shape) - 1, shape)
 
     def __repr__(self):
+        """
+        Displays the meta data of the arrayfire array.
+
+        Note
+        ----
+        Use arrayfire.display(a) to display the contents of the array.
+        """
         # Having __repr__ directly print things is a bad idea
         # Placeholder for when af_array_to_string is available
         # safe_call(backend.get().af_array_to_string...
-        return '%s of dimensions %s' % (type(self), self.dims())
+        return 'Type: arrayfire.Array()\nShape: %s\nType char: %s' % \
+            (self.dims(), to_typecode[self.type()])
 
     def __array__(self):
+        """
+        Constructs a numpy.array from arrayfire.Array
+        """
         import numpy as np
         res = np.empty(self.dims(), dtype=np.dtype(to_typecode[self.type()]), order='F')
         safe_call(backend.get().af_get_data_ptr(ct.c_void_p(res.ctypes.data), self.arr))
         return res
 
 def display(a):
+    """
+    Displays the contents of an array.
+
+    Parameters
+    ----------
+    a : af.Array
+        Multi dimensional arrayfire array
+    """
     expr = inspect.stack()[1][-2]
     if (expr is not None):
         print('%s' % expr[0].split('display(')[1][:-2])

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/python-arrayfire.git



More information about the debian-science-commits mailing list