Skip to content

Commit 710edda

Browse files
authored
Arm backend: Add Arm Neural Statistics (pytorch#20662)
This PR adds opt-in VGF Arm Neural Accelerator Statistics collection for ETDump. When EXECUTORCH_VGF_ENABLE_NEURAL_STATISTICS=1 is set, the VGF backend collects VK_ARM_data_graph neural statistics metadata, wraps the opaque binary blobs in a versioned JSON payload, and attaches it to ETDump delegate metadata under the VGF_NEURAL_STATISTICS event. The implementation keeps normal timing-only profiling unchanged by default, handles unsupported Vulkan/API/bind-point paths gracefully, and adds Inspector parsing support to recover decoded debug_database, statistics_info, and statistics_memory bytes. This option EXECUTORCH_VGF_ENABLE_NEURAL_STATISTICS was added to attach this payload only when it is requested specifically, otherwise it could blow up ETDump in some runs. cc @digantdesai @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani Signed-off-by: Elena Zhelezina <elena.zhelezina@arm.com>
1 parent 4147869 commit 710edda

11 files changed

Lines changed: 1225 additions & 14 deletions

File tree

backends/arm/CMakeLists.txt

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,36 @@ if(EXECUTORCH_BUILD_VGF)
184184
set(LIBVGF_PATH "${_vgf_site_pure}")
185185
endif()
186186

187+
if(EXECUTORCH_BUILD_TESTS)
188+
add_executable(
189+
vgf_neural_statistics_test
190+
${EXECUTORCH_ROOT}/backends/arm/test/vgf_neural_statistics_test.cpp
191+
${EXECUTORCH_ROOT}/backends/arm/runtime/VGFNeuralStatistics.cpp
192+
)
193+
target_include_directories(
194+
vgf_neural_statistics_test
195+
PRIVATE ${_common_include_directories} ${VULKAN_HEADERS_PATH}
196+
${VOLK_HEADERS_PATH}
197+
)
198+
target_compile_options(
199+
vgf_neural_statistics_test PRIVATE -DUSE_VULKAN_WRAPPER
200+
-DUSE_VULKAN_VOLK
201+
)
202+
target_link_libraries(vgf_neural_statistics_test PRIVATE executorch_core)
203+
if(TARGET GTest::gtest_main)
204+
target_link_libraries(
205+
vgf_neural_statistics_test PRIVATE GTest::gtest_main
206+
)
207+
else()
208+
target_link_libraries(
209+
vgf_neural_statistics_test PRIVATE gtest gtest_main
210+
)
211+
endif()
212+
add_test(NAME vgf_neural_statistics_test
213+
COMMAND vgf_neural_statistics_test
214+
)
215+
endif()
216+
187217
set(LIBVGF_STATIC "${LIBVGF_PATH}/lib/libvgf.a")
188218
endif()
189219

@@ -194,8 +224,9 @@ if(EXECUTORCH_BUILD_VGF)
194224
target_include_directories(vgf INTERFACE "${LIBVGF_INCLUDE}")
195225

196226
# Add backend delegate for VGF
197-
set(_vgf_backend_sources backends/arm/runtime/VGFBackend.cpp
198-
backends/arm/runtime/VGFSetup.cpp
227+
set(_vgf_backend_sources
228+
backends/arm/runtime/VGFBackend.cpp backends/arm/runtime/VGFSetup.cpp
229+
backends/arm/runtime/VGFNeuralStatistics.cpp
199230
)
200231
if(NOT EXECUTORCH_BUILD_VULKAN)
201232
list(APPEND _vgf_backend_sources backends/vulkan/third-party/volk/volk.c)

backends/arm/runtime/VGFBackend.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
#include <algorithm>
89
#include <atomic>
910
#include <cerrno>
1011
#include <chrono>
@@ -118,13 +119,21 @@ void vkml_free_basics(
118119
constexpr const char* kVgfDumpInputsDirEnv = "EXECUTORCH_VGF_DUMP_INPUTS_DIR";
119120
constexpr const char* kVgfDumpInputsAndExitEnv =
120121
"EXECUTORCH_VGF_DUMP_INPUTS_AND_EXIT";
122+
constexpr const char* kVgfNeuralStatisticsEnv =
123+
"EXECUTORCH_VGF_ENABLE_NEURAL_STATISTICS";
121124

122125
std::atomic<uint64_t> g_vgf_dump_invocation{0};
123126

124127
bool env_flag_enabled(const char* name) {
125128
const char* value = std::getenv(name);
126-
return value != nullptr && value[0] != '\0' && std::strcmp(value, "0") != 0 &&
127-
std::strcmp(value, "false") != 0 && std::strcmp(value, "False") != 0;
129+
if (value == nullptr || value[0] == '\0') {
130+
return false;
131+
}
132+
133+
return std::strcmp(value, "0") != 0 && std::strcmp(value, "false") != 0 &&
134+
std::strcmp(value, "False") != 0 && std::strcmp(value, "FALSE") != 0 &&
135+
std::strcmp(value, "off") != 0 && std::strcmp(value, "Off") != 0 &&
136+
std::strcmp(value, "OFF") != 0;
128137
}
129138

130139
const char* descriptor_type_to_string(VkDescriptorType type) {
@@ -692,6 +701,28 @@ class VGFBackend final : public ::executorch::runtime::BackendInterface {
692701
#ifdef ET_EVENT_TRACER_ENABLED
693702
event_tracer_end_profiling_delegate(event_tracer, dispatch_event);
694703

704+
if (event_tracer != nullptr && env_flag_enabled(kVgfNeuralStatisticsEnv)) {
705+
// We attach the neural statistics JSON blob to ETDump as delegate
706+
// metadata, when event tracer is active.
707+
708+
// This is “synthetic” event, which we use as a carrier for metadata
709+
EventTracerEntry neural_statistics_event =
710+
event_tracer_start_profiling_delegate(
711+
event_tracer,
712+
kVgfNeuralStatisticsDelegateEventName,
713+
/*delegate_debug_id=*/-1);
714+
715+
// Ask VGF representation for neural accelerator diagnostics
716+
std::string neural_statistics_metadata =
717+
repr->collect_neural_statistics_metadata();
718+
719+
event_tracer_end_profiling_delegate(
720+
event_tracer,
721+
neural_statistics_event,
722+
neural_statistics_metadata.data(),
723+
neural_statistics_metadata.size());
724+
}
725+
695726
EventTracerEntry copy_outputs_event = event_tracer_start_profiling_delegate(
696727
event_tracer,
697728
"VGF_COPY_OUTPUTS",

0 commit comments

Comments
 (0)