Skip to content

Commit af9049b

Browse files
Gasoonjiafacebook-github-bot
authored andcommitted
introducing filter to etdumpgen
Summary: This diff introduce etdump filter to etdumpgen. Detail design can be found in Details can be found in #9260 Differential Revision: D72151631
1 parent 1f5ca0c commit af9049b

File tree

7 files changed

+172
-9
lines changed

7 files changed

+172
-9
lines changed

devtools/etdump/etdump_filter.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ class ETDumpFilter : public ::executorch::runtime::EventTracerFilterBase {
7777
*
7878
* @return A Result<bool> indicating whether the event matches the filter
7979
* criteria.
80-
* - True if the event matches the filter, or filter is unset.
81-
* - False if the event does not match or is unknown.
80+
* - True if the event matches the filter.
81+
* - False if the event does not match, or is unknown, or filter is
82+
* unset.
8283
* - An error code if an error occurs during filtering.
8384
*/
8485
Result<bool> filter(

devtools/etdump/etdump_flatcc.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,19 @@ Result<bool> ETDumpGen::log_intermediate_output_delegate_helper(
369369
InvalidArgument,
370370
"Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
371371

372+
if (filter_) {
373+
Result<bool> result = filter_->filter(name, delegate_debug_index);
374+
if (!result.ok()) {
375+
return result;
376+
}
377+
378+
// If the filter returns true, meaning this event should be filtered out and
379+
// we should not log it.
380+
if (result.get()) {
381+
return false;
382+
}
383+
}
384+
372385
check_ready_to_add_events();
373386
int64_t string_id = name != nullptr ? create_string_entry(name) : -1;
374387

@@ -654,6 +667,11 @@ DataSinkBase* ETDumpGen::get_data_sink() {
654667
return data_sink_;
655668
}
656669

670+
void ETDumpGen::set_delegation_intermediate_output_filter(
671+
EventTracerFilterBase* filter) {
672+
filter_ = filter;
673+
}
674+
657675
long ETDumpGen::write_tensor_or_raise_error(Tensor tensor) {
658676
// Previously, the function copy_tensor_to_debug_buffer returned 0xFF..F when
659677
// given an empty tensor, which is an invalid offset for most buffers. In our

devtools/etdump/etdump_flatcc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace executorch {
2525
namespace etdump {
2626

2727
using ::executorch::runtime::DelegateDebugIntId;
28+
using ::executorch::runtime::EventTracerFilterBase;
2829
using ::executorch::runtime::Result;
2930

3031
namespace internal {
@@ -146,6 +147,13 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
146147
const char* name,
147148
DelegateDebugIntId delegate_debug_index,
148149
const double& output) override;
150+
151+
/**
152+
* Set the filter of event tracer for delegation intermediate outputs.
153+
*/
154+
virtual void set_delegation_intermediate_output_filter(
155+
EventTracerFilterBase* event_tracer_filter) override;
156+
149157
void set_debug_buffer(::executorch::runtime::Span<uint8_t> buffer);
150158
void set_data_sink(DataSinkBase* data_sink);
151159
ETDumpResult get_etdump_data();
@@ -188,6 +196,8 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
188196
int bundled_input_index_ = -1;
189197
State state_ = State::Init;
190198
struct internal::ETDumpStaticAllocator alloc_;
199+
200+
EventTracerFilterBase* filter_ = nullptr;
191201
};
192202

193203
} // namespace etdump

devtools/etdump/tests/etdump_test.cpp

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <executorch/devtools/etdump/data_sinks/buffer_data_sink.h>
1414
#include <executorch/devtools/etdump/data_sinks/file_data_sink.h>
15+
#include <executorch/devtools/etdump/etdump_filter.h>
1516
#include <executorch/devtools/etdump/etdump_flatcc.h>
1617
#include <executorch/devtools/etdump/etdump_schema_flatcc_builder.h>
1718
#include <executorch/devtools/etdump/etdump_schema_flatcc_reader.h>
@@ -33,6 +34,7 @@ using ::executorch::runtime::AllocatorID;
3334
using ::executorch::runtime::ArrayRef;
3435
using ::executorch::runtime::BoxedEvalueList;
3536
using ::executorch::runtime::DelegateDebugIdType;
37+
using ::executorch::runtime::DelegateDebugIntId;
3638
using ::executorch::runtime::Error;
3739
using ::executorch::runtime::EValue;
3840
using ::executorch::runtime::EventTracerEntry;
@@ -45,6 +47,8 @@ using ::executorch::runtime::testing::TensorFactory;
4547
using ::executorch::etdump::BufferDataSink;
4648
using ::executorch::etdump::FileDataSink;
4749

50+
using ::executorch::etdump::ETDumpFilter;
51+
4852
class ProfilerETDumpTest : public ::testing::Test {
4953
protected:
5054
void SetUp() override {
@@ -75,6 +79,70 @@ class ProfilerETDumpTest : public ::testing::Test {
7579
"Must set data sink before writing tensor-like data");
7680
}
7781

82+
void check_log_with_filter(
83+
const char* name,
84+
DelegateDebugIntId delegate_debug_index,
85+
bool use_tensor_input,
86+
bool expected_log,
87+
bool expected_ok) {
88+
TensorFactory<ScalarType::Float> tf;
89+
for (size_t i = 0; i < 2; i++) {
90+
const size_t buffer_size = 2048;
91+
92+
void* ptr = malloc(buffer_size);
93+
auto buffer_data_sink = BufferDataSink::create(ptr, buffer_size);
94+
auto filter = ETDumpFilter();
95+
filter.add_regex("filtered.*");
96+
filter.set_debug_handle_range(1, 10);
97+
etdump_gen[i]->set_delegation_intermediate_output_filter(&filter);
98+
99+
etdump_gen[i]->create_event_block("test_block");
100+
etdump_gen[i]->set_data_sink(&buffer_data_sink.get());
101+
102+
// size of empty etdump
103+
size_t initial_size = 68;
104+
105+
// Perform logging
106+
107+
if (use_tensor_input) {
108+
auto tensor = tf.ones({3, 2});
109+
auto result = etdump_gen[i]->log_intermediate_output_delegate(
110+
name, delegate_debug_index, tensor);
111+
ASSERT_EQ(result.ok(), expected_ok);
112+
if (expected_ok) {
113+
ASSERT_EQ(result.get(), expected_log);
114+
}
115+
} else { // use tensor_list instead
116+
std::vector<Tensor> tensors = {tf.ones({5, 4}), tf.ones({7, 6})};
117+
Result<bool> result = etdump_gen[i]->log_intermediate_output_delegate(
118+
name,
119+
delegate_debug_index,
120+
ArrayRef<Tensor>(tensors.data(), tensors.size()));
121+
ASSERT_EQ(result.ok(), expected_ok);
122+
if (expected_ok) {
123+
ASSERT_EQ(result.get(), expected_log);
124+
}
125+
}
126+
127+
// Get final size of etdump
128+
ETDumpResult final_result = etdump_gen[i]->get_etdump_data();
129+
size_t final_size = final_result.size;
130+
// Check if the size of etdump has changed based on logging success
131+
if (expected_log) {
132+
ASSERT_NE(initial_size, final_size); // Expect size change if logged
133+
} else {
134+
ASSERT_EQ(
135+
initial_size, final_size); // Expect no size change if not logged
136+
}
137+
138+
if (!etdump_gen[i]->is_static_etdump()) {
139+
free(final_result.buf);
140+
}
141+
142+
free(ptr);
143+
}
144+
}
145+
78146
ETDumpGen* etdump_gen[2];
79147
uint8_t* buf = nullptr;
80148
std::unique_ptr<TempFile> temp_file;
@@ -652,7 +720,7 @@ TEST_F(ProfilerETDumpTest, VerifyDelegateIntermediateLogging) {
652720

653721
void* ptr = malloc(2048);
654722
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
655-
;
723+
656724
auto buffer_data_sink = BufferDataSink::create(ptr, 2048);
657725
auto file_data_sink = FileDataSink::create(dump_file_path.c_str());
658726

@@ -892,3 +960,62 @@ TEST_F(ProfilerETDumpTest, WriteAfterGetETDumpData) {
892960
}
893961
}
894962
}
963+
964+
TEST_F(ProfilerETDumpTest, LogWithRegexAndUnsetDelegateDebugIdOnTensor) {
965+
check_log_with_filter(
966+
"filtered_event",
967+
kUnsetDelegateDebugIntId,
968+
/*use_tensor_input=*/true,
969+
/*expected_log=*/false,
970+
/*expected_ok=*/true);
971+
}
972+
973+
TEST_F(ProfilerETDumpTest, LogWithRegexAndUnsetDelegateDebugIdOnTensorList) {
974+
check_log_with_filter(
975+
"filtered_event",
976+
kUnsetDelegateDebugIntId,
977+
/*use_tensor_input=*/true,
978+
/*expected_log=*/false,
979+
/*expected_ok=*/true);
980+
}
981+
982+
TEST_F(ProfilerETDumpTest, LogWithNullptrAndInRange) {
983+
check_log_with_filter(
984+
nullptr,
985+
5,
986+
/*use_tensor_input=*/true,
987+
/*expected_log=*/false,
988+
/*expected_ok=*/true);
989+
}
990+
TEST_F(ProfilerETDumpTest, LogWithNonMatchingRegexAndOutOfRange) {
991+
check_log_with_filter(
992+
"unfiltered_event",
993+
kUnsetDelegateDebugIntId,
994+
/*use_tensor_input=*/true,
995+
/*expected_log=*/true,
996+
/*expected_ok=*/true);
997+
}
998+
TEST_F(ProfilerETDumpTest, LogWithNullptrAndOutOfRange) {
999+
check_log_with_filter(
1000+
nullptr,
1001+
20,
1002+
/*use_tensor_input=*/true,
1003+
/*expected_log=*/true,
1004+
/*expected_ok=*/true);
1005+
}
1006+
TEST_F(ProfilerETDumpTest, LogWithRegexAndInRange) {
1007+
check_log_with_filter(
1008+
"filtered_event",
1009+
5,
1010+
/*use_tensor_input=*/true,
1011+
/*expected_log=*/false,
1012+
/*expected_ok=*/false);
1013+
}
1014+
TEST_F(ProfilerETDumpTest, LogWithNullptrAndUnsetDebugHandle) {
1015+
check_log_with_filter(
1016+
nullptr,
1017+
kUnsetDelegateDebugIntId,
1018+
/*use_tensor_input=*/true,
1019+
/*expected_log=*/false,
1020+
/*expected_ok=*/false);
1021+
}

devtools/etdump/tests/targets.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def define_common_targets():
1919
"//executorch/extension/testing_util:temp_file",
2020
"//executorch/runtime/platform:platform",
2121
"//executorch/runtime/core/exec_aten/testing_util:tensor_util",
22+
"//executorch/devtools/etdump:etdump_filter",
2223
],
2324
)
2425

runtime/core/event_tracer.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,12 @@ class EventTracer {
439439
DelegateDebugIntId delegate_debug_index,
440440
const double& output) = 0;
441441

442+
/**
443+
* Set the filter of event tracer for delegation intermediate outputs.
444+
*/
445+
virtual void set_delegation_intermediate_output_filter(
446+
EventTracerFilterBase* event_tracer_filter) = 0;
447+
442448
/**
443449
* Helper function to set the chain id ands debug handle. Users have two
444450
* options, the first is that they can directly pass in the chain id and debug
@@ -513,12 +519,6 @@ class EventTracer {
513519
event_tracer_profiling_level_ = profiling_level;
514520
}
515521

516-
/**
517-
* Set the filter of event tracer for delegation intermediate outputs.
518-
*/
519-
void set_delegation_intermediate_output_filter(
520-
EventTracerFilterBase* event_tracer_filter);
521-
522522
/**
523523
* Return the current level of event tracer profiling.
524524
*/

runtime/core/test/event_tracer_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ using executorch::runtime::EValue;
2828
using executorch::runtime::EventTracer;
2929
using executorch::runtime::EventTracerDebugLogLevel;
3030
using executorch::runtime::EventTracerEntry;
31+
using executorch::runtime::EventTracerFilterBase;
3132
using executorch::runtime::kUnsetChainId;
3233
using executorch::runtime::kUnsetDebugHandle;
3334
using executorch::runtime::kUnsetDelegateDebugIntId;
@@ -90,6 +91,11 @@ class DummyEventTracer : public EventTracer {
9091
(void)metadata_len;
9192
}
9293

94+
void set_delegation_intermediate_output_filter(
95+
EventTracerFilterBase* event_tracer_filter) override {
96+
(void)event_tracer_filter;
97+
}
98+
9399
void log_profiling_delegate(
94100
const char* name,
95101
DelegateDebugIntId delegate_debug_id,

0 commit comments

Comments
 (0)