Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse logical operations from dpctl.tensor #1464

Merged
merged 5 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions dpnp/dpnp_algo/dpnp_algo.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,6 @@ cdef extern from "dpnp_iface_fptr.hpp" namespace "DPNPFuncName": # need this na
DPNP_FN_LOG1P_EXT
DPNP_FN_LOG2
DPNP_FN_LOG2_EXT
DPNP_FN_LOGICAL_AND_EXT
DPNP_FN_LOGICAL_NOT_EXT
DPNP_FN_LOGICAL_OR_EXT
DPNP_FN_LOGICAL_XOR_EXT
DPNP_FN_MATMUL
DPNP_FN_MATMUL_EXT
DPNP_FN_MATRIX_RANK
Expand Down Expand Up @@ -477,10 +473,6 @@ Logic functions
"""
cpdef dpnp_descriptor dpnp_isclose(dpnp_descriptor input1, dpnp_descriptor input2,
double rtol=*, double atol=*, cpp_bool equal_nan=*)
cpdef dpnp_descriptor dpnp_logical_and(dpnp_descriptor input1, dpnp_descriptor input2)
cpdef dpnp_descriptor dpnp_logical_not(dpnp_descriptor input1)
cpdef dpnp_descriptor dpnp_logical_or(dpnp_descriptor input1, dpnp_descriptor input2)
cpdef dpnp_descriptor dpnp_logical_xor(dpnp_descriptor input1, dpnp_descriptor input2)


"""
Expand Down
35 changes: 0 additions & 35 deletions dpnp/dpnp_algo/dpnp_algo_logic.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ __all__ += [
"dpnp_isfinite",
"dpnp_isinf",
"dpnp_isnan",
"dpnp_logical_and",
"dpnp_logical_not",
"dpnp_logical_or",
"dpnp_logical_xor",
]


Expand Down Expand Up @@ -223,34 +219,3 @@ cpdef utils.dpnp_descriptor dpnp_isnan(utils.dpnp_descriptor input1):
result.get_pyobj()[i] = numpy.isnan(input1.get_pyobj()[i])

return result


cpdef utils.dpnp_descriptor dpnp_logical_and(utils.dpnp_descriptor x1_obj,
utils.dpnp_descriptor x2_obj,
object dtype=None,
utils.dpnp_descriptor out=None,
object where=True):
return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_AND_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_and")


cpdef utils.dpnp_descriptor dpnp_logical_not(utils.dpnp_descriptor x_obj,
object dtype=None,
utils.dpnp_descriptor out=None,
object where=True):
return call_fptr_1in_1out_strides(DPNP_FN_LOGICAL_NOT_EXT, x_obj, dtype, out, where, func_name="logical_not")


cpdef utils.dpnp_descriptor dpnp_logical_or(utils.dpnp_descriptor x1_obj,
utils.dpnp_descriptor x2_obj,
object dtype=None,
utils.dpnp_descriptor out=None,
object where=True):
return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_OR_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_or")


cpdef utils.dpnp_descriptor dpnp_logical_xor(utils.dpnp_descriptor x1_obj,
utils.dpnp_descriptor x2_obj,
object dtype=None,
utils.dpnp_descriptor out=None,
object where=True):
return call_fptr_2in_1out_strides(DPNP_FN_LOGICAL_XOR_EXT, x1_obj, x2_obj, dtype, out, where, func_name="logical_xor")
235 changes: 234 additions & 1 deletion dpnp/dpnp_algo/dpnp_elementwise_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,101 @@
import dpctl
import dpctl.tensor as dpt
import dpctl.tensor._tensor_impl as ti
from dpctl.tensor._elementwise_common import BinaryElementwiseFunc
from dpctl.tensor._elementwise_common import (
BinaryElementwiseFunc,
UnaryElementwiseFunc,
)

import dpnp
import dpnp.backend.extensions.vm._vm_impl as vmi
from dpnp.dpnp_array import dpnp_array

__all__ = [
"check_nd_call_func",
"dpnp_add",
"dpnp_divide",
"dpnp_equal",
"dpnp_greater",
"dpnp_greater_equal",
"dpnp_less",
"dpnp_less_equal",
"dpnp_logical_and",
"dpnp_logical_not",
"dpnp_logical_or",
"dpnp_logical_xor",
"dpnp_multiply",
"dpnp_not_equal",
"dpnp_subtract",
]


def check_nd_call_func(
origin_func,
dpnp_func,
*x_args,
out=None,
where=True,
order="K",
dtype=None,
subok=True,
**kwargs,
):
"""
Checks arguments and calls function with a single input array.

Chooses a common internal elementwise function to call in DPNP based on input arguments
or to fallback on NumPy call if any passed argument is not currently supported.

"""

args_len = len(x_args)
if kwargs:
pass
elif where is not True:
pass
elif dtype is not None:
pass
elif subok is not True:
pass
elif args_len < 1 or args_len > 2:
raise ValueError(
"Unsupported number of input arrays to pass in elementwise function {}".format(
dpnp_func.__name__
)
)
elif args_len == 1 and dpnp.isscalar(x_args[0]):
# input has to be an array
pass
elif (
args_len == 2 and dpnp.isscalar(x_args[0]) and dpnp.isscalar(x_args[1])
):
# at least one of input has to be an array
pass
else:
if order in "afkcAFKC":
order = order.upper()
elif order is None:
order = "K"
else:
raise ValueError(
"order must be one of 'C', 'F', 'A', or 'K' (got '{}')".format(
order
)
)

