diff --git a/hipamd/src/hip_event.cpp b/hipamd/src/hip_event.cpp index 9a036127e2..51e462d1f7 100644 --- a/hipamd/src/hip_event.cpp +++ b/hipamd/src/hip_event.cpp @@ -39,6 +39,16 @@ bool Event::ready() { return ready; } +bool EventDD::ready() { + // Check HW status of the ROCcrl event. Note: not all ROCclr modes support HW status + bool ready = g_devices[deviceId()]->devices()[0]->IsHwEventReady(*event_); + // FIXME: Remove status check entirely + if (!ready) { + ready = (event_->status() == CL_COMPLETE); + } + return ready; +} + hipError_t Event::query() { amd::ScopedLock lock(lock_); @@ -67,10 +77,18 @@ hipError_t Event::synchronize() { return hipSuccess; } +bool Event::awaitEventCompletion() { + return event_->awaitCompletion(); +} + +bool EventDD::awaitEventCompletion() { + return g_devices[deviceId()]->devices()[0]->IsHwEventReady(*event_, true); +} + hipError_t Event::elapsedTime(Event& eStop, float& ms) { amd::ScopedLock startLock(lock_); - if (this == &eStop) { + ms = 0.f; if (event_ == nullptr) { return hipErrorInvalidHandle; } @@ -83,12 +101,11 @@ hipError_t Event::elapsedTime(Event& eStop, float& ms) { return hipErrorNotReady; } - ms = 0.f; return hipSuccess; } - amd::ScopedLock stopLock(eStop.lock_); + amd::ScopedLock stopLock(eStop.lock()); - if (event_ == nullptr || eStop.event_ == nullptr) { + if (event_ == nullptr || eStop.event() == nullptr) { return hipErrorInvalidHandle; } @@ -100,7 +117,7 @@ hipError_t Event::elapsedTime(Event& eStop, float& ms) { return hipErrorNotReady; } - if (event_ == eStop.event_ && recorded_ && eStop.recorded_) { + if (event_ == eStop.event_ && recorded_ && eStop.isRecorded()) { // Events are the same, which indicates the stream is empty and likely // eventRecord is called on another stream. For such cases insert and measure a // marker. @@ -113,8 +130,8 @@ hipError_t Event::elapsedTime(Event& eStop, float& ms) { } else { // Note: with direct dispatch eStop.ready() relies on HW event, but CPU status can be delayed. // Hence for now make sure CPU status is updated by calling awaitCompletion(); - event_->awaitCompletion(); - eStop.event_->awaitCompletion(); + awaitEventCompletion(); + eStop.awaitEventCompletion(); ms = static_cast(eStop.time() - time()) / 1000000.f; } return hipSuccess; @@ -129,6 +146,21 @@ int64_t Event::time() const { } } +int64_t EventDD::time() const { + uint64_t start = 0, end = 0; + assert(event_ != nullptr); + g_devices[deviceId()]->devices()[0]->getHwEventTime(*event_, &start, &end); + // FIXME: This is only needed if the command had to wait CL_COMPLETE status + if (start == 0 || end == 0) { + return Event::time(); + } + if (recorded_) { + return static_cast(end); + } else { + return static_cast(start); + } +} + hipError_t Event::streamWaitCommand(amd::Command*& command, amd::HostQueue* queue) { amd::Command::EventWaitList eventWaitList; if (event_ != nullptr) { @@ -225,7 +257,11 @@ hipError_t ihipEventCreateWithFlags(hipEvent_t* event, unsigned flags) { if (flags & hipEventInterprocess) { e = new hip::IPCEvent(); } else { - e = new hip::Event(flags); + if (AMD_DIRECT_DISPATCH) { + e = new hip::EventDD(flags); + } else { + e = new hip::Event(flags); + } } if (e == nullptr) { return hipErrorOutOfMemory; diff --git a/hipamd/src/hip_event.hpp b/hipamd/src/hip_event.hpp index 831083d001..89095b5c73 100644 --- a/hipamd/src/hip_event.hpp +++ b/hipamd/src/hip_event.hpp @@ -111,6 +111,7 @@ class Event { amd::Monitor& lock() { return lock_; } const int deviceId() const { return device_id_; } void setDeviceId(int id) { device_id_ = id; } + amd::Event* event() { return event_; } /// End capture on this event void EndCapture() { @@ -140,6 +141,9 @@ class Event { virtual hipError_t OpenHandle(ihipIpcEventHandle_t* handle) { return hipErrorInvalidConfiguration; } + virtual bool awaitEventCompletion(); + virtual bool ready(); + virtual int64_t time() const; protected: amd::Monitor lock_; @@ -150,9 +154,16 @@ class Event { //! hip*ModuleLaunchKernel API which takes start and stop events so no //! hipEventRecord is called. Cleanup needed once those APIs are deprecated. bool recorded_; +}; - bool ready(); - int64_t time() const; +class EventDD : public Event { + public: + EventDD(unsigned int flags) : Event(flags) {} + virtual ~EventDD() {} + + virtual bool awaitEventCompletion(); + virtual bool ready(); + virtual int64_t time() const; }; class IPCEvent : public Event {