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

DYN-1722 #9578

Merged
merged 10 commits into from
Mar 25, 2019
Merged

DYN-1722 #9578

merged 10 commits into from
Mar 25, 2019

Conversation

reddyashish
Copy link
Contributor

@reddyashish reddyashish commented Mar 15, 2019

Purpose

This PR is to address a regression issue from 2.0. (https://jira.autodesk.com/browse/DYN-1722)

This also fixes most of the non-regressions from https://jira.autodesk.com/browse/DYN-1496. The only case that is failing would be the second case in the description of the above JIRA.

Explanation:
Instead of the just returning the first replication option that matches the target function, we check for all the replications that match the target function and then choose the replication option with largest rank. In the case where both cartesian and zipped replication options are possible, we check for the first option that matches the target function and modify the replication option(in next iterations) only if
a similar replication option, with a higher rank, is matched with the target function.

Replication Fix

Performance test results on around 11 graphs:

Before the fix:
before

After the fix:
after

Declarations

Check these if you believe they are true

  • The code base is in a better state after this PR
  • Is documented according to the standards
  • The level of testing this PR includes is appropriate
  • User facing strings, if any, are extracted into *.resx files
  • All tests pass using the self-service CI.
  • Snapshot of UI changes, if any.
  • Changes to the API follow Semantic Versioning, and are documented in the API Changes document.

Reviewers

@aparajit-pratap @mjkkirschner @QilongTang

@mjkkirschner
Copy link
Member

@reddyashish have you had a chance to try running this change over a set of graphs before and after using the perf console app?

@reddyashish
Copy link
Contributor Author

reddyashish commented Mar 15, 2019

Not yet, discussed this with Aparajit and we will be doing it next. We would be needing a set of large graphs that would be testing cases involving function match resolution. Any idea on if we got any?

@mjkkirschner
Copy link
Member

I am sure if we can be specific about what graph types we want @JacobSmall and @Amoursol can provide a bunch.

@JacobSmall
Copy link

If I don’t have one ready I can likely build one (or ten) up pretty quickly. Looking for a lot of nodes or a lot of objects?

@aparajit-pratap
Copy link
Contributor

@reddyashish please enumerate and explain the case(s) that are yet to be fixed. You mentioned that the second example in DYN-1496 isn't fixed but you can generalize it a bit more; for example: A heterogeneous list of sublists, where the first sublist type does not match the target function, does not replicate properly. Example:
image

src/Engine/ProtoCore/Lang/CallSite.cs Outdated Show resolved Hide resolved
src/Engine/ProtoCore/Lang/CallSite.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@aparajit-pratap aparajit-pratap left a comment

Choose a reason for hiding this comment

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

Ashish, I don’t fully understand the code change especially the IsCompatible function. I saw the 2 test failures you mentioned on self serve and I didn’t see why the above change was required to address them?

private Boolean IsCompatibleReplicationOption(List<ReplicationInstruction> oldOption, List<ReplicationInstruction> newOption)
{
if (oldOption.Count > 0 && newOption.Count > 0 && oldOption.Count < newOption.Count)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

I’m not sure I understand this change. Why are you checking equality only for the first option?

Copy link
Contributor Author

@reddyashish reddyashish Mar 18, 2019

Choose a reason for hiding this comment

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

For those 2 cases where it was failing, as we are checking for all the replication options(to find a match), the first match is found for "cartesian:indices=0" option. Then it finds a match for "zipped:indices=0,1" and it applies zipped replication option(as this is the final option that is tested). Previously, the first option that found a match was applied directly. After this change, it would not accept the zipped replication as the cartesian option has already found the match.
Another case is, we want to accept this new replication option, if it is of the higher rank than the previous option (old option: "cartesian:indices=0" and new option: "cartesian:indices=0, cartesian:indices=0". Similar option but checks for one extra depth level). Since all options are unique, I was checking the first element and the count for the new option to be higher than the first. Also can use, newOption.Count = oldOption.Count +1.

Copy link
Member

Choose a reason for hiding this comment

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

I'm definitely having a hard time understanding this one, is it possible @reddyashish you could draw a diagram or do a longer writeup of the problem here and the approach taken to fix it - I know it's kind of a tall order.

Copy link
Member

@mjkkirschner mjkkirschner Mar 22, 2019

Choose a reason for hiding this comment

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

so - I'm trying to think of cases where this will fail -
I think naming this method or adding a summary might help - but my interpretation is that this method is used to find List<ReplicationInstruction> where the first instruction matches the previous one but is of a greater depth?

What I cannot figure out or explain yet is what case this is used to avoid or to guarantee we hit? Can you try to sum it up in the summary of the method or in the git here.

}
}
if (matchFound)
return;
Copy link
Member

