xref: /aosp_15_r20/external/executorch/devtools/etdump/etdump_flatcc.cpp (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1*523fa7a6SAndroid Build Coastguard Worker /*
2*523fa7a6SAndroid Build Coastguard Worker  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*523fa7a6SAndroid Build Coastguard Worker  * All rights reserved.
4*523fa7a6SAndroid Build Coastguard Worker  *
5*523fa7a6SAndroid Build Coastguard Worker  * This source code is licensed under the BSD-style license found in the
6*523fa7a6SAndroid Build Coastguard Worker  * LICENSE file in the root directory of this source tree.
7*523fa7a6SAndroid Build Coastguard Worker  */
8*523fa7a6SAndroid Build Coastguard Worker 
9*523fa7a6SAndroid Build Coastguard Worker #include <executorch/devtools/etdump/etdump_flatcc.h>
10*523fa7a6SAndroid Build Coastguard Worker 
11*523fa7a6SAndroid Build Coastguard Worker #include <cstring>
12*523fa7a6SAndroid Build Coastguard Worker 
13*523fa7a6SAndroid Build Coastguard Worker #include <executorch/devtools/etdump/emitter.h>
14*523fa7a6SAndroid Build Coastguard Worker #include <executorch/devtools/etdump/etdump_schema_flatcc_builder.h>
15*523fa7a6SAndroid Build Coastguard Worker #include <executorch/devtools/etdump/etdump_schema_flatcc_reader.h>
16*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/exec_aten/exec_aten.h>
17*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
18*523fa7a6SAndroid Build Coastguard Worker #include <executorch/runtime/platform/assert.h>
19*523fa7a6SAndroid Build Coastguard Worker 
20*523fa7a6SAndroid Build Coastguard Worker #include <flatcc/flatcc_types.h>
21*523fa7a6SAndroid Build Coastguard Worker 
22*523fa7a6SAndroid Build Coastguard Worker using ::exec_aten::Tensor;
23*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::AllocatorID;
24*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::ArrayRef;
25*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::ChainID;
26*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::DebugHandle;
27*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::DelegateDebugIdType;
28*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::EValue;
29*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::EventTracerEntry;
30*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::LoggedEValueType;
31*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::Span;
32*523fa7a6SAndroid Build Coastguard Worker using ::executorch::runtime::Tag;
33*523fa7a6SAndroid Build Coastguard Worker 
34*523fa7a6SAndroid Build Coastguard Worker namespace executorch {
35*523fa7a6SAndroid Build Coastguard Worker namespace etdump {
36*523fa7a6SAndroid Build Coastguard Worker 
37*523fa7a6SAndroid Build Coastguard Worker namespace {
38*523fa7a6SAndroid Build Coastguard Worker 
get_flatbuffer_scalar_type(exec_aten::ScalarType tensor_scalar_type)39*523fa7a6SAndroid Build Coastguard Worker executorch_flatbuffer_ScalarType_enum_t get_flatbuffer_scalar_type(
40*523fa7a6SAndroid Build Coastguard Worker     exec_aten::ScalarType tensor_scalar_type) {
41*523fa7a6SAndroid Build Coastguard Worker   switch (tensor_scalar_type) {
42*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Byte:
43*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_BYTE;
44*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Char:
45*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_CHAR;
46*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Short:
47*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_SHORT;
48*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Float:
49*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_FLOAT;
50*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Int:
51*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_INT;
52*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Long:
53*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_LONG;
54*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Double:
55*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_DOUBLE;
56*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Bool:
57*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_BOOL;
58*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::Bits16:
59*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_BITS16;
60*523fa7a6SAndroid Build Coastguard Worker     case exec_aten::ScalarType::UInt16:
61*523fa7a6SAndroid Build Coastguard Worker       return executorch_flatbuffer_ScalarType_UINT16;
62*523fa7a6SAndroid Build Coastguard Worker     default:
63*523fa7a6SAndroid Build Coastguard Worker       ET_CHECK_MSG(
64*523fa7a6SAndroid Build Coastguard Worker           0,
65*523fa7a6SAndroid Build Coastguard Worker           "This ScalarType = %hhd is not yet supported in ETDump",
66*523fa7a6SAndroid Build Coastguard Worker           static_cast<char>(tensor_scalar_type));
67*523fa7a6SAndroid Build Coastguard Worker   }
68*523fa7a6SAndroid Build Coastguard Worker }
69*523fa7a6SAndroid Build Coastguard Worker 
add_tensor_entry(flatcc_builder_t * builder_,const exec_aten::Tensor & tensor,long offset)70*523fa7a6SAndroid Build Coastguard Worker etdump_Tensor_ref_t add_tensor_entry(
71*523fa7a6SAndroid Build Coastguard Worker     flatcc_builder_t* builder_,
72*523fa7a6SAndroid Build Coastguard Worker     const exec_aten::Tensor& tensor,
73*523fa7a6SAndroid Build Coastguard Worker     long offset) {
74*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_start(builder_);
75*523fa7a6SAndroid Build Coastguard Worker 
76*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_scalar_type_add(
77*523fa7a6SAndroid Build Coastguard Worker       builder_, get_flatbuffer_scalar_type(tensor.scalar_type()));
78*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_sizes_start(builder_);
79*523fa7a6SAndroid Build Coastguard Worker 
80*523fa7a6SAndroid Build Coastguard Worker   for (auto dim : tensor.sizes()) {
81*523fa7a6SAndroid Build Coastguard Worker     int64_t cast_dim = static_cast<int64_t>(dim);
82*523fa7a6SAndroid Build Coastguard Worker     etdump_Tensor_sizes_push(builder_, &cast_dim);
83*523fa7a6SAndroid Build Coastguard Worker   }
84*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_sizes_end(builder_);
85*523fa7a6SAndroid Build Coastguard Worker 
86*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_strides_start(builder_);
87*523fa7a6SAndroid Build Coastguard Worker   for (auto dim : tensor.strides()) {
88*523fa7a6SAndroid Build Coastguard Worker     int64_t cast_dim = static_cast<int64_t>(dim);
89*523fa7a6SAndroid Build Coastguard Worker     etdump_Tensor_strides_push(builder_, &cast_dim);
90*523fa7a6SAndroid Build Coastguard Worker   }
91*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_strides_end(builder_);
92*523fa7a6SAndroid Build Coastguard Worker   etdump_Tensor_offset_add(builder_, offset);
93*523fa7a6SAndroid Build Coastguard Worker 
94*523fa7a6SAndroid Build Coastguard Worker   return etdump_Tensor_end(builder_);
95*523fa7a6SAndroid Build Coastguard Worker }
96*523fa7a6SAndroid Build Coastguard Worker 
alignPointer(void * ptr,size_t alignment)97*523fa7a6SAndroid Build Coastguard Worker static uint8_t* alignPointer(void* ptr, size_t alignment) {
98*523fa7a6SAndroid Build Coastguard Worker   intptr_t addr = reinterpret_cast<intptr_t>(ptr);
99*523fa7a6SAndroid Build Coastguard Worker   if ((addr & (alignment - 1)) == 0) {
100*523fa7a6SAndroid Build Coastguard Worker     // Already aligned.
101*523fa7a6SAndroid Build Coastguard Worker     return reinterpret_cast<uint8_t*>(ptr);
102*523fa7a6SAndroid Build Coastguard Worker   }
103*523fa7a6SAndroid Build Coastguard Worker   addr = (addr | (alignment - 1)) + 1;
104*523fa7a6SAndroid Build Coastguard Worker   return reinterpret_cast<uint8_t*>(addr);
105*523fa7a6SAndroid Build Coastguard Worker }
106*523fa7a6SAndroid Build Coastguard Worker 
107*523fa7a6SAndroid Build Coastguard Worker } // namespace
108*523fa7a6SAndroid Build Coastguard Worker 
109*523fa7a6SAndroid Build Coastguard Worker // Constructor implementation
ETDumpGen(Span<uint8_t> buffer)110*523fa7a6SAndroid Build Coastguard Worker ETDumpGen::ETDumpGen(Span<uint8_t> buffer) {
111*523fa7a6SAndroid Build Coastguard Worker   constexpr size_t max_alloc_buf_size = 128 * 1024;
112*523fa7a6SAndroid Build Coastguard Worker 
113*523fa7a6SAndroid Build Coastguard Worker   // Initialize the flatcc builder_ using the buffer and buffer size.
114*523fa7a6SAndroid Build Coastguard Worker 
115*523fa7a6SAndroid Build Coastguard Worker   if (buffer.data() != nullptr) {
116*523fa7a6SAndroid Build Coastguard Worker     builder_ = (struct flatcc_builder*)alignPointer(buffer.data(), 64);
117*523fa7a6SAndroid Build Coastguard Worker     uintptr_t buffer_with_builder =
118*523fa7a6SAndroid Build Coastguard Worker         (uintptr_t)alignPointer(builder_ + sizeof(struct flatcc_builder), 64);
119*523fa7a6SAndroid Build Coastguard Worker     size_t buffer_size = buffer.size() -
120*523fa7a6SAndroid Build Coastguard Worker         (size_t)(buffer_with_builder - (uintptr_t)buffer.data());
121*523fa7a6SAndroid Build Coastguard Worker     alloc_.set_buffer(
122*523fa7a6SAndroid Build Coastguard Worker         (uint8_t*)buffer_with_builder,
123*523fa7a6SAndroid Build Coastguard Worker         buffer_size,
124*523fa7a6SAndroid Build Coastguard Worker         (size_t)((buffer_size / 4 > max_alloc_buf_size) ? max_alloc_buf_size
125*523fa7a6SAndroid Build Coastguard Worker                                                         : buffer_size / 4));
126*523fa7a6SAndroid Build Coastguard Worker     internal::etdump_flatcc_custom_init(builder_, &alloc_);
127*523fa7a6SAndroid Build Coastguard Worker   } else {
128*523fa7a6SAndroid Build Coastguard Worker     builder_ = (struct flatcc_builder*)malloc(sizeof(struct flatcc_builder));
129*523fa7a6SAndroid Build Coastguard Worker     ET_CHECK_MSG(
130*523fa7a6SAndroid Build Coastguard Worker         builder_ != nullptr, "Failed to allocate memory for flatcc builder_.");
131*523fa7a6SAndroid Build Coastguard Worker     flatcc_builder_init(builder_);
132*523fa7a6SAndroid Build Coastguard Worker   }
133*523fa7a6SAndroid Build Coastguard Worker   reset();
134*523fa7a6SAndroid Build Coastguard Worker }
135*523fa7a6SAndroid Build Coastguard Worker 
~ETDumpGen()136*523fa7a6SAndroid Build Coastguard Worker ETDumpGen::~ETDumpGen() {
137*523fa7a6SAndroid Build Coastguard Worker   flatcc_builder_clear(builder_);
138*523fa7a6SAndroid Build Coastguard Worker   if (!is_static_etdump()) {
139*523fa7a6SAndroid Build Coastguard Worker     free(builder_);
140*523fa7a6SAndroid Build Coastguard Worker   }
141*523fa7a6SAndroid Build Coastguard Worker }
142*523fa7a6SAndroid Build Coastguard Worker 
reset()143*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::reset() {
144*523fa7a6SAndroid Build Coastguard Worker   state_ = State::Init;
145*523fa7a6SAndroid Build Coastguard Worker   num_blocks_ = 0;
146*523fa7a6SAndroid Build Coastguard Worker   flatcc_builder_reset(builder_);
147*523fa7a6SAndroid Build Coastguard Worker   flatbuffers_buffer_start(builder_, etdump_ETDump_file_identifier);
148*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_start_as_root_with_size(builder_);
149*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_version_add(builder_, ETDUMP_VERSION);
150*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_run_data_start(builder_);
151*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_run_data_push_start(builder_);
152*523fa7a6SAndroid Build Coastguard Worker }
153*523fa7a6SAndroid Build Coastguard Worker 
create_event_block(const char * name)154*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::create_event_block(const char* name) {
155*523fa7a6SAndroid Build Coastguard Worker   if (state_ == State::AddingEvents) {
156*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_events_end(builder_);
157*523fa7a6SAndroid Build Coastguard Worker   } else if (state_ == State::Done) {
158*523fa7a6SAndroid Build Coastguard Worker     reset();
159*523fa7a6SAndroid Build Coastguard Worker   }
160*523fa7a6SAndroid Build Coastguard Worker   if (num_blocks_ > 0) {
161*523fa7a6SAndroid Build Coastguard Worker     etdump_ETDump_run_data_push_end(builder_);
162*523fa7a6SAndroid Build Coastguard Worker     etdump_ETDump_run_data_push_start(builder_);
163*523fa7a6SAndroid Build Coastguard Worker   }
164*523fa7a6SAndroid Build Coastguard Worker   ++num_blocks_;
165*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_name_create_strn(builder_, name, strlen(name));
166*523fa7a6SAndroid Build Coastguard Worker   if (bundled_input_index_ != -1) {
167*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_bundled_input_index_add(builder_, bundled_input_index_);
168*523fa7a6SAndroid Build Coastguard Worker   }
169*523fa7a6SAndroid Build Coastguard Worker   state_ = State::BlockCreated;
170*523fa7a6SAndroid Build Coastguard Worker }
171*523fa7a6SAndroid Build Coastguard Worker 
create_string_entry(const char * name)172*523fa7a6SAndroid Build Coastguard Worker int64_t ETDumpGen::create_string_entry(const char* name) {
173*523fa7a6SAndroid Build Coastguard Worker   return flatbuffers_string_create_str(builder_, name);
174*523fa7a6SAndroid Build Coastguard Worker }
175*523fa7a6SAndroid Build Coastguard Worker 
176*523fa7a6SAndroid Build Coastguard Worker // ETDumpGen has the following possible states, ETDumpGen_Init,
177*523fa7a6SAndroid Build Coastguard Worker // ETDumpGen_Block_Created, ETDumpGen_Adding_Allocators,
178*523fa7a6SAndroid Build Coastguard Worker // ETDumpGen_Adding_Events. Right after boot-up the state of ETDump will be
179*523fa7a6SAndroid Build Coastguard Worker // ETDumpGen_Init. At this point we have an option of adding allocators that
180*523fa7a6SAndroid Build Coastguard Worker // we want to track. Once we've completed adding the allocators we want to track
181*523fa7a6SAndroid Build Coastguard Worker // we will close the allocators table and move ETDumpGen to the
182*523fa7a6SAndroid Build Coastguard Worker // ETDumpGen_Adding_Events state. After this point we can start adding events to
183*523fa7a6SAndroid Build Coastguard Worker // ETDump as we wish.
184*523fa7a6SAndroid Build Coastguard Worker // The reason we need to maintain this state machine inside of ETDumpGen is
185*523fa7a6SAndroid Build Coastguard Worker // because, once a table of one type has been closed and another table of a
186*523fa7a6SAndroid Build Coastguard Worker // different type is opened after it we cannot open another table of the first
187*523fa7a6SAndroid Build Coastguard Worker // type again. In this case once we close the allocators table and start pushing
188*523fa7a6SAndroid Build Coastguard Worker // to the events table we cannot push to the allocators table again.
check_ready_to_add_events()189*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::check_ready_to_add_events() {
190*523fa7a6SAndroid Build Coastguard Worker   if (state_ != State::AddingEvents) {
191*523fa7a6SAndroid Build Coastguard Worker     ET_CHECK_MSG(
192*523fa7a6SAndroid Build Coastguard Worker         (state_ == State::AddingAllocators || state_ == State::BlockCreated),
193*523fa7a6SAndroid Build Coastguard Worker         "ETDumpGen in an invalid state. Cannot add new events now.");
194*523fa7a6SAndroid Build Coastguard Worker     if (state_ == State::AddingAllocators) {
195*523fa7a6SAndroid Build Coastguard Worker       etdump_RunData_allocators_end(builder_);
196*523fa7a6SAndroid Build Coastguard Worker     }
197*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_events_start(builder_);
198*523fa7a6SAndroid Build Coastguard Worker     state_ = State::AddingEvents;
199*523fa7a6SAndroid Build Coastguard Worker   }
200*523fa7a6SAndroid Build Coastguard Worker }
201*523fa7a6SAndroid Build Coastguard Worker 
start_profiling(const char * name,ChainID chain_id,DebugHandle debug_handle)202*523fa7a6SAndroid Build Coastguard Worker EventTracerEntry ETDumpGen::start_profiling(
203*523fa7a6SAndroid Build Coastguard Worker     const char* name,
204*523fa7a6SAndroid Build Coastguard Worker     ChainID chain_id,
205*523fa7a6SAndroid Build Coastguard Worker     DebugHandle debug_handle) {
206*523fa7a6SAndroid Build Coastguard Worker   EventTracerEntry prof_entry;
207*523fa7a6SAndroid Build Coastguard Worker   prof_entry.event_id = name != nullptr ? create_string_entry(name) : -1;
208*523fa7a6SAndroid Build Coastguard Worker   prof_entry.delegate_event_id_type = DelegateDebugIdType::kNone;
209*523fa7a6SAndroid Build Coastguard Worker 
210*523fa7a6SAndroid Build Coastguard Worker   if (chain_id == -1) {
211*523fa7a6SAndroid Build Coastguard Worker     prof_entry.chain_id = chain_id_;
212*523fa7a6SAndroid Build Coastguard Worker     prof_entry.debug_handle = debug_handle_;
213*523fa7a6SAndroid Build Coastguard Worker   } else {
214*523fa7a6SAndroid Build Coastguard Worker     prof_entry.chain_id = chain_id;
215*523fa7a6SAndroid Build Coastguard Worker     prof_entry.debug_handle = debug_handle;
216*523fa7a6SAndroid Build Coastguard Worker   }
217*523fa7a6SAndroid Build Coastguard Worker   prof_entry.start_time = et_pal_current_ticks();
218*523fa7a6SAndroid Build Coastguard Worker   return prof_entry;
219*523fa7a6SAndroid Build Coastguard Worker }
220*523fa7a6SAndroid Build Coastguard Worker 
221*523fa7a6SAndroid Build Coastguard Worker // TODO: Update all occurrences of the ProfileEvent calls once the
222*523fa7a6SAndroid Build Coastguard Worker // EventTracerEntry struct is updated.
start_profiling_delegate(const char * name,DebugHandle delegate_debug_index)223*523fa7a6SAndroid Build Coastguard Worker EventTracerEntry ETDumpGen::start_profiling_delegate(
224*523fa7a6SAndroid Build Coastguard Worker     const char* name,
225*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index) {
226*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
227*523fa7a6SAndroid Build Coastguard Worker       (name == nullptr) ^ (delegate_debug_index == -1),
228*523fa7a6SAndroid Build Coastguard Worker       "Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
229*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
230*523fa7a6SAndroid Build Coastguard Worker   EventTracerEntry prof_entry;
231*523fa7a6SAndroid Build Coastguard Worker   DelegateDebugIdType delegate_event_id_type =
232*523fa7a6SAndroid Build Coastguard Worker       name == nullptr ? DelegateDebugIdType::kInt : DelegateDebugIdType::kStr;
233*523fa7a6SAndroid Build Coastguard Worker   prof_entry.delegate_event_id_type = delegate_event_id_type;
234*523fa7a6SAndroid Build Coastguard Worker   prof_entry.chain_id = chain_id_;
235*523fa7a6SAndroid Build Coastguard Worker   prof_entry.debug_handle = debug_handle_;
236*523fa7a6SAndroid Build Coastguard Worker   prof_entry.event_id = delegate_debug_index == static_cast<unsigned int>(-1)
237*523fa7a6SAndroid Build Coastguard Worker       ? create_string_entry(name)
238*523fa7a6SAndroid Build Coastguard Worker       : delegate_debug_index;
239*523fa7a6SAndroid Build Coastguard Worker   prof_entry.start_time = et_pal_current_ticks();
240*523fa7a6SAndroid Build Coastguard Worker   return prof_entry;
241*523fa7a6SAndroid Build Coastguard Worker }
242*523fa7a6SAndroid Build Coastguard Worker 
end_profiling_delegate(EventTracerEntry event_tracer_entry,const void * metadata,size_t metadata_len)243*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::end_profiling_delegate(
244*523fa7a6SAndroid Build Coastguard Worker     EventTracerEntry event_tracer_entry,
245*523fa7a6SAndroid Build Coastguard Worker     const void* metadata,
246*523fa7a6SAndroid Build Coastguard Worker     size_t metadata_len) {
247*523fa7a6SAndroid Build Coastguard Worker   et_timestamp_t end_time = et_pal_current_ticks();
248*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
249*523fa7a6SAndroid Build Coastguard Worker 
250*523fa7a6SAndroid Build Coastguard Worker   // Start building the ProfileEvent entry.
251*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start(builder_);
252*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start_time_add(builder_, event_tracer_entry.start_time);
253*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_end_time_add(builder_, end_time);
254*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_chain_index_add(builder_, chain_id_);
255*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_instruction_id_add(builder_, debug_handle_);
256*523fa7a6SAndroid Build Coastguard Worker   // Delegate debug identifier can either be of a string type or an integer
257*523fa7a6SAndroid Build Coastguard Worker   // type. If it's a string type then it's a value of type
258*523fa7a6SAndroid Build Coastguard Worker   // flatbuffers_string_ref_t type, whereas if it's an integer type then we
259*523fa7a6SAndroid Build Coastguard Worker   // write the integer value directly.
260*523fa7a6SAndroid Build Coastguard Worker   if (event_tracer_entry.delegate_event_id_type == DelegateDebugIdType::kInt) {
261*523fa7a6SAndroid Build Coastguard Worker     etdump_ProfileEvent_delegate_debug_id_int_add(
262*523fa7a6SAndroid Build Coastguard Worker         builder_, event_tracer_entry.event_id);
263*523fa7a6SAndroid Build Coastguard Worker   } else {
264*523fa7a6SAndroid Build Coastguard Worker     etdump_ProfileEvent_delegate_debug_id_str_add(
265*523fa7a6SAndroid Build Coastguard Worker         builder_, event_tracer_entry.event_id);
266*523fa7a6SAndroid Build Coastguard Worker   }
267*523fa7a6SAndroid Build Coastguard Worker   flatbuffers_uint8_vec_ref_t vec_ref = flatbuffers_uint8_vec_create_pe(
268*523fa7a6SAndroid Build Coastguard Worker       builder_, (const uint8_t*)metadata, metadata_len);
269*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_delegate_debug_metadata_add(builder_, vec_ref);
270*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_ref_t id = etdump_ProfileEvent_end(builder_);
271*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
272*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_profile_event_add(builder_, id);
273*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
274*523fa7a6SAndroid Build Coastguard Worker }
275*523fa7a6SAndroid Build Coastguard Worker 
log_profiling_delegate(const char * name,DebugHandle delegate_debug_index,et_timestamp_t start_time,et_timestamp_t end_time,const void * metadata,size_t metadata_len)276*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_profiling_delegate(
277*523fa7a6SAndroid Build Coastguard Worker     const char* name,
278*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
279*523fa7a6SAndroid Build Coastguard Worker     et_timestamp_t start_time,
280*523fa7a6SAndroid Build Coastguard Worker     et_timestamp_t end_time,
281*523fa7a6SAndroid Build Coastguard Worker     const void* metadata,
282*523fa7a6SAndroid Build Coastguard Worker     size_t metadata_len) {
283*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
284*523fa7a6SAndroid Build Coastguard Worker       (name == nullptr) ^ (delegate_debug_index == -1),
285*523fa7a6SAndroid Build Coastguard Worker       "Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
286*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
287*523fa7a6SAndroid Build Coastguard Worker   int64_t string_id = name != nullptr ? create_string_entry(name) : -1;
288*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start(builder_);
289*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start_time_add(builder_, start_time);
290*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_end_time_add(builder_, end_time);
291*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_chain_index_add(builder_, chain_id_);
292*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_instruction_id_add(builder_, debug_handle_);
293*523fa7a6SAndroid Build Coastguard Worker   if (string_id == -1) {
294*523fa7a6SAndroid Build Coastguard Worker     etdump_ProfileEvent_delegate_debug_id_int_add(
295*523fa7a6SAndroid Build Coastguard Worker         builder_, delegate_debug_index);
296*523fa7a6SAndroid Build Coastguard Worker   } else {
297*523fa7a6SAndroid Build Coastguard Worker     etdump_ProfileEvent_delegate_debug_id_str_add(builder_, string_id);
298*523fa7a6SAndroid Build Coastguard Worker   }
299*523fa7a6SAndroid Build Coastguard Worker   flatbuffers_uint8_vec_ref_t vec_ref = flatbuffers_uint8_vec_create_pe(
300*523fa7a6SAndroid Build Coastguard Worker       builder_, (const uint8_t*)metadata, metadata_len);
301*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_delegate_debug_metadata_add(builder_, vec_ref);
302*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_ref_t id = etdump_ProfileEvent_end(builder_);
303*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
304*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_profile_event_add(builder_, id);
305*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
306*523fa7a6SAndroid Build Coastguard Worker }
307*523fa7a6SAndroid Build Coastguard Worker 
log_intermediate_output_delegate(const char * name,DebugHandle delegate_debug_index,const Tensor & output)308*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate(
309*523fa7a6SAndroid Build Coastguard Worker     const char* name,
310*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
311*523fa7a6SAndroid Build Coastguard Worker     const Tensor& output) {
312*523fa7a6SAndroid Build Coastguard Worker   log_intermediate_output_delegate_helper(name, delegate_debug_index, output);
313*523fa7a6SAndroid Build Coastguard Worker }
314*523fa7a6SAndroid Build Coastguard Worker 
log_intermediate_output_delegate(const char * name,DebugHandle delegate_debug_index,const ArrayRef<Tensor> output)315*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate(
316*523fa7a6SAndroid Build Coastguard Worker     const char* name,
317*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
318*523fa7a6SAndroid Build Coastguard Worker     const ArrayRef<Tensor> output) {
319*523fa7a6SAndroid Build Coastguard Worker   log_intermediate_output_delegate_helper(name, delegate_debug_index, output);
320*523fa7a6SAndroid Build Coastguard Worker }
321*523fa7a6SAndroid Build Coastguard Worker 
log_intermediate_output_delegate(const char * name,DebugHandle delegate_debug_index,const int & output)322*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate(
323*523fa7a6SAndroid Build Coastguard Worker     const char* name,
324*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
325*523fa7a6SAndroid Build Coastguard Worker     const int& output) {
326*523fa7a6SAndroid Build Coastguard Worker   log_intermediate_output_delegate_helper(name, delegate_debug_index, output);
327*523fa7a6SAndroid Build Coastguard Worker }
328*523fa7a6SAndroid Build Coastguard Worker 
log_intermediate_output_delegate(const char * name,DebugHandle delegate_debug_index,const bool & output)329*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate(
330*523fa7a6SAndroid Build Coastguard Worker     const char* name,
331*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
332*523fa7a6SAndroid Build Coastguard Worker     const bool& output) {
333*523fa7a6SAndroid Build Coastguard Worker   log_intermediate_output_delegate_helper(name, delegate_debug_index, output);
334*523fa7a6SAndroid Build Coastguard Worker }
335*523fa7a6SAndroid Build Coastguard Worker 
log_intermediate_output_delegate(const char * name,DebugHandle delegate_debug_index,const double & output)336*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate(
337*523fa7a6SAndroid Build Coastguard Worker     const char* name,
338*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
339*523fa7a6SAndroid Build Coastguard Worker     const double& output) {
340*523fa7a6SAndroid Build Coastguard Worker   log_intermediate_output_delegate_helper(name, delegate_debug_index, output);
341*523fa7a6SAndroid Build Coastguard Worker }
342*523fa7a6SAndroid Build Coastguard Worker 
343*523fa7a6SAndroid Build Coastguard Worker template <typename T>
log_intermediate_output_delegate_helper(const char * name,DebugHandle delegate_debug_index,const T & output)344*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_intermediate_output_delegate_helper(
345*523fa7a6SAndroid Build Coastguard Worker     const char* name,
346*523fa7a6SAndroid Build Coastguard Worker     DebugHandle delegate_debug_index,
347*523fa7a6SAndroid Build Coastguard Worker     const T& output) {
348*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
349*523fa7a6SAndroid Build Coastguard Worker       (name == nullptr) ^ (delegate_debug_index == -1),
350*523fa7a6SAndroid Build Coastguard Worker       "Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
351*523fa7a6SAndroid Build Coastguard Worker   if (debug_buffer_.empty()) {
352*523fa7a6SAndroid Build Coastguard Worker     ET_CHECK_MSG(0, "Must pre-set debug buffer with set_debug_buffer()\n");
353*523fa7a6SAndroid Build Coastguard Worker     return;
354*523fa7a6SAndroid Build Coastguard Worker   }
355*523fa7a6SAndroid Build Coastguard Worker 
356*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
357*523fa7a6SAndroid Build Coastguard Worker   int64_t string_id = name != nullptr ? create_string_entry(name) : -1;
358*523fa7a6SAndroid Build Coastguard Worker 
359*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_start(builder_);
360*523fa7a6SAndroid Build Coastguard Worker 
361*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_chain_index_add(builder_, chain_id_);
362*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_instruction_id_add(builder_, debug_handle_);
363*523fa7a6SAndroid Build Coastguard Worker   if (string_id == -1) {
364*523fa7a6SAndroid Build Coastguard Worker     etdump_DebugEvent_delegate_debug_id_int_add(builder_, delegate_debug_index);
365*523fa7a6SAndroid Build Coastguard Worker   } else {
366*523fa7a6SAndroid Build Coastguard Worker     etdump_DebugEvent_delegate_debug_id_str_add(builder_, string_id);
367*523fa7a6SAndroid Build Coastguard Worker   }
368*523fa7a6SAndroid Build Coastguard Worker 
369*523fa7a6SAndroid Build Coastguard Worker   // Check the type of `output` then call the corresponding logging functions
370*523fa7a6SAndroid Build Coastguard Worker   if constexpr (std::is_same<T, Tensor>::value) {
371*523fa7a6SAndroid Build Coastguard Worker     long offset = copy_tensor_to_debug_buffer(output);
372*523fa7a6SAndroid Build Coastguard Worker     etdump_Tensor_ref_t tensor_ref = add_tensor_entry(builder_, output, offset);
373*523fa7a6SAndroid Build Coastguard Worker 
374*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_start(builder_);
375*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_val_add(builder_, etdump_ValueType_Tensor);
376*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_tensor_add(builder_, tensor_ref);
377*523fa7a6SAndroid Build Coastguard Worker 
378*523fa7a6SAndroid Build Coastguard Worker   } else if constexpr (std::is_same<T, ArrayRef<Tensor>>::value) {
379*523fa7a6SAndroid Build Coastguard Worker     etdump_Tensor_vec_start(builder_);
380*523fa7a6SAndroid Build Coastguard Worker     for (size_t i = 0; i < output.size(); ++i) {
381*523fa7a6SAndroid Build Coastguard Worker       long offset = copy_tensor_to_debug_buffer(output[i]);
382*523fa7a6SAndroid Build Coastguard Worker       etdump_Tensor_vec_push(
383*523fa7a6SAndroid Build Coastguard Worker           builder_, add_tensor_entry(builder_, output[i], offset));
384*523fa7a6SAndroid Build Coastguard Worker     }
385*523fa7a6SAndroid Build Coastguard Worker     etdump_Tensor_vec_ref_t tensor_vec_ref = etdump_Tensor_vec_end(builder_);
386*523fa7a6SAndroid Build Coastguard Worker     etdump_TensorList_ref_t tensor_list_ref =
387*523fa7a6SAndroid Build Coastguard Worker         etdump_TensorList_create(builder_, tensor_vec_ref);
388*523fa7a6SAndroid Build Coastguard Worker 
389*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_start(builder_);
390*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_val_add(builder_, etdump_ValueType_TensorList);
391*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_tensor_list_add(builder_, tensor_list_ref);
392*523fa7a6SAndroid Build Coastguard Worker   } else if constexpr (std::is_same<T, int>::value) {
393*523fa7a6SAndroid Build Coastguard Worker     auto int_ref = etdump_Int_create(builder_, output);
394*523fa7a6SAndroid Build Coastguard Worker 
395*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_start(builder_);
396*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_val_add(builder_, etdump_ValueType_Int);
397*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_int_value_add(builder_, int_ref);
398*523fa7a6SAndroid Build Coastguard Worker   } else if constexpr (std::is_same<T, double>::value) {
399*523fa7a6SAndroid Build Coastguard Worker     auto double_ref = etdump_Double_create(builder_, output);
400*523fa7a6SAndroid Build Coastguard Worker 
401*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_start(builder_);
402*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_double_value_add(builder_, double_ref);
403*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_val_add(builder_, etdump_ValueType_Double);
404*523fa7a6SAndroid Build Coastguard Worker   } else if constexpr (std::is_same<T, bool>::value) {
405*523fa7a6SAndroid Build Coastguard Worker     flatbuffers_bool_t flatbuffer_bool_val =
406*523fa7a6SAndroid Build Coastguard Worker         output ? FLATBUFFERS_TRUE : FLATBUFFERS_FALSE;
407*523fa7a6SAndroid Build Coastguard Worker     auto bool_ref = etdump_Bool_create(builder_, flatbuffer_bool_val);
408*523fa7a6SAndroid Build Coastguard Worker 
409*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_start(builder_);
410*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_bool_value_add(builder_, bool_ref);
411*523fa7a6SAndroid Build Coastguard Worker     etdump_Value_val_add(builder_, etdump_ValueType_Bool);
412*523fa7a6SAndroid Build Coastguard Worker   } else {
413*523fa7a6SAndroid Build Coastguard Worker     ET_CHECK_MSG(0, "Unsupported output type for intermediate logging\n");
414*523fa7a6SAndroid Build Coastguard Worker   }
415*523fa7a6SAndroid Build Coastguard Worker 
416*523fa7a6SAndroid Build Coastguard Worker   auto value_ref = etdump_Value_end(builder_);
417*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_debug_entry_add(builder_, value_ref);
418*523fa7a6SAndroid Build Coastguard Worker 
419*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_ref_t debug_event = etdump_DebugEvent_end(builder_);
420*523fa7a6SAndroid Build Coastguard Worker 
421*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
422*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_debug_event_add(builder_, debug_event);
423*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
424*523fa7a6SAndroid Build Coastguard Worker }
425*523fa7a6SAndroid Build Coastguard Worker 
end_profiling(EventTracerEntry prof_entry)426*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::end_profiling(EventTracerEntry prof_entry) {
427*523fa7a6SAndroid Build Coastguard Worker   et_timestamp_t end_time = et_pal_current_ticks();
428*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
429*523fa7a6SAndroid Build Coastguard Worker       prof_entry.delegate_event_id_type == DelegateDebugIdType::kNone,
430*523fa7a6SAndroid Build Coastguard Worker       "Delegate events must use end_profiling_delegate to mark the end of a delegate profiling event.");
431*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
432*523fa7a6SAndroid Build Coastguard Worker 
433*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start(builder_);
434*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_start_time_add(builder_, prof_entry.start_time);
435*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_end_time_add(builder_, end_time);
436*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_chain_index_add(builder_, prof_entry.chain_id);
437*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_instruction_id_add(builder_, prof_entry.debug_handle);
438*523fa7a6SAndroid Build Coastguard Worker   if (prof_entry.event_id != -1) {
439*523fa7a6SAndroid Build Coastguard Worker     etdump_ProfileEvent_name_add(builder_, prof_entry.event_id);
440*523fa7a6SAndroid Build Coastguard Worker   }
441*523fa7a6SAndroid Build Coastguard Worker   etdump_ProfileEvent_ref_t id = etdump_ProfileEvent_end(builder_);
442*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
443*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_profile_event_add(builder_, id);
444*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
445*523fa7a6SAndroid Build Coastguard Worker }
446*523fa7a6SAndroid Build Coastguard Worker 
track_allocator(const char * name)447*523fa7a6SAndroid Build Coastguard Worker AllocatorID ETDumpGen::track_allocator(const char* name) {
448*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
449*523fa7a6SAndroid Build Coastguard Worker       (state_ == State::BlockCreated || state_ == State::AddingAllocators),
450*523fa7a6SAndroid Build Coastguard Worker       "Allocators can only be added immediately after a new block is created and before any events are added.");
451*523fa7a6SAndroid Build Coastguard Worker   if (state_ != State::AddingAllocators) {
452*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_allocators_start(builder_);
453*523fa7a6SAndroid Build Coastguard Worker     state_ = State::AddingAllocators;
454*523fa7a6SAndroid Build Coastguard Worker   }
455*523fa7a6SAndroid Build Coastguard Worker   flatbuffers_string_ref_t ref = create_string_entry(name);
456*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_allocators_push_create(builder_, ref);
457*523fa7a6SAndroid Build Coastguard Worker   return etdump_RunData_allocators_reserved_len(builder_);
458*523fa7a6SAndroid Build Coastguard Worker }
459*523fa7a6SAndroid Build Coastguard Worker 
track_allocation(AllocatorID allocator_id,size_t allocation_size)460*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::track_allocation(
461*523fa7a6SAndroid Build Coastguard Worker     AllocatorID allocator_id,
462*523fa7a6SAndroid Build Coastguard Worker     size_t allocation_size) {
463*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
464*523fa7a6SAndroid Build Coastguard Worker 
465*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
466*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_allocation_event_create(builder_, allocator_id, allocation_size);
467*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
468*523fa7a6SAndroid Build Coastguard Worker }
469*523fa7a6SAndroid Build Coastguard Worker 
get_etdump_data()470*523fa7a6SAndroid Build Coastguard Worker ETDumpResult ETDumpGen::get_etdump_data() {
471*523fa7a6SAndroid Build Coastguard Worker   ETDumpResult result;
472*523fa7a6SAndroid Build Coastguard Worker   if (state_ == State::AddingEvents) {
473*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_events_end(builder_);
474*523fa7a6SAndroid Build Coastguard Worker   } else if (state_ == State::AddingAllocators) {
475*523fa7a6SAndroid Build Coastguard Worker     etdump_RunData_allocators_end(builder_);
476*523fa7a6SAndroid Build Coastguard Worker   } else if (state_ == State::Init) {
477*523fa7a6SAndroid Build Coastguard Worker     result.buf = nullptr;
478*523fa7a6SAndroid Build Coastguard Worker     result.size = 0;
479*523fa7a6SAndroid Build Coastguard Worker     return result;
480*523fa7a6SAndroid Build Coastguard Worker   }
481*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_run_data_push_end(builder_);
482*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_run_data_end(builder_);
483*523fa7a6SAndroid Build Coastguard Worker   etdump_ETDump_ref_t root = etdump_ETDump_end(builder_);
484*523fa7a6SAndroid Build Coastguard Worker   flatbuffers_buffer_end(builder_, root);
485*523fa7a6SAndroid Build Coastguard Worker   if (num_blocks_ == 0) {
486*523fa7a6SAndroid Build Coastguard Worker     result = {nullptr, 0};
487*523fa7a6SAndroid Build Coastguard Worker   } else {
488*523fa7a6SAndroid Build Coastguard Worker     if (alloc_.data) {
489*523fa7a6SAndroid Build Coastguard Worker       result.buf = alloc_.front_cursor;
490*523fa7a6SAndroid Build Coastguard Worker       result.size = alloc_.out_size - alloc_.front_left;
491*523fa7a6SAndroid Build Coastguard Worker     } else {
492*523fa7a6SAndroid Build Coastguard Worker       result.buf =
493*523fa7a6SAndroid Build Coastguard Worker           flatcc_builder_finalize_aligned_buffer(builder_, &result.size);
494*523fa7a6SAndroid Build Coastguard Worker     }
495*523fa7a6SAndroid Build Coastguard Worker   }
496*523fa7a6SAndroid Build Coastguard Worker   state_ = State::Done;
497*523fa7a6SAndroid Build Coastguard Worker   return result;
498*523fa7a6SAndroid Build Coastguard Worker }
499*523fa7a6SAndroid Build Coastguard Worker 
set_debug_buffer(Span<uint8_t> buffer)500*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::set_debug_buffer(Span<uint8_t> buffer) {
501*523fa7a6SAndroid Build Coastguard Worker   debug_buffer_ = buffer;
502*523fa7a6SAndroid Build Coastguard Worker }
503*523fa7a6SAndroid Build Coastguard Worker 
copy_tensor_to_debug_buffer(exec_aten::Tensor tensor)504*523fa7a6SAndroid Build Coastguard Worker size_t ETDumpGen::copy_tensor_to_debug_buffer(exec_aten::Tensor tensor) {
505*523fa7a6SAndroid Build Coastguard Worker   if (tensor.nbytes() == 0) {
506*523fa7a6SAndroid Build Coastguard Worker     return static_cast<size_t>(-1);
507*523fa7a6SAndroid Build Coastguard Worker   }
508*523fa7a6SAndroid Build Coastguard Worker   uint8_t* offset_ptr =
509*523fa7a6SAndroid Build Coastguard Worker       alignPointer(debug_buffer_.data() + debug_buffer_offset_, 64);
510*523fa7a6SAndroid Build Coastguard Worker   debug_buffer_offset_ = (offset_ptr - debug_buffer_.data()) + tensor.nbytes();
511*523fa7a6SAndroid Build Coastguard Worker   ET_CHECK_MSG(
512*523fa7a6SAndroid Build Coastguard Worker       debug_buffer_offset_ <= debug_buffer_.size(),
513*523fa7a6SAndroid Build Coastguard Worker       "Ran out of space to store intermediate outputs.");
514*523fa7a6SAndroid Build Coastguard Worker   memcpy(offset_ptr, tensor.const_data_ptr(), tensor.nbytes());
515*523fa7a6SAndroid Build Coastguard Worker   return (size_t)(offset_ptr - debug_buffer_.data());
516*523fa7a6SAndroid Build Coastguard Worker }
517*523fa7a6SAndroid Build Coastguard Worker 
log_evalue(const EValue & evalue,LoggedEValueType evalue_type)518*523fa7a6SAndroid Build Coastguard Worker void ETDumpGen::log_evalue(const EValue& evalue, LoggedEValueType evalue_type) {
519*523fa7a6SAndroid Build Coastguard Worker   if (debug_buffer_.empty()) {
520*523fa7a6SAndroid Build Coastguard Worker     return;
521*523fa7a6SAndroid Build Coastguard Worker   }
522*523fa7a6SAndroid Build Coastguard Worker 
523*523fa7a6SAndroid Build Coastguard Worker   check_ready_to_add_events();
524*523fa7a6SAndroid Build Coastguard Worker 
525*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_start(builder_);
526*523fa7a6SAndroid Build Coastguard Worker 
527*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_chain_index_add(builder_, chain_id_);
528*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_instruction_id_add(builder_, debug_handle_);
529*523fa7a6SAndroid Build Coastguard Worker 
530*523fa7a6SAndroid Build Coastguard Worker   switch (evalue.tag) {
531*523fa7a6SAndroid Build Coastguard Worker     case Tag::Tensor: {
532*523fa7a6SAndroid Build Coastguard Worker       exec_aten::Tensor tensor = evalue.toTensor();
533*523fa7a6SAndroid Build Coastguard Worker       long offset = copy_tensor_to_debug_buffer(tensor);
534*523fa7a6SAndroid Build Coastguard Worker       etdump_Tensor_ref_t tensor_ref =
535*523fa7a6SAndroid Build Coastguard Worker           add_tensor_entry(builder_, tensor, offset);
536*523fa7a6SAndroid Build Coastguard Worker 
537*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_start(builder_);
538*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_val_add(builder_, etdump_ValueType_Tensor);
539*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_tensor_add(builder_, tensor_ref);
540*523fa7a6SAndroid Build Coastguard Worker       if (evalue_type == LoggedEValueType::kProgramOutput) {
541*523fa7a6SAndroid Build Coastguard Worker         auto bool_ref = etdump_Bool_create(builder_, FLATBUFFERS_TRUE);
542*523fa7a6SAndroid Build Coastguard Worker         etdump_Value_output_add(builder_, bool_ref);
543*523fa7a6SAndroid Build Coastguard Worker       }
544*523fa7a6SAndroid Build Coastguard Worker       auto value_ref = etdump_Value_end(builder_);
545*523fa7a6SAndroid Build Coastguard Worker 
546*523fa7a6SAndroid Build Coastguard Worker       etdump_DebugEvent_debug_entry_add(builder_, value_ref);
547*523fa7a6SAndroid Build Coastguard Worker       break;
548*523fa7a6SAndroid Build Coastguard Worker     }
549*523fa7a6SAndroid Build Coastguard Worker 
550*523fa7a6SAndroid Build Coastguard Worker     case Tag::ListTensor: {
551*523fa7a6SAndroid Build Coastguard Worker       exec_aten::ArrayRef<exec_aten::Tensor> tensors = evalue.toTensorList();
552*523fa7a6SAndroid Build Coastguard Worker       etdump_Tensor_vec_start(builder_);
553*523fa7a6SAndroid Build Coastguard Worker       for (size_t i = 0; i < tensors.size(); ++i) {
554*523fa7a6SAndroid Build Coastguard Worker         long offset = copy_tensor_to_debug_buffer(tensors[i]);
555*523fa7a6SAndroid Build Coastguard Worker         etdump_Tensor_vec_push(
556*523fa7a6SAndroid Build Coastguard Worker             builder_, add_tensor_entry(builder_, tensors[i], offset));
557*523fa7a6SAndroid Build Coastguard Worker       }
558*523fa7a6SAndroid Build Coastguard Worker       etdump_Tensor_vec_ref_t tensor_vec_ref = etdump_Tensor_vec_end(builder_);
559*523fa7a6SAndroid Build Coastguard Worker       etdump_TensorList_ref_t tensor_list_ref =
560*523fa7a6SAndroid Build Coastguard Worker           etdump_TensorList_create(builder_, tensor_vec_ref);
561*523fa7a6SAndroid Build Coastguard Worker 
562*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_start(builder_);
563*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_val_add(builder_, etdump_ValueType_TensorList);
564*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_tensor_list_add(builder_, tensor_list_ref);
565*523fa7a6SAndroid Build Coastguard Worker       if (evalue_type == LoggedEValueType::kProgramOutput) {
566*523fa7a6SAndroid Build Coastguard Worker         auto bool_ref = etdump_Bool_create(builder_, FLATBUFFERS_TRUE);
567*523fa7a6SAndroid Build Coastguard Worker         etdump_Value_output_add(builder_, bool_ref);
568*523fa7a6SAndroid Build Coastguard Worker       }
569*523fa7a6SAndroid Build Coastguard Worker       auto value_ref = etdump_Value_end(builder_);
570*523fa7a6SAndroid Build Coastguard Worker 
571*523fa7a6SAndroid Build Coastguard Worker       etdump_DebugEvent_debug_entry_add(builder_, value_ref);
572*523fa7a6SAndroid Build Coastguard Worker       break;
573*523fa7a6SAndroid Build Coastguard Worker     }
574*523fa7a6SAndroid Build Coastguard Worker 
575*523fa7a6SAndroid Build Coastguard Worker     case Tag::Int: {
576*523fa7a6SAndroid Build Coastguard Worker       int64_t val = evalue.toInt();
577*523fa7a6SAndroid Build Coastguard Worker       auto int_ref = etdump_Int_create(builder_, val);
578*523fa7a6SAndroid Build Coastguard Worker 
579*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_start(builder_);
580*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_val_add(builder_, etdump_ValueType_Int);
581*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_int_value_add(builder_, int_ref);
582*523fa7a6SAndroid Build Coastguard Worker       auto value_ref = etdump_Value_end(builder_);
583*523fa7a6SAndroid Build Coastguard Worker       etdump_DebugEvent_debug_entry_add(builder_, value_ref);
584*523fa7a6SAndroid Build Coastguard Worker 
585*523fa7a6SAndroid Build Coastguard Worker       break;
586*523fa7a6SAndroid Build Coastguard Worker     }
587*523fa7a6SAndroid Build Coastguard Worker 
588*523fa7a6SAndroid Build Coastguard Worker     case Tag::Double: {
589*523fa7a6SAndroid Build Coastguard Worker       double val = evalue.toDouble();
590*523fa7a6SAndroid Build Coastguard Worker       auto double_ref = etdump_Double_create(builder_, val);
591*523fa7a6SAndroid Build Coastguard Worker 
592*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_start(builder_);
593*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_double_value_add(builder_, double_ref);
594*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_val_add(builder_, etdump_ValueType_Double);
595*523fa7a6SAndroid Build Coastguard Worker       auto value_ref = etdump_Value_end(builder_);
596*523fa7a6SAndroid Build Coastguard Worker       etdump_DebugEvent_debug_entry_add(builder_, value_ref);
597*523fa7a6SAndroid Build Coastguard Worker 
598*523fa7a6SAndroid Build Coastguard Worker       break;
599*523fa7a6SAndroid Build Coastguard Worker     }
600*523fa7a6SAndroid Build Coastguard Worker 
601*523fa7a6SAndroid Build Coastguard Worker     case Tag::Bool: {
602*523fa7a6SAndroid Build Coastguard Worker       flatbuffers_bool_t flatbuffer_bool_val =
603*523fa7a6SAndroid Build Coastguard Worker           evalue.toBool() ? FLATBUFFERS_TRUE : FLATBUFFERS_FALSE;
604*523fa7a6SAndroid Build Coastguard Worker       auto bool_ref = etdump_Bool_create(builder_, flatbuffer_bool_val);
605*523fa7a6SAndroid Build Coastguard Worker 
606*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_start(builder_);
607*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_bool_value_add(builder_, bool_ref);
608*523fa7a6SAndroid Build Coastguard Worker       etdump_Value_val_add(builder_, etdump_ValueType_Bool);
609*523fa7a6SAndroid Build Coastguard Worker       auto value_ref = etdump_Value_end(builder_);
610*523fa7a6SAndroid Build Coastguard Worker       etdump_DebugEvent_debug_entry_add(builder_, value_ref);
611*523fa7a6SAndroid Build Coastguard Worker 
612*523fa7a6SAndroid Build Coastguard Worker       break;
613*523fa7a6SAndroid Build Coastguard Worker     }
614*523fa7a6SAndroid Build Coastguard Worker 
615*523fa7a6SAndroid Build Coastguard Worker     default:
616*523fa7a6SAndroid Build Coastguard Worker       ET_CHECK_MSG(
617*523fa7a6SAndroid Build Coastguard Worker           0,
618*523fa7a6SAndroid Build Coastguard Worker           "This EValue type = %d is not yet supported for logging\n",
619*523fa7a6SAndroid Build Coastguard Worker           static_cast<int>(evalue.tag));
620*523fa7a6SAndroid Build Coastguard Worker       break;
621*523fa7a6SAndroid Build Coastguard Worker   }
622*523fa7a6SAndroid Build Coastguard Worker 
623*523fa7a6SAndroid Build Coastguard Worker   etdump_DebugEvent_ref_t debug_event = etdump_DebugEvent_end(builder_);
624*523fa7a6SAndroid Build Coastguard Worker 
625*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_start(builder_);
626*523fa7a6SAndroid Build Coastguard Worker   etdump_Event_debug_event_add(builder_, debug_event);
627*523fa7a6SAndroid Build Coastguard Worker   etdump_RunData_events_push_end(builder_);
628*523fa7a6SAndroid Build Coastguard Worker }
629*523fa7a6SAndroid Build Coastguard Worker 
get_num_blocks()630*523fa7a6SAndroid Build Coastguard Worker size_t ETDumpGen::get_num_blocks() {
631*523fa7a6SAndroid Build Coastguard Worker   return num_blocks_;
632*523fa7a6SAndroid Build Coastguard Worker }
633*523fa7a6SAndroid Build Coastguard Worker 
is_static_etdump()634*523fa7a6SAndroid Build Coastguard Worker bool ETDumpGen::is_static_etdump() {
635*523fa7a6SAndroid Build Coastguard Worker   return alloc_.data != nullptr;
636*523fa7a6SAndroid Build Coastguard Worker }
637*523fa7a6SAndroid Build Coastguard Worker 
638*523fa7a6SAndroid Build Coastguard Worker } // namespace etdump
639*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch
640