Skip to content

Commit c2c26f2

Browse files
authored
Merge pull request #79 from SwayamInSync/promoter-logic-fix
[BUG, REFAC]: Simplifies `quad_ufunc_promoter` + fixes reduction bug in `comparison_ufunc_promoter`
2 parents bab707d + 7e913e3 commit c2c26f2

2 files changed

Lines changed: 28 additions & 55 deletions

File tree

src/csrc/umath/comparison_ops.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,31 @@ NPY_NO_EXPORT int
260260
comparison_ufunc_promoter(PyObject *ufunc_obj, PyArray_DTypeMeta *const op_dtypes[],
261261
PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])
262262
{
263-
PyArray_DTypeMeta *new_signature[NPY_MAXARGS];
264-
memcpy(new_signature, signature, 3 * sizeof(PyArray_DTypeMeta *));
265-
new_signature[2] = NULL;
266-
int res = quad_ufunc_promoter(ufunc_obj, op_dtypes, new_signature, new_op_dtypes);
267-
if (res < 0) {
268-
return -1;
263+
// Reduction: accumulator is Bool, element is QuadPrecDType, output is Bool
264+
if (op_dtypes[0] == NULL) {
265+
Py_INCREF(&PyArray_BoolDType);
266+
new_op_dtypes[0] = &PyArray_BoolDType;
267+
Py_INCREF(op_dtypes[1]);
268+
new_op_dtypes[1] = op_dtypes[1];
269+
Py_INCREF(&PyArray_BoolDType);
270+
new_op_dtypes[2] = &PyArray_BoolDType;
271+
return 0;
272+
}
273+
274+
// Normal path: promote both inputs to QuadPrecDType, output is Bool
275+
for (int i = 0; i < 2; i++) {
276+
if (signature[i]) {
277+
Py_INCREF(signature[i]);
278+
new_op_dtypes[i] = signature[i];
279+
}
280+
else {
281+
Py_INCREF(&QuadPrecDType);
282+
new_op_dtypes[i] = &QuadPrecDType;
283+
}
269284
}
285+
270286
Py_INCREF(&PyArray_BoolDType);
271-
Py_XSETREF(new_op_dtypes[2], &PyArray_BoolDType);
287+
new_op_dtypes[2] = &PyArray_BoolDType;
272288
return 0;
273289
}
274290

src/include/umath/promoters.hpp

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,74 +16,31 @@ quad_ufunc_promoter(PyObject *ufunc_obj, PyArray_DTypeMeta *const op_dtypes[],
1616
PyArray_DTypeMeta *const signature[], PyArray_DTypeMeta *new_op_dtypes[])
1717
{
1818
PyUFuncObject *ufunc = (PyUFuncObject *)ufunc_obj;
19-
int nin = ufunc->nin;
2019
int nargs = ufunc->nargs;
21-
PyArray_DTypeMeta *common = NULL;
22-
bool has_quad = false;
2320

2421
// Handle the special case for reductions
2522
if (op_dtypes[0] == NULL) {
26-
assert(nin == 2 && ufunc->nout == 1); /* must be reduction */
23+
assert(ufunc->nin == 2 && ufunc->nout == 1); /* must be reduction */
2724
for (int i = 0; i < 3; i++) {
2825
Py_INCREF(op_dtypes[1]);
2926
new_op_dtypes[i] = op_dtypes[1];
3027
}
3128
return 0;
3229
}
3330

34-
// Check if any input or signature is QuadPrecision
35-
for (int i = 0; i < nin; i++) {
36-
if (op_dtypes[i] == &QuadPrecDType) {
37-
has_quad = true;
38-
}
39-
}
40-
41-
if (has_quad) {
42-
common = &QuadPrecDType;
43-
}
44-
else {
45-
for (int i = nin; i < nargs; i++) {
46-
if (signature[i] != NULL) {
47-
if (common == NULL) {
48-
Py_INCREF(signature[i]);
49-
common = signature[i];
50-
}
51-
else if (common != signature[i]) {
52-
Py_CLEAR(common); // Not homogeneous, unset common
53-
break;
54-
}
55-
}
56-
}
57-
}
58-
// If no common output dtype, use standard promotion for inputs
59-
if (common == NULL) {
60-
common = PyArray_PromoteDTypeSequence(nin, const_cast<PyArray_DTypeMeta **>(op_dtypes));
61-
if (common == NULL) {
62-
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
63-
PyErr_Clear(); // Do not propagate normal promotion errors
64-
}
65-
66-
return -1;
67-
}
68-
}
69-
70-
// Set all new_op_dtypes to the common dtype
31+
// This promoter is only registered for patterns where at least one
32+
// input is QuadPrecDType, so we always promote all args to QuadPrecDType.
7133
for (int i = 0; i < nargs; i++) {
7234
if (signature[i]) {
73-
// If signature is specified for this argument, use it
7435
Py_INCREF(signature[i]);
7536
new_op_dtypes[i] = signature[i];
7637
}
7738
else {
78-
// Otherwise, use the common dtype
79-
Py_INCREF(common);
80-
81-
new_op_dtypes[i] = common;
39+
Py_INCREF(&QuadPrecDType);
40+
new_op_dtypes[i] = &QuadPrecDType;
8241
}
8342
}
8443

85-
Py_XDECREF(common);
86-
8744
return 0;
8845
}
8946

0 commit comments

Comments
 (0)