Choose a reason for hiding this comment

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

@reddyashish so - what about case 5 - why do we exit the other cases late, and exit case 5 as soon as we find a match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did not understand this case and it adds an empty replication option to the previous list and finds the match. I was not able to find any examples related to this case.

Copy link
Member

Choose a reason for hiding this comment

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

I will try to find when it's called.
@saintentropy any ideas?

Copy link
Contributor

Choose a reason for hiding this comment

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

@mjkkirschner @reddyashish In general this whole function is still black magic to me. I have been able to look at indivual examples and how they flow through but it is hard to make judgment on individual PR's without holistic picture. I think we need to document examples of different data, data structures, replication settings, and functions and what the result replication instruction and function endpoint list. Not sure if we need to do that on this PR but it is hard to validate the code changes otherwise

Copy link
Member

Choose a reason for hiding this comment

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

For a start - I've filed a followup task to cover each of the missing cases with explicit tests.

@mjkkirschner
Copy link
Member

mjkkirschner commented Mar 22, 2019

I think these cases really need examples. I know they are not new, but I think if you have some idea about which types of function calls apply to which cases those examples inline would be a good addition to the comments.

return;
if (replicationInstructions == null || IsCompatibleReplicationOption(replicationInstructions, replicationOption))
{
//Otherwise we have a cluster of FEPs that can be used to dispatch the array
Copy link
Member

Choose a reason for hiding this comment

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

I find this comment confusing - what is the otherwise referring to - theres no comment before this and we are inside an if statement... not an else statement -

@@ -44,5 +45,22 @@ public override string ToString()
}

}

