Skip to content

Commit 1df6f97

Browse files
committed
Add event tracing and ETDumps to executor_runner
- Enabled via EXECUTORCH_ENABLE_EVENT_TRACER - Add flag 'etdump_path' to specify the file path for the ETDump file - Add flag 'num_executions' for number of iterations to run - Create and pass event tracer 'ETDumpGen' - Save ETDump to disk - Update docs to reflect the changes Signed-off-by: Benjamin Klimczak <[email protected]> Change-Id: I876d5138455d1b04fba9af4016d8341e8866f9c0
1 parent 6c69ebd commit 1df6f97

File tree

5 files changed

+66
-12
lines changed

5 files changed

+66
-12
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# Copyright 2024 Arm Limited and/or its affiliates.
23
# All rights reserved.
34
#
45
# This source code is licensed under the BSD-style license found in the
@@ -581,6 +582,10 @@ if(EXECUTORCH_BUILD_EXECUTOR_RUNNER)
581582
list(APPEND _executor_runner_libs portable_ops_lib)
582583
endif()
583584

585+
if(EXECUTORCH_ENABLE_EVENT_TRACER)
586+
list(APPEND _executor_runner_libs etdump flatccrt)
587+
endif()
588+
584589
# Generate lib to register quantized ops
585590
if(EXECUTORCH_BUILD_KERNELS_QUANTIZED)
586591
list(APPEND _executor_runner_libs quantized_ops_lib)

backends/xnnpack/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# Copyright 2024 Arm Limited and/or its affiliates.
23
# All rights reserved.
34
#
45
# This source code is licensed under the BSD-style license found in the
@@ -113,8 +114,13 @@ if(NOT CMAKE_TOOLCHAIN_FILE MATCHES ".*(iOS|ios\.toolchain)\.cmake$")
113114
#
114115
list(TRANSFORM _xnn_executor_runner__srcs PREPEND "${EXECUTORCH_ROOT}/")
115116
add_executable(xnn_executor_runner ${_xnn_executor_runner__srcs})
117+
118+
if(EXECUTORCH_ENABLE_EVENT_TRACER)
119+
list(APPEND xnn_executor_runner_libs etdump)
120+
endif()
121+
116122
target_link_libraries(
117-
xnn_executor_runner xnnpack_backend gflags portable_ops_lib
123+
xnn_executor_runner gflags portable_ops_lib ${xnn_executor_runner_libs}
118124
)
119125
target_compile_options(xnn_executor_runner PUBLIC ${_common_compile_options})
120126
endif()

docs/source/native-delegates-executorch-xnnpack-delegate.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Since weight packing creates an extra copy of the weights inside XNNPACK, We fre
7474
When executing the XNNPACK subgraphs, we prepare the tensor inputs and outputs and feed them to the XNNPACK runtime graph. After executing the runtime graph, the output pointers are filled with the computed tensors.
7575

7676
#### **Profiling**
77-
We have enabled basic profiling for XNNPACK delegate that can be enabled with the following compiler flag `-DENABLE_XNNPACK_PROFILING`. With ExecuTorch's SDK integration, you can also now use the SDK tools to profile the model. You can follow the steps in [Using the ExecuTorch SDK to Profile a Model](./tutorials/sdk-integration-tutorial) on how to profile ExecuTorch models and use SDK's Inspector API to view XNNPACK's internal profiling information.
77+
We have enabled basic profiling for XNNPACK delegate that can be enabled with the following compiler flag `-DEXECUTORCH_ENABLE_EVENT_TRACER`. With ExecuTorch's SDK integration, you can also now use the SDK tools to profile the model. You can follow the steps in [Using the ExecuTorch SDK to Profile a Model](./tutorials/sdk-integration-tutorial) on how to profile ExecuTorch models and use SDK's Inspector API to view XNNPACK's internal profiling information. An example implementation is available in the `xnn_executor_runner` (see [tutorial here](tutorial-xnnpack-delegate-lowering.md#profiling)).
7878

7979

8080
[comment]: <> (TODO: Refactor quantizer to a more official quantization doc)

