SWDEV-240806 - Added few Graph API Implementation

hipGraph APIs clone, childGraph, RemoveDependencies, GetEdges,GetDependencies, GetDependentNodes, GetType and DestroyNode
hipStream APIs GetCaptureInfo, GetCaptureInfo_v2, UpdateCaptureDependencies.

Change-Id: Ib0f4cb8ea335698eecdd6d744ffab1e954153673


[ROCm/clr commit: 1c51d82dd5]
Dieser Commit ist enthalten in:
anusha GodavarthySurya
2021-10-05 07:34:04 -07:00
Ursprung 4a7b23b848
Commit 78f89618cb
6 geänderte Dateien mit 830 neuen und 191 gelöschten Zeilen
+320 -71
Datei anzeigen
@@ -27,6 +27,14 @@
thread_local std::vector<hipStream_t> g_captureStreams;
std::unordered_map<amd::Command*, hipGraphExec_t> hipGraphExec::activeGraphExec_;
inline void ihipGraphAddNode(hipGraphNode_t graphNode, hipGraph_t graph,
const hipGraphNode_t* pDependencies, size_t numDependencies) {
graph->AddNode(graphNode);
for (size_t i = 0; i < numDependencies; i++) {
pDependencies[i]->AddEdge(graphNode);
}
}
hipError_t ihipValidateKernelParams(const hipKernelNodeParams* pNodeParams) {
hipFunction_t func = nullptr;
hipError_t status =
@@ -70,14 +78,7 @@ hipError_t ihipGraphAddKernelNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
return hipErrorInvalidDeviceFunction;
}
*pGraphNode = new hipGraphKernelNode(pNodeParams, func);
if (numDependencies == 0) {
graph->AddNode(*pGraphNode);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(*(pDependencies + i), *pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
return hipSuccess;
}
@@ -88,16 +89,12 @@ hipError_t ihipGraphAddMemcpyNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
(numDependencies > 0 && pDependencies == nullptr) || pCopyParams == nullptr) {
return hipErrorInvalidValue;
}
ihipMemcpy3D_validate(pCopyParams);
hipError_t status = ihipMemcpy3D_validate(pCopyParams);
if (status != hipSuccess) {
return status;
}
*pGraphNode = new hipGraphMemcpyNode(pCopyParams);
if (numDependencies == 0) {
graph->AddNode(*pGraphNode);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(*(pDependencies + i), *pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
return hipSuccess;
}
@@ -108,16 +105,12 @@ hipError_t ihipGraphAddMemcpyNode1D(hipGraphNode_t* pGraphNode, hipGraph_t graph
(numDependencies > 0 && pDependencies == nullptr)) {
return hipErrorInvalidValue;
}
ihipMemcpy_validate(dst, src, count, kind);
hipError_t status = ihipMemcpy_validate(dst, src, count, kind);
if (status != hipSuccess) {
return status;
}
*pGraphNode = new hipGraphMemcpyNode1D(dst, src, count, kind);
if (numDependencies == 0) {
graph->AddNode(*pGraphNode);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(*(pDependencies + i), *pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
return hipSuccess;
}
@@ -128,25 +121,22 @@ hipError_t ihipGraphAddMemsetNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
(numDependencies > 0 && pDependencies == nullptr) || pMemsetParams == nullptr) {
return hipErrorInvalidValue;
}
hipError_t status;
if (pMemsetParams->height == 1) {
ihipMemset_validate(pMemsetParams->dst, pMemsetParams->value, pMemsetParams->elementSize,
pMemsetParams->width * pMemsetParams->elementSize);
status =
ihipMemset_validate(pMemsetParams->dst, pMemsetParams->value, pMemsetParams->elementSize,
pMemsetParams->width * pMemsetParams->elementSize);
} else {
auto sizeBytes = pMemsetParams->width * pMemsetParams->height * 1;
ihipMemset3D_validate(
status = ihipMemset3D_validate(
{pMemsetParams->dst, pMemsetParams->pitch, pMemsetParams->width, pMemsetParams->height},
pMemsetParams->value, {pMemsetParams->width, pMemsetParams->height, 1}, sizeBytes);
}
if (status != hipSuccess) {
return status;
}
*pGraphNode = new hipGraphMemsetNode(pMemsetParams);
if (numDependencies == 0) {
graph->AddNode(*pGraphNode);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(*(pDependencies + i), *pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
return hipSuccess;
}
@@ -194,22 +184,17 @@ hipError_t capturehipMemcpyAsync(hipStream_t& stream, void*& dst, const void*& s
ClPrint(amd::LOG_INFO, amd::LOG_API, "[hipGraph] current capture node Memcpy1D on stream : %p",
stream);
hip::Stream* s = reinterpret_cast<hip::Stream*>(stream);
hipGraphNode_t pGraphNode;
hipGraph_t graph = nullptr;
std::vector<hipGraphNode_t> pDependencies = s->GetLastCapturedNodes();
size_t numDependencies = s->GetLastCapturedNodes().size();
graph = s->GetCaptureGraph();
ihipMemcpy_validate(dst, src, sizeBytes, kind);
pGraphNode = new hipGraphMemcpyNode1D(dst, src, sizeBytes, kind);
if (numDependencies == 0) {
graph->AddNode(pGraphNode);
hipError_t status = ihipMemcpy_validate(dst, src, sizeBytes, kind);
if (status != hipSuccess) {
return status;
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(pDependencies[i], pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
s->SetLastCapturedNode(pGraphNode);
hipGraphNode_t node = new hipGraphMemcpyNode1D(dst, src, sizeBytes, kind);
ihipGraphAddNode(node, graph, pDependencies.data(), numDependencies);
s->SetLastCapturedNode(node);
return hipSuccess;
}
@@ -318,13 +303,12 @@ hipError_t capturehipStreamWaitEvent(hipEvent_t& event, hipStream_t& stream, uns
HIP_RETURN(hipSuccess);
}
hipError_t hipStreamIsCapturing(hipStream_t stream, hipStreamCaptureStatus** pCaptureStatus) {
hipError_t hipStreamIsCapturing(hipStream_t stream, hipStreamCaptureStatus* pCaptureStatus) {
HIP_INIT_API(hipStreamIsCapturing, stream, pCaptureStatus);
if (stream == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
hipStreamCaptureStatus captureStatus = reinterpret_cast<hip::Stream*>(stream)->GetCaptureStatus();
*pCaptureStatus = &captureStatus;
*pCaptureStatus = reinterpret_cast<hip::Stream*>(stream)->GetCaptureStatus();
HIP_RETURN(hipSuccess);
}
@@ -363,8 +347,22 @@ hipError_t hipStreamEndCapture(hipStream_t stream, hipGraph_t* pGraph) {
HIP_RETURN(hipErrorStreamCaptureInvalidated);
}
// check if all parallel streams have joined
// Nodes that are removed from the dependency set via API hipStreamUpdateCaptureDependencies do
// not result in hipErrorStreamCaptureUnjoined
if (s->GetCaptureGraph()->GetLeafNodeCount() != 1) {
return hipErrorStreamCaptureUnjoined;
std::vector<hipGraphNode_t> leafNodes = s->GetCaptureGraph()->GetLeafNodes();
const std::vector<hipGraphNode_t>& removedDepNodes = s->GetRemovedDependencies();
bool foundInRemovedDep = false;
for (auto leafNode : leafNodes) {
for (auto node : removedDepNodes) {
if (node == leafNode) {
foundInRemovedDep = true;
}
}
}
if (foundInRemovedDep == false) {
return hipErrorStreamCaptureUnjoined;
}
}
*pGraph = s->GetCaptureGraph();
// end capture on all streams/events part of graph capture
@@ -379,6 +377,9 @@ hipError_t hipGraphCreate(hipGraph_t* pGraph, unsigned int flags) {
hipError_t hipGraphDestroy(hipGraph_t graph) {
HIP_INIT_API(hipGraphDestroy, graph);
if (graph == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
delete graph;
HIP_RETURN(hipSuccess);
}
@@ -430,15 +431,21 @@ hipError_t hipGraphAddEmptyNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
HIP_RETURN(hipErrorInvalidValue);
}
*pGraphNode = new hipGraphEmptyNode();
if (numDependencies == 0) {
graph->AddNode(*pGraphNode);
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphAddChildGraphNode(hipGraphNode_t* pGraphNode, hipGraph_t graph,
const hipGraphNode_t* pDependencies, size_t numDependencies,
hipGraph_t childGraph) {
HIP_INIT_API(hipGraphAddChildGraphNode, pGraphNode, pDependencies, numDependencies, childGraph);
if (pGraphNode == nullptr || graph == nullptr ||
(numDependencies > 0 && pDependencies == nullptr) || childGraph == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(*(pDependencies + i), *pGraphNode) != hipSuccess) {
return hipErrorInvalidValue;
}
}
return hipSuccess;
*pGraphNode = new hipChildGraphNode(childGraph);
ihipGraphAddNode(*pGraphNode, graph, pDependencies, numDependencies);
HIP_RETURN(hipSuccess);
}
hipError_t ihipGraphInstantiate(hipGraphExec_t* pGraphExec, hipGraph_t graph,
@@ -464,6 +471,9 @@ hipError_t hipGraphInstantiate(hipGraphExec_t* pGraphExec, hipGraph_t graph,
hipError_t hipGraphExecDestroy(hipGraphExec_t pGraphExec) {
HIP_INIT_API(hipGraphExecDestroy, pGraphExec);
if (pGraphExec == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
delete pGraphExec;
HIP_RETURN(hipSuccess);
}
@@ -474,6 +484,9 @@ hipError_t ihipGraphlaunch(hipGraphExec_t graphExec, hipStream_t stream) {
hipError_t hipGraphLaunch(hipGraphExec_t graphExec, hipStream_t stream) {
HIP_INIT_API(hipGraphLaunch, graphExec, stream);
if (graphExec == nullptr || stream == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
HIP_RETURN_DURATION(ihipGraphlaunch(graphExec, stream));
}
@@ -482,22 +495,43 @@ hipError_t hipGraphGetNodes(hipGraph_t graph, hipGraphNode_t* nodes, size_t* num
if (graph == nullptr || numNodes == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
*numNodes = graph->GetNodeCount();
if (*numNodes > 0) {
nodes = graph->GetNodes().data();
const std::vector<hipGraphNode_t>& graphNodes = graph->GetNodes();
if (nodes == nullptr) {
*numNodes = graphNodes.size();
HIP_RETURN(hipSuccess);
} else if (*numNodes < graphNodes.size()) {
HIP_RETURN(hipErrorInvalidValue);
}
HIP_RETURN(hipSuccess);
for (int i = 0; i < graphNodes.size(); i++) {
nodes[i] = graphNodes[i];
}
for (int i = graphNodes.size(); i < *numNodes; i++) {
nodes[i] = nullptr;
}
*numNodes = graphNodes.size();
}
hipError_t hipGraphGetRootNodes(hipGraph_t graph, hipGraphNode_t* pRootNodes,
size_t* pNumRootNodes) {
HIP_INIT_API(hipGraphGetRootNodes, graph, pRootNodes, pNumRootNodes);
if (graph == nullptr || pNumRootNodes == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
std::vector<Node> rootNodes = graph->GetRootNodes();
pRootNodes = rootNodes.data();
*pNumRootNodes = rootNodes.size();
const std::vector<hipGraphNode_t> nodes = graph->GetRootNodes();
if (pRootNodes == nullptr) {
*pNumRootNodes = nodes.size();
HIP_RETURN(hipSuccess);
} else if (*pNumRootNodes < nodes.size()) {
HIP_RETURN(hipErrorInvalidValue);
}
for (int i = 0; i < nodes.size(); i++) {
pRootNodes[i] = nodes[i];
}
for (int i = nodes.size(); i < *pNumRootNodes; i++) {
pRootNodes[i] = nullptr;
}
*pNumRootNodes = nodes.size();
HIP_RETURN(hipSuccess);
}
@@ -568,9 +602,7 @@ hipError_t hipGraphAddDependencies(hipGraph_t graph, const hipGraphNode_t* from,
HIP_RETURN(hipErrorInvalidValue);
}
for (size_t i = 0; i < numDependencies; i++) {
if (graph->AddEdge(from[i], to[i]) != hipSuccess) {
HIP_RETURN(hipErrorInvalidValue);
}
from[i]->AddEdge(to[i]);
}
HIP_RETURN(hipSuccess);
}
@@ -583,3 +615,220 @@ hipError_t hipGraphExecKernelNodeSetParams(hipGraphExec_t hGraphExec, hipGraphNo
}
return reinterpret_cast<hipGraphKernelNode*>(node)->SetCommandParams(pNodeParams);
}
hipError_t hipGraphChildGraphNodeGetGraph(hipGraphNode_t node, hipGraph_t* pGraph) {
HIP_INIT_API(hipGraphChildGraphNodeGetGraph, node, pGraph);
if (node == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
*pGraph = reinterpret_cast<hipChildGraphNode*>(node)->GetChildGraph();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphExecChildGraphNodeSetParams(hipGraphExec_t hGraphExec, hipGraphNode_t node,
hipGraph_t childGraph) {
HIP_INIT_API(hipGraphExecChildGraphNodeSetParams, hGraphExec, node, childGraph);
if (hGraphExec == nullptr || node == nullptr || childGraph == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
HIP_RETURN(hipSuccess);
}
hipError_t hipStreamGetCaptureInfo(hipStream_t stream, hipStreamCaptureStatus* pCaptureStatus,
unsigned long long* pId) {
HIP_INIT_API(hipStreamGetCaptureInfo, stream, pCaptureStatus, pId);
if (pCaptureStatus == nullptr || pId == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
if (stream == nullptr) {
HIP_RETURN(hipErrorStreamCaptureImplicit);
}
hip::Stream* s = reinterpret_cast<hip::Stream*>(stream);
*pCaptureStatus = s->GetCaptureStatus();
*pId = s->GetCaptureID();
HIP_RETURN(hipSuccess);
}
hipError_t hipStreamGetCaptureInfo_v2(hipStream_t stream, hipStreamCaptureStatus* captureStatus_out,
unsigned long long* id_out, hipGraph_t* graph_out,
const hipGraphNode_t** dependencies_out,
size_t* numDependencies_out) {
HIP_INIT_API(hipStreamGetCaptureInfo_v2, stream, captureStatus_out, id_out, graph_out,
dependencies_out, numDependencies_out);
if (stream == nullptr) {
HIP_RETURN(hipErrorStreamCaptureImplicit);
}
hip::Stream* s = reinterpret_cast<hip::Stream*>(stream);
*captureStatus_out = s->GetCaptureStatus();
if (*captureStatus_out == hipStreamCaptureStatusActive) {
if (id_out != nullptr) {
*id_out = s->GetCaptureID();
}
if (graph_out != nullptr) {
*graph_out = s->GetCaptureGraph();
}
if (dependencies_out != nullptr && numDependencies_out != nullptr) {
*dependencies_out = s->GetLastCapturedNodes().data();
*numDependencies_out = s->GetLastCapturedNodes().size();
}
}
HIP_RETURN(hipSuccess);
}
hipError_t hipStreamUpdateCaptureDependencies(hipStream_t stream, hipGraphNode_t* dependencies,
size_t numDependencies, unsigned int flags) {
HIP_INIT_API(hipStreamUpdateCaptureDependencies, stream, dependencies, numDependencies, flags);
hip::Stream* s = reinterpret_cast<hip::Stream*>(stream);
if (s->GetCaptureStatus() == hipStreamCaptureStatusActive) {
return hipErrorIllegalState;
}
if (numDependencies > 0 && dependencies == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
std::vector<hipGraphNode_t> depNodes;
for (int i = 0; i < numDependencies; i++) {
depNodes.push_back(dependencies[i]);
}
if (flags == hipStreamAddCaptureDependencies) {
s->AddCrossCapturedNode(depNodes);
} else if (flags == hipStreamSetCaptureDependencies) {
bool replace = true;
s->AddCrossCapturedNode(depNodes, replace);
}
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphRemoveDependencies(hipGraph_t graph, const hipGraphNode_t* from,
const hipGraphNode_t* to, size_t numDependencies) {
HIP_INIT_API(hipGraphRemoveDependencies, graph, from, to, numDependencies);
if (graph == nullptr || from == nullptr || to == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
for (size_t i = 0; i < numDependencies; i++) {
from[i]->RemoveEdge(to[i]);
}
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphGetEdges(hipGraph_t graph, hipGraphNode_t* from, hipGraphNode_t* to,
size_t* numEdges) {
HIP_INIT_API(hipGraphGetEdges, graph, from, to, numEdges);
if (graph == nullptr || numEdges == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
const std::vector<std::pair<Node, Node>> edges = graph->GetEdges();
// returns only the number of edges in numEdges when from and to are null
if (from == nullptr && to == nullptr) {
*numEdges = edges.size();
return hipSuccess;
} else if (*numEdges < edges.size()) {
HIP_RETURN(hipErrorInvalidValue);
}
for (int i = 0; i < edges.size(); i++) {
from[i] = edges[i].first;
to[i] = edges[i].second;
}
// If numEdges > actual number of edges, the remaining entries in from and to will be set to NULL
for (int i = edges.size(); i < *numEdges; i++) {
from[i] = nullptr;
to[i] = nullptr;
}
*numEdges = edges.size();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphNodeGetDependencies(hipGraphNode_t node, hipGraphNode_t* pDependencies,
size_t* pNumDependencies) {
HIP_INIT_API(hipGraphNodeGetDependencies, node, pDependencies, pNumDependencies);
if (node == nullptr || pNumDependencies == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
const std::vector<hipGraphNode_t>& dependencies = node->GetDependencies();
if (pDependencies == NULL) {
*pNumDependencies = dependencies.size();
HIP_RETURN(hipSuccess);
} else if (*pNumDependencies < dependencies.size()) {
HIP_RETURN(hipErrorInvalidValue);
}
for (int i = 0; i < dependencies.size(); i++) {
pDependencies[i] = dependencies[i];
}
// pNumDependencies > actual number of dependencies, the remaining entries in pDependencies will
// be set to NULL
for (int i = dependencies.size(); i < *pNumDependencies; i++) {
pDependencies[i] = nullptr;
}
*pNumDependencies = dependencies.size();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphNodeGetDependentNodes(hipGraphNode_t node, hipGraphNode_t* pDependentNodes,
size_t* pNumDependentNodes) {
HIP_INIT_API(hipGraphNodeGetDependentNodes, node, pDependentNodes, pNumDependentNodes);
if (node == nullptr || pNumDependentNodes == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
const std::vector<hipGraphNode_t>& dependents = node->GetEdges();
if (pDependentNodes == NULL) {
*pNumDependentNodes = dependents.size();
HIP_RETURN(hipSuccess);
} else if (*pNumDependentNodes < dependents.size()) {
HIP_RETURN(hipErrorInvalidValue);
}
for (int i = 0; i < dependents.size(); i++) {
pDependentNodes[i] = dependents[i];
}
// pNumDependentNodes > actual number of dependents, the remaining entries in pDependentNodes will
// be set to NULL
for (int i = dependents.size(); i < *pNumDependentNodes; i++) {
pDependentNodes[i] = nullptr;
}
*pNumDependentNodes = dependents.size();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphNodeGetType(hipGraphNode_t node, hipGraphNodeType* pType) {
HIP_INIT_API(hipGraphNodeGetType, node, pType);
if (node == nullptr || pType == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
*pType = node->GetType();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphDestroyNode(hipGraphNode_t node) {
HIP_INIT_API(hipGraphDestroyNode, node);
if (node == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
node->GetParentGraph()->RemoveNode(node);
// Takescare of removing its dependencies and dependent nodes
delete node;
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphClone(hipGraph_t* pGraphClone, hipGraph_t originalGraph) {
HIP_INIT_API(hipGraphClone, pGraphClone, originalGraph);
if (originalGraph == nullptr || pGraphClone == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
*pGraphClone = originalGraph->clone();
HIP_RETURN(hipSuccess);
}
hipError_t hipGraphNodeFindInClone(hipGraphNode_t* pNode, hipGraphNode_t originalNode,
hipGraph_t clonedGraph) {
HIP_INIT_API(hipGraphNodeFindInClone, pNode, originalNode, clonedGraph);
if (pNode == nullptr || originalNode == nullptr || clonedGraph == nullptr) {
HIP_RETURN(hipErrorInvalidValue);
}
for (auto node : clonedGraph->GetNodes()) {
if (node->GetID() == originalNode->GetID()) {
*pNode = node;
HIP_RETURN(hipSuccess);
}
}
HIP_RETURN(hipErrorInvalidValue);
}