From 3ce98d33d4c5a72d368a7f7d64c2abc9efc151e0 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 30 Apr 2020 02:38:18 -0500 Subject: [PATCH] get_time API: make public; extende with more time id: coarse and raw; added time error return value; Change-Id: I1641eb2c38915222204617e07fc0bfb388bb8346 --- inc/rocprofiler.h | 8 +++++-- src/core/rocprofiler.cpp | 33 ++++++++++++++++---------- src/util/hsa_rsrc_factory.cpp | 5 ++-- src/util/hsa_rsrc_factory.h | 27 ++++++++++++++++++---- test/app/standalone_test.cpp | 42 ++++++++++++++++++++++++++++++++++ test/util/hsa_rsrc_factory.cpp | 9 ++++---- test/util/hsa_rsrc_factory.h | 29 ++++++++++++++++++----- 7 files changed, 122 insertions(+), 31 deletions(-) diff --git a/inc/rocprofiler.h b/inc/rocprofiler.h index 5889432510..fac482eaf9 100644 --- a/inc/rocprofiler.h +++ b/inc/rocprofiler.h @@ -210,14 +210,18 @@ hsa_status_t rocprofiler_get_agent(rocprofiler_t* context, // [in] profil // Supported time value ID typedef enum { ROCPROFILER_TIME_ID_CLOCK_REALTIME = 0, // Linux realtime clock time - ROCPROFILER_TIME_ID_CLOCK_MONOTONIC = 1, // Linux monotonic clock time + ROCPROFILER_TIME_ID_CLOCK_REALTIME_COARSE = 1, // Linux realtime-coarse clock time + ROCPROFILER_TIME_ID_CLOCK_MONOTONIC = 2, // Linux monotonic clock time + ROCPROFILER_TIME_ID_CLOCK_MONOTONIC_COARSE = 3, // Linux monotonic-coarse clock time + ROCPROFILER_TIME_ID_CLOCK_MONOTONIC_RAW = 4, // Linux monotonic-raw clock time } rocprofiler_time_id_t; // Return time value for a given time ID and profiling timestamp hsa_status_t rocprofiler_get_time( rocprofiler_time_id_t time_id, // identifier of the particular time to convert the timesatmp uint64_t timestamp, // profiling timestamp - uint64_t* value_ns); // [out] returned time 'ns' value + uint64_t* value_ns, // [out] returned time 'ns' value, ignored if NULL + uint64_t* error_ns); // [out] returned time error 'ns' value, ignored if NULL //////////////////////////////////////////////////////////////////////////////// // Queue callbacks diff --git a/src/core/rocprofiler.cpp b/src/core/rocprofiler.cpp index 00990e1058..1840bbdc1b 100644 --- a/src/core/rocprofiler.cpp +++ b/src/core/rocprofiler.cpp @@ -843,7 +843,7 @@ PUBLIC_API hsa_status_t rocprofiler_iterate_info( uint32_t block_counters; profile.events = &(counters_vec[0]->event); status = rocprofiler::util::HsaRsrcFactory::Instance().AqlProfileApi()->hsa_ven_amd_aqlprofile_get_info( - &profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters); + &profile, HSA_VEN_AMD_AQLPROFILE_INFO_BLOCK_COUNTERS, &block_counters); if (status != HSA_STATUS_SUCCESS) continue; info.metric.instances = query.instance_count; @@ -898,24 +898,36 @@ PUBLIC_API hsa_status_t rocprofiler_queue_create_profiled( void* data, uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue) { - return rocprofiler::InterceptQueue::QueueCreateTracked(agent, size, type, callback, data, private_segment_size, group_segment_size, queue); + API_METHOD_PREFIX + status = rocprofiler::InterceptQueue::QueueCreateTracked( + agent, size, type, callback, data, private_segment_size, group_segment_size, queue); + API_METHOD_SUFFIX } // Return time value for a given time ID and profiling timestamp -hsa_status_t rocprofiler_get_time( +PUBLIC_API hsa_status_t rocprofiler_get_time( rocprofiler_time_id_t time_id, uint64_t timestamp, - uint64_t* value_ns) + uint64_t* value_ns, + uint64_t* error_ns) { - return rocprofiler::util::HsaRsrcFactory::Instance().GetTime(time_id, timestamp, value_ns); + API_METHOD_PREFIX + if (error_ns != NULL) { + *error_ns = 0; + status = rocprofiler::util::HsaRsrcFactory::Instance().GetTimeErr(time_id, error_ns); + } + if ((status == HSA_STATUS_SUCCESS) && (value_ns != NULL)) { + *value_ns = 0; + status = rocprofiler::util::HsaRsrcFactory::Instance().GetTimeVal(time_id, timestamp, value_ns); + } + API_METHOD_SUFFIX } -// Set new callbacks. If a callback is NULL then it is disabled } // extern "C" +/////////////////////////////////////////////////////////////////////////////////////////////////// // HSA API callbacks routines - -// Static fields +// bool rocprofiler::HsaInterceptor::enable_ = false; thread_local bool rocprofiler::HsaInterceptor::recursion_ = false;; rocprofiler_hsa_callbacks_t rocprofiler::HsaInterceptor::callbacks_{}; @@ -923,13 +935,10 @@ rocprofiler::HsaInterceptor::arg_t rocprofiler::HsaInterceptor::arg_{}; hsa_ven_amd_loader_1_01_pfn_t rocprofiler::HsaInterceptor::LoaderApiTable{}; rocprofiler::HsaInterceptor::mutex_t rocprofiler::HsaInterceptor::mutex_; -extern "C" { // Set HSA callbacks. If a callback is NULL then it is disabled -PUBLIC_API hsa_status_t rocprofiler_set_hsa_callbacks(const rocprofiler_hsa_callbacks_t callbacks, void* arg) { +extern "C" PUBLIC_API hsa_status_t rocprofiler_set_hsa_callbacks(const rocprofiler_hsa_callbacks_t callbacks, void* arg) { API_METHOD_PREFIX rocprofiler::HsaInterceptor::SetCallbacks(callbacks, arg); rocprofiler::InterceptQueue::SetSubmitCallback(callbacks.submit, arg); API_METHOD_SUFFIX } -} // extern "C" - diff --git a/src/util/hsa_rsrc_factory.cpp b/src/util/hsa_rsrc_factory.cpp index 1a4cf6e70c..e42ca2c0a9 100644 --- a/src/util/hsa_rsrc_factory.cpp +++ b/src/util/hsa_rsrc_factory.cpp @@ -149,8 +149,9 @@ HsaRsrcFactory::HsaRsrcFactory(bool initialize_hsa) : initialize_hsa_(initialize // Time correlation const uint32_t corr_iters = 1000; - CorrelateTime(HsaTimer::TIME_ID_CLOCK_REALTIME, corr_iters); - CorrelateTime(HsaTimer::TIME_ID_CLOCK_MONOTONIC, corr_iters); + for (unsigned time_id = 0; time_id < HsaTimer::TIME_ID_NUMBER; time_id += 1) { + CorrelateTime((HsaTimer::time_id_t)time_id, corr_iters); + } // System timeout timeout_ = (timeout_ns_ == HsaTimer::TIMESTAMP_MAX) ? timeout_ns_ : timer_->ns_to_sysclock(timeout_ns_); diff --git a/src/util/hsa_rsrc_factory.h b/src/util/hsa_rsrc_factory.h index b0f11be73c..38f9ceb83b 100644 --- a/src/util/hsa_rsrc_factory.h +++ b/src/util/hsa_rsrc_factory.h @@ -183,7 +183,10 @@ class HsaTimer { enum time_id_t { TIME_ID_CLOCK_REALTIME = 0, - TIME_ID_CLOCK_MONOTONIC = 1, + TIME_ID_CLOCK_REALTIME_COARSE = 1, + TIME_ID_CLOCK_MONOTONIC = 2, + TIME_ID_CLOCK_MONOTONIC_COARSE = 3, + TIME_ID_CLOCK_MONOTONIC_RAW = 4, TIME_ID_NUMBER }; @@ -203,7 +206,7 @@ class HsaTimer { } // Method for timespec/ns conversion - timestamp_t timespec_to_ns(const timespec& time) const { + static timestamp_t timespec_to_ns(const timespec& time) { return ((timestamp_t)time.tv_sec * 1000000000) + time.tv_nsec; } @@ -227,13 +230,22 @@ class HsaTimer { void correlated_pair_ns(time_id_t time_id, uint32_t iters, timestamp_t* timestamp_v, timestamp_t* time_v, timestamp_t* error_v) { clockid_t clock_id = 0; - switch (clock_id) { + switch (time_id) { case TIME_ID_CLOCK_REALTIME: clock_id = CLOCK_REALTIME; break; + case TIME_ID_CLOCK_REALTIME_COARSE: + clock_id = CLOCK_REALTIME_COARSE; + break; case TIME_ID_CLOCK_MONOTONIC: clock_id = CLOCK_MONOTONIC; break; + case TIME_ID_CLOCK_MONOTONIC_COARSE: + clock_id = CLOCK_MONOTONIC_COARSE; + break; + case TIME_ID_CLOCK_MONOTONIC_RAW: + clock_id = CLOCK_MONOTONIC_RAW; + break; default: CHECK_STATUS("internal error: invalid time_id", HSA_STATUS_ERROR); } @@ -431,9 +443,14 @@ class HsaRsrcFactory { time_error_[time_id] = error_v; } - hsa_status_t GetTime(uint32_t time_id, uint64_t value, uint64_t* time) { + hsa_status_t GetTimeVal(uint32_t time_id, uint64_t time_stamp, uint64_t* time_value) { if (time_id >= HsaTimer::TIME_ID_NUMBER) return HSA_STATUS_ERROR; - *time = value + time_shift_[time_id]; + *time_value = time_stamp + time_shift_[time_id]; + return HSA_STATUS_SUCCESS; + } + + hsa_status_t GetTimeErr(uint32_t time_id, uint64_t* err) { + *err = time_error_[time_id]; return HSA_STATUS_SUCCESS; } diff --git a/test/app/standalone_test.cpp b/test/app/standalone_test.cpp index fbd1b1c8fd..34bc05ea80 100644 --- a/test/app/standalone_test.cpp +++ b/test/app/standalone_test.cpp @@ -31,8 +31,46 @@ THE SOFTWARE. #include "inc/rocprofiler.h" #include "dummy_kernel/dummy_kernel.h" #include "simple_convolution/simple_convolution.h" +#include "util/hsa_rsrc_factory.h" #include "util/test_assert.h" +// print time +void print_sys_time(clockid_t clock_id, rocprofiler_time_id_t time_id) { + HsaTimer::timestamp_t value_ns = 0; + HsaTimer::timestamp_t error_ns = 0; + HsaTimer::timestamp_t timestamp = 0; + + timespec tm_val; + clock_gettime(clock_id, &tm_val); + HsaTimer::timestamp_t tm_val_ns = HsaTimer::timespec_to_ns(tm_val); + + timestamp = HsaRsrcFactory::Instance().TimestampNs(); + hsa_status_t status = rocprofiler_get_time(time_id, timestamp, &value_ns, &error_ns); + TEST_STATUS(status == HSA_STATUS_SUCCESS); + + HsaTimer::timestamp_t timestamp1 = timestamp; + HsaTimer::timestamp_t value_ns1 = value_ns; + + printf("time-id(%d) ts_ns(%lu) orig_ns(%lu) time_ns(%lu) err_ns(%lu)\n", (int)time_id, timestamp, tm_val_ns, value_ns, error_ns); + + sleep(1); + + timestamp = HsaRsrcFactory::Instance().TimestampNs(); + status = rocprofiler_get_time(time_id, timestamp, &value_ns, NULL); + TEST_STATUS(status == HSA_STATUS_SUCCESS); + status = rocprofiler_get_time(time_id, timestamp, NULL, &error_ns); + TEST_STATUS(status == HSA_STATUS_SUCCESS); + status = rocprofiler_get_time(time_id, timestamp, NULL, NULL); + TEST_STATUS(status == HSA_STATUS_SUCCESS); + + HsaTimer::timestamp_t timestamp2 = timestamp; + HsaTimer::timestamp_t value_ns2 = value_ns; + + printf("time-id(%d) ts_ns(%lu) orig_ns(%lu) time_ns(%lu) err_ns(%lu)\n", (int)time_id, timestamp, tm_val_ns, value_ns, error_ns); + printf("ts-diff(%lu) tm-diff(%lu)\n", timestamp2 - timestamp1, value_ns2 - value_ns1); +} + +// print profiler features void print_features(rocprofiler_feature_t* feature, uint32_t feature_count) { for (rocprofiler_feature_t* p = feature; p < feature + feature_count; ++p) { std::cout << (p - feature) << ": " << p->name; @@ -176,5 +214,9 @@ int main() { status = rocprofiler_close(context); TEST_STATUS(status == HSA_STATUS_SUCCESS); + print_sys_time(CLOCK_REALTIME, ROCPROFILER_TIME_ID_CLOCK_REALTIME); + sleep(1); + print_sys_time(CLOCK_MONOTONIC, ROCPROFILER_TIME_ID_CLOCK_MONOTONIC); + return (ret_val) ? 0 : 1; } diff --git a/test/util/hsa_rsrc_factory.cpp b/test/util/hsa_rsrc_factory.cpp index e132a9e093..10f9fbc1e6 100644 --- a/test/util/hsa_rsrc_factory.cpp +++ b/test/util/hsa_rsrc_factory.cpp @@ -146,8 +146,9 @@ HsaRsrcFactory::HsaRsrcFactory(bool initialize_hsa) : initialize_hsa_(initialize // Time correlation const uint32_t corr_iters = 1000; - CorrelateTime(HsaTimer::TIME_ID_CLOCK_REALTIME, corr_iters); - CorrelateTime(HsaTimer::TIME_ID_CLOCK_MONOTONIC, corr_iters); + for (unsigned time_id = 0; time_id < HsaTimer::TIME_ID_NUMBER; time_id += 1) { + CorrelateTime((HsaTimer::time_id_t)time_id, corr_iters); + } // System timeout timeout_ = (timeout_ns_ == HsaTimer::TIMESTAMP_MAX) ? timeout_ns_ : timer_->ns_to_sysclock(timeout_ns_); @@ -692,14 +693,14 @@ uint64_t HsaRsrcFactory::Submit(hsa_queue_t* queue, const void* packet, size_t s return write_idx; } -const char* HsaRsrcFactory::GetKernelName(uint64_t addr) { +const char* HsaRsrcFactory::GetKernelNameRef(uint64_t addr) { std::lock_guard lck(mutex_); const auto it = symbols_map_->find(addr); if (it == symbols_map_->end()) { fprintf(stderr, "HsaRsrcFactory::kernel addr (0x%lx) is not found\n", addr); abort(); } - return strdup(it->second); + return it->second; } void HsaRsrcFactory::EnableExecutableTracking(HsaApiTable* table) { diff --git a/test/util/hsa_rsrc_factory.h b/test/util/hsa_rsrc_factory.h index 2edb0fd813..e857813b24 100644 --- a/test/util/hsa_rsrc_factory.h +++ b/test/util/hsa_rsrc_factory.h @@ -181,7 +181,10 @@ class HsaTimer { enum time_id_t { TIME_ID_CLOCK_REALTIME = 0, - TIME_ID_CLOCK_MONOTONIC = 1, + TIME_ID_CLOCK_REALTIME_COARSE = 1, + TIME_ID_CLOCK_MONOTONIC = 2, + TIME_ID_CLOCK_MONOTONIC_COARSE = 3, + TIME_ID_CLOCK_MONOTONIC_RAW = 4, TIME_ID_NUMBER }; @@ -201,7 +204,7 @@ class HsaTimer { } // Method for timespec/ns conversion - timestamp_t timespec_to_ns(const timespec& time) const { + static timestamp_t timespec_to_ns(const timespec& time) { return ((timestamp_t)time.tv_sec * 1000000000) + time.tv_nsec; } @@ -225,13 +228,22 @@ class HsaTimer { void correlated_pair_ns(time_id_t time_id, uint32_t iters, timestamp_t* timestamp_v, timestamp_t* time_v, timestamp_t* error_v) { clockid_t clock_id = 0; - switch (clock_id) { + switch (time_id) { case TIME_ID_CLOCK_REALTIME: clock_id = CLOCK_REALTIME; break; + case TIME_ID_CLOCK_REALTIME_COARSE: + clock_id = CLOCK_REALTIME_COARSE; + break; case TIME_ID_CLOCK_MONOTONIC: clock_id = CLOCK_MONOTONIC; break; + case TIME_ID_CLOCK_MONOTONIC_COARSE: + clock_id = CLOCK_MONOTONIC_COARSE; + break; + case TIME_ID_CLOCK_MONOTONIC_RAW: + clock_id = CLOCK_MONOTONIC_RAW; + break; default: CHECK_STATUS("internal error: invalid time_id", HSA_STATUS_ERROR); } @@ -394,7 +406,7 @@ class HsaRsrcFactory { // Enable executables loading tracking static bool IsExecutableTracking() { return executable_tracking_on_; } static void EnableExecutableTracking(HsaApiTable* table); - static const char* GetKernelName(uint64_t addr); + static const char* GetKernelNameRef(uint64_t addr); // Initialize HSA API table void static InitHsaApiTable(HsaApiTable* table); @@ -429,9 +441,14 @@ class HsaRsrcFactory { time_error_[time_id] = error_v; } - hsa_status_t GetTime(uint32_t time_id, uint64_t value, uint64_t* time) { + hsa_status_t GetTimeVal(uint32_t time_id, uint64_t time_stamp, uint64_t* time_value) { if (time_id >= HsaTimer::TIME_ID_NUMBER) return HSA_STATUS_ERROR; - *time = value + time_shift_[time_id]; + *time_value = time_stamp + time_shift_[time_id]; + return HSA_STATUS_SUCCESS; + } + + hsa_status_t GetTimeErr(uint32_t time_id, uint64_t* err) { + *err = time_error_[time_id]; return HSA_STATUS_SUCCESS; }