docs/source/tutorial-xnnpack-delegate-lowering.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,6 @@ Now you should be able to find the executable built at `./cmake-out/backends/xnn
171171

172172
## Building and Linking with the XNNPACK Backend
173173
You can build the XNNPACK backend [CMake target](https://github.com/pytorch/executorch/blob/main/backends/xnnpack/CMakeLists.txt#L83), and link it with your application binary such as an Android or iOS application. For more information on this you may take a look at this [resource](demo-apps-android.md) next.
174+
175+
## Profiling
176+
To enable profiling in the `xnn_executor_runner` pass the flags `-DEXECUTORCH_ENABLE_EVENT_TRACER=ON` and `-DEXECUTORCH_BUILD_SDK=ON` to the build command. This will enable ETDump generation when running the inference and enables command line flags for profiling (see `xnn_executor_runner --help` for details).

examples/portable/executor_runner/executor_runner.cpp

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* Copyright 2024 Arm Limited and/or its affiliates.
34
* All rights reserved.
45
*
56
* This source code is licensed under the BSD-style license found in the
@@ -29,13 +30,23 @@
2930
#include <executorch/runtime/executor/program.h>
3031
#include <executorch/runtime/platform/log.h>
3132
#include <executorch/runtime/platform/runtime.h>
33+
#ifdef ET_EVENT_TRACER_ENABLED
34+
#include <executorch/sdk/etdump/etdump_flatcc.h>
35+
#endif // ET_EVENT_TRACER_ENABLED
3236

3337
static uint8_t method_allocator_pool[4 * 1024U * 1024U]; // 4 MB
3438

3539
DEFINE_string(
3640
model_path,
3741
"model.pte",
3842
"Model serialized in flatbuffer format.");
43+
#ifdef ET_EVENT_TRACER_ENABLED
44+
DEFINE_string(
45+
etdump_path,
46+
"model.etdump",
47+
"If ETDump generation is enabled an ETDump will be written out to this path.");
48+
DEFINE_uint32(num_executions, 10, "Number of times to run the model.");
49+
#endif // ET_EVENT_TRACER_ENABLED
3950

4051
using namespace torch::executor;
4152
using torch::executor::util::FileDataLoader;
@@ -142,8 +153,22 @@ int main(int argc, char** argv) {
142153
// the method can mutate the memory-planned buffers, so the method should only
143154
// be used by a single thread at at time, but it can be reused.
144155
//
145-
146-
Result<Method> method = program->load_method(method_name, &memory_manager);
156+
uint32_t num_executions = 1;
157+
EventTracer* event_tracer_ptr = nullptr;
158+
#ifdef ET_EVENT_TRACER_ENABLED
159+
std::unique_ptr<FILE, decltype(&fclose)> etdump_file(
160+
fopen(FLAGS_etdump_path.c_str(), "w+"), fclose);
161+
ET_CHECK_MSG(
162+
etdump_file,
163+
"Failed to open ETDump file at %s.",
164+
FLAGS_etdump_path.c_str());
165+
166+
num_executions = FLAGS_num_executions;
167+
torch::executor::ETDumpGen etdump_gen = torch::executor::ETDumpGen();
168+
event_tracer_ptr = &etdump_gen;
169+
#endif // ET_EVENT_TRACER_ENABLED
170+
Result<Method> method =
171+
program->load_method(method_name, &memory_manager, event_tracer_ptr);
147172
ET_CHECK_MSG(
148173
method.ok(),
149174
"Loading of method %s failed with status 0x%" PRIx32,
@@ -162,24 +187,39 @@ int main(int argc, char** argv) {
162187
ET_LOG(Info, "Inputs prepared.");
163188

164189
// Run the model.
165-
Error status = method->execute();
166-
ET_CHECK_MSG(
167-
status == Error::Ok,
168-
"Execution of method %s failed with status 0x%" PRIx32,
169-
method_name,
170-
(uint32_t)status);
171-
ET_LOG(Info, "Model executed successfully.");
190+
for (uint32_t i = 0; i < num_executions; i++) {
191+
Error status = method->execute();
192+
ET_CHECK_MSG(
193+
status == Error::Ok,
194+
"Execution of method %s failed with status 0x%" PRIx32,
195+
method_name,
196+
(uint32_t)status);
197+
}
198+
ET_LOG(Info, "Model executed successfully %i time(s).", num_executions);
172199

173200
// Print the outputs.
174201
std::vector<EValue> outputs(method->outputs_size());
175202
ET_LOG(Info, "%zu outputs: ", outputs.size());
176-
status = method->get_outputs(outputs.data(), outputs.size());
203+
Error status = method->get_outputs(outputs.data(), outputs.size());
177204
ET_CHECK(status == Error::Ok);
178205
// Print the first and last 100 elements of long lists of scalars.
179206
std::cout << torch::executor::util::evalue_edge_items(100);
180207
for (int i = 0; i < outputs.size(); ++i) {
181208
std::cout << "Output " << i << ": " << outputs[i] << std::endl;
182209
}
183210

211+
#ifdef ET_EVENT_TRACER_ENABLED
212+
// Dump the ETDump data containing profiling/debugging data to the specified
213+
// file.
214+
etdump_result result = etdump_gen.get_etdump_data();
215+
if (result.buf != nullptr && result.size > 0) {
216+
fwrite((uint8_t*)result.buf, 1, result.size, etdump_file.get());
217+
free(result.buf);
218+
ET_LOG(Info, "ETDump written to file '%s'.", FLAGS_etdump_path.c_str());
219+
} else {
220+
ET_LOG(Error, "No ETDump data available!");
221+
}
222+
#endif // ET_EVENT_TRACER_ENABLED
223+
184224
return 0;
185225
}

0 commit comments

Comments
 (0)