From 4c887fdc0115a64173d85e9825e970d53c4f0ea9 Mon Sep 17 00:00:00 2001 From: Joseph Thomas Guman Date: Tue, 13 Feb 2024 15:28:22 -0800 Subject: [PATCH] Style changes and adding logical_or.reduce() functionality with UnaryRedCode.ANY Signed-off-by: Joseph Guman --- cunumeric/_ufunc/comparison.py | 3 ++- cunumeric/_ufunc/ufunc.py | 8 ++++++-- tests/integration/test_fallback.py | 11 +++++++++-- tests/integration/test_logical_reduction.py | 16 +++++++++------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/cunumeric/_ufunc/comparison.py b/cunumeric/_ufunc/comparison.py index b6f5739a3..726936166 100644 --- a/cunumeric/_ufunc/comparison.py +++ b/cunumeric/_ufunc/comparison.py @@ -73,7 +73,7 @@ "logical_and", BinaryOpCode.LOGICAL_AND, relation_types_of(all_dtypes), - red_code=UnaryRedCode.PROD, + red_code=UnaryRedCode.ALL, ) logical_or = create_binary_ufunc( @@ -81,6 +81,7 @@ "logical_or", BinaryOpCode.LOGICAL_OR, relation_types_of(all_dtypes), + red_code=UnaryRedCode.ANY, ) logical_xor = create_binary_ufunc( diff --git a/cunumeric/_ufunc/ufunc.py b/cunumeric/_ufunc/ufunc.py index 7b6c4b84b..011ef13d1 100644 --- a/cunumeric/_ufunc/ufunc.py +++ b/cunumeric/_ufunc/ufunc.py @@ -756,9 +756,12 @@ def reduce( if self._op_code in [ BinaryOpCode.LOGICAL_AND, BinaryOpCode.LOGICAL_OR, - BinaryOpCode.LOGICAL_XOR, ]: - array = array._astype(bool, temporary=True) + res_dtype = bool + if dtype is not None: + raise TypeError("Cannot set dtype on a logical reduction") + else: + res_dtype = None # NumPy seems to be using None as the default axis value for scalars if array.ndim == 0 and axis == 0: @@ -774,6 +777,7 @@ def reduce( keepdims=keepdims, initial=initial, where=where, + res_dtype=res_dtype, ) diff --git a/tests/integration/test_fallback.py b/tests/integration/test_fallback.py index e910fa706..545f1513d 100644 --- a/tests/integration/test_fallback.py +++ b/tests/integration/test_fallback.py @@ -28,8 +28,15 @@ def test_ufunc(): in_num = num.array([0, 1, 2, 3]) in_np = in_num.__array__() - out_num = np.logical_or.reduce(in_num) - out_np = np.logical_or.reduce(in_np) + # This test uses logical_xor.reduce because it is currently unimplemented, + # and we want to verify a behaviour of unimplemented ufunc methods. If + # logical_xor.reduce becomes implemented in the future, this assertion will + # start to fail, and a new (unimplemented) ufunc method should be found to + # replace it + assert not num.logical_and.accumulate._cunumeric.implemented + + out_num = np.logical_and.accumulate(in_num) + out_np = np.logical_and.accumulate(in_np) assert np.array_equal(out_num, out_np) diff --git a/tests/integration/test_logical_reduction.py b/tests/integration/test_logical_reduction.py index 3bcc75fd1..023c2526c 100644 --- a/tests/integration/test_logical_reduction.py +++ b/tests/integration/test_logical_reduction.py @@ -1,20 +1,22 @@ import numpy as np import pytest -from utils.comparisons import allclose import cunumeric as num -def test_logical_and_reduce(): +@pytest.mark.parametrize("axis", [None, 0, 1, 2, (0, 1, 2)]) +def test_logical_reductions(axis): input = [[[12, 0, 1, 2], [9, 0, 0, 1]], [[0, 0, 0, 5], [1, 1, 1, 1]]] in_num = num.array(input) in_np = np.array(input) - axes = [None, 0, 1, 2, (0, 1, 2)] - for axis in axes: - out_num = num.logical_and.reduce(in_num, axis=axis) - out_np = np.logical_and.reduce(in_np, axis=axis) - assert allclose(out_num, out_np, check_dtype=True) + out_num = num.logical_and.reduce(in_num, axis=axis) + out_np = np.logical_and.reduce(in_np, axis=axis) + assert num.array_equal(out_num, out_np) + + out_num = num.logical_or.reduce(in_num, axis=axis) + out_np = np.logical_or.reduce(in_np, axis=axis) + assert num.array_equal(out_num, out_np) if __name__ == "__main__":