Skip to content

Commit f95f49e

Browse files
Olivia-liufacebook-github-bot
authored andcommitted
delegation debug page (#3254)
Summary: Create a new page for the new util functions Chen and I made to debug delegations. These functions were well-received within the team as well as by partner teams including modai, thus I think it's important to call them out in our documentation. The examples were copied from the llm manual, but reworded a little bit to flow naturally in this doc. Reviewed By: cccclai Differential Revision: D56491214
1 parent b6e54d0 commit f95f49e

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

docs/source/debug-backend-delegate.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Debug Backend Delegate
2+
3+
We provide a list of util functions to give users insights on what happened to the graph modules during the `to_backend()` stage.
4+
5+
## Get delegation summary
6+
The `get_delegation_info()` method provides a summary of what happened to the model after the `to_backend()` call:
7+
8+
```python
9+
from executorch.exir.backend.utils import get_delegation_info
10+
from tabulate import tabulate
11+
12+
# ... After call to to_backend(), but before to_executorch()
13+
graph_module = edge_manager.exported_program().graph_module
14+
delegation_info = get_delegation_info(graph_module)
15+
print(delegation_info.get_summary())
16+
df = delegation_info.get_operator_delegation_dataframe()
17+
print(tabulate(df, headers="keys", tablefmt="fancy_grid"))
18+
```
19+
20+
Example printout:
21+
```
22+
Total delegated subgraphs: 86
23+
Number of delegated nodes: 473
24+
Number of non-delegated nodes: 430
25+
```
26+
27+
28+
| | op_type | occurrences_in_delegated_graphs | occurrences_in_non_delegated_graphs |
29+
|----|---------------------------------|------- |-----|
30+
| 0 | aten__softmax_default | 12 | 0 |
31+
| 1 | aten_add_tensor | 37 | 0 |
32+
| 2 | aten_addmm_default | 48 | 0 |
33+
| 3 | aten_arange_start_step | 0 | 25 |
34+
| | ... | | |
35+
| 23 | aten_view_copy_default | 170 | 48 |
36+
| | ... | | |
37+
| 26 | Total | 473 | 430 |
38+
39+
From the table, the operator `aten_view_copy_default` appears 170 times in delegate graphs and 48 times in non-delegated graphs. Users can use information like this to debug.
40+
41+
## Visualize delegated graph
42+
To see a more detailed view, use the `print_delegated_graph()` method to display a printout of the whole graph:
43+
44+
```python
45+
from executorch.exir.backend.utils import print_delegated_graph
46+
graph_module = edge_manager.exported_program().graph_module
47+
print(print_delegated_graph(graph_module))
48+
```
49+
It will print the whole model as well as the subgraph consumed by the backend. The generic debug function provided by fx like `print_tabular()` or `print_readable()` will only show `call_delegate` but hide the the subgraph consumes by the backend, while this function exposes the contents inside the subgraph.
50+
51+
In the example printout below, observe that `embedding` and `add` operators are delegated to `XNNPACK` while the `sub` operator is not.
52+
53+
```
54+
%aten_unsqueeze_copy_default_22 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.unsqueeze_copy.default](args = (%aten_arange_start_step_23, -2), kwargs = {})
55+
%aten_unsqueeze_copy_default_23 : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.unsqueeze_copy.default](args = (%aten_arange_start_step_24, -1), kwargs = {})
56+
%lowered_module_0 : [num_users=1] = get_attr[target=lowered_module_0]
57+
backend_id: XnnpackBackend
58+
lowered graph():
59+
%aten_embedding_default : [num_users=1] = placeholder[target=aten_embedding_default]
60+
%aten_embedding_default_1 : [num_users=1] = placeholder[target=aten_embedding_default_1]
61+
%aten_add_tensor : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.add.Tensor](args = (%aten_embedding_default, %aten_embedding_default_1), kwargs = {})
62+
return (aten_add_tensor,)
63+
%executorch_call_delegate : [num_users=1] = call_function[target=torch.ops.higher_order.executorch_call_delegate](args = (%lowered_module_0, %aten_embedding_default, %aten_embedding_default_1), kwargs = {})
64+
%aten_sub_tensor : [num_users=1] = call_function[target=executorch.exir.dialects.edge._ops.aten.sub.Tensor](args = (%aten_unsqueeze_copy_default, %aten_unsqueeze_copy_default_1), kwargs = {})
65+
```

docs/source/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ Topics in this section will help you get started with ExecuTorch.
187187
native-delegates-executorch-vulkan-delegate
188188
backend-delegates-integration
189189
backend-delegates-dependencies
190+
debug-backend-delegate
190191

191192
.. toctree::
192193
:glob:

0 commit comments

Comments
 (0)