Skip to content

introducing filter to etdumpgen #9937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions devtools/etdump/etdump_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ class ETDumpFilter : public ::executorch::runtime::EventTracerFilterBase {
*
* @return A Result<bool> indicating whether the event matches the filter
* criteria.
* - True if the event matches the filter, or filter is unset.
* - False if the event does not match or is unknown.
* - True if the event matches the filter.
* - False if the event does not match, or is unknown, or filter is
* unset.
* - An error code if an error occurs during filtering.
*/
Result<bool> filter(
Expand Down
18 changes: 18 additions & 0 deletions devtools/etdump/etdump_flatcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,19 @@ Result<bool> ETDumpGen::log_intermediate_output_delegate_helper(
InvalidArgument,
"Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");

if (filter_) {
Result<bool> result = filter_->filter(name, delegate_debug_index);
if (!result.ok()) {
return result;
}

// If the filter returns true, meaning this event should be filtered out and
// we should not log it.
if (result.get()) {
return false;
}
}

check_ready_to_add_events();
int64_t string_id = name != nullptr ? create_string_entry(name) : -1;

Expand Down Expand Up @@ -654,6 +667,11 @@ DataSinkBase* ETDumpGen::get_data_sink() {
return data_sink_;
}

void ETDumpGen::set_delegation_intermediate_output_filter(
EventTracerFilterBase* filter) {
filter_ = filter;
}

long ETDumpGen::write_tensor_or_raise_error(Tensor tensor) {
// Previously, the function copy_tensor_to_debug_buffer returned 0xFF..F when
// given an empty tensor, which is an invalid offset for most buffers. In our
Expand Down
10 changes: 10 additions & 0 deletions devtools/etdump/etdump_flatcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace executorch {
namespace etdump {

using ::executorch::runtime::DelegateDebugIntId;
using ::executorch::runtime::EventTracerFilterBase;
using ::executorch::runtime::Result;

namespace internal {
Expand Down Expand Up @@ -146,6 +147,13 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
const char* name,
DelegateDebugIntId delegate_debug_index,
const double& output) override;

/**
* Set the filter of event tracer for delegation intermediate outputs.
*/
virtual void set_delegation_intermediate_output_filter(
EventTracerFilterBase* event_tracer_filter) override;

void set_debug_buffer(::executorch::runtime::Span<uint8_t> buffer);
void set_data_sink(DataSinkBase* data_sink);
ETDumpResult get_etdump_data();
Expand Down Expand Up @@ -188,6 +196,8 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
int bundled_input_index_ = -1;
State state_ = State::Init;
struct internal::ETDumpStaticAllocator alloc_;

EventTracerFilterBase* filter_ = nullptr;
};

} // namespace etdump
Expand Down
129 changes: 128 additions & 1 deletion devtools/etdump/tests/etdump_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <executorch/devtools/etdump/data_sinks/buffer_data_sink.h>
#include <executorch/devtools/etdump/data_sinks/file_data_sink.h>
#include <executorch/devtools/etdump/etdump_filter.h>
#include <executorch/devtools/etdump/etdump_flatcc.h>
#include <executorch/devtools/etdump/etdump_schema_flatcc_builder.h>
#include <executorch/devtools/etdump/etdump_schema_flatcc_reader.h>
Expand All @@ -33,6 +34,7 @@ using ::executorch::runtime::AllocatorID;
using ::executorch::runtime::ArrayRef;
using ::executorch::runtime::BoxedEvalueList;
using ::executorch::runtime::DelegateDebugIdType;
using ::executorch::runtime::DelegateDebugIntId;
using ::executorch::runtime::Error;
using ::executorch::runtime::EValue;
using ::executorch::runtime::EventTracerEntry;
Expand All @@ -45,6 +47,8 @@ using ::executorch::runtime::testing::TensorFactory;
using ::executorch::etdump::BufferDataSink;
using ::executorch::etdump::FileDataSink;

using ::executorch::etdump::ETDumpFilter;

class ProfilerETDumpTest : public ::testing::Test {
protected:
void SetUp() override {
Expand Down Expand Up @@ -75,6 +79,70 @@ class ProfilerETDumpTest : public ::testing::Test {
"Must set data sink before writing tensor-like data");
}

void check_log_with_filter(
const char* name,
DelegateDebugIntId delegate_debug_index,
bool use_tensor_input,
bool expected_log,
bool expected_ok) {
TensorFactory<ScalarType::Float> tf;
for (size_t i = 0; i < 2; i++) {
const size_t buffer_size = 2048;

void* ptr = malloc(buffer_size);
auto buffer_data_sink = BufferDataSink::create(ptr, buffer_size);
auto filter = ETDumpFilter();
filter.add_regex("filtered.*");
filter.set_debug_handle_range(1, 10);
etdump_gen[i]->set_delegation_intermediate_output_filter(&filter);

etdump_gen[i]->create_event_block("test_block");
etdump_gen[i]->set_data_sink(&buffer_data_sink.get());

// size of empty etdump
size_t initial_size = 68;

// Perform logging

if (use_tensor_input) {
auto tensor = tf.ones({3, 2});
auto result = etdump_gen[i]->log_intermediate_output_delegate(
name, delegate_debug_index, tensor);
ASSERT_EQ(result.ok(), expected_ok);
if (expected_ok) {
ASSERT_EQ(result.get(), expected_log);
}
} else { // use tensor_list instead
std::vector<Tensor> tensors = {tf.ones({5, 4}), tf.ones({7, 6})};
Result<bool> result = etdump_gen[i]->log_intermediate_output_delegate(
name,
delegate_debug_index,
ArrayRef<Tensor>(tensors.data(), tensors.size()));
ASSERT_EQ(result.ok(), expected_ok);
if (expected_ok) {
ASSERT_EQ(result.get(), expected_log);
}
}

// Get final size of etdump
ETDumpResult final_result = etdump_gen[i]->get_etdump_data();
size_t final_size = final_result.size;
// Check if the size of etdump has changed based on logging success
if (expected_log) {
ASSERT_NE(initial_size, final_size); // Expect size change if logged
} else {
ASSERT_EQ(
initial_size, final_size); // Expect no size change if not logged
}

if (!etdump_gen[i]->is_static_etdump()) {
free(final_result.buf);
}

free(ptr);
}
}

ETDumpGen* etdump_gen[2];
uint8_t* buf = nullptr;
std::unique_ptr<TempFile> temp_file;
Expand Down Expand Up @@ -652,7 +720,7 @@ TEST_F(ProfilerETDumpTest, VerifyDelegateIntermediateLogging) {

void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
;

auto buffer_data_sink = BufferDataSink::create(ptr, 2048);
auto file_data_sink = FileDataSink::create(dump_file_path.c_str());

Expand Down Expand Up @@ -892,3 +960,62 @@ TEST_F(ProfilerETDumpTest, WriteAfterGetETDumpData) {
}
}
}

TEST_F(ProfilerETDumpTest, LogWithRegexAndUnsetDelegateDebugIdOnTensor) {
check_log_with_filter(
"filtered_event",
kUnsetDelegateDebugIntId,
/*use_tensor_input=*/true,
/*expected_log=*/false,
/*expected_ok=*/true);
}

TEST_F(ProfilerETDumpTest, LogWithRegexAndUnsetDelegateDebugIdOnTensorList) {
check_log_with_filter(
"filtered_event",
kUnsetDelegateDebugIntId,
/*use_tensor_input=*/true,
/*expected_log=*/false,
/*expected_ok=*/true);
}

TEST_F(ProfilerETDumpTest, LogWithNullptrAndInRange) {
check_log_with_filter(
nullptr,
5,
/*use_tensor_input=*/true,
/*expected_log=*/false,
/*expected_ok=*/true);
}
TEST_F(ProfilerETDumpTest, LogWithNonMatchingRegexAndOutOfRange) {
check_log_with_filter(
"unfiltered_event",
kUnsetDelegateDebugIntId,
/*use_tensor_input=*/true,
/*expected_log=*/true,
/*expected_ok=*/true);
}
TEST_F(ProfilerETDumpTest, LogWithNullptrAndOutOfRange) {
check_log_with_filter(
nullptr,
20,
/*use_tensor_input=*/true,
/*expected_log=*/true,
/*expected_ok=*/true);
}
TEST_F(ProfilerETDumpTest, LogWithRegexAndInRange) {
check_log_with_filter(
"filtered_event",
5,
/*use_tensor_input=*/true,
/*expected_log=*/false,
/*expected_ok=*/false);
}
TEST_F(ProfilerETDumpTest, LogWithNullptrAndUnsetDebugHandle) {
check_log_with_filter(
nullptr,
kUnsetDelegateDebugIntId,
/*use_tensor_input=*/true,
/*expected_log=*/false,
/*expected_ok=*/false);
}
1 change: 1 addition & 0 deletions devtools/etdump/tests/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def define_common_targets():
"//executorch/extension/testing_util:temp_file",
"//executorch/runtime/platform:platform",
"//executorch/runtime/core/exec_aten/testing_util:tensor_util",
"//executorch/devtools/etdump:etdump_filter",
],
)

