SWDEV-325711: Add userobject functions for graph

- add user obj APIs for creating release and retain of user onbjects

Signed-off-by: sdashmiz <shadi.dashmiz@amd.com>
Change-Id: I0bf2999c77e44269565b27c31c7c1461f8a160a2
This commit is contained in:
sdashmiz authored and Shadi Dashmiz committed 2022-08-17 14:31:43 -04:00
1 والد a682934251
کامیت 2c010dec17
8 files changed
+323 -7

No files matched your search

+6
مشاهده پرونده
@@ -427,3 +427,9 @@ hipMemcpy2DFromArrayAsync_spt
hipMemcpy2DToArrayAsync_spt
hipDrvGetErrorName
hipDrvGetErrorString
hipUserObjectCreate
hipUserObjectRelease
hipUserObjectRetain
hipGraphRetainUserObject
hipGraphReleaseUserObject
+66 -2
مشاهده پرونده
@@ -23,6 +23,7 @@
#include "hip_conversions.hpp"
#include "hip_platform.hpp"
#include "hip_event.hpp"
#include "top.hpp"
std::vector<hip::Stream*> g_captureStreams;
amd::Monitor g_captureStreamsLock{"StreamCaptureGlobalList"};
@@ -1017,10 +1018,12 @@ hipError_t ihipGraphInstantiate(hipGraphExec_t* pGraphExec, hipGraph_t graph) {
}
std::vector<std::vector<Node>> parallelLists;
std::unordered_map<Node, std::vector<Node>> nodeWaitLists;
std::unordered_set<hipUserObject*> graphExeUserObj;
clonedGraph->GetRunList(parallelLists, nodeWaitLists);
std::vector<Node> levelOrder;
clonedGraph->LevelOrder(levelOrder);
*pGraphExec = new hipGraphExec(levelOrder, parallelLists, nodeWaitLists, clonedNodes);
clonedGraph->GetUserObjs(graphExeUserObj);
*pGraphExec = new hipGraphExec(levelOrder, parallelLists, nodeWaitLists, clonedNodes, graphExeUserObj);
if (*pGraphExec != nullptr) {
return (*pGraphExec)->Init();
} else {
@@ -1965,4 +1968,65 @@ hipError_t hipDeviceGraphMemTrim(int device) {
}
// not implemented yet
return HIP_RETURN(hipSuccess);
}
}
hipError_t hipUserObjectCreate(hipUserObject_t* object_out, void* ptr, hipHostFn_t destroy, unsigned int initialRefcount, unsigned int flags) {
HIP_INIT_API(hipUserObjectCreate, object_out, ptr, destroy, initialRefcount, flags);
if (object_out == nullptr || flags != hipUserObjectNoDestructorSync) {
HIP_RETURN(hipErrorInvalidValue);
}
*object_out = new hipUserObject(destroy, ptr, flags);
//! Creating object adds one reference.
if (initialRefcount > 1) {
(*object_out)->increaseRefCount(static_cast<const unsigned int>(initialRefcount - 1));
}
HIP_RETURN(hipSuccess);
}
hipError_t hipUserObjectRelease(hipUserObject_t object, unsigned int count) {
HIP_INIT_API(hipUserObjectRelease, object, count);
if (object == nullptr || !hipUserObject::isUserObjvalid(object) || (object->referenceCount() < count)) {
HIP_RETURN(hipErrorInvalidValue);
}
object->decreaseRefCount(count);
HIP_RETURN(hipSuccess);
}
hipError_t hipUserObjectRetain(hipUserObject_t object, unsigned int count) {
HIP_INIT_API(hipUserObjectRetain, object, count);
if (object == nullptr || !hipUserObject::isUserObjvalid(object)) {
HIP_RETURN(hipErrorInvalidValue);
}
object->increaseRefCount(count);
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphRetainUserObject(hipGraph_t graph, hipUserObject_t object, unsigned int count, unsigned int flags) {
HIP_INIT_API(hipGraphRetainUserObject, graph, object, count, flags);
hipError_t status = hipSuccess;
if (graph == nullptr || object == nullptr || !hipUserObject::isUserObjvalid(object)) {
HIP_RETURN(hipErrorInvalidValue);
}
if (flags != hipGraphUserObjectMove) {
status = hipUserObjectRetain(object, count);
if (status != hipSuccess) {
HIP_RETURN(status);
}
}
graph->addUserObjGraph(object);
HIP_RETURN(status);
}
hipError_t hipGraphReleaseUserObject(hipGraph_t graph, hipUserObject_t object, unsigned int count) {
HIP_INIT_API(hipGraphReleaseUserObject, graph, object, count);
if (graph == nullptr || object == nullptr || !ihipGraph::isUserObjGraphValid(object)) {
HIP_RETURN(hipErrorInvalidValue);
}
//! Obj is being destroyed
if (object->referenceCount() == count) {
graph->RemoveUserObjGraph(object);
}
hipError_t status = hipUserObjectRelease(object, count);
HIP_RETURN(status);
}
@@ -53,6 +53,9 @@ std::unordered_set<ihipGraph*> ihipGraph::graphSet_;
amd::Monitor ihipGraph::graphSetLock_{"Guards global graph set"};
std::unordered_set<hipGraphExec*> hipGraphExec::graphExecSet_;
amd::Monitor hipGraphExec::graphExecSetLock_{"Guards global exec graph set"};
std::unordered_set<hipUserObject*> hipUserObject::ObjectSet_;
amd::Monitor hipUserObject::UserObjectLock_{"Guards global user object"};
std::unordered_set<hipUserObject*> ihipGraph::graphUserObj_;
hipError_t hipGraphMemcpyNode1D::ValidateParams(void* dst, const void* src, size_t count,
hipMemcpyKind kind) {
@@ -635,7 +638,6 @@ void ihipGraph::LevelOrder(std::vector<Node>& levelOrder) {
const ihipGraph* ihipGraph::getOriginalGraph() const {
return pOriginalGraph_;
}
void ihipGraph::setOriginalGraph(const ihipGraph* pOriginalGraph) {
pOriginalGraph_ = pOriginalGraph;
}
@@ -43,6 +43,55 @@ hipError_t FillCommands(std::vector<std::vector<Node>>& parallelLists,
void UpdateQueue(std::vector<std::vector<Node>>& parallelLists, amd::HostQueue*& queue,
hipGraphExec* ptr);
struct hipUserObject : public amd::ReferenceCountedObject {
typedef void(*UserCallbackDestructor)(void* data);
static std::unordered_set<hipUserObject*> ObjectSet_;
static amd::Monitor UserObjectLock_;
public:
hipUserObject(UserCallbackDestructor callback, void* data, unsigned int flags) : ReferenceCountedObject(),
callback_(callback), data_(data), flags_(flags) {
amd::ScopedLock lock(UserObjectLock_);
ObjectSet_.insert(this);
}
virtual ~hipUserObject() {
amd::ScopedLock lock(UserObjectLock_);
if (callback_ != nullptr) {
callback_(data_);
}
ObjectSet_.erase(this);
}
void increaseRefCount(const unsigned int refCount) {
for (uint32_t i = 0; i < refCount; i++) {
retain();
}
}
void decreaseRefCount(const unsigned int refCount) {
assert((refCount <= referenceCount()) && "count is bigger than refcount");
for (uint32_t i = 0; i < refCount; i++) {
release();
}
}
static bool isUserObjvalid(hipUserObject* pUsertObj) {
amd::ScopedLock lock(UserObjectLock_);
if (ObjectSet_.find(pUsertObj) == ObjectSet_.end()) {
return false;
}
return true;
}
private:
UserCallbackDestructor callback_;
void* data_;
unsigned int flags_;
//! Disable default operator=
hipUserObject& operator=(const hipUserObject&) = delete;
//! Disable copy constructor
hipUserObject(const hipUserObject& obj) = delete;
};
struct hipGraphNode {
protected:
amd::HostQueue* queue_;
@@ -237,6 +286,7 @@ struct ihipGraph {
const ihipGraph* pOriginalGraph_ = nullptr;
static std::unordered_set<ihipGraph*> graphSet_;
static amd::Monitor graphSetLock_;
static std::unordered_set<hipUserObject*> graphUserObj_;
public:
ihipGraph() {
@@ -250,6 +300,9 @@ struct ihipGraph {
}
amd::ScopedLock lock(graphSetLock_);
graphSet_.erase(this);
for (auto userobj : graphUserObj_) {
userobj->release();
}
};
// check graphs validity
@@ -272,6 +325,24 @@ struct ihipGraph {
std::vector<std::pair<Node, Node>> GetEdges() const;
// returns the original graph ptr if cloned
const ihipGraph* getOriginalGraph() const;
// Add user obj resource to graph
void addUserObjGraph(hipUserObject* pUserObj) {
amd::ScopedLock lock(graphSetLock_);
graphUserObj_.insert(pUserObj);
}
// Check user obj resource from graph is valid
static bool isUserObjGraphValid(hipUserObject* pUserObj) {
amd::ScopedLock lock(graphSetLock_);
if (graphUserObj_.find(pUserObj) == graphUserObj_.end()) {
return false;
}
return true;
}
// Delete user obj resource from graph
void RemoveUserObjGraph(hipUserObject* pUserObj) {
amd::ScopedLock lock(graphSetLock_);
graphUserObj_.erase(pUserObj);
}
// saves the original graph ptr if cloned
void setOriginalGraph(const ihipGraph* pOriginalGraph);
@@ -281,6 +352,14 @@ struct ihipGraph {
void GetRunList(std::vector<std::vector<Node>>& parallelLists,
std::unordered_map<Node, std::vector<Node>>& dependencies);
void LevelOrder(std::vector<Node>& levelOrder);
void GetUserObjs( std::unordered_set<hipUserObject*>& graphExeUserObjs) {
for(auto userObj : graphUserObj_)
{
amd::ScopedLock lock(graphSetLock_);
userObj->retain();
graphExeUserObjs.insert(userObj);
}
}
ihipGraph* clone(std::unordered_map<Node, Node>& clonedNodes) const;
ihipGraph* clone() const;
};
@@ -295,17 +374,19 @@ struct hipGraphExec {
std::unordered_map<Node, Node> clonedNodes_;
amd::Command* lastEnqueuedCommand_;
static std::unordered_set<hipGraphExec*> graphExecSet_;
std::unordered_set<hipUserObject*> graphExeUserObj_;
static amd::Monitor graphExecSetLock_;
public:
hipGraphExec(std::vector<Node>& levelOrder, std::vector<std::vector<Node>>& lists,
std::unordered_map<Node, std::vector<Node>>& nodeWaitLists,
std::unordered_map<Node, Node>& clonedNodes)
std::unordered_map<Node, Node>& clonedNodes, std::unordered_set<hipUserObject*>& userObjs)
: parallelLists_(lists),
levelOrder_(levelOrder),
nodeWaitLists_(nodeWaitLists),
clonedNodes_(clonedNodes),
lastEnqueuedCommand_(nullptr),
graphExeUserObj_(userObjs),
currentQueueIndex_(0) {
amd::ScopedLock lock(graphExecSetLock_);
graphExecSet_.insert(this);
@@ -319,6 +400,9 @@ struct hipGraphExec {
}
for (auto it = clonedNodes_.begin(); it != clonedNodes_.end(); it++) delete it->second;
amd::ScopedLock lock(graphExecSetLock_);
for (auto userobj : graphExeUserObj_) {
userobj->release();
}
graphExecSet_.erase(this);
}
+6 -1
مشاهده پرونده
@@ -440,4 +440,9 @@ hipMemcpyFromArray_spt
hipMemcpy2DToArray_spt
hipMemcpy2DFromArrayAsync_spt
hipDrvGetErrorName
hipDrvGetErrorString
hipDrvGetErrorString
hipUserObjectCreate
hipUserObjectRelease
hipUserObjectRetain
hipGraphRetainUserObject
hipGraphReleaseUserObject
@@ -441,6 +441,11 @@ global:
hipMemRetainAllocationHandle;
hipMemSetAccess;
hipMemUnmap;
hipUserObjectCreate;
hipUserObjectRelease;
hipUserObjectRetain;
hipGraphRetainUserObject;
hipGraphReleaseUserObject;
local:
*;
} hip_5.0;