#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
namespace executorch {
namespace runtime {
#define ET_PROF_VER 0x00000001
#ifndef MAX_PROFILE_EVENTS
#define MAX_PROFILE_EVENTS 1024
#endif
#ifndef MAX_MEM_PROFILE_EVENTS
#define MAX_MEM_PROFILE_EVENTS 1024
#endif
#ifndef MEM_PROFILE_MAX_ALLOCATORS
#define MEM_PROFILE_MAX_ALLOCATORS 32
#endif
#ifndef MAX_PROFILE_BLOCKS
#define MAX_PROFILE_BLOCKS 2
#endif
#define PROF_NAME_MAX_LEN 32
typedef struct alignas(8) {
union {
const char* name_str;
char name[PROF_NAME_MAX_LEN];
};
int32_t chain_idx;
uint32_t instruction_idx;
uint64_t start_time;
uint64_t end_time;
} prof_event_t;
typedef struct alignas(8) {
uint32_t allocator_id;
uint32_t allocation_size;
} mem_prof_event_t;
typedef struct alignas(8) {
char name[PROF_NAME_MAX_LEN];
uint64_t allocator_id;
} prof_allocator_t;
typedef struct alignas(8) {
uint8_t* prof_data;
uint32_t num_bytes;
uint32_t num_blocks;
} prof_result_t;
typedef struct alignas(8) {
char name[32];
uint32_t prof_ver;
uint32_t max_prof_entries;
uint32_t prof_entries;
uint32_t max_allocator_entries;
uint32_t allocator_entries;
uint32_t max_mem_prof_entries;
uint32_t mem_prof_entries;
} prof_header_t;
constexpr uint32_t prof_buf_size = sizeof(prof_header_t) +
sizeof(prof_event_t) * MAX_PROFILE_EVENTS +
sizeof(mem_prof_event_t) * MAX_MEM_PROFILE_EVENTS +
sizeof(prof_allocator_t) * MEM_PROFILE_MAX_ALLOCATORS;
constexpr size_t prof_header_offset = 0;
constexpr size_t prof_events_offset = sizeof(prof_header_t);
constexpr size_t prof_mem_alloc_info_offset =
prof_events_offset + sizeof(prof_event_t) * MAX_PROFILE_EVENTS;
constexpr size_t prof_mem_alloc_events_offset = prof_mem_alloc_info_offset +
sizeof(prof_allocator_t) * MEM_PROFILE_MAX_ALLOCATORS;
void profiler_init(void);
uint32_t begin_profiling(const char* name);
void end_profiling(uint32_t token_id);
void dump_profile_stats(prof_result_t* prof_result);
void reset_profile_stats();
void track_allocation(int32_t id, uint32_t size);
uint32_t track_allocator(const char* name);
void profiling_create_block(const char* name);
class ExecutorchProfiler {
public:
explicit ExecutorchProfiler(const char* name);
~ExecutorchProfiler();
private:
uint32_t prof_tok;
};
typedef struct {
int32_t chain_idx;
uint32_t instruction_idx;
} prof_state_t;
const prof_state_t& get_profile_tls_state();
void set_profile_tls_state(const prof_state_t& state);
class ExecutorchProfilerInstructionScope {
public:
explicit ExecutorchProfilerInstructionScope(const prof_state_t& state);
~ExecutorchProfilerInstructionScope();
ExecutorchProfilerInstructionScope(
const ExecutorchProfilerInstructionScope&) = delete;
ExecutorchProfilerInstructionScope& operator=(
const ExecutorchProfilerInstructionScope&) = delete;
ExecutorchProfilerInstructionScope(ExecutorchProfilerInstructionScope&&) =
delete;
ExecutorchProfilerInstructionScope& operator=(
ExecutorchProfilerInstructionScope&&) = delete;
private:
prof_state_t old_state_;
};
} }
namespace torch {
namespace executor {
using ::executorch::runtime::begin_profiling;
using ::executorch::runtime::dump_profile_stats;
using ::executorch::runtime::end_profiling;
using ::executorch::runtime::ExecutorchProfiler;
using ::executorch::runtime::ExecutorchProfilerInstructionScope;
using ::executorch::runtime::get_profile_tls_state;
using ::executorch::runtime::mem_prof_event_t;
using ::executorch::runtime::prof_allocator_t;
using ::executorch::runtime::prof_buf_size;
using ::executorch::runtime::prof_event_t;
using ::executorch::runtime::prof_events_offset;
using ::executorch::runtime::prof_header_offset;
using ::executorch::runtime::prof_header_t;
using ::executorch::runtime::prof_mem_alloc_events_offset;
using ::executorch::runtime::prof_mem_alloc_info_offset;
using ::executorch::runtime::prof_result_t;
using ::executorch::runtime::prof_state_t;
using ::executorch::runtime::profiler_init;
using ::executorch::runtime::profiling_create_block;
using ::executorch::runtime::reset_profile_stats;
using ::executorch::runtime::set_profile_tls_state;
using ::executorch::runtime::track_allocation;
using ::executorch::runtime::track_allocator;
} }
#ifdef PROFILING_ENABLED
#define EXECUTORCH_PROFILE_CREATE_BLOCK(name) \
::executorch::runtime::profiling_create_block(name);
#define EXECUTORCH_BEGIN_PROF(name) \
::executorch::runtime::begin_profiling(name);
#define EXECUTORCH_END_PROF(token_id) \
::executorch::runtime::end_profiling(token_id);
#define EXECUTORCH_SCOPE_PROF_CONCAT_IMPL(a, b) a##b
#define EXECUTORCH_SCOPE_PROF_CONCAT(a, b) \
EXECUTORCH_SCOPE_PROF_CONCAT_IMPL(a, b)
#define EXECUTORCH_SCOPE_PROF(name) \
::executorch::runtime::ExecutorchProfiler EXECUTORCH_SCOPE_PROF_CONCAT( \
et_profiler_, __LINE__)(name);
#define EXECUTORCH_PROFILE_INSTRUCTION_SCOPE(chain_idx, instruction_idx) \
::executorch::runtime::ExecutorchProfilerInstructionScope \
__profiler_instruction_scope({chain_idx, instruction_idx});
#define EXECUTORCH_DUMP_PROFILE_RESULTS(prof_result) \
::executorch::runtime::dump_profile_stats(prof_result);
#define EXECUTORCH_RESET_PROFILE_RESULTS() \
::executorch::runtime::reset_profile_stats();
#define EXECUTORCH_TRACK_ALLOCATOR(name) \
::executorch::runtime::track_allocator(name);
#define EXECUTORCH_TRACK_ALLOCATION(id, size) \
::executorch::runtime::track_allocation(id, size);
#else
#define EXECUTORCH_PROFILE_CREATE_BLOCK(name) \
do { \
(void)(name); \
} while (0)
#define EXECUTORCH_BEGIN_PROF(name) \
{}
#define EXECUTORCH_END_PROF(token_id) \
do { \
(void)(token_id); \
} while (0)
#define EXECUTORCH_SCOPE_PROF(name) \
do { \
(void)(name); \
} while (0)
#define EXECUTORCH_PROFILE_INSTRUCTION_SCOPE(chain_idx, instruction_idx) \
do { \
(void)(chain_idx); \
(void)(instruction_idx); \
} while (0)
#define EXECUTORCH_DUMP_PROFILE_RESULTS(prof_result_test) \
memset(prof_result_test, 0, sizeof(::executorch::runtime::prof_result_t));
#define EXECUTORCH_RESET_PROFILE_RESULTS() \
{}
#define EXECUTORCH_TRACK_ALLOCATOR(name) ((void)(name), -1)
#define EXECUTORCH_TRACK_ALLOCATION(id, size) \
do { \
(void)(id); \
(void)(size); \
} while (0)
#endif