Expand Down
12 changes: 6 additions & 6 deletions runtime/core/event_tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,12 @@ class EventTracer {
DelegateDebugIntId delegate_debug_index,
const double& output) = 0;

/**
* Set the filter of event tracer for delegation intermediate outputs.
*/
virtual void set_delegation_intermediate_output_filter(
EventTracerFilterBase* event_tracer_filter) = 0;

/**
* Helper function to set the chain id ands debug handle. Users have two
* options, the first is that they can directly pass in the chain id and debug
Expand Down Expand Up @@ -513,12 +519,6 @@ class EventTracer {
event_tracer_profiling_level_ = profiling_level;
}

/**
* Set the filter of event tracer for delegation intermediate outputs.
*/
void set_delegation_intermediate_output_filter(
EventTracerFilterBase* event_tracer_filter);

/**
* Return the current level of event tracer profiling.
*/
Expand Down
6 changes: 6 additions & 0 deletions runtime/core/test/event_tracer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ using executorch::runtime::EValue;
using executorch::runtime::EventTracer;
using executorch::runtime::EventTracerDebugLogLevel;
using executorch::runtime::EventTracerEntry;
using executorch::runtime::EventTracerFilterBase;
using executorch::runtime::kUnsetChainId;
using executorch::runtime::kUnsetDebugHandle;
using executorch::runtime::kUnsetDelegateDebugIntId;
Expand Down Expand Up @@ -90,6 +91,11 @@ class DummyEventTracer : public EventTracer {
(void)metadata_len;
}

void set_delegation_intermediate_output_filter(
EventTracerFilterBase* event_tracer_filter) override {
(void)event_tracer_filter;
}

void log_profiling_delegate(
const char* name,
DelegateDebugIntId delegate_debug_id,
Expand Down
Loading