Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions onnxruntime/python/tools/transformers/onnx_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,65 @@ def is_safe_to_fuse_nodes(self, nodes_to_remove, keep_outputs, input_name_to_nod
return False
return True

def graph_topological_sort(self, graph):
Comment thread
gh-yewang marked this conversation as resolved.
Outdated
deps_count = [0]*len(graph.node) # dependency count of each node
deps_to_nodes = {} # input to node indice
sorted_nodes = [] # initialize sorted_nodes
for node_idx, node in enumerate(graph.node):
# CANNOT use len(node.input) directly because input can be optional
deps_count[node_idx] = sum(1 for _ in node.input if _ )
if deps_count[node_idx] == 0: # Constant doesn't depend on any inputs
sorted_nodes.append(graph.node[node_idx])
continue

for input_name in node.input:
if input_name not in deps_to_nodes:
deps_to_nodes[input_name] = [node_idx]
else:
deps_to_nodes[input_name].append(node_idx)

initializer_names = [init.name for init in graph.initializer]
Comment thread
gh-yewang marked this conversation as resolved.
graph_input_names = [input.name for input in graph.input]
input_names = initializer_names + graph_input_names
input_names.sort()
prev_input_name = None
for input_name in input_names:
if prev_input_name == input_name:
continue

prev_input_name = input_name
if input_name in deps_to_nodes:
for node_idx in deps_to_nodes[input_name]:
deps_count[node_idx] = deps_count[node_idx] - 1
if deps_count[node_idx] == 0:
sorted_nodes.append(graph.node[node_idx])

start = 0
end = len(sorted_nodes)

while start < end:
for output in sorted_nodes[start].output:
if output in deps_to_nodes:
for node_idx in deps_to_nodes[output]:
deps_count[node_idx] = deps_count[node_idx] - 1
if deps_count[node_idx] == 0:
sorted_nodes.append(graph.node[node_idx])
end = end + 1
start = start + 1

# TODO: This assertion does not apply to the subgraphs, need other type of check
#assert(end == len(graph.node)), "Graph is not a DAG"
Comment thread
gh-yewang marked this conversation as resolved.
Outdated
graph.ClearField('node')
graph.node.extend(sorted_nodes)

def topological_sort(self):
for graph in self.graphs():
self.graph_topological_sort(graph)

def save_model_to_file(self, output_path, use_external_data_format=False):
logger.info(f"Sort graphs in topological order")
self.topological_sort()

logger.info(f"Output model to {output_path}")

Path(output_path).parent.mkdir(parents=True, exist_ok=True)
Expand Down