public Boolean Equals(ReplicationInstruction oldOption) {
Copy link
Member

Choose a reason for hiding this comment

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

this does not seem to actually perform a full equality check... it only returns true for zip replication - you should override Equals like this

https://docs.microsoft.com/en-us/dotnet/api/system.object.equals?view=netframework-4.7.2

use the override keyword

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mjkkirschner Do you want me change anything in this Equals method after our discussion on friday or is this ok?

Copy link
Member

Choose a reason for hiding this comment

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

hmm, well I guess I am a bit confused why you do not just compare the properties directly? ie Why all the use of Except?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added the comments to code, on why we can use Except to compare the elements in both the lists.

@mjkkirschner
Copy link
Member

@reddyashish thanks for updating comments and tests - is the only thing left that we discussed the performance testing of a pathologically bad case? (super nested?) or many many parameter function?

@reddyashish
Copy link
Contributor Author

Performance results for a case which has around 110 replication replication trials.
Before the fix(snapshot on top) and after the fix(snapshot on below):

latest

if (this.Zipped == oldOption.Zipped)
{
if (this.ZipIndecies == null && oldOption.ZipIndecies == null)
return true;
Copy link
Member

Choose a reason for hiding this comment

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

why is this true even if the zip algorithm is different?

Copy link
Contributor Author

@reddyashish reddyashish Mar 25, 2019

Choose a reason for hiding this comment

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

Added the zipAlgorithm check.

if (this.ZipIndecies == null && oldOption.ZipIndecies == null)
return true;

if (this.ZipIndecies != null && oldOption.ZipIndecies != null)
Copy link
Member

@mjkkirschner mjkkirschner Mar 25, 2019

Choose a reason for hiding this comment

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

I'm not getting something here - can you add a comment - but like I said above, I'm confused why we're not using sequence equals or something like that?

Copy link
Member

Choose a reason for hiding this comment

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

@reddyashish explained this is an optimization.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fastest way to compare elements of both the lists:
https://stackoverflow.com/questions/12795882/quickest-way-to-compare-two-list

I have added comments to the code.

@mjkkirschner
Copy link
Member

mjkkirschner commented Mar 25, 2019

@reddyashish - Is this ready to merge?

@reddyashish
Copy link
Contributor Author

reddyashish commented Mar 25, 2019

The self-serve looks good.
https://master-15.jenkins.autodesk.com/view/DYN/job/DYN-DevCI_Self_Service/219/

The performance benchmark tests for the graphs(created by Scott) are still running, so once that is done we can merge it.

@reddyashish
Copy link
Contributor Author

reddyashish commented Mar 25, 2019

Performance benchmark results for graphs in here:https://github.com/DynamoDS/Dynamo/tree/master/tools/Performance/DynamoPerformanceTests/graphs

Before these changes:
before

After these changes:
after

Both the times, the run time was higher than what Scott has reported in his PR. I followed up with Scott and he will be running them again on his machine to see if he can see any difference.

@mjkkirschner
Copy link
Member

@scottmitchell - we really need to figure out how to get the full name in the performance results output 😉... @reddyashish what do you make of those results?

@reddyashish
Copy link
Contributor Author

reddyashish commented Mar 25, 2019

The Mean, Error, StdDev values are not that different but the run time is. That is confusing to me.
https://user-images.githubusercontent.com/43763136/54951795-e0286b00-4f1a-11e9-9df3-7f3f79ff3f3e.PNG
Also, I ran both the tests parallely. Scott told me he ran it only once, so he will be doing it again today.

@mjkkirschner
Copy link
Member

mjkkirschner commented Mar 25, 2019

if you ran the tests in parallel it makes sense they will have longer run time - it also appears that it ran them both different numbers of times in each comparison - I would look only at the benchmark times relative to each other (before and after), not the total runtime.

@mjkkirschner mjkkirschner added the LGTM Looks good to me label Mar 25, 2019
@reddyashish reddyashish merged commit 62e1b56 into DynamoDS:master Mar 25, 2019
reddyashish added a commit to reddyashish/Dynamo that referenced this pull request Mar 26, 2019
* DYN-1722

* Variable change name

* Update the callsite.cs

* Modifying the equals function.

* adding comments

* Test comments

* Changing variable name

* Adding zipAlgorithm check and comments.

* More Comments.

(cherry picked from commit 62e1b56)
@reddyashish reddyashish mentioned this pull request Mar 26, 2019
7 tasks
reddyashish added a commit that referenced this pull request Mar 26, 2019
* DYN-1722

* Variable change name

* Update the callsite.cs

* Modifying the equals function.

* adding comments

* Test comments

* Changing variable name

* Adding zipAlgorithm check and comments.

* More Comments.

(cherry picked from commit 62e1b56)
reddyashish added a commit that referenced this pull request May 21, 2019
reddyashish added a commit to reddyashish/Dynamo that referenced this pull request May 21, 2019
QilongTang pushed a commit that referenced this pull request May 28, 2019
* Cherry-picking #9388 into 2.0.3

* Cherry-picking #9559 into 2.0.3

* Cherry-picking #9578 into 2.0.3

* cherry-picking #9632 into 2.0.3

* cherry-picking #9408 into 2.0.3

* cherry-picking #9441 into 2.0.3

* Adding gradient.png for the Test_PerforationsByImage test.

This was missed while cherrypicking #9441

* Removing DSCoreDataTests.cs as this was the test fixture was introduced in a different commit and is not needed here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LGTM Looks good to me
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants