blob: de8c0abc39d951e16ed4ab8ab30c26a1818ecbd8 [file] [log] [blame]
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <gtest/gtest.h>
#include <cstdio>
#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>
#include <executorch/runtime/core/exec_aten/testing_util/tensor_factory.h>
#include <executorch/runtime/core/span.h>
#include <executorch/runtime/platform/runtime.h>
#include <executorch/test/utils/DeathTest.h>
#include <cstdint>
#include <cstring>
#include <memory>
namespace torch {
namespace executor {
class ProfilerETDumpTest : public ::testing::Test {
protected:
void SetUp() override {
torch::executor::runtime_init();
etdump_gen[0] = new ETDumpGen();
const size_t buf_size = 1024 * 1024;
buf = (uint8_t*)malloc(buf_size * sizeof(uint8_t));
etdump_gen[1] = new ETDumpGen(Span<uint8_t>(buf, buf_size));
}
void TearDown() override {
delete etdump_gen[0];
delete etdump_gen[1];
free(buf);
}
ETDumpGen* etdump_gen[2];
uint8_t* buf = nullptr;
};
TEST_F(ProfilerETDumpTest, SingleProfileEvent) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
EventTracerEntry entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
ASSERT_NE(etdump, nullptr);
EXPECT_EQ(etdump_ETDump_version(etdump), ETDUMP_VERSION);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
EXPECT_EQ(
etdump_gen[i]->get_num_blocks(), etdump_RunData_vec_len(run_data_vec));
etdump_RunData_table_t run_data_single_prof =
etdump_RunData_vec_at(run_data_vec, 0);
EXPECT_EQ(
std::string(
etdump_RunData_name(run_data_single_prof),
strlen(etdump_RunData_name(run_data_single_prof))),
"test_block");
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, MultipleProfileEvent) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
// Create the profile events and then add the actual profile events in
// reverse.
EventTracerEntry entry_1 =
etdump_gen[i]->start_profiling("test_event_1", 0, 1);
EventTracerEntry entry_2 =
etdump_gen[i]->start_profiling("test_event_2", 0, 2);
etdump_gen[i]->end_profiling(entry_2);
etdump_gen[i]->end_profiling(entry_1);
}
}
TEST_F(ProfilerETDumpTest, EmptyBlocks) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
etdump_gen[i]->create_event_block("test_block_1");
etdump_gen[i]->create_event_block("test_block_2");
EventTracerEntry entry =
etdump_gen[i]->start_profiling("test_event_1", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
ASSERT_EQ(etdump_RunData_vec_len(run_data_vec), 3);
ASSERT_EQ(
etdump_Event_vec_len(
etdump_RunData_events(etdump_RunData_vec_at(run_data_vec, 0))),
0);
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, AddAllocators) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
AllocatorID allocator_id = etdump_gen[i]->track_allocator("test_allocator");
EXPECT_EQ(allocator_id, 1);
allocator_id = etdump_gen[i]->track_allocator("test_allocator_1");
EXPECT_EQ(allocator_id, 2);
// Add a profiling event and then try to add an allocator which should fail.
EventTracerEntry entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
ET_EXPECT_DEATH(etdump_gen[i]->track_allocator("test_allocator"), "");
}
}
TEST_F(ProfilerETDumpTest, AllocationEvents) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
// Add allocation events.
etdump_gen[i]->track_allocation(1, 64);
etdump_gen[i]->track_allocation(2, 128);
// Add a mix of performance and memory events.
etdump_gen[i]->track_allocation(1, 64);
EventTracerEntry entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_gen[i]->track_allocation(2, 128);
}
}
TEST_F(ProfilerETDumpTest, DebugEvent) {
for (size_t i = 0; i < 2; i++) {
testing::TensorFactory<ScalarType::Float> tf;
EValue evalue(tf.ones({3, 2}));
etdump_gen[i]->create_event_block("test_block");
void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
etdump_gen[i]->set_debug_buffer(buffer);
etdump_gen[i]->log_evalue(evalue);
etdump_gen[i]->log_evalue(evalue, LoggedEValueType::kProgramOutput);
EValue evalue_int((int64_t)5);
etdump_gen[i]->log_evalue(evalue_int);
EValue evalue_double((double)1.5);
etdump_gen[i]->log_evalue(evalue_double);
EValue evalue_bool(true);
etdump_gen[i]->log_evalue(evalue_bool);
etdump_gen[i]->log_evalue(evalue_bool);
free(ptr);
}
}
TEST_F(ProfilerETDumpTest, DebugEventTensorList) {
for (size_t i = 0; i < 2; i++) {
testing::TensorFactory<ScalarType::Int> tf;
exec_aten::Tensor storage[2] = {tf.ones({3, 2}), tf.ones({3, 2})};
EValue evalue_1(storage[0]);
EValue evalue_2(storage[1]);
EValue* values_p[2] = {&evalue_1, &evalue_2};
BoxedEvalueList<exec_aten::Tensor> a_box(values_p, storage, 2);
EValue evalue(a_box);
evalue.tag = Tag::ListTensor;
etdump_gen[i]->create_event_block("test_block");
void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
etdump_gen[i]->set_debug_buffer(buffer);
etdump_gen[i]->log_evalue(evalue);
free(ptr);
}
}
TEST_F(ProfilerETDumpTest, VerifyLogging) {
testing::TensorFactory<ScalarType::Float> tf;
EValue evalue(tf.ones({3, 2}));
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
etdump_gen[i]->set_debug_buffer(buffer);
etdump_gen[i]->log_evalue(evalue);
etdump_gen[i]->log_evalue(evalue, LoggedEValueType::kProgramOutput);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
ASSERT_EQ(etdump_RunData_vec_len(run_data_vec), 1);
etdump_Event_vec_t events =
etdump_RunData_events(etdump_RunData_vec_at(run_data_vec, 0));
ASSERT_EQ(etdump_Event_vec_len(events), 2);
etdump_Event_table_t event = etdump_Event_vec_at(events, 0);
etdump_DebugEvent_table_t single_debug_event =
etdump_Event_debug_event(event);
etdump_Value_table_t value =
etdump_DebugEvent_debug_entry(single_debug_event);
ASSERT_EQ(etdump_Value_tensor_is_present(value), true);
ASSERT_EQ(etdump_Value_output_is_present(value), false);
etdump_Tensor_table_t tensor = etdump_Value_tensor(value);
executorch_flatbuffer_ScalarType_enum_t scalar_enum =
etdump_Tensor_scalar_type(tensor);
ASSERT_EQ(scalar_enum, executorch_flatbuffer_ScalarType_FLOAT);
flatbuffers_int64_vec_t sizes = etdump_Tensor_sizes(tensor);
ASSERT_EQ(flatbuffers_int64_vec_len(sizes), 2);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 0), 3);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 1), 2);
event = etdump_Event_vec_at(events, 1);
single_debug_event = etdump_Event_debug_event(event);
value = etdump_DebugEvent_debug_entry(single_debug_event);
ASSERT_EQ(etdump_Value_tensor_is_present(value), true);
ASSERT_EQ(etdump_Value_output_is_present(value), true);
etdump_Bool_table_t bool_val = etdump_Value_output_get(value);
bool bool_val_from_table = etdump_Bool_bool_val(bool_val);
ASSERT_EQ(bool_val_from_table, true);
free(ptr);
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, MultipleBlocksWithEvents) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
AllocatorID allocator_id_0 =
etdump_gen[i]->track_allocator("test_allocator_0");
AllocatorID allocator_id_1 =
etdump_gen[i]->track_allocator("test_allocator_1");
etdump_gen[i]->track_allocation(allocator_id_0, 64);
etdump_gen[i]->track_allocation(allocator_id_1, 128);
EventTracerEntry entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_gen[i]->create_event_block("test_block_1");
allocator_id_0 = etdump_gen[i]->track_allocator("test_allocator_0");
allocator_id_1 = etdump_gen[i]->track_allocator("test_allocator_1");
etdump_gen[i]->track_allocation(allocator_id_0, 64);
etdump_gen[i]->track_allocation(allocator_id_0, 128);
entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
ASSERT_NE(etdump, nullptr);
EXPECT_EQ(etdump_ETDump_version(etdump), ETDUMP_VERSION);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
ASSERT_EQ(
etdump_gen[i]->get_num_blocks(), etdump_RunData_vec_len(run_data_vec));
etdump_RunData_table_t run_data_0 = etdump_RunData_vec_at(run_data_vec, 0);
EXPECT_EQ(
std::string(
etdump_RunData_name(run_data_0),
strlen(etdump_RunData_name(run_data_0))),
"test_block");
etdump_Allocator_vec_t allocator_vec_0 =
etdump_RunData_allocators(run_data_0);
ASSERT_EQ(etdump_Allocator_vec_len(allocator_vec_0), 2);
etdump_Allocator_table_t allocator_0 =
etdump_Allocator_vec_at(allocator_vec_0, 0);
EXPECT_EQ(
std::string(
etdump_Allocator_name(allocator_0),
strlen(etdump_Allocator_name(allocator_0))),
"test_allocator_0");
etdump_Event_vec_t event_vec = etdump_RunData_events(run_data_0);
ASSERT_EQ(etdump_Event_vec_len(event_vec), 3);
etdump_Event_table_t event_0 = etdump_Event_vec_at(event_vec, 0);
EXPECT_EQ(
etdump_AllocationEvent_allocation_size(
etdump_Event_allocation_event(event_0)),
64);
etdump_Event_table_t event_2 = etdump_Event_vec_at(event_vec, 2);
flatbuffers_string_t event_2_name =
etdump_ProfileEvent_name(etdump_Event_profile_event(event_2));
EXPECT_EQ(std::string(event_2_name, strlen(event_2_name)), "test_event");
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, VerifyData) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
etdump_gen[i]->track_allocator("single prof allocator");
EventTracerEntry entry = etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
entry = etdump_gen[i]->start_profiling("test_event2", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
ASSERT_NE(etdump, nullptr);
EXPECT_EQ(etdump_ETDump_version(etdump), ETDUMP_VERSION);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
EXPECT_EQ(
etdump_gen[i]->get_num_blocks(), etdump_RunData_vec_len(run_data_vec));
etdump_RunData_table_t run_data_single_prof =
etdump_RunData_vec_at(run_data_vec, 0);
EXPECT_EQ(
std::string(
etdump_RunData_name(run_data_single_prof),
strlen(etdump_RunData_name(run_data_single_prof))),
"test_block");
etdump_Allocator_vec_t allocator_vec =
etdump_RunData_allocators(run_data_single_prof);
etdump_Event_table_t single_event =
etdump_Event_vec_at(etdump_RunData_events(run_data_single_prof), 0);
etdump_ProfileEvent_table_t single_prof_event =
etdump_Event_profile_event(single_event);
EXPECT_EQ(
std::string(
etdump_ProfileEvent_name(single_prof_event),
strlen(etdump_ProfileEvent_name(single_prof_event))),
"test_event");
EXPECT_EQ(etdump_ProfileEvent_chain_index(single_prof_event), 0);
flatbuffers_string_t allocator_name =
etdump_Allocator_name(etdump_Allocator_vec_at(allocator_vec, 0));
EXPECT_EQ(
std::string(allocator_name, strlen(allocator_name)),
"single prof allocator");
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, LogDelegateIntermediateOutput) {
for (size_t i = 0; i < 2; i++) {
void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
etdump_gen[i]->create_event_block("test_block");
testing::TensorFactory<ScalarType::Float> tf;
ET_EXPECT_DEATH(
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensor",
static_cast<torch::executor::DebugHandle>(-1),
tf.ones({3, 2})),
"Must pre-set debug buffer with set_debug_buffer()");
etdump_gen[i]->set_debug_buffer(buffer);
// Log a tensor
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensor",
static_cast<torch::executor::DebugHandle>(-1),
tf.ones({3, 2}));
// Log a tensor list
std::vector<Tensor> tensors = {tf.ones({5, 4}), tf.ones({7, 6})};
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensorlist",
static_cast<torch::executor::DebugHandle>(-1),
ArrayRef<Tensor>(tensors.data(), tensors.size()));
// Log an int
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensorlist",
static_cast<torch::executor::DebugHandle>(-1),
10);
// Log a double
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensorlist",
static_cast<torch::executor::DebugHandle>(-1),
20.75);
// Log a bool
etdump_gen[i]->log_intermediate_output_delegate(
"test_event_tensorlist",
static_cast<torch::executor::DebugHandle>(-1),
true);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
free(ptr);
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, VerifyDelegateIntermediateLogging) {
testing::TensorFactory<ScalarType::Float> tf;
EValue evalue(tf.ones({3, 2}));
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
void* ptr = malloc(2048);
Span<uint8_t> buffer((uint8_t*)ptr, 2048);
etdump_gen[i]->set_debug_buffer(buffer);
// Event 0
etdump_gen[i]->log_intermediate_output_delegate(
nullptr, 257, tf.ones({3, 4}));
// Event 1
etdump_gen[i]->log_intermediate_output_delegate(
nullptr, 258, tf.ones({5, 6}));
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
ASSERT_EQ(etdump_RunData_vec_len(run_data_vec), 1);
etdump_Event_vec_t events =
etdump_RunData_events(etdump_RunData_vec_at(run_data_vec, 0));
ASSERT_EQ(etdump_Event_vec_len(events), 2);
// Verify Event 0
etdump_Event_table_t event_0 = etdump_Event_vec_at(events, 0);
etdump_DebugEvent_table_t single_debug_event =
etdump_Event_debug_event(event_0);
etdump_Value_table_t value =
etdump_DebugEvent_debug_entry(single_debug_event);
ASSERT_EQ(etdump_Value_tensor_is_present(value), true);
etdump_Tensor_table_t tensor = etdump_Value_tensor(value);
executorch_flatbuffer_ScalarType_enum_t scalar_enum =
etdump_Tensor_scalar_type(tensor);
ASSERT_EQ(scalar_enum, executorch_flatbuffer_ScalarType_FLOAT);
flatbuffers_int64_vec_t sizes = etdump_Tensor_sizes(tensor);
ASSERT_EQ(flatbuffers_int64_vec_len(sizes), 2);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 0), 3);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 1), 4);
// Verify Event 1
etdump_Event_table_t event_1 = etdump_Event_vec_at(events, 1);
single_debug_event = etdump_Event_debug_event(event_1);
value = etdump_DebugEvent_debug_entry(single_debug_event);
tensor = etdump_Value_tensor(value);
sizes = etdump_Tensor_sizes(tensor);
ASSERT_EQ(flatbuffers_int64_vec_len(sizes), 2);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 0), 5);
ASSERT_EQ(flatbuffers_int64_vec_at(sizes, 1), 6);
// Event 1 should have a empty delegate_debug_id_str
flatbuffers_string_t delegate_debug_id_name =
etdump_DebugEvent_delegate_debug_id_str(
etdump_Event_debug_event(event_1));
EXPECT_EQ(delegate_debug_id_name, nullptr);
// Check for the correct delegate_debug_id_int
EXPECT_EQ(
etdump_DebugEvent_delegate_debug_id_int(
etdump_Event_debug_event(event_1)),
258);
free(ptr);
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, LogDelegateEvents) {
for (size_t i = 0; i < 2; i++) {
etdump_gen[i]->create_event_block("test_block");
// Event 0
etdump_gen[i]->log_profiling_delegate(nullptr, 276, 1, 2, nullptr, 0);
// Event 1
const char* metadata = "test_metadata";
etdump_gen[i]->log_profiling_delegate(
nullptr, 278, 1, 2, metadata, strlen(metadata) + 1);
EventTracerEntry entry = etdump_gen[i]->start_profiling_delegate(
"test_event", static_cast<torch::executor::DebugHandle>(-1));
EXPECT_NE(entry.delegate_event_id_type, DelegateDebugIdType::kNone);
// Event 2
etdump_gen[i]->end_profiling_delegate(
entry, metadata, strlen(metadata) + 1);
// Event 3
etdump_gen[i]->log_profiling_delegate(
"test_event",
static_cast<torch::executor::DebugHandle>(-1),
1,
2,
nullptr,
0);
// Event 4
etdump_gen[i]->log_profiling_delegate(
"test_event",
static_cast<torch::executor::DebugHandle>(-1),
1,
2,
metadata,
strlen(metadata) + 1);
// Only a valid name or delegate debug index should be passed in. If valid
// entries are passed in for both then the test should assert out.
ET_EXPECT_DEATH(
etdump_gen[i]->start_profiling_delegate("test_event", 1),
"Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
ET_EXPECT_DEATH(
etdump_gen[i]->log_profiling_delegate(
"test_event", 1, 1, 2, nullptr, 0),
"Only name or delegate_debug_index can be valid. Check DelegateMappingBuilder documentation for more details.");
ET_EXPECT_DEATH(
etdump_gen[i]->end_profiling(entry),
"Delegate events must use end_profiling_delegate to mark the end of a delegate profiling event.");
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
// Run verification tests on the data that was just serialized.
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
// Event 0
etdump_RunData_table_t run_data_0 = etdump_RunData_vec_at(run_data_vec, 0);
etdump_Event_vec_t event_vec = etdump_RunData_events(run_data_0);
ASSERT_EQ(etdump_Event_vec_len(event_vec), 5);
etdump_Event_table_t event = etdump_Event_vec_at(event_vec, 0);
flatbuffers_string_t delegate_debug_id_name =
etdump_ProfileEvent_delegate_debug_id_str(
etdump_Event_profile_event(event));
// Event 0 should have a empty delegate_debug_id_str
EXPECT_EQ(delegate_debug_id_name, nullptr);
// Check for the correct delegate_debug_id_int
EXPECT_EQ(
etdump_ProfileEvent_delegate_debug_id_int(
etdump_Event_profile_event(event)),
276);
flatbuffers_uint8_vec_t debug_metadata_name =
etdump_ProfileEvent_delegate_debug_metadata(
etdump_Event_profile_event(event));
// Event 0 should have an empty delegate_debug_metadata string.
EXPECT_EQ(flatbuffers_uint8_vec_len(debug_metadata_name), 0);
// Event 1
event = etdump_Event_vec_at(event_vec, 1);
// Check for the correct delegate_debug_id_int
EXPECT_EQ(
etdump_ProfileEvent_delegate_debug_id_int(
etdump_Event_profile_event(event)),
278);
debug_metadata_name = etdump_ProfileEvent_delegate_debug_metadata(
etdump_Event_profile_event(event));
// Check for the correct delegate_debug_metadata string
EXPECT_EQ(
std::string(
(char*)debug_metadata_name,
flatbuffers_uint8_vec_len(debug_metadata_name) - 1),
"test_metadata");
// Event 2
event = etdump_Event_vec_at(event_vec, 2);
delegate_debug_id_name = etdump_ProfileEvent_delegate_debug_id_str(
etdump_Event_profile_event(event));
// Check for the correct delegate_debug_id_str string.
EXPECT_EQ(
std::string(delegate_debug_id_name, strlen(delegate_debug_id_name)),
"test_event");
// Event 2 used a string delegate debug identifier, so delegate_debug_id_int
// should be -1.
EXPECT_EQ(
etdump_ProfileEvent_delegate_debug_id_int(
etdump_Event_profile_event(event)),
-1);
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
TEST_F(ProfilerETDumpTest, WriteAfterGetETDumpData) {
for (size_t i = 0; i < 2; i++) {
for (size_t j = 0; j < 2; j++) {
etdump_gen[i]->create_event_block("test_block");
EventTracerEntry entry =
etdump_gen[i]->start_profiling("test_event", 0, 1);
etdump_gen[i]->end_profiling(entry);
etdump_result result = etdump_gen[i]->get_etdump_data();
ASSERT_TRUE(result.buf != nullptr);
ASSERT_TRUE(result.size != 0);
size_t size = 0;
void* buf = flatbuffers_read_size_prefix(result.buf, &size);
etdump_ETDump_table_t etdump = etdump_ETDump_as_root_with_identifier(
buf, etdump_ETDump_file_identifier);
ASSERT_NE(etdump, nullptr);
EXPECT_EQ(etdump_ETDump_version(etdump), ETDUMP_VERSION);
etdump_RunData_vec_t run_data_vec = etdump_ETDump_run_data(etdump);
EXPECT_EQ(
etdump_gen[i]->get_num_blocks(),
etdump_RunData_vec_len(run_data_vec));
etdump_RunData_table_t run_data_single_prof =
etdump_RunData_vec_at(run_data_vec, 0);
EXPECT_EQ(
std::string(
etdump_RunData_name(run_data_single_prof),
strlen(etdump_RunData_name(run_data_single_prof))),
"test_block");
if (!etdump_gen[i]->is_static_etdump()) {
free(result.buf);
}
}
}
}
} // namespace executor
} // namespace torch