Skip to content

Commit 4f67ac3

Browse files
committed
[devtool] make ETDumpGen use bufferdatasink
Pull Request resolved: #8499 This diff enables customized debug data pipeline by making ETDumpGen leverage user-provided datasink. Details can be found in https://docs.google.com/document/d/1y_m32mKdj-OgLcLUz9TKhBW3PC3bBDYSBbeAH544EfM/edit?tab=t.0#heading=h.jlkcrurw482r ghstack-source-id: 267038962 @exported-using-ghexport Differential Revision: [D69647096](https://our.internmc.facebook.com/intern/diff/D69647096/)
1 parent a0a7fea commit 4f67ac3

File tree

6 files changed

+316
-226
lines changed

6 files changed

+316
-226
lines changed

devtools/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ add_custom_command(
176176
add_library(
177177
etdump ${CMAKE_CURRENT_SOURCE_DIR}/etdump/etdump_flatcc.cpp
178178
${CMAKE_CURRENT_SOURCE_DIR}/etdump/emitter.cpp
179+
${CMAKE_CURRENT_SOURCE_DIR}/etdump/buffer_data_sink.cpp
180+
${CMAKE_CURRENT_SOURCE_DIR}/etdump/buffer_data_sink.h
179181
)
180182

181183
target_link_libraries(

devtools/etdump/buffer_data_sink.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,24 @@ namespace etdump {
2525
class BufferDataSink : public DataSinkBase {
2626
public:
2727
/**
28-
* Constructs a BufferDataSink with a given buffer.
28+
* Constructs a BufferDataSink with a given span buffer.
2929
*
3030
* @param[in] buffer A Span object representing the buffer where data will be
3131
* stored.
3232
*/
3333
explicit BufferDataSink(::executorch::runtime::Span<uint8_t> buffer)
3434
: debug_buffer_(buffer), offset_(0) {}
3535

36+
/**
37+
* Constructs a BufferDataSink with a given ptr to data blob, and the size of
38+
* data blob.
39+
*
40+
* @param[in] ptr A pointer to the data blob where data will be stored.
41+
* @param[in] size The size of the data blob in bytes.
42+
*/
43+
BufferDataSink(void* ptr, size_t size)
44+
: debug_buffer_((uint8_t*)ptr, size), offset_(0) {}
45+
3646
BufferDataSink(const BufferDataSink&) = delete;
3747
BufferDataSink& operator=(const BufferDataSink&) = delete;
3848
BufferDataSink(BufferDataSink&&) = default;

devtools/etdump/etdump_flatcc.cpp

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <cstring>
1212

13+
#include <executorch/devtools/etdump/buffer_data_sink.h>
1314
#include <executorch/devtools/etdump/emitter.h>
1415
#include <executorch/devtools/etdump/etdump_schema_flatcc_builder.h>
1516
#include <executorch/devtools/etdump/etdump_schema_flatcc_reader.h>
@@ -29,6 +30,7 @@ using ::executorch::runtime::DelegateDebugIdType;
2930
using ::executorch::runtime::EValue;
3031
using ::executorch::runtime::EventTracerEntry;
3132
using ::executorch::runtime::LoggedEValueType;
33+
using ::executorch::runtime::Result;
3234
using ::executorch::runtime::Span;
3335
using ::executorch::runtime::Tag;
3436

@@ -347,10 +349,10 @@ void ETDumpGen::log_intermediate_output_delegate_helper(
347349
ET_CHECK_MSG(
348350
(name == nullptr) ^ (delegate_debug_index == -1),
349351
"Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
350-
if (debug_buffer_.empty()) {
351-
ET_CHECK_MSG(0, "Must pre-set debug buffer with set_debug_buffer()\n");
352-
return;
353-
}
352+
353+
ET_CHECK_MSG(
354+
data_sink_,
355+
"Must pre-set data sink before logging evalue with set_data_sink() or set_debug_buffer()\n");
354356

355357
check_ready_to_add_events();
356358
int64_t string_id = name != nullptr ? create_string_entry(name) : -1;
@@ -367,7 +369,7 @@ void ETDumpGen::log_intermediate_output_delegate_helper(
367369

368370
// Check the type of `output` then call the corresponding logging functions
369371
if constexpr (std::is_same<T, Tensor>::value) {
370-
long offset = copy_tensor_to_debug_buffer(output);
372+
long offset = write_tensor_or_raise_error(output);
371373
etdump_Tensor_ref_t tensor_ref = add_tensor_entry(builder_, output, offset);
372374

373375
etdump_Value_start(builder_);
@@ -377,7 +379,7 @@ void ETDumpGen::log_intermediate_output_delegate_helper(
377379
} else if constexpr (std::is_same<T, ArrayRef<Tensor>>::value) {
378380
etdump_Tensor_vec_start(builder_);
379381
for (size_t i = 0; i < output.size(); ++i) {
380-
long offset = copy_tensor_to_debug_buffer(output[i]);
382+
long offset = write_tensor_or_raise_error(output[i]);
381383
etdump_Tensor_vec_push(
382384
builder_, add_tensor_entry(builder_, output[i], offset));
383385
}
@@ -497,27 +499,15 @@ ETDumpResult ETDumpGen::get_etdump_data() {
497499
}
498500

499501
void ETDumpGen::set_debug_buffer(Span<uint8_t> buffer) {
500-
debug_buffer_ = buffer;
502+
data_sink_ = std::make_shared<BufferDataSink>(buffer);
501503
}
502504

503-
size_t ETDumpGen::copy_tensor_to_debug_buffer(executorch::aten::Tensor tensor) {
504-
if (tensor.nbytes() == 0) {
505-
return static_cast<size_t>(-1);
506-
}
507-
uint8_t* offset_ptr =
508-
internal::align_pointer(debug_buffer_.data() + debug_buffer_offset_, 64);
509-
debug_buffer_offset_ = (offset_ptr - debug_buffer_.data()) + tensor.nbytes();
510-
ET_CHECK_MSG(
511-
debug_buffer_offset_ <= debug_buffer_.size(),
512-
"Ran out of space to store intermediate outputs.");
513-
memcpy(offset_ptr, tensor.const_data_ptr(), tensor.nbytes());
514-
return (size_t)(offset_ptr - debug_buffer_.data());
505+
void ETDumpGen::set_data_sink(std::shared_ptr<DataSinkBase> buffer_data_sink) {
506+
data_sink_ = buffer_data_sink;
515507
}
516508

517509
void ETDumpGen::log_evalue(const EValue& evalue, LoggedEValueType evalue_type) {
518-
if (debug_buffer_.empty()) {
519-
return;
520-
}
510+
ET_CHECK_MSG(data_sink_, "Must set data sink before logging evalue\n");
521511

522512
check_ready_to_add_events();
523513

@@ -529,7 +519,7 @@ void ETDumpGen::log_evalue(const EValue& evalue, LoggedEValueType evalue_type) {
529519
switch (evalue.tag) {
530520
case Tag::Tensor: {
531521
executorch::aten::Tensor tensor = evalue.toTensor();
532-
long offset = copy_tensor_to_debug_buffer(tensor);
522+
long offset = write_tensor_or_raise_error(tensor);
533523
etdump_Tensor_ref_t tensor_ref =
534524
add_tensor_entry(builder_, tensor, offset);
535525

@@ -551,7 +541,7 @@ void ETDumpGen::log_evalue(const EValue& evalue, LoggedEValueType evalue_type) {
551541
evalue.toTensorList();
552542
etdump_Tensor_vec_start(builder_);
553543
for (size_t i = 0; i < tensors.size(); ++i) {
554-
long offset = copy_tensor_to_debug_buffer(tensors[i]);
544+
long offset = write_tensor_or_raise_error(tensors[i]);
555545
etdump_Tensor_vec_push(
556546
builder_, add_tensor_entry(builder_, tensors[i], offset));
557547
}
@@ -636,7 +626,28 @@ bool ETDumpGen::is_static_etdump() {
636626
}
637627

638628
size_t ETDumpGen::get_debug_buffer_size() const {
639-
return debug_buffer_.size();
629+
return ETDumpGen::get_data_sink_size();
630+
}
631+
632+
size_t ETDumpGen::get_data_sink_size() const {
633+
ET_CHECK_MSG(data_sink_, "Must set data sink before checking its size\n");
634+
Result<size_t> ret = data_sink_->get_storage_size();
635+
ET_CHECK_MSG(
636+
ret.ok(),
637+
"Failed to get storage size with error 0x%" PRIx32,
638+
static_cast<uint32_t>(ret.error()));
639+
return ret.get();
640+
}
641+
642+
long ETDumpGen::write_tensor_or_raise_error(Tensor tensor) {
643+
ET_CHECK_MSG(data_sink_, "Must set data sink before writing data\n");
644+
Result<size_t> ret =
645+
data_sink_->write(tensor.const_data_ptr(), tensor.nbytes());
646+
ET_CHECK_MSG(
647+
ret.ok(),
648+
"Failed to write tensor with error 0x%" PRIx32,
649+
static_cast<uint32_t>(ret.error()));
650+
return static_cast<long>(ret.get());
640651
}
641652

642653
} // namespace etdump

devtools/etdump/etdump_flatcc.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#pragma once
1010

1111
#include <cstdint>
12+
#include <memory>
1213

14+
#include <executorch/devtools/etdump/data_sink_base.h>
1315
#include <executorch/runtime/core/event_tracer.h>
1416
#include <executorch/runtime/core/span.h>
1517
#include <executorch/runtime/platform/platform.h>
@@ -141,8 +143,10 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
141143
::executorch::runtime::DebugHandle delegate_debug_index,
142144
const double& output) override;
143145
void set_debug_buffer(::executorch::runtime::Span<uint8_t> buffer);
146+
void set_data_sink(std::shared_ptr<DataSinkBase> buffer_data_sink);
144147
ETDumpResult get_etdump_data();
145148
size_t get_debug_buffer_size() const;
149+
size_t get_data_sink_size() const;
146150
size_t get_num_blocks();
147151
bool is_static_etdump();
148152
void reset();
@@ -158,7 +162,6 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
158162

159163
void check_ready_to_add_events();
160164
int64_t create_string_entry(const char* name);
161-
size_t copy_tensor_to_debug_buffer(executorch::aten::Tensor tensor);
162165

163166
/**
164167
* Templated helper function used to log various types of intermediate output.
@@ -170,10 +173,11 @@ class ETDumpGen : public ::executorch::runtime::EventTracer {
170173
::executorch::runtime::DebugHandle delegate_debug_index,
171174
const T& output);
172175

176+
long write_tensor_or_raise_error(executorch::aten::Tensor tensor);
177+
173178
struct flatcc_builder* builder_;
174179
size_t num_blocks_ = 0;
175-
::executorch::runtime::Span<uint8_t> debug_buffer_;
176-
size_t debug_buffer_offset_ = 0;
180+
std::shared_ptr<DataSinkBase> data_sink_;
177181
int bundled_input_index_ = -1;
178182
State state_ = State::Init;
179183
struct internal::ETDumpStaticAllocator alloc_;

devtools/etdump/targets.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def define_common_targets():
117117

118118
runtime.cxx_library(
119119
name = "buffer_data_sink" + aten_suffix,
120-
headers = [
120+
exported_headers = [
121121
"buffer_data_sink.h",
122122
],
123123
srcs = [
@@ -153,6 +153,8 @@ def define_common_targets():
153153
exported_deps = [
154154
":etdump_schema_flatcc",
155155
":utils",
156+
":data_sink_base" + aten_suffix,
157+
":buffer_data_sink" + aten_suffix,
156158
"//executorch/runtime/core:event_tracer" + aten_suffix,
157159
"//executorch/runtime/core/exec_aten/util:scalar_type_util" + aten_suffix,
158160
],

0 commit comments

Comments
 (0)