[IE][VPU]: Fix injection in dynamic case (#4343)
* Redirect StageDependencies from injected stage to the parent of the injection. * Change StageDependencyEdge to be Stage<->Stage connection. In fact, it affects only stages order, so it would be more natural (also more convenient) to represent it so. * Add injectedStageDependencies to InjectionEdge to be able to distinguish those dependencies that were added to hwStage during the injection process and make the revertion correct.
This commit is contained in:
parent
7df5a98dde
commit
695d2a90ba
@ -126,8 +126,6 @@ class DataNode final :
|
||||
VPU_MODEL_ATTRIBUTE(StageOutput, producerEdge, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE_PTR_RANGE(StageInputList, consumerEdges)
|
||||
|
||||
VPU_MODEL_ATTRIBUTE_PTR_RANGE(StageDependencyList, dependentStagesEdges)
|
||||
|
||||
VPU_MODEL_ATTRIBUTE(StageTempBuffer, tempBufferEdge, nullptr)
|
||||
|
||||
/**
|
||||
@ -282,7 +280,6 @@ private:
|
||||
private:
|
||||
inline DataNode() :
|
||||
_consumerEdges(&StageInputEdge::_posInData),
|
||||
_dependentStagesEdges(&StageDependencyEdge::_posInData),
|
||||
_childDataToDataEdges(&DataToDataAllocationEdge::_posInData),
|
||||
_childDataToShapeEdges(&DataToShapeAllocationEdge::_posInData),
|
||||
_posInModel(this) {
|
||||
|
@ -37,28 +37,6 @@ private:
|
||||
friend DataNode;
|
||||
};
|
||||
|
||||
//
|
||||
// StageDependencyEdge defines that some data should be calculated before the stage starts
|
||||
// but this data is not an input for the stage, e.g. this data is used as a shape for stage output.
|
||||
//
|
||||
|
||||
class StageDependencyEdge final :
|
||||
public EnableHandle,
|
||||
public EnableCustomAttributes {
|
||||
VPU_MODEL_ATTRIBUTE(Data, dependency, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE(Stage, dependentStage, nullptr)
|
||||
|
||||
private:
|
||||
StageDependencyEdge() : _posInData(this) {}
|
||||
|
||||
private:
|
||||
StageDependencyPtrList::iterator _ptrPosInModel;
|
||||
StageDependencyListNode _posInData;
|
||||
|
||||
friend ModelObj;
|
||||
friend DataNode;
|
||||
};
|
||||
|
||||
//
|
||||
// StageOutputEdge
|
||||
//
|
||||
@ -209,6 +187,7 @@ class InjectionEdge final :
|
||||
VPU_MODEL_ATTRIBUTE(Stage, parent, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE(StagePtr, child, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE(int, portInd, -1)
|
||||
VPU_MODEL_ATTRIBUTE(StageDependencyVector, injectedStageDependencies, {})
|
||||
|
||||
private:
|
||||
InjectionEdge() : _posInStage(this) {}
|
||||
@ -222,4 +201,25 @@ private:
|
||||
friend StageNode;
|
||||
};
|
||||
|
||||
//
|
||||
// StageDependencyEdge defines that some stage should be executed before other
|
||||
//
|
||||
|
||||
class StageDependencyEdge final :
|
||||
public EnableHandle,
|
||||
public EnableCustomAttributes {
|
||||
VPU_MODEL_ATTRIBUTE(Stage, parent, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE(Stage, child, nullptr)
|
||||
|
||||
private:
|
||||
StageDependencyEdge() : _posInStage(this) {}
|
||||
|
||||
private:
|
||||
StageDependencyPtrList::iterator _ptrPosInModel;
|
||||
StageDependencyListNode _posInStage;
|
||||
|
||||
friend ModelObj;
|
||||
friend StageNode;
|
||||
};
|
||||
|
||||
} // namespace vpu
|
||||
|
@ -139,8 +139,8 @@ public:
|
||||
const Data& data);
|
||||
|
||||
StageDependency addStageDependency(
|
||||
const Stage& stage,
|
||||
const Data& data);
|
||||
const Stage& parent,
|
||||
const Stage& child);
|
||||
|
||||
StageTempBuffer addTempBuffer(
|
||||
const Stage& stage,
|
||||
@ -158,16 +158,16 @@ public:
|
||||
const StageOutput& edge,
|
||||
const Data& newOutput);
|
||||
|
||||
void replaceStageDependency(
|
||||
void replaceStageDependencyParent(
|
||||
const StageDependency& edge,
|
||||
const Data& newDependency);
|
||||
const Stage& newParent);
|
||||
|
||||
void replaceDependentStage(
|
||||
void replaceStageDependencyChild(
|
||||
const StageDependency& edge,
|
||||
const Stage& newDependentStage);
|
||||
const Stage& newChild);
|
||||
|
||||
void removeStageDependency(const StageDependency& edge);
|
||||
void removeStageDependency(const Stage& stage, const Data& dependency);
|
||||
void removeStageDependency(const Stage& parent, const Stage& child);
|
||||
|
||||
//
|
||||
// Stage <-> Stage edges
|
||||
|
@ -411,6 +411,9 @@ class StageNode :
|
||||
|
||||
VPU_MODEL_ATTRIBUTE_PTR_RANGE(StageTempBufferVector, tempBufferEdges)
|
||||
|
||||
VPU_MODEL_ATTRIBUTE_PTR_RANGE(StageDependencyVector, parentDependencyEdges)
|
||||
VPU_MODEL_ATTRIBUTE_PTR_RANGE(StageDependencyVector, childDependencyEdges)
|
||||
|
||||
VPU_MODEL_ATTRIBUTE(Injection, parentStageEdge, nullptr)
|
||||
VPU_MODEL_ATTRIBUTE(Injection, injectedStageEdge, nullptr)
|
||||
|
||||
|
@ -310,22 +310,6 @@ void BackEnd::dumpModelToDot(
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dump Data->Stage edges
|
||||
//
|
||||
|
||||
for (const auto& data : model->datas()) {
|
||||
for (const auto& dependentStageEdge : data->dependentStagesEdges()) {
|
||||
out.append("%s -> %s [", dataDotName(data), stageDotName(dependentStageEdge->dependentStage()));
|
||||
{
|
||||
VPU_DOT_IDENT(out);
|
||||
|
||||
DotLabel lbl("Extra dependency", out);
|
||||
}
|
||||
out.append("];");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dump Data<->Data edges
|
||||
//
|
||||
@ -395,6 +379,16 @@ void BackEnd::dumpModelToDot(
|
||||
}
|
||||
out.append("}");
|
||||
}
|
||||
|
||||
for (const auto& stageDependencyEdge : stage->childDependencyEdges()) {
|
||||
out.append("%s -> %s [", stageDotName(stage), stageDotName(stageDependencyEdge->child()));
|
||||
{
|
||||
VPU_DOT_IDENT(out);
|
||||
|
||||
DotLabel lbl("Extra dependency", out);
|
||||
}
|
||||
out.append("];");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.append("}");
|
||||
|
@ -217,8 +217,7 @@ bool Allocator::allocateData(const Data& data) {
|
||||
VPU_INTERNAL_CHECK(data->producerEdge() != nullptr,
|
||||
"Allocation check failed: data {} with usage {} must have producer, but actually it doesn't",
|
||||
data->name(), data->usage());
|
||||
VPU_INTERNAL_CHECK(!data->consumers().empty() || !data->childDataToShapeEdges().empty() ||
|
||||
!data->dependentStagesEdges().empty(),
|
||||
VPU_INTERNAL_CHECK(!data->consumers().empty() || !data->childDataToShapeEdges().empty(),
|
||||
"Allocation check failed: data {} with usage {} must have at least one data/stage "
|
||||
"depending on it, but it doesn't have either",
|
||||
data->name(), data->usage());
|
||||
|
@ -53,13 +53,14 @@ void PassImpl::run(const Model& model) {
|
||||
DataDesc(DataType::S32, DimsOrder::C, {convertedShape->desc().totalDimSize()}),
|
||||
generator);
|
||||
|
||||
_stageBuilder->addGatherStage(model,
|
||||
shape->name() + "@convert-notation",
|
||||
nullptr,
|
||||
shape,
|
||||
gatherIndices,
|
||||
convertedShape,
|
||||
Dim::C);
|
||||
const auto& gather = _stageBuilder->addGatherStage(
|
||||
model,
|
||||
shape->name() + "@convert-notation",
|
||||
nullptr,
|
||||
shape,
|
||||
gatherIndices,
|
||||
convertedShape,
|
||||
Dim::C);
|
||||
|
||||
for (const auto& dataToShapeEdge : shape->childDataToShapeEdges()) {
|
||||
model->replaceDataToShapeParent(dataToShapeEdge, convertedShape);
|
||||
@ -81,18 +82,18 @@ void PassImpl::run(const Model& model) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& dependentStagesEdges = convertedShape->dependentStagesEdges();
|
||||
const auto& stageDependencyEdges = gather->childDependencyEdges();
|
||||
|
||||
for (const auto& consumer : child->consumers()) {
|
||||
const auto it = std::find_if(dependentStagesEdges.begin(), dependentStagesEdges.end(), [&consumer](const StageDependency& edge) {
|
||||
return edge->dependentStage() == consumer;
|
||||
const auto it = std::find_if(stageDependencyEdges.begin(), stageDependencyEdges.end(), [&consumer](const StageDependency& edge) {
|
||||
return edge->child() == consumer;
|
||||
});
|
||||
|
||||
if (it != dependentStagesEdges.end()) {
|
||||
if (it != stageDependencyEdges.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
model->addStageDependency(consumer, convertedShape);
|
||||
model->addStageDependency(gather, consumer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,34 +391,25 @@ StageOutput ModelObj::addStageOutput(
|
||||
return edge;
|
||||
}
|
||||
|
||||
StageDependency ModelObj::addStageDependency(const Stage& stage, const Data& data) {
|
||||
for (const auto& dependentStageEdge : data->dependentStagesEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->dependentStage() != stage,
|
||||
"Adding stage dependency for {} with type {} failed: data {} with usage {} is already its dependency",
|
||||
stage->name(), stage->type(), data->name(), data->usage());
|
||||
StageDependency ModelObj::addStageDependency(const Stage& parent, const Stage& child) {
|
||||
for (const auto& dependentStageEdge : parent->childDependencyEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->child() != child,
|
||||
"Adding dependent stage for {} with type {} failed: stage {} with type {} is already its dependent stage",
|
||||
parent->name(), parent->type(), child->name(), child->type());
|
||||
}
|
||||
|
||||
for (const auto& input : stage->inputs()) {
|
||||
VPU_THROW_UNLESS(data != input,
|
||||
"Adding stage dependency for {} with type {} failed: data {} with usage {} is already its input",
|
||||
stage->name(), stage->type(), data->name(), data->usage());
|
||||
}
|
||||
|
||||
VPU_THROW_UNLESS(data->producer() != nullptr,
|
||||
"Adding stage dependency for {} with type {} failed: data {} with usage {} should have producer, "
|
||||
"but actually it doesn't", stage->name(), stage->type(), data->name(), data->usage());
|
||||
|
||||
_resetStageOrder = true;
|
||||
|
||||
std::shared_ptr<StageDependencyEdge> edge(new StageDependencyEdge);
|
||||
edge->_ptrPosInModel = _stageDependencyEdgePtrList.emplace(_stageDependencyEdgePtrList.end(), edge);
|
||||
|
||||
edge->_dependency = data;
|
||||
edge->_dependentStage = stage;
|
||||
edge->_parent = parent;
|
||||
edge->_child = child;
|
||||
|
||||
data->_dependentStagesEdges.push_back(edge);
|
||||
parent->_childDependencyEdges.push_back(edge);
|
||||
child->_parentDependencyEdges.push_back(edge);
|
||||
|
||||
setStagesOrder(data->producerEdge()->producer(), stage);
|
||||
setStagesOrder(parent, child);
|
||||
|
||||
return edge;
|
||||
}
|
||||
@ -681,111 +672,84 @@ void ModelObj::replaceStageOutput(
|
||||
}
|
||||
}
|
||||
|
||||
void ModelObj::replaceStageDependency(
|
||||
void ModelObj::replaceStageDependencyParent(
|
||||
const StageDependency& edge,
|
||||
const Data& newDependency) {
|
||||
const auto previousDependency = edge->dependency();
|
||||
const auto dependentStage = edge->dependentStage();
|
||||
const Stage& newParent) {
|
||||
const auto previousParent = edge->parent();
|
||||
const auto child = edge->child();
|
||||
|
||||
for (const auto& dependentStageEdge : newDependency->dependentStagesEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->dependentStage() != dependentStage,
|
||||
"replaceStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"new dependency {} with usage {} is already dependency for dependent stage", previousDependency->name(), previousDependency->usage(),
|
||||
dependentStage->name(), dependentStage->type(), newDependency->name(), newDependency->usage());
|
||||
for (const auto& dependentStageEdge : newParent->childDependencyEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->child() != child,
|
||||
"replaceStageDependencyParent failed for {} with type {}: stage {} with type {} is already its parent",
|
||||
child->name(), child->type(), newParent->name(), newParent->type());
|
||||
}
|
||||
|
||||
for (const auto& input : dependentStage->inputs()) {
|
||||
VPU_THROW_UNLESS(newDependency != input,
|
||||
"replaceStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"new dependency {} with usage {} is already input for dependent stage", previousDependency->name(), previousDependency->usage(),
|
||||
dependentStage->name(), dependentStage->type(), newDependency->name(), newDependency->usage());
|
||||
}
|
||||
|
||||
VPU_THROW_UNLESS(newDependency->producer() != nullptr,
|
||||
"replaceStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"newDependency {} with usage {} has no producer", previousDependency->name(), previousDependency->usage(),
|
||||
dependentStage->name(), dependentStage->type(), newDependency->name(), newDependency->usage());
|
||||
|
||||
VPU_THROW_UNLESS(previousDependency->producer() != nullptr,
|
||||
"replaceStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"previous dependency has no producer",
|
||||
previousDependency->name(), previousDependency->usage(), dependentStage->name(), dependentStage->type());
|
||||
|
||||
_resetStageOrder = true;
|
||||
|
||||
previousDependency->_dependentStagesEdges.erase(edge);
|
||||
auto& childDependencyEdges = previousParent->_childDependencyEdges;
|
||||
childDependencyEdges.erase(std::remove(childDependencyEdges.begin(), childDependencyEdges.end(), edge));
|
||||
|
||||
removeStagesOrder(previousDependency->producer(), dependentStage);
|
||||
removeStagesOrder(previousParent, child);
|
||||
|
||||
edge->_dependency = newDependency;
|
||||
newDependency->_dependentStagesEdges.push_back(edge);
|
||||
edge->_parent = newParent;
|
||||
newParent->_childDependencyEdges.push_back(edge);
|
||||
|
||||
setStagesOrder(newDependency->producerEdge()->producer(), dependentStage);
|
||||
setStagesOrder(newParent, child);
|
||||
}
|
||||
|
||||
void ModelObj::replaceDependentStage(
|
||||
void ModelObj::replaceStageDependencyChild(
|
||||
const StageDependency& edge,
|
||||
const Stage& newDependentStage) {
|
||||
const auto dependency = edge->dependency();
|
||||
const auto previousDependentStage = edge->dependentStage();
|
||||
const Stage& newChild) {
|
||||
const auto parent = edge->parent();
|
||||
const auto previousChild = edge->child();
|
||||
|
||||
for (const auto& dependentStageEdge : dependency->dependentStagesEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->dependentStage() != newDependentStage,
|
||||
"replaceDependentStage failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"new dependent stage {} with type {} is already dependent stage for dependency", dependency->name(), dependency->usage(),
|
||||
previousDependentStage->name(), previousDependentStage->type(), newDependentStage->name(), newDependentStage->type());
|
||||
for (const auto& dependentStageEdge : parent->childDependencyEdges()) {
|
||||
VPU_THROW_UNLESS(dependentStageEdge->child() != newChild,
|
||||
"replaceStageDependencyChild failed for {} with type {}: stage {} with type {} is already its child",
|
||||
parent->name(), parent->type(), newChild->name(), newChild->type());
|
||||
}
|
||||
|
||||
for (const auto& input : newDependentStage->inputs()) {
|
||||
VPU_THROW_UNLESS(dependency != input,
|
||||
"replaceDependentStage failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"new dependent stage {} with type {} already has dependency as its input", dependency->name(), dependency->usage(),
|
||||
previousDependentStage->name(), previousDependentStage->type(), newDependentStage->name(), newDependentStage->type());
|
||||
}
|
||||
|
||||
VPU_THROW_UNLESS(dependency->producer() != nullptr,
|
||||
"replaceDependentStage failed for dependency {} with usage {} and dependentStage {} with type {}: "
|
||||
"dependency has no producer",
|
||||
dependency->name(), dependency->usage(), previousDependentStage->name(), previousDependentStage->type());
|
||||
|
||||
_resetStageOrder = true;
|
||||
|
||||
removeStagesOrder(dependency->producer(), previousDependentStage);
|
||||
auto& parentDependencyEdges = previousChild->_parentDependencyEdges;
|
||||
parentDependencyEdges.erase(std::remove(parentDependencyEdges.begin(), parentDependencyEdges.end(), edge));
|
||||
|
||||
edge->_dependentStage = newDependentStage;
|
||||
removeStagesOrder(parent, previousChild);
|
||||
|
||||
setStagesOrder(dependency->producer(), newDependentStage);
|
||||
edge->_child = newChild;
|
||||
newChild->_parentDependencyEdges.push_back(edge);
|
||||
|
||||
setStagesOrder(parent, newChild);
|
||||
}
|
||||
|
||||
void ModelObj::removeStageDependency(const StageDependency& edge) {
|
||||
const auto dependency = edge->dependency();
|
||||
const auto dependentStage = edge->dependentStage();
|
||||
|
||||
VPU_THROW_UNLESS(dependency->producer(),
|
||||
"removeStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: dependency has no producer",
|
||||
dependency->name(), dependency->usage(), dependentStage->name(), dependentStage->type());
|
||||
const auto parent = edge->parent();
|
||||
const auto child = edge->child();
|
||||
|
||||
_resetStageOrder = true;
|
||||
|
||||
dependency->_dependentStagesEdges.erase(edge);
|
||||
auto& childDependencyEdges = parent->_childDependencyEdges;
|
||||
childDependencyEdges.erase(std::remove(childDependencyEdges.begin(), childDependencyEdges.end(), edge));
|
||||
auto& parentDependencyEdges = child->_parentDependencyEdges;
|
||||
parentDependencyEdges.erase(std::remove(parentDependencyEdges.begin(), parentDependencyEdges.end(), edge));
|
||||
|
||||
removeStagesOrder(dependency->producer(), dependentStage);
|
||||
removeStagesOrder(parent, child);
|
||||
|
||||
VPU_THROW_UNLESS(edge->_ptrPosInModel != _stageDependencyEdgePtrList.end(),
|
||||
"removeStageDependency failed for dependency {} with usage {} and dependentStage {} with type {}: no such edge in Model's DataToShapeEdges list",
|
||||
dependency->name(), dependency->usage(), dependentStage->name(), dependentStage->type());
|
||||
"removeStageDependency failed for parent {} with type {} and child {} with type {}: no such edge in Model's DataToShapeEdges list",
|
||||
parent->name(), parent->type(), child->name(), child->type());
|
||||
|
||||
_stageDependencyEdgePtrList.erase(edge->_ptrPosInModel);
|
||||
}
|
||||
|
||||
void ModelObj::removeStageDependency(const Stage& stage, const Data& dependency) {
|
||||
const auto& dependentStagesEdges = dependency->dependentStagesEdges();
|
||||
void ModelObj::removeStageDependency(const Stage& parent, const Stage& child) {
|
||||
const auto& childDependencyEdges = parent->childDependencyEdges();
|
||||
|
||||
const auto it = std::find_if(dependentStagesEdges.begin(), dependentStagesEdges.end(), [&stage](const StageDependency& edge) {
|
||||
return edge->dependentStage() == stage;
|
||||
const auto it = std::find_if(childDependencyEdges.begin(), childDependencyEdges.end(), [&child](const StageDependency& edge) {
|
||||
return edge->child() == child;
|
||||
});
|
||||
|
||||
if (it != dependentStagesEdges.end()) {
|
||||
if (it != childDependencyEdges.end()) {
|
||||
const auto stageDependencyEdge = *it;
|
||||
removeStageDependency(stageDependencyEdge);
|
||||
}
|
||||
@ -923,6 +887,22 @@ Injection ModelObj::injectStageImpl(
|
||||
parent->_injectedStageEdge = edge;
|
||||
child->_parentStageEdge = edge;
|
||||
|
||||
//
|
||||
// Redirect child stage dependencies to parent.
|
||||
//
|
||||
|
||||
const auto parentDependencyEdges = child->_parentDependencyEdges;
|
||||
for (const auto& parentDependencyEdge : parentDependencyEdges) {
|
||||
edge->_injectedStageDependencies.push_back(parentDependencyEdge);
|
||||
replaceStageDependencyChild(parentDependencyEdge, parent);
|
||||
}
|
||||
|
||||
const auto childDependencyEdges = child->_childDependencyEdges;
|
||||
for (const auto& childDependencyEdge : childDependencyEdges) {
|
||||
edge->_injectedStageDependencies.push_back(childDependencyEdge);
|
||||
replaceStageDependencyParent(childDependencyEdge, parent);
|
||||
}
|
||||
|
||||
//
|
||||
// Redirect child inputs to parent.
|
||||
//
|
||||
@ -1049,6 +1029,19 @@ void ModelObj::revertInjection(const Injection& edge) {
|
||||
|
||||
childStage->_ptrPosInModel = _stagePtrList.emplace(_stagePtrList.end(), childStage);
|
||||
|
||||
//
|
||||
// Redirect stage dependencies back to child.
|
||||
//
|
||||
|
||||
for (const auto& injectedStageDependency : edge->injectedStageDependencies()) {
|
||||
if (parentStage == injectedStageDependency->parent()) {
|
||||
replaceStageDependencyParent(injectedStageDependency, childStage);
|
||||
} else {
|
||||
replaceStageDependencyChild(injectedStageDependency, childStage);
|
||||
}
|
||||
}
|
||||
edge->_injectedStageDependencies.clear();
|
||||
|
||||
//
|
||||
// Remove Injection Edge from parent and child Stage.
|
||||
//
|
||||
@ -1706,7 +1699,7 @@ DataToShapeAllocation ModelObj::connectDataWithShape(
|
||||
|
||||
if (childProducer && isStageDependencyNeeded(childProducer, parent)) {
|
||||
// Shape and data are produced from different stages, make sure that shape is calculated before data
|
||||
addStageDependency(childProducer, parent);
|
||||
addStageDependency(parent->producer(), childProducer);
|
||||
}
|
||||
|
||||
return edge;
|
||||
@ -1724,11 +1717,14 @@ void ModelObj::replaceDataToShapeParent(
|
||||
|
||||
const auto& childProducer = child->producer();
|
||||
if (childProducer != nullptr) {
|
||||
removeStageDependency(childProducer, oldParent);
|
||||
const auto& oldParentProducer = oldParent->producer();
|
||||
if (oldParentProducer != nullptr) {
|
||||
removeStageDependency(oldParent->producer(), childProducer);
|
||||
}
|
||||
|
||||
if (isStageDependencyNeeded(childProducer, newParent)) {
|
||||
// Shape and data are produced from different stages, make sure that shape is calculated before data
|
||||
addStageDependency(childProducer, newParent);
|
||||
addStageDependency(newParent->producer(), childProducer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1749,15 +1745,16 @@ void ModelObj::replaceDataToShapeChild(
|
||||
newChild->_parentDataToShapeEdge = edge;
|
||||
|
||||
const auto& oldChildProducer = oldChild->producer();
|
||||
if (oldChildProducer != nullptr) {
|
||||
removeStageDependency(oldChildProducer, parent);
|
||||
const auto& parentProducer = parent->producer();
|
||||
if (parentProducer != nullptr && oldChildProducer != nullptr) {
|
||||
removeStageDependency(parentProducer, oldChildProducer);
|
||||
}
|
||||
|
||||
const auto& newChildProducer = newChild->producer();
|
||||
|
||||
if (newChildProducer && isStageDependencyNeeded(newChildProducer, parent)) {
|
||||
// Shape and data are produced from different stages, make sure that shape is calculated before data
|
||||
addStageDependency(newChildProducer, parent);
|
||||
addStageDependency(parent->producer(), newChildProducer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1839,8 +1836,9 @@ void ModelObj::disconnectDatas(const DataToShapeAllocation& edge) {
|
||||
_shapeEdgePtrList.erase(edge->_ptrPosInModel);
|
||||
|
||||
const auto& childProducer = child->producer();
|
||||
if (childProducer != nullptr) {
|
||||
removeStageDependency(childProducer, parent);
|
||||
const auto& parentProducer = parent->producer();
|
||||
if (parentProducer != nullptr && childProducer != nullptr) {
|
||||
removeStageDependency(parentProducer, childProducer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1893,7 +1891,10 @@ void ModelObj::disconnectStage(const Stage& stage) {
|
||||
for (const auto& outEdge : stage->_outputEdges) {
|
||||
// Disconnect from dependency
|
||||
if (const auto& dataToShapeEdge = outEdge->output()->parentDataToShapeEdge()) {
|
||||
removeStageDependency(stage, dataToShapeEdge->parent());
|
||||
const auto& parentProducer = dataToShapeEdge->parent()->producer();
|
||||
if (parentProducer != nullptr) {
|
||||
removeStageDependency(parentProducer, stage);
|
||||
}
|
||||
}
|
||||
// Disconnect from consumers
|
||||
for (const auto& consumerEdge : outEdge->_output->_consumerEdges) {
|
||||
|
@ -163,7 +163,10 @@ void TestModel::createOutputs(std::vector<DataDesc> descriptors) {
|
||||
}
|
||||
}
|
||||
|
||||
Stage TestModel::addStage(const std::vector<InputInfo>& curInputInfos, const std::vector<OutputInfo>& curOutputInfos) {
|
||||
Stage TestModel::addStage(
|
||||
const std::vector<InputInfo>& curInputInfos,
|
||||
const std::vector<OutputInfo>& curOutputInfos,
|
||||
StageType stageType) {
|
||||
DataVector curInputs;
|
||||
for (const auto& info : curInputInfos) {
|
||||
if (info.type == InputType::Original) {
|
||||
@ -188,7 +191,7 @@ Stage TestModel::addStage(const std::vector<InputInfo>& curInputInfos, const std
|
||||
|
||||
auto stage = _model->addNewStage<TestStage>(
|
||||
formatString("Stage %m%m%d", std::setw(2), std::setfill('0'), _stages.size()),
|
||||
StageType::None,
|
||||
stageType,
|
||||
nullptr,
|
||||
curInputs,
|
||||
curOutputs);
|
||||
|
@ -95,7 +95,10 @@ public:
|
||||
void createInputs(std::vector<DataDesc> inputDescs = {});
|
||||
void createOutputs(std::vector<DataDesc> outputDescs = {});
|
||||
|
||||
Stage addStage(const std::vector<InputInfo>& curInputInfos, const std::vector<OutputInfo>& curOutputInfos);
|
||||
Stage addStage(
|
||||
const std::vector<InputInfo>& curInputInfos,
|
||||
const std::vector<OutputInfo>& curOutputInfos,
|
||||
StageType stageType = StageType::None);
|
||||
|
||||
void setStageDataOrderInfo(
|
||||
int stageInd,
|
||||
|
@ -328,12 +328,12 @@ TEST_F(DataToShapeEdgeProcessingTests, ReplaceDataToShapeParentReplacesConnectio
|
||||
ASSERT_EQ(finalShape->childDataToShapeEdges().front(), dataToShapeEdge);
|
||||
ASSERT_EQ(dataToShapeEdge->parent(), finalShape);
|
||||
|
||||
ASSERT_TRUE(initialShape->dependentStagesEdges().empty());
|
||||
ASSERT_FALSE(finalShape->dependentStagesEdges().empty());
|
||||
ASSERT_TRUE(firstShapeProcessor->childDependencyEdges().empty());
|
||||
ASSERT_FALSE(secondShapeProcessor->childDependencyEdges().empty());
|
||||
|
||||
const auto& stageDependencyEdge = finalShape->dependentStagesEdges().front();
|
||||
ASSERT_EQ(stageDependencyEdge->dependentStage(), dataProcessor);
|
||||
ASSERT_EQ(stageDependencyEdge->dependency(), finalShape);
|
||||
const auto& stageDependencyEdge = secondShapeProcessor->childDependencyEdges().front();
|
||||
ASSERT_EQ(stageDependencyEdge->child(), dataProcessor);
|
||||
ASSERT_EQ(stageDependencyEdge->parent(), secondShapeProcessor);
|
||||
}
|
||||
|
||||
TEST_F(DataToShapeEdgeProcessingTests, ReplaceDataToShapeChildReplacesConnections) {
|
||||
@ -372,11 +372,11 @@ TEST_F(DataToShapeEdgeProcessingTests, ReplaceDataToShapeChildReplacesConnection
|
||||
ASSERT_EQ(finalData->parentDataToShapeEdge(), dataToShapeEdge);
|
||||
ASSERT_EQ(dataToShapeEdge->child(), finalData);
|
||||
|
||||
ASSERT_FALSE(processedShape->dependentStagesEdges().empty());
|
||||
const auto& stageDependencyEdge = processedShape->dependentStagesEdges().front();
|
||||
ASSERT_FALSE(shapeProcessor->childDependencyEdges().empty());
|
||||
const auto& stageDependencyEdge = shapeProcessor->childDependencyEdges().front();
|
||||
|
||||
ASSERT_EQ(stageDependencyEdge->dependentStage(), secondDataProcessor);
|
||||
ASSERT_EQ(stageDependencyEdge->dependency(), processedShape);
|
||||
ASSERT_EQ(stageDependencyEdge->child(), secondDataProcessor);
|
||||
ASSERT_EQ(stageDependencyEdge->parent(), shapeProcessor);
|
||||
}
|
||||
|
||||
TEST_F(DataToShapeEdgeProcessingTests, DisconnectDatasRemovesConnections) {
|
||||
@ -408,7 +408,7 @@ TEST_F(DataToShapeEdgeProcessingTests, DisconnectDatasRemovesConnections) {
|
||||
|
||||
ASSERT_EQ(processedData->parentDataToShapeEdge(), nullptr);
|
||||
ASSERT_TRUE(processedShape->childDataToShapeEdges().empty());
|
||||
ASSERT_TRUE(processedShape->dependentStagesEdges().empty());
|
||||
ASSERT_TRUE(shapeProcessor->childDependencyEdges().empty());
|
||||
}
|
||||
|
||||
} // namespace vpu
|
||||
|
@ -22,266 +22,9 @@ protected:
|
||||
TestModel _testModel;
|
||||
};
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyAssertsOnNetworkInput) {
|
||||
//
|
||||
// -> [Output]
|
||||
// [Input] -> (Stage)
|
||||
// -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
auto stage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(0),
|
||||
OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_ANY_THROW(model->addStageDependency(stage, _testModel.getInputs().front()));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyAssertsOnStageInput) {
|
||||
//
|
||||
// -> [Output]
|
||||
// [Input] -> (Stage)
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::fromNetwork(1)});
|
||||
auto stage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_ANY_THROW(model->addStageDependency(stage, stage->input(0)));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyDoesNotAssertOnOutputData) {
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyDoesNotAssertOnOutputProducer) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyAssertsIfDependencyExists) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
ASSERT_ANY_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, NetWithTwoStagesHasCorrectExecOrder) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::intermediate(desc)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(2)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependentStage->id(), dependencyProducer->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependencyProducer->id(), dependentStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, NetWithThreeStagesHasCorrectExecOrder) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ---------------------------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::intermediate(desc)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(2)}, {OutputInfo::intermediate(desc)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(3)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependentStage->id(), dependencyProducer->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependencyProducer->id(), dependentStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyAssertsOnNetworkInput) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceStageDependency(edge, _testModel.getInputs().front()));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyAssertsOnStageInput) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceStageDependency(edge, dependentStage->input(0)));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyAssertsIfDependencyExists) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceStageDependency(edge, dependencyProducer->output(0)));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyReplacesConnection) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
// [Input] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto initialDependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto resultDependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(2)}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, initialDependencyProducer->output(0)));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {initialDependencyProducer->id(), dependentStage->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependentStage->id(), resultDependencyProducer->id()}));
|
||||
|
||||
const auto edge = initialDependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_NO_THROW(model->replaceStageDependency(edge, resultDependencyProducer->output(0)));
|
||||
|
||||
ASSERT_EQ(initialDependencyProducer->output(0)->dependentStagesEdges().size(), 0);
|
||||
ASSERT_EQ(edge->dependency(), resultDependencyProducer->output(0));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {resultDependencyProducer->id(), dependentStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageAssertsOnStageInput) {
|
||||
//
|
||||
// -----------> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
@ -291,25 +34,21 @@ TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageAssertsOnStageIn
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto initialDependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto resultDependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(initialDependentStage, dependencyProducer->output(1)));
|
||||
|
||||
const auto edge = dependencyProducer->output(1)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceDependentStage(edge, resultDependentStage));
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageAssertsIfDependencyExists) {
|
||||
TEST_F(StageDependencyEdgeProcessingTests, AddStageDependencyAssertsIfDependencyExists) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
@ -319,25 +58,103 @@ TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageAssertsIfDepende
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceDependentStage(edge, dependentStage));
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
ASSERT_ANY_THROW(model->addStageDependency(parentStage, childStage));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageReplacesConnection) {
|
||||
TEST_F(StageDependencyEdgeProcessingTests, NetWithTwoStagesHasCorrectExecOrder) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::intermediate(desc)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(2)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {childStage->id(), parentStage->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), childStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, NetWithThreeStagesHasCorrectExecOrder) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ----------------------> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::intermediate(desc)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(2)}, {OutputInfo::intermediate(desc)});
|
||||
_testModel.addStage({InputInfo::fromPrevStage(3)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {childStage->id(), parentStage->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), childStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyParentAssertsIfDependencyExists) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
const auto edge = parentStage->childDependencyEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceStageDependencyParent(edge, parentStage));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyParentReplacesConnection) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
// [Input] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
// |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
@ -348,31 +165,32 @@ TEST_F(StageDependencyEdgeProcessingTests, ReplaceDependentStageReplacesConnecti
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto initialDependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto resultDependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(2)}, {OutputInfo::fromNetwork(2)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto initialParentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto resultParentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(2)}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(initialDependentStage, dependencyProducer->output(0)));
|
||||
ASSERT_NO_THROW(model->addStageDependency(initialParentStage, childStage));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependencyProducer->id(), initialDependentStage->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {resultDependentStage->id(), dependencyProducer->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {initialParentStage->id(), childStage->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {childStage->id(), resultParentStage->id()}));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
const auto edge = initialParentStage->childDependencyEdges().front();
|
||||
|
||||
ASSERT_NO_THROW(model->replaceDependentStage(edge, resultDependentStage));
|
||||
ASSERT_NO_THROW(model->replaceStageDependencyParent(edge, resultParentStage));
|
||||
|
||||
ASSERT_EQ(edge->dependentStage(), resultDependentStage);
|
||||
ASSERT_EQ(initialParentStage->childDependencyEdges().size(), 0);
|
||||
ASSERT_EQ(edge->parent(), resultParentStage);
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {dependencyProducer->id(), resultDependentStage->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {resultParentStage->id(), childStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, RemoveStageDependencyUpdatesNextPrevStages) {
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyChildAssertsIfDependencyExists) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] ------------> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
@ -382,24 +200,87 @@ TEST_F(StageDependencyEdgeProcessingTests, RemoveStageDependencyUpdatesNextPrevS
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
const auto edge = dependencyProducer->output(0)->dependentStagesEdges().front();
|
||||
const auto edge = parentStage->childDependencyEdges().front();
|
||||
|
||||
ASSERT_ANY_THROW(model->replaceStageDependencyChild(edge, childStage));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, ReplaceStageDependencyChildReplacesConnection) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
// [Input] -> (Stage) -> [Data] -> (Stage) -> [Output]
|
||||
// |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto initialChildStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto resultChildStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(2)}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, initialChildStage));
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), initialChildStage->id()}));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {resultChildStage->id(), parentStage->id()}));
|
||||
|
||||
const auto edge = parentStage->childDependencyEdges().front();
|
||||
|
||||
ASSERT_NO_THROW(model->replaceStageDependencyChild(edge, resultChildStage));
|
||||
|
||||
ASSERT_EQ(edge->child(), resultChildStage);
|
||||
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), resultChildStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(StageDependencyEdgeProcessingTests, RemoveStageDependencyUpdatesNextPrevStages) {
|
||||
//
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) |
|
||||
// -> [Data] -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc});
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
const auto edge = parentStage->childDependencyEdges().front();
|
||||
|
||||
ASSERT_NO_THROW(model->removeStageDependency(edge));
|
||||
|
||||
const auto prevStages = dependentStage->prevStages();
|
||||
const auto nextStages = dependencyProducer->prevStages();
|
||||
const auto prevStages = childStage->prevStages();
|
||||
const auto nextStages = parentStage->prevStages();
|
||||
|
||||
auto it = std::find(prevStages.begin(), prevStages.end(), dependencyProducer);
|
||||
auto it = std::find(prevStages.begin(), prevStages.end(), parentStage);
|
||||
ASSERT_EQ(it, prevStages.end());
|
||||
|
||||
it = std::find(nextStages.begin(), nextStages.end(), dependentStage);
|
||||
it = std::find(nextStages.begin(), nextStages.end(), childStage);
|
||||
ASSERT_EQ(it, nextStages.end());
|
||||
}
|
||||
|
||||
@ -417,22 +298,22 @@ TEST_F(StageDependencyEdgeProcessingTests, RemoveStageDependencyViaDataToShapeEd
|
||||
|
||||
_testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::intermediate(desc),
|
||||
OutputInfo::intermediate(desc)});
|
||||
auto dependentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto dependencyProducer = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
auto childStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(0)}, {OutputInfo::fromNetwork(0)});
|
||||
auto parentStage = _testModel.addStage({InputInfo::fromPrevStage(0).output(1)}, {OutputInfo::fromNetwork(1)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, childStage));
|
||||
|
||||
ASSERT_NO_THROW(model->removeStageDependency(dependentStage, dependencyProducer->output(0)));
|
||||
ASSERT_NO_THROW(model->removeStageDependency(parentStage, childStage));
|
||||
|
||||
const auto prevStages = dependentStage->prevStages();
|
||||
const auto nextStages = dependencyProducer->prevStages();
|
||||
const auto prevStages = childStage->prevStages();
|
||||
const auto nextStages = parentStage->prevStages();
|
||||
|
||||
auto it = std::find(prevStages.begin(), prevStages.end(), dependencyProducer);
|
||||
auto it = std::find(prevStages.begin(), prevStages.end(), parentStage);
|
||||
ASSERT_EQ(it, prevStages.end());
|
||||
|
||||
it = std::find(nextStages.begin(), nextStages.end(), dependentStage);
|
||||
it = std::find(nextStages.begin(), nextStages.end(), childStage);
|
||||
ASSERT_EQ(it, nextStages.end());
|
||||
}
|
||||
|
||||
|
@ -89,16 +89,16 @@ protected:
|
||||
ASSERT_EQ(edge->parent(), shape);
|
||||
}
|
||||
|
||||
void checkStageDependency(const Data& shape, const Stage& stage) {
|
||||
ASSERT_FALSE(shape->dependentStagesEdges().empty());
|
||||
const auto& dependentStagesEdges = shape->dependentStagesEdges();
|
||||
void checkStageDependency(const Stage& parent, const Stage& child) {
|
||||
ASSERT_FALSE(parent->childDependencyEdges().empty());
|
||||
const auto& childDependencyEdges = parent->childDependencyEdges();
|
||||
|
||||
auto it = std::find_if(dependentStagesEdges.begin(), dependentStagesEdges.end(),
|
||||
[&stage](const StageDependency& edge) {
|
||||
return edge->dependentStage() == stage;
|
||||
auto it = std::find_if(childDependencyEdges.begin(), childDependencyEdges.end(),
|
||||
[&child](const StageDependency& edge) {
|
||||
return edge->child() == child;
|
||||
});
|
||||
|
||||
ASSERT_NE(it, dependentStagesEdges.end());
|
||||
ASSERT_NE(it, childDependencyEdges.end());
|
||||
}
|
||||
|
||||
void checkNoDataToShapeDependency(const Data& shape, const Data& data) {
|
||||
@ -114,15 +114,15 @@ protected:
|
||||
ASSERT_EQ(it, childDataToShapeEdges.end());
|
||||
}
|
||||
|
||||
void checkNoStageDependency(const Data& shape, const Stage& stage) {
|
||||
const auto& dependentStagesEdges = shape->dependentStagesEdges();
|
||||
void checkNoStageDependency(const Stage& parent, const Stage& child) {
|
||||
const auto& childDependencyEdges = parent->childDependencyEdges();
|
||||
|
||||
auto it = std::find_if(dependentStagesEdges.begin(), dependentStagesEdges.end(),
|
||||
[&stage](const StageDependency& edge) {
|
||||
return edge->dependentStage() == stage;
|
||||
auto it = std::find_if(childDependencyEdges.begin(), childDependencyEdges.end(),
|
||||
[&child](const StageDependency& edge) {
|
||||
return edge->child() == child;
|
||||
});
|
||||
|
||||
ASSERT_EQ(it, shape->dependentStagesEdges().end());
|
||||
ASSERT_EQ(it, parent->childDependencyEdges().end());
|
||||
}
|
||||
|
||||
void checkGathers(int gathersCount) {
|
||||
@ -145,8 +145,8 @@ protected:
|
||||
dependentStage = dataConsumingShape->producer();
|
||||
}
|
||||
|
||||
checkStageDependency(convertedShape, dependentStage);
|
||||
checkNoStageDependency(shape, dependentStage);
|
||||
checkStageDependency(convertedShape->producer(), dependentStage);
|
||||
checkNoStageDependency(shape->producer(), dependentStage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "graph_transformer_tests.hpp"
|
||||
|
||||
namespace vpu {
|
||||
|
||||
namespace ie = InferenceEngine;
|
||||
|
||||
class InjectStageTests : public GraphTransformerTest {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
ASSERT_NO_FATAL_FAILURE(GraphTransformerTest::SetUp());
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(InitCompileEnv());
|
||||
|
||||
_testModel = CreateTestModel();
|
||||
}
|
||||
|
||||
protected:
|
||||
TestModel _testModel;
|
||||
};
|
||||
|
||||
TEST_F(InjectStageTests, InjectionRedirectsChildStageDependency) {
|
||||
//
|
||||
// -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) -> [Output]
|
||||
// -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
const auto hwStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(0)}, StageType::MyriadXHwOp);
|
||||
const auto swStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(1)}, StageType::Copy);
|
||||
const auto childStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(swStage, childStage));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {swStage->id(), childStage->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->injectStage()
|
||||
.parentHW(hwStage)
|
||||
.childSW(swStage)
|
||||
.done());
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {hwStage->id(), childStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(InjectStageTests, InjectionRedirectsParentStageDependency) {
|
||||
//
|
||||
// -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) -> [Output]
|
||||
// -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
const auto hwStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(0)}, StageType::MyriadXHwOp);
|
||||
const auto swStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(1)}, StageType::Copy);
|
||||
const auto parentStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, swStage));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), swStage->id()}));
|
||||
|
||||
ASSERT_NO_THROW(model->injectStage()
|
||||
.parentHW(hwStage)
|
||||
.childSW(swStage)
|
||||
.done());
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), hwStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(InjectStageTests, RevertInjectionRedirectsChildStageDependency) {
|
||||
//
|
||||
// -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) -> [Output]
|
||||
// -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
const auto hwStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(0)}, StageType::MyriadXHwOp);
|
||||
const auto swStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(1)}, StageType::Copy);
|
||||
const auto parentStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, swStage));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), swStage->id()}));
|
||||
|
||||
Injection edge;
|
||||
ASSERT_NO_THROW(edge = model->injectStage()
|
||||
.parentHW(hwStage)
|
||||
.childSW(swStage)
|
||||
.done());
|
||||
ASSERT_NO_THROW(model->revertInjection(edge));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), swStage->id()}));
|
||||
}
|
||||
|
||||
TEST_F(InjectStageTests, RevertInjectionRedirectsParentStageDependency) {
|
||||
//
|
||||
// -> (Stage) -> [Output]
|
||||
// [Input] -> (Stage) -> [Output]
|
||||
// -> (Stage) -> [Output]
|
||||
//
|
||||
|
||||
const DataDesc desc{1};
|
||||
|
||||
_testModel.createInputs({desc});
|
||||
_testModel.createOutputs({desc, desc, desc});
|
||||
|
||||
const auto hwStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(0)}, StageType::MyriadXHwOp);
|
||||
const auto swStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(1)}, StageType::Copy);
|
||||
const auto parentStage = _testModel.addStage({InputInfo::fromNetwork()}, {OutputInfo::fromNetwork(2)});
|
||||
|
||||
auto model = _testModel.getBaseModel();
|
||||
|
||||
ASSERT_NO_THROW(model->addStageDependency(parentStage, swStage));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), swStage->id()}));
|
||||
|
||||
Injection edge;
|
||||
ASSERT_NO_THROW(edge = model->injectStage()
|
||||
.parentHW(hwStage)
|
||||
.childSW(swStage)
|
||||
.done());
|
||||
ASSERT_NO_THROW(model->revertInjection(edge));
|
||||
ASSERT_TRUE(checkExecutionOrder(model, {parentStage->id(), swStage->id()}));
|
||||
}
|
||||
|
||||
} // namespace vpu
|
Loading…
Reference in New Issue
Block a user