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

Graph Visualization: Added the data structure for graph visualization, Dot and Pbtxt formats, super-nodes and unit testing for data structure. #2507

Merged
merged 2 commits into from
Jan 8, 2019

Conversation

ecapia
Copy link
Contributor

@ecapia ecapia commented Jan 2, 2019

No description provided.

Dot and Pbtxt formats from the graph, super-nodes (hierarchies)
based on command type and graph properties. Added unit testing for
graph data structure.

Data Structure: The data structure for the graph visualization supports
efficiently operations such as: addNode, addEdge, deleteNode,
deleteEdge, etc.

Get Dot and Pbtxt formats: The dot format allows visualize static graphs
(using Graphviz and Gephi) and the Pbtxt allows visualize dynamic graphs
using TensorBoard.

Super-nodes (hierarchies): Due limits on human and TensorBoard visualization,
creating super-nodes is necessary to improve performance. Initial super-nodes
defined on command type (CommandBuffer, CommandRenderPass and CommandSubPass) and
Strongly connected components.
@ecapia ecapia force-pushed the graph_visualization_2 branch from 93d5edf to dc19fb7 Compare January 2, 2019 19:48
VK_CMD_DRAW_INDEXED = "vkCmdDrawIndexed"
VK_CMD_DRAW = "vkCmdDraw"
COMMAND_BUFFER = "commandBuffer"
MAXIMUM_LEVEL_IN_HIERARCHY = 10
Copy link
Contributor

Choose a reason for hiding this comment

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

These shouldn't be outside of the Vulkan package.
In general we keep the knowledge of an API confined to the package where at all possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think it makes sense to abstract away this hierarchy logic into something like an interface providing getCommandLabel, which could be implemented by vulkan.API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I moved this into //gapis/api and //gapis/api/vulkan. I put the functions and structures such that the main code (//gapis/resolve/dependencygraph2/graph_visualization/..) depends only from //gapis/api considering future changes in the next commits.

return newGraph
}

func (g *Graph) addNodeByDefault() int {
Copy link
Contributor

Choose a reason for hiding this comment

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

There are a lot of addNodeBy... variants that all seem to do almost the same thing. Could you get away with just one, or maybe 2 of these?

Alternatively, you could separate this out into something like newNode(id int, label string) *Node, then set the fields you care about, and then call something like (g *Graph) addNode(*Node) bool that actually updates g.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I have reduced this into two functions getNewNode(int,string) *Node and addNode(*Node), I think is the best option considering the future modifications in the next commits as well.

VK_CMD_DRAW_INDEXED = "vkCmdDrawIndexed"
VK_CMD_DRAW = "vkCmdDraw"
COMMAND_BUFFER = "commandBuffer"
MAXIMUM_LEVEL_IN_HIERARCHY = 10
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I think it makes sense to abstract away this hierarchy logic into something like an interface providing getCommandLabel, which could be implemented by vulkan.API.

return true
}

func (g *Graph) removeNodePreservingEdges(idNode int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this bool supposed to be success/failure?
If so, in Go it is more typical to return an error (or nil).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is. I am using error now to handle that situation. In addition, I removed unnecessary returned errors from functions, keeping only the most relevant to detect bugs.

@ecapia
Copy link
Contributor Author

ecapia commented Jan 4, 2019

I have pushed a new commit considering the recommendations and feedback

return output
}

func (g *graph) getGraphInPbtxtFormat() string {
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like it is trying to write JSON:

I may suggest creating a golang object that matches the json object you are trying to write, and using the json package to output the Golang object directly.

Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't quite JSON. It's TensorFlow's particular flavor of protobuf text format (which is different than the protobuf text format that Go's protobuf package produces).

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh I apologize, also yay new formats for everyone to write!

)

type Hierarchy struct {
LevelId [MAXIMUM_LEVEL_IN_HIERARCHY]int
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this a statically sized array, rather than a slice? Is 10 significant in some way, or just big enough that you think it's unlikely to ever need more than 10 levels? I also don't see any runtime checks to make sure the current level never exceeds 10.

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 changed this in slice, also I added functions setValue and GetValue for this slice, because its length could increment dynamically.

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 added functions to manage the Hierarchy in a better and simpler way. In this commit for the trace "multithreading" is obtained unexpected results because multiple threads running , but this problem is addressed in a later commit.

gapis/api/vulkan/graph_visualization.go Show resolved Hide resolved
gapis/api/graph_visualization.go Outdated Show resolved Hide resolved
@ecapia ecapia force-pushed the graph_visualization_2 branch 2 times, most recently from ee27b60 to 3b6969f Compare January 4, 2019 21:27
@ecapia ecapia force-pushed the graph_visualization_2 branch from 3b6969f to 1b486c3 Compare January 5, 2019 02:56
Dot and Pbtxt formats from the graph, super-nodes (hierarchies)
based on command type and graph properties. Added unit testing for
graph data structure.

Data Structure: The data structure for the graph visualization supports
efficiently operations such as: addNode, addEdge, deleteNode,
deleteEdge, etc.

Get Dot and Pbtxt formats: The dot format allows visualize static graphs
(using Graphviz and Gephi) and the Pbtxt allows visualize dynamic graphs
using TensorBoard.

Super-nodes (hierarchies): Due limits on human and TensorBoard visualization,
creating super-nodes is necessary to improve performance. Initial super-nodes
defined on command type (CommandBuffer, CommandRenderPass and CommandSubPass) and
Strongly connected components.
Copy link
Contributor

@bjoeris bjoeris left a comment

Choose a reason for hiding this comment

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

lgtm

parameters := command.CmdParams()
for _, parameter := range parameters {
if parameter.Name == COMMAND_BUFFER {
commandBuffer := parameter.Name + fmt.Sprintf("%d", parameter.Get()) + "/"
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: if you're using sprintf anyway, you might as well let sprintf also handle the concatenations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I will consider that in next commits, thank you.

@bjoeris bjoeris merged commit 1236ebb into google:master Jan 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants