From 35d4d93590a67e425397cd003b5de85692234524 Mon Sep 17 00:00:00 2001 From: SwayamInSync Date: Thu, 30 Oct 2025 11:34:32 +0000 Subject: [PATCH 1/3] comparison reduction ops support --- quaddtype/numpy_quaddtype/src/casts.cpp | 2 + .../src/umath/comparison_ops.cpp | 2 +- quaddtype/tests/test_quaddtype.py | 64 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/quaddtype/numpy_quaddtype/src/casts.cpp b/quaddtype/numpy_quaddtype/src/casts.cpp index c43b89f0..e00f7a36 100644 --- a/quaddtype/numpy_quaddtype/src/casts.cpp +++ b/quaddtype/numpy_quaddtype/src/casts.cpp @@ -502,6 +502,8 @@ template <> inline npy_byte from_quad(quad_value x, QuadBackendType backend) { + // reduction ops often give warning, we can handle the NAN casting + // this behaviour might apply to all casting if (backend == BACKEND_SLEEF) { return (npy_byte)Sleef_cast_to_int64q1(x.sleef_value); } diff --git a/quaddtype/numpy_quaddtype/src/umath/comparison_ops.cpp b/quaddtype/numpy_quaddtype/src/umath/comparison_ops.cpp index 8ff2e661..ec285b86 100644 --- a/quaddtype/numpy_quaddtype/src/umath/comparison_ops.cpp +++ b/quaddtype/numpy_quaddtype/src/umath/comparison_ops.cpp @@ -200,7 +200,7 @@ create_quad_comparison_ufunc(PyObject *numpy, const char *ufunc_name) return -1; } - PyObject *DTypes = PyTuple_Pack(3, &PyArrayDescr_Type, &PyArrayDescr_Type, &PyArray_BoolDType); + PyObject *DTypes = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (DTypes == 0) { Py_DECREF(promoter_capsule); return -1; diff --git a/quaddtype/tests/test_quaddtype.py b/quaddtype/tests/test_quaddtype.py index d657d8df..39118165 100644 --- a/quaddtype/tests/test_quaddtype.py +++ b/quaddtype/tests/test_quaddtype.py @@ -385,6 +385,70 @@ def test_array_minmax(op, a, b): assert np.signbit(float_res) == np.signbit( quad_res), f"Zero sign mismatch for {op}({a}, {b})" +class TestComparisonReductionOps: + """Test suite for comparison reduction operations on QuadPrecision arrays.""" + + @pytest.mark.parametrize("op", ["all", "any"]) + @pytest.mark.parametrize("input_array", [ + (["1.0", "2.0", "3.0"]), + (["1.0", "0.0", "3.0"]), + (["0.0", "0.0", "0.0"]), + # Including negative zero + (["-0.0", "0.0"]), + # Including NaN (should be treated as true) + (["nan", "1.0"]), + (["nan", "0.0"]), + (["nan", "nan"]), + # inf cases + (["inf", "1.0"]), + (["-inf", "0.0"]), + (["inf", "-inf"]), + # Mixed cases + (["1.0", "-0.0", "nan", "inf"]), + (["0.0", "-0.0", "nan", "-inf"]), + ]) + def test_reduction_ops(self, op, input_array): + """Test all and any reduction operations.""" + quad_array = np.array([QuadPrecision(x) for x in input_array]) + float_array = np.array([float(x) for x in input_array]) + if op == "all": + result = np.all(quad_array) + expected = np.all(float_array) + else: # op == "any" + result = np.any(quad_array) + expected = np.any(float_array) + + assert result == expected, ( + f"Reduction op '{op}' failed for input {input_array}: " + f"expected {expected}, got {result}" + ) + + @pytest.mark.parametrize("val_str", [ + "0.0", + "-0.0", + "1.0", + "-1.0", + "nan", + "inf", + "-inf", + ]) + def test_scalar_reduction_ops(self, val_str): + """Test reduction operations on scalar QuadPrecision values.""" + quad_val = QuadPrecision(val_str) + float_val = float(val_str) + + result_all = np.all(quad_val) + expected_all_result = np.all(float_val) + assert result_all == expected_all_result, ( + f"Scalar all failed for {val_str}: expected {expected_all_result}, got {result_all}" + ) + + result_any = np.any(quad_val) + expected_any_result = np.any(float_val) + assert result_any == expected_any_result, ( + f"Scalar any failed for {val_str}: expected {expected_any_result}, got {result_any}" + ) + # Logical operations tests @pytest.mark.parametrize("op", ["logical_and", "logical_or", "logical_xor"]) From e3c51a93a5ba7f68c608a0a48474405472071c29 Mon Sep 17 00:00:00 2001 From: SwayamInSync Date: Thu, 30 Oct 2025 11:37:50 +0000 Subject: [PATCH 2/3] np.f64 --- quaddtype/tests/test_quaddtype.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/quaddtype/tests/test_quaddtype.py b/quaddtype/tests/test_quaddtype.py index 39118165..f3a229c4 100644 --- a/quaddtype/tests/test_quaddtype.py +++ b/quaddtype/tests/test_quaddtype.py @@ -435,16 +435,16 @@ def test_reduction_ops(self, op, input_array): def test_scalar_reduction_ops(self, val_str): """Test reduction operations on scalar QuadPrecision values.""" quad_val = QuadPrecision(val_str) - float_val = float(val_str) - - result_all = np.all(quad_val) - expected_all_result = np.all(float_val) + float_val = np.float64(val_str) + + result_all = quad_val.all() + expected_all_result = float_val.all() assert result_all == expected_all_result, ( f"Scalar all failed for {val_str}: expected {expected_all_result}, got {result_all}" ) - result_any = np.any(quad_val) - expected_any_result = np.any(float_val) + result_any = quad_val.any() + expected_any_result = float_val.any() assert result_any == expected_any_result, ( f"Scalar any failed for {val_str}: expected {expected_any_result}, got {result_any}" ) From 41fc5ad2bbb4ab0fadc78e23df2e0ed319ea365e Mon Sep 17 00:00:00 2001 From: SwayamInSync Date: Thu, 30 Oct 2025 12:18:21 +0000 Subject: [PATCH 3/3] better comment + getattr --- quaddtype/numpy_quaddtype/src/casts.cpp | 5 +++-- quaddtype/tests/test_quaddtype.py | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/quaddtype/numpy_quaddtype/src/casts.cpp b/quaddtype/numpy_quaddtype/src/casts.cpp index e00f7a36..e4da0ad9 100644 --- a/quaddtype/numpy_quaddtype/src/casts.cpp +++ b/quaddtype/numpy_quaddtype/src/casts.cpp @@ -502,8 +502,9 @@ template <> inline npy_byte from_quad(quad_value x, QuadBackendType backend) { - // reduction ops often give warning, we can handle the NAN casting - // this behaviour might apply to all casting + // runtime warnings often comes from/to casting of NaN, inf + // casting is used by ops at several positions leading to warnings + // fix can be catching the cases and returning corresponding type value without casting if (backend == BACKEND_SLEEF) { return (npy_byte)Sleef_cast_to_int64q1(x.sleef_value); } diff --git a/quaddtype/tests/test_quaddtype.py b/quaddtype/tests/test_quaddtype.py index f3a229c4..27368e57 100644 --- a/quaddtype/tests/test_quaddtype.py +++ b/quaddtype/tests/test_quaddtype.py @@ -411,12 +411,9 @@ def test_reduction_ops(self, op, input_array): """Test all and any reduction operations.""" quad_array = np.array([QuadPrecision(x) for x in input_array]) float_array = np.array([float(x) for x in input_array]) - if op == "all": - result = np.all(quad_array) - expected = np.all(float_array) - else: # op == "any" - result = np.any(quad_array) - expected = np.any(float_array) + op = getattr(np, op) + result = op(quad_array) + expected = op(float_array) assert result == expected, ( f"Reduction op '{op}' failed for input {input_array}: "