-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
09142d1
commit ae4080e
Showing
7 changed files
with
164 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright 2023 Parallel Software and Systems Group, University of Maryland. | ||
# See the top-level LICENSE file for details. | ||
# | ||
# SPDX-License-Identifier: MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
# Copyright 2023 Parallel Software and Systems Group, University of Maryland. | ||
# See the top-level LICENSE file for details. | ||
# | ||
# SPDX-License-Identifier: MIT | ||
|
||
from pipit.graph import Graph, Node | ||
|
||
|
||
def create_cct(events): | ||
""" | ||
Generic function to iterate through the events dataframe and create a CCT. | ||
Uses pipit's graph data structure for this. Returns a CCT | ||
and creates a new column in the Events DataFrame that stores | ||
a reference to each row's corresponding node in the CCT. | ||
""" | ||
|
||
# CCT and list of nodes in DataFrame | ||
graph = Graph() | ||
graph_nodes = [None for i in range(len(events))] | ||
|
||
# determines whether a node exists or not | ||
callpath_to_node = dict() | ||
|
||
node_id = 0 # each node has a unique id | ||
|
||
# Filter the DataFrame to only Enter/Leave | ||
enter_leave_df = events.loc[events["Event Type"].isin(["Enter", "Leave"])] | ||
|
||
# list of processes and/or threads to iterate over | ||
if "Thread" in events.columns: | ||
exec_locations = set(zip(events["Process"], events["Thread"])) | ||
has_thread = True | ||
else: | ||
exec_locations = set(events["Process"]) | ||
has_thread = False | ||
|
||
for curr_loc in exec_locations: | ||
# only filter by thread if the trace has a thread column | ||
if has_thread: | ||
curr_process, curr_thread = curr_loc | ||
filtered_df = enter_leave_df.loc[ | ||
(enter_leave_df["Process"] == curr_process) | ||
& (enter_leave_df["Thread"] == curr_thread) | ||
] | ||
else: | ||
filtered_df = enter_leave_df.loc[(enter_leave_df["Process"] == curr_loc)] | ||
|
||
curr_depth, callpath = 0, "" | ||
|
||
""" | ||
Iterating over lists instead of | ||
DataFrame columns is more efficient | ||
""" | ||
df_indices = filtered_df.index.to_list() | ||
function_names = filtered_df["Name"].to_list() | ||
event_types = filtered_df["Event Type"].to_list() | ||
|
||
# stacks used to iterate through the trace and add nodes to the cct | ||
functions_stack, nodes_stack = [], [] | ||
|
||
# iterating over the events of the current thread's trace | ||
for i in range(len(filtered_df)): | ||
curr_df_index, evt_type, function_name = ( | ||
df_indices[i], | ||
event_types[i], | ||
function_names[i], | ||
) | ||
|
||
# encounter a new function through its entry point. | ||
if evt_type == "Enter": | ||
# add the function to the stack and get the call path | ||
functions_stack.append(function_name) | ||
callpath = "->".join(functions_stack) | ||
|
||
# get the parent node of the function if it exists | ||
parent_node = None if curr_depth == 0 else nodes_stack[-1] | ||
|
||
if callpath in callpath_to_node: | ||
# don't create new node if callpath is in map | ||
curr_node = callpath_to_node[callpath] | ||
else: | ||
# create new node if callpath isn't in map | ||
curr_node = Node(node_id, parent_node, curr_depth) | ||
callpath_to_node[callpath] = curr_node | ||
node_id += 1 | ||
|
||
# add node as root or child of its | ||
# parent depending on current depth | ||
graph.add_root( | ||
curr_node | ||
) if curr_depth == 0 else parent_node.add_child(curr_node) | ||
|
||
# Update nodes stack, column, and current depth | ||
nodes_stack.append(curr_node) | ||
graph_nodes[curr_df_index] = curr_node | ||
curr_depth += 1 | ||
else: | ||
# we want to iterate through the stack in reverse order | ||
# until we find the corresponding "Enter" Event | ||
enter_name, j = None, len(functions_stack) - 1 | ||
while enter_name != function_name and j > -1: | ||
enter_name = functions_stack[j] | ||
j -= 1 | ||
|
||
if enter_name == function_name: | ||
# update stacks and current depth | ||
del functions_stack[j + 1] | ||
del nodes_stack[j + 1] | ||
curr_depth -= 1 | ||
else: | ||
continue | ||
|
||
# Update the Trace with the generated cct | ||
events["Graph_Node"] = graph_nodes | ||
|
||
return graph |