return dpnp_func(*x_args, out=out, order=order)
return call_origin(
origin_func,
*x_args,
out=out,
where=where,
order=order,
dtype=dtype,
subok=subok,
**kwargs,
)


_add_docstring_ = """
add(x1, x2, out=None, order="K")

Expand Down Expand Up @@ -374,6 +449,164 @@ def dpnp_less_equal(x1, x2, out=None, order="K"):
return dpnp_array._create_from_usm_ndarray(res_usm)


_logical_and_docstring_ = """
logical_and(x1, x2, out=None, order='K')

Computes the logical AND for each element `x1_i` of the input array `x1`
with the respective element `x2_i` of the input array `x2`.

Args:
x1 (usm_ndarray):
First input array.
x2 (usm_ndarray):
Second input array.
out ({None, usm_ndarray}, optional):
Output array to populate.
Array have the correct shape and the expected data type.
order ("C","F","A","K", optional):
Memory layout of the newly output array, if parameter `out` is `None`.
Default: "K".
Returns:
usm_narray:
An array containing the element-wise logical AND results.
"""


def dpnp_logical_and(x1, x2, out=None, order="K"):
"""Invokes logical_and() from dpctl.tensor implementation for logical_and() function."""

# dpctl.tensor only works with usm_ndarray or scalar
x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
out_usm = None if out is None else dpnp.get_usm_ndarray(out)

func = BinaryElementwiseFunc(
"logical_and",
ti._logical_and_result_type,
ti._logical_and,
_logical_and_docstring_,
)
res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
return dpnp_array._create_from_usm_ndarray(res_usm)


_logical_not_docstring_ = """
logical_not(x, out=None, order='K')
Computes the logical NOT for each element `x_i` of input array `x`.
Args:
x (usm_ndarray):
Input array.
out (usm_ndarray):
antonwolfy marked this conversation as resolved.
Show resolved Hide resolved
Output array to populate. Array must have the correct
shape and the expected data type.
order ("C","F","A","K", optional): memory layout of the new
output array, if parameter `out` is `None`.
Default: "K".
Return:
usm_ndarray:
An array containing the element-wise logical NOT results.
"""


def dpnp_logical_not(x, out=None, order="K"):
"""Invokes logical_not() from dpctl.tensor implementation for logical_not() function."""

# dpctl.tensor only works with usm_ndarray or scalar
x_usm = dpnp.get_usm_ndarray(x)
out_usm = None if out is None else dpnp.get_usm_ndarray(out)

func = UnaryElementwiseFunc(
"logical_not",
ti._logical_not_result_type,
ti._logical_not,
_logical_not_docstring_,
)
res_usm = func(x_usm, out=out_usm, order=order)
return dpnp_array._create_from_usm_ndarray(res_usm)


_logical_or_docstring_ = """
logical_or(x1, x2, out=None, order='K')

Computes the logical OR for each element `x1_i` of the input array `x1`
with the respective element `x2_i` of the input array `x2`.

Args:
x1 (usm_ndarray):
First input array.
x2 (usm_ndarray):
Second input array.
out ({None, usm_ndarray}, optional):
Output array to populate.
Array have the correct shape and the expected data type.
order ("C","F","A","K", optional):
Memory layout of the newly output array, if parameter `out` is `None`.
Default: "K".
Returns:
usm_narray:
An array containing the element-wise logical OR results.
"""


def dpnp_logical_or(x1, x2, out=None, order="K"):
"""Invokes logical_or() from dpctl.tensor implementation for logical_or() function."""

# dpctl.tensor only works with usm_ndarray or scalar
x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
out_usm = None if out is None else dpnp.get_usm_ndarray(out)

func = BinaryElementwiseFunc(
"logical_or",
ti._logical_or_result_type,
ti._logical_or,
_logical_or_docstring_,
)
res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
return dpnp_array._create_from_usm_ndarray(res_usm)


_logical_xor_docstring_ = """
logical_xor(x1, x2, out=None, order='K')

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`.

Args:
x1 (usm_ndarray):
First input array.
x2 (usm_ndarray):
Second input array.
out ({None, usm_ndarray}, optional):
Output array to populate.
Array have the correct shape and the expected data type.
order ("C","F","A","K", optional):
Memory layout of the newly output array, if parameter `out` is `None`.
Default: "K".
Returns:
usm_narray:
An array containing the element-wise logical XOR results.
"""


def dpnp_logical_xor(x1, x2, out=None, order="K"):
"""Invokes logical_xor() from dpctl.tensor implementation for logical_xor() function."""

# dpctl.tensor only works with usm_ndarray or scalar
x1_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x1)
x2_usm_or_scalar = dpnp.get_usm_ndarray_or_scalar(x2)
out_usm = None if out is None else dpnp.get_usm_ndarray(out)

func = BinaryElementwiseFunc(
"logical_xor",
ti._logical_xor_result_type,
ti._logical_xor,
_logical_xor_docstring_,
)
res_usm = func(x1_usm_or_scalar, x2_usm_or_scalar, out=out_usm, order=order)
return dpnp_array._create_from_usm_ndarray(res_usm)


_multiply_docstring_ = """
multiply(x1, x2, out=None, order="K")

Expand Down
Loading