From b7cffa124098a1eed4ba0320942129c6ff7f749f Mon Sep 17 00:00:00 2001 From: Anton Chernyatevich Date: Sat, 14 Nov 2020 06:06:50 +0200 Subject: [PATCH] Flak8 refactoring. Fix minor bugs and close tags --- arrayfire/algorithm.py | 41 +++-- arrayfire/arith.py | 14 +- arrayfire/array.py | 76 ++++----- 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 | 24 ++- arrayfire/index.py | 8 +- arrayfire/interop.py | 30 ++-- arrayfire/library.py | 352 ++++++++++++++++++++++------------------ arrayfire/opencl.py | 89 ++-------- arrayfire/random.py | 3 +- arrayfire/signal.py | 152 +++++++---------- arrayfire/statistics.py | 40 ++--- arrayfire/util.py | 133 +++++++-------- 18 files changed, 486 insertions(+), 590 deletions(-) diff --git a/arrayfire/algorithm.py b/arrayfire/algorithm.py index 84d02422f..853f8ae6e 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. @@ -98,8 +109,6 @@ def sum(a, dim=None, nan_val=None): 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 is not None: 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..edd239bab 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)) @@ -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) @@ -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): @@ -464,12 +462,7 @@ def __init__(self, src=None, dims=None, dtype=None, is_device=False, offset=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 = 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 is None: 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 is not None 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 dtype is None: 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..2ab890188 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(): 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..fdab73e1c 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 @@ -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..35221c215 100644 --- a/arrayfire/opencl.py +++ b/arrayfire/opencl.py @@ -13,7 +13,9 @@ This module provides interoperability with other OpenCL libraries. """ -from .library import _Enum, _Enum_Type, c_int_t, c_pointer, c_void_ptr_t +# FIXME: import private variables +from .library import _Enum, _Enum_Type, backend, c_int_t, c_pointer, c_void_ptr_t +from .util import safe_call as safe_call class DEVICE_TYPE(_Enum): @@ -53,14 +55,7 @@ def get_context(retain=False): ----------- context : integer denoting the context id. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() context = c_void_ptr_t(0) safe_call(backend.get().afcl_get_context(c_pointer(context), retain)) return context.value @@ -80,14 +75,7 @@ def get_queue(retain): ----------- queue : integer denoting the queue id. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() queue = c_int_t(0) safe_call(backend.get().afcl_get_queue(c_pointer(queue), retain)) return queue.value @@ -103,14 +91,7 @@ def get_device_id(): idx : int. Specifies the `cl_device_id` of the device. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() idx = c_int_t(0) safe_call(backend.get().afcl_get_device_id(c_pointer(idx))) return idx.value @@ -126,14 +107,7 @@ def set_device_id(idx): idx : int. Specifies the `cl_device_id` of the device. """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() safe_call(backend.get().afcl_set_device_id(idx)) return @@ -152,14 +126,7 @@ def add_device_context(dev, ctx, que): que : cl_command_queue """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() safe_call(backend.get().afcl_add_device_context(dev, ctx, que)) @@ -176,13 +143,7 @@ def set_device_context(dev, ctx): """ # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() safe_call(backend.get().afcl_set_device_context(dev, ctx)) @@ -198,14 +159,7 @@ def delete_device_context(dev, ctx): ctx : cl_context """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() safe_call(backend.get().afcl_delete_device_context(dev, ctx)) @@ -229,14 +183,7 @@ def get_device_type(): """ Get opencl device type """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_backend() res = c_int_t(DEVICE_TYPE.UNKNOWN.value) safe_call(backend.get().afcl_get_device_type(c_pointer(res))) return _to_device_type[res.value] @@ -246,14 +193,12 @@ def get_platform(): """ Get opencl platform """ - # FIXME: ctypes imported but unused - import ctypes as ct - from .util import safe_call as safe_call - from .library import backend - - if backend.name() != "opencl": - raise RuntimeError("Invalid backend loaded") - + _check_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(): + if backend.name() != "opencl": + raise RuntimeError("Invalid backend loaded") diff --git a/arrayfire/random.py b/arrayfire/random.py index 622660342..5f3f7f5c8 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 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..7ff3efcf1 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): @@ -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): @@ -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..deadf64cc 100644 --- a/arrayfire/util.py +++ b/arrayfire/util.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,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'} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy