Skip to content

[Sema] Use different solution vectors for ComponentSteps created by DependentComponentSplitterStep #37964

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

Merged
merged 1 commit into from
Jun 23, 2021

Conversation

ahoppen
Copy link
Member

@ahoppen ahoppen commented Jun 17, 2021

Currently all ComponentSteps created by DependentComponentSplitterStep share the same Solutions vector. Because of this, the ComponentSteps might modify solutions created by previous ComponentSteps. Use different Solutions vectors for each ComponentStep to avoid sharing information between the ComponentSteps.

The concrete manifestation in the added test case is that the Bar overload gets added to Solutions, it’s score gets reduced by its ComponentStep original score, then the Foo overload gets added to Solutions and both solutions have their score decreased by the OriginalScore of Foo’s ComponentStep, causing Bar’s score to underflow.

Fixes rdar://78780840 [SR-14692]

@ahoppen ahoppen requested a review from xedin June 17, 2021 06:32
@ahoppen
Copy link
Member Author

ahoppen commented Jun 17, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 3aaa97fd881686d956227d1a9d14a438792f9667

@ahoppen
Copy link
Member Author

ahoppen commented Jun 17, 2021

@swift-ci Please test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 3aaa97fd881686d956227d1a9d14a438792f9667

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 3aaa97fd881686d956227d1a9d14a438792f9667

@ahoppen ahoppen force-pushed the pr/solutions-scoring branch from 3aaa97f to 59f9d43 Compare June 17, 2021 21:47
@ahoppen
Copy link
Member Author

ahoppen commented Jun 17, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 59f9d434b4f1ca14da585fdc60d8e359f990756a

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -294,6 +294,11 @@ class DependentComponentSplitterStep final : public SolverStep {
/// Array containing all of the partial solutions for the parent split.
MutableArrayRef<SmallVector<Solution, 4>> AllPartialSolutions;

/// The solutions computed the \c ComponentSteps created for each partial
/// solution combinations. Will be merged into the final \c Solutions vector
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: combination*

/// The solutions computed the \c ComponentSteps created for each partial
/// solution combinations. Will be merged into the final \c Solutions vector
/// in \c resume.
SmallVector<std::unique_ptr<SmallVector<Solution, 2>>, 2> ContextualSolutions;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we consider using plain std::vector here instead of wasting stack?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don’t have strong opinions but I think based on the fact that all but two tests passed with the SmallVector of size 2, it’s reasonable to assume that there are often only ComponentSteps that need to be taken here, so I think it’s worth to avoid the heap allocation of std::vector here, especially since the member of ContextualSolutions is only a pointer and thus not really occupying a whole lot of stack space.

Copy link
Contributor

Choose a reason for hiding this comment

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

We just might not have too many examples of complex result builders in the suite., but I am okay with leaving it as small vector for now too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, that’s true. I still think there’s still value in using the SmallVector and the overhead should be relatively low.

Copy link
Contributor

Choose a reason for hiding this comment

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

The only concern I have is for sufficiently complex result builders not to run out of stack in memory constrained environments because each dependent component would now allocate this storage and keep it along the whole duration of sub-path processing in splitter step.

Copy link
Member Author

@ahoppen ahoppen Jun 18, 2021

Choose a reason for hiding this comment

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

Maybe I’m missing something but I thought the constraint solver had a very low stack usage because it is using a work list to schedule new steps.

But if you think that’s an issue, I’ll change it to std::vector. As I said, I don’t have strong feelings about this.

Edit: I changed it to std::vector for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Constraint system and solutions use plenty of stack, we had to convert some of the small vectors to std::vector to mitigate that.

@xedin
Copy link
Contributor

xedin commented Jun 18, 2021

I would be great if you could add a unit test test with two dependencies that produce multiple solutions and non-empty original score to make sure that score behaves correctly. Could be done separately.

… `DependentComponentSplitterStep`

Currently all `ComponentSteps` created by `DependentComponentSplitterStep` share the same `Solutions` vector. Because of this, the `ComponentStep`s might modify solutions created by previous `ComponentStep`s. Use different `Solutions` vectors for each `ComponentStep` to avoid sharing information between the `ComponentStep`s.

The concrete manifestation in the added test case is that the `Bar` overload gets added to `Solutions`, it’s score gets reduced by its `ComponentStep` original score, then the `Foo` overload gets added to `Solutions` and both solutions have their score decreased by the `OriginalScore` of `Foo`’s `ComponentStep`, causing `Bar`’s score to underflow.

Fixes rdar://78780840 [SR-14692]
@ahoppen ahoppen force-pushed the pr/solutions-scoring branch from 59f9d43 to c3ce40d Compare June 18, 2021 13:17
@ahoppen
Copy link
Member Author

ahoppen commented Jun 18, 2021

I would be great if you could add a unit test test with two dependencies that produce multiple solutions and non-empty original score to make sure that score behaves correctly. Could be done separately.

I changed the code completion test case to a Sema test case that tests the same behavior. Could you take a look at it?

@ahoppen
Copy link
Member Author

ahoppen commented Jun 18, 2021

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - c3ce40d

@xedin
Copy link
Contributor

xedin commented Jun 18, 2021

I changed the code completion test case to a Sema test case that tests the same behavior.

I think that's good. I'll look into adding a more specific unit test which would validate scores directly, it would be pretty hard to do with integration tests using swift code.

@ahoppen
Copy link
Member Author

ahoppen commented Jun 22, 2021

@swift-ci Please test macOS

@ahoppen
Copy link
Member Author

ahoppen commented Jun 22, 2021

@swift-ci Please test Windows

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - c3ce40d

@ahoppen
Copy link
Member Author

ahoppen commented Jun 22, 2021

@swift-ci Please test macOS

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - c3ce40d

@ahoppen
Copy link
Member Author

ahoppen commented Jun 23, 2021

@swift-ci Please smoke test macOS

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.

3 participants