-
Notifications
You must be signed in to change notification settings - Fork 680
[Backend Tester] Report delegation statistics #12846
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
Changes from 88 commits
f120e70
0fb85e6
4d8d844
dc12b40
ead0616
0f13676
b0b01f2
8b9c9ef
06bf03a
2f8f49b
8ca7766
bffb95f
d21492b
e2c4ea5
8230848
2a1f564
b35e7b1
5c4c6ce
9397803
9dfeb5a
ff5c4a5
42a5de5
402d8f5
34d3ab3
1105e04
482bd21
ea548b7
4108f54
7ef236b
4a58c9d
3b866b4
5ba25cb
19760fc
81dfb07
4d50265
5f66043
24e919d
523cc20
74c95fe
5d437b1
89757ce
423f79a
69f7f9c
c0f6224
e2ea2a3
7a2fab5
033c231
a9ed762
64b174a
3976629
27cd171
7bdd3e5
b1254cd
f2e2289
cdd15c1
e2df06e
4461bd8
7e97fd0
bcb697c
11a5a02
244b146
de21ac2
fd26fc7
4ae840d
710ea49
32f54b0
a27d18c
2eb59fc
5cc4941
ef7af5c
18e89c1
4719c90
dd09555
f1db3a0
e0700b2
f260b50
d62ee60
f261355
c3a24f9
1697cbc
b94b45e
5740f0a
bd79ef2
7e1a002
a628d29
3615d89
1d34f49
933fba2
1897d4e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
import argparse | ||
import importlib | ||
import re | ||
import time | ||
import unittest | ||
|
||
from datetime import timedelta | ||
from typing import Any | ||
|
||
import torch | ||
|
@@ -14,11 +16,13 @@ | |
from executorch.backends.test.suite.reporting import ( | ||
begin_test_session, | ||
complete_test_session, | ||
count_ops, | ||
generate_csv_report, | ||
RunSummary, | ||
TestCaseSummary, | ||
TestResult, | ||
) | ||
from executorch.exir import EdgeProgramManager | ||
|
||
|
||
# A list of all runnable test suites and the corresponding python package. | ||
|
@@ -44,6 +48,7 @@ def run_test( # noqa: C901 | |
""" | ||
|
||
error_statistics: list[ErrorStatistics] = [] | ||
extra_stats = {} | ||
|
||
# Helper method to construct the summary. | ||
def build_result( | ||
|
@@ -58,6 +63,7 @@ def build_result( | |
result=result, | ||
error=error, | ||
tensor_error_statistics=error_statistics, | ||
**extra_stats, | ||
) | ||
|
||
# Ensure the model can run in eager mode. | ||
|
@@ -72,11 +78,16 @@ def build_result( | |
return build_result(TestResult.UNKNOWN_FAIL, e) | ||
|
||
if flow.quantize: | ||
start_time = time.perf_counter() | ||
try: | ||
tester.quantize( | ||
flow.quantize_stage_factory() if flow.quantize_stage_factory else None | ||
) | ||
elapsed = time.perf_counter() - start_time | ||
extra_stats["quantize_time"] = timedelta(seconds=elapsed) | ||
except Exception as e: | ||
elapsed = time.perf_counter() - start_time | ||
extra_stats["quantize_time"] = timedelta(seconds=elapsed) | ||
return build_result(TestResult.QUANTIZE_FAIL, e) | ||
|
||
try: | ||
|
@@ -87,11 +98,27 @@ def build_result( | |
except Exception as e: | ||
return build_result(TestResult.EXPORT_FAIL, e) | ||
|
||
lower_start_time = time.perf_counter() | ||
try: | ||
tester.to_edge_transform_and_lower() | ||
tester.to_edge_transform_and_lower(generate_etrecord=True) | ||
elapsed = time.perf_counter() - lower_start_time | ||
extra_stats["lower_time"] = timedelta(seconds=elapsed) | ||
except Exception as e: | ||
elapsed = time.perf_counter() - lower_start_time | ||
extra_stats["lower_time"] = timedelta(seconds=elapsed) | ||
return build_result(TestResult.LOWER_FAIL, e) | ||
|
||
# Compute delegation statistics. Use the ETRecord to access the edge dialect graph between | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious why do we need to go through ETRecord? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is because we need the graph in between to_edge and to_backend when using to_edge_transform_and_lower in order to see the edge-dialect graph before partitioning. In theory, we have the info with the exported program, but it's aten dialect and pre-decompositions, so it's hard to reason about what's delegated. With to_edge_transform_and_lower, we don't otherwise have a way to inspect the graph between the edge and lowering steps. ETRecord has effectively the same problem (they need the pre-delegation edge graph), so I'm using it here. |
||
# to_edge and delegation. Note that ETRecord only stores the edge dialect graph for a single | ||
# method currently and assumes it is called "forward". | ||
edge_manager: EdgeProgramManager = tester.get_artifact() | ||
edge_op_counts = count_ops({"forward": edge_manager._etrecord.edge_dialect_program}) | ||
undelegated_op_counts = count_ops(edge_manager._edge_programs) | ||
delegated_op_counts = edge_op_counts - undelegated_op_counts | ||
|
||
extra_stats["delegated_op_counts"] = delegated_op_counts | ||
extra_stats["undelegated_op_counts"] = undelegated_op_counts | ||
|
||
is_delegated = any( | ||
n.target == torch._higher_order_ops.executorch_call_delegate | ||
for n in tester.stages[tester.cur].graph_module.graph.nodes | ||
|
@@ -185,6 +212,7 @@ def parse_args(): | |
"--report", | ||
nargs="?", | ||
help="A file to write the test report to, in CSV format.", | ||
default="backend_test_report.csv", | ||
) | ||
return parser.parse_args() | ||
|
||
|
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.
we can make this pretty but OK for now