From ad7759504317004a56b169c20a9dd76e94613156 Mon Sep 17 00:00:00 2001 From: Anton Chernyatevich Date: Fri, 13 Nov 2020 19:18:32 +0200 Subject: [PATCH] Fix flake8 errors. Minor refactoring and bugfixes --- arrayfire/algorithm.py | 47 ++++-- arrayfire/arith.py | 14 +- arrayfire/array.py | 82 +++++----- arrayfire/blas.py | 47 +++--- arrayfire/cuda.py | 31 +--- arrayfire/data.py | 12 +- arrayfire/device.py | 7 +- arrayfire/features.py | 2 +- arrayfire/graphics.py | 15 +- arrayfire/image.py | 28 ++-- arrayfire/index.py | 8 +- arrayfire/interop.py | 30 ++-- arrayfire/library.py | 352 ++++++++++++++++++++++------------------ arrayfire/opencl.py | 32 ++-- arrayfire/random.py | 5 +- arrayfire/signal.py | 152 +++++++---------- arrayfire/statistics.py | 44 ++--- arrayfire/util.py | 131 +++++++-------- 18 files changed, 493 insertions(+), 546 deletions(-) diff --git a/arrayfire/algorithm.py b/arrayfire/algorithm.py index 84d02422f..d9d20d2f9 100644 --- a/arrayfire/algorithm.py +++ b/arrayfire/algorithm.py @@ -1,5 +1,5 @@ ####################################################### -# Copyright (c) 2019, ArrayFire +# Copyright (c) 2020, ArrayFire # All rights reserved. # # This file is distributed under 3-clause BSD license. @@ -14,11 +14,13 @@ from .array import Array from .library import backend, safe_call, BINARYOP, c_bool_t, c_double_t, c_int_t, c_pointer, c_uint_t + def _parallel_dim(a, dim, c_func): out = Array() safe_call(c_func(c_pointer(out.arr), a.arr, c_int_t(dim))) return out + def _reduce_all(a, c_func): real = c_double_t(0) imag = c_double_t(0) @@ -29,11 +31,13 @@ def _reduce_all(a, c_func): imag = imag.value return real if imag == 0 else real + imag * 1j + def _nan_parallel_dim(a, dim, c_func, nan_val): out = Array() safe_call(c_func(c_pointer(out.arr), a.arr, c_int_t(dim), c_double_t(nan_val))) return out + def _nan_reduce_all(a, c_func, nan_val): real = c_double_t(0) imag = c_double_t(0) @@ -44,6 +48,7 @@ def _nan_reduce_all(a, c_func, nan_val): imag = imag.value return real if imag == 0 else real + imag * 1j + def _FNSD(dim, dims): if dim >= 0: return int(dim) @@ -55,6 +60,7 @@ def _FNSD(dim, dims): break return int(fnsd) + def _rbk_dim(keys, vals, dim, c_func): keys_out = Array() vals_out = Array() @@ -62,13 +68,18 @@ def _rbk_dim(keys, vals, dim, c_func): safe_call(c_func(c_pointer(keys_out.arr), c_pointer(vals_out.arr), keys.arr, vals.arr, c_int_t(rdim))) return keys_out, vals_out + def _nan_rbk_dim(a, dim, c_func, nan_val): keys_out = Array() vals_out = Array() + # FIXME: vals is undefined rdim = _FNSD(dim, vals.dims()) - safe_call(c_func(c_pointer(keys_out.arr), c_pointer(vals_out.arr), keys.arr, vals.arr, c_int_t(rdim), c_double_t(nan_val))) + # FIXME: keys is undefined + safe_call(c_func( + c_pointer(keys_out.arr), c_pointer(vals_out.arr), keys.arr, vals.arr, c_int_t(rdim), c_double_t(nan_val))) return keys_out, vals_out + def sum(a, dim=None, nan_val=None): """ Calculate the sum of all the elements along a specified dimension. @@ -88,18 +99,16 @@ def sum(a, dim=None, nan_val=None): The sum of all elements in `a` along dimension `dim`. If `dim` is `None`, sum of the entire Array is returned. """ - if nan_val is not None: - if dim is not None: + if nan_val: + if dim: return _nan_parallel_dim(a, dim, backend.get().af_sum_nan, nan_val) return _nan_reduce_all(a, backend.get().af_sum_nan_all, nan_val) - if dim is not None: + if dim: return _parallel_dim(a, dim, backend.get().af_sum) return _reduce_all(a, backend.get().af_sum_all) - - def sumByKey(keys, vals, dim=-1, nan_val=None): """ Calculate the sum of elements along a specified dimension according to a key. @@ -122,10 +131,10 @@ def sumByKey(keys, vals, dim=-1, nan_val=None): values: af.Array or scalar number The sum of all elements in `vals` along dimension `dim` according to keys """ - if (nan_val is not None): + if nan_val: return _nan_rbk_dim(keys, vals, dim, backend.get().af_sum_by_key_nan, nan_val) - else: - return _rbk_dim(keys, vals, dim, backend.get().af_sum_by_key) + return _rbk_dim(keys, vals, dim, backend.get().af_sum_by_key) + def product(a, dim=None, nan_val=None): """ @@ -178,10 +187,10 @@ def productByKey(keys, vals, dim=-1, nan_val=None): values: af.Array or scalar number The product of all elements in `vals` along dimension `dim` according to keys """ - if (nan_val is not None): + if nan_val is not None: return _nan_rbk_dim(keys, vals, dim, backend.get().af_product_by_key_nan, nan_val) - else: - return _rbk_dim(keys, vals, dim, backend.get().af_product_by_key) + return _rbk_dim(keys, vals, dim, backend.get().af_product_by_key) + def min(a, dim=None): """ @@ -227,6 +236,7 @@ def minByKey(keys, vals, dim=-1): """ return _rbk_dim(keys, vals, dim, backend.get().af_min_by_key) + def max(a, dim=None): """ Find the maximum value of all the elements along a specified dimension. @@ -271,6 +281,7 @@ def maxByKey(keys, vals, dim=-1): """ return _rbk_dim(keys, vals, dim, backend.get().af_max_by_key) + def all_true(a, dim=None): """ Check if all the elements along a specified dimension are true. @@ -315,6 +326,7 @@ def allTrueByKey(keys, vals, dim=-1): """ return _rbk_dim(keys, vals, dim, backend.get().af_all_true_by_key) + def any_true(a, dim=None): """ Check if any the elements along a specified dimension are true. @@ -334,8 +346,8 @@ def any_true(a, dim=None): """ if dim is not None: return _parallel_dim(a, dim, backend.get().af_any_true) - else: - return _reduce_all(a, backend.get().af_any_true_all) + return _reduce_all(a, backend.get().af_any_true_all) + def anyTrueByKey(keys, vals, dim=-1): """ @@ -359,6 +371,7 @@ def anyTrueByKey(keys, vals, dim=-1): """ return _rbk_dim(keys, vals, dim, backend.get().af_any_true_by_key) + def count(a, dim=None): """ Count the number of non zero elements in an array along a specified dimension. @@ -378,8 +391,7 @@ def count(a, dim=None): """ if dim is not None: return _parallel_dim(a, dim, backend.get().af_count) - else: - return _reduce_all(a, backend.get().af_count_all) + return _reduce_all(a, backend.get().af_count_all) def countByKey(keys, vals, dim=-1): @@ -404,6 +416,7 @@ def countByKey(keys, vals, dim=-1): """ return _rbk_dim(keys, vals, dim, backend.get().af_count_by_key) + def imin(a, dim=None): """ Find the value and location of the minimum value along a specified dimension diff --git a/arrayfire/arith.py b/arrayfire/arith.py index 85176436a..09bdaf29d 100644 --- a/arrayfire/arith.py +++ b/arrayfire/arith.py @@ -77,7 +77,7 @@ def cast(a, dtype): out : af.Array array containing the values from `a` after converting to `dtype`. """ - out=Array() + out = Array() safe_call(backend.get().af_cast(c_pointer(out.arr), a.arr, dtype.value)) return out @@ -156,15 +156,8 @@ def clamp(val, low, high): vdims = dim4_to_tuple(val.dims()) vty = val.type() - if not is_low_array: - low_arr = constant_array(low, vdims[0], vdims[1], vdims[2], vdims[3], vty) - else: - low_arr = low.arr - - if not is_high_array: - high_arr = constant_array(high, vdims[0], vdims[1], vdims[2], vdims[3], vty) - else: - high_arr = high.arr + low_arr = low.arr if is_low_array else constant_array(low, vdims[0], vdims[1], vdims[2], vdims[3], vty) + high_arr = high.arr if is_high_array else constant_array(high, vdims[0], vdims[1], vdims[2], vdims[3], vty) safe_call(backend.get().af_clamp(c_pointer(out.arr), val.arr, low_arr, high_arr, _bcast_var.get())) @@ -1003,6 +996,7 @@ def sqrt(a): """ return _arith_unary_func(a, backend.get().af_sqrt) + def rsqrt(a): """ Reciprocal or inverse square root of each element in the array. diff --git a/arrayfire/array.py b/arrayfire/array.py index acbf14230..e56a3acbe 100644 --- a/arrayfire/array.py +++ b/arrayfire/array.py @@ -20,9 +20,9 @@ from .library import backend, safe_call from .library import ( Dtype, Source, c_bool_t, c_char_ptr_t, c_dim_t, c_double_t, c_int_t, c_longlong_t, c_pointer, c_size_t, c_uint_t, - c_ulonglong_t, c_void_ptr_t) + c_ulonglong_t, c_void_ptr_t, to_str) from .util import ( - _is_number, dim4, dim4_to_tuple, implicit_dtype, to_c_type, to_dtype, to_str, to_typecode, to_typename) + _is_number, dim4, dim4_to_tuple, implicit_dtype, to_c_type, to_dtype, to_typecode, to_typename) _is_running_in_py_charm = "PYCHARM_HOSTED" in os.environ @@ -76,7 +76,8 @@ def get_display_dims_limit(): def _in_display_dims_limit(dims): if _is_running_in_py_charm: return False - if _display_dims_limit is not None: + + if _display_dims_limit: limit_len = len(_display_dims_limit) dim_len = len(dims) if dim_len > limit_len: @@ -84,6 +85,7 @@ def _in_display_dims_limit(dims): for i in range(dim_len): if dims[i] > _display_dims_limit[i]: return False + return True @@ -102,18 +104,21 @@ def _create_array(buf, numdims, idims, dtype, is_device): def _create_strided_array(buf, numdims, idims, dtype, is_device, offset, strides): out_arr = c_void_ptr_t(0) c_dims = dim4(idims[0], idims[1], idims[2], idims[3]) - if offset is None: + + if not offset: offset = 0 + offset = c_dim_t(offset) - if strides is None: + + if not strides: strides = (1, idims[0], idims[0]*idims[1], idims[0]*idims[1]*idims[2]) + while len(strides) < 4: strides = strides + (strides[-1],) + strides = dim4(strides[0], strides[1], strides[2], strides[3]) - if is_device: - location = Source.device - else: - location = Source.host + location = Source.device if is_device else Source.host + safe_call(backend.get().af_create_strided_array( c_pointer(out_arr), c_void_ptr_t(buf), offset, numdims, c_pointer(c_dims), c_pointer(strides), dtype.value, location.value)) @@ -123,7 +128,7 @@ def _create_strided_array(buf, numdims, idims, dtype, is_device, offset, strides def _create_empty_array(numdims, idims, dtype): out_arr = c_void_ptr_t(0) - if numdims == 0: + if not numdims: return out_arr c_dims = dim4(idims[0], idims[1], idims[2], idims[3]) @@ -147,12 +152,11 @@ def constant_array(val, d0, d1=None, d2=None, d3=None, dtype=Dtype.f32): dims = dim4(d0, d1, d2, d3) if isinstance(val, complex): - c_real = c_double_t(val.real) - c_imag = c_double_t(val.imag) - if dtype.value != Dtype.c32.value and dtype.value != Dtype.c64.value: dtype = Dtype.c32.value + c_real = c_double_t(val.real) + c_imag = c_double_t(val.imag) safe_call(backend.get().af_constant_complex(c_pointer(out), c_real, c_imag, 4, c_pointer(dims), dtype)) elif dtype.value == Dtype.s64.value: c_val = c_longlong_t(val.real) @@ -202,7 +206,7 @@ def _binary_funcr(lhs, rhs, c_func): def _ctype_to_lists(ctype_arr, dim, shape, offset=0): - if dim == 0: + if not dim: return list(ctype_arr[offset: offset + shape[0]]) dim_len = shape[dim] @@ -216,17 +220,17 @@ def _ctype_to_lists(ctype_arr, dim, shape, offset=0): def _slice_to_length(key, dim): tkey = [key.start, key.stop, key.step] - if tkey[0] is None: + if not tkey[0]: tkey[0] = 0 elif tkey[0] < 0: tkey[0] = dim - tkey[0] - if tkey[1] is None: + if not tkey[1]: tkey[1] = dim elif tkey[1] < 0: tkey[1] = dim - tkey[1] - if tkey[2] is None: + if not tkey[2]: tkey[2] = 1 return int(((tkey[1] - tkey[0] - 1) / tkey[2]) + 1) @@ -280,10 +284,7 @@ def _get_assign_dims(key, idims): return dims if isinstance(key, BaseArray): # If the array is boolean take only the number of nonzeros - if key.dtype() is Dtype.b8: - dims[0] = int(sum(key)) - else: - dims[0] = key.elements() + dims[0] = int(sum(key)) if key.dtype() is Dtype.b8 else key.elements() return dims if not isinstance(key, tuple): raise IndexError("Invalid type while assigning to arrayfire.array") @@ -295,10 +296,7 @@ def _get_assign_dims(key, idims): dims[n] = 1 elif isinstance(key[n], BaseArray): # If the array is boolean take only the number of nonzeros - if key[n].dtype() is Dtype.b8: - dims[n] = int(sum(key[n])) - else: - dims[n] = key[n].elements() + dims[n] = int(sum(key[n])) if key[n].dtype() is Dtype.b8 else key[n].elements() elif isinstance(key[n], slice): dims[n] = _slice_to_length(key[n], idims[n]) elif isinstance(key[n], ParallelRange): @@ -463,13 +461,8 @@ def __init__(self, src=None, dims=None, dtype=None, is_device=False, offset=None 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 + if dtype: + type_char = dtype if isinstance(dtype, str) else to_typecode[dtype.value] _type_char = 'f' @@ -502,7 +495,7 @@ def __init__(self, src=None, dims=None, dtype=None, is_device=False, offset=None if elements == 0: raise RuntimeError("Expected dims when src is data pointer") - if type_char is None: + if dtype: raise TypeError("Expected type_char when src is data pointer") _type_char = type_char @@ -510,14 +503,14 @@ def __init__(self, src=None, dims=None, dtype=None, is_device=False, offset=None else: raise TypeError("src is an object of unsupported class") - if type_char is not None and type_char != _type_char: + if dtype and type_char != _type_char: raise TypeError("Can not create array of requested type from input data type") - if offset is None and strides is None: + if not (offset or strides): self.arr = _create_array(buf, numdims, idims, to_dtype[_type_char], is_device) else: self.arr = _create_strided_array(buf, numdims, idims, to_dtype[_type_char], is_device, offset, strides) else: - if type_char is None: + if not dtype: type_char = 'f' numdims = len(dims) if dims else 0 @@ -1117,7 +1110,7 @@ def logical_and(self, other): Return self && other. """ out = Array() - safe_call(backend.get().af_and(c_pointer(out.arr), self.arr, other.arr)) #TODO: bcast var? + safe_call(backend.get().af_and(c_pointer(out.arr), self.arr, other.arr)) # TODO: bcast var? return out def logical_or(self, other): @@ -1125,7 +1118,7 @@ def logical_or(self, other): Return self || other. """ out = Array() - safe_call(backend.get().af_or(c_pointer(out.arr), self.arr, other.arr)) #TODO: bcast var? + safe_call(backend.get().af_or(c_pointer(out.arr), self.arr, other.arr)) # TODO: bcast var? return out def __nonzero__(self): @@ -1240,7 +1233,7 @@ def to_ctype(self, row_major=False, return_shape=False): (res, dims): tuple of the ctypes array and the shape of the array """ - if self.arr.value == 0: + if not self.arr.value: raise RuntimeError("Can not call to_ctype on empty array") ctype_type = to_c_type[self.type()] * self.elements() @@ -1274,7 +1267,7 @@ def to_array(self, row_major=False, return_shape=False): (res, dims): array.array and the shape of the array """ - if self.arr.value == 0: + if not self.arr.value: raise RuntimeError("Can not call to_array on empty array") res = self.to_ctype(row_major, return_shape) @@ -1316,7 +1309,7 @@ def scalar(self): """ Return the first element of the array """ - if self.arr.value == 0: + if not self.arr.value: raise RuntimeError("Can not call to_ctype on empty array") ctype_type = to_c_type[self.type()] @@ -1355,6 +1348,7 @@ def _as_str(self): arr_str = c_char_ptr_t(0) be = backend.get() safe_call(be.af_array_to_string(c_pointer(arr_str), "", self.arr, 4, True)) + # FIXME: not intuitive transformation and return py_str = to_str(arr_str) safe_call(be.af_free_host(arr_str)) return py_str @@ -1365,6 +1359,7 @@ def __array__(self): """ # FIXME: import insdie of a function import numpy as np + # FIXME: not intuitive transformation and return res = np.empty(self.dims(), dtype=np.dtype(to_typecode[self.type()]), order='F') safe_call(backend.get().af_get_data_ptr(c_void_ptr_t(res.ctypes.data), self.arr)) return res @@ -1423,7 +1418,7 @@ def display(a, precision=4): name = "" try: - if expr is not None: + if expr: st = expr[0].find('(') + 1 en = expr[0].rfind(')') name = expr[0][st:en] @@ -1483,12 +1478,9 @@ def read_array(filename, index=None, key=None): Returns --------- """ - assert((index is not None) or (key is not None)) out = Array() if index is not None: safe_call(backend.get().af_read_array_index(c_pointer(out.arr), filename.encode('utf-8'), index)) elif key is not None: safe_call(backend.get().af_read_array_key(c_pointer(out.arr), filename.encode('utf-8'), key.encode('utf-8'))) return out - - diff --git a/arrayfire/blas.py b/arrayfire/blas.py index a62110fc1..7765e7dd8 100644 --- a/arrayfire/blas.py +++ b/arrayfire/blas.py @@ -12,7 +12,9 @@ """ from .array import Array -from .library import backend, safe_call, MATPROP, c_double_t, c_pointer +from .library import ( + MATPROP, Dtype, af_cdouble_t, af_cfloat_t, backend, c_cast, c_double_t, c_float_t, c_pointer, c_void_ptr_t, + safe_call, get_complex_number) def matmul(lhs, rhs, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE): @@ -54,8 +56,7 @@ def matmul(lhs, rhs, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE): """ out = Array() - safe_call(backend.get().af_matmul( - c_pointer(out.arr), lhs.arr, rhs.arr, lhs_opts.value, rhs_opts.value)) + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, lhs_opts.value, rhs_opts.value)) return out @@ -86,8 +87,7 @@ def matmulTN(lhs, rhs): """ out = Array() - safe_call(backend.get().af_matmul( - c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.TRANS.value, MATPROP.NONE.value)) + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.TRANS.value, MATPROP.NONE.value)) return out @@ -118,8 +118,7 @@ def matmulNT(lhs, rhs): """ out = Array() - safe_call(backend.get().af_matmul( - c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.NONE.value, MATPROP.TRANS.value)) + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.NONE.value, MATPROP.TRANS.value)) return out @@ -150,8 +149,7 @@ def matmulTT(lhs, rhs): """ out = Array() - safe_call(backend.get().af_matmul( - c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.TRANS.value, MATPROP.TRANS.value)) + safe_call(backend.get().af_matmul(c_pointer(out.arr), lhs.arr, rhs.arr, MATPROP.TRANS.value, MATPROP.TRANS.value)) return out @@ -199,21 +197,19 @@ def dot(lhs, rhs, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE, return_scalar=Fa imag = c_double_t(0) safe_call(backend.get().af_dot_all( c_pointer(real), c_pointer(imag), lhs.arr, rhs.arr, lhs_opts.value, rhs_opts.value)) - real = real.value - imag = imag.value - return real if imag == 0 else real + imag * 1j - else: - out = Array() - safe_call(backend.get().af_dot(c_pointer(out.arr), lhs.arr, rhs.arr, - lhs_opts.value, rhs_opts.value)) - return out + return get_complex_number(real, imag) + + out = Array() + safe_call(backend.get().af_dot(c_pointer(out.arr), lhs.arr, rhs.arr, lhs_opts.value, rhs_opts.value)) + return out def gemm(lhs, rhs, alpha=1.0, beta=0.0, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP.NONE, C=None): """ BLAS general matrix multiply (GEMM) of two af_array objects. - This provides a general interface to the BLAS level 3 general matrix multiply (GEMM), which is generally defined as: + This provides a general interface to the BLAS level 3 general matrix multiply (GEMM), + which is generally defined as: C = alpha * opA(A) opB(B) + beta * C @@ -262,15 +258,12 @@ def gemm(lhs, rhs, alpha=1.0, beta=0.0, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP. - Batches are not supported. """ - if C is None: - out = Array() - else: - out = C + out = Array() if C is None else C ltype = lhs.dtype() if ltype == Dtype.f32: - aptr = c_cast(c_pointer(c_float_t(alpha)),c_void_ptr_t) + aptr = c_cast(c_pointer(c_float_t(alpha)), c_void_ptr_t) bptr = c_cast(c_pointer(c_float_t(beta)), c_void_ptr_t) elif ltype == Dtype.c32: if isinstance(alpha, af_cfloat_t): @@ -288,7 +281,7 @@ def gemm(lhs, rhs, alpha=1.0, beta=0.0, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP. bptr = c_cast(c_pointer(af_cfloat_t(beta)), c_void_ptr_t) elif ltype == Dtype.f64: - aptr = c_cast(c_pointer(c_double_t(alpha)),c_void_ptr_t) + aptr = c_cast(c_pointer(c_double_t(alpha)), c_void_ptr_t) bptr = c_cast(c_pointer(c_double_t(beta)), c_void_ptr_t) elif ltype == Dtype.c64: if isinstance(alpha, af_cdouble_t): @@ -309,8 +302,6 @@ def gemm(lhs, rhs, alpha=1.0, beta=0.0, lhs_opts=MATPROP.NONE, rhs_opts=MATPROP. else: raise TypeError("unsupported input type") - - safe_call(backend.get().af_gemm(c_pointer(out.arr), - lhs_opts.value, rhs_opts.value, - aptr, lhs.arr, rhs.arr, bptr)) + safe_call(backend.get().af_gemm( + c_pointer(out.arr), lhs_opts.value, rhs_opts.value, aptr, lhs.arr, rhs.arr, bptr)) return out diff --git a/arrayfire/cuda.py b/arrayfire/cuda.py index ab5c5673b..efd1276fd 100644 --- a/arrayfire/cuda.py +++ b/arrayfire/cuda.py @@ -13,7 +13,8 @@ This module provides interoperability with other CUDA libraries. """ -from .library import c_int_t, c_pointer, c_void_ptr_t +from .library import backend, c_int_t, c_pointer, c_void_ptr_t +from .util import safe_call def get_stream(idx): @@ -30,14 +31,7 @@ def get_stream(idx): ----------- stream : integer denoting the stream id. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call - from .library import backend - - if backend.name() != "cuda": - raise RuntimeError("Invalid backend loaded") - + _check_backend() stream = c_void_ptr_t(0) safe_call(backend.get().afcu_get_stream(c_pointer(stream), idx)) return stream.value @@ -57,14 +51,7 @@ def get_native_id(idx): ----------- native_idx : integer denoting the native cuda id. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call - from .library import backend - - if backend.name() != "cuda": - raise RuntimeError("Invalid backend loaded") - + _check_backend() native = c_int_t(0) safe_call(backend.get().afcu_get_native_id(c_pointer(native), idx)) return native.value @@ -80,12 +67,10 @@ def set_native_id(idx): idx : int. Specifies the (unsorted) native index of the device. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call - from .library import backend + _check_backend() + safe_call(backend.get().afcu_set_native_id(idx)) + +def _check_backend(backend): if backend.name() != "cuda": raise RuntimeError("Invalid backend loaded") - - safe_call(backend.get().afcu_set_native_id(idx)) diff --git a/arrayfire/data.py b/arrayfire/data.py index 9fac5a3cc..452ea7819 100644 --- a/arrayfire/data.py +++ b/arrayfire/data.py @@ -176,14 +176,13 @@ def iota(d0, d1=None, d2=None, d3=None, tile_dims=None, dtype=Dtype.f32): dims = dim4(d0, d1, d2, d3) td = [1]*4 - if tile_dims is not None: + if tile_dims: for i in _brange(len(tile_dims)): td[i] = tile_dims[i] tdims = dim4(td[0], td[1], td[2], td[3]) - safe_call(backend.get().af_iota( - c_pointer(out.arr), 4, c_pointer(dims), 4, c_pointer(tdims), dtype.value)) + safe_call(backend.get().af_iota(c_pointer(out.arr), 4, c_pointer(dims), 4, c_pointer(tdims), dtype.value)) return out @@ -808,7 +807,7 @@ def replace(lhs, cond, rhs): safe_call(backend.get().af_replace_scalar(lhs.arr, cond.arr, c_double_t(rhs))) -def pad(a, beginPadding, endPadding, padFillType = PAD.ZERO): +def pad(a, beginPadding, endPadding, padFillType=PAD.ZERO): """ Pad an array @@ -854,9 +853,10 @@ def pad(a, beginPadding, endPadding, padFillType = PAD.ZERO): """ out = Array() begin_dims = dim4(beginPadding[0], beginPadding[1], beginPadding[2], beginPadding[3]) - end_dims = dim4(endPadding[0], endPadding[1], endPadding[2], endPadding[3]) + end_dims = dim4(endPadding[0], endPadding[1], endPadding[2], endPadding[3]) - safe_call(backend.get().af_pad(c_pointer(out.arr), a.arr, 4, c_pointer(begin_dims), 4, c_pointer(end_dims), padFillType.value)) + safe_call(backend.get().af_pad( + c_pointer(out.arr), a.arr, 4, c_pointer(begin_dims), 4, c_pointer(end_dims), padFillType.value)) return out diff --git a/arrayfire/device.py b/arrayfire/device.py index e12f74c41..905ef1022 100644 --- a/arrayfire/device.py +++ b/arrayfire/device.py @@ -12,8 +12,9 @@ """ from .array import Array -from .library import backend, safe_call, c_bool_t, c_char_t, c_dim_t, c_int_t, c_pointer, c_size_t, c_void_ptr_t -from .util import to_str +from .library import ( + backend, c_bool_t, c_char_t, c_dim_t, c_int_t, c_pointer, c_size_t, c_void_ptr_t, safe_call, to_str) +from .util import get_version def init(): @@ -181,6 +182,7 @@ def is_half_supported(device=None): safe_call(backend.get().af_get_half_support(c_pointer(res), dev)) return res.value + def sync(device=None): """ Block until all the functions on the device have completed execution. @@ -506,4 +508,3 @@ def free_pinned(ptr): """ cptr = c_void_ptr_t(ptr) safe_call(backend.get().af_free_pinned(cptr)) - diff --git a/arrayfire/features.py b/arrayfire/features.py index 3025f4c1b..315a14311 100644 --- a/arrayfire/features.py +++ b/arrayfire/features.py @@ -30,7 +30,7 @@ class Features(object): def __init__(self, num=0): self.feat = c_void_ptr_t(0) - if num is not None: + if num: assert isinstance(num, numbers.Number) safe_call(backend.get().af_create_features(c_pointer(self.feat), c_dim_t(num))) diff --git a/arrayfire/graphics.py b/arrayfire/graphics.py index bb214d983..9fb057990 100644 --- a/arrayfire/graphics.py +++ b/arrayfire/graphics.py @@ -13,7 +13,9 @@ import ctypes as ct -from .library import backend, safe_call, COLORMAP, MARKER, c_bool_t, c_char_ptr_t, c_double_t, c_float_t, c_int_t, c_pointer, c_void_ptr_t +from .library import ( + backend, safe_call, COLORMAP, MARKER, c_bool_t, c_char_ptr_t, c_double_t, c_float_t, c_int_t, c_pointer, + c_void_ptr_t) from .util import _is_number @@ -378,8 +380,7 @@ def surface(self, x_vals, y_vals, z_vals, title=None): Title used for the plot. """ _cell = _Cell(self._r, self._c, title, self._cmap) - safe_call(backend.get().af_draw_surface( - self._wnd, x_vals.arr, y_vals.arr, z_vals.arr, c_pointer(_cell))) + safe_call(backend.get().af_draw_surface(self._wnd, x_vals.arr, y_vals.arr, z_vals.arr, c_pointer(_cell))) def hist(self, X, min_val, max_val, title=None): """ @@ -511,11 +512,8 @@ def set_axes_label_format(self, xformat="4.1%f", yformat="4.1%f", zformat="4.1%f xformat = xformat.encode("ascii") yformat = yformat.encode("ascii") zformat = zformat.encode("ascii") - safe_call(backend.get().af_set_axes_label_format(self._wnd, - c_char_ptr_t(xformat), - c_char_ptr_t(yformat), - c_char_ptr_t(zformat), - c_pointer(_cell))) + safe_call(backend.get().af_set_axes_label_format( + self._wnd, c_char_ptr_t(xformat), c_char_ptr_t(yformat), c_char_ptr_t(zformat), c_pointer(_cell))) def __getitem__(self, keys): """ @@ -538,6 +536,7 @@ def __getitem__(self, keys): raise IndexError("Window expects indexing along two dimensions only") if not (_is_number(keys[0]) and _is_number(keys[1])): raise IndexError("Window expects the indices to be numbers") + self._r = keys[0] self._c = keys[1] diff --git a/arrayfire/image.py b/arrayfire/image.py index 9e4de7fe0..9135f4a9a 100644 --- a/arrayfire/image.py +++ b/arrayfire/image.py @@ -16,8 +16,8 @@ from .array import Array from .data import constant from .library import ( - CANNY_THRESHOLD, CONNECTIVITY, DIFFUSION, FLUX, INTERP, ITERATIVE_DECONV, MOMENT, PAD, YCC_STD, Dtype, c_bool_t, c_char_ptr_t, - c_dim_t, c_double_t, c_float_t, c_int_t, c_pointer, c_uint_t) + CANNY_THRESHOLD, CONNECTIVITY, DIFFUSION, FLUX, INTERP, ITERATIVE_DECONV, MOMENT, PAD, YCC_STD, Dtype, c_bool_t, + c_char_ptr_t, c_dim_t, c_double_t, c_float_t, c_int_t, c_pointer, c_uint_t) from .library import backend, safe_call @@ -64,8 +64,7 @@ def load_image(file_name, is_color=False): """ assert os.path.isfile(file_name) image = Array() - safe_call( - backend.get().af_load_image(c_pointer(image.arr), c_char_ptr_t(file_name.encode('ascii')), is_color)) + safe_call(backend.get().af_load_image(c_pointer(image.arr), c_char_ptr_t(file_name.encode('ascii')), is_color)) return image @@ -103,8 +102,7 @@ def load_image_native(file_name): """ assert os.path.isfile(file_name) image = Array() - safe_call( - backend.get().af_load_image_native(c_pointer(image.arr), c_char_ptr_t(file_name.encode('ascii')))) + safe_call(backend.get().af_load_image_native(c_pointer(image.arr), c_char_ptr_t(file_name.encode('ascii')))) return image @@ -756,8 +754,9 @@ def confidenceCC(image, seedx, seedy, radius, multiplier, iters, segmented_value """ output = Array() - safe_call(backend.get().af_confidence_cc(c_pointer(output.arr), image.arr, seedx.arr, seedy.arr, - c_uint_t(radius), c_uint_t(multiplier), c_int_t(iters), c_double_t(segmented_value))) + safe_call(backend.get().af_confidence_cc( + c_pointer(output.arr), image.arr, seedx.arr, seedy.arr, c_uint_t(radius), c_uint_t(multiplier), + c_int_t(iters), c_double_t(segmented_value))) return output @@ -819,10 +818,10 @@ def gaussian_kernel(rows, cols, sigma_r=None, sigma_c=None): """ out = Array() - if sigma_r is None: + if not sigma_r: sigma_r = 0.25 * rows + 0.75 - if sigma_c is None: + if not sigma_c: sigma_c = 0.25 * cols + 0.75 safe_call(backend.get().af_gaussian_kernel( @@ -1333,7 +1332,7 @@ def anisotropic_diffusion( return out -def iterativeDeconv(image, psf, iterations, relax_factor, algo = ITERATIVE_DECONV.DEFAULT): +def iterativeDeconv(image, psf, iterations, relax_factor, algo=ITERATIVE_DECONV.DEFAULT): """ Iterative deconvolution algorithm. @@ -1372,7 +1371,8 @@ def iterativeDeconv(image, psf, iterations, relax_factor, algo = ITERATIVE_DECON c_pointer(out.arr), image.arr, psf.arr, c_uint_t(iterations), c_float_t(relax_factor), algo.value)) return out -def inverseDeconv(image, psf, gamma, algo = ITERATIVE_DECONV.DEFAULT): + +def inverseDeconv(image, psf, gamma, algo=ITERATIVE_DECONV.DEFAULT): """ Inverse deconvolution algorithm. @@ -1399,9 +1399,7 @@ def inverseDeconv(image, psf, gamma, algo = ITERATIVE_DECONV.DEFAULT): """ out = Array() - safe_call(backend.get(). - af_inverse_deconv(c_pointer(out.arr), image.arr, psf.arr, - c_float_t(gamma), algo.value)) + safe_call(backend.get().af_inverse_deconv(c_pointer(out.arr), image.arr, psf.arr, c_float_t(gamma), algo.value)) return out diff --git a/arrayfire/index.py b/arrayfire/index.py index ae49e4934..afbb90373 100644 --- a/arrayfire/index.py +++ b/arrayfire/index.py @@ -56,13 +56,13 @@ def __init__(self, S): self.begin = c_double_t(S) self.end = c_double_t(S) elif isinstance(S, slice): - if S.step is not None: + if S.step: self.step = c_double_t(S.step) if S.step < 0: self.begin, self.end = self.end, self.begin - if S.start is not None: + if S.start: self.begin = c_double_t(S.start) - if S.stop is not None: + if S.stop: self.end = c_double_t(S.stop) # handle special cases @@ -75,7 +75,7 @@ def __init__(self, S): self.end = -2 self.step = -1 - if S.stop is not None: + if S.stop: self.end = self.end - math.copysign(1, self.step) else: raise IndexError("Invalid type while indexing arrayfire.array") diff --git a/arrayfire/interop.py b/arrayfire/interop.py index 3c75d271f..fc2ca5abc 100644 --- a/arrayfire/interop.py +++ b/arrayfire/interop.py @@ -67,14 +67,10 @@ def _cc_to_af_array(in_ptr, ndim, in_shape, in_dtype, is_device=False, copy=True 'c16': Dtype.c64} try: - # FIXME: numpy imported but unused - import numpy as np -except ImportError: - AF_NUMPY_FOUND = False -else: from numpy import ndarray as NumpyArray - AF_NUMPY_FOUND = True +except ImportError: + AF_NUMPY_FOUND = False def np_to_af_array(np_arr, copy=True): """ @@ -109,13 +105,10 @@ def np_to_af_array(np_arr, copy=True): from_ndarray = np_to_af_array try: - # FIXME: pycuda imported but unused - import pycuda.gpuarray -except ImportError: - AF_PYCUDA_FOUND = False -else: from pycuda.gpuarray import GPUArray as CudaArray AF_PYCUDA_FOUND = True +except ImportError: + AF_PYCUDA_FOUND = False def pycuda_to_af_array(pycu_arr, copy=True): """ @@ -141,7 +134,7 @@ def pycuda_to_af_array(pycu_arr, copy=True): in_shape = pycu_arr.shape in_dtype = pycu_arr.dtype.char - if not copy and not pycu_arr.flags.f_contiguous: + if not (copy or pycu_arr.flags.f_contiguous): raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") if pycu_arr.flags.f_contiguous: @@ -195,7 +188,7 @@ def pyopencl_to_af_array(pycl_arr, copy=True): if dev_idx == dev and ctx_idx == ctx: break - if (dev_idx is None or ctx_idx is None or dev_idx != dev or ctx_idx != ctx): + if (not dev_idx or not ctx_idx or dev_idx != dev or ctx_idx != ctx): print("Adding context and queue") _add_device_context(dev, ctx, que) _set_device_context(dev, ctx) @@ -205,7 +198,7 @@ def pyopencl_to_af_array(pycl_arr, copy=True): in_shape = pycl_arr.shape in_dtype = pycl_arr.dtype.char - if not copy and not pycl_arr.flags.f_contiguous: + if not (copy or pycl_arr.flags.f_contiguous): raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") print("Copying array") @@ -218,14 +211,11 @@ def pyopencl_to_af_array(pycl_arr, copy=True): return pyopencl_to_af_array(pycl_arr.copy()) try: - # FIXME: numba imported but unused - import numba -except ImportError: - AF_NUMBA_FOUND = False -else: from numba import cuda NumbaCudaArray = cuda.cudadrv.devicearray.DeviceNDArray AF_NUMBA_FOUND = True +except ImportError: + AF_NUMBA_FOUND = False def numba_to_af_array(nb_arr, copy=True): """ @@ -251,7 +241,7 @@ def numba_to_af_array(nb_arr, copy=True): in_shape = nb_arr.shape in_dtype = _nptype_to_aftype[nb_arr.dtype.str[1:]] - if not copy and not nb_arr.flags.f_contiguous: + if not (copy or nb_arr.flags.f_contiguous): raise RuntimeError("Copy can only be False when arr.flags.f_contiguous is True") if nb_arr.is_f_contiguous(): diff --git a/arrayfire/library.py b/arrayfire/library.py index f4031cc5b..daf2aecf1 100644 --- a/arrayfire/library.py +++ b/arrayfire/library.py @@ -16,26 +16,28 @@ import os import traceback -c_float_t = ct.c_float -c_double_t = ct.c_double -c_int_t = ct.c_int -c_uint_t = ct.c_uint -c_longlong_t = ct.c_longlong +c_float_t = ct.c_float +c_double_t = ct.c_double +c_int_t = ct.c_int +c_uint_t = ct.c_uint +c_longlong_t = ct.c_longlong c_ulonglong_t = ct.c_ulonglong -c_char_t = ct.c_char -c_bool_t = ct.c_bool -c_uchar_t = ct.c_ubyte -c_short_t = ct.c_short -c_ushort_t = ct.c_ushort -c_pointer = ct.pointer -c_void_ptr_t = ct.c_void_p -c_char_ptr_t = ct.c_char_p -c_size_t = ct.c_size_t -c_cast = ct.cast +c_char_t = ct.c_char +c_bool_t = ct.c_bool +c_uchar_t = ct.c_ubyte +c_short_t = ct.c_short +c_ushort_t = ct.c_ushort +c_pointer = ct.pointer +c_void_ptr_t = ct.c_void_p +c_char_ptr_t = ct.c_char_p +c_size_t = ct.c_size_t +c_cast = ct.cast + class af_cfloat_t(ct.Structure): _fields_ = [("real", ct.c_float), ("imag", ct.c_float)] + class af_cdouble_t(ct.Structure): _fields_ = [("real", ct.c_double), ("imag", ct.c_double)] @@ -46,6 +48,7 @@ class af_cdouble_t(ct.Structure): # Work around for unexpected architectures if 'c_dim_t_forced' in globals(): global c_dim_t_forced + # FIXME c_dim_t_forced is undefined c_dim_t = c_dim_t_forced else: # dim_t is long long by default @@ -57,7 +60,9 @@ class af_cdouble_t(ct.Structure): c_dim_t = c_int_t try: + # FIXME consider using the Enum or custom clas. No need in this check. from enum import Enum as _Enum + def _Enum_Type(v): return v except ImportError: @@ -71,49 +76,52 @@ def __init__(cls, name, bases, attrs): class _Enum(object): __metaclass__ = _MetaEnum + # FIXME class _Enum_Type(object): def __init__(self, v): self.value = v + class ERR(_Enum): """ Error values. For internal use only. """ - NONE = _Enum_Type(0) + NONE = _Enum_Type(0) - #100-199 Errors in environment - NO_MEM = _Enum_Type(101) - DRIVER = _Enum_Type(102) - RUNTIME = _Enum_Type(103) + # 100-199 Errors in environment + NO_MEM = _Enum_Type(101) + DRIVER = _Enum_Type(102) + RUNTIME = _Enum_Type(103) # 200-299 Errors in input parameters - INVALID_ARRAY = _Enum_Type(201) - ARG = _Enum_Type(202) - SIZE = _Enum_Type(203) - TYPE = _Enum_Type(204) - DIFF_TYPE = _Enum_Type(205) - BATCH = _Enum_Type(207) - DEVICE = _Enum_Type(208) + INVALID_ARRAY = _Enum_Type(201) + ARG = _Enum_Type(202) + SIZE = _Enum_Type(203) + TYPE = _Enum_Type(204) + DIFF_TYPE = _Enum_Type(205) + BATCH = _Enum_Type(207) + DEVICE = _Enum_Type(208) # 300-399 Errors for missing software features - NOT_SUPPORTED = _Enum_Type(301) + NOT_SUPPORTED = _Enum_Type(301) NOT_CONFIGURED = _Enum_Type(302) - NONFREE = _Enum_Type(303) + NONFREE = _Enum_Type(303) # 400-499 Errors for missing hardware features - NO_DBL = _Enum_Type(401) - NO_GFX = _Enum_Type(402) - NO_HALF = _Enum_Type(403) + NO_DBL = _Enum_Type(401) + NO_GFX = _Enum_Type(402) + NO_HALF = _Enum_Type(403) # 500-599 Errors specific to the heterogeneous API - LOAD_LIB = _Enum_Type(501) - LOAD_SYM = _Enum_Type(502) + LOAD_LIB = _Enum_Type(501) + LOAD_SYM = _Enum_Type(502) ARR_BKND_MISMATCH = _Enum_Type(503) # 900-999 Errors from upstream libraries and runtimes - INTERNAL = _Enum_Type(998) - UNKNOWN = _Enum_Type(999) + INTERNAL = _Enum_Type(998) + UNKNOWN = _Enum_Type(999) + class Dtype(_Enum): """ @@ -123,77 +131,85 @@ class Dtype(_Enum): c32 = _Enum_Type(1) f64 = _Enum_Type(2) c64 = _Enum_Type(3) - b8 = _Enum_Type(4) + b8 = _Enum_Type(4) s32 = _Enum_Type(5) u32 = _Enum_Type(6) - u8 = _Enum_Type(7) + u8 = _Enum_Type(7) s64 = _Enum_Type(8) u64 = _Enum_Type(9) s16 = _Enum_Type(10) u16 = _Enum_Type(11) f16 = _Enum_Type(12) + class Source(_Enum): """ Source of the pointer """ device = _Enum_Type(0) - host = _Enum_Type(1) + host = _Enum_Type(1) + class INTERP(_Enum): """ Interpolation method """ - NEAREST = _Enum_Type(0) - LINEAR = _Enum_Type(1) - BILINEAR = _Enum_Type(2) - CUBIC = _Enum_Type(3) - LOWER = _Enum_Type(4) - LINEAR_COSINE = _Enum_Type(5) + NEAREST = _Enum_Type(0) + LINEAR = _Enum_Type(1) + BILINEAR = _Enum_Type(2) + CUBIC = _Enum_Type(3) + LOWER = _Enum_Type(4) + LINEAR_COSINE = _Enum_Type(5) BILINEAR_COSINE = _Enum_Type(6) - BICUBIC = _Enum_Type(7) - CUBIC_SPLINE = _Enum_Type(8) - BICUBIC_SPLINE = _Enum_Type(9) + BICUBIC = _Enum_Type(7) + CUBIC_SPLINE = _Enum_Type(8) + BICUBIC_SPLINE = _Enum_Type(9) + class PAD(_Enum): """ Edge padding types """ ZERO = _Enum_Type(0) - SYM = _Enum_Type(1) - CLAMP_TO_EDGE = _Enum_Type(2) + SYM = _Enum_Type(1) + CLAMP_TO_EDGE = _Enum_Type(2) PERIODIC = _Enum_Type(3) + class CONNECTIVITY(_Enum): """ Neighborhood connectivity """ - FOUR = _Enum_Type(4) + FOUR = _Enum_Type(4) EIGHT = _Enum_Type(8) + class CONV_MODE(_Enum): """ Convolution mode """ DEFAULT = _Enum_Type(0) - EXPAND = _Enum_Type(1) + EXPAND = _Enum_Type(1) + class CONV_DOMAIN(_Enum): """ Convolution domain """ - AUTO = _Enum_Type(0) + AUTO = _Enum_Type(0) SPATIAL = _Enum_Type(1) - FREQ = _Enum_Type(2) + FREQ = _Enum_Type(2) + class CONV_GRADIENT(_Enum): """ Convolution gradient type """ DEFAULT = _Enum_Type(0) - FILTER = _Enum_Type(1) - DATA = _Enum_Type(2) - BIAS = _Enum_Type(3) + FILTER = _Enum_Type(1) + DATA = _Enum_Type(2) + BIAS = _Enum_Type(3) + class MATCH(_Enum): """ @@ -203,7 +219,7 @@ class MATCH(_Enum): """ Sum of absolute differences """ - SAD = _Enum_Type(0) + SAD = _Enum_Type(0) """ Zero mean SAD @@ -218,7 +234,7 @@ class MATCH(_Enum): """ Sum of squared differences """ - SSD = _Enum_Type(3) + SSD = _Enum_Type(3) """ Zero mean SSD @@ -233,7 +249,7 @@ class MATCH(_Enum): """ Normalized cross correlation """ - NCC = _Enum_Type(6) + NCC = _Enum_Type(6) """ Zero mean NCC @@ -243,25 +259,27 @@ class MATCH(_Enum): """ Sum of hamming distances """ - SHD = _Enum_Type(8) + SHD = _Enum_Type(8) class YCC_STD(_Enum): """ YCC Standard formats """ - BT_601 = _Enum_Type(601) - BT_709 = _Enum_Type(709) - BT_2020 = _Enum_Type(2020) + BT_601 = _Enum_Type(601) + BT_709 = _Enum_Type(709) + BT_2020 = _Enum_Type(2020) + class CSPACE(_Enum): """ Colorspace formats """ GRAY = _Enum_Type(0) - RGB = _Enum_Type(1) - HSV = _Enum_Type(2) - YCbCr= _Enum_Type(3) + RGB = _Enum_Type(1) + HSV = _Enum_Type(2) + YCbCr = _Enum_Type(3) + class MATPROP(_Enum): """ @@ -271,169 +289,180 @@ class MATPROP(_Enum): """ None, general. """ - NONE = _Enum_Type(0) + NONE = _Enum_Type(0) """ Transposed. """ - TRANS = _Enum_Type(1) + TRANS = _Enum_Type(1) """ Conjugate transposed. """ - CTRANS = _Enum_Type(2) + CTRANS = _Enum_Type(2) """ Upper triangular matrix. """ - UPPER = _Enum_Type(32) + UPPER = _Enum_Type(32) """ Lower triangular matrix. """ - LOWER = _Enum_Type(64) + LOWER = _Enum_Type(64) """ Treat diagonal as units. """ - DIAG_UNIT = _Enum_Type(128) + DIAG_UNIT = _Enum_Type(128) """ Symmetric matrix. """ - SYM = _Enum_Type(512) + SYM = _Enum_Type(512) """ Positive definite matrix. """ - POSDEF = _Enum_Type(1024) + POSDEF = _Enum_Type(1024) """ Orthogonal matrix. """ - ORTHOG = _Enum_Type(2048) + ORTHOG = _Enum_Type(2048) """ Tri diagonal matrix. """ - TRI_DIAG = _Enum_Type(4096) + TRI_DIAG = _Enum_Type(4096) """ Block diagonal matrix. """ BLOCK_DIAG = _Enum_Type(8192) + class NORM(_Enum): """ Norm types """ - VECTOR_1 = _Enum_Type(0) - VECTOR_INF = _Enum_Type(1) - VECTOR_2 = _Enum_Type(2) - VECTOR_P = _Enum_Type(3) - MATRIX_1 = _Enum_Type(4) - MATRIX_INF = _Enum_Type(5) - MATRIX_2 = _Enum_Type(6) + VECTOR_1 = _Enum_Type(0) + VECTOR_INF = _Enum_Type(1) + VECTOR_2 = _Enum_Type(2) + VECTOR_P = _Enum_Type(3) + MATRIX_1 = _Enum_Type(4) + MATRIX_INF = _Enum_Type(5) + MATRIX_2 = _Enum_Type(6) MATRIX_L_PQ = _Enum_Type(7) - EUCLID = VECTOR_2 + EUCLID = VECTOR_2 + class COLORMAP(_Enum): """ Colormaps """ - DEFAULT = _Enum_Type(0) + DEFAULT = _Enum_Type(0) SPECTRUM = _Enum_Type(1) - COLORS = _Enum_Type(2) - RED = _Enum_Type(3) - MOOD = _Enum_Type(4) - HEAT = _Enum_Type(5) - BLUE = _Enum_Type(6) + COLORS = _Enum_Type(2) + RED = _Enum_Type(3) + MOOD = _Enum_Type(4) + HEAT = _Enum_Type(5) + BLUE = _Enum_Type(6) + class IMAGE_FORMAT(_Enum): """ Image Formats """ - BMP = _Enum_Type(0) - ICO = _Enum_Type(1) - JPEG = _Enum_Type(2) - JNG = _Enum_Type(3) - PNG = _Enum_Type(13) - PPM = _Enum_Type(14) - PPMRAW = _Enum_Type(15) - TIFF = _Enum_Type(18) - PSD = _Enum_Type(20) - HDR = _Enum_Type(26) - EXR = _Enum_Type(29) - JP2 = _Enum_Type(31) - RAW = _Enum_Type(34) + BMP = _Enum_Type(0) + ICO = _Enum_Type(1) + JPEG = _Enum_Type(2) + JNG = _Enum_Type(3) + PNG = _Enum_Type(13) + PPM = _Enum_Type(14) + PPMRAW = _Enum_Type(15) + TIFF = _Enum_Type(18) + PSD = _Enum_Type(20) + HDR = _Enum_Type(26) + EXR = _Enum_Type(29) + JP2 = _Enum_Type(31) + RAW = _Enum_Type(34) + class HOMOGRAPHY(_Enum): """ Homography Types """ - RANSAC = _Enum_Type(0) - LMEDS = _Enum_Type(1) + RANSAC = _Enum_Type(0) + LMEDS = _Enum_Type(1) + class BACKEND(_Enum): """ Backend libraries """ DEFAULT = _Enum_Type(0) - CPU = _Enum_Type(1) - CUDA = _Enum_Type(2) - OPENCL = _Enum_Type(4) + CPU = _Enum_Type(1) + CUDA = _Enum_Type(2) + OPENCL = _Enum_Type(4) + class MARKER(_Enum): """ Markers used for different points in graphics plots """ - NONE = _Enum_Type(0) - POINT = _Enum_Type(1) - CIRCLE = _Enum_Type(2) - SQUARE = _Enum_Type(3) - TRIANGE = _Enum_Type(4) - CROSS = _Enum_Type(5) - PLUS = _Enum_Type(6) - STAR = _Enum_Type(7) + NONE = _Enum_Type(0) + POINT = _Enum_Type(1) + CIRCLE = _Enum_Type(2) + SQUARE = _Enum_Type(3) + TRIANGE = _Enum_Type(4) + CROSS = _Enum_Type(5) + PLUS = _Enum_Type(6) + STAR = _Enum_Type(7) + class MOMENT(_Enum): """ Image Moments types """ - M00 = _Enum_Type(1) - M01 = _Enum_Type(2) - M10 = _Enum_Type(4) - M11 = _Enum_Type(8) + M00 = _Enum_Type(1) + M01 = _Enum_Type(2) + M10 = _Enum_Type(4) + M11 = _Enum_Type(8) FIRST_ORDER = _Enum_Type(15) + class BINARYOP(_Enum): """ Binary Operators """ - ADD = _Enum_Type(0) - MUL = _Enum_Type(1) - MIN = _Enum_Type(2) - MAX = _Enum_Type(3) + ADD = _Enum_Type(0) + MUL = _Enum_Type(1) + MIN = _Enum_Type(2) + MAX = _Enum_Type(3) + class RANDOM_ENGINE(_Enum): """ Random engine types """ - PHILOX_4X32_10 = _Enum_Type(100) + PHILOX_4X32_10 = _Enum_Type(100) THREEFRY_2X32_16 = _Enum_Type(200) MERSENNE_GP11213 = _Enum_Type(300) - PHILOX = PHILOX_4X32_10 - THREEFRY = THREEFRY_2X32_16 - DEFAULT = PHILOX + PHILOX = PHILOX_4X32_10 + THREEFRY = THREEFRY_2X32_16 + DEFAULT = PHILOX + class STORAGE(_Enum): """ Matrix Storage types """ DENSE = _Enum_Type(0) - CSR = _Enum_Type(1) - CSC = _Enum_Type(2) - COO = _Enum_Type(3) + CSR = _Enum_Type(1) + CSC = _Enum_Type(2) + COO = _Enum_Type(3) + class CANNY_THRESHOLD(_Enum): """ @@ -442,54 +471,59 @@ class CANNY_THRESHOLD(_Enum): MANUAL = _Enum_Type(0) AUTO_OTSU = _Enum_Type(1) + class FLUX(_Enum): """ Flux functions """ - DEFAULT = _Enum_Type(0) - QUADRATIC = _Enum_Type(1) + DEFAULT = _Enum_Type(0) + QUADRATIC = _Enum_Type(1) EXPONENTIAL = _Enum_Type(2) + class DIFFUSION(_Enum): """ Diffusion equations """ DEFAULT = _Enum_Type(0) - GRAD = _Enum_Type(1) - MCDE = _Enum_Type(2) + GRAD = _Enum_Type(1) + MCDE = _Enum_Type(2) + class TOPK(_Enum): """ Top-K ordering """ DEFAULT = _Enum_Type(0) - MIN = _Enum_Type(1) - MAX = _Enum_Type(2) + MIN = _Enum_Type(1) + MAX = _Enum_Type(2) + class ITERATIVE_DECONV(_Enum): """ Iterative deconvolution algorithm """ - DEFAULT = _Enum_Type(0) - LANDWEBER = _Enum_Type(1) + DEFAULT = _Enum_Type(0) + LANDWEBER = _Enum_Type(1) RICHARDSONLUCY = _Enum_Type(2) + class INVERSE_DECONV(_Enum): """ Inverse deconvolution algorithm """ - DEFAULT = _Enum_Type(0) - TIKHONOV = _Enum_Type(1) + DEFAULT = _Enum_Type(0) + TIKHONOV = _Enum_Type(1) + class VARIANCE(_Enum): """ Variance bias type """ - DEFAULT = _Enum_Type(0) - SAMPLE = _Enum_Type(1) + DEFAULT = _Enum_Type(0) + SAMPLE = _Enum_Type(1) POPULATION = _Enum_Type(2) -from .util import to_str AF_VER_MAJOR = "3" FORGE_VER_MAJOR = "1" @@ -526,10 +560,10 @@ def _setup(): # https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx ct.windll.kernel32.SetErrorMode(0x0001 | 0x0002) - if AF_SEARCH_PATH is None: + if not AF_SEARCH_PATH: AF_SEARCH_PATH = "C:/Program Files/ArrayFire/v" + AF_VER_MAJOR + "/" - if CUDA_PATH is not None: + if CUDA_PATH: CUDA_FOUND = os.path.isdir(CUDA_PATH + "/bin") and os.path.isdir(CUDA_PATH + "/nvvm/bin/") elif platform_name == "Darwin": @@ -537,13 +571,13 @@ def _setup(): pre = "lib" post = "." + _VER_MAJOR_PLACEHOLDER + ".dylib" - if AF_SEARCH_PATH is None: + if not AF_SEARCH_PATH: if os.path.exists('/opt/arrayfire'): AF_SEARCH_PATH = '/opt/arrayfire/' else: AF_SEARCH_PATH = '/usr/local/' - if CUDA_PATH is None: + if not CUDA_PATH: CUDA_PATH = "/usr/local/cuda/" CUDA_FOUND = os.path.isdir(CUDA_PATH + "/lib") and os.path.isdir(CUDA_PATH + "/nvvm/lib") @@ -552,10 +586,10 @@ def _setup(): pre = "lib" post = ".so." + _VER_MAJOR_PLACEHOLDER - if AF_SEARCH_PATH is None: + if not AF_SEARCH_PATH: AF_SEARCH_PATH = "/opt/arrayfire-" + AF_VER_MAJOR + "/" - if CUDA_PATH is None: + if not CUDA_PATH: CUDA_PATH = "/usr/local/cuda/" if platform.architecture()[0][:2] == "64": @@ -565,14 +599,13 @@ def _setup(): else: raise OSError(platform_name + " not supported") - if AF_PATH is None: + if not AF_PATH: os.environ["AF_PATH"] = AF_SEARCH_PATH return pre, post, AF_SEARCH_PATH, CUDA_FOUND class _clibrary(object): - def __libname(self, name, head="af", ver_major=AF_VER_MAJOR): post = self.__post.replace(_VER_MAJOR_PLACEHOLDER, ver_major) libname = self.__pre + head + name + post @@ -583,8 +616,7 @@ def __libname(self, name, head="af", ver_major=AF_VER_MAJOR): return (libname, libname_full) def set_unsafe(self, name): - lib = self.__clibs[name] - if lib is None: + if not self.__clibs[name]: raise RuntimeError("Backend not found") self.__name = name @@ -664,7 +696,7 @@ def __init__(self): traceback.print_exc() print("Unable to load " + libname) - if self.__name is None: + if not self.__name: raise RuntimeError("Could not load any ArrayFire libraries.\n" + more_info_str) def get_id(self, name): @@ -817,3 +849,11 @@ def safe_call(af_error): err_len = c_dim_t(0) backend.get().af_get_last_error(c_pointer(err_str), c_pointer(err_len)) raise RuntimeError(to_str(err_str)) + + +def to_str(c_str): + return str(c_str.value.decode('utf-8')) + + +def get_complex_number(real, imag): + return real.value if not imag.value else real.value + imag.value * 1j diff --git a/arrayfire/opencl.py b/arrayfire/opencl.py index 5c21e5cb8..0cde30a33 100644 --- a/arrayfire/opencl.py +++ b/arrayfire/opencl.py @@ -58,8 +58,7 @@ def get_context(retain=False): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) context = c_void_ptr_t(0) safe_call(backend.get().afcl_get_context(c_pointer(context), retain)) @@ -85,8 +84,7 @@ def get_queue(retain): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) queue = c_int_t(0) safe_call(backend.get().afcl_get_queue(c_pointer(queue), retain)) @@ -108,8 +106,7 @@ def get_device_id(): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) idx = c_int_t(0) safe_call(backend.get().afcl_get_device_id(c_pointer(idx))) @@ -131,8 +128,7 @@ def set_device_id(idx): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) safe_call(backend.get().afcl_set_device_id(idx)) return @@ -157,8 +153,7 @@ def add_device_context(dev, ctx, que): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) safe_call(backend.get().afcl_add_device_context(dev, ctx, que)) @@ -180,8 +175,7 @@ def set_device_context(dev, ctx): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) safe_call(backend.get().afcl_set_device_context(dev, ctx)) @@ -203,8 +197,7 @@ def delete_device_context(dev, ctx): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) safe_call(backend.get().afcl_delete_device_context(dev, ctx)) @@ -234,8 +227,7 @@ def get_device_type(): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) res = c_int_t(DEVICE_TYPE.UNKNOWN.value) safe_call(backend.get().afcl_get_device_type(c_pointer(res))) @@ -251,9 +243,13 @@ def get_platform(): from .util import safe_call as safe_call from .library import backend - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") + _check_backend(backend) res = c_int_t(PLATFORM.UNKNOWN.value) safe_call(backend.get().afcl_get_platform(c_pointer(res))) return _to_platform[res.value] + + +def _check_backend(backend): + if backend.name() != "opencl": + raise RuntimeError("Invalid backend loaded") diff --git a/arrayfire/random.py b/arrayfire/random.py index 622660342..fd2f2a298 100644 --- a/arrayfire/random.py +++ b/arrayfire/random.py @@ -12,7 +12,8 @@ """ from .array import Array -from .library import backend, safe_call, RANDOM_ENGINE, Dtype, c_int_t, c_longlong_t, c_pointer, c_ulonglong_t, c_void_ptr_t +from .library import ( + RANDOM_ENGINE, Dtype, backend, c_int_t, c_longlong_t, c_pointer, c_ulonglong_t, c_void_ptr_t, safe_call) from .util import dim4 @@ -165,7 +166,7 @@ def randn(d0, d1=None, d2=None, d3=None, dtype=Dtype.f32, engine=None): out = Array() dims = dim4(d0, d1, d2, d3) - if engine is None: + if not engine: safe_call(backend.get().af_randn(c_pointer(out.arr), 4, c_pointer(dims), dtype.value)) else: safe_call(backend.get().af_random_normal(c_pointer(out.arr), 4, c_pointer(dims), dtype.value, engine.engine)) diff --git a/arrayfire/signal.py b/arrayfire/signal.py index 059b584a7..13a411691 100644 --- a/arrayfire/signal.py +++ b/arrayfire/signal.py @@ -13,8 +13,9 @@ from .array import Array from .bcast import broadcast -from .library import backend, safe_call, CONV_DOMAIN, CONV_MODE, INTERP, PAD, c_dim_t, c_double_t, c_float_t, c_pointer, c_size_t -from .util import dim4, dim4_to_tuple +from .library import ( + backend, safe_call, CONV_DOMAIN, CONV_MODE, INTERP, PAD, c_dim_t, c_double_t, c_float_t, c_pointer, c_size_t) +from .util import dim4 @broadcast @@ -31,7 +32,7 @@ def _scale_pos_axis1(y_curr, y_orig): return (y_curr - y0) / dy -def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp = None, output = None): +def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp=None, output=None): """ Interpolate along a single dimension.Interpolation is performed along axis 0 of the input array. @@ -40,20 +41,19 @@ def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp = None, output = N ---------- signal: af.Array - Input signal array (signal = f(x)) + Input signal array (signal = f(x)) x: af.Array - The x-coordinates of the interpolation points. The interpolation - function is queried at these set of points. + The x-coordinates of the interpolation points. The interpolation function is queried at these set of points. method: optional: af.INTERP. default: af.INTERP.LINEAR. - Interpolation method. + Interpolation method. off_grid: optional: scalar. default: 0.0. - The value used for positions outside the range. + The value used for positions outside the range. xp : af.Array - The x-coordinates of the input data points + The x-coordinates of the input data points output: None or af.Array Optional preallocated output array. If it is a sub-array of an existing af_array, @@ -63,7 +63,7 @@ def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp = None, output = N ------- output: af.Array - Values calculated at interpolation points. + Values calculated at interpolation points. Note @@ -72,29 +72,19 @@ def approx1(signal, x, method=INTERP.LINEAR, off_grid=0.0, xp = None, output = N The initial measurements are assumed to have taken place at equal steps between [0, N - 1], where N is the length of the first dimension of `signal`. """ + pos0 = _scale_pos_axis0(x, xp) if xp is not None else x if output is None: output = Array() - - if(xp is not None): - pos0 = _scale_pos_axis0(x, xp) - else: - pos0 = x - - safe_call(backend.get().af_approx1(c_pointer(output.arr), signal.arr, pos0.arr, - method.value, c_float_t(off_grid))) - + safe_call(backend.get().af_approx1( + c_pointer(output.arr), signal.arr, pos0.arr, method.value, c_float_t(off_grid))) else: - if(xp is not None): - pos0 = _scale_pos_axis0(x, xp) - else: - pos0 = x - safe_call(backend.get().af_approx1_v2(c_pointer(output.arr), signal.arr, pos0.arr, - method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx1_v2( + c_pointer(output.arr), signal.arr, pos0.arr, method.value, c_float_t(off_grid))) return output -def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LINEAR, off_grid=0.0, output = None): +def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LINEAR, off_grid=0.0, output=None): """ Interpolation on one dimensional signals along specified dimension. @@ -105,11 +95,10 @@ def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LI ---------- signal: af.Array - Input signal array (signal = f(x)) + Input signal array (signal = f(x)) x: af.Array - The x-coordinates of the interpolation points. The interpolation - function is queried at these set of points. + The x-coordinates of the interpolation points. The interpolation function is queried at these set of points. interp_dim: scalar is the dimension to perform interpolation across. @@ -121,10 +110,10 @@ def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LI is the uniform spacing value between subsequent indices along interp_dim. method: optional: af.INTERP. default: af.INTERP.LINEAR. - Interpolation method. + Interpolation method. off_grid: optional: scalar. default: 0.0. - The value used for positions outside the range. + The value used for positions outside the range. output: None or af.Array Optional preallocated output array. If it is a sub-array of an existing af_array, @@ -134,25 +123,23 @@ def approx1_uniform(signal, x, interp_dim, idx_start, idx_step, method=INTERP.LI ------- output: af.Array - Values calculated at interpolation points. + Values calculated at interpolation points. """ if output is None: output = Array() - - safe_call(backend.get().af_approx1_uniform(c_pointer(output.arr), signal.arr, x.arr, - c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), - method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx1_uniform( + c_pointer(output.arr), signal.arr, x.arr, c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), + method.value, c_float_t(off_grid))) else: - safe_call(backend.get().af_approx1_uniform_v2(c_pointer(output.arr), signal.arr, x.arr, - c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), - method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx1_uniform_v2( + c_pointer(output.arr), signal.arr, x.arr, c_dim_t(interp_dim), c_double_t(idx_start), c_double_t(idx_step), + method.value, c_float_t(off_grid))) return output -def approx2(signal, x, y, - method=INTERP.LINEAR, off_grid=0.0, xp = None, yp = None, output = None): +def approx2(signal, x, y, method=INTERP.LINEAR, off_grid=0.0, xp=None, yp=None, output=None): """ Interpolate along a two dimension.Interpolation is performed along axes 0 and 1 of the input array. @@ -204,41 +191,23 @@ def approx2(signal, x, y, where M is the length of the first dimension of `signal`, and N is the length of the second dimension of `signal`. """ + pos0 = _scale_pos_axis0(x, xp) if xp is not None else x + pos1 = _scale_pos_axis1(y, yp) if yp is not None else y if output is None: output = Array() - - if(xp is not None): - pos0 = _scale_pos_axis0(x, xp) - else: - pos0 = x - - if(yp is not None): - pos1 = _scale_pos_axis1(y, yp) - else: - pos1 = y - - safe_call(backend.get().af_approx2(c_pointer(output.arr), signal.arr, - pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx2( + c_pointer(output.arr), signal.arr, pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) else: - if(xp is not None): - pos0 = _scale_pos_axis0(x, xp) - else: - pos0 = x - - if(yp is not None): - pos1 = _scale_pos_axis1(y, yp) - else: - pos1 = y - - safe_call(backend.get().af_approx2_v2(c_pointer(output.arr), signal.arr, - pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx2_v2( + c_pointer(output.arr), signal.arr, pos0.arr, pos1.arr, method.value, c_float_t(off_grid))) return output -def approx2_uniform(signal, pos0, interp_dim0, idx_start0, idx_step0, pos1, interp_dim1, idx_start1, idx_step1, - method=INTERP.LINEAR, off_grid=0.0, output = None): +def approx2_uniform( + signal, pos0, interp_dim0, idx_start0, idx_step0, pos1, interp_dim1, idx_start1, idx_step1, + method=INTERP.LINEAR, off_grid=0.0, output=None): """ Interpolate along two uniformly spaced dimensions of the input array. af_approx2_uniform() accepts two dimensions to perform the interpolation along the input. @@ -298,23 +267,21 @@ def approx2_uniform(signal, pos0, interp_dim0, idx_start0, idx_step0, pos1, inte where M is the length of the first dimension of `signal`, and N is the length of the second dimension of `signal`. """ - - if output is None: + if not output: output = Array() - safe_call(backend.get().af_approx2_uniform(c_pointer(output.arr), signal.arr, - pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), c_double_t(idx_step0), - pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), - method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx2_uniform( + c_pointer(output.arr), signal.arr, pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), + c_double_t(idx_step0), pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), + method.value, c_float_t(off_grid))) else: - safe_call(backend.get().af_approx2_uniform_v2(c_pointer(output.arr), signal.arr, - pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), c_double_t(idx_step0), - pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), - method.value, c_float_t(off_grid))) + safe_call(backend.get().af_approx2_uniform_v2( + c_pointer(output.arr), signal.arr, pos0.arr, c_dim_t(interp_dim0), c_double_t(idx_start0), + c_double_t(idx_step0), pos1.arr, c_dim_t(interp_dim1), c_double_t(idx_start1), c_double_t(idx_step1), + method.value, c_float_t(off_grid))) return output - -def fft(signal, dim0 = None , scale = None): +def fft(signal, dim0=None, scale=None): """ Fast Fourier Transform: 1D @@ -654,8 +621,6 @@ def fft3_inplace(signal, scale=None): if scale is None: scale = 1.0 - # FIXME: output is assigned, but not used in function - output = Array() safe_call(backend.get().af_fft3_inplace(signal.arr, c_double_t(scale))) @@ -995,9 +960,6 @@ def dft(signal, odims=(None, None, None, None), scale=None): - A complex array that is the ouput of n-dimensional fourier transform. """ - # FIXME: odims4 is assigned, but not used in function - odims4 = dim4_to_tuple(odims, default=None) - dims = signal.dims() ndims = len(dims) @@ -1039,9 +1001,6 @@ def idft(signal, scale=None, odims=(None, None, None, None)): the output is always complex. """ - # FIXME: odims4 is assigned, but not used in function - odims4 = dim4_to_tuple(odims, default=None) - dims = signal.dims() ndims = len(dims) @@ -1151,7 +1110,8 @@ def convolve2(signal, kernel, conv_mode=CONV_MODE.DEFAULT, conv_domain=CONV_DOMA c_pointer(output.arr), signal.arr, kernel.arr, conv_mode.value, conv_domain.value)) return output -def convolve2NN(signal, kernel, stride = (1, 1), padding = (0, 0), dilation = (1, 1)): + +def convolve2NN(signal, kernel, stride=(1, 1), padding=(0, 0), dilation=(1, 1)): """ This version of convolution is consistent with the machine learning formulation that will spatially convolve a filter on 2-dimensions against a @@ -1191,17 +1151,17 @@ def convolve2NN(signal, kernel, stride = (1, 1), padding = (0, 0), dilation = (1 """ output = Array() - stride_dim = dim4(stride[0], stride[1]) - padding_dim = dim4(padding[0], padding[1]) + stride_dim = dim4(stride[0], stride[1]) + padding_dim = dim4(padding[0], padding[1]) dilation_dim = dim4(dilation[0], dilation[1]) - safe_call(backend.get().af_convolve2_nn(c_pointer(output.arr), signal.arr, kernel.arr, - 2, c_pointer(stride_dim), - 2, c_pointer(padding_dim), - 2, c_pointer(dilation_dim))) + safe_call(backend.get().af_convolve2_nn( + c_pointer(output.arr), signal.arr, kernel.arr, 2, c_pointer(stride_dim), 2, c_pointer(padding_dim), + 2, c_pointer(dilation_dim))) return output -def convolve2_separable(col_kernel, row_kernel, signal, conv_mode = CONV_MODE.DEFAULT): + +def convolve2_separable(col_kernel, row_kernel, signal, conv_mode=CONV_MODE.DEFAULT): """ Convolution: 2D separable convolution diff --git a/arrayfire/statistics.py b/arrayfire/statistics.py index bc51fcbad..278c05665 100644 --- a/arrayfire/statistics.py +++ b/arrayfire/statistics.py @@ -12,7 +12,7 @@ """ from .array import Array -from .library import TOPK, VARIANCE, c_double_t, c_int_t, c_pointer, backend, safe_call +from .library import TOPK, VARIANCE, c_double_t, c_int_t, c_pointer, backend, safe_call, get_complex_number def mean(a, weights=None, dim=None): @@ -55,10 +55,7 @@ def mean(a, weights=None, dim=None): else: safe_call(backend.get().af_mean_all_weighted(c_pointer(real), c_pointer(imag), a.arr, weights.arr)) - real = real.value - imag = imag.value - - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def var(a, isbiased=False, weights=None, dim=None): @@ -105,10 +102,7 @@ def var(a, isbiased=False, weights=None, dim=None): else: safe_call(backend.get().af_var_all_weighted(c_pointer(real), c_pointer(imag), a.arr, weights.arr)) - real = real.value - imag = imag.value - - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def meanvar(a, weights=None, bias=VARIANCE.DEFAULT, dim=-1): @@ -142,13 +136,13 @@ def meanvar(a, weights=None, bias=VARIANCE.DEFAULT, dim=-1): """ mean_out = Array() - var_out = Array() + var_out = Array() if weights is None: - weights = Array() + weights = Array() - safe_call(backend.get().af_meanvar(c_pointer(mean_out.arr), c_pointer(var_out.arr), - a.arr, weights.arr, bias.value, c_int_t(dim))) + safe_call(backend.get().af_meanvar( + c_pointer(mean_out.arr), c_pointer(var_out.arr), a.arr, weights.arr, bias.value, c_int_t(dim))) return mean_out, var_out @@ -180,9 +174,7 @@ def stdev(a, dim=None): real = c_double_t(0) imag = c_double_t(0) safe_call(backend.get().af_stdev_all(c_pointer(real), c_pointer(imag), a.arr)) - real = real.value - imag = imag.value - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def cov(a, isbiased=False, dim=None): @@ -206,7 +198,7 @@ def cov(a, isbiased=False, dim=None): Array containing the covariance of the input array along a given dimension. """ - if dim is not None: + if dim: out = Array() safe_call(backend.get().af_cov(c_pointer(out.arr), a.arr, isbiased, c_int_t(dim))) return out @@ -214,9 +206,7 @@ def cov(a, isbiased=False, dim=None): real = c_double_t(0) imag = c_double_t(0) safe_call(backend.get().af_cov_all(c_pointer(real), c_pointer(imag), a.arr, isbiased)) - real = real.value - imag = imag.value - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def median(a, dim=None): @@ -237,7 +227,7 @@ def median(a, dim=None): Array containing the median of the input array along a given dimension. """ - if dim is not None: + if dim: out = Array() safe_call(backend.get().af_median(c_pointer(out.arr), a.arr, c_int_t(dim))) return out @@ -245,9 +235,7 @@ def median(a, dim=None): real = c_double_t(0) imag = c_double_t(0) safe_call(backend.get().af_median_all(c_pointer(real), c_pointer(imag), a.arr)) - real = real.value - imag = imag.value - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def corrcoef(x, y): @@ -270,9 +258,7 @@ def corrcoef(x, y): real = c_double_t(0) imag = c_double_t(0) safe_call(backend.get().af_corrcoef(c_pointer(real), c_pointer(imag), x.arr, y.arr)) - real = real.value - imag = imag.value - return real if imag == 0 else real + imag * 1j + return get_complex_number(real, imag) def topk(data, k, dim=0, order=TOPK.DEFAULT): @@ -307,7 +293,7 @@ def topk(data, k, dim=0, order=TOPK.DEFAULT): values = Array() indices = Array() - safe_call( - backend.get().af_topk(c_pointer(values.arr), c_pointer(indices.arr), data.arr, k, c_int_t(dim), order.value)) + safe_call(backend.get().af_topk( + c_pointer(values.arr), c_pointer(indices.arr), data.arr, k, c_int_t(dim), order.value)) return values, indices diff --git a/arrayfire/util.py b/arrayfire/util.py index bf01639a0..95d3e7bfc 100644 --- a/arrayfire/util.py +++ b/arrayfire/util.py @@ -14,8 +14,8 @@ import numbers from .library import ( - Dtype, c_char_t, c_dim_t, c_double_t, c_float_t, c_int_t, c_longlong_t, c_short_t, c_uchar_t, c_uint_t, - c_ulonglong_t, c_ushort_t) + Dtype, backend, c_char_t, c_dim_t, c_double_t, c_float_t, c_int_t, c_longlong_t, c_pointer, + c_short_t, c_uchar_t, c_uint_t, c_ulonglong_t, c_ushort_t, safe_call, to_str) def dim4(d0=1, d1=1, d2=1, d3=1): @@ -79,19 +79,15 @@ def dim4_to_tuple(dims, default=1): return tuple(out) -def to_str(c_str): - return str(c_str.value.decode('utf-8')) - - def get_version(): """ Function to get the version of arrayfire. """ - major=c_int_t(0) - minor=c_int_t(0) - patch=c_int_t(0) + major = c_int_t(0) + minor = c_int_t(0) + patch = c_int_t(0) safe_call(backend.get().af_get_version(c_pointer(major), c_pointer(minor), c_pointer(patch))) - return major.value,minor.value,patch.value + return major.value, minor.value, patch.value def get_reversion(): @@ -100,58 +96,63 @@ def get_reversion(): """ return to_str(backend.get().af_get_revision()) -to_dtype = {'f' : Dtype.f32, - 'd' : Dtype.f64, - 'b' : Dtype.b8, - 'B' : Dtype.u8, - 'h' : Dtype.s16, - 'H' : Dtype.u16, - 'i' : Dtype.s32, - 'I' : Dtype.u32, - 'l' : Dtype.s64, - 'L' : Dtype.u64, - 'F' : Dtype.c32, - 'D' : Dtype.c64, - 'hf': Dtype.f16} - -to_typecode = {Dtype.f32.value : 'f', - Dtype.f64.value : 'd', - Dtype.b8.value : 'b', - Dtype.u8.value : 'B', - Dtype.s16.value : 'h', - Dtype.u16.value : 'H', - Dtype.s32.value : 'i', - Dtype.u32.value : 'I', - Dtype.s64.value : 'l', - Dtype.u64.value : 'L', - Dtype.c32.value : 'F', - Dtype.c64.value : 'D', - Dtype.f16.value : 'hf'} - -to_c_type = {Dtype.f32.value : c_float_t, - Dtype.f64.value : c_double_t, - Dtype.b8.value : c_char_t, - Dtype.u8.value : c_uchar_t, - Dtype.s16.value : c_short_t, - Dtype.u16.value : c_ushort_t, - Dtype.s32.value : c_int_t, - Dtype.u32.value : c_uint_t, - Dtype.s64.value : c_longlong_t, - Dtype.u64.value : c_ulonglong_t, - Dtype.c32.value : c_float_t * 2, - Dtype.c64.value : c_double_t * 2, - Dtype.f16.value : c_ushort_t} - -to_typename = {Dtype.f32.value : 'float', - Dtype.f64.value : 'double', - Dtype.b8.value : 'bool', - Dtype.u8.value : 'unsigned char', - Dtype.s16.value : 'short int', - Dtype.u16.value : 'unsigned short int', - Dtype.s32.value : 'int', - Dtype.u32.value : 'unsigned int', - Dtype.s64.value : 'long int', - Dtype.u64.value : 'unsigned long int', - Dtype.c32.value : 'float complex', - Dtype.c64.value : 'double complex', - Dtype.f16.value : 'half'} + +to_dtype = { + 'f': Dtype.f32, + 'd': Dtype.f64, + 'b': Dtype.b8, + 'B': Dtype.u8, + 'h': Dtype.s16, + 'H': Dtype.u16, + 'i': Dtype.s32, + 'I': Dtype.u32, + 'l': Dtype.s64, + 'L': Dtype.u64, + 'F': Dtype.c32, + 'D': Dtype.c64, + 'hf': Dtype.f16} + +to_typecode = { + Dtype.f32.value: 'f', + Dtype.f64.value: 'd', + Dtype.b8.value: 'b', + Dtype.u8.value: 'B', + Dtype.s16.value: 'h', + Dtype.u16.value: 'H', + Dtype.s32.value: 'i', + Dtype.u32.value: 'I', + Dtype.s64.value: 'l', + Dtype.u64.value: 'L', + Dtype.c32.value: 'F', + Dtype.c64.value: 'D', + Dtype.f16.value: 'hf'} + +to_c_type = { + Dtype.f32.value: c_float_t, + Dtype.f64.value: c_double_t, + Dtype.b8.value: c_char_t, + Dtype.u8.value: c_uchar_t, + Dtype.s16.value: c_short_t, + Dtype.u16.value: c_ushort_t, + Dtype.s32.value: c_int_t, + Dtype.u32.value: c_uint_t, + Dtype.s64.value: c_longlong_t, + Dtype.u64.value: c_ulonglong_t, + Dtype.c32.value: c_float_t * 2, + Dtype.c64.value: c_double_t * 2, + Dtype.f16.value: c_ushort_t} + +to_typename = { + Dtype.f32.value: 'float', + Dtype.f64.value: 'double', + Dtype.b8.value: 'bool', + Dtype.u8.value: 'unsigned char', + Dtype.s16.value: 'short int', + Dtype.u16.value: 'unsigned short int', + Dtype.s32.value: 'int', + Dtype.u32.value: 'unsigned int', + Dtype.s64.value: 'long int', + Dtype.u64.value: 'unsigned long int', + Dtype.c32.value: 'float complex', + Dtype.c64.value: 'double complex', + Dtype.f16.value: 'half'}