diff --git a/.github/workflows/rbc_test.yml b/.github/workflows/rbc_test.yml index dba87fbbe..97a9c39c5 100644 --- a/.github/workflows/rbc_test.yml +++ b/.github/workflows/rbc_test.yml @@ -7,10 +7,6 @@ on: branches: - main -env: - NUMBA_LOOP_VECTORIZE: 0 - NUMBA_SLP_VECTORIZE: 0 - # kill any previous running job on a new commit concurrency: @@ -231,8 +227,6 @@ jobs: RBC_TESTS_FULL: TRUE run: | mamba run -n rbc pytest -sv -r A rbc/tests/heavydb/ -x - pkill -f heavydb - mamba run -n rbc pytest -sv -r A rbc/tests/ -x --ignore rbc/tests/heavydb - name: Run rbc tests shell: bash -l {0} @@ -245,8 +239,13 @@ jobs: RBC_TESTS_FULL: TRUE run: | mamba run -n rbc pytest -sv -r A rbc/tests/heavydb/ -x - pkill -f heavydb - mamba run -n rbc pytest -sv -r A rbc/tests/ -x --ignore rbc/tests/heavydb + + - name: Run doctests + shell: bash -l {0} + # requires HeavyDB 6.4 or newer + if: ${{ false }} + run: | + mamba run -n rbc pytest -sv -r A rbc/stdlib/ --doctest-modules -x - name: Show Heavydb conda logs on failure [conda] shell: bash -l {0} @@ -271,6 +270,17 @@ jobs: mamba run -n heavydb-env killall heavydb sleep 5 + - name: Run Non-HeavyDB tests + shell: bash -l {0} + env: + HEAVYDB_SOURCE: ${{ matrix.heavydb-from }} + EXPECTED_PYTHON_VERSION: ${{ matrix.python-version }} + EXPECTED_HEAVYDB_VERSION: ${{ matrix.heavydb-version }} + EXPECTED_NUMBA_VERSION: ${{ matrix.numba-version }} + RBC_TESTS_FULL: TRUE + run: | + mamba run -n rbc pytest -sv -r A rbc/tests/ -x --ignore rbc/tests/heavydb + - name: Show Heavydb server output [conda] shell: bash -l {0} if: matrix.os == 'ubuntu-latest' && matrix.heavydb-from == 'conda' diff --git a/doc/conf.py b/doc/conf.py index c6a277448..c682d076e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -94,3 +94,13 @@ "github_version": "main", "doc_path": "doc", } + + +# -- ignore certain parts of the docstring ----------------------------------- +from sphinx.ext.autodoc import between + +def setup(app): + # Register a sphinx.ext.autodoc.between listener to ignore everything + # between lines that contain the word IGNORE + app.connect('autodoc-process-docstring', between('^.*IGNORE.*$', exclude=True)) + return app \ No newline at end of file diff --git a/rbc/stdlib/__init__.py b/rbc/stdlib/__init__.py index 1791e4efb..1cf30674b 100644 --- a/rbc/stdlib/__init__.py +++ b/rbc/stdlib/__init__.py @@ -1,13 +1,12 @@ +import textwrap import functools from enum import Enum from numba.core import extending from rbc.heavydb import Array, ArrayPointer from rbc import typesystem, errors - -ARRAY_API_ADDRESS = ("https://data-apis.org/array-api/latest/API_specification" - "/generated/signatures.{0}.{1}.html" - "#signatures.{0}.{1}") +ARRAY_API_ADDRESS = ("https://data-apis.org/array-api/latest/API_specification/" + "generated/array_api.{0}.html#array_api.{0}") NUMPY_API_ADDRESS = ("https://numpy.org/doc/stable/reference/generated/numpy.{0}.html") ADDRESS = ARRAY_API_ADDRESS @@ -37,6 +36,7 @@ def determine_input_type(argty): class Expose: def __init__(self, globals, module_name): self._globals = globals + # XXX: remove module_name as it is not used self.module_name = module_name def create_function(self, func_name): @@ -56,10 +56,10 @@ def format_docstring(self, ov_func, func_name, api): # Array API link = ( f"`Array-API '{func_name}' " - f"doc <{ARRAY_API_ADDRESS.format(self.module_name, func_name)}>`_") + f"doc <{ARRAY_API_ADDRESS.format(func_name)}>`_") if original_docstring is not None: - new_doctring = f"{original_docstring}\n\n{link}" + new_doctring = f"{textwrap.dedent(original_docstring)}\n\n{link}" else: new_doctring = link return new_doctring @@ -95,12 +95,12 @@ def wraps(overload_func): class BinaryUfuncExpose(Expose): - def implements(self, ufunc, ufunc_name=None, dtype=None, api=API.ARRAY_API): + def implements(self, ufunc, func_name=None, dtype=None, api=API.ARRAY_API): """ Wrapper for binary ufuncs that returns an array """ - if ufunc_name is None: - ufunc_name = ufunc.__name__ + if func_name is None: + func_name = ufunc.__name__ def binary_ufunc_impl(a, b): typA = determine_input_type(a) @@ -154,10 +154,10 @@ def impl(a, b): return nb_dtype(ufunc(cast_a, cast_b)) return impl - fn = self.create_function(ufunc_name) + fn = self.create_function(func_name) def wrapper(overload_func): - overload_func.__doc__ = self.format_docstring(overload_func, ufunc_name, api) + overload_func.__doc__ = self.format_docstring(overload_func, func_name, api) functools.update_wrapper(fn, overload_func) decorate = extending.overload(fn) @@ -168,12 +168,12 @@ def wrapper(overload_func): class UnaryUfuncExpose(BinaryUfuncExpose): - def implements(self, ufunc, ufunc_name=None, dtype=None, api=API.ARRAY_API): + def implements(self, ufunc, func_name=None, dtype=None, api=API.ARRAY_API): """ Wrapper for unary ufuncs that returns an array """ - if ufunc_name is None: - ufunc_name = ufunc.__name__ + if func_name is None: + func_name = ufunc.__name__ def unary_ufunc_impl(a): nb_dtype = determine_dtype(a, dtype) @@ -196,10 +196,10 @@ def impl(a): return nb_dtype(ufunc(cast)) return impl - fn = self.create_function(ufunc_name) + fn = self.create_function(func_name) def wrapper(overload_func): - overload_func.__doc__ = self.format_docstring(overload_func, ufunc_name, api) + overload_func.__doc__ = self.format_docstring(overload_func, func_name, api) functools.update_wrapper(fn, overload_func) decorate = extending.overload(fn) diff --git a/rbc/stdlib/creation_functions.py b/rbc/stdlib/creation_functions.py index 2f886ea80..756a78add 100644 --- a/rbc/stdlib/creation_functions.py +++ b/rbc/stdlib/creation_functions.py @@ -108,6 +108,28 @@ def _array_api_triu(x, k=0): def _impl__full(shape, fill_value, dtype=None): """ Return a new array of given shape and type, filled with fill_value. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](int64, double)') + ... def rbc_full(size, fill_value): + ... return array_api.full(size, fill_value) + >>> rbc_full(3, 3.14).execute() + array([3.14, 3.14, 3.14], dtype=float32) + + >>> @heavydb('int64[](int64, int64)') + ... def rbc_full2(size, fill_value): + ... return array_api.full(size, fill_value, 'int64') + >>> rbc_full2(2, 0).execute() + array([0, 0]) """ nb_dtype = _determine_dtype(dtype, fill_value) @@ -122,6 +144,28 @@ def impl(shape, fill_value, dtype=None): def _impl_full_like(a, fill_value, dtype=None): """ Return a full array with the same shape and type as a given array. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[], double)') + ... def full_like(other, fill_value): + ... return array_api.full_like(other, fill_value) + >>> full_like([1.0, 2.0, 3.0], 3.14).execute() + array([3.14, 3.14, 3.14], dtype=float32) + + >>> @heavydb('int64[](int64[], int64)') + ... def full_like(other, fill_value): + ... return array_api.full_like(other, fill_value, 'int64') + >>> full_like([1, 2, 3], 3).execute() + array([3, 3, 3]) """ if isinstance(a, ArrayPointer): if dtype is None: @@ -175,6 +219,28 @@ def impl(shape, dtype=None): def _impl_zeros(shape, dtype=None): """ Return a new array of given shape and type, filled with zeros. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](int64)') + ... def zeros(size): + ... return array_api.zeros(size) + >>> zeros(3).execute() + array([0., 0., 0.], dtype=float32) + + >>> @heavydb('int64[](int64)') + ... def zeros2(size): + ... return array_api.zeros(size, 'int64') + >>> zeros2(2).execute() + array([0, 0]) """ nb_dtype = _determine_dtype(dtype, fill_value=None) @@ -189,6 +255,28 @@ def impl(shape, dtype=None): def _impl_zeros_like(a, dtype=None): """ Return an array of zeros with the same shape and type as a given array. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[])') + ... def zeros_like(other): + ... return array_api.zeros_like(other) + >>> zeros_like([1, 2, 3]).execute() + array([0, 0, 0]) + + >>> @heavydb('float[](int64[])') + ... def zeros_like2(other): + ... return array_api.zeros_like(other, 'float32') + >>> zeros_like2([1, 2, 3]).execute() + array([0., 0., 0.], dtype=float32) """ if isinstance(a, ArrayPointer): if dtype is None: @@ -207,6 +295,28 @@ def impl(a, dtype=None): def _impl_ones(shape, dtype=None): """ Return a new array of given shape and type, filled with ones. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](int64)') + ... def ones(size): + ... return array_api.ones(size) + >>> ones(3).execute() + array([1., 1., 1.], dtype=float32) + + >>> @heavydb('int64[](int64)') + ... def ones2(size): + ... return array_api.ones(size, 'int64') + >>> ones2(2).execute() + array([1, 1]) """ nb_dtype = _determine_dtype(dtype, fill_value=None) @@ -221,6 +331,28 @@ def impl(shape, dtype=None): def _impl_ones_like(a, dtype=None): """ Return an array of ones with the same shape and type as a given array. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[])') + ... def ones_like(other): + ... return array_api.ones_like(other) + >>> ones_like([1, 2, 3]).execute() + array([1, 1, 1]) + + >>> @heavydb('float[](int64[])') + ... def ones_like2(other): + ... return array_api.ones_like(other, 'float32') + >>> ones_like2([1, 2, 3]).execute() + array([1., 1., 1.], dtype=float32) """ if isinstance(a, ArrayPointer): if dtype is None: diff --git a/rbc/stdlib/datatypes.py b/rbc/stdlib/datatypes.py index 67364aedb..af5b94df9 100644 --- a/rbc/stdlib/datatypes.py +++ b/rbc/stdlib/datatypes.py @@ -2,10 +2,43 @@ Array API specification for data types. https://data-apis.org/array-api/latest/API_specification/data_types.html + +Datatypes exported +------------------ + ++------------+ +| Types | ++============+ +| bool | ++------------+ +| int8 | ++------------+ +| int16 | ++------------+ +| int32 | ++------------+ +| int64 | ++------------+ +| uint8 | ++------------+ +| uint16 | ++------------+ +| uint32 | ++------------+ +| uint64 | ++------------+ +| float32 | ++------------+ +| float64 | ++------------+ +| complex64 | ++------------+ +| complex128 | ++------------+ + """ __all__ = [ - 'Array', 'bool', 'int8', 'int16', @@ -16,14 +49,11 @@ 'uint32', 'uint64', 'float32', - 'float64' + 'float64', + 'complex64', + 'complex128', ] -# NOTE: currently the code lives in rbc.heavydb, but eventually we -# should move it here and leave rbc.heavydb.Array only for backwards -# compatibility -from rbc.heavydb import Array - # array API data types from numba.types import ( boolean as bool, @@ -36,4 +66,6 @@ uint32, uint64, float32, - float64) + float64, + complex64, + complex128) diff --git a/rbc/stdlib/elementwise_functions.py b/rbc/stdlib/elementwise_functions.py index 12fd0afea..a8b805d5a 100644 --- a/rbc/stdlib/elementwise_functions.py +++ b/rbc/stdlib/elementwise_functions.py @@ -1,10 +1,16 @@ """ Array API specification for element-wise functions. -https://data-apis.org/array- api/latest/API_specification/elementwise_functions.html. +https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html. """ -from rbc.stdlib import Expose, BinaryUfuncExpose, UnaryUfuncExpose, API, determine_input_type +from rbc.stdlib import ( + Expose, + BinaryUfuncExpose, + UnaryUfuncExpose, + API, + determine_input_type, +) import numpy as np from rbc import typesystem from rbc.heavydb import ArrayPointer, Array @@ -15,13 +21,13 @@ 'add', 'subtract', 'multiply', 'divide', 'logaddexp', 'logaddexp2', 'true_divide', 'floor_divide', 'pow', 'remainder', 'mod', 'fmod', 'gcd', 'lcm', 'bitwise_and', 'bitwise_or', 'bitwise_xor', - 'bitwise_not', 'atan2', 'hypot', + 'bitwise_invert', 'atan2', 'hypot', 'greater', 'greater_equal', 'less', 'less_equal', 'not_equal', 'equal', 'logical_and', 'logical_or', 'logical_xor', 'maximum', 'minimum', 'fmax', 'fmin', 'nextafter', 'ldexp', 'negative', 'positive', 'rint', 'sign', 'abs', 'conj', 'conjugate', 'exp', 'exp2', 'log', 'log2', 'log10', 'expm1', - 'log1p', 'sqrt', 'square', 'reciprocal', 'bitwise_not', 'sin', 'cos', + 'log1p', 'sqrt', 'square', 'reciprocal', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh', 'tanh', 'asinh', 'acosh', 'atanh', 'degrees', 'radians', 'deg2rad', 'rad2deg', 'logical_not', 'isfinite', 'isinf', 'isnan', 'fabs', @@ -35,279 +41,954 @@ ] -expose = Expose(globals(), 'elementwise_functions') -binary_expose = BinaryUfuncExpose(globals(), 'elementwise_functions') -unary_expose = UnaryUfuncExpose(globals(), 'elementwise_functions') +expose = Expose(globals(), "elementwise_functions") +binary_expose = BinaryUfuncExpose(globals(), "elementwise_functions") +unary_expose = UnaryUfuncExpose(globals(), "elementwise_functions") -# math functions -@binary_expose.implements(np.add) -def _impl_add(x1, x2): - """ - Calculates the sum for each element x1_i of the input array x1 with the respective element - x2_i of the input array x2. +@unary_expose.implements(np.absolute, func_name="abs") +def _impl_ufunc_abs(x): """ - pass + Calculates the absolute value for each element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_abs(arr): + ... return array_api.abs(arr) + >>> array_api_abs([-1.0, 2.0, -3.0]).execute() + array([1., 2., 3.], dtype=float32) -@binary_expose.implements(np.subtract) -def _impl_ufunc_subtract(x1, x2): - """ - Calculates the difference for each element x1_i of the input array x1 with the respective - element x2_i of the input array x2. """ pass -@binary_expose.implements(np.multiply) -def _impl_ufunc_multiply(x1, x2): +@unary_expose.implements(np.arccos, func_name="acos") +def _impl_ufunc_acos(x): """ - Calculates the product for each element x1_i of the input array x1 with the respective element - x2_i of the input array x2. + Calculates an implementation-dependent approximation of the principal value + of the inverse cosine for each element x_i of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_acos(arr): + ... return array_api.acos(arr) + >>> array_api_acos([1., -1.]).execute() + array([0. , 3.1415927], dtype=float32) + """ pass -@binary_expose.implements(np.divide, ufunc_name='divide') -def _impl_ufunc_divide(x1, x2): +@unary_expose.implements(np.arccosh, func_name="acosh") +def _impl_ufunc_acosh(x): """ - Calculates the division for each element x1_i of the input array x1 with the respective - element x2_i of the input array x2. + Calculates an implementation-dependent approximation to the inverse + hyperbolic cosine for each element x_i of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_acosh(arr): + ... return array_api.acosh(arr) + >>> array_api_acosh([np.e, 10.0, 1.0]).execute() + array([1.6574545, 2.993223 , 0. ], dtype=float32) + """ pass -@binary_expose.implements(np.logaddexp) -def _impl_ufunc_logaddexp(x1, x2): +@binary_expose.implements(np.add, func_name="add") +def _impl_add(x1, x2): """ - Calculates the logarithm of the sum of exponentiations ``log(exp(x1) + exp(x2))`` for each - element x1_i of the input array x1 with the respective element x2_i of the input array x2. + Calculates the sum for each element x1_i of the input array x1 with the + respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[], int64[])') + ... def array_api_add(x1, x2): + ... return array_api.add(x1, x2) + >>> array_api_add([1, -1], [3, 4]).execute() + array([4, 3]) """ pass -@binary_expose.implements(np.copysign, api=API.NUMPY_API) -def _impl_ufunc_copysign(x1, x2): - pass +@unary_expose.implements(np.arcsin, func_name="asin") +def _impl_ufunc_asin(x): + """ + Calculates an implementation-dependent approximation of the principal value + of the inverse sine for each element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@binary_expose.implements(np.logaddexp2, api=API.NUMPY_API) -def _impl_ufunc_logaddexp2(x1, x2): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_asin(arr): + ... return array_api.asin(arr) + >>> array_api_asin([1.0, 0.0, -1.0]).execute() + array([ 1.5707964, 0. , -1.5707964], dtype=float32) -@binary_expose.implements(np.true_divide, ufunc_name="true_divide", api=API.NUMPY_API) -def _impl_ufunc_true_divide(x1, x2): + """ pass -@binary_expose.implements(np.floor_divide) -def _impl_ufunc_floor_divide(x1, x2): - """ - Rounds the result of dividing each element x1_i of the input array x1 by the respective - element x2_i of the input array x2 to the greatest (i.e., closest to +infinity) integer-value - number that is not greater than the division result. +@unary_expose.implements(np.arcsinh, func_name="asinh") +def _impl_ufunc_asinh(x): """ - pass + Calculates an implementation-dependent approximation to the inverse + hyperbolic sine for each element x_i in the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@binary_expose.implements(np.power, ufunc_name='power', api=API.NUMPY_API) -def _impl_ufunc_power(x1, x2): + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_asinh(arr): + ... return array_api.asinh(arr) + >>> array_api_asinh([np.e, 10.0]).execute() + array([1.7253826, 2.998223 ], dtype=float32) + """ pass -@binary_expose.implements(np.power, ufunc_name='pow') -def _impl_ufunc_pow(x1, x2): +@unary_expose.implements(np.arctan, func_name="atan") +def _impl_ufunc_atan(x): """ - Calculates an implementation-dependent approximation of exponentiation by raising each element - x1_i (the base) of the input array x1 to the power of x2_i (the exponent), where x2_i is the - corresponding element of the input array x2. + Calculates an implementation-dependent approximation of the principal value + of the inverse tangent for each element x_i of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_atan(arr): + ... return array_api.atan(arr) + >>> array_api_atan([0, 1, np.pi/4]).execute() + array([0. , 0.7853982 , 0.66577375], dtype=float32) + """ pass -@binary_expose.not_implemented('float_power') # not supported by Numba -def _impl_ufunc_float_power(x1, x2): +@binary_expose.implements(np.arctan2, func_name="atan2", dtype=types.float64) +def _impl_ufunc_atan2(x1, x2): + """ + Calculates an implementation-dependent approximation of the inverse tangent of the quotient + x1/x2, having domain [-infinity, +infinity] x ``[-infinity, +infinity]`` (where the x notation + denotes the set of ordered pairs of elements (x1_i, x2_i)) and codomain [-π, +π], for each + pair of elements (x1_i, x2_i) of the input arrays x1 and x2, respectively. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](int64[], int64[])') + ... def array_api_atan2(x1, x2): + ... return array_api.atan2(x1, x2) + >>> x = np.array([-1, +1, +1, -1]) + >>> y = np.array([-1, -1, +1, +1]) + >>> array_api_atan2(x, y).execute() * 180 / np.pi + array([-135., 135., 45., -45.], dtype=float32) + + """ pass -@binary_expose.implements(np.remainder) -def _impl_ufunc_remainder(x1, x2): +@unary_expose.implements(np.arctanh, func_name="atanh") +def _impl_ufunc_atanh(x): """ - Returns the remainder of division for each element x1_i of the input array x1 and the - respective element x2_i of the input array x2. + Calculates an implementation-dependent approximation to the inverse hyperbolic tangent, having + domain [-1, +1] and codomain [-infinity, +infinity], for each element x_i of the input array + x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_atanh(x): + ... return array_api.atanh(x) + >>> array_api_atanh([0, -0.5]).execute() + array([ 0. , -0.54930615], dtype=float32) + """ pass -@binary_expose.implements(np.mod, ufunc_name='mod', api=API.NUMPY_API) -def _impl_ufunc_mod(x1, x2): - pass +@binary_expose.implements(np.bitwise_and, func_name="bitwise_and") +def _impl_ufunc_bitwise_and(x1, x2): + """ + Computes the bitwise AND of the underlying binary representation of each element x1_iof the + input array x1 with the respective element x2_i of the input array x2. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@binary_expose.implements(np.fmod, api=API.NUMPY_API) -def _impl_ufunc_fmod(x1, x2): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[], int64[])') + ... def array_api_bitwise_and(x1, x2): + ... return array_api.bitwise_and(x1, x2) + >>> array_api_bitwise_and([11,7], [4,25]).execute() + array([0, 1]) -@binary_expose.not_implemented('divmod') # not supported by Numba -def _impl_ufunc_divmod(x1, x2): + """ pass -@binary_expose.implements(np.gcd, api=API.NUMPY_API) -def _impl_ufunc_gcd(x1, x2): - pass +@binary_expose.implements(np.left_shift, func_name="bitwise_left_shift") +def _impl_ufunc_bitwise_left_shift(x1, x2): + """ + Shifts the bits of each element x1_i of the input array x1 to the left by appending x2_i + (i.e., the respective element in the input array x2) zeros to the right of x1_i. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@binary_expose.implements(np.lcm, api=API.NUMPY_API) -def _impl_ufunc_lcm(x1, x2): + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64, int64[])') + ... def array_api_bitwise_left_shift(x1, x2): + ... return array_api.bitwise_left_shift(x1, x2) + >>> array_api_bitwise_left_shift(5, [1, 2, 3]).execute() + array([10, 20, 40]) + + """ pass -# Bit-twiddling functions -@binary_expose.implements(np.bitwise_and) -def _impl_ufunc_bitwise_and(x1, x2): +@unary_expose.implements(np.invert, func_name="bitwise_invert") +def _impl_ufunc_bitwise_invert(x): """ - Computes the bitwise AND of the underlying binary representation of each element x1_iof the - input array x1 with the respective element x2_i of the input array x2. + Inverts (flips) each bit for each element x_i of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int8(int8)') + ... def array_api_bitwise_invert(x): + ... return array_api.bitwise_invert(x) + >>> array_api_bitwise_invert(13).execute() + -14 + >>> np.binary_repr(-14, width=8) + '11110010' + """ pass -@binary_expose.implements(np.bitwise_or) +@binary_expose.implements(np.bitwise_or, func_name="bitwise_or") def _impl_ufunc_bitwise_or(x1, x2): """ Computes the bitwise OR of the underlying binary representation of each element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64(int64, int64)') + ... def array_api_bitwise_or(x1, x2): + ... return array_api.bitwise_or(x1, x2) + >>> array_api_bitwise_or(13, 16).execute() + 29 + >>> np.binary_repr(29) + '11101' + >>> array_api_bitwise_or(32, 2).execute() + 34 + + """ + pass + + +@binary_expose.implements(np.right_shift, func_name="bitwise_right_shift") +def _impl_ufunc_bitwise_right_shift(x1, x2): + """ + Shifts the bits of each element x1_i of the input array x1 to the right by appending x2_i + (i.e., the respective element in the input array x2) zeros to the right of x1_i. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64(int64, int64)') + ... def array_api_bitwise_right_shift(x1, x2): + ... return array_api.bitwise_right_shift(x1, x2) + >>> array_api_bitwise_right_shift(10, 1).execute() + 5 + >>> np.binary_repr(5) + '101' """ pass -@binary_expose.implements(np.bitwise_xor) +@binary_expose.implements(np.bitwise_xor, func_name="bitwise_xor") def _impl_ufunc_bitwise_xor(x1, x2): """ Computes the bitwise XOR of the underlying binary representation of each element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64(int64, int64)') + ... def array_api_bitwise_xor(x1, x2): + ... return array_api.bitwise_xor(x1, x2) + >>> array_api_bitwise_xor(13, 17).execute() + 28 + >>> np.binary_repr(28) + '11100' """ pass -@binary_expose.implements(np.bitwise_not, ufunc_name='bitwise_not') -def _impl_ufunc_bitwise_not(x1, x2): +@unary_expose.implements(np.ceil, func_name="ceil", dtype=types.double) +def _impl_ufunc_ceil(x): """ - Computes the bitwise NOR of the underlying binary representation of each element x1_i of the - input array x1 with the respective element x2_i of the input array x2. + Rounds each element x_i of the input array x to the smallest (i.e., closest to -infinity) + integer-valued number that is not less than x_i. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_ceil(x): + ... return array_api.ceil(x) + >>> arr = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]) + >>> array_api_ceil(arr).execute() + array([-1., -1., -0., 1., 2., 2., 2.], dtype=float32) + """ pass -@binary_expose.implements(np.left_shift, api=API.NUMPY_API) -def _impl_ufunc_left_shift(x1, x2): +@unary_expose.implements(np.conj, func_name="conj") +def _impl_ufunc_conj(x): + """ + Returns the complex conjugate for each element x_i of the input array + """ pass -@binary_expose.implements(np.left_shift, ufunc_name='bitwise_left_shift') -def _impl_ufunc_bitwise_left_shift(x1, x2): +@unary_expose.implements(np.cos, func_name="cos") +def _impl_ufunc_cos(x): + """Calculates an implementation-dependent approximation to the cosine, having domain + (-infinity, +infinity) and codomain [-1, +1], for each element x_i of the input + array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_cos(x): + ... return array_api.cos(x) + >>> array_api_cos(np.array([0, np.pi/2, np.pi])).execute() + array([ 1.000000e+00, 6.123234e-17, -1.000000e+00], dtype=float32) + """ - Shifts the bits of each element x1_i of the input array x1 to the left by appending x2_i - (i.e., the respective element in the input array x2) zeros to the right of x1_i. + pass + + +@unary_expose.implements(np.cosh, func_name="cosh") +def _impl_ufunc_cosh(x): + """Calculates an implementation-dependent approximation to the hyperbolic cosine, having + domain. + + [-infinity, +infinity] and codomain [-infinity, +infinity], for each + element x_i in the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_cosh(x): + ... return array_api.cosh(x) + >>> array_api_cosh(0.0).execute() + 1.0 + """ pass -@binary_expose.implements(np.right_shift, api=API.NUMPY_API) -def _impl_ufunc_right_shift(x1, x2): +@binary_expose.implements(np.divide, func_name="divide") +def _impl_ufunc_divide(x1, x2): + """ + Calculates the division for each element x1_i of the input array x1 with the respective + element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double, double)') + ... def array_api_divide(x1, x2): + ... return array_api.divide(x1, x2) + >>> array_api_divide(2.0, 4.0).execute() + 0.5 + """ pass -@binary_expose.implements(np.right_shift, ufunc_name='bitwise_right_shift') -def _impl_ufunc_bitwise_right_shift(x1, x2): +@binary_expose.implements(np.equal, func_name="equal", dtype=typesystem.boolean8) +def _impl_ufunc_equal(x1, x2): """ - Shifts the bits of each element x1_i of the input array x1 to the right by appending x2_i - (i.e., the respective element in the input array x2) zeros to the right of x1_i. + Computes the truth value of x1_i == x2_i for each element x1_i of the input array x1 with the + respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](int64[], int64[])') + ... def array_api_equal(x1, x2): + ... return array_api.equal(x1, x2) + >>> array_api_equal([0, 1, 3], np.arange(3)).execute() + array([ True, True, False]) """ pass -# trigonometric functions -@binary_expose.implements(np.arctan2, api=API.NUMPY_API) -def _impl_ufunc_arctan2(x1, x2): +@unary_expose.implements(np.exp, func_name="exp") +def _impl_ufunc_exp(x): + """Calculates an implementation-dependent approximation to the exponential function, having + domain. + + [-infinity, +infinity] and codomain [+0, +infinity], for each + element x_i of the input array x (e raised to the power of x_i, + where e is the base of the natural logarithm). + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_exp(x): + ... return array_api.exp(x) + >>> array_api_exp(np.array([1.0, np.pi, np.e])).execute() + array([ 2.7182817, 23.140692 , 15.154263 ], dtype=float32) + + """ pass -@binary_expose.implements(np.arctan2, ufunc_name='atan2') -def _impl_ufunc_atan2(x1, x2): +@unary_expose.implements(np.expm1, func_name="expm1") +def _impl_ufunc_expm1(x): + """Calculates an implementation-dependent approximation to exp(x)-1, having domain [-infinity, + + +infinity] and codomain [-1, +infinity], for each element x_i of the + input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_expm1(x): + ... return array_api.expm1(x) + >>> array_api_expm1(np.array([1.0, np.pi, np.e])).execute() + array([ 1.7182819, 22.140692 , 14.154263 ], dtype=float32) + """ - Calculates an implementation-dependent approximation of the inverse tangent of the quotient - x1/x2, having domain [-infinity, +infinity] x ``[-infinity, +infinity]`` (where the x notation - denotes the set of ordered pairs of elements (x1_i, x2_i)) and codomain [-π, +π], for each - pair of elements (x1_i, x2_i) of the input arrays x1 and x2, respectively. + pass + + +@unary_expose.implements(np.floor, func_name="floor", dtype=types.double) +def _impl_ufunc_floor(x): + """ + Rounds each element x_i of the input array x to the greatest (i.e., closest to +infinity) + integer-valued number that is not greater than x_i. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_floor(x): + ... return array_api.floor(x) + >>> array_api_floor(np.array([1.0, np.pi, np.e])).execute() + array([1., 3., 2.], dtype=float32) + """ pass -@binary_expose.implements(np.hypot, api=API.NUMPY_API) -def _impl_ufunc_hypot(x1, x2): +@binary_expose.implements(np.floor_divide, func_name="floor_divide") +def _impl_ufunc_floor_divide(x1, x2): + """ + Rounds the result of dividing each element x1_i of the input array x1 by the respective + element x2_i of the input array x2 to the greatest (i.e., closest to +infinity) integer-value + number that is not greater than the division result. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64(int64, int64)') + ... def array_api_bitwise_floor_divide(x1, x2): + ... return array_api.floor_divide(x1, x2) + >>> array_api_bitwise_floor_divide(7, 3).execute() + 2 + + """ pass -# Comparison functions -@binary_expose.implements(np.greater, dtype=typesystem.boolean8) +@binary_expose.implements(np.greater, func_name="greater", dtype=typesystem.boolean8) def _impl_ufunc_greater(x1, x2): """ Computes the truth value of x1_i > x2_i for each element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](int64[], int64[])') + ... def array_api_greater(x1, x2): + ... return array_api.greater(x1, x2) + >>> array_api_greater([4,2],[2,2]).execute() + array([ True, False]) + """ pass -@binary_expose.implements(np.greater_equal, dtype=typesystem.boolean8) +@binary_expose.implements( + np.greater_equal, func_name="greater_equal", dtype=typesystem.boolean8 +) def _impl_ufunc_greater_equal(x1, x2): """ - Computes the truth value of x1_i >= x2_i for each element x1_i of the input array x1 with the - respective element x2_i of the input array x2. + Computes the truth value of x1_i >= x2_i for each element x1_i of the + input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](int64[], int64[])') + ... def array_api_greater_equal(x1, x2): + ... return array_api.greater_equal(x1, x2) + >>> array_api_greater_equal([4, 2, 1], [2, 2, 2]).execute() + array([ True, True, False]) + """ pass -@binary_expose.implements(np.less, dtype=typesystem.boolean8) +@unary_expose.not_implemented(func_name="imag") +def _impl_ufunc_imag(x): + """ + Returns the imaginary component of a complex number for each element x_i of + the input array x. + """ + + +@unary_expose.implements(np.isfinite, func_name="isfinite", dtype=typesystem.boolean8) +def _impl_ufunc_isfinite(x): + """ + Tests each element x_i of the input array x to determine if finite (i.e., not NaN and not + equal to positive or negative infinity). + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](double[])') + ... def array_api_isfinite(x): + ... return array_api.isfinite(x) + >>> array_api_isfinite([1.0, 0.0]).execute() + array([ True, True]) + + """ + pass + + +@unary_expose.implements(np.isinf, func_name="isinf", dtype=typesystem.boolean8) +def _impl_ufunc_isinf(x): + """ + Tests each element x_i of the input array x to determine if equal to positive or negative + infinity. + """ + pass + + +@unary_expose.implements(np.isnan, func_name="isnan", dtype=typesystem.boolean8) +def _impl_ufunc_isnan(x): + """ + Tests each element x_i of the input array x to determine whether the element is NaN. + """ + pass + + +@binary_expose.implements(np.less, func_name="less", dtype=typesystem.boolean8) def _impl_ufunc_less(x1, x2): """ Computes the truth value of x1_i < x2_i for each element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](int64[], int64[])') + ... def array_api_less(x1, x2): + ... return array_api.less(x1, x2) + >>> array_api_less([4, 2, 1], [2, 2, 2]).execute() + array([False, False, True]) + """ pass -@binary_expose.implements(np.less_equal, dtype=typesystem.boolean8) +@binary_expose.implements( + np.less_equal, func_name="less_equal", dtype=typesystem.boolean8 +) def _impl_ufunc_less_equal(x1, x2): """ Computes the truth value of x1_i <= x2_i for each element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('bool[](int64[], int64[])') + ... def array_api_less_equal(x1, x2): + ... return array_api.less_equal(x1, x2) + >>> array_api_less_equal([4, 2, 1], [2, 2, 2]).execute() + array([False, True, True]) + """ pass -@binary_expose.implements(np.not_equal, dtype=typesystem.boolean8) -def _impl_ufunc_not_equal(x1, x2): +@unary_expose.implements(np.log, func_name="log") +def _impl_ufunc_log(x): """ - Computes the truth value of x1_i != x2_i for each element x1_i of the input array x1 with the - respective element x2_i of the input array x2. + Calculates an implementation-dependent approximation to the natural (base e) logarithm, having + domain [0, +infinity] and codomain [-infinity, +infinity], for each element x_i of the input + array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_log(x): + ... return array_api.log(x) + >>> array_api_log([1.0, np.e, np.e**2, 0.0]).execute() + array([ 0., 1., 2., -inf], dtype=float32) + """ pass -@binary_expose.implements(np.equal, dtype=typesystem.boolean8) -def _impl_ufunc_equal(x1, x2): +@unary_expose.implements(np.log1p, func_name="log1p") +def _impl_ufunc_log1p(x): """ - Computes the truth value of x1_i == x2_i for each element x1_i of the input array x1 with the - respective element x2_i of the input array x2. + Calculates an implementation-dependent approximation to log(1+x), where log refers to the + natural (base e) logarithm, having domain [-1, +infinity] and codomain [-infinity, +infinity], + for each element x_i of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_log1p(x): + ... return array_api.log1p(x) + >>> array_api_log1p([np.e, 8.0]).execute() + array([1.3132616, 2.1972246], dtype=float32) + """ pass -@binary_expose.implements(np.logical_and, dtype=typesystem.boolean8) +@unary_expose.implements(np.log2, func_name="log2") +def _impl_ufunc_log2(x): + """Calculates an implementation-dependent approximation to the base 2 logarithm, having + domain. [0, +infinity] and codomain [-infinity, +infinity], for each element x_i + of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_log2(x): + ... return array_api.log2(x) + >>> array_api_log2([np.e, 8.0]).execute() + array([1.442695, 3. ], dtype=float32) + + """ + pass + + +@unary_expose.implements(np.log10, func_name="log10") +def _impl_ufunc_log10(x): + """Calculates an implementation-dependent approximation to the base 10 logarithm, having + domain. [0, +infinity] and codomain [-infinity, +infinity], for each element x_i + of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_log10(x): + ... return array_api.log10(x) + >>> array_api_log10([0.01, -3.0]).execute() + array([-2., nan], dtype=float32) + + """ + pass + + +@binary_expose.implements(np.logaddexp, func_name="logaddexp") +def _impl_ufunc_logaddexp(x1, x2): + """ + Calculates the logarithm of the sum of exponentiations ``log(exp(x1) + exp(x2))`` for each + element x1_i of the input array x1 with the respective element x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double, double)') + ... def array_api_logaddexp(x1, x2): + ... return array_api.logaddexp(x1, x2) + >>> prob1 = np.log(1e-50) + >>> prob2 = np.log(2.5e-50) + >>> array_api_logaddexp(prob1, prob2).execute() + -113.876495 + + """ + pass + + +@binary_expose.implements( + np.logical_and, func_name="logical_and", dtype=typesystem.boolean8 +) def _impl_ufunc_logical_and(x1, x2): """ Computes the logical AND for each element x1_i of the input array x1 with the respective @@ -316,7 +997,9 @@ def _impl_ufunc_logical_and(x1, x2): pass -@binary_expose.implements(np.logical_or, dtype=typesystem.boolean8) +@binary_expose.implements( + np.logical_or, func_name="logical_or", dtype=typesystem.boolean8 +) def _impl_ufunc_logical_or(x1, x2): """ Computes the logical OR for each element x1_i of the input array x1 with the respective @@ -325,506 +1008,678 @@ def _impl_ufunc_logical_or(x1, x2): pass -@binary_expose.implements(np.logical_xor, dtype=typesystem.boolean8) -def _impl_ufunc_logical_xor(x1, x2): +@binary_expose.implements( + np.logical_xor, func_name="logical_xor", dtype=typesystem.boolean8 +) +def _impl_ufunc_logical_xor(x1, x2): + """ + "Computes the logical XOR for each element x1_i of the input array x1 with the respective + element x2_i of the input array x2. + """ + pass + + +@unary_expose.implements(np.logical_not, dtype=typesystem.boolean8) +def _impl_ufunc_logical_not(x): + """ + Computes the logical NOT for each element x_i of the input array x. + """ + pass + + +@binary_expose.implements(np.multiply, func_name="multiply") +def _impl_ufunc_multiply(x1, x2): + """ + Calculates the product for each element x1_i of the input array x1 with the respective element + x2_i of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double, double)') + ... def array_api_multiply(x1, x2): + ... return array_api.multiply(x1, x2) + >>> array_api_multiply(2.0, 4.0).execute() + 8.0 + + """ + pass + + +@unary_expose.implements(np.negative, func_name="negative") +def _impl_ufunc_negative(x): + """Computes the numerical negative of each element x_i (i.e., y_i = -x_i) of the + input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_negative(x): + ... return array_api.negative(x) + >>> array_api_negative([1., -1.]).execute() + array([-1., 1.], dtype=float32) + + """ + pass + + +@binary_expose.implements( + np.not_equal, func_name="not_equal", dtype=typesystem.boolean8 +) +def _impl_ufunc_not_equal(x1, x2): + """ + Computes the truth value of x1_i != x2_i for each element x1_i of the input array x1 with the + respective element x2_i of the input array x2. + """ + pass + + +@unary_expose.implements(np.positive, func_name="positive") +def _impl_ufunc_positive(x): + """Computes the numerical positive of each element x_i (i.e., y_i = +x_i) of the + input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_positive(x): + ... return array_api.positive(x) + >>> array_api_positive([1., -1.]).execute() + array([ 1., -1.], dtype=float32) + + """ + pass + + +@binary_expose.implements(np.power, func_name="pow") +def _impl_ufunc_pow(x1, x2): + """ + Calculates an implementation-dependent approximation of exponentiation by raising each element + x1_i (the base) of the input array x1 to the power of x2_i (the exponent), where x2_i is the + corresponding element of the input array x2. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[], int64)') + ... def array_api_pow(x1, x2): + ... return array_api.pow(x1, x2) + >>> x1 = np.arange(6) + >>> array_api_pow(x1, 3).execute() + array([ 0, 1, 8, 27, 64, 125]) + + """ + pass + + +@unary_expose.not_implemented(func_name="real") +def _impl_ufunc_real(x): """ - "Computes the logical XOR for each element x1_i of the input array x1 with the respective - element x2_i of the input array x2. + Returns the real component of a complex number for each element x_i of the + input array x. """ pass -@binary_expose.implements(np.maximum, api=API.NUMPY_API) -def _impl_ufunc_maximum(x1, x2): - pass +@binary_expose.implements(np.remainder, func_name="remainder") +def _impl_ufunc_remainder(x1, x2): + """ + Returns the remainder of division for each element x1_i of the input array x1 and the + respective element x2_i of the input array x2. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@binary_expose.implements(np.minimum, api=API.NUMPY_API) -def _impl_ufunc_minimum(x1, x2): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('int64[](int64[], int64[])') + ... def array_api_remainder(x1, x2): + ... return array_api.remainder(x1, x2) + >>> array_api_remainder([4, 7], [2, 3]).execute() + array([0, 1]) -@binary_expose.implements(np.fmax, api=API.NUMPY_API) -def _impl_ufunc_fmax(x1, x2): + """ pass -@binary_expose.implements(np.fmin, api=API.NUMPY_API) -def _impl_ufunc_fmin(x1, x2): - pass +@unary_expose.implements(np.round, func_name="round") +def _impl_ufunc_round(x): + """ + Rounds each element x_i of the input array x to the nearest integer-valued number. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -# Floating functions -@binary_expose.implements(np.nextafter, api=API.NUMPY_API) -def _impl_ufunc_nextafter(x1, x2): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_round(x): + ... return array_api.round(x) + >>> array_api_round([0.37, 1.64]).execute() + array([0., 2.], dtype=float32) -@binary_expose.implements(np.ldexp, api=API.NUMPY_API) -def _impl_ufunc_ldexp(x1, x2): + """ pass -################################################################## +@unary_expose.implements(np.sign, func_name="sign") +def _impl_ufunc_sign(x): + """ + Returns an indication of the sign of a number for each element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_sign(x): + ... return array_api.sign(x) + >>> array_api_sign([-5., 4.5]).execute() + array([-1., 1.], dtype=float32) -@unary_expose.implements(np.around, ufunc_name='round') -def _impl_ufunc_round(a): - """ - Rounds each element x_i of the input array x to the nearest integer-valued number. """ pass -@unary_expose.implements(np.negative) -def _impl_ufunc_negative(a): - """Computes the numerical negative of each element x_i (i.e., y_i = -x_i) of the - input array x.""" - pass +@unary_expose.implements(np.sin, func_name="sin") +def _impl_ufunc_sin(x): + """ + Calculates an implementation-dependent approximation to the sine for each + element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@unary_expose.implements(np.positive) -def _impl_ufunc_positive(a): - """Computes the numerical positive of each element x_i (i.e., y_i = +x_i) of the - input array x.""" - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_sin(x): + ... return array_api.sin(x) + >>> array_api_sin(np.pi/2.).execute() + 1.0 -@unary_expose.implements(np.absolute, api=API.NUMPY_API) -def _impl_ufunc_absolute(a): + """ pass -@unary_expose.implements(np.absolute, ufunc_name='abs') -def _impl_ufunc_abs(a): - """ - Calculates the absolute value for each element x_i of the input array x (i.e., the element- - wise result has the same magnitude as the respective element in x but has positive sign). +@unary_expose.implements(np.sinh, func_name="sinh") +def _impl_ufunc_sinh(x): """ - pass + Calculates an implementation-dependent approximation to the hyperbolic sine + for each element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@unary_expose.implements(np.rint, api=API.NUMPY_API) -def _impl_ufunc_rint(a): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_sinh(x): + ... return array_api.sinh(x) + >>> array_api_sinh(0).execute() + 0.0 + >>> array_api_sinh(np.pi).execute() + 11.548739 -@unary_expose.implements(np.sign) -def _impl_ufunc_sign(a): - """ - Returns an indication of the sign of a number for each element x_i of the input array x. """ pass -@unary_expose.implements(np.conj, ufunc_name='conj', api=API.NUMPY_API) -def _impl_ufunc_conj(a): - pass +@unary_expose.implements(np.square, func_name="square") +def _impl_ufunc_square(x): + """ + Squares (x_i * x_i) each element x_i of the input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@unary_expose.implements(np.conjugate, api=API.NUMPY_API) -def _impl_ufunc_conjugate(a): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_square(x): + ... return array_api.square(x) + >>> array_api_square(4.0).execute() + 16.0 -@unary_expose.implements(np.exp) -def _impl_ufunc_exp(a): - """Calculates an implementation-dependent approximation to the exponential function, having - domain. + """ + pass - [-infinity, +infinity] and codomain [+0, +infinity], for each - element x_i of the input array x (e raised to the power of x_i, - where e is the base of the natural logarithm). +@unary_expose.implements(np.sqrt, func_name="sqrt") +def _impl_ufunc_sqrt(x): """ - pass + Calculates the principal square root for each element x_i of the input + array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() -@unary_expose.implements(np.exp2, api=API.NUMPY_API) -def _impl_ufunc_exp2(a): - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_sqrt(x): + ... return array_api.sqrt(x) + >>> array_api_sqrt(4.0).execute() + 2.0 -@unary_expose.implements(np.log) -def _impl_ufunc_log(a): - """ - Calculates an implementation-dependent approximation to the natural (base e) logarithm, having - domain [0, +infinity] and codomain [-infinity, +infinity], for each element x_i of the input - array x. """ pass -@unary_expose.implements(np.log2) -def _impl_ufunc_log2(a): - """Calculates an implementation-dependent approximation to the base 2 logarithm, having - domain. +@binary_expose.implements(np.subtract, func_name="subtract") +def _impl_ufunc_subtract(x1, x2): + """ + Calculates the difference for each element x1_i of the input array x1 with + the respective element x2_i of the input array x2 - [0, + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() - +infinity] and codomain [-infinity, +infinity], for each element x_i - of the input array x. + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('int64(int64, int64)') + ... def array_api_subtract(x1, x2): + ... return array_api.subtract(x1, x2) + >>> array_api_subtract(5, 3).execute() + 2 """ pass -@unary_expose.implements(np.log10) -def _impl_ufunc_log10(a): - """Calculates an implementation-dependent approximation to the base 10 logarithm, having - domain. +@unary_expose.implements(np.tan, func_name="tan") +def _impl_ufunc_tan(x): + """ + Calculates an implementation-dependent approximation to the tangent for + each element x_i of the input array x. - [0, + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() - +infinity] and codomain [-infinity, +infinity], for each element x_i - of the input array x. + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_tan(x): + ... return array_api.tan(x) + >>> array_api_tan([-np.pi, np.pi/2, np.pi]).execute() + array([ 1.2246469e-16, 1.6331239e+16, -1.2246469e-16], dtype=float32) """ pass -@unary_expose.implements(np.expm1) -def _impl_ufunc_expm1(a): - """Calculates an implementation-dependent approximation to exp(x)-1, having domain [-infinity, +@unary_expose.implements(np.tanh, func_name="tanh") +def _impl_ufunc_tanh(x): + """ + Calculates an implementation-dependent approximation to the hyperbolic + tangent for each element x_i of the input array x. - +infinity] and codomain [-1, +infinity], for each element x_i of the - input array x. + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() - """ - pass + IGNORE + >>> from rbc.stdlib import array_api + >>> @heavydb('double[](double[])') + ... def array_api_tanh(x): + ... return array_api.tanh(x) + >>> array_api_tanh([0.0, np.pi/2, np.pi]).execute() + array([0. , 0.91715235, 0.9962721 ], dtype=float32) -@unary_expose.implements(np.log1p) -def _impl_ufunc_log1p(a): - """ - Calculates an implementation-dependent approximation to log(1+x), where log refers to the - natural (base e) logarithm, having domain [-1, +infinity] and codomain [-infinity, +infinity], - for each element x_i of the input array x. """ pass -@unary_expose.implements(np.sqrt) -def _impl_ufunc_sqrt(a): +@unary_expose.implements(np.trunc, func_name="trunc", dtype=types.double) +def _impl_ufunc_trunc(x): """ - Calculates the square root, having domain [0, +infinity] and codomain [0, +infinity], for each - element x_i of the input array x. + Rounds each element x_i of the input array x to the nearest integer-valued + number that is closer to zero than x_i. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double)') + ... def array_api_trunc(x): + ... return array_api.trunc(x) + >>> array_api_trunc(np.pi).execute() + 3.0 + """ pass -@unary_expose.implements(np.square) -def _impl_ufunc_square(a): - """Squares (x_i * x_i) each element x_i of the input array x.""" - pass +############### -# @unary_expose.implements(np.cbrt) # not supported by numba -@unary_expose.not_implemented('cbrt') -def _impl_ufunc_cbrt(a): +@binary_expose.implements(np.copysign, api=API.NUMPY_API) +def _impl_ufunc_copysign(x1, x2): pass -@unary_expose.implements(np.reciprocal, api=API.NUMPY_API) -def _impl_ufunc_reciprocal(a): +@binary_expose.implements(np.logaddexp2, api=API.NUMPY_API) +def _impl_ufunc_logaddexp2(x1, x2): pass -# Bit-twiddling functions -@unary_expose.implements(np.invert, api=API.NUMPY_API) -def _impl_ufunc_invert(a): +@binary_expose.implements(np.true_divide, func_name="true_divide", api=API.NUMPY_API) +def _impl_ufunc_true_divide(x1, x2): pass -@unary_expose.implements(np.invert, ufunc_name='bitwise_invert') -def _impl_ufunc_bitwise_invert(a): - """ - Inverts (flips) each bit for each element x_i of the input array x. - """ +@binary_expose.implements(np.power, func_name="power", api=API.NUMPY_API) +def _impl_ufunc_power(x1, x2): pass -# trigonometric functions -@unary_expose.implements(np.sin) -def _impl_ufunc_sin(a): - """Calculates an implementation-dependent approximation to the sine, having domain (-infinity, +@binary_expose.not_implemented("float_power") # not supported by Numba +def _impl_ufunc_float_power(x1, x2): + pass - +infinity) and codomain [-1, +1], for each element x_i of the input - array x. - """ +@binary_expose.implements(np.mod, func_name="mod", api=API.NUMPY_API) +def _impl_ufunc_mod(x1, x2): pass -@unary_expose.implements(np.cos) -def _impl_ufunc_cos(a): - """Calculates an implementation-dependent approximation to the cosine, having domain - (-infinity, +@binary_expose.implements(np.fmod, api=API.NUMPY_API) +def _impl_ufunc_fmod(x1, x2): + pass - +infinity) and codomain [-1, +1], for each element x_i of the input - array x. - """ +@binary_expose.not_implemented("divmod") # not supported by Numba +def _impl_ufunc_divmod(x1, x2): pass -@unary_expose.implements(np.tan) -def _impl_ufunc_tan(a): - """Calculates an implementation-dependent approximation to the tangent, having domain - (-infinity, +@binary_expose.implements(np.gcd, api=API.NUMPY_API) +def _impl_ufunc_gcd(x1, x2): + pass - +infinity) and codomain (-infinity, +infinity), for each element x_i - of the input array x. - """ +@binary_expose.implements(np.lcm, api=API.NUMPY_API) +def _impl_ufunc_lcm(x1, x2): pass -@unary_expose.implements(np.arcsin, api=API.NUMPY_API) -def _impl_ufunc_arcsin(a): +# Bit-twiddling functions +@binary_expose.implements(np.left_shift, api=API.NUMPY_API) +def _impl_ufunc_left_shift(x1, x2): pass -@unary_expose.implements(np.arcsin, ufunc_name='asin') -def _impl_ufunc_asin(a): - """ - Calculates an implementation-dependent approximation of the principal value of the inverse - sine, having domain [-1, +1] and codomain [-π/2, +π/2] for each element x_i of the input array - x. - """ +@binary_expose.implements(np.right_shift, api=API.NUMPY_API) +def _impl_ufunc_right_shift(x1, x2): pass -@unary_expose.implements(np.arccos, api=API.NUMPY_API) -def _impl_ufunc_arccos(a): +# trigonometric functions +@binary_expose.implements(np.arctan2, api=API.NUMPY_API) +def _impl_ufunc_arctan2(x1, x2): pass -@unary_expose.implements(np.arccos, ufunc_name='acos') -def _impl_ufunc_acos(a): - """ - Calculates an implementation-dependent approximation of the principal value of the inverse - cosine, having domain [-1, +1] and codomain [+0, +π], for each element x_i of the input array - x. - """ +@binary_expose.implements(np.hypot, api=API.NUMPY_API) +def _impl_ufunc_hypot(x1, x2): pass -@unary_expose.implements(np.arctan, api=API.NUMPY_API) -def _impl_ufunc_arctan(a): +# Comparison functions + +@binary_expose.implements(np.maximum, api=API.NUMPY_API) +def _impl_ufunc_maximum(x1, x2): pass -@unary_expose.implements(np.arctan, ufunc_name='atan') -def _impl_ufunc_atan(a): - """ - Calculates an implementation-dependent approximation of the principal value of the inverse - tangent, having domain [-infinity, +infinity] and codomain [-π/2, +π/2], for each element x_i - of the input array x. - """ +@binary_expose.implements(np.minimum, api=API.NUMPY_API) +def _impl_ufunc_minimum(x1, x2): pass -@unary_expose.implements(np.sinh) -def _impl_ufunc_sinh(a): - """Calculates an implementation-dependent approximation to the hyperbolic sine, having domain. +@binary_expose.implements(np.fmax, api=API.NUMPY_API) +def _impl_ufunc_fmax(x1, x2): + pass - [-infinity, +infinity] and codomain [-infinity, +infinity], for each - element x_i of the input array x. - """ +@binary_expose.implements(np.fmin, api=API.NUMPY_API) +def _impl_ufunc_fmin(x1, x2): pass -@unary_expose.implements(np.cosh) -def _impl_ufunc_cosh(a): - """Calculates an implementation-dependent approximation to the hyperbolic cosine, having - domain. +# Floating functions +@binary_expose.implements(np.nextafter, api=API.NUMPY_API) +def _impl_ufunc_nextafter(x1, x2): + pass - [-infinity, +infinity] and codomain [-infinity, +infinity], for each - element x_i in the input array x. - """ +@binary_expose.implements(np.ldexp, api=API.NUMPY_API) +def _impl_ufunc_ldexp(x1, x2): pass -@unary_expose.implements(np.tanh) -def _impl_ufunc_tanh(a): - """Calculates an implementation-dependent approximation to the hyperbolic tangent, having - domain. +################################################################## - [-infinity, +infinity] and codomain [-1, +1], for each element x_i - of the input array x. - """ +@unary_expose.implements(np.absolute, api=API.NUMPY_API) +def _impl_ufunc_absolute(x): pass -@unary_expose.implements(np.arcsinh, api=API.NUMPY_API) -def _impl_ufunc_arcsinh(a): +@unary_expose.implements(np.rint, api=API.NUMPY_API) +def _impl_ufunc_rint(x): pass -@unary_expose.implements(np.arcsinh, ufunc_name='asinh') -def _impl_ufunc_asinh(a): - """ - Calculates an implementation-dependent approximation to the inverse hyperbolic sine, having - domain [-infinity, +infinity] and codomain [-infinity, +infinity], for each element x_i in the - input array x. - """ +@unary_expose.implements(np.conjugate, api=API.NUMPY_API) +def _impl_ufunc_conjugate(x): pass -@unary_expose.implements(np.arccosh, api=API.NUMPY_API) -def _impl_ufunc_arccosh(a): +@unary_expose.implements(np.exp2, api=API.NUMPY_API) +def _impl_ufunc_exp2(x): pass -@unary_expose.implements(np.arccosh, ufunc_name='acosh') -def _impl_ufunc_acosh(a): - """ - Calculates an implementation-dependent approximation to the inverse hyperbolic cosine, having - domain [+1, +infinity] and codomain [+0, +infinity], for each element x_i of the input array - x. - """ +# @unary_expose.implements(np.cbrt) # not supported by numba +@unary_expose.not_implemented("cbrt") +def _impl_ufunc_cbrt(x): pass -@unary_expose.implements(np.arctanh, api=API.NUMPY_API) -def _impl_ufunc_arctanh(a): +@unary_expose.implements(np.reciprocal, api=API.NUMPY_API) +def _impl_ufunc_reciprocal(x): pass -@unary_expose.implements(np.arctanh, ufunc_name='atanh') -def _impl_ufunc_atanh(a): - """ - Calculates an implementation-dependent approximation to the inverse hyperbolic tangent, having - domain [-1, +1] and codomain [-infinity, +infinity], for each element x_i of the input array - x. - """ +# Bit-twiddling functions +@unary_expose.implements(np.invert, api=API.NUMPY_API) +def _impl_ufunc_invert(x): pass -@unary_expose.implements(np.degrees, api=API.NUMPY_API) -def _impl_ufunc_degrees(a): - pass +# trigonometric functions -@unary_expose.implements(np.radians, api=API.NUMPY_API) -def _impl_ufunc_radians(a): +@unary_expose.implements(np.arcsin, api=API.NUMPY_API) +def _impl_ufunc_arcsin(x): pass -@unary_expose.implements(np.deg2rad, api=API.NUMPY_API) -def _impl_ufunc_deg2rad(a): +@unary_expose.implements(np.arccos, api=API.NUMPY_API) +def _impl_ufunc_arccos(x): pass -@unary_expose.implements(np.rad2deg, api=API.NUMPY_API) -def _impl_ufunc_rad2deg(a): +@unary_expose.implements(np.arctan, api=API.NUMPY_API) +def _impl_ufunc_arctan(x): pass -# Comparison functions -@unary_expose.implements(np.logical_not, dtype=typesystem.boolean8) -def _impl_ufunc_logical_not(a): - """ - Computes the logical NOT for each element x_i of the input array x. - """ +@unary_expose.implements(np.arcsinh, api=API.NUMPY_API) +def _impl_ufunc_arcsinh(x): pass -# Floating functions -@unary_expose.implements(np.isfinite, dtype=typesystem.boolean8) -def _impl_ufunc_isfinite(a): - """ - Tests each element x_i of the input array x to determine if finite (i.e., not NaN and not - equal to positive or negative infinity). - """ +@unary_expose.implements(np.arccosh, api=API.NUMPY_API) +def _impl_ufunc_arccosh(x): pass -@unary_expose.implements(np.isinf, dtype=typesystem.boolean8) -def _impl_ufunc_isinf(a): - """ - Tests each element x_i of the input array x to determine if equal to positive or negative - infinity. - """ +@unary_expose.implements(np.arctanh, api=API.NUMPY_API) +def _impl_ufunc_arctanh(x): pass -@unary_expose.implements(np.isnan, dtype=typesystem.boolean8) -def _impl_ufunc_isnan(a): - """ - Tests each element x_i of the input array x to determine whether the element is NaN. - """ +@unary_expose.implements(np.degrees, api=API.NUMPY_API) +def _impl_ufunc_degrees(x): pass -@unary_expose.implements(np.fabs, dtype=types.double, api=API.NUMPY_API) -def _impl_ufunc_fabs(a): +@unary_expose.implements(np.radians, api=API.NUMPY_API) +def _impl_ufunc_radians(x): pass -@unary_expose.implements(np.floor, dtype=types.double) -def _impl_ufunc_floor(a): - """ - Rounds each element x_i of the input array x to the greatest (i.e., closest to +infinity) - integer-valued number that is not greater than x_i. - """ +@unary_expose.implements(np.deg2rad, api=API.NUMPY_API) +def _impl_ufunc_deg2rad(x): pass -@unary_expose.implements(np.ceil, dtype=types.double) -def _impl_ufunc_ceil(a): - """ - Rounds each element x_i of the input array x to the smallest (i.e., closest to -infinity) - integer-valued number that is not less than x_i. - """ +@unary_expose.implements(np.rad2deg, api=API.NUMPY_API) +def _impl_ufunc_rad2deg(x): pass -@unary_expose.implements(np.trunc, dtype=types.double) -def _impl_ufunc_trunc(a): - """ - Rounds each element x_i of the input array x to the integer-valued number that is closest to - but no greater than x_i. - """ +# Floating functions + + +@unary_expose.implements(np.fabs, dtype=types.double, api=API.NUMPY_API) +def _impl_ufunc_fabs(x): pass # not supported? # @unary_expose.implements(np.isnat, dtype=types.int8) -@unary_expose.not_implemented('isnat') -def _impl_ufunc_isnat(a): +@unary_expose.not_implemented("isnat", api=API.NUMPY_API) +def _impl_ufunc_isnat(x): pass # issue 152: @unary_expose.implements(np.signbit, dtype=typesystem.boolean8, api=API.NUMPY_API) -def _impl_ufunc_signbit(a): +def _impl_ufunc_signbit(x): pass @unary_expose.implements(np.spacing, dtype=types.double, api=API.NUMPY_API) -def _impl_ufunc_spacing(a): +def _impl_ufunc_spacing(x): pass -@expose.implements('heaviside', api=API.NUMPY_API) +@expose.implements("heaviside", api=API.NUMPY_API) def _impl_heaviside(x1, x2): nb_dtype = types.double typA = determine_input_type(x1) typB = determine_input_type(x2) if isinstance(x1, ArrayPointer): + def impl(x1, x2): sz = len(x1) r = Array(sz, nb_dtype) for i in range(sz): r[i] = heaviside(x1[i], x2) # noqa: F821 return r + return impl else: + def impl(x1, x2): if typA(x1) < 0: return nb_dtype(0) @@ -832,4 +1687,5 @@ def impl(x1, x2): return nb_dtype(typB(x2)) else: return nb_dtype(1) + return impl diff --git a/rbc/stdlib/statistical_functions.py b/rbc/stdlib/statistical_functions.py index 307be92ca..04f977733 100644 --- a/rbc/stdlib/statistical_functions.py +++ b/rbc/stdlib/statistical_functions.py @@ -37,6 +37,23 @@ def _get_type_limits(eltype): def _impl_array_max(x): """ Calculates the maximum value of the input array x + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double[])') + ... def array_api_max(arr): + ... return array_api.max(arr) + >>> array_api_max([1.0, 3.0, 2.0]).execute() + 3.0 + """ if isinstance(x, ArrayPointer): # the array api standard says this is implementation specific @@ -68,6 +85,23 @@ def impl(x): def _impl_array_min(x): """ Calculates the minimum value of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double[])') + ... def array_api_min(arr): + ... return array_api.min(arr) + >>> array_api_min([1.0, 3.0, 2.0]).execute() + 1.0 + """ if isinstance(x, ArrayPointer): max_value = _get_type_limits(x.eltype).max @@ -91,6 +125,23 @@ def impl(x): def _impl_np_sum(a): """ Calculates the sum of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double[])') + ... def array_api_sum(arr): + ... return array_api.sum(arr) + >>> array_api_sum([1.0, 3.0, 2.0]).execute() + 6.0 + """ if isinstance(a, ArrayPointer): def impl(a): @@ -107,6 +158,23 @@ def impl(a): def _impl_np_prod(a): """ Calculates the product of input array x elements. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double[])') + ... def array_api_prod(arr): + ... return array_api.prod(arr) + >>> array_api_prod([4.0, 3.0, 2.0]).execute() + 24.0 + """ if isinstance(a, ArrayPointer): def impl(a): @@ -123,6 +191,23 @@ def impl(a): def _impl_array_mean(x): """ Calculates the arithmetic mean of the input array x. + + Examples + -------- + IGNORE: + >>> from rbc.heavydb import global_heavydb_singleton + >>> heavydb = next(global_heavydb_singleton) + >>> heavydb.unregister() + + IGNORE + + >>> from rbc.stdlib import array_api + >>> @heavydb('double(double[])') + ... def array_api_mean(arr): + ... return array_api.mean(arr) + >>> array_api_mean([1.0, 3.0, 2.0]).execute() + 2.0 + """ zero_value = np.nan diff --git a/rbc/tests/heavydb/test_array_api_datatypes.py b/rbc/tests/heavydb/test_array_api_datatypes.py new file mode 100644 index 000000000..4c326f580 --- /dev/null +++ b/rbc/tests/heavydb/test_array_api_datatypes.py @@ -0,0 +1,27 @@ +import pytest +import numpy as np +from rbc.tests import heavydb_fixture +from rbc.stdlib import datatypes, array_api + + +@pytest.fixture(scope='module') +def heavydb(): + for o in heavydb_fixture(globals(), load_test_data=False): + yield o + + +@pytest.mark.parametrize('dtype', datatypes.__all__) +def test_datatypes(heavydb, dtype): + heavydb.unregister() + + @heavydb(f'{dtype}[](int32)') + def test_datatype(size): + return array_api.ones(size, dtype=dtype) + + if dtype.startswith('uint') or dtype.startswith('complex'): + with pytest.raises(ValueError, match=".*cannot convert.*"): + test_datatype(5).execute() + else: + expected = np.ones(5, dtype=dtype) + got = test_datatype(5).execute() + np.testing.assert_equal(expected, got)