Skip to content

Commit

Permalink
logical_and reduction (#1123)
Browse files Browse the repository at this point in the history
* Adding functionality for logical_and.reduce() with appropriate modifications in tests \n\n Joseph Guman <[email protected]>

* Minor style change to test for logical_and.reduce() \n\nSigned-off-by: Joseph Guman <[email protected]>

* Style changes and adding logical_or.reduce() functionality with UnaryRedCode.ANY Signed-off-by: Joseph Guman <[email protected]>

* Minor fixes

---------

Co-authored-by: Joseph Thomas Guman <[email protected]>
Co-authored-by: Manolis Papadakis <[email protected]>
Co-authored-by: Manolis Papadakis <[email protected]>
  • Loading branch information
4 people authored Mar 9, 2024
1 parent 788fed0 commit 9ece0a3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
2 changes: 2 additions & 0 deletions cunumeric/_ufunc/comparison.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@
"logical_and",
BinaryOpCode.LOGICAL_AND,
relation_types_of(all_dtypes),
red_code=UnaryRedCode.ALL,
)

logical_or = create_binary_ufunc(
"Compute the truth value of x1 OR x2 element-wise.",
"logical_or",
BinaryOpCode.LOGICAL_OR,
relation_types_of(all_dtypes),
red_code=UnaryRedCode.ANY,
)

logical_xor = create_binary_ufunc(
Expand Down
11 changes: 11 additions & 0 deletions cunumeric/_ufunc/ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,16 @@ def reduce(
f"reduction for {self} is not yet implemented"
)

if self._op_code in [
BinaryOpCode.LOGICAL_AND,
BinaryOpCode.LOGICAL_OR,
]:
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:
axis = None
Expand All @@ -767,6 +777,7 @@ def reduce(
keepdims=keepdims,
initial=initial,
where=where,
res_dtype=res_dtype,
)


Expand Down
11 changes: 9 additions & 2 deletions tests/integration/test_fallback.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,15 @@ def test_ufunc():
in_num = num.array([0, 1, 2, 3])
in_np = in_num.__array__()

out_num = np.logical_and.reduce(in_num)
out_np = np.logical_and.reduce(in_np)
# This test uses logical_and.accumulate because it is currently
# unimplemented, and we want to verify a behaviour of unimplemented ufunc
# methods. If logical_and.accumulate 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 = num.logical_and.accumulate(in_num)
out_np = np.logical_and.accumulate(in_np)
assert np.array_equal(out_num, out_np)


Expand Down
25 changes: 25 additions & 0 deletions tests/integration/test_logical_reduction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import numpy as np
import pytest

import cunumeric as num


@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)

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__":
import sys

sys.exit(pytest.main(sys.argv))

0 comments on commit 9ece0a3

Please sign in to comment.