Integrated perfetto + roctracer (#5)
- hosttrace library automatically collects and merges timestamps for HIP API calls and kernels with the host-side instrumentation
- mostly eliminates the need for using external rocprof
- added thread_instruction_count in perfetto output
- increased hosttrace min_loop_address_range to 512
- disabled instrumenting functions with dynamic callsites by default
- miscellaneous cmake updates
* roctracer support
- fully integrated perfetto + roctracer outputs
- thread_instruction_count in perfetto
- increased min_loop_address_range to 512
- disabled instrumenting functions with dynamic callsites by default
- updated timemory submodule
* hosttrace_launch_compiler
- support for using an alternative compiler as needed via launch compiler
- elfio added as submodule (not currently used)
- miscellaneous cmake updates
* README update + host/device categories + misc
- timemory fix for TIMEMORY_ROCTRACER_ENABLED
- transpose fix
* papi_tuple_t -> papi_tot_ins
- minor fix to Findroctracer.cmake
[ROCm/rocprofiler-systems commit: a061b7947f]
Tá an tiomantas seo le fáil i:
tiomanta ag
GitHub
tuismitheoir
7435122726
tiomantas
244b308cb5
@@ -396,9 +396,6 @@ struct module_function
|
||||
std::pair<address_t, address_t> _range{};
|
||||
if(proc->getAddressRange(_range.first, _range.second))
|
||||
address_range = _range.second - _range.first;
|
||||
auto _instructions = proc->findPoint(BPatch_locInstruction);
|
||||
if(_instructions)
|
||||
instr_count = _instructions->size();
|
||||
}
|
||||
|
||||
friend bool operator<(const module_function& lhs, const module_function& rhs)
|
||||
@@ -418,7 +415,6 @@ struct module_function
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::setw(14) << "AddressRange"
|
||||
<< " " << std::setw(14) << "InstrCount"
|
||||
<< " " << std::setw(w0 + 8) << std::left << "Module"
|
||||
<< " " << std::setw(w1 + 8) << std::left << "Function"
|
||||
<< " " << std::setw(w2 + 8) << std::left << "FunctionSignature"
|
||||
@@ -442,7 +438,6 @@ struct module_function
|
||||
|
||||
// clang-format off
|
||||
ss << std::setw(14) << rhs.address_range << " "
|
||||
<< std::setw(14) << rhs.instr_count << " "
|
||||
<< std::setw(w0 + 8) << std::left << _get_str(rhs.module) << " "
|
||||
<< std::setw(w1 + 8) << std::left << _get_str(rhs.function) << " "
|
||||
<< std::setw(w2 + 8) << std::left << _get_str(rhs.signature.get());
|
||||
@@ -453,7 +448,6 @@ struct module_function
|
||||
}
|
||||
|
||||
size_t address_range = 0;
|
||||
size_t instr_count = 0;
|
||||
string_t module = {};
|
||||
string_t function = {};
|
||||
function_signature signature;
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
#if !defined(TIMEMORY_USE_PERFETTO)
|
||||
# include <perfetto.h>
|
||||
# define PERFETTO_CATEGORIES \
|
||||
perfetto::Category("hosttrace").SetDescription("Function trace")
|
||||
perfetto::Category("host").SetDescription("Host-side function tracing"), \
|
||||
perfetto::Category("device").SetDescription("Device-side function tracing")
|
||||
#else
|
||||
# define PERFETTO_CATEGORIES \
|
||||
perfetto::Category("hosttrace").SetDescription("Function trace"), \
|
||||
perfetto::Category("timemory") \
|
||||
.SetDescription("Events from the timemory API")
|
||||
perfetto::Category("host").SetDescription("Host-side function tracing"), \
|
||||
perfetto::Category("device").SetDescription("Device-side function tracing")
|
||||
perfetto::Category("timemory")
|
||||
.SetDescription("Events from the timemory API")
|
||||
# define TIMEMORY_PERFETTO_CATEGORIES PERFETTO_CATEGORIES
|
||||
#endif
|
||||
|
||||
@@ -42,6 +44,8 @@
|
||||
#include "timemory/storage.hpp"
|
||||
#include "timemory/variadic.hpp"
|
||||
|
||||
#include "roctracer.hpp"
|
||||
|
||||
// forward decl of the API
|
||||
extern "C"
|
||||
{
|
||||
@@ -74,6 +78,11 @@ namespace audit = tim::audit;
|
||||
namespace comp = tim::component;
|
||||
namespace quirk = tim::quirk;
|
||||
namespace threading = tim::threading;
|
||||
namespace scope = tim::scope;
|
||||
namespace dmp = tim::dmp;
|
||||
namespace process = tim::process;
|
||||
namespace units = tim::units;
|
||||
namespace trait = tim::trait;
|
||||
|
||||
// this is used to wrap fork()
|
||||
struct fork_gotcha : comp::base<fork_gotcha, void>
|
||||
@@ -122,12 +131,16 @@ private:
|
||||
const char* m_prefix = nullptr;
|
||||
};
|
||||
|
||||
using papi_tot_ins = comp::papi_tuple<PAPI_TOT_INS>;
|
||||
using fork_gotcha_t = comp::gotcha<4, tim::component_tuple<fork_gotcha>, hosttrace>;
|
||||
using mpi_gotcha_t = comp::gotcha<4, tim::component_tuple<mpi_gotcha>, hosttrace>;
|
||||
using hosttrace_bundle_t =
|
||||
tim::lightweight_tuple<comp::wall_clock, comp::peak_rss, comp::cpu_clock,
|
||||
comp::cpu_util, comp::user_global_bundle, fork_gotcha_t,
|
||||
mpi_gotcha_t>;
|
||||
comp::cpu_util, comp::roctracer, papi_tot_ins,
|
||||
comp::user_global_bundle, fork_gotcha_t, mpi_gotcha_t>;
|
||||
using hosttrace_thread_bundle_t =
|
||||
tim::lightweight_tuple<comp::wall_clock, comp::thread_cpu_clock,
|
||||
comp::thread_cpu_util, papi_tot_ins>;
|
||||
using bundle_t =
|
||||
tim::component_bundle<hosttrace, comp::wall_clock*, comp::user_global_bundle*>;
|
||||
using bundle_allocator_t = tim::data::ring_buffer_allocator<bundle_t>;
|
||||
@@ -190,6 +203,54 @@ get_state();
|
||||
std::unique_ptr<hosttrace_bundle_t>&
|
||||
get_main_bundle();
|
||||
|
||||
bool
|
||||
get_use_perfetto();
|
||||
|
||||
bool
|
||||
get_use_timemory();
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <typename Tp, size_t MaxThreads = 1024>
|
||||
struct hosttrace_thread_data
|
||||
{
|
||||
static constexpr size_t max_supported_threads = MaxThreads;
|
||||
using instance_array_t = std::array<std::unique_ptr<Tp>, max_supported_threads>;
|
||||
|
||||
template <typename... Args>
|
||||
static void construct(Args&&...);
|
||||
static std::unique_ptr<Tp>& instance();
|
||||
static instance_array_t& instances();
|
||||
};
|
||||
|
||||
template <typename Tp, size_t MaxThreads>
|
||||
template <typename... Args>
|
||||
void
|
||||
hosttrace_thread_data<Tp, MaxThreads>::construct(Args&&... _args)
|
||||
{
|
||||
static thread_local bool _v = [&_args...]() {
|
||||
instances().at(threading::get_id()) =
|
||||
std::make_unique<Tp>(std::forward<Args>(_args)...);
|
||||
return true;
|
||||
}();
|
||||
(void) _v;
|
||||
}
|
||||
|
||||
template <typename Tp, size_t MaxThreads>
|
||||
std::unique_ptr<Tp>&
|
||||
hosttrace_thread_data<Tp, MaxThreads>::instance()
|
||||
{
|
||||
return instances().at(threading::get_id());
|
||||
}
|
||||
|
||||
template <typename Tp, size_t MaxThreads>
|
||||
typename hosttrace_thread_data<Tp, MaxThreads>::instance_array_t&
|
||||
hosttrace_thread_data<Tp, MaxThreads>::instances()
|
||||
{
|
||||
static auto _v = instance_array_t{};
|
||||
return _v;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// there are currently some strange things that happen with vector<bundle_t> so using
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "timemory/api.hpp"
|
||||
#include "timemory/components/base.hpp"
|
||||
#include "timemory/components/data_tracker/components.hpp"
|
||||
#include "timemory/components/macros.hpp"
|
||||
#include "timemory/enum.h"
|
||||
#include "timemory/macros/os.hpp"
|
||||
#include "timemory/mpl/type_traits.hpp"
|
||||
#include "timemory/mpl/types.hpp"
|
||||
|
||||
TIMEMORY_DECLARE_COMPONENT(roctracer)
|
||||
|
||||
#if !defined(HOSTTRACE_USE_ROCTRACER)
|
||||
TIMEMORY_DEFINE_CONCRETE_TRAIT(is_available, component::roctracer, false_type)
|
||||
#endif
|
||||
|
||||
namespace tim
|
||||
{
|
||||
namespace component
|
||||
{
|
||||
using roctracer_data = data_tracker<double, roctracer>;
|
||||
|
||||
struct roctracer
|
||||
: base<roctracer, void>
|
||||
, private policy::instance_tracker<roctracer, false>
|
||||
{
|
||||
using value_type = void;
|
||||
using base_type = base<roctracer, void>;
|
||||
using tracker_type = policy::instance_tracker<roctracer, false>;
|
||||
|
||||
TIMEMORY_DEFAULT_OBJECT(roctracer)
|
||||
|
||||
static void setup();
|
||||
static void tear_down();
|
||||
static void preinit();
|
||||
static void global_init() { setup(); }
|
||||
static void global_finalize() { tear_down(); }
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void set_prefix(const char* _v) { m_prefix = _v; }
|
||||
|
||||
private:
|
||||
const char* m_prefix = nullptr;
|
||||
};
|
||||
} // namespace component
|
||||
} // namespace tim
|
||||
|
||||
TIMEMORY_SET_COMPONENT_API(component::roctracer_data, project::timemory, category::timing,
|
||||
os::supports_unix)
|
||||
TIMEMORY_DEFINE_CONCRETE_TRAIT(is_timing_category, component::roctracer_data, true_type)
|
||||
TIMEMORY_DEFINE_CONCRETE_TRAIT(uses_timing_units, component::roctracer_data, true_type)
|
||||
|
||||
#include "timemory/operations.hpp"
|
||||
|
||||
TIMEMORY_DECLARE_EXTERN_COMPONENT(roctracer, false, void)
|
||||
TIMEMORY_DECLARE_EXTERN_COMPONENT(roctracer_data, true, double)
|
||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir