SWDEV-470612 - Added fixes in optimized multistream path for graph execution
This change adds fixes in optimized multistream path for childGraph uses cases. 1) For childgraph nodes, rely on runNodes() only to process the childgraph and skip calls to createCommand and enqueueCommands. This ensures that the start/end markers are enqueued correctly with respect to the childGraph commands. In addition, the runNodes() for the childgraph should be called after the dependency walkthrough to make sure that the subgraph is executed once. 2) Nodes with no outgoing edges should be marked as a leafs regardless of which stream they are assigned to. This is to ensure that marker dependencies from nodes that run on non-zero stream to subgraph leafs that run on zero stream are still set up correctly. Change-Id: I4a5f4f3b0e0d01e515cdcb045b46c2798f291255
Этот коммит содержится в:
@@ -640,11 +640,6 @@ void Graph::UpdateStreams(
|
||||
// ================================================================================================
|
||||
bool Graph::RunOneNode(Node node, bool wait) {
|
||||
if (node->launch_id_ == -1) {
|
||||
// Process child graph separately, since, there is no connection
|
||||
if (node->GetType() == hipGraphNodeTypeGraph) {
|
||||
auto child = reinterpret_cast<hip::ChildGraphNode*>(node)->childGraph_;
|
||||
child->RunNodes(node->stream_id_, &streams_);
|
||||
}
|
||||
// Clear the storage of the wait nodes
|
||||
memset(&wait_order_[0], 0, sizeof(Node) * wait_order_.size());
|
||||
amd::Command::EventWaitList waitList;
|
||||
@@ -668,35 +663,47 @@ bool Graph::RunOneNode(Node node, bool wait) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Create a wait list from the last launches of all dependencies
|
||||
for (auto dep : wait_order_) {
|
||||
if (dep != nullptr) {
|
||||
// Add all commands in the wait list
|
||||
for (auto command : dep->GetCommands()) {
|
||||
waitList.push_back(command);
|
||||
|
||||
if (node->GetType() == hipGraphNodeTypeGraph) {
|
||||
// Process child graph separately, since, there is no connection
|
||||
auto child = reinterpret_cast<hip::ChildGraphNode*>(node)->childGraph_;
|
||||
if (!reinterpret_cast<hip::ChildGraphNode*>(node)->graphCaptureStatus_) {
|
||||
child->RunNodes(node->stream_id_, &streams_);
|
||||
}
|
||||
} else {
|
||||
// Create a wait list from the last launches of all dependencies
|
||||
for (auto dep : wait_order_) {
|
||||
if (dep != nullptr) {
|
||||
// Add all commands in the wait list
|
||||
if (dep->GetType() != hipGraphNodeTypeGraph) {
|
||||
for (auto command : dep->GetCommands()) {
|
||||
waitList.push_back(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Assing a stream to the current node
|
||||
node->SetStream(streams_);
|
||||
// Create the execution commands on the assigned stream
|
||||
auto status = node->CreateCommand(node->GetQueue());
|
||||
if (status != hipSuccess) {
|
||||
LogPrintfError("Command creation for node id(%d) failed!", current_id_ + 1);
|
||||
return false;
|
||||
}
|
||||
// Retain all commands, since potentially the command can finish before a wait signal
|
||||
for (auto command : node->GetCommands()) {
|
||||
command->retain();
|
||||
}
|
||||
// Assing a stream to the current node
|
||||
node->SetStream(streams_);
|
||||
// Create the execution commands on the assigned stream
|
||||
auto status = node->CreateCommand(node->GetQueue());
|
||||
if (status != hipSuccess) {
|
||||
LogPrintfError("Command creation for node id(%d) failed!", current_id_ + 1);
|
||||
return false;
|
||||
}
|
||||
// Retain all commands, since potentially the command can finish before a wait signal
|
||||
for (auto command : node->GetCommands()) {
|
||||
command->retain();
|
||||
}
|
||||
|
||||
// If a wait was requested, then process the list
|
||||
if (wait && !waitList.empty()) {
|
||||
node->UpdateEventWaitLists(waitList);
|
||||
// If a wait was requested, then process the list
|
||||
if (wait && !waitList.empty()) {
|
||||
node->UpdateEventWaitLists(waitList);
|
||||
}
|
||||
// Start the execution
|
||||
node->EnqueueCommands(node->GetQueue());
|
||||
}
|
||||
// Start the execution
|
||||
node->EnqueueCommands(node->GetQueue());
|
||||
// Assign the launch ID of the submmitted node
|
||||
// This is also applied to childGraphs to prevent them from being reprocessed
|
||||
node->launch_id_ = current_id_++;
|
||||
uint32_t i = 0;
|
||||
// Execute the nodes in the edges list
|
||||
@@ -710,7 +717,7 @@ bool Graph::RunOneNode(Node node, bool wait) {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ((i == 0) && (node->stream_id_ != 0)) {
|
||||
if (i == 0) {
|
||||
// Add a leaf node into the list for a wait.
|
||||
// Always use the last node, since it's the latest for the particular queue
|
||||
leafs_[node->stream_id_] = node;
|
||||
@@ -764,8 +771,10 @@ bool Graph::RunNodes(
|
||||
for (uint32_t i = 0; i < DEBUG_HIP_FORCE_GRAPH_QUEUES; ++i) {
|
||||
if ((base_stream != i) && (leafs_[i] != nullptr)) {
|
||||
// Add all commands in the wait list
|
||||
for (auto command : leafs_[i]->GetCommands()) {
|
||||
wait_list.push_back(command);
|
||||
if (leafs_[i]->GetType() != hipGraphNodeTypeGraph) {
|
||||
for (auto command : leafs_[i]->GetCommands()) {
|
||||
wait_list.push_back(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,8 +789,10 @@ bool Graph::RunNodes(
|
||||
// Release commands after execution
|
||||
for (auto& node : vertices_) {
|
||||
node->launch_id_ = -1;
|
||||
for (auto command : node->GetCommands()) {
|
||||
command->release();
|
||||
if (node->GetType() != hipGraphNodeTypeGraph) {
|
||||
for (auto command : node->GetCommands()) {
|
||||
command->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
Ссылка в новой задаче
Block a user