Skip to content

Commit b09d09e

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: I7e8e8b7f21453bb8d88fa2b9c2ef66c532f3ea46
1 parent b2517d6 commit b09d09e

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
@@ -804,6 +805,10 @@ if(EXECUTORCH_BUILD_EXECUTOR_RUNNER)
804805
list(APPEND _executor_runner_libs quantized_ops_lib)
805806
endif()
806807

808+
if(EXECUTORCH_ENABLE_EVENT_TRACER)
809+
list(APPEND _executor_runner_libs etdump ${FLATCCRT_LIB})
810+
endif()
811+
807812
add_executable(executor_runner ${_executor_runner__srcs})
808813
if(CMAKE_BUILD_TYPE STREQUAL "Release")
809814
if(APPLE)

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
@@ -122,8 +123,13 @@ if(NOT CMAKE_TOOLCHAIN_FILE MATCHES ".*(iOS|ios\.toolchain)\.cmake$")
122123
#
123124
list(TRANSFORM _xnn_executor_runner__srcs PREPEND "${EXECUTORCH_ROOT}/")
124125
add_executable(xnn_executor_runner ${_xnn_executor_runner__srcs})
126+
127+
if(EXECUTORCH_ENABLE_EVENT_TRACER)
128+
list(APPEND xnn_executor_runner_libs etdump)
129+
endif()
130+
125131
target_link_libraries(
126-
xnn_executor_runner xnnpack_backend gflags portable_ops_lib
132+
xnn_executor_runner gflags portable_ops_lib ${xnn_executor_runner_libs}
127133
)
128134
target_compile_options(xnn_executor_runner PUBLIC ${_common_compile_options})
129135
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 Developer Tools integration, you can also now use the Developer Tools to profile the model. You can follow the steps in [Using the ExecuTorch Developer Tools to Profile a Model](./tutorials/devtools-integration-tutorial) on how to profile ExecuTorch models and use Developer Tools' Inspector API to view XNNPACK's internal profiling information.
77+
We have enabled basic profiling for the XNNPACK delegate that can be enabled with the compiler flag `-DEXECUTORCH_ENABLE_EVENT_TRACER` (add `-DENABLE_XNNPACK_PROFILING` for additional details). With ExecuTorch's Developer Tools integration, you can also now use the Developer Tools to profile the model. You can follow the steps in [Using the ExecuTorch Developer Tools to Profile a Model](./tutorials/devtools-integration-tutorial) on how to profile ExecuTorch models and use Developer Tools' 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
@@ -172,3 +172,6 @@ Now you should be able to find the executable built at `./cmake-out/backends/xnn
172172

173173
## Building and Linking with the XNNPACK Backend
174174
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.
175+
176+
## Profiling
177+
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 (add `-DENABLE_XNNPACK_PROFILING=ON` for additional details). 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
@@ -25,21 +26,33 @@
2526
#include <executorch/extension/data_loader/file_data_loader.h>
2627
#include <executorch/extension/evalue_util/print_evalue.h>
2728
#include <executorch/extension/runner_util/inputs.h>
29+
#include <executorch/runtime/core/event_tracer.h>
2830
#include <executorch/runtime/executor/method.h>
2931
#include <executorch/runtime/executor/program.h>
3032
#include <executorch/runtime/platform/log.h>
3133
#include <executorch/runtime/platform/runtime.h>
34+
#ifdef ET_EVENT_TRACER_ENABLED
35+
#include <executorch/devtools/etdump/etdump_flatcc.h>
36+
#endif // ET_EVENT_TRACER_ENABLED
3237

3338
static uint8_t method_allocator_pool[4 * 1024U * 1024U]; // 4 MB
3439

3540
DEFINE_string(
3641
model_path,
3742
"model.pte",
3843
"Model serialized in flatbuffer format.");
44+
DEFINE_uint32(num_executions, 1, "Number of times to run the model.");
45+
#ifdef ET_EVENT_TRACER_ENABLED
46+
DEFINE_string(
47+
etdump_path,
48+
"model.etdump",
49+
"If ETDump generation is enabled an ETDump will be written out to this path.");
50+
#endif // ET_EVENT_TRACER_ENABLED
3951

4052
using executorch::extension::FileDataLoader;
4153
using executorch::runtime::Error;
4254
using executorch::runtime::EValue;
55+
using executorch::runtime::EventTracer;
4356
using executorch::runtime::HierarchicalAllocator;
4457
using executorch::runtime::MemoryAllocator;
4558
using executorch::runtime::MemoryManager;
@@ -151,8 +164,20 @@ int main(int argc, char** argv) {
151164
// the method can mutate the memory-planned buffers, so the method should only
152165
// be used by a single thread at at time, but it can be reused.
153166
//
154-
155-
Result<Method> method = program->load_method(method_name, &memory_manager);
167+
EventTracer* event_tracer_ptr = nullptr;
168+
#ifdef ET_EVENT_TRACER_ENABLED
169+
std::unique_ptr<FILE, decltype(&fclose)> etdump_file(
170+
fopen(FLAGS_etdump_path.c_str(), "w+"), fclose);
171+
ET_CHECK_MSG(
172+
etdump_file,
173+
"Failed to open ETDump file at %s.",
174+
FLAGS_etdump_path.c_str());
175+
176+
torch::executor::ETDumpGen etdump_gen = torch::executor::ETDumpGen();
177+
event_tracer_ptr = &etdump_gen;
178+
#endif // ET_EVENT_TRACER_ENABLED
179+
Result<Method> method =
180+
program->load_method(method_name, &memory_manager, event_tracer_ptr);
156181
ET_CHECK_MSG(
157182
method.ok(),
158183
"Loading of method %s failed with status 0x%" PRIx32,
@@ -171,24 +196,39 @@ int main(int argc, char** argv) {
171196
ET_LOG(Info, "Inputs prepared.");
172197

173198
// Run the model.
174-
Error status = method->execute();
175-
ET_CHECK_MSG(
176-
status == Error::Ok,
177-
"Execution of method %s failed with status 0x%" PRIx32,
178-
method_name,
179-
(uint32_t)status);
180-
ET_LOG(Info, "Model executed successfully.");
199+
for (uint32_t i = 0; i < FLAGS_num_executions; i++) {
200+
Error status = method->execute();
201+
ET_CHECK_MSG(
202+
status == Error::Ok,
203+
"Execution of method %s failed with status 0x%" PRIx32,
204+
method_name,
205+
(uint32_t)status);
206+
}
207+
ET_LOG(Info, "Model executed successfully %i time(s).", FLAGS_num_executions);
181208

182209
// Print the outputs.
183210
std::vector<EValue> outputs(method->outputs_size());
184211
ET_LOG(Info, "%zu outputs: ", outputs.size());
185-
status = method->get_outputs(outputs.data(), outputs.size());
212+
Error status = method->get_outputs(outputs.data(), outputs.size());
186213
ET_CHECK(status == Error::Ok);
187214
// Print the first and last 100 elements of long lists of scalars.
188215
std::cout << executorch::extension::evalue_edge_items(100);
189216
for (int i = 0; i < outputs.size(); ++i) {
190217
std::cout << "Output " << i << ": " << outputs[i] << std::endl;
191218
}
192219

220+
#ifdef ET_EVENT_TRACER_ENABLED
221+
// Dump the ETDump data containing profiling/debugging data to the specified
222+
// file.
223+
torch::executor::etdump_result result = etdump_gen.get_etdump_data();
224+
if (result.buf != nullptr && result.size > 0) {
225+
fwrite((uint8_t*)result.buf, 1, result.size, etdump_file.get());
226+
free(result.buf);
227+
ET_LOG(Info, "ETDump written to file '%s'.", FLAGS_etdump_path.c_str());
228+
} else {
229+
ET_LOG(Error, "No ETDump data available!");
230+
}
231+
#endif // ET_EVENT_TRACER_ENABLED
232+
193233
return 0;
194234
}

0 commit comments

Comments
 (0)