Skip to content

Commit

Permalink
[CPU] Fix resolve edge conflicts Convert insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorDuplensky committed Jul 22, 2024
1 parent f8c7ccc commit 4ee44d8
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 45 deletions.
94 changes: 49 additions & 45 deletions src/plugins/intel_cpu/src/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "graph.h"

#include <algorithm>
#include <cstddef>
#include <limits>
#include <map>
#include <memory>
Expand Down Expand Up @@ -537,70 +538,73 @@ void Graph::insertReorder(EdgePtr& edge, bool isOptimized, std::unordered_set<st
InsertReorder(edge, layerName, edge->getInputDesc(), edge->getOutputDesc(), isOptimized);
}

void Graph::ResolveEdgeConflicts() {
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::intel_cpu_LT, "Graph::ResolveEdgeConflicts");
void Graph::insertConvert(EdgePtr& edge) {
const auto& inDesc = edge->getInputDesc();
const auto& outDesc = edge->getOutputDesc();

ptrdiff_t numberOfEdges = static_cast<ptrdiff_t>(graphEdges.size());
std::string convertName = edge->getParent()->getName() + "_" +
inDesc.getPrecision().get_type_name() + "_" + outDesc.getPrecision().get_type_name();

auto convertNode = std::make_shared<node::Convert>(inDesc.getShape(), inDesc.getPrecision(), outDesc.getPrecision(),
convertName, context);
convertNode->setDescs(inDesc, outDesc);
InsertNode(edge, convertNode, true);
}

static std::unordered_set<std::string> getUniqueLayerNames(const std::vector<NodePtr>& graphNodes) {
std::unordered_set<std::string> uniqueLayerNames;
uniqueLayerNames.reserve(graphNodes.size());

for (auto node : graphNodes) {
uniqueLayerNames.insert(node->getName());
}

auto updateEdge = [&](ptrdiff_t& i) {
graphEdges.erase(graphEdges.begin() + i);
i--;
numberOfEdges--;
};
return uniqueLayerNames;
}

for (ptrdiff_t i = 0; i < numberOfEdges; i++) {
auto edge = graphEdges[i];
auto reorderStatus = graphEdges[i]->needReorder();
DEBUG_LOG(graphEdges[i]->name(), " reorderStatus = ", reorderStatus);
if (reorderStatus == Edge::ReorderStatus::Regular) {
Edge::ReorderStatus reorderStatusInternal = Edge::ReorderStatus::Regular;
// Check if there is a reorder that needs the precision conversion
if (edge->getInputDesc().getPrecision() != edge->getOutputDesc().getPrecision() &&
!isReorderAvailable(edge->getInputPortDesc()->getMemDesc(),
edge->getOutputPortDesc()->getMemDesc(),
this->getEngine())) {
// If we are here, then we need to insert Convert, because there are no reorders that support such type conversion
const auto& inDesc = edge->getInputDesc();
const auto& outDesc = edge->getOutputDesc();

std::string convertName = edge->getParent()->getName() + "_" +
inDesc.getPrecision().get_type_name() + "_" + outDesc.getPrecision().get_type_name();

auto convertNode = std::make_shared<node::Convert>(inDesc.getShape(), inDesc.getPrecision(), outDesc.getPrecision(),
convertName, context);
convertNode->setDescs(inDesc, outDesc);
InsertNode(edge, convertNode, true);

//Check if reorder is still needed
reorderStatusInternal = convertNode->getChildEdgeAt(0)->needReorder();
if (reorderStatusInternal != Edge::ReorderStatus::No)
edge = convertNode->getChildEdgeAt(0);
}
if (reorderStatusInternal != Edge::ReorderStatus::No) {
insertReorder(edge, reorderStatusInternal == Edge::ReorderStatus::Optimized, uniqueLayerNames);
void Graph::ResolveEdgeConflicts() {
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::intel_cpu_LT, "Graph::ResolveEdgeConflicts");

std::unordered_set<std::string> uniqueLayerNames = getUniqueLayerNames(graphNodes);

/* When inserting convert / reorder, two new edges are added (pushed to the end) to the graphEdges.
So use a plain for loop, to handle newly inserted edges as well */
for (size_t i = 0; i < graphEdges.size(); i++) {
auto& edge = graphEdges[i];
auto reorderStatus = edge->needReorder();
DEBUG_LOG(*edge, " reorderStatus = ", reorderStatus);

switch (reorderStatus) {
case Edge::ReorderStatus::Regular: {
if (reorderStatus == Edge::ReorderStatus::Regular &&
edge->getInputDesc().getPrecision() != edge->getOutputDesc().getPrecision() &&
!isReorderAvailable(edge->getInputPortDesc()->getMemDesc(),
edge->getOutputPortDesc()->getMemDesc(),
this->getEngine())) {
// just insert convert. If layout reorder is still needed, it will be inserted later in the traverse
insertConvert(edge);
} else {
insertReorder(edge, false, uniqueLayerNames);
}
updateEdge(i);
} else if (reorderStatus == Edge::ReorderStatus::Optimized) {
break;
}
case Edge::ReorderStatus::Optimized:
insertReorder(edge, true, uniqueLayerNames);
updateEdge(i);
break;
case Edge::ReorderStatus::No:
break;
}
}

RemoveDroppedEdges();
}

void Graph::ResolveComplexInplaceConflicts() {
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::intel_cpu_LT, "Graph::ResolveComplexInplaceConflicts");

ptrdiff_t numberOfEdges = static_cast<ptrdiff_t>(graphEdges.size());

std::unordered_set<std::string> uniqueLayerNames;
for (auto node : graphNodes) {
uniqueLayerNames.insert(node->getName());
}
std::unordered_set<std::string> uniqueLayerNames = getUniqueLayerNames(graphNodes);

auto updateEdge = [&](ptrdiff_t& i) {
graphEdges.erase(graphEdges.begin() + i);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/intel_cpu/src/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class Graph {
void EnforceInferencePrecision();
void EnforceBF16();
void insertReorder(EdgePtr& edge, bool isOptimized, std::unordered_set<std::string>& uniqueLayerNames);
void insertConvert(EdgePtr& edge);
};

using GraphPtr = std::shared_ptr<Graph>;
Expand Down

0 comments on commit 4ee44d8

Please sign in to comment.