Describe the bug
While I am able to do binary operations between decimal128 columns and python Decimal objects, attempting this with decimal32/64 raises a failure at the libcudf level:
```python-traceback
ValueError Traceback (most recent call last)
Cell In[1], line 19
16 col * Decimal("2.0")
18 # fails
---> 19 f(d.astype(cudf.Decimal32Dtype(1, 0)))
20 f(d.astype(cudf.Decimal64Dtype(1, 0)))
Cell In[1], line 7, in f(col)
6 def f(col):
----> 7 col > Decimal("2.0")
8 col >= Decimal("2.0")
9 col < Decimal("2.0")
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/site-packages/cudf/core/mixins/mixin_factory.py:11, in _partialmethod..wrapper(self, *args2, **kwargs2)
10 def wrapper(self, *args2, **kwargs2):
---> 11 return method(self, *args1, *args2, **kwargs1, **kwargs2)
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/site-packages/cudf/core/indexed_frame.py:3304, in IndexedFrame._binaryop(self, other, op, fill_value, can_reindex, *args, **kwargs)
3300 if operands is NotImplemented:
3301 return NotImplemented
3303 return self._from_data(
-> 3304 ColumnAccessor(type(self)._colwise_binop(operands, op)),
3305 index=out_index,
3306 )
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/contextlib.py:79, in ContextDecorator.__call__..inner(*args, **kwds)
76 @wraps(func)
77 def inner(*args, **kwds):
78 with self._recreate_cm():
---> 79 return func(*args, **kwds)
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/site-packages/cudf/core/frame.py:1730, in Frame._colwise_binop(cls, operands, fn)
1722 assert False, "At least one operand must be a column."
1724 # TODO: Disable logical and binary operators between columns that
1725 # are not numerical using the new binops mixin.
1727 outcol = (
1728 getattr(operator, fn)(right_column, left_column)
1729 if reflect
-> 1730 else getattr(operator, fn)(left_column, right_column)
1731 )
1733 if output_mask is not None:
1734 outcol = outcol.set_mask(output_mask)
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/site-packages/cudf/core/mixins/mixin_factory.py:11, in _partialmethod..wrapper(self, *args2, **kwargs2)
10 def wrapper(self, *args2, **kwargs2):
---> 11 return method(self, *args1, *args2, **kwargs1, **kwargs2)
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/site-packages/cudf/core/column/decimal.py:96, in DecimalBaseColumn._binaryop(self, other, op)
87 result.dtype.precision = output_type.precision
88 elif op in {
89 "__eq__",
90 "__ne__",
(...)
94 "__ge__",
95 }:
---> 96 result = libcudf.binaryop.binaryop(lhs, rhs, op, bool)
97 else:
98 raise TypeError(
99 f"{op} not supported for the following dtypes: "
100 f"{self.dtype}, {other.dtype}"
101 )
File /datasets/charlesb/mambaforge/envs/decimal/lib/python3.10/contextlib.py:79, in ContextDecorator.__call__..inner(*args, **kwds)
76 @wraps(func)
77 def inner(*args, **kwds):
78 with self._recreate_cm():
---> 79 return func(*args, **kwds)
File binaryop.pyx:188, in cudf._lib.binaryop.binaryop()
File binaryop.pyx:130, in cudf._lib.binaryop.binaryop_v_s()
ValueError: CUDF failure at:/opt/conda/conda-bld/work/cpp/src/binaryop/binaryop.cpp:206: Unsupported operator for these types
```
Steps/Code to reproduce bug
import cudf
from decimal import Decimal
d = cudf.Series([1, 2, 3])
def f(col):
col > Decimal("2.0")
col >= Decimal("2.0")
col < Decimal("2.0")
col <= Decimal("2.0")
col == Decimal("2.0")
col != Decimal("2.0")
col + Decimal("2.0")
col - Decimal("2.0")
col / Decimal("2.0")
col * Decimal("2.0")
# succeeds
f(d.astype(cudf.Decimal128Dtype(1, 0)))
# fails
f(d.astype(cudf.Decimal32Dtype(1, 0)))
f(d.astype(cudf.Decimal64Dtype(1, 0)))
Expected behavior
I would expect this operation to succeed and ideally return a column of the same decimal type.
Environment overview (please complete the following information)
Digging through the traceback, it seems like the underlying issue here is that Decimal32Column/Decimal64Column._wrap_binop_normalization normalize Decimal objects to cudf.Scalar(..., dtype=decimal128) when it seems like they should be normalize to their corresponding size. I also notice that for binary arithmetic we're seemingly upcasting to decimal128 following the operation:
Describe the bug While I am able to do binary operations between
decimal128
columns and pythonDecimal
objects, attempting this withdecimal32/64
raises a failure at the libcudf level:Steps/Code to reproduce bug
Expected behavior I would expect this operation to succeed and ideally return a column of the same decimal type.
Environment overview (please complete the following information)
Environment details
Click here to see environment details
Additional context This is coming up as part of adding support for decimal columns in dask-sql with https://github.com/dask-contrib/dask-sql/pull/1073.
Digging through the traceback, it seems like the underlying issue here is that
Decimal32Column
/Decimal64Column._wrap_binop_normalization
normalizeDecimal
objects tocudf.Scalar(..., dtype=decimal128)
when it seems like they should be normalize to their corresponding size. I also notice that for binary arithmetic we're seemingly upcasting todecimal128
following the operation:https://github.com/rapidsai/cudf/blob/173fde9d9ae335014a1aa6de60b417f6f245dcf2/python/cudf/cudf/core/column/decimal.py#L83-L87
But I'm not sure if this is intentional.