Support external (i.e. user-defined) trace annotations (#195)
* Support external (i.e. user-defined) trace annotations
- tweaked the python examples to be more balanced
- updated the user-api example to conform to user API changes
- moved the get/set for State and ThreadState to state.{hpp,cpp}
- introduced user-provided trace annotations
- added perfetto python category
- moved coverage impl files around
- created enumerations for mapping category enums to category types
- created enumerations for mapping annotation type enums to annotation values
- moved tracing::add_perfetto_annotations to tracing/annotation.hpp
- utility make_index_sequence_range
- libomnitrace-dl: omnitrace_push_category_region
- libomnitrace-dl: omnitrace_pop_category_region
- libomnitrace-user: omnitrace_user_push_annotated_region
- libomnitrace-user: omnitrace_user_pop_annotated_region
- libpyomnitrace: support extra annotations via annotate_trace config value
- filename
- line
- last attempted instr in bytecode (lasti)
- argcount
- num local variables
- stacksize
- omnitrace-python: -a / --annotate-traces option
* tweak ubuntu-focal workflow
* Fix installation of omnitrace-user headers
* ubuntu-focal-codecov workflow update
- Install texinfo
* Update timemory submodule
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1b8f09aa2d
Коммит
642b6b95ca
@@ -23,7 +23,8 @@
|
||||
#include "libpyomnitrace.hpp"
|
||||
#include "dl.hpp"
|
||||
#include "library/coverage.hpp"
|
||||
#include "library/impl/coverage.hpp"
|
||||
#include "library/coverage/impl.hpp"
|
||||
#include "omnitrace/categories.h"
|
||||
#include "omnitrace/user.h"
|
||||
|
||||
#include <timemory/backends/process.hpp>
|
||||
@@ -179,6 +180,8 @@ using profiler_vec_t = std::vector<profiler_t>;
|
||||
using profiler_label_map_t = std::unordered_map<std::string, profiler_vec_t>;
|
||||
using profiler_index_map_t = std::unordered_map<uint32_t, profiler_label_map_t>;
|
||||
using strset_t = std::unordered_set<std::string>;
|
||||
using note_t = omnitrace_annotation_t;
|
||||
using annotations_t = std::array<note_t, 6>;
|
||||
//
|
||||
namespace
|
||||
{
|
||||
@@ -202,6 +205,7 @@ struct config
|
||||
bool include_line = false;
|
||||
bool include_filename = false;
|
||||
bool full_filepath = false;
|
||||
bool annotate_trace = false;
|
||||
int32_t ignore_stack_depth = 0;
|
||||
int32_t base_stack_depth = -1;
|
||||
int32_t verbose = 0;
|
||||
@@ -214,6 +218,12 @@ struct config
|
||||
strset_t exclude_functions = default_exclude_functions;
|
||||
strset_t exclude_filenames = default_exclude_filenames;
|
||||
std::vector<profiler_t> records = {};
|
||||
annotations_t annotations = { note_t{ "file", OMNITRACE_STRING, nullptr },
|
||||
note_t{ "line", OMNITRACE_INT32, nullptr },
|
||||
note_t{ "lasti", OMNITRACE_INT32, nullptr },
|
||||
note_t{ "argcount", OMNITRACE_INT32, nullptr },
|
||||
note_t{ "nlocals", OMNITRACE_INT32, nullptr },
|
||||
note_t{ "stacksize", OMNITRACE_INT32, nullptr } };
|
||||
};
|
||||
//
|
||||
inline config&
|
||||
@@ -233,6 +243,7 @@ get_config()
|
||||
_tmp->include_line = _instance->include_line;
|
||||
_tmp->include_filename = _instance->include_filename;
|
||||
_tmp->full_filepath = _instance->full_filepath;
|
||||
_tmp->annotate_trace = _instance->annotate_trace;
|
||||
_tmp->base_module_path = _instance->base_module_path;
|
||||
_tmp->restrict_functions = _instance->restrict_functions;
|
||||
_tmp->restrict_filenames = _instance->restrict_filenames;
|
||||
@@ -241,6 +252,7 @@ get_config()
|
||||
_tmp->exclude_functions = _instance->exclude_functions;
|
||||
_tmp->exclude_filenames = _instance->exclude_filenames;
|
||||
_tmp->verbose = _instance->verbose;
|
||||
_tmp->annotations = _instance->annotations;
|
||||
// if full filepath is specified, include filename is implied
|
||||
if(_tmp->full_filepath && !_tmp->include_filename) _tmp->include_filename = true;
|
||||
return _tmp;
|
||||
@@ -454,12 +466,29 @@ profiler_function(py::object pframe, const char* swhat, py::object arg)
|
||||
|
||||
static thread_local strset_t _labels{};
|
||||
const auto& _label_ref = *_labels.emplace(_label).first;
|
||||
auto _annotate = _config.annotate_trace;
|
||||
|
||||
// start function
|
||||
auto _profiler_call = [&]() {
|
||||
_config.records.emplace_back(
|
||||
[&_label_ref]() { omnitrace_pop_region(_label_ref.c_str()); });
|
||||
omnitrace_push_region(_label_ref.c_str());
|
||||
if(_annotate)
|
||||
{
|
||||
_config.annotations.at(0).value = const_cast<char*>(_full.c_str());
|
||||
_config.annotations.at(1).value = &frame->f_lineno;
|
||||
_config.annotations.at(2).value = &frame->f_lasti;
|
||||
_config.annotations.at(3).value = &frame->f_code->co_argcount;
|
||||
_config.annotations.at(4).value = &frame->f_code->co_nlocals;
|
||||
_config.annotations.at(5).value = &frame->f_code->co_stacksize;
|
||||
}
|
||||
|
||||
_config.records.emplace_back([&_label_ref, _annotate]() {
|
||||
omnitrace_pop_category_region(OMNITRACE_CATEGORY_PYTHON, _label_ref.c_str(),
|
||||
(_annotate) ? _config.annotations.data()
|
||||
: nullptr,
|
||||
_config.annotations.size());
|
||||
});
|
||||
omnitrace_push_category_region(OMNITRACE_CATEGORY_PYTHON, _label_ref.c_str(),
|
||||
(_annotate) ? _config.annotations.data() : nullptr,
|
||||
_config.annotations.size());
|
||||
};
|
||||
|
||||
// stop function
|
||||
@@ -554,6 +583,10 @@ generate(py::module& _pymod)
|
||||
CONFIGURATION_PROPERTY("full_filepath", bool,
|
||||
"Display the full filepath (instead of file basename)",
|
||||
get_config().full_filepath)
|
||||
CONFIGURATION_PROPERTY(
|
||||
"annotate_trace", bool,
|
||||
"Add detailed annotations to the trace about the executing function",
|
||||
get_config().annotate_trace)
|
||||
CONFIGURATION_PROPERTY("verbosity", int32_t, "Verbosity of the logging",
|
||||
get_config().verbose)
|
||||
|
||||
|
||||
@@ -220,6 +220,16 @@ def parse_args(args=None):
|
||||
default=_profiler_config.trace_c,
|
||||
help="Enable profiling C functions",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--annotate-trace",
|
||||
type=str2bool,
|
||||
nargs="?",
|
||||
metavar="BOOL",
|
||||
const=True,
|
||||
default=_profiler_config.annotate_trace,
|
||||
help="Enable perfetto debug annotations",
|
||||
)
|
||||
|
||||
return parser.parse_args(args)
|
||||
|
||||
@@ -322,6 +332,7 @@ def main():
|
||||
_profiler_config.exclude_modules = opts.module_exclude
|
||||
_profiler_config.restrict_functions = opts.function_restrict
|
||||
_profiler_config.restrict_modules = opts.module_restrict
|
||||
_profiler_config.annotate_trace = opts.annotate_trace
|
||||
_profiler_config.verbosity = opts.verbosity
|
||||
|
||||
print("[omnitrace]> profiling: {}".format(argv))
|
||||
|
||||
Ссылка в новой задаче
Block a user