SWDEV-482692, SWDEV-485802, SWDEV-485489 - Handle refcounts owned by graph for user objects.
Change-Id: Ic739ab1ec5d3dc3143e3ae70f9591922bc0e3d9f
[ROCm/clr commit: e74ac6f580]
Этот коммит содержится в:
коммит произвёл
Jaydeepkumar Patel
родитель
3130b4639f
Коммит
b31bf885a3
@@ -2758,8 +2758,13 @@ hipError_t hipUserObjectRelease(hipUserObject_t object, unsigned int count) {
|
||||
HIP_RETURN(hipSuccess);
|
||||
}
|
||||
//! If all the counts are gone not longer need the obj in the list
|
||||
//! If user object is about to be deleted, It's reference needs to be
|
||||
//! removed from graph's user object list.
|
||||
if (userObject->referenceCount() == count) {
|
||||
hip::UserObject::removeUSerObj(userObject);
|
||||
for (auto& g : userObject->owning_graphs_) {
|
||||
g->RemoveUserObjGraph(userObject);
|
||||
}
|
||||
}
|
||||
userObject->decreaseRefCount(count);
|
||||
HIP_RETURN(hipSuccess);
|
||||
@@ -2796,11 +2801,10 @@ hipError_t hipGraphRetainUserObject(hipGraph_t graph, hipUserObject_t object, un
|
||||
if (status != hipSuccess) {
|
||||
HIP_RETURN(status);
|
||||
}
|
||||
} else {
|
||||
//! if flag is UserObjMove delete userobj from list
|
||||
hip::UserObject::removeUSerObj(userObject);
|
||||
}
|
||||
g->addUserObjGraph(userObject);
|
||||
userObject->owning_graphs_.insert(g);
|
||||
g->IncrementGraphUserObjRefCount(userObject, count);
|
||||
HIP_RETURN(status);
|
||||
}
|
||||
|
||||
@@ -2814,11 +2818,14 @@ hipError_t hipGraphReleaseUserObject(hipGraph_t graph, hipUserObject_t object, u
|
||||
if (!g->isUserObjGraphValid(userObject) || userObject->referenceCount() < count) {
|
||||
HIP_RETURN(hipSuccess);
|
||||
}
|
||||
g->DecrementGraphUserObjRefCount(userObject, count);
|
||||
//! Obj is being destroyed
|
||||
unsigned int releaseCount =
|
||||
(userObject->referenceCount() < count) ? userObject->referenceCount() : count;
|
||||
if (userObject->referenceCount() == releaseCount) {
|
||||
g->RemoveUserObjGraph(userObject);
|
||||
//! If user object is about to be deleted, Its owner needs to be updated.
|
||||
userObject->owning_graphs_.erase(g);
|
||||
}
|
||||
hipError_t status = hip::hipUserObjectRelease(object, count);
|
||||
HIP_RETURN(status);
|
||||
|
||||
@@ -357,9 +357,12 @@ Graph* Graph::clone(std::unordered_map<Node, Node>& clonedNodes) const {
|
||||
}
|
||||
clonedNodes[node]->SetDependencies(clonedDependencies);
|
||||
}
|
||||
for (auto userObj : graphUserObj_) {
|
||||
userObj->retain();
|
||||
for (auto& userObj : graphUserObj_) {
|
||||
userObj.first->retain();
|
||||
newGraph->graphUserObj_.insert(userObj);
|
||||
// Clone graph should have its separate graph owned ref count = 1
|
||||
newGraph->graphUserObj_[userObj.first] = 1;
|
||||
userObj.first->owning_graphs_.insert(newGraph);
|
||||
}
|
||||
// Clone the root nodes to the new graph
|
||||
if (roots_.size() > 0) {
|
||||
|
||||
@@ -58,7 +58,10 @@ struct UserObject : public amd::ReferenceCountedObject {
|
||||
typedef void (*UserCallbackDestructor)(void* data);
|
||||
static std::unordered_set<UserObject*> ObjectSet_;
|
||||
static amd::Monitor UserObjectLock_;
|
||||
|
||||
// Graphs owns this user object.
|
||||
// In case if User object is about to be deleted (last release()), Pointer refering to it
|
||||
// should be cleared from Graph's list of user object.
|
||||
std::unordered_set<Graph*> owning_graphs_;
|
||||
public:
|
||||
UserObject(UserCallbackDestructor callback, void* data, unsigned int flags)
|
||||
: ReferenceCountedObject(), callback_(callback), data_(data), flags_(flags) {
|
||||
@@ -72,6 +75,7 @@ struct UserObject : public amd::ReferenceCountedObject {
|
||||
callback_(data_);
|
||||
}
|
||||
ObjectSet_.erase(this);
|
||||
owning_graphs_.clear();
|
||||
}
|
||||
|
||||
void increaseRefCount(const unsigned int refCount) {
|
||||
@@ -478,7 +482,8 @@ struct Graph {
|
||||
const Graph* pOriginalGraph_ = nullptr;
|
||||
static std::unordered_set<Graph*> graphSet_;
|
||||
static amd::Monitor graphSetLock_;
|
||||
std::unordered_set<UserObject*> graphUserObj_;
|
||||
//!<graphUserObj_.second stores refcount owned by this graph for user object,
|
||||
std::unordered_map<UserObject*, int> graphUserObj_;
|
||||
unsigned int id_;
|
||||
static int nextID;
|
||||
int max_streams_ = 0; //!< Maximum number of extra streams used in the graph launch
|
||||
@@ -508,16 +513,38 @@ struct Graph {
|
||||
leafs_.resize(DEBUG_HIP_FORCE_GRAPH_QUEUES);
|
||||
wait_order_.resize(DEBUG_HIP_FORCE_GRAPH_QUEUES);
|
||||
}
|
||||
|
||||
void RemoveUserObjectFromOwingGraphs(UserObject* uObj) {
|
||||
for (auto& g : uObj->owning_graphs_) {
|
||||
if (g != this) {
|
||||
g->RemoveUserObjGraph(uObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
~Graph() {
|
||||
for (auto node : vertices_) {
|
||||
delete node;
|
||||
}
|
||||
amd::ScopedLock lock(graphSetLock_);
|
||||
graphSet_.erase(this);
|
||||
for (auto userobj : graphUserObj_) {
|
||||
userobj->release();
|
||||
for (auto& userobj : graphUserObj_) {
|
||||
// Graph is destorying so remove it from user object's graph list.
|
||||
userobj.first->owning_graphs_.erase(this);
|
||||
// Bypass if graph owned refcount is more then actual refcount of user object
|
||||
if (userobj.second > userobj.first->referenceCount()) {
|
||||
continue;
|
||||
}
|
||||
// User object is about to die and hence remove it.
|
||||
if (userobj.first->referenceCount() == userobj.second) {
|
||||
RemoveUserObjectFromOwingGraphs(userobj.first);
|
||||
}
|
||||
// Release user object = # of times it is owned by this graph.
|
||||
for (int i = 0; i < userobj.second; i++) {
|
||||
if (userobj.first->referenceCount() >= 1) {
|
||||
userobj.first->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
graphUserObj_.clear();
|
||||
if (mem_pool_ != nullptr) {
|
||||
mem_pool_->release();
|
||||
}
|
||||
@@ -558,7 +585,23 @@ struct Graph {
|
||||
// Add user obj resource to graph
|
||||
void addUserObjGraph(UserObject* pUserObj) {
|
||||
amd::ScopedLock lock(graphSetLock_);
|
||||
graphUserObj_.insert(pUserObj);
|
||||
graphUserObj_.insert({pUserObj, 0});
|
||||
}
|
||||
// Increments graphUserObj_.second.
|
||||
void IncrementGraphUserObjRefCount(UserObject* pUserObj, unsigned int count) {
|
||||
amd::ScopedLock lock(graphSetLock_);
|
||||
auto it = graphUserObj_.find(pUserObj);
|
||||
if (it != graphUserObj_.end()) {
|
||||
it->second += count;
|
||||
}
|
||||
}
|
||||
// Decrements graphUserObj_.second.
|
||||
void DecrementGraphUserObjRefCount(UserObject* pUserObj, unsigned int count) {
|
||||
amd::ScopedLock lock(graphSetLock_);
|
||||
auto it = graphUserObj_.find(pUserObj);
|
||||
if (it != graphUserObj_.end()) {
|
||||
it->second -= count;
|
||||
}
|
||||
}
|
||||
// Check user obj resource from graph is valid
|
||||
bool isUserObjGraphValid(UserObject* pUserObj) {
|
||||
|
||||
Ссылка в новой задаче
Block a user