diff --git a/hipamd/src/amdhip.def b/hipamd/src/amdhip.def index a0becb5fc8..b2fcb01274 100644 --- a/hipamd/src/amdhip.def +++ b/hipamd/src/amdhip.def @@ -344,3 +344,4 @@ hipGraphAddHostNode hipGraphHostNodeGetParams hipGraphHostNodeSetParams hipGraphExecHostNodeSetParams +hipGraphExecUpdate diff --git a/hipamd/src/hip_graph.cpp b/hipamd/src/hip_graph.cpp index a24d71b793..b0d28b7769 100644 --- a/hipamd/src/hip_graph.cpp +++ b/hipamd/src/hip_graph.cpp @@ -1408,3 +1408,38 @@ hipError_t hipGraphExecHostNodeSetParams(hipGraphExec_t hGraphExec, hipGraphNode } HIP_RETURN(reinterpret_cast(clonedNode)->SetParams(pNodeParams)); } + +hipError_t hipGraphExecUpdate(hipGraphExec_t hGraphExec, hipGraph_t hGraph, + hipGraphNode_t* hErrorNode_out, + hipGraphExecUpdateResult* updateResult_out) { + HIP_INIT_API(hipGraphExecUpdate, hGraphExec, hGraph, hErrorNode_out, updateResult_out); + std::vector newGraphNodes; + hGraph->LevelOrder(newGraphNodes); + std::vector& oldGraphExecNodes = hGraphExec->GetNodes(); + if (newGraphNodes.size() != oldGraphExecNodes.size()) { + *updateResult_out = hipGraphExecUpdateErrorTopologyChanged; + HIP_RETURN(hipErrorGraphExecUpdateFailure); + } + for (std::vector::size_type i = 0; i != newGraphNodes.size(); i++) { + if (newGraphNodes[i]->GetType() == oldGraphExecNodes[i]->GetType()) { + hipError_t status = oldGraphExecNodes[i]->SetParams(newGraphNodes[i]); + if (status != hipSuccess) { + *hErrorNode_out = newGraphNodes[i]; + if (status == hipErrorInvalidDeviceFunction) { + *updateResult_out = hipGraphExecUpdateErrorUnsupportedFunctionChange; + } else if (status == hipErrorInvalidValue || status == hipErrorInvalidDevicePointer) { + *updateResult_out = hipGraphExecUpdateErrorParametersChanged; + } else { + *updateResult_out = hipGraphExecUpdateErrorNotSupported; + } + HIP_RETURN(hipErrorGraphExecUpdateFailure); + } + } else { + *hErrorNode_out = newGraphNodes[i]; + *updateResult_out = hipGraphExecUpdateErrorNodeTypeChanged; + HIP_RETURN(hipErrorGraphExecUpdateFailure); + } + } + *updateResult_out = hipGraphExecUpdateSuccess; + HIP_RETURN(hipSuccess); +} diff --git a/hipamd/src/hip_graph_internal.hpp b/hipamd/src/hip_graph_internal.hpp index 2ca6046149..41603ce890 100644 --- a/hipamd/src/hip_graph_internal.hpp +++ b/hipamd/src/hip_graph_internal.hpp @@ -190,6 +190,7 @@ struct hipGraphNode { } ihipGraph* GetParentGraph() { return parentGraph_; } void SetParentGraph(ihipGraph* graph) { parentGraph_ = graph; } + virtual hipError_t SetParams(hipGraphNode* node) { return hipSuccess; } }; struct ihipGraph { @@ -267,6 +268,8 @@ struct hipGraphExec { return clonedNode; } + std::vector& GetNodes() { return levelOrder_; } + amd::HostQueue* GetAvailableQueue() { return parallelQueues_[currentQueueIndex_++]; } void ResetQueueIndex() { currentQueueIndex_ = 0; } hipError_t Init(); @@ -364,6 +367,23 @@ struct hipChildGraphNode : public hipGraphNode { commands_[1]->enqueue(); } } + + hipError_t SetParams(const ihipGraph* childGraph) { + const std::vector& newNodes = childGraph->GetNodes(); + const std::vector& oldNodes = childGraph_->GetNodes(); + for (std::vector::size_type i = 0; i != newNodes.size(); i++) { + hipError_t status = oldNodes[i]->SetParams(newNodes[i]); + if (status != hipSuccess) { + return status; + } + } + return hipSuccess; + } + + hipError_t SetParams(hipGraphNode* node) { + const hipChildGraphNode* childGraphNode = static_cast(node); + return SetParams(childGraphNode->childGraph_); + } }; class hipGraphKernelNode : public hipGraphNode { @@ -422,6 +442,7 @@ class hipGraphKernelNode : public hipGraphNode { std::memcpy(pKernelParams_, params, sizeof(hipKernelNodeParams)); return status; } + // ToDo: use this when commands are cloned and command params are to be updated hipError_t SetCommandParams(const hipKernelNodeParams* params) { if (params->func != pKernelParams_->func) { hipFunction_t func = nullptr; @@ -446,6 +467,11 @@ class hipGraphKernelNode : public hipGraphNode { ->setSharedMemBytes(params->sharedMemBytes); return hipSuccess; } + + hipError_t SetParams(hipGraphNode* node) { + const hipGraphKernelNode* kernelNode = static_cast(node); + return SetParams(kernelNode->pKernelParams_); + } }; class hipGraphMemcpyNode : public hipGraphNode { @@ -488,6 +514,11 @@ class hipGraphMemcpyNode : public hipGraphNode { std::memcpy(pCopyParams_, params, sizeof(hipMemcpy3DParms)); return hipSuccess; } + hipError_t SetParams(hipGraphNode* node) { + const hipGraphMemcpyNode* memcpyNode = static_cast(node); + return SetParams(memcpyNode->pCopyParams_); + } + // ToDo: use this when commands are cloned and command params are to be updated hipError_t SetCommandParams(const hipMemcpy3DParms* pNodeParams); hipError_t ValidateParams(const hipMemcpy3DParms* pNodeParams); }; @@ -542,6 +573,12 @@ class hipGraphMemcpyNode1D : public hipGraphNode { return hipSuccess; } + hipError_t SetParams(hipGraphNode* node) { + const hipGraphMemcpyNode1D* memcpy1DNode = static_cast(node); + return SetParams(memcpy1DNode->dst_, memcpy1DNode->src_, memcpy1DNode->count_, + memcpy1DNode->kind_); + } + // ToDo: use this when commands are cloned and command params are to be updated hipError_t SetCommandParams(void* dst, const void* src, size_t count, hipMemcpyKind kind); hipError_t ValidateParams(void* dst, const void* src, size_t count, hipMemcpyKind kind); }; @@ -603,6 +640,13 @@ class hipGraphMemcpyNodeFromSymbol : public hipGraphMemcpyNode1D { return hipSuccess; } + hipError_t SetParams(hipGraphNode* node) { + const hipGraphMemcpyNodeFromSymbol* memcpyNode = + static_cast(node); + return SetParams(memcpyNode->dst_, memcpyNode->symbol_, memcpyNode->count_, memcpyNode->offset_, + memcpyNode->kind_); + } + // ToDo: use this when commands are cloned and command params are to be updated hipError_t SetCommandParams(void* dst, const void* symbol, size_t count, size_t offset, hipMemcpyKind kind) { size_t sym_size = 0; @@ -671,6 +715,13 @@ class hipGraphMemcpyNodeToSymbol : public hipGraphMemcpyNode1D { return hipSuccess; } + hipError_t SetParams(hipGraphNode* node) { + const hipGraphMemcpyNodeToSymbol* memcpyNode = + static_cast(node); + return SetParams(memcpyNode->src_, memcpyNode->symbol_, memcpyNode->count_, memcpyNode->offset_, + memcpyNode->kind_); + } + // ToDo: use this when commands are cloned and command params are to be updated hipError_t SetCommandParams(const void* symbol, const void* src, size_t count, size_t offset, hipMemcpyKind kind) { size_t sym_size = 0; @@ -733,6 +784,11 @@ class hipGraphMemsetNode : public hipGraphNode { std::memcpy(pMemsetParams_, params, sizeof(hipMemsetParams)); return hipSuccess; } + + hipError_t SetParams(hipGraphNode* node) { + const hipGraphMemsetNode* memsetNode = static_cast(node); + return SetParams(memsetNode->pMemsetParams_); + } }; class hipGraphEventRecordNode : public hipGraphNode { @@ -778,6 +834,22 @@ class hipGraphEventRecordNode : public hipGraphNode { event_ = event; return hipSuccess; } + + hipError_t SetParams(hipGraphNode* node) { + const hipGraphEventRecordNode* eventRecordNode = + static_cast(node); + return SetParams(eventRecordNode->event_); + } + // ToDo: use this when commands are cloned and command params are to be updated + hipError_t SetCommandParams(hipEvent_t event) { + amd::HostQueue* queue; + if (!commands_.empty()) { + queue = commands_[0]->queue(); + commands_[0]->release(); + } + commands_.clear(); + return CreateCommand(queue); + } }; class hipGraphEventWaitNode : public hipGraphNode { @@ -823,6 +895,21 @@ class hipGraphEventWaitNode : public hipGraphNode { event_ = event; return hipSuccess; } + + hipError_t SetParams(hipGraphNode* node) { + const hipGraphEventWaitNode* eventWaitNode = static_cast(node); + return SetParams(eventWaitNode->event_); + } + // ToDo: use this when commands are cloned and command params are to be updated + hipError_t SetCommandParams(hipEvent_t event) { + amd::HostQueue* queue; + if (!commands_.empty()) { + queue = commands_[0]->queue(); + commands_[0]->release(); + } + commands_.clear(); + return CreateCommand(queue); + } }; class hipGraphHostNode : public hipGraphNode { @@ -881,6 +968,13 @@ class hipGraphHostNode : public hipGraphNode { std::memcpy(pNodeParams_, params, sizeof(hipHostNodeParams)); return hipSuccess; } + + hipError_t SetParams(hipGraphNode* node) { + const hipGraphHostNode* hostNode = static_cast(node); + return SetParams(hostNode->pNodeParams_); + } + // ToDo: use this when commands are cloned and command params are to be updated + hipError_t SetCommandParams(const hipHostNodeParams* params); }; class hipGraphEmptyNode : public hipGraphNode { diff --git a/hipamd/src/hip_hcc.def.in b/hipamd/src/hip_hcc.def.in index b92267fe79..7cf574c407 100644 --- a/hipamd/src/hip_hcc.def.in +++ b/hipamd/src/hip_hcc.def.in @@ -342,3 +342,4 @@ hipGraphAddHostNode hipGraphHostNodeGetParams hipGraphHostNodeSetParams hipGraphExecHostNodeSetParams +hipGraphExecUpdate diff --git a/hipamd/src/hip_hcc.map.in b/hipamd/src/hip_hcc.map.in index d9491e7d85..fd37af7036 100644 --- a/hipamd/src/hip_hcc.map.in +++ b/hipamd/src/hip_hcc.map.in @@ -374,6 +374,7 @@ global: hipGraphHostNodeGetParams; hipGraphHostNodeSetParams; hipGraphExecHostNodeSetParams; + hipGraphExecUpdate; local: *; } hip_4.4;