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-1754: As a developer I want detailed per node profiling during perf benchmarks #9667

Merged
merged 48 commits into from
May 16, 2019

Conversation

ColinDayOrg
Copy link
Contributor

Please Note:

  1. Before submitting the PR, please review How to Contribute to Dynamo
  2. Dynamo Team will meet 1x a month to review PRs found on Github (Issues will be handled separately)
  3. PRs will be reviewed from oldest to newest
  4. If a reviewed PR requires changes by the owner, the owner of the PR has 30 days to respond. If the PR has seen no activity by the next session, it will be either closed by the team or depending on its utility will be taken over by someone on the team
  5. PRs should use either Dynamo's default PR template or one of these other template options in order to be considered for review.
  6. PRs that do not have one of the Dynamo PR templates completely filled out with all declarations satisfied will not be reviewed by the Dynamo team.
  7. PRs made to the DynamoRevit repo will need to be cherry-picked into all the DynamoRevit Release branches that Dynamo supports. Contributors will be responsible for cherry-picking their reviewed commits to the other branches after a LGTM label is added to the PR.

Purpose

This PR uses the VMDataBridge to add extra AST nodes to the beginning and end of the list of AST nodes for each workspace node that store the start and end time of compile/run in a data structure for each node for profiling reasons.

Note that tests will be added, they are just being cleaned up.

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

@mjkkirschner

/// <summary>
/// AstBuilder is a factory class to create different kinds of AST nodes.
/// </summary>
public class AstBuilder : LogSourceBase
{
private readonly IAstNodeContainer nodeContainer;

internal ProfilingSession profilingSession = null;
Copy link
Member

Choose a reason for hiding this comment

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

is this internal for a specific reason? (sorry have not looked further down to see if that's the case yet)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, has been changed to be private now

@alvpickmans
Copy link
Contributor

Hi @ColinDayOrg ! Hope you don't mind me chiming in but I am very interested on this feature.

We participated on the London Dynamo Hackathon with a diagnostic toolkit for Dynamo in mind, and we based our work on the existing RechargeEast2016 branch, which I think is the same you used for this branch.

Based on our experience, I wanted to share some comments:

  • Astbuilder.cs was a flipping hell to understand from a non-dynamo developer perpective, so thanks for tidying it up and making it a bit clearer!
  • We followed the same approach as on the RechargeEast2016 branch by implementing a ViewExtension that could "tap" into the PreExecuted and PostExecuted events, registering those two extra AssociativeNodes using the VMDataBridge.
  • By having the ViewExtension we could limit the collection of metrics to only when the extension was open, but either way didn't notice any considerable performance issue.
  • We implemented a basic UI that exposed the execution time of each node as a Scatter Plot graph, plus adding the time to each NodeView (very rough as it was a very last minute thing).

I understand @mjkkirschner comments on making some of these classes private to minimize the work on the new API, but as package/viewExtension developer and even regular Dynamo user, having these metrics easily exposed is very beneficial.

I found a bit obscure and difficult to follow and implement the logic using the DataBridge and making sure when and how methods were registered. As a developer I would find it easier if it were some NodePreExecution and NodePostExecution events I could tap into to calculate the execution time and any other metric that could be retrieved on that interval (RAM increase for example).

Not sure how feasible it would be to implement these events or if it would even be a good idea from the Dynamo API perspective, but we are more than happy to help on anything we can, so maybe we can release the ViewExtension publicly (atm it still needs a bit of tidy up after the hackathon 😅)

@@ -63,6 +63,8 @@ internal bool Initialize(EngineController controller, WorkspaceModel workspace)
if (graphSyncData == null)
return false;

engineController.UpdateProfilingData(workspace.Nodes);
Copy link
Member

Choose a reason for hiding this comment

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

is there a more specific location this can be handled in - the profiling session itself or is this the cleanest?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to the profiling session, engine controller methods cleaned up and test updated to reflect the change.

@alvpickmans alvpickmans mentioned this pull request May 8, 2019
7 tasks
@@ -69,7 +70,7 @@ private void OnTraceReconciliationComplete(TraceReconciliationEventArgs e)
/// </summary>
public static CompilationServices CompilationServices;

internal ProfilingSession profilingSession;
internal ProfilingSession profilingSession = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the ProfilingSession need to be owned both by AstBuilder and EngineController?

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 have moved the ownership of the profiling data into the ASTBuilder only. Latest changes have just been pushed.

@aparajit-pratap
Copy link
Contributor

Thanks Colin, LGTM.

@mjkkirschner
Copy link
Member

@ColinDayOrg - If I wrote an extension today how would I actually collect any timing data, is the entry point on engineController meant to be internal? Is there another entry point I am missing? Or did you just want to keep it internal until we start working on the extension?

@mjkkirschner mjkkirschner added the LGTM Looks good to me label May 15, 2019
@@ -71,5 +71,28 @@ public void TestProfilingSingleNode()
engineController.EnableProfiling(false, homeWorkspace, nodes);
Assert.IsNull(engineController.ProfilingSession);
}

[Test]
public void TestProfilingSingleNodePublicMethodsOnly()
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel this test is redundant; it's testing what is already being tested in the first test case you added, is it not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is a little redundant, but it is testing the public data accessor as opposed to the other test that is using internal methods.

@ColinDayOrg ColinDayOrg changed the title [WIP] DYN-1754: As a developer I want detailed per node profiling during perf benchmarks DYN-1754: As a developer I want detailed per node profiling during perf benchmarks May 16, 2019
@ColinDayOrg ColinDayOrg merged commit b9b6637 into DynamoDS:master May 16, 2019
@ColinDayOrg ColinDayOrg deleted the DYN-1754 branch May 16, 2019 18:23
@QilongTang QilongTang mentioned this pull request May 20, 2019
11 tasks
mjkkirschner pushed a commit that referenced this pull request Aug 3, 2019
…rf benchmarks (#9667)

* Update changes from librarie.js to fix QNTM-3710

* Initial add and code cleanup for profiling data

* Add profiling changes

* Add missing summaries and accessor items

* Add an accessor for the profiling data to the profiling session

* Make profiling session private

* Improve infrastructure (switch to property,  make DateTime property nullable)

* Add test for pre-run, post-run, and node deletion post-run

* Remove unused AstCompilationEvents class

* Remove unused CompilationEventArgs class

* Rename IProfilingData to IProfilingExecutionTimeData

* Remove derivation from NotificationObject

* Restrict access to NodeProfilingData methods as much as possible

* Pull strings out to constants

* Update naming

* Obsolete Node property getter and add NodeId property getter

* Change property name from Node to NodeId and obsolete Node to avoid confusion

* Move profiling data housekeeping out of the engine controller

* Add the abillity to switch profiling on/off (off by default), including tests

* Move ownership of profiling data to the ast builder

* minor code fixes

* Fix typo

* Add public interface to get profiling data

* Add test for public data access method
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.

4 participants