Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ Additional configuration options to control the tracing behavior include:
- ``ROCPROFSYS_TRACE_PERIODS`` (``--trace-periods``): Specifies multiple delay/duration periods in the format ``<DELAY>:<DURATION>``, ``<DELAY>:<DURATION>:<REPEAT>``, or ``<DELAY>:<DURATION>:<REPEAT>:<CLOCK_ID>``.
- ``ROCPROFSYS_TRACE_PERIOD_CLOCK_ID`` (``--trace-clock-id``): Clock type for timing, either ``realtime`` (default) or ``cputime``.

The trace-period clock controls only when collection starts and stops. All CPU and GPU events stored on the trace timeline use ``CLOCK_BOOTTIME``.

Profile mode
^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(control_headers
${CMAKE_CURRENT_LIST_DIR}/clock.hpp
${CMAKE_CURRENT_LIST_DIR}/clocks/posix.hpp
${CMAKE_CURRENT_LIST_DIR}/clocks/steady.hpp
${CMAKE_CURRENT_LIST_DIR}/clocks/timeline.hpp
${CMAKE_CURRENT_LIST_DIR}/session.hpp
${CMAKE_CURRENT_LIST_DIR}/triggers/roctx.hpp
${CMAKE_CURRENT_LIST_DIR}/triggers/time_window.hpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
namespace rocprofsys::control::clocks
{
/// Clock backed by a POSIX clock (clock_gettime / clock_nanosleep).
/// Used for time-window delay/duration sleeps, not absolute event stamps.
class posix
{
public:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Advanced Micro Devices, Inc.
// SPDX-License-Identifier: MIT

#pragma once

#include <chrono>
#include <cstdint>
#include <ctime>
#include <time.h>

namespace rocprofsys::control::clocks
{
/// Absolute timeline clock for CPU and call-stack event stamps.
/// Matches the host domain used by rocprofiler-sdk (`CLOCK_BOOTTIME`).
[[nodiscard]] inline bool
timeline_available() noexcept
{
struct timespec specs = {};
return clock_gettime(CLOCK_BOOTTIME, &specs) == 0;
}

[[nodiscard]] inline std::chrono::nanoseconds
timeline_now() noexcept
{
struct timespec specs = {};
if(clock_gettime(CLOCK_BOOTTIME, &specs) != 0)
{
return std::chrono::nanoseconds::zero();
}
return std::chrono::seconds{ specs.tv_sec } +
std::chrono::nanoseconds{ specs.tv_nsec };
}

template <typename Tp = std::uint64_t>
[[nodiscard]] inline Tp
timeline_ns() noexcept
{
return static_cast<Tp>(timeline_now().count());
}
} // namespace rocprofsys::control::clocks
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ target_include_directories(
PRIVATE ${PROJECT_SOURCE_DIR}/source/lib ${CMAKE_BINARY_DIR}/source/lib
)

add_library(control-timeline-clock-tests OBJECT test_timeline.cpp)

target_link_libraries(
control-timeline-clock-tests
PRIVATE
rocprofiler-systems-googletest-library
rocprofiler-systems-core-library
rocprofiler-systems-common-library
rocprofiler-systems-logger
)

target_include_directories(
control-timeline-clock-tests
PRIVATE ${PROJECT_SOURCE_DIR}/source/lib ${CMAKE_BINARY_DIR}/source/lib
)

add_library(control-steady-clock-tests OBJECT test_steady_clock.cpp)

target_link_libraries(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@

#include "core/control/clock.hpp"
#include "core/control/triggers/time_window.hpp"
#include <memory>

#include <atomic>
#include <chrono>
#include <gtest/gtest.h>
#include <string>
#include <memory>
#include <thread>

namespace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Advanced Micro Devices, Inc.
// SPDX-License-Identifier: MIT

#include "core/control/clocks/timeline.hpp"

#include <cstdint>
#include <gtest/gtest.h>
#include <ratio>
#include <time.h>

namespace
{
using rocprofsys::control::clocks::timeline_available;
using rocprofsys::control::clocks::timeline_now;
using rocprofsys::control::clocks::timeline_ns;

std::uint64_t
read_boottime_ns()
{
timespec specs{};
EXPECT_EQ(clock_gettime(CLOCK_BOOTTIME, &specs), 0);
return static_cast<std::uint64_t>(specs.tv_sec) * std::nano::den +
static_cast<std::uint64_t>(specs.tv_nsec);
}
} // namespace

TEST(timeline_clock_test, available_on_linux) { EXPECT_TRUE(timeline_available()); }

TEST(timeline_clock_test, uses_clock_boottime)
{
ASSERT_TRUE(timeline_available());
const auto before_duration = read_boottime_ns();
const auto now_duration = timeline_now();
const auto after_duration = read_boottime_ns();
EXPECT_LE(before_duration, static_cast<std::uint64_t>(now_duration.count()));
EXPECT_LE(static_cast<std::uint64_t>(now_duration.count()), after_duration);

const auto before_ns = read_boottime_ns();
const auto now_ns = timeline_ns();
const auto after_ns = read_boottime_ns();
EXPECT_LE(before_ns, now_ns);
EXPECT_LE(now_ns, after_ns);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "core/config/trace_period_config.hpp"
#include "core/control/clocks/posix.hpp"
#include "core/control/clocks/steady.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/control/session.hpp"
#include "core/control/triggers/time_window.hpp"
#include "core/cpu.hpp"
Expand Down Expand Up @@ -1058,7 +1059,7 @@ rocprofsys_init_hidden(const char* _mode, bool _is_binary_rewrite, const char* _
}
});

set_metadata_process_start_timestamp(comp::wall_clock::record());
set_metadata_process_start_timestamp(control::clocks::timeline_ns<std::int64_t>());

if(get_debug_env() || get_verbose_env() > 2)
{
Expand Down Expand Up @@ -1129,7 +1130,7 @@ rocprofsys_finalize_hidden(void)
return;
}

set_metadata_process_end_timestamp(comp::wall_clock::record());
set_metadata_process_end_timestamp(control::clocks::timeline_ns<std::int64_t>());

if(_is_child)
{
Expand Down Expand Up @@ -1160,7 +1161,7 @@ rocprofsys_finalize_hidden(void)

sampling::block_samples();

thread_info::set_stop(comp::wall_clock::record());
thread_info::set_stop(control::clocks::timeline_ns());

tim::signals::block_signals(get_sampling_signals(),
tim::signals::sigmask_scope::process);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// SPDX-License-Identifier: MIT

#include "library/components/backtrace_timestamp.hpp"
#include "core/control/clocks/timeline.hpp"
#include "library/thread_info.hpp"
#include <cstdint>

#include <timemory/components/timing/backends.hpp>

namespace rocprofsys::component
{
bool
Expand All @@ -26,7 +25,7 @@ void
backtrace_timestamp::sample(int)
{
m_tid = tim::threading::get_id();
m_real = tim::get_clock_real_now<std::uint64_t, std::nano>();
m_real = control::clocks::timeline_ns();
}
} // namespace rocprofsys::component

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common/defines.h"
#include "core/common_types.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/demangler.hpp"
#include "core/state.hpp"
#include "core/timemory.hpp"
Expand Down Expand Up @@ -86,10 +87,7 @@ inline constexpr std::size_t renumber_growth_slack = 16;

struct wall_clock_source
{
timestamp_t now() const
{
return static_cast<timestamp_t>(rocprofsys::comp::wall_clock::record());
}
[[nodiscard]] timestamp_t now() const { return control::clocks::timeline_ns(); }
};

struct trace_cache_region_sink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "library/components/pthread_create_gotcha.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/locking.hpp"
#include "core/state.hpp"
#include "core/utility.hpp"
Expand Down Expand Up @@ -221,7 +222,7 @@ pthread_create_gotcha::wrapper::operator()() const
{
return;
}
thread_info::set_stop(comp::wall_clock::record());
thread_info::set_stop(control::clocks::timeline_ns());
auto& _thr_bundle = thread_bundle_data_t::instance();
if(_thr_bundle && _thr_bundle->get<comp::wall_clock>() &&
_thr_bundle->get<comp::wall_clock>()->get_is_running())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "core/agent_manager.hpp"
#include "core/components/fwd.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/node_info.hpp"
#include "core/perfetto.hpp"
#include "core/trace_cache/cache_manager.hpp"
Expand Down Expand Up @@ -762,7 +763,7 @@ extern "C"
return;
}

auto const timestamp = tim::get_clock_real_now<std::uint64_t, std::nano>();
auto const timestamp = rocprofsys::control::clocks::timeline_ns();

auto const _thread_state_guard =
rocprofsys::state::thread::scoped(rocprofsys::state::thread::Internal);
Expand Down Expand Up @@ -796,7 +797,7 @@ extern "C"
return;
}

auto const timestamp = tim::get_clock_real_now<std::uint64_t, std::nano>();
auto const timestamp = rocprofsys::control::clocks::timeline_ns();
auto const _thread_state_guard =
rocprofsys::state::thread::scoped(rocprofsys::state::thread::Internal);
if(rocprofsys::config::get_use_perfetto())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ perf_event::open(double freq, std::uint32_t batch_size, pid_t pid, int cpu)
perf_event_a.exclude_callchain_kernel = 1;
perf_event_a.use_clockid = 1;
// NOLINTNEXTLINE
perf_event_a.clockid = CLOCK_REALTIME;
perf_event_a.clockid = CLOCK_BOOTTIME;

return open(perf_event_a, pid, cpu);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// and ROCPROFSYS_USE_AINIC before any header gates code on that macro.
#include "backends/amd_smi/ainic_feature.hpp"

#include "core/control/clocks/timeline.hpp"
#include "library/pmc/collectors/common/collector_slice.hpp"
#include "library/pmc/collectors/common/settings.hpp"
#include "library/pmc/collectors/gpu/cache_policy.hpp"
Expand Down Expand Up @@ -301,8 +302,7 @@ sample()
return;
}

auto timestamp =
static_cast<std::int64_t>(tim::get_clock_real_now<size_t, std::nano>());
auto timestamp = control::clocks::timeline_ns<std::int64_t>();

for(auto& slice : g_collector_slices)
{
Expand Down Expand Up @@ -405,8 +405,7 @@ post_process()
void
pause()
{
const auto timestamp =
static_cast<std::int64_t>(tim::get_clock_real_now<size_t, std::nano>());
const auto timestamp = control::clocks::timeline_ns<std::int64_t>();

// sample() holds this lock for a whole AMD SMI sweep, and the caller is an
// application thread leaving a traced region. Hand the timestamp to the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "core/common.hpp"
#include "core/components/fwd.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/demangler.hpp"
#include "core/locking.hpp"
#include "core/node_info.hpp"
Expand Down Expand Up @@ -795,11 +796,11 @@ configure(bool _setup, std::int64_t _tid)
_pe.disabled = 1;
_pe.inherit = 0;

if(_pe.type == PERF_TYPE_SOFTWARE)
{
_pe.use_clockid = 1;
_pe.clockid = CLOCK_REALTIME;
}
// Hardware events are the default overflow source. Their sample times
// otherwise stay on perf's CLOCK_MONOTONIC, and parse_overflow_data()
// freezes the monotonic-to-timeline offset from the first sample.
_pe.use_clockid = 1;
_pe.clockid = CLOCK_BOOTTIME;
Comment thread
sputhala-amd marked this conversation as resolved.
Resolved

auto _perf_open_error =
_perf_sampler->open(_pe, _info->index_data->system_value);
Expand Down Expand Up @@ -2112,7 +2113,7 @@ pause()
}

LOG_DEBUG("Pausing sampling...");
pending_pause_ts.store(tim::get_clock_real_now<std::uint64_t, std::nano>());
pending_pause_ts.store(control::clocks::timeline_ns());
block_samples();
set_sampler_timers(timer_state::stopped);
}
Expand All @@ -2130,13 +2131,13 @@ resume()
}

