Initial exception support for signals.
Also separate signal ABI block allocations from the runtime interface object.
Change-Id: If16763338db664f29163a1348f8f4c38cf0597b2
[ROCm/ROCR-Runtime commit: 2732b18092]
这个提交包含在:
@@ -80,10 +80,6 @@ class Shared : public BaseShared {
|
||||
shared_object_ =
|
||||
reinterpret_cast<T*>(allocate_(sizeof(T), Max(__alignof(T), Align), 0));
|
||||
|
||||
assert(shared_object_ != NULL && "Failed on allocating shared_object_");
|
||||
|
||||
memset(shared_object_, 0, sizeof(T));
|
||||
|
||||
if (shared_object_ != NULL) new (shared_object_) T;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace amd {
|
||||
/// @brief Encapsulates HW Aql Command Processor functionality. It
|
||||
/// provide the interface for things such as Doorbell register, read,
|
||||
/// write pointers and a buffer.
|
||||
class AqlQueue : public core::Queue, public core::Signal {
|
||||
class AqlQueue : public core::Queue, private core::LocalSignal, public core::Signal {
|
||||
public:
|
||||
static __forceinline bool IsType(core::Signal* signal) {
|
||||
return signal->IsType(&rtti_id_);
|
||||
@@ -336,12 +336,6 @@ class AqlQueue : public core::Queue, public core::Signal {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 64 byte-aligned allocation and release, for Queue::amd_queue_.
|
||||
void* operator new(size_t size);
|
||||
void* operator new(size_t size, void* ptr) { return ptr; }
|
||||
void operator delete(void* ptr);
|
||||
void operator delete(void*, void*) {}
|
||||
|
||||
protected:
|
||||
bool _IsA(rtti_t id) const override { return id == &rtti_id_; }
|
||||
|
||||
|
||||
@@ -48,29 +48,61 @@
|
||||
|
||||
namespace core {
|
||||
|
||||
/// @brief Base class for all classes whose validity can be checked using
|
||||
/// IsValid() method.
|
||||
template <uint64_t code>
|
||||
class Checked {
|
||||
/// @brief Compares type codes and pointers to check object validity. Used for cast validation.
|
||||
template <uint64_t code, bool multiProcess = false> class Check final {
|
||||
public:
|
||||
typedef Checked<code> CheckedType;
|
||||
typedef Check<code> CheckType;
|
||||
|
||||
Checked() { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
Checked(const Checked&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
Checked(Checked&&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
Check() { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
Check(const Check&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
Check(Check&&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
|
||||
|
||||
virtual ~Checked() { object_ = NULL; }
|
||||
~Check() { object_ = NULL; }
|
||||
|
||||
const Checked& operator=(Checked&& rhs) { return *this; }
|
||||
const Checked& operator=(const Checked& rhs) { return *this; }
|
||||
const Check& operator=(Check&& rhs) { return *this; }
|
||||
const Check& operator=(const Check& rhs) { return *this; }
|
||||
|
||||
bool IsValid() const {
|
||||
return object_ == (uintptr_t(this) ^ uintptr_t(code));
|
||||
}
|
||||
|
||||
uint64_t check_code() const { return code; }
|
||||
|
||||
private:
|
||||
uintptr_t object_;
|
||||
};
|
||||
|
||||
template <uint64_t code> class Check<code, true> final {
|
||||
public:
|
||||
typedef Check<code> CheckType;
|
||||
|
||||
Check() { object_ = uintptr_t(code); }
|
||||
Check(const Check&) { object_ = uintptr_t(code); }
|
||||
Check(Check&&) { object_ = uintptr_t(code); }
|
||||
|
||||
const Check& operator=(Check&& rhs) { return *this; }
|
||||
const Check& operator=(const Check& rhs) { return *this; }
|
||||
|
||||
bool IsValid() const { return object_ == uintptr_t(code); }
|
||||
|
||||
uint64_t check_code() const { return code; }
|
||||
|
||||
private:
|
||||
uintptr_t object_;
|
||||
};
|
||||
|
||||
/// @brief Base class for validating objects.
|
||||
template <uint64_t code> class Checked {
|
||||
public:
|
||||
typedef Checked<code> CheckedType;
|
||||
|
||||
bool IsValid() const { return id.IsValid(); }
|
||||
|
||||
virtual ~Checked() {}
|
||||
|
||||
private:
|
||||
Check<code, false> id;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
#endif // header guard
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace core {
|
||||
|
||||
/// @brief Simple pure memory based signal.
|
||||
/// @brief See base class Signal.
|
||||
class DefaultSignal : public Signal {
|
||||
class DefaultSignal : private LocalSignal, public Signal {
|
||||
public:
|
||||
/// @brief Determines if a Signal* can be safely converted to DefaultSignal*
|
||||
/// via static_cast.
|
||||
@@ -155,12 +155,6 @@ class DefaultSignal : public Signal {
|
||||
/// @brief see the base class Signal
|
||||
__forceinline HsaEvent* EopEvent() { return NULL; }
|
||||
|
||||
/// @brief prevent throwing exceptions
|
||||
void* operator new(size_t size) { return malloc(size); }
|
||||
|
||||
/// @brief prevent throwing exceptions
|
||||
void operator delete(void* ptr) { free(ptr); }
|
||||
|
||||
protected:
|
||||
bool _IsA(rtti_t id) const { return id == &rtti_id_; }
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace core {
|
||||
/// Supports only one waiter for now.
|
||||
/// KFD changes are needed to support multiple waiters and have device
|
||||
/// signaling.
|
||||
class InterruptSignal : public Signal {
|
||||
class InterruptSignal : private LocalSignal, public Signal {
|
||||
public:
|
||||
static HsaEvent* CreateEvent(HSA_EVENTTYPE type, bool manual_reset);
|
||||
static void DestroyEvent(HsaEvent* evt);
|
||||
@@ -165,12 +165,6 @@ class InterruptSignal : public Signal {
|
||||
/// @brief See base class Signal.
|
||||
__forceinline HsaEvent* EopEvent() { return event_; }
|
||||
|
||||
/// @brief prevent throwing exceptions
|
||||
void* operator new(size_t size) { return malloc(size); }
|
||||
|
||||
/// @brief prevent throwing exceptions
|
||||
void operator delete(void* ptr) { free(ptr); }
|
||||
|
||||
protected:
|
||||
bool _IsA(rtti_t id) const { return id == &rtti_id_; }
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "core/inc/checked.h"
|
||||
|
||||
#include "core/util/utils.h"
|
||||
#include "core/util/locks.h"
|
||||
|
||||
#include "inc/amd_hsa_signal.h"
|
||||
|
||||
@@ -60,54 +61,72 @@ namespace core {
|
||||
class Agent;
|
||||
class Signal;
|
||||
|
||||
/// @brief Helper structure to simplify conversion of amd_signal_t and
|
||||
/// core::Signal object.
|
||||
/// @brief ABI and object conversion struct for signals. May be shared between processes.
|
||||
struct SharedSignal {
|
||||
amd_signal_t amd_signal;
|
||||
Signal* core_signal;
|
||||
Check<0x71FCCA6A3D5D5276, true> id;
|
||||
|
||||
bool IsValid() const { return id.IsValid(); }
|
||||
|
||||
SharedSignal() {
|
||||
amd_signal.kind = AMD_SIGNAL_KIND_INVALID;
|
||||
core_signal = nullptr;
|
||||
}
|
||||
|
||||
static __forceinline SharedSignal* Convert(hsa_signal_t signal) {
|
||||
if (signal.handle == 0) throw std::bad_cast();
|
||||
SharedSignal* ret = reinterpret_cast<SharedSignal*>(static_cast<uintptr_t>(signal.handle) -
|
||||
offsetof(SharedSignal, amd_signal));
|
||||
if (!ret->IsValid()) throw std::bad_cast();
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
static_assert(std::is_standard_layout<SharedSignal>::value,
|
||||
"SharedSignal must remain standard layout for IPC use.");
|
||||
static_assert(std::is_trivially_destructible<SharedSignal>::value,
|
||||
"SharedSignal must not be modified on delete for IPC use.");
|
||||
|
||||
class LocalSignal {
|
||||
public:
|
||||
explicit LocalSignal(hsa_signal_value_t initial_value) {
|
||||
if (!local_signal_.IsSharedObjectAllocationValid()) throw std::bad_alloc();
|
||||
local_signal_.shared_object()->amd_signal.value = initial_value;
|
||||
}
|
||||
|
||||
SharedSignal* signal() const { return local_signal_.shared_object(); }
|
||||
|
||||
private:
|
||||
Shared<SharedSignal, AMD_SIGNAL_ALIGN_BYTES> local_signal_;
|
||||
};
|
||||
|
||||
/// @brief An abstract base class which helps implement the public hsa_signal_t
|
||||
/// type (an opaque handle) and its associated APIs. At its core, signal uses
|
||||
/// a 32 or 64 bit value. This value can be waitied on or signaled atomically
|
||||
/// using specified memory ordering semantics.
|
||||
class Signal : public Checked<0x71FCCA6A3D5D5276>,
|
||||
public Shared<SharedSignal, AMD_SIGNAL_ALIGN_BYTES> {
|
||||
class Signal {
|
||||
public:
|
||||
/// @brief Constructor initializes the signal with initial value.
|
||||
explicit Signal(hsa_signal_value_t initial_value)
|
||||
: Shared(),
|
||||
signal_(shared_object()->amd_signal),
|
||||
async_copy_agent_(NULL) {
|
||||
if (!Shared::IsSharedObjectAllocationValid()) {
|
||||
invalid_ = true;
|
||||
return;
|
||||
}
|
||||
/// @brief Constructor Links and publishes the signal interface object.
|
||||
explicit Signal(SharedSignal* abi_block)
|
||||
: signal_(abi_block->amd_signal), async_copy_agent_(NULL) {
|
||||
if (abi_block == nullptr) throw std::bad_alloc();
|
||||
|
||||
shared_object()->core_signal = this;
|
||||
|
||||
signal_.kind = AMD_SIGNAL_KIND_INVALID;
|
||||
signal_.value = initial_value;
|
||||
invalid_ = false;
|
||||
waiting_ = 0;
|
||||
retained_ = 0;
|
||||
|
||||
abi_block->core_signal = this;
|
||||
}
|
||||
|
||||
virtual ~Signal() { signal_.kind = AMD_SIGNAL_KIND_INVALID; }
|
||||
virtual ~Signal() { invalid_ = true; }
|
||||
|
||||
bool IsValid() const {
|
||||
if (CheckedType::IsValid() && !invalid_) return true;
|
||||
return false;
|
||||
}
|
||||
bool IsValid() const { return !invalid_; }
|
||||
|
||||
/// @brief Converts from this implementation class to the public
|
||||
/// hsa_signal_t type - an opaque handle.
|
||||
static __forceinline hsa_signal_t Convert(Signal* signal) {
|
||||
const uint64_t handle =
|
||||
(signal != NULL && signal->IsValid())
|
||||
? static_cast<uint64_t>(
|
||||
reinterpret_cast<uintptr_t>(&signal->signal_))
|
||||
: 0;
|
||||
assert(signal != nullptr && signal->IsValid() && "Conversion on invalid Signal object.");
|
||||
const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));
|
||||
const hsa_signal_t signal_handle = {handle};
|
||||
return signal_handle;
|
||||
}
|
||||
@@ -115,11 +134,8 @@ class Signal : public Checked<0x71FCCA6A3D5D5276>,
|
||||
/// @brief Converts from this implementation class to the public
|
||||
/// hsa_signal_t type - an opaque handle.
|
||||
static __forceinline const hsa_signal_t Convert(const Signal* signal) {
|
||||
const uint64_t handle =
|
||||
(signal != NULL && signal->IsValid())
|
||||
? static_cast<uint64_t>(
|
||||
reinterpret_cast<uintptr_t>(&signal->signal_))
|
||||
: 0;
|
||||
assert(signal != nullptr && signal->IsValid() && "Conversion on invalid Signal object.");
|
||||
const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));
|
||||
const hsa_signal_t signal_handle = {handle};
|
||||
return signal_handle;
|
||||
}
|
||||
@@ -127,13 +143,11 @@ class Signal : public Checked<0x71FCCA6A3D5D5276>,
|
||||
/// @brief Converts from public hsa_signal_t type (an opaque handle) to
|
||||
/// this implementation class object.
|
||||
static __forceinline Signal* Convert(hsa_signal_t signal) {
|
||||
return (signal.handle != 0)
|
||||
? reinterpret_cast<const SharedSignal*>(
|
||||
static_cast<uintptr_t>(signal.handle) -
|
||||
(reinterpret_cast<uintptr_t>(
|
||||
&reinterpret_cast<SharedSignal*>(1234)->amd_signal) -
|
||||
uintptr_t(1234)))->core_signal
|
||||
: NULL;
|
||||
SharedSignal* shared = SharedSignal::Convert(signal);
|
||||
if (shared->core_signal != nullptr)
|
||||
return shared->core_signal;
|
||||
else
|
||||
throw std::bad_cast();
|
||||
}
|
||||
|
||||
// Below are various methods corresponding to the APIs, which load/store the
|
||||
|
||||
@@ -77,18 +77,11 @@ volatile uint32_t AqlQueue::queue_count_ = 0;
|
||||
KernelMutex AqlQueue::queue_lock_;
|
||||
int AqlQueue::rtti_id_;
|
||||
|
||||
void* AqlQueue::operator new(size_t size) {
|
||||
// Align base to 64B to enforce amd_queue_ member alignment.
|
||||
return _aligned_malloc(size, kAmdQueueAlignBytes);
|
||||
}
|
||||
|
||||
void AqlQueue::operator delete(void* ptr) { _aligned_free(ptr); }
|
||||
|
||||
AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id,
|
||||
ScratchInfo& scratch, core::HsaEventCallback callback,
|
||||
void* err_data, bool is_kv)
|
||||
AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id, ScratchInfo& scratch,
|
||||
core::HsaEventCallback callback, void* err_data, bool is_kv)
|
||||
: Queue(),
|
||||
Signal(0),
|
||||
LocalSignal(0),
|
||||
Signal(signal()),
|
||||
ring_buf_(NULL),
|
||||
ring_buf_alloc_bytes_(0),
|
||||
queue_id_(HSA_QUEUEID(-1)),
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace core {
|
||||
int DefaultSignal::rtti_id_ = 0;
|
||||
|
||||
DefaultSignal::DefaultSignal(hsa_signal_value_t initial_value)
|
||||
: Signal(initial_value) {
|
||||
: LocalSignal(initial_value), Signal(signal()) {
|
||||
signal_.kind = AMD_SIGNAL_KIND_USER;
|
||||
signal_.event_mailbox_ptr = NULL;
|
||||
HSA::hsa_memory_register(this, sizeof(DefaultSignal));
|
||||
|
||||
文件差异内容过多而无法显示
加载差异
@@ -40,6 +40,10 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <new>
|
||||
#include <typeinfo>
|
||||
#include <exception>
|
||||
|
||||
#include "hsakmt.h"
|
||||
|
||||
#include "core/inc/runtime.h"
|
||||
@@ -109,11 +113,37 @@ static __forceinline bool IsValid(T* ptr) {
|
||||
return (ptr == NULL) ? NULL : ptr->IsValid();
|
||||
}
|
||||
|
||||
#define TRY try {
|
||||
#define CATCH } catch(...) { return AMD::handleException(); }
|
||||
#define CATCHRET(RETURN_TYPE) } catch(...) { return AMD::handleExceptionT<RETURN_TYPE>(); }
|
||||
|
||||
namespace AMD {
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_coherency_get_type(hsa_agent_t agent_handle,
|
||||
hsa_amd_coherency_type_t* type) {
|
||||
hsa_status_t handleException() {
|
||||
try {
|
||||
throw;
|
||||
} catch (const std::bad_alloc& e) {
|
||||
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
|
||||
} catch (const std::bad_cast& e) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
} catch (std::nested_exception& e) { // Rethrow exceptions from callbacks after unwinding HSA.
|
||||
e.rethrow_nested();
|
||||
return HSA_STATUS_ERROR;
|
||||
} catch (...) {
|
||||
assert(false && "Unhandled exception.");
|
||||
abort();
|
||||
return HSA_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T> static __forceinline T handleExceptionT() {
|
||||
handleException();
|
||||
abort();
|
||||
return T();
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_coherency_get_type(hsa_agent_t agent_handle, hsa_amd_coherency_type_t* type) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
const core::Agent* agent = core::Agent::Convert(agent_handle);
|
||||
@@ -132,10 +162,12 @@ hsa_status_t
|
||||
*type = gpu_agent->current_coherency_type();
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent_handle,
|
||||
hsa_amd_coherency_type_t type) {
|
||||
hsa_amd_coherency_type_t type) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
core::Agent* agent = core::Agent::Convert(agent_handle);
|
||||
@@ -158,10 +190,11 @@ hsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent_handle,
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {
|
||||
hsa_status_t hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (ptr == NULL) {
|
||||
@@ -173,17 +206,15 @@ hsa_status_t
|
||||
}
|
||||
|
||||
return core::Runtime::runtime_singleton_->FillMemory(ptr, value, count);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent_handle,
|
||||
const void* src, hsa_agent_t src_agent_handle,
|
||||
size_t size, uint32_t num_dep_signals,
|
||||
const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal) {
|
||||
if (dst == NULL || src == NULL) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
hsa_status_t hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent_handle, const void* src,
|
||||
hsa_agent_t src_agent_handle, size_t size,
|
||||
uint32_t num_dep_signals, const hsa_signal_t* dep_signals,
|
||||
hsa_signal_t completion_signal) {
|
||||
TRY
|
||||
if (dst == NULL || src == NULL) { return HSA_STATUS_ERROR_INVALID_ARGUMENT; }
|
||||
|
||||
if ((num_dep_signals == 0 && dep_signals != NULL) ||
|
||||
(num_dep_signals > 0 && dep_signals == NULL)) {
|
||||
@@ -215,10 +246,11 @@ hsa_status_t
|
||||
}
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {
|
||||
hsa_status_t hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
core::Queue* cmd_queue = core::Queue::Convert(queue);
|
||||
@@ -229,9 +261,11 @@ hsa_status_t
|
||||
AMD_QUEUE_PROPERTIES_ENABLE_PROFILING, (enable != 0));
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_profiling_async_copy_enable(bool enable) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
return core::Runtime::runtime_singleton_->IterateAgent(
|
||||
@@ -240,11 +274,13 @@ hsa_status_t hsa_amd_profiling_async_copy_enable(bool enable) {
|
||||
return core::Agent::Convert(agent_handle)->profiling_enabled(enable);
|
||||
},
|
||||
reinterpret_cast<void*>(&enable));
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_profiling_get_dispatch_time(
|
||||
hsa_agent_t agent_handle, hsa_signal_t hsa_signal,
|
||||
hsa_amd_profiling_dispatch_time_t* time) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
IS_BAD_PTR(time);
|
||||
@@ -267,10 +303,12 @@ hsa_status_t hsa_amd_profiling_get_dispatch_time(
|
||||
gpu_agent->TranslateTime(signal, *time);
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_profiling_get_async_copy_time(
|
||||
hsa_signal_t hsa_signal, hsa_amd_profiling_async_copy_time_t* time) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
IS_BAD_PTR(time);
|
||||
@@ -295,12 +333,13 @@ hsa_status_t hsa_amd_profiling_get_async_copy_time(
|
||||
time->start = signal->signal_.start_ts;
|
||||
time->end = signal->signal_.end_ts;
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent_handle,
|
||||
uint64_t agent_tick,
|
||||
uint64_t* system_tick) {
|
||||
hsa_status_t hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent_handle,
|
||||
uint64_t agent_tick,
|
||||
uint64_t* system_tick) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
IS_BAD_PTR(system_tick);
|
||||
@@ -318,31 +357,28 @@ hsa_status_t
|
||||
*system_tick = gpu_agent->TranslateTime(agent_tick);
|
||||
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
uint32_t
|
||||
hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* hsa_signals,
|
||||
hsa_signal_condition_t* conds,
|
||||
hsa_signal_value_t* values, uint64_t timeout_hint,
|
||||
hsa_wait_state_t wait_hint,
|
||||
hsa_signal_value_t* satisfying_value) {
|
||||
uint32_t hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* hsa_signals,
|
||||
hsa_signal_condition_t* conds, hsa_signal_value_t* values,
|
||||
uint64_t timeout_hint, hsa_wait_state_t wait_hint,
|
||||
hsa_signal_value_t* satisfying_value) {
|
||||
TRY
|
||||
// Do not check for signal invalidation. Invalidation may occur during async
|
||||
// signal handler loop and is not an error.
|
||||
for (uint i = 0; i < signal_count; i++)
|
||||
assert(hsa_signals[i].handle != 0 &&
|
||||
static_cast<core::Checked<0x71FCCA6A3D5D5276>*>(
|
||||
core::Signal::Convert(hsa_signals[i]))->IsValid() &&
|
||||
"Invalid signal.");
|
||||
assert(core::SharedSignal::Convert(hsa_signals[i])->IsValid() && "Invalid signal.");
|
||||
|
||||
return core::Signal::WaitAny(signal_count, hsa_signals, conds, values,
|
||||
timeout_hint, wait_hint, satisfying_value);
|
||||
CATCHRET(uint32_t)
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_signal_async_handler(hsa_signal_t hsa_signal,
|
||||
hsa_signal_condition_t cond,
|
||||
hsa_signal_value_t value,
|
||||
hsa_amd_signal_handler handler, void* arg) {
|
||||
hsa_status_t hsa_amd_signal_async_handler(hsa_signal_t hsa_signal, hsa_signal_condition_t cond,
|
||||
hsa_signal_value_t value, hsa_amd_signal_handler handler,
|
||||
void* arg) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
core::Signal* signal = core::Signal::Convert(hsa_signal);
|
||||
@@ -352,10 +388,11 @@ hsa_status_t
|
||||
return HSA_STATUS_ERROR_INVALID_SIGNAL;
|
||||
return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(
|
||||
hsa_signal, cond, value, handler, arg);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_async_function(void (*callback)(void* arg), void* arg) {
|
||||
hsa_status_t hsa_amd_async_function(void (*callback)(void* arg), void* arg) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
IS_BAD_PTR(callback);
|
||||
@@ -363,25 +400,28 @@ hsa_status_t
|
||||
return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(
|
||||
null_signal, HSA_SIGNAL_CONDITION_EQ, 0, (hsa_amd_signal_handler)callback,
|
||||
arg);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue,
|
||||
uint32_t num_cu_mask_count,
|
||||
const uint32_t* cu_mask) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(cu_mask);
|
||||
|
||||
core::Queue* cmd_queue = core::Queue::Convert(queue);
|
||||
IS_VALID(cmd_queue);
|
||||
return cmd_queue->SetCUMasking(num_cu_mask_count, cu_mask);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,
|
||||
hsa_agent_t* agents, int num_agent,
|
||||
void** agent_ptr) {
|
||||
*agent_ptr = NULL;
|
||||
|
||||
hsa_agent_t* agents, int num_agent,
|
||||
void** agent_ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
*agent_ptr = NULL;
|
||||
|
||||
if (size == 0 || host_ptr == NULL || agent_ptr == NULL) {
|
||||
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
|
||||
@@ -397,9 +437,11 @@ hsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,
|
||||
core::Runtime::runtime_singleton_->system_regions_fine()[0]);
|
||||
|
||||
return system_region->Lock(num_agent, agents, host_ptr, size, agent_ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_unlock(void* host_ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
const amd::MemoryRegion* system_region =
|
||||
@@ -407,12 +449,12 @@ hsa_status_t hsa_amd_memory_unlock(void* host_ptr) {
|
||||
core::Runtime::runtime_singleton_->system_regions_fine()[0]);
|
||||
|
||||
return system_region->Unlock(host_ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,
|
||||
hsa_amd_memory_pool_info_t attribute,
|
||||
void* value) {
|
||||
hsa_status_t hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,
|
||||
hsa_amd_memory_pool_info_t attribute, void* value) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(value);
|
||||
|
||||
@@ -423,12 +465,14 @@ hsa_status_t
|
||||
}
|
||||
|
||||
return mem_region->GetPoolInfo(attribute, value);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_agent_iterate_memory_pools(
|
||||
hsa_agent_t agent_handle,
|
||||
hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),
|
||||
void* data) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(callback);
|
||||
const core::Agent* agent = core::Agent::Convert(agent_handle);
|
||||
@@ -446,11 +490,12 @@ hsa_status_t hsa_amd_agent_iterate_memory_pools(
|
||||
reinterpret_cast<hsa_status_t (*)(hsa_region_t memory_pool, void* data)>(
|
||||
callback),
|
||||
data);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,
|
||||
uint32_t flags, void** ptr) {
|
||||
hsa_status_t hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,
|
||||
uint32_t flags, void** ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (size == 0 || ptr == NULL) {
|
||||
@@ -466,15 +511,16 @@ hsa_status_t
|
||||
|
||||
return core::Runtime::runtime_singleton_->AllocateMemory(
|
||||
mem_region, size, core::MemoryRegion::AllocateRestrict, ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_pool_free(void* ptr) {
|
||||
return HSA::hsa_memory_free(ptr);
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,
|
||||
const uint32_t* flags, const void* ptr) {
|
||||
hsa_status_t hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,
|
||||
const uint32_t* flags, const void* ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (num_agents == 0 || agents == NULL || flags != NULL || ptr == NULL) {
|
||||
@@ -483,12 +529,12 @@ hsa_status_t
|
||||
|
||||
return core::Runtime::runtime_singleton_->AllowAccess(num_agents, agents,
|
||||
ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,
|
||||
hsa_amd_memory_pool_t dst_memory_pool,
|
||||
bool* result) {
|
||||
hsa_status_t hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,
|
||||
hsa_amd_memory_pool_t dst_memory_pool, bool* result) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (result == NULL) {
|
||||
@@ -512,11 +558,13 @@ hsa_status_t
|
||||
}
|
||||
|
||||
return src_mem_region->CanMigrate(*dst_mem_region, *result);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_memory_migrate(const void* ptr,
|
||||
hsa_amd_memory_pool_t memory_pool,
|
||||
uint32_t flags) {
|
||||
hsa_amd_memory_pool_t memory_pool,
|
||||
uint32_t flags) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (ptr == NULL || flags != 0) {
|
||||
@@ -532,11 +580,13 @@ hsa_status_t hsa_amd_memory_migrate(const void* ptr,
|
||||
}
|
||||
|
||||
return dst_mem_region->Migrate(flags, ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_agent_memory_pool_get_info(
|
||||
hsa_agent_t agent_handle, hsa_amd_memory_pool_t memory_pool,
|
||||
hsa_amd_agent_memory_pool_info_t attribute, void* value) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
|
||||
if (value == NULL) {
|
||||
@@ -555,6 +605,7 @@ hsa_status_t hsa_amd_agent_memory_pool_get_info(
|
||||
}
|
||||
|
||||
return mem_region->GetAgentPoolInfo(*agent, attribute, value);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
@@ -563,6 +614,7 @@ hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
void** ptr, size_t* metadata_size,
|
||||
const void** metadata) {
|
||||
static const int tinyArraySize=8;
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(agents);
|
||||
IS_BAD_PTR(size);
|
||||
@@ -589,39 +641,49 @@ hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
|
||||
|
||||
if (num_agents > tinyArraySize) delete[] core_agents;
|
||||
return ret;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_interop_unmap_buffer(void* ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
if (ptr != NULL) core::Runtime::runtime_singleton_->InteropUnmap(ptr);
|
||||
return HSA_STATUS_SUCCESS;
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_pointer_info(void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),
|
||||
uint32_t* num_accessible, hsa_agent_t** accessible) {
|
||||
uint32_t* num_accessible, hsa_agent_t** accessible) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(ptr);
|
||||
IS_BAD_PTR(info);
|
||||
return core::Runtime::runtime_singleton_->PtrInfo(ptr, info, alloc, num_accessible, accessible);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_pointer_info_set_userdata(void* ptr, void* userdata) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(ptr);
|
||||
return core::Runtime::runtime_singleton_->SetPtrInfoData(ptr, userdata);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_ipc_memory_create(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(ptr);
|
||||
IS_BAD_PTR(handle);
|
||||
return core::Runtime::runtime_singleton_->IPCCreate(ptr, len, handle);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t len,
|
||||
uint32_t num_agents, const hsa_agent_t* mapping_agents,
|
||||
void** mapped_ptr) {
|
||||
static const int tinyArraySize = 8;
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(mapped_ptr);
|
||||
if (num_agents != 0) IS_BAD_PTR(mapping_agents);
|
||||
@@ -644,12 +706,15 @@ hsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t l
|
||||
|
||||
return core::Runtime::runtime_singleton_->IPCAttach(ipc, len, num_agents, core_agents,
|
||||
mapped_ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
hsa_status_t hsa_amd_ipc_memory_detach(void* mapped_ptr) {
|
||||
TRY
|
||||
IS_OPEN();
|
||||
IS_BAD_PTR(mapped_ptr);
|
||||
return core::Runtime::runtime_singleton_->IPCDetach(mapped_ptr);
|
||||
CATCH
|
||||
}
|
||||
|
||||
} // end of AMD namespace
|
||||
|
||||
@@ -68,9 +68,8 @@ int InterruptSignal::rtti_id_ = 0;
|
||||
|
||||
void InterruptSignal::DestroyEvent(HsaEvent* evt) { hsaKmtDestroyEvent(evt); }
|
||||
|
||||
InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value,
|
||||
HsaEvent* use_event)
|
||||
: Signal(initial_value) {
|
||||
InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value, HsaEvent* use_event)
|
||||
: LocalSignal(initial_value), Signal(signal()) {
|
||||
if (use_event != NULL) {
|
||||
event_ = use_event;
|
||||
free_event_ = false;
|
||||
|
||||
在新工单中引用
屏蔽一个用户