-
Notifications
You must be signed in to change notification settings - Fork 915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use fused types for overloaded function signatures #14969
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,25 +18,25 @@ from .types cimport DataType | |
|
||
|
||
cpdef Column binary_operation( | ||
object lhs, | ||
object rhs, | ||
LeftBinaryOperand lhs, | ||
RightBinaryOperand rhs, | ||
binary_operator op, | ||
DataType data_type | ||
): | ||
"""Perform a binary operation between a column and another column or scalar. | ||
|
||
Either ``lhs`` or ``rhs`` must be a | ||
:py:class:`~cudf._lib.pylibcudf.column.Column`. The other may be a | ||
``lhs`` and ``rhs`` may be a | ||
:py:class:`~cudf._lib.pylibcudf.column.Column` or a | ||
:py:class:`~cudf._lib.pylibcudf.scalar.Scalar`. | ||
:py:class:`~cudf._lib.pylibcudf.scalar.Scalar`, but at least one must be a | ||
:py:class:`~cudf._lib.pylibcudf.column.Column`. | ||
|
||
For details, see :cpp:func:`binary_operation`. | ||
|
||
Parameters | ||
---------- | ||
lhs : Column or Scalar | ||
lhs : Union[Column, Scalar] | ||
The left hand side argument. | ||
rhs : Column or Scalar | ||
rhs : Union[Column, Scalar] | ||
The right hand side argument. | ||
op : BinaryOperator | ||
The operation to perform. | ||
|
@@ -50,32 +50,32 @@ cpdef Column binary_operation( | |
""" | ||
cdef unique_ptr[column] result | ||
|
||
if isinstance(lhs, Column) and isinstance(rhs, Column): | ||
if LeftBinaryOperand is Column and RightBinaryOperand is Column: | ||
with nogil: | ||
result = move( | ||
cpp_binaryop.binary_operation( | ||
(<Column> lhs).view(), | ||
(<Column> rhs).view(), | ||
lhs.view(), | ||
rhs.view(), | ||
op, | ||
data_type.c_obj | ||
) | ||
) | ||
elif isinstance(lhs, Column) and isinstance(rhs, Scalar): | ||
elif LeftBinaryOperand is Column and RightBinaryOperand is Scalar: | ||
with nogil: | ||
result = move( | ||
cpp_binaryop.binary_operation( | ||
(<Column> lhs).view(), | ||
dereference((<Scalar> rhs).c_obj), | ||
lhs.view(), | ||
dereference(rhs.c_obj), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to evaluate the lhs/rhs objects ahead of time and reduce the dispatching logic here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm assuming that what you're envisioning is something like (pseudocode):
Is that what you're thinking? If so, unfortunately no that doesn't work. There are two reasons:
Ultimately the translation from Cython types (fused or not) to C++ types remains a point of friction. Let me know if that answered your question or if you meant something else. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool. That was my expectation but I didn't want to miss out on anything special if fused types would allow this. |
||
op, | ||
data_type.c_obj | ||
) | ||
) | ||
elif isinstance(lhs, Scalar) and isinstance(rhs, Column): | ||
elif LeftBinaryOperand is Scalar and RightBinaryOperand is Column: | ||
with nogil: | ||
result = move( | ||
cpp_binaryop.binary_operation( | ||
dereference((<Scalar> lhs).c_obj), | ||
(<Column> rhs).view(), | ||
dereference(lhs.c_obj), | ||
rhs.view(), | ||
op, | ||
data_type.c_obj | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pull out the line that defines the table/scalar here and declare a separate variable for it? It is hard to read a three-line expression that just supplies one argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's fair. TBH I'm not too concerned about how legacy Cython code looks right now because once we've completed pylibcudf we'll need to rewrite cudf internals substantially to leverage pylibcudf properly, so all of this will go away.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would pulling that out into a variable be able to avoid the conditional cdef-ing problem? Why/why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, was this question meant for the other thread?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I'm trying to ask a related question here. I realize now it's because this is
def
and the other iscpdef
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right that's why I was confused, now I see. You're on the right track; it's less about this function being a def or a cpdef, and more about what it's calling. We're calling pylibcudf as a Python API here, so it accepts arbitrary objects as input and we're not cdefing them. In the other places we have to cdef the inputs because we are calling cdef functions (C++ cdef extern functions) that require strongly typed input.