Prerequisite | ETRecord - ExecuTorch Record#
Overview#
ETRecord
is intended to be the debug artifact that is generated by
users ahead of time (when they export their model to run on ExecuTorch).
To draw a rough equivalent to conventional software development,
ETRecord
can be considered as the binary built with debug symbols
that is used for debugging in GNU Debugger (gdb). It is expected that
the user will supply this to the ExecuTorch Developer Tools in order for
them to debug and visualize their model.
ETRecord
contains numerous components such as:
Edge dialect graph with debug handles
Delegate debug handle maps
The ETRecord
object itself is intended to be opaque to users and they should not access any components inside it directly.
It should be provided to the Inspector API to link back performance and debug data sourced from the runtime back to the Python source code.
Generating an ETRecord
#
There are multiple ways to generate an ETRecord
for debugging purposes:
Method 1: Using the generate_etrecord
Parameter (Recommended)#
The recommended approach is to enable ETRecord
generation by passing generate_etrecord=True
to your export API calls. This can be used with:
executorch.export()
- High-level export APIto_edge()
- Edge dialect conversionto_edge_transform_and_lower()
- Edge conversion with transformations and lowering
After export completes, retrieve the ETRecord
using the get_etrecord()
method, and save it using the save()
method:
Example with executorch.export()
:
import executorch
from executorch.export import ExportRecipe
# Export with ETRecord generation enabled
session = executorch.export(
model=model,
example_inputs=[example_inputs],
export_recipe=recipe,
generate_etrecord=True # Enable ETRecord generation
)
# Get and save the ETRecord
etrecord = session.get_etrecord()
etrecord.save("model_debug.etrecord")
Example with to_edge()
:
from executorch.exir.program import to_edge
from torch.export import export
# Export model first
exported_program = export(model, example_inputs)
# Convert to edge with ETRecord generation
edge_manager = to_edge(
exported_program,
generate_etrecord=True # Enable ETRecord generation
)
# Apply transformations
edge_manager = edge_manager.to_backend()
et_manager = edge_manager.to_executorch()
# Get and save ETRecord
etrecord = et_manager.get_etrecord()
etrecord.save("edge_debug.etrecord")
Example with to_edge_transform_and_lower()
:
from executorch.exir.program import to_edge_transform_and_lower
from torch.export import export
# Export model first
exported_program = export(model, example_inputs)
# Transform and lower with ETRecord generation
edge_manager = to_edge_transform_and_lower(
exported_program,
partitioner=[MyPartitioner()],
generate_etrecord=True # Enable ETRecord generation
)
et_manager = edge_manager.to_executorch()
# Get and save ETRecord
etrecord = et_manager.get_etrecord()
etrecord.save("debug.etrecord")
Method 2: Using the generate_etrecord()
Function#
You can also use the standalone generate_etrecord()
function to generate an ETRecord
.
This method requires you to provide the Edge Dialect program (returned by to_edge()
),
the ExecuTorch program (returned by to_executorch()
), and optional models.
Warning
When using the standalone function, users should do a deepcopy of the output of to_edge()
and pass in the deepcopy to the generate_etrecord
API. This is needed because the subsequent call, to_executorch()
, does an in-place mutation and will lose debug data in the process.
Example:
import copy
from executorch.devtools import generate_etrecord
from torch.export import export
# Export and convert to edge
aten_dialect = export(model, example_inputs, strict=True)
edge_program = to_edge(aten_dialect)
# Create copy for ETRecord (needed because to_executorch modifies in-place)
edge_program_copy = copy.deepcopy(edge_program)
# Convert to ExecutorchProgramManager
executorch_program = edge_program_copy.to_executorch()
# Generate ETRecord separately
generate_etrecord(
"debug.etrecord",
edge_program,
executorch_program,
)
- executorch.devtools.etrecord._etrecord.generate_etrecord(et_record, edge_dialect_program, executorch_program, exported_program=None, extra_recorded_export_modules=None)[source]#
Generates an ETRecord from the given objects, serializes it and saves it to the given path. The objects that will be serialized to an ETRecord are all the graph modules present in the extra_recorded_export_modules dict, the graph module present in the edge dialect program object, and also the graph module present in the ExecuTorch program object, which is the closest graph module representation of what is eventually run on the device. In addition to all the graph modules, we also serialize the program buffer, which the users can provide to the ExecuTorch runtime to run the model, and the debug handle map for Developer Tools usage.
- Parameters:
et_record – Path to where the ETRecord file will be saved to.
edge_dialect_program – EdgeProgramManager for this model returned by the call to to_edge()
executorch_program – The ExecuTorch program for this model returned by the call to to_executorch() or the BundledProgram of this model
exported_program – Optional graph module for this model returned by the call to torch.export from nn.Module.
[Optional] (extra_recorded_export_modules) – Should be ignored by OSS users. A dictionary of graph modules with the key being the user provided name and the value being the corresponding exported module. The exported graph modules can be either the output of torch.export() or exir.to_edge().
- Returns:
None
Using an ETRecord
#
Pass the ETRecord
as an optional argument into the Inspector API to access this data and do post-run analysis.