Skip to content
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

Filter rows with null keys when coalescing due to reaching cuDF row limits [databricks] #5531

Merged
merged 8 commits into from
May 23, 2022

Conversation

abellina
Copy link
Collaborator

@abellina abellina commented May 18, 2022

This PR is a workaround to handle cases where we would go above the cuDF row limit when coalescing a build-side batch in the hash join, but we have a chance to potentially rescue things if the batch is built mostly of nulls. The real fix is to not materialize those rows with null keys (https://issues.apache.org/jira/browse/SPARK-39131), but that fix in the logical plan introduces other issues that we don't have an answer to yet.

Posting this as a draft to get some comments on the implementation. Specifically on the join types that this applies to, it would be nice to get another pair of eyes there.

I'll look into adding a test for this.

…imits

Signed-off-by: Alessandro Bellina <abellina@nvidia.com>
val cb = if (inputFilterExpression.isDefined) {
// If we have reached the cuDF limit once, proactively filter batches
// after that first limit is reached.
GpuFilter.apply(cbFromIter, inputFilterExpression.get)
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit the apply is not needed.

GpuFilter(cbFromITer, inputFilterExpression.get)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this should be done.

@@ -351,7 +373,14 @@ abstract class AbstractGpuCoalesceIterator(

// there is a hard limit of 2^31 rows
while (numRows < Int.MaxValue && !hasOnDeck && iter.hasNext) {
closeOnExcept(iter.next()) { cb =>
closeOnExcept(iter.next()) { cbFromIter =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

The closing of this appears to be off by a bit in error cases. GpuFilter.apply closes the input batch. Ideally we should rename it to make it clear what it is doing. So after that happens if an exception is thrown we will get a double close on cbFromIter. This is kind of minor, but the result of the filter cb now is left unprotected if an exception is thrown and would leak.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have taken care of two of these cases, but I am still left with a potential double close on cb: 751dce0#diff-26bc5860b4878c986610d72135b63fedf0051e84e2a89c61a8df18aea942e139R417

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the problem is GpuFilter and us relying on it to close things for us. We should have a version that does not close and then we can have clearly defined boundaries.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes that makes sense. Will do

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried this, but at the end really in this case we always filter + close except for this last case I was left with, which seems like the simplest solution without refactoring more code is to null out the batch after it gets consumed by the filter: 74e16c2. Let me know if you disagree @revans2

@abellina
Copy link
Collaborator Author

Ok, I may need to cover one more case, and that is where we still have GpuCoalesceBatches(GpuShuffleCoalesce(shuffle)) for the build side. I am seeing this can still show up in the plan, even though we are trying to replace these actively via shuffledHashJoinOptimizeShuffle.

I am looking into it. Before I PRed this I had also changed childrenCoalesceGoal in GpuShuffledHashJoinExec to use RequireSingleBatchWithFilter instead of RequireSingleBatch, which totally works. But I am confused why the plan looks the way it looks. The change to childrenCoalesceGoal may require changes to other pattern matching, or to the inheritance structure so that RequireSingleBatchWithFilter and RequireSingleBatch have a common trait.

@abellina
Copy link
Collaborator Author

Ok, the reason for what I am seeing with some GpuShuffledHashJoinExec still having a build-side with GpuCoalesceBatches(GpuShuffleCoalesce(shuffle)) is because the rule I added here (#4588) is too restrictive: https://github.com/NVIDIA/spark-rapids/blob/branch-22.06/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuTransitionOverrides.scala#L247, checking also that the left side has a coalesce batches.

@sameerz sameerz added the reliability Features to improve reliability or bugs that severly impact the reliability of the plugin label May 20, 2022
@abellina abellina marked this pull request as ready for review May 20, 2022 05:21
@abellina
Copy link
Collaborator Author

build

@jlowe jlowe added this to the May 2 - May 20 milestone May 20, 2022
@abellina abellina changed the title Filter rows with null keys when coalescing due to reaching cuDF row l… Filter rows with null keys when coalescing due to reaching cuDF row limits [databricks] May 20, 2022
@abellina
Copy link
Collaborator Author

triggering the databricks CI

@abellina
Copy link
Collaborator Author

build

@abellina
Copy link
Collaborator Author

build

@abellina abellina merged commit 5f33368 into NVIDIA:branch-22.06 May 23, 2022
@abellina abellina deleted the join_coalesce_nulls branch May 23, 2022 18:27
tgravescs added a commit to tgravescs/spark-rapids that referenced this pull request Jun 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
reliability Features to improve reliability or bugs that severly impact the reliability of the plugin
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants