Fixes SWDEV-223910 and SWDEV-223663
[ROCm/clr commit: cea5489f00]
This commit is contained in:
@@ -139,6 +139,8 @@ namespace {
|
|||||||
return r;
|
return r;
|
||||||
}()};
|
}()};
|
||||||
|
|
||||||
|
constexpr std::uint32_t is_cpu_owned{UINT32_MAX};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
hsa_amd_pointer_info_t info(const void* p)
|
hsa_amd_pointer_info_t info(const void* p)
|
||||||
{
|
{
|
||||||
@@ -148,14 +150,14 @@ namespace {
|
|||||||
const_cast<void*>(p), &r, nullptr, nullptr, nullptr),
|
const_cast<void*>(p), &r, nullptr, nullptr, nullptr),
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
|
|
||||||
if (is_large_BAR) r.size = UINT32_MAX;
|
if (type(r.agentOwner) == HSA_DEVICE_TYPE_CPU) r.size = is_cpu_owned;
|
||||||
else if (type(r.agentOwner) == HSA_DEVICE_TYPE_CPU) r.size = INT32_MAX;
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr size_t staging_sz{4 * 1024 * 1024}; // 2 Pages.
|
constexpr size_t staging_sz{4 * 1024 * 1024}; // 2 Pages.
|
||||||
constexpr size_t max_std_memcpy_sz{8 * 1024}; // 8 KiB.
|
constexpr size_t max_h2d_std_memcpy_sz{8 * 1024}; // 8 KiB.
|
||||||
|
constexpr size_t max_d2h_std_memcpy_sz{64}; // 1 cacheline.
|
||||||
|
|
||||||
thread_local const std::unique_ptr<void, void (*)(void *)> staging_buffer{
|
thread_local const std::unique_ptr<void, void (*)(void *)> staging_buffer{
|
||||||
[]() {
|
[]() {
|
||||||
@@ -224,14 +226,20 @@ void do_std_memcpy(
|
|||||||
inline
|
inline
|
||||||
void d2h_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
void d2h_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
||||||
hsa_amd_pointer_info_t si) {
|
hsa_amd_pointer_info_t si) {
|
||||||
if (si.size == INT32_MAX) return do_std_memcpy(dst, src, n);
|
const auto di{info(dst)};
|
||||||
if (si.size == UINT32_MAX && n <= max_std_memcpy_sz) {
|
const auto is_locked{di.type == HSA_EXT_POINTER_TYPE_LOCKED};
|
||||||
|
|
||||||
|
if (!is_locked && si.size == is_cpu_owned) {
|
||||||
return do_std_memcpy(dst, src, n);
|
return do_std_memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
if (!is_locked && is_large_BAR && n <= max_d2h_std_memcpy_sz) {
|
||||||
|
return do_std_memcpy(dst, src, n);
|
||||||
|
}
|
||||||
|
if (di.type == HSA_EXT_POINTER_TYPE_HSA) {
|
||||||
|
return do_copy(dst, src, n, si.agentOwner, si.agentOwner);
|
||||||
|
}
|
||||||
|
|
||||||
const auto di{info(dst)};
|
if (is_locked) {
|
||||||
|
|
||||||
if (di.type == HSA_EXT_POINTER_TYPE_LOCKED) {
|
|
||||||
dst = static_cast<char*>(di.agentBaseAddress) +
|
dst = static_cast<char*>(di.agentBaseAddress) +
|
||||||
(static_cast<char*>(dst) -
|
(static_cast<char*>(dst) -
|
||||||
static_cast<char*>(di.hostBaseAddress));
|
static_cast<char*>(di.hostBaseAddress));
|
||||||
@@ -247,7 +255,7 @@ void d2h_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
|||||||
|
|
||||||
throwing_result_check(hsa_amd_memory_lock(dst, n, &si.agentOwner, 1,
|
throwing_result_check(hsa_amd_memory_lock(dst, n, &si.agentOwner, 1,
|
||||||
const_cast<void**>(&dst)),
|
const_cast<void**>(&dst)),
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
|
|
||||||
do_copy(dst, src, n, si.agentOwner, si.agentOwner);
|
do_copy(dst, src, n, si.agentOwner, si.agentOwner);
|
||||||
}
|
}
|
||||||
@@ -256,14 +264,20 @@ void d2h_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
|||||||
inline
|
inline
|
||||||
void h2d_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
void h2d_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
||||||
hsa_amd_pointer_info_t di) {
|
hsa_amd_pointer_info_t di) {
|
||||||
if (di.size == INT32_MAX) return do_std_memcpy(dst, src, n);
|
const auto si{info(const_cast<void*>(src))};
|
||||||
if (di.size == UINT32_MAX && n <= max_std_memcpy_sz) {
|
const auto is_locked{si.type == HSA_EXT_POINTER_TYPE_LOCKED};
|
||||||
|
|
||||||
|
if (!is_locked && di.size == is_cpu_owned) {
|
||||||
return do_std_memcpy(dst, src, n);
|
return do_std_memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
if (!is_locked && is_large_BAR && n <= max_h2d_std_memcpy_sz) {
|
||||||
|
return do_std_memcpy(dst, src, n);
|
||||||
|
}
|
||||||
|
if (si.type == HSA_EXT_POINTER_TYPE_HSA) {
|
||||||
|
return do_copy(dst, src, n, di.agentOwner, di.agentOwner);
|
||||||
|
}
|
||||||
|
|
||||||
const auto si{info(const_cast<void*>(src))};
|
if (is_locked) {
|
||||||
|
|
||||||
if (si.type == HSA_EXT_POINTER_TYPE_LOCKED) {
|
|
||||||
src = static_cast<char*>(si.agentBaseAddress) +
|
src = static_cast<char*>(si.agentBaseAddress) +
|
||||||
(static_cast<const char*>(src) -
|
(static_cast<const char*>(src) -
|
||||||
static_cast<char*>(si.hostBaseAddress));
|
static_cast<char*>(si.hostBaseAddress));
|
||||||
@@ -280,7 +294,7 @@ void h2d_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
|||||||
throwing_result_check(hsa_amd_memory_lock(const_cast<void*>(src), n,
|
throwing_result_check(hsa_amd_memory_lock(const_cast<void*>(src), n,
|
||||||
&di.agentOwner, 1,
|
&di.agentOwner, 1,
|
||||||
const_cast<void**>(&src)),
|
const_cast<void**>(&src)),
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
|
|
||||||
do_copy(dst, src, n, di.agentOwner, di.agentOwner);
|
do_copy(dst, src, n, di.agentOwner, di.agentOwner);
|
||||||
}
|
}
|
||||||
@@ -289,36 +303,23 @@ void h2d_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
|||||||
inline
|
inline
|
||||||
void generic_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
void generic_copy(void* __restrict dst, const void* __restrict src, size_t n,
|
||||||
hsa_amd_pointer_info_t di, hsa_amd_pointer_info_t si) {
|
hsa_amd_pointer_info_t di, hsa_amd_pointer_info_t si) {
|
||||||
if (di.size == INT32_MAX && si.size == INT32_MAX) {
|
if (di.size == is_cpu_owned && si.size == is_cpu_owned) {
|
||||||
return do_std_memcpy(dst, src, n);
|
|
||||||
}
|
|
||||||
if (di.size == UINT32_MAX && si.size == UINT32_MAX &&
|
|
||||||
n <= max_std_memcpy_sz) {
|
|
||||||
return do_std_memcpy(dst, src, n);
|
return do_std_memcpy(dst, src, n);
|
||||||
}
|
}
|
||||||
|
if (di.size == is_cpu_owned) return d2h_copy(dst, src, n, si);
|
||||||
|
if (si.size == is_cpu_owned) return h2d_copy(dst, src, n, di);
|
||||||
|
|
||||||
switch (type(si.agentOwner)) {
|
throwing_result_check(hsa_amd_agents_allow_access(1u, &si.agentOwner,
|
||||||
case HSA_DEVICE_TYPE_GPU:
|
nullptr,
|
||||||
if (type(di.agentOwner) == HSA_DEVICE_TYPE_GPU) {
|
di.agentBaseAddress),
|
||||||
throwing_result_check(
|
__FILE__, __func__, __LINE__);
|
||||||
hsa_amd_agents_allow_access(
|
|
||||||
1u, &si.agentOwner, nullptr, di.agentBaseAddress),
|
return do_copy(dst, src, n, di.agentOwner, si.agentOwner);
|
||||||
__FILE__, __func__, __LINE__);
|
|
||||||
return do_copy(dst, src, n, di.agentOwner, si.agentOwner);
|
|
||||||
}
|
|
||||||
return d2h_copy(dst, src, n, si);
|
|
||||||
case HSA_DEVICE_TYPE_CPU:
|
|
||||||
if (type(di.agentOwner) == HSA_DEVICE_TYPE_CPU) {
|
|
||||||
return do_std_memcpy(dst, src, n);
|
|
||||||
}
|
|
||||||
return h2d_copy(dst, src, n, di);
|
|
||||||
default: throw std::runtime_error{"Unsupported copy type."};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void memcpy_impl(void* __restrict dst, const void* __restrict src, size_t n,
|
void memcpy_impl(void* __restrict dst, const void* __restrict src, size_t n,
|
||||||
hipMemcpyKind k) noexcept {
|
hipMemcpyKind k) {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case hipMemcpyHostToHost: std::memcpy(dst, src, n); break;
|
case hipMemcpyHostToHost: std::memcpy(dst, src, n); break;
|
||||||
case hipMemcpyHostToDevice: return h2d_copy(dst, src, n, info(dst));
|
case hipMemcpyHostToDevice: return h2d_copy(dst, src, n, info(dst));
|
||||||
@@ -326,10 +327,10 @@ void memcpy_impl(void* __restrict dst, const void* __restrict src, size_t n,
|
|||||||
case hipMemcpyDeviceToDevice: {
|
case hipMemcpyDeviceToDevice: {
|
||||||
const auto di{info(dst)};
|
const auto di{info(dst)};
|
||||||
const auto si{info(src)};
|
const auto si{info(src)};
|
||||||
throwing_result_check(
|
throwing_result_check(hsa_amd_agents_allow_access(1u, &si.agentOwner,
|
||||||
hsa_amd_agents_allow_access(
|
nullptr,
|
||||||
1u, &si.agentOwner, nullptr, di.agentBaseAddress),
|
di.agentBaseAddress),
|
||||||
__FILE__, __func__, __LINE__);
|
__FILE__, __func__, __LINE__);
|
||||||
return do_copy(dst, src, n, di.agentOwner, si.agentOwner);
|
return do_copy(dst, src, n, di.agentOwner, si.agentOwner);
|
||||||
}
|
}
|
||||||
default: return generic_copy(dst, src, n, info(dst), info(src));
|
default: return generic_copy(dst, src, n, info(dst), info(src));
|
||||||
|
|||||||
Reference in New Issue
Block a user