Skip to content

BUG: Preserve object common-dtype promotion in Quad ufuncs - #118

Open
SwayamInSync wants to merge 1 commit into
numpy:mainfrom
SwayamInSync:fix-object-promotion-114
Open

BUG: Preserve object common-dtype promotion in Quad ufuncs#118
SwayamInSync wants to merge 1 commit into
numpy:mainfrom
SwayamInSync:fix-object-promotion-114

Conversation

@SwayamInSync

@SwayamInSync SwayamInSync commented Jul 29, 2026

Copy link
Copy Markdown
Member

Closes #114

The promoters now preserve NumPy's ObjectDType precedence. When a Quad ufunc receives an object-array input, it selects NumPy's existing object loop rather than forcing the object operand to Quad.

This applies in both operand orders and covers:

  • Arithmetic ufuncs such as add and multiply
  • Comparisons with Boolean output
  • Logical operations with the object output used by NumPy's object loops
  • matmul
  • Broadcasting and masked out= operations
  • Both SLEEF and long-double backends

Operations without an applicable object loop continue to raise normally. Unsupported Quad/complex and Quad/string promotion is unchanged, and importing quaddtype does not affect built-in-only NumPy dispatch.

The change also makes matmul promoter registration failures propagate instead of being silently cleared.

@SwayamInSync
SwayamInSync requested a review from ngoldbaum July 29, 2026 13:05
@SwayamInSync

Copy link
Copy Markdown
Member Author

This is small addition but important to ensure we do not override NumPy's default

@ngoldbaum ngoldbaum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for taking so long! Just one comment about the promoters below and a request for a comment. Also maybe take a look if the promoters are overly-broad right now elsewhere in the implementation (try to avoid promoters that match for all dtypes).



static bool
comparison_object_output_is_bool(PyUFuncObject *ufunc)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a one-line comment that this is needed to match numpy's semantics, which use bools for the comparison loops but object dtype for the logical_ functions.

@@ -373,7 +386,7 @@ create_quad_comparison_ufunc(PyObject *numpy, const char *ufunc_name)

// Register promoter for (Any, QuadPrecDType, Bool) - needed for reverse mixed-type comparisons
DTypes = PyTuple_Pack(3, &PyArrayDescr_Type, &QuadPrecDType, &PyArray_BoolDType);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this one and the one on line 373 use PyArray_ObjectDType as the result and "other" operand dtype? For changing the result dtype, this works just fine (for example):

>>> import numpy as np
>>> a = np.array(4, dtype='O')
>>> b = np.array(4.5)
>>> result = np.array(7, dtype='O')
>>> np.equal(a, b, out=result)
array(False, dtype=object)
>>> result
array(False, dtype=object)

The way you have it written here with exactly Bool as the output doesn't match that.

Also use PyArray_ObjectDtype instead of PyArrayDescr_Type, the latter fires for all dtypes so even if that doesn't lead to a bug and cause weirdness in unrelated dtypes, it's also a performance hit for all ufunc dispatch for all other dtypes.

Comment thread tests/test_quaddtype.py
Comment on lines +6570 to +6573
with pytest.raises(AttributeError):
np.logical_xor(left.astype(object), right.astype(object))
with pytest.raises(AttributeError):
np.logical_xor(left, right)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeError?? Is this test encoding a bug in numpy or something?

Comment thread tests/test_quaddtype.py

@pytest.mark.parametrize("backend", ["sleef", "longdouble"], indirect=True)
@pytest.mark.parametrize("reverse", [False, True])
def test_divmod_without_object_loop_still_raises(self, operands, reverse):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not add a divmod object loop?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Quad ufunc promoters override valid object common-dtype promotion

2 participants