LOG_DEBUG("Resuming sampling...");
auto const _pause_ts = pending_pause_ts.exchange(0);
auto const _resume_ts = tim::get_clock_real_now<std::uint64_t, std::nano>();
if(_pause_ts > 0)
auto const pause_ts = pending_pause_ts.exchange(0);
auto const resume_ts = control::clocks::timeline_ns();
if(pause_ts > 0)
{
auto const _lk = std::lock_guard<std::mutex>{ pause_mutex };
pause_intervals.push_back(
pause_interval_t{ .pause_ts = _pause_ts, .resume_ts = _resume_ts });
pause_interval_t{ .pause_ts = pause_ts, .resume_ts = resume_ts });
}

set_sampler_timers(timer_state::running);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "core/common.hpp"
#include "core/concepts.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/state.hpp"
#include "core/utility.hpp"
#include "library/causal/delay.hpp"
Expand All @@ -13,7 +14,6 @@
#include "library/thread_data_growth.hpp"

#include <timemory/backends/threading.hpp>
#include <timemory/components/timing/backends.hpp>
#include <timemory/process/threading.hpp>

#include "logger/debug.hpp"
Expand Down Expand Up @@ -202,7 +202,7 @@ thread_info::init(bool _offset)
_info = thread_info{};
_info->is_offset = threading::offset_this_id();
_info->index_data = init_index_data(_tid, _info->is_offset);
_info->lifetime.first = tim::get_clock_real_now<std::uint64_t, std::nano>();
_info->lifetime.first = control::clocks::timeline_ns();

const auto _sequent_tid = _info->index_data->sequent_value;
_info->causal_count = (!_info->is_offset && _sequent_tid < peak_num_threads)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "common/env_vars.hpp"
#include "core/concepts.hpp"
#include "core/config.hpp"
#include "core/control/clocks/timeline.hpp"
#include "core/perfetto/emitter.hpp"
#include "core/perfetto/engine.hpp"
#include "core/state.hpp"
Expand Down Expand Up @@ -166,7 +167,7 @@ record_thread_start_time()
{
static thread_local std::once_flag _once{};
std::call_once(_once, []() {
thread_info::set_start(comp::wall_clock::record(),
thread_info::set_start(control::clocks::timeline_ns(),
get_mode() != state::process::Mode::sampling);
});
}
Expand Down
Loading
Loading