-
Notifications
You must be signed in to change notification settings - Fork 327
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
Conversation
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.
93d5edf
to
dc19fb7
Compare
VK_CMD_DRAW_INDEXED = "vkCmdDrawIndexed" | ||
VK_CMD_DRAW = "vkCmdDraw" | ||
COMMAND_BUFFER = "commandBuffer" | ||
MAXIMUM_LEVEL_IN_HIERARCHY = 10 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
gapis/resolve/dependencygraph2/graph_visualization/graph_structure.go
Outdated
Show resolved
Hide resolved
return newGraph | ||
} | ||
|
||
func (g *Graph) addNodeByDefault() int { |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
gapis/resolve/dependencygraph2/graph_visualization/graph_structure.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_structure.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
VK_CMD_DRAW_INDEXED = "vkCmdDrawIndexed" | ||
VK_CMD_DRAW = "vkCmdDraw" | ||
COMMAND_BUFFER = "commandBuffer" | ||
MAXIMUM_LEVEL_IN_HIERARCHY = 10 |
There was a problem hiding this comment.
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
.
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
return true | ||
} | ||
|
||
func (g *Graph) removeNodePreservingEdges(idNode int) bool { |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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.
I have pushed a new commit considering the recommendations and feedback |
return output | ||
} | ||
|
||
func (g *graph) getGraphInPbtxtFormat() string { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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!
gapis/api/graph_visualization.go
Outdated
) | ||
|
||
type Hierarchy struct { | ||
LevelId [MAXIMUM_LEVEL_IN_HIERARCHY]int |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_structure_test.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_structure_test.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_structure_test.go
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
gapis/resolve/dependencygraph2/graph_visualization/graph_visualization.go
Outdated
Show resolved
Hide resolved
ee27b60
to
3b6969f
Compare
3b6969f
to
1b486c3
Compare
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.
1b486c3
to
a100a72
Compare
There was a problem hiding this 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()) + "/" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
No description provided.