6eb06cf201
Squashed commit of the following: commit f029195705a15700380c6f832ba5d15d46fd6de7 Author: Jonathan R. Madsen <jrmadsen@users.noreply.github.com> Date: Thu Jul 13 14:38:56 2023 -0500 Formatting workflows for source (clang-format) and cmake (cmake-format) (#4) * Add .cmake-format.yaml file * Add formatting workflow * provide base input for creating PR * Update scheme for extracting branch name - disable running formatting on push to amd-staging branch * patch .cmake-format.yaml for find_package signature - apparently cmake-format doesn't format the full signature of find_package * run formatting (clang-format v11) (#7) Co-authored-by: jrmadsen <jrmadsen@users.noreply.github.com> * run cmake formatting (cmake-format) (#6) Co-authored-by: jrmadsen <jrmadsen@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> commit bc4d135fdd8a1a9e51235f18a5d575fd2b3735e6 Author: Ammar ELWazir <aelwazir@amd.com> Date: Thu Jul 13 12:55:17 2023 -0500 Removing Build cache for potential issues with auto-generated header files (#5) Change-Id: I9e2319f4335e2f88585ffa6fac2bd88a1c952e6e commit ce86dea6a311d44d880fa684eb78f3329295e2a4 Author: Jonathan R. Madsen <jrmadsen@users.noreply.github.com> Date: Thu Jul 13 11:08:58 2023 -0500 Fix decltype(<hsa-function>) function pointer usage (#3) - the following is done in several places: decltype(hsa_memory_allocate)* hsa_memory_allocate - above can cause compiler errors - replace decltype(<hsa-function>) with decltype(::<hsa-function>) - this ensures that the type within the decltype is recognized as the global scope HSA function, not the variable - in many places, the variable has a "_fn" suffix to prevent this issue but added '::' anyway for consistency commit ac49fdd92a72e9c99394253a02da413a6c2e3b3a Merge: a07946a 03a0855 Author: Ammar ELWazir <aelwazir@amd.com> Date: Wed Jul 12 11:36:24 2023 -0500 Merge pull request #2 from ROCm-Developer-Tools/gerrit-amd-staging Pull from gerrit commit 03a085588cffe863e8f466de67be1cfb205b675a Merge:c26b32ba07946a Author: Ammar ELWazir <aelwazir@amd.com> Date: Wed Jul 12 10:57:30 2023 -0500 Merge branch 'amd-staging' into gerrit-amd-staging commit a07946a5cd4c670c83c27ad1a076a9d4567ce6d7 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 15:46:04 2023 +0000 Enabling Cached Builds commit 525e494a7f13941077a8fd4ad6840904db4d27d4 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 04:53:54 2023 +0000 Updating missed GPU Targets commit 42c75862f628c9bee7cfb7dc04dff2619430efbc Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 04:43:02 2023 +0000 Adding V1 Testing commit 9d72fd4aee85e4b0c12e717060d2730fa5b73be1 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:34:31 2023 +0000 Fixing Artifacts directory path commit f4000cc558b3b2e4676f7994f7ce8c8e6f94518e Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:27:26 2023 +0000 Fixing CMake for test build job commit 2ce8115d4c33948c3c8f957f545a95a04e1d6cd2 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:16:18 2023 +0000 Fixing Ubuntu CMake for ubuntu test build commit 6d0ed439191be900748d0c025157f9d689a73ec7 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 01:28:41 2023 +0000 Removing Navi21 commit e349a7642e5ae5eb03ab9fcd0a0f74f09f78cab5 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 01:14:14 2023 +0000 Removing Navi21 commit fefd02fe68d2a4bca7ec2e381960ad004ee9fc5b Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:42:48 2023 +0000 Fixing CMake Job commit 2ea46abf7bf92643efa8c549fa70346ffbd79d65 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:35:13 2023 +0000 Fixing CMake Job commit d99d681ed1999c5fcf291dc678b11a77205fb0f3 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:32:13 2023 +0000 Fixing Pull Latest Dockers and CMake Jobs commit dfc4498072d13b4a1df3a63047d34c682c3d9a29 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 23:54:21 2023 +0000 Fixing CMake job commit 919efe04de707f7c702031be15c3e2c5f8442cbb Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 23:52:13 2023 +0000 Adding Pull Last dockers job commit be1b1256e8b0e05308e8f7e7e69bee3acca55281 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:25:40 2023 -0500 Update cmake.yml commit 212299fa4355ae6ec18f9aaacbb79c51ea6c6f97 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:23:35 2023 -0500 Update cmake.yml commit 7c2c1327086a61466cc6cac39f70865c051a8bc7 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:18:53 2023 -0500 Update cmake.yml commit 191b5ce007e612e814c1d7a3afb4ad398f3852e1 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 16:03:22 2023 -0500 Update cmake.yml commit 8824113d95f3e13c7ce4d0af8e0d9d8f522a6c4a Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 16:28:09 2023 +0000 Fixing Pull from Gerrit job name Change-Id: I9e7ed9a27a13ca49d62c93bdadb30f0057e4d385 commit cc3d5e4b02ffb439e8cc2b3efa53527c376f9982 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 16:21:43 2023 +0000 Adding Staging sync job Change-Id: I0551f43878b0678ce4b3e74e27d62357cf95ad95 commit b9be2eee71380a2e6dd34d520e92d0c4209277a0 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 15:57:11 2023 +0000 Fixing build.sh Change-Id: Ia987b0244f0875370d5fe69907b3f5e9cea914de commit 9eee33a95a1abd656a7ac5ca10a9f245e9825431 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:39:46 2023 -0500 Update cmake.yml commit 7093b85a78497140e8b52632ca2a002bdaeacd62 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:33:29 2023 -0500 Update cmake.yml commit f54697172c72a67740f9fdfa0c217b6ea6931576 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:01:26 2023 -0500 Update cmake.yml commit 1b6620e16f8940386b0f4f04e69e2410d21c0e26 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 20:21:02 2023 -0500 Update cmake.yml commit a94bec740c6b42c4b79c87bca20fa87b99bf060d Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:46:35 2023 -0500 Update cmake.yml commit 85d6b29d4375a69d575c18ece8542c50f2ddfcc3 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:34:39 2023 -0500 Update cmake.yml commit 8c004887cf1435f1a6214c3d2455299a8a27bd4c Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:31:17 2023 -0500 Update cmake.yml commit a14a9168e17d9348a53c6e9c9a47ba1edb4c4509 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:25:46 2023 -0500 Update cmake.yml commit 000f2f40b84e6a2f7d4becdbf5aed01436ca4c83 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:08:18 2023 -0500 Update cmake.yml commit a28a53d56731cad848fa9133d1c4dbaa8fc7afa7 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:03:39 2023 -0500 Update cmake.yml commit a6a2db01027f0b01fdfbb5997ddb772c7f51b649 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 18:21:53 2023 -0500 Update cmake.yml commit 118ef2a88b2d44e3207c31c343da3e5e5ec6f176 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 17:55:57 2023 -0500 Update cmake.yml commit 03c4c232396440cd0be6d2dd7baf4ceea1c2589d Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 17:48:49 2023 -0500 Create cmake.yml Change-Id: I77992f15694e77cbae49c56f9ff02f4f9079235d [ROCm/rocprofiler commit:d4a33cf33a]
623 linhas
23 KiB
C++
623 linhas
23 KiB
C++
/**********************************************************************
|
|
Copyright ©2013 Advanced Micro Devices, Inc. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted
|
|
provided that the following conditions are met:
|
|
|
|
<95> Redistributions of source code must retain the above copyright notice, this list of
|
|
conditions and the following disclaimer.
|
|
<95> Redistributions in binary form must reproduce the above copyright notice, this list of
|
|
conditions and the following disclaimer in the documentation and/or
|
|
other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
********************************************************************/
|
|
|
|
#ifndef TEST_UTIL_HSA_RSRC_FACTORY_H_
|
|
#define TEST_UTIL_HSA_RSRC_FACTORY_H_
|
|
|
|
#include <hsa/hsa.h>
|
|
#include <hsa/hsa_api_trace.h>
|
|
#include <hsa/hsa_ext_amd.h>
|
|
#include <hsa/hsa_ext_finalize.h>
|
|
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
|
#include <hsa/hsa_ven_amd_loader.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#include <atomic>
|
|
#include <iostream>
|
|
#include <mutex>
|
|
#include <map>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#define HSA_ARGUMENT_ALIGN_BYTES 16
|
|
#define HSA_QUEUE_ALIGN_BYTES 64
|
|
#define HSA_PACKET_ALIGN_BYTES 64
|
|
|
|
#define CHECK_STATUS(msg, status) \
|
|
do { \
|
|
if ((status) != HSA_STATUS_SUCCESS) { \
|
|
const char* emsg = 0; \
|
|
hsa_status_string(status, &emsg); \
|
|
printf("%s: %s\n", msg, emsg ? emsg : "<unknown error>"); \
|
|
abort(); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define CHECK_ITER_STATUS(msg, status) \
|
|
do { \
|
|
if ((status) != HSA_STATUS_INFO_BREAK) { \
|
|
const char* emsg = 0; \
|
|
hsa_status_string(status, &emsg); \
|
|
printf("%s: %s\n", msg, emsg ? emsg : "<unknown error>"); \
|
|
abort(); \
|
|
} \
|
|
} while (0)
|
|
|
|
static const size_t MEM_PAGE_BYTES = 0x1000;
|
|
static const size_t MEM_PAGE_MASK = MEM_PAGE_BYTES - 1;
|
|
typedef decltype(hsa_agent_t::handle) hsa_agent_handle_t;
|
|
|
|
struct hsa_pfn_t {
|
|
decltype(::hsa_init)* hsa_init;
|
|
decltype(::hsa_shut_down)* hsa_shut_down;
|
|
decltype(::hsa_agent_get_info)* hsa_agent_get_info;
|
|
decltype(::hsa_iterate_agents)* hsa_iterate_agents;
|
|
|
|
decltype(::hsa_queue_create)* hsa_queue_create;
|
|
decltype(::hsa_queue_destroy)* hsa_queue_destroy;
|
|
decltype(::hsa_queue_load_read_index_relaxed)* hsa_queue_load_read_index_relaxed;
|
|
decltype(::hsa_queue_load_write_index_relaxed)* hsa_queue_load_write_index_relaxed;
|
|
decltype(::hsa_queue_add_write_index_scacq_screl)* hsa_queue_add_write_index_scacq_screl;
|
|
|
|
decltype(::hsa_signal_create)* hsa_signal_create;
|
|
decltype(::hsa_signal_destroy)* hsa_signal_destroy;
|
|
decltype(::hsa_signal_load_relaxed)* hsa_signal_load_relaxed;
|
|
decltype(::hsa_signal_store_relaxed)* hsa_signal_store_relaxed;
|
|
decltype(::hsa_signal_wait_scacquire)* hsa_signal_wait_scacquire;
|
|
decltype(::hsa_signal_store_screlease)* hsa_signal_store_screlease;
|
|
|
|
decltype(::hsa_code_object_reader_create_from_file)* hsa_code_object_reader_create_from_file;
|
|
decltype(::hsa_executable_create_alt)* hsa_executable_create_alt;
|
|
decltype(::hsa_executable_load_agent_code_object)* hsa_executable_load_agent_code_object;
|
|
decltype(::hsa_executable_freeze)* hsa_executable_freeze;
|
|
decltype(::hsa_executable_destroy)* hsa_executable_destroy;
|
|
decltype(::hsa_executable_get_symbol)* hsa_executable_get_symbol;
|
|
decltype(::hsa_executable_symbol_get_info)* hsa_executable_symbol_get_info;
|
|
decltype(::hsa_executable_iterate_symbols)* hsa_executable_iterate_symbols;
|
|
|
|
decltype(::hsa_system_get_info)* hsa_system_get_info;
|
|
decltype(::hsa_system_get_major_extension_table)* hsa_system_get_major_extension_table;
|
|
|
|
decltype(::hsa_amd_agent_iterate_memory_pools)* hsa_amd_agent_iterate_memory_pools;
|
|
decltype(::hsa_amd_memory_pool_get_info)* hsa_amd_memory_pool_get_info;
|
|
decltype(::hsa_amd_memory_pool_allocate)* hsa_amd_memory_pool_allocate;
|
|
decltype(::hsa_amd_agents_allow_access)* hsa_amd_agents_allow_access;
|
|
decltype(::hsa_amd_memory_async_copy)* hsa_amd_memory_async_copy;
|
|
|
|
decltype(::hsa_amd_signal_async_handler)* hsa_amd_signal_async_handler;
|
|
decltype(::hsa_amd_profiling_set_profiler_enabled)* hsa_amd_profiling_set_profiler_enabled;
|
|
decltype(::hsa_amd_profiling_get_async_copy_time)* hsa_amd_profiling_get_async_copy_time;
|
|
decltype(::hsa_amd_profiling_get_dispatch_time)* hsa_amd_profiling_get_dispatch_time;
|
|
};
|
|
|
|
// Encapsulates information about a Hsa Agent such as its
|
|
// handle, name, max queue size, max wavefront size, etc.
|
|
struct AgentInfo {
|
|
// Handle of Agent
|
|
hsa_agent_t dev_id;
|
|
|
|
// Agent type - Cpu = 0, Gpu = 1 or Dsp = 2
|
|
uint32_t dev_type;
|
|
|
|
// APU flag
|
|
bool is_apu;
|
|
|
|
// Agent system index
|
|
uint32_t dev_index;
|
|
|
|
// GFXIP name
|
|
char gfxip[64];
|
|
|
|
// Name of Agent whose length is less than 64
|
|
char name[64];
|
|
|
|
// Max size of Wavefront size
|
|
uint32_t max_wave_size;
|
|
|
|
// Max size of Queue buffer
|
|
uint32_t max_queue_size;
|
|
|
|
// Hsail profile supported by agent
|
|
hsa_profile_t profile;
|
|
|
|
// CPU/GPU/kern-arg memory pools
|
|
hsa_amd_memory_pool_t cpu_pool;
|
|
hsa_amd_memory_pool_t gpu_pool;
|
|
hsa_amd_memory_pool_t kern_arg_pool;
|
|
|
|
// The number of compute unit available in the agent.
|
|
uint32_t cu_num;
|
|
|
|
// Maximum number of waves possible in a Compute Unit.
|
|
uint32_t waves_per_cu;
|
|
|
|
// Number of SIMD's per compute unit CU
|
|
uint32_t simds_per_cu;
|
|
|
|
// Number of Shader Engines (SE) in Gpu
|
|
uint32_t se_num;
|
|
|
|
// Number of Shader Arrays Per Shader Engines in Gpu
|
|
uint32_t shader_arrays_per_se;
|
|
|
|
static const uint32_t lds_block_size = 128 * 4;
|
|
};
|
|
|
|
// HSA timer class
|
|
// Provides current HSA timestampa and system-clock/ns conversion API
|
|
class HsaTimer {
|
|
public:
|
|
typedef uint64_t timestamp_t;
|
|
static const timestamp_t TIMESTAMP_MAX = UINT64_MAX;
|
|
typedef long double freq_t;
|
|
|
|
enum time_id_t {
|
|
TIME_ID_CLOCK_REALTIME = 0,
|
|
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
|
|
};
|
|
|
|
HsaTimer(const hsa_pfn_t* hsa_api) : hsa_api_(hsa_api) {
|
|
timestamp_t sysclock_hz = 0;
|
|
hsa_status_t status =
|
|
hsa_api_->hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY, &sysclock_hz);
|
|
CHECK_STATUS("hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP_FREQUENCY)", status);
|
|
sysclock_factor_ = (freq_t)1000000000 / (freq_t)sysclock_hz;
|
|
}
|
|
|
|
// Methods for system-clock/ns conversion
|
|
timestamp_t sysclock_to_ns(const timestamp_t& sysclock) const {
|
|
return timestamp_t((freq_t)sysclock * sysclock_factor_);
|
|
}
|
|
timestamp_t ns_to_sysclock(const timestamp_t& time) const {
|
|
return timestamp_t((freq_t)time / sysclock_factor_);
|
|
}
|
|
|
|
// Method for timespec/ns conversion
|
|
static timestamp_t timespec_to_ns(const timespec& time) {
|
|
return ((timestamp_t)time.tv_sec * 1000000000) + time.tv_nsec;
|
|
}
|
|
|
|
// Return timestamp in 'ns'
|
|
timestamp_t timestamp_ns() const {
|
|
timestamp_t sysclock;
|
|
hsa_status_t status = hsa_api_->hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP, &sysclock);
|
|
CHECK_STATUS("hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP)", status);
|
|
return sysclock_to_ns(sysclock);
|
|
}
|
|
|
|
// Return time in 'ns'
|
|
timestamp_t clocktime_ns(clockid_t clock_id) const {
|
|
timespec time;
|
|
clock_gettime(clock_id, &time);
|
|
return timespec_to_ns(time);
|
|
}
|
|
|
|
// Return pair of correlated values of profiling timestamp and time with
|
|
// correlation error for a given time ID and number of iterations
|
|
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 (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);
|
|
}
|
|
|
|
std::vector<timestamp_t> ts_vec(iters);
|
|
std::vector<timespec> tm_vec(iters);
|
|
const uint32_t steps = iters - 1;
|
|
|
|
for (uint32_t i = 0; i < iters; ++i) {
|
|
hsa_api_->hsa_system_get_info(HSA_SYSTEM_INFO_TIMESTAMP, &ts_vec[i]);
|
|
clock_gettime(clock_id, &tm_vec[i]);
|
|
}
|
|
|
|
const timestamp_t ts_base = sysclock_to_ns(ts_vec.front());
|
|
const timestamp_t tm_base = timespec_to_ns(tm_vec.front());
|
|
const timestamp_t error = (ts_vec.back() - ts_vec.front()) / (2 * steps);
|
|
|
|
timestamp_t ts_accum = 0;
|
|
timestamp_t tm_accum = 0;
|
|
for (uint32_t i = 0; i < iters; ++i) {
|
|
ts_accum += (ts_vec[i] - ts_base);
|
|
tm_accum += (timespec_to_ns(tm_vec[i]) - tm_base);
|
|
}
|
|
|
|
*timestamp_v = (ts_accum / iters) + ts_base + error;
|
|
*time_v = (tm_accum / iters) + tm_base;
|
|
*error_v = error;
|
|
}
|
|
|
|
private:
|
|
// Timestamp frequency factor
|
|
freq_t sysclock_factor_;
|
|
// HSA API table
|
|
const hsa_pfn_t* const hsa_api_;
|
|
};
|
|
|
|
class HsaRsrcFactory {
|
|
public:
|
|
static const size_t CMD_SLOT_SIZE_B = 0x40;
|
|
typedef std::recursive_mutex mutex_t;
|
|
typedef HsaTimer::timestamp_t timestamp_t;
|
|
|
|
// Executables loading tracking
|
|
struct symbols_map_data_t {
|
|
const char* name;
|
|
uint64_t refs_count;
|
|
};
|
|
typedef std::map<uint64_t, symbols_map_data_t> symbols_map_t;
|
|
|
|
static HsaRsrcFactory* Create(bool initialize_hsa = true) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
HsaRsrcFactory* obj = instance_.load(std::memory_order_relaxed);
|
|
if (obj == NULL) {
|
|
obj = new HsaRsrcFactory(initialize_hsa);
|
|
instance_.store(obj, std::memory_order_release);
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
static HsaRsrcFactory& Instance() {
|
|
HsaRsrcFactory* obj = instance_.load(std::memory_order_acquire);
|
|
if (obj == NULL) obj = Create(false);
|
|
hsa_status_t status = (obj != NULL) ? HSA_STATUS_SUCCESS : HSA_STATUS_ERROR;
|
|
CHECK_STATUS("HsaRsrcFactory::Instance() failed", status);
|
|
return *obj;
|
|
}
|
|
|
|
static void Destroy() {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
if (instance_) delete instance_.load();
|
|
instance_ = NULL;
|
|
}
|
|
|
|
// Return system agent info
|
|
const AgentInfo* GetAgentInfo(const hsa_agent_t agent);
|
|
|
|
// Get the count of Hsa Gpu Agents available on the platform
|
|
// @return uint32_t Number of Gpu agents on platform
|
|
uint32_t GetCountOfGpuAgents();
|
|
|
|
// Get the count of Hsa Cpu Agents available on the platform
|
|
// @return uint32_t Number of Cpu agents on platform
|
|
uint32_t GetCountOfCpuAgents();
|
|
|
|
// Get the AgentInfo handle of a Gpu device
|
|
// @param idx Gpu Agent at specified index
|
|
// @param agent_info Output parameter updated with AgentInfo
|
|
// @return bool true if successful, false otherwise
|
|
bool GetGpuAgentInfo(uint32_t idx, const AgentInfo** agent_info);
|
|
|
|
// Get the AgentInfo handle of a Cpu device
|
|
// @param idx Cpu Agent at specified index
|
|
// @param agent_info Output parameter updated with AgentInfo
|
|
// @return bool true if successful, false otherwise
|
|
bool GetCpuAgentInfo(uint32_t idx, const AgentInfo** agent_info);
|
|
|
|
// Create a Queue object and return its handle. The queue object is expected
|
|
// to support user requested number of Aql dispatch packets.
|
|
// @param agent_info Gpu Agent on which to create a queue object
|
|
// @param num_Pkts Number of packets to be held by queue
|
|
// @param queue Output parameter updated with handle of queue object
|
|
// @return bool true if successful, false otherwise
|
|
bool CreateQueue(const AgentInfo* agent_info, uint32_t num_pkts, hsa_queue_t** queue);
|
|
|
|
// Create a Signal object and return its handle.
|
|
// @param value Initial value of signal object
|
|
// @param signal Output parameter updated with handle of signal object
|
|
// @return bool true if successful, false otherwise
|
|
bool CreateSignal(uint32_t value, hsa_signal_t* signal);
|
|
|
|
// Allocate local GPU memory
|
|
// @param agent_info Agent from whose memory region to allocate
|
|
// @param size Size of memory in terms of bytes
|
|
// @return uint8_t* Pointer to buffer, null if allocation fails.
|
|
uint8_t* AllocateLocalMemory(const AgentInfo* agent_info, size_t size);
|
|
|
|
// Allocate memory tp pass kernel parameters
|
|
// Memory is alocated accessible for all CPU agents and for GPU given by AgentInfo parameter.
|
|
// @param agent_info Agent from whose memory region to allocate
|
|
// @param size Size of memory in terms of bytes
|
|
// @return uint8_t* Pointer to buffer, null if allocation fails.
|
|
uint8_t* AllocateKernArgMemory(const AgentInfo* agent_info, size_t size);
|
|
|
|
// Allocate system memory accessible from both CPU and GPU
|
|
// Memory is alocated accessible to all CPU agents and AgentInfo parameter is ignored.
|
|
// @param agent_info Agent from whose memory region to allocate
|
|
// @param size Size of memory in terms of bytes
|
|
// @return uint8_t* Pointer to buffer, null if allocation fails.
|
|
uint8_t* AllocateSysMemory(const AgentInfo* agent_info, size_t size);
|
|
|
|
// Allocate memory for command buffer.
|
|
// @param agent_info Agent from whose memory region to allocate
|
|
// @param size Size of memory in terms of bytes
|
|
// @return uint8_t* Pointer to buffer, null if allocation fails.
|
|
uint8_t* AllocateCmdMemory(const AgentInfo* agent_info, size_t size);
|
|
|
|
// Wait signal
|
|
hsa_signal_value_t SignalWait(const hsa_signal_t& signal,
|
|
const hsa_signal_value_t& signal_value) const;
|
|
|
|
// Wait signal with signal value restore
|
|
void SignalWaitRestore(const hsa_signal_t& signal, const hsa_signal_value_t& signal_value) const;
|
|
|
|
// Copy data from GPU to host memory
|
|
bool Memcpy(const hsa_agent_t& agent, void* dst, const void* src, size_t size);
|
|
bool Memcpy(const AgentInfo* agent_info, void* dst, const void* src, size_t size);
|
|
|
|
// Memory free method
|
|
static bool FreeMemory(void* ptr);
|
|
|
|
// Loads an Assembled Brig file and Finalizes it into Device Isa
|
|
// @param agent_info Gpu device for which to finalize
|
|
// @param brig_path File path of the Assembled Brig file
|
|
// @param kernel_name Name of the kernel to finalize
|
|
// @param code_desc Handle of finalized Code Descriptor that could
|
|
// be used to submit for execution
|
|
// @return true if successful, false otherwise
|
|
bool LoadAndFinalize(const AgentInfo* agent_info, const char* brig_path, const char* kernel_name,
|
|
hsa_executable_t* hsa_exec, hsa_executable_symbol_t* code_desc);
|
|
|
|
// Print the various fields of Hsa Gpu Agents
|
|
bool PrintGpuAgents(const std::string& header);
|
|
|
|
// Utils for submitting AQL packet to a given queue
|
|
static void* GetReadPointer(hsa_queue_t* queue);
|
|
static uint64_t Submit(hsa_queue_t* queue, const void* packet);
|
|
static uint64_t Submit(hsa_queue_t* queue, const void* packet, size_t size_bytes);
|
|
|
|
// Enable executables loading tracking
|
|
static bool IsExecutableTracking() { return executable_tracking_on_; }
|
|
static void EnableExecutableTracking(HsaApiTable* table);
|
|
|
|
typedef symbols_map_t::iterator symbols_map_it_t;
|
|
|
|
static inline const char* GetKernelNameRef(const uint64_t& addr) {
|
|
if (symbols_map_ == NULL) {
|
|
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx), error\n", addr);
|
|
abort();
|
|
}
|
|
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
|
|
const auto it = symbols_map_->find(addr);
|
|
if (it == symbols_map_->end()) {
|
|
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx) is not found\n", addr);
|
|
abort();
|
|
}
|
|
|
|
return it->second.name;
|
|
}
|
|
|
|
static inline symbols_map_it_t AcquireKernelNameRef(const uint64_t& addr) {
|
|
if (symbols_map_ == NULL) {
|
|
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx), error\n", addr);
|
|
abort();
|
|
}
|
|
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
|
|
const auto it = symbols_map_->find(addr);
|
|
if (it == symbols_map_->end()) {
|
|
fprintf(stderr, "HsaRsrcFactory::GetKernelNameRef: kernel addr (0x%lx) is not found\n", addr);
|
|
abort();
|
|
}
|
|
|
|
std::atomic<uint64_t>* atomic_ptr =
|
|
reinterpret_cast<std::atomic<uint64_t>*>(&(it->second.refs_count));
|
|
atomic_ptr->fetch_add(1, std::memory_order_relaxed);
|
|
|
|
return it;
|
|
}
|
|
|
|
static inline void ReleaseKernelNameRef(const symbols_map_it_t& it) {
|
|
std::atomic<uint64_t>* atomic_ptr =
|
|
reinterpret_cast<std::atomic<uint64_t>*>(&(it->second.refs_count));
|
|
atomic_ptr->fetch_sub(1, std::memory_order_relaxed);
|
|
}
|
|
|
|
static inline void SetKernelNameRef(const uint64_t& addr, const char* name, const int& free) {
|
|
if (symbols_map_ == NULL) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
if (symbols_map_ == NULL) symbols_map_ = new symbols_map_t;
|
|
}
|
|
|
|
auto it = symbols_map_->find(addr);
|
|
if (it != symbols_map_->end()) {
|
|
while (1) {
|
|
while (it->second.refs_count != 0) sched_yield();
|
|
mutex_.lock();
|
|
if (it->second.refs_count == 0) break;
|
|
mutex_.unlock();
|
|
}
|
|
}
|
|
|
|
if (it != symbols_map_->end()) {
|
|
delete[] it->second.name;
|
|
if (free == 1) {
|
|
symbols_map_->erase(it);
|
|
} else {
|
|
fprintf(stderr, "HsaRsrcFactory::SetKernelNameRef: to set kernel addr (0x%lx) conflict\n",
|
|
addr);
|
|
abort();
|
|
}
|
|
} else {
|
|
if (free == 0) {
|
|
symbols_map_->insert({addr, symbols_map_data_t{name, 0}});
|
|
} else {
|
|
fprintf(stderr, "HsaRsrcFactory::SetKernelNameRef: to free kernel addr (0x%lx) not found\n",
|
|
addr);
|
|
abort();
|
|
}
|
|
}
|
|
|
|
mutex_.unlock();
|
|
}
|
|
|
|
// Initialize HSA API table
|
|
void static InitHsaApiTable(HsaApiTable* table);
|
|
static const hsa_pfn_t* HsaApi() { return &hsa_api_; }
|
|
|
|
// Return AqlProfile API table
|
|
typedef hsa_ven_amd_aqlprofile_pfn_t aqlprofile_pfn_t;
|
|
const aqlprofile_pfn_t* AqlProfileApi() const { return &aqlprofile_api_; }
|
|
|
|
// Return Loader API table
|
|
const hsa_ven_amd_loader_1_00_pfn_t* LoaderApi() const { return &loader_api_; }
|
|
|
|
// Methods for system-clock/ns conversion and timestamp in 'ns'
|
|
timestamp_t SysclockToNs(const timestamp_t& sysclock) const {
|
|
return timer_->sysclock_to_ns(sysclock);
|
|
}
|
|
timestamp_t NsToSysclock(const timestamp_t& time) const { return timer_->ns_to_sysclock(time); }
|
|
timestamp_t TimestampNs() const { return timer_->timestamp_ns(); }
|
|
|
|
timestamp_t GetSysTimeout() const { return timeout_; }
|
|
static timestamp_t GetTimeoutNs() { return timeout_ns_; }
|
|
static void SetTimeoutNs(const timestamp_t& time) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
timeout_ns_ = time;
|
|
if (instance_ != NULL) Instance().timeout_ = Instance().timer_->ns_to_sysclock(time);
|
|
}
|
|
|
|
void CorrelateTime(HsaTimer::time_id_t time_id, uint32_t iters) {
|
|
timestamp_t timestamp_v = 0;
|
|
timestamp_t time_v = 0;
|
|
timestamp_t error_v = 0;
|
|
timer_->correlated_pair_ns(time_id, iters, ×tamp_v, &time_v, &error_v);
|
|
time_shift_[time_id] = time_v - timestamp_v;
|
|
time_error_[time_id] = error_v;
|
|
}
|
|
|
|
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_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;
|
|
}
|
|
|
|
private:
|
|
// System agents iterating callback
|
|
static hsa_status_t GetHsaAgentsCallback(hsa_agent_t agent, void* data);
|
|
|
|
// Callback function to find and bind kernarg region of an agent
|
|
static hsa_status_t FindMemRegionsCallback(hsa_region_t region, void* data);
|
|
|
|
// Load AQL profile HSA extension library directly
|
|
static hsa_status_t LoadAqlProfileLib(aqlprofile_pfn_t* api);
|
|
|
|
// Constructor of the class. Will initialize the Hsa Runtime and
|
|
// query the system topology to get the list of Cpu and Gpu devices
|
|
explicit HsaRsrcFactory(bool initialize_hsa);
|
|
|
|
// Destructor of the class
|
|
~HsaRsrcFactory();
|
|
|
|
// Add an instance of AgentInfo representing a Hsa Gpu agent
|
|
const AgentInfo* AddAgentInfo(const hsa_agent_t agent);
|
|
|
|
// To mmap command buffer memory
|
|
static const bool CMD_MEMORY_MMAP = false;
|
|
|
|
// HSA was initialized
|
|
const bool initialize_hsa_;
|
|
|
|
static std::atomic<HsaRsrcFactory*> instance_;
|
|
static mutex_t mutex_;
|
|
|
|
// Used to maintain a list of Hsa Gpu Agent Info
|
|
std::vector<const AgentInfo*> gpu_list_;
|
|
std::vector<hsa_agent_t> gpu_agents_;
|
|
|
|
// Used to maintain a list of Hsa Cpu Agent Info
|
|
std::vector<const AgentInfo*> cpu_list_;
|
|
std::vector<hsa_agent_t> cpu_agents_;
|
|
|
|
// System agents map
|
|
std::map<hsa_agent_handle_t, const AgentInfo*> agent_map_;
|
|
|
|
static symbols_map_t* symbols_map_;
|
|
static bool executable_tracking_on_;
|
|
static hsa_status_t hsa_executable_freeze_interceptor(hsa_executable_t executable,
|
|
const char* options);
|
|
static hsa_status_t hsa_executable_destroy_interceptor(hsa_executable_t executable);
|
|
static hsa_status_t executable_symbols_cb(hsa_executable_t exec, hsa_executable_symbol_t symbol,
|
|
void* data);
|
|
|
|
// HSA runtime API table
|
|
static hsa_pfn_t hsa_api_;
|
|
|
|
// AqlProfile API table
|
|
aqlprofile_pfn_t aqlprofile_api_;
|
|
|
|
// Loader API table
|
|
hsa_ven_amd_loader_1_00_pfn_t loader_api_;
|
|
|
|
// System timeout, ns
|
|
static timestamp_t timeout_ns_;
|
|
// System timeout, sysclock
|
|
timestamp_t timeout_;
|
|
|
|
// HSA timer
|
|
HsaTimer* timer_;
|
|
|
|
// Time shift array to support time conversion
|
|
timestamp_t time_shift_[HsaTimer::TIME_ID_NUMBER];
|
|
timestamp_t time_error_[HsaTimer::TIME_ID_NUMBER];
|
|
|
|
// CPU/kern-arg memory pools
|
|
hsa_amd_memory_pool_t* cpu_pool_;
|
|
hsa_amd_memory_pool_t* kern_arg_pool_;
|
|
};
|
|
|
|
|
|
#endif // TEST_UTIL_HSA_RSRC_FACTORY_H_
|