[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