[IE][VPU]: Faster-RCNN fixes on myriad plugin side (#665)
authorGladilov, Gleb <gleb.gladilov@intel.com>
Sun, 31 May 2020 10:17:36 +0000 (13:17 +0300)
committerGitHub <noreply@github.com>
Sun, 31 May 2020 10:17:36 +0000 (13:17 +0300)
* [IE][VPU]: Fixes deallocation data for cases of CMX allocator run

The final loop tries to deallocate data objects that keep shape values for
other data objects that're outputs of a model. But the case when allocator
takes only CMX data into consideration was not handled and since allocation
could not happen, it lead to fail on deallocation of a data object that has
not been allocated.

Signed-off-by: Gladilov, Gleb <gleb.gladilov@intel.com>
* [IE][VPU]: Fixes allocator with work on data to shape edges

Since there is new relationship between data objects: some
data objects may contain shape of other data object - allocator
must properly respect that. The thing is if 2 data objects are
connected in such a way, they represent unite entity (dynamic
data object) and should have the same lifetime.

Signed-off-by: Gladilov, Gleb <gleb.gladilov@intel.com>
inference-engine/src/vpu/graph_transformer/src/middleend/allocator/allocator.cpp
inference-engine/src/vpu/graph_transformer/src/middleend/passes/allocate_resources.cpp

index 5c9ee38..92663b9 100644 (file)
@@ -92,6 +92,27 @@ void updateChildDataAllocation(const Data& data, int offsetLimitation) {
     }
 }
 
+int getInUse(const Data& data) {
+    int inUse = 0;
+    inUse += data->numConsumers();
+    for (const auto& childData : data->childDatas()) {
+        inUse += getInUse(childData);
+    }
+    for (const auto& childEdge : data->childDataToShapeEdges()) {
+        auto const& child = childEdge->child();
+        if (child->usage() == DataUsage::Output) {
+            VPU_THROW_UNLESS(child->parentData() == nullptr, "Output data object must not have parent");
+            inUse++;
+        } else if (child->getTopParentData() == child) {
+            inUse += getInUse(child);
+        } else {
+            inUse += child->numConsumers();
+        }
+    }
+    return inUse;
+}
+
+
 }  // namespace
 
 bool Allocator::allocateData(const Data& data) {
@@ -247,14 +268,9 @@ bool Allocator::allocateData(const Data& data) {
     if (data->usage() == DataUsage::Temp) {
         inUse = 1;
     } else {
-        loopOverData(data, [&inUse](const Data& subData) {
-            inUse += subData->numConsumers();
-            return DataLoopStatus::NextChild;
-        });
+        inUse = getInUse(data);
     }
 
-    inUse += data->childDataToShapeEdges().size();
-
     VPU_INTERNAL_CHECK(inUse >= 1,
         "allocateData failed: data {} with usage {} isn't used by anything",
         data->name(), data->usage());
@@ -356,23 +372,35 @@ void Allocator::freeData(const Data& data, DeallocationMode mode) {
     // Release the chunk
     //
 
-    if (const auto& parentDataToShapeEdge = data->parentDataToShapeEdge()) {
-        auto const& parent = parentDataToShapeEdge->parent();
-
-        if (parent->usage() == DataUsage::Intermediate || parent->usage() == DataUsage::Temp) {
-            auto chunk = getChunk(parent);
-            decreaseChunkUsage(chunk, parent);
+    auto topParent = data->getTopParentData();
+    if (topParent != data) {
+        if (const auto& parentDataToShapeEdge = data->parentDataToShapeEdge()) {
+            const auto& parent = parentDataToShapeEdge->parent();
+
+            if (parent->usage() == DataUsage::Intermediate || parent->usage() == DataUsage::Temp) {
+                const auto dtopParent = parent->getTopParentData();
+                const auto chunk = getChunk(dtopParent);
+                decreaseChunkUsage(chunk, dtopParent);
+            }
         }
     }
 
-    auto topParent = data->getTopParentData();
-
     if (topParent->usage() == DataUsage::Intermediate ||
         topParent->usage() == DataUsage::Temp) {
         auto chunk = getChunk(topParent);
 
         switch (mode) {
         case DeallocationMode::JustFree: {
+            if (const auto& parentDataToShapeEdge = topParent->parentDataToShapeEdge()) {
+                const auto& parent = parentDataToShapeEdge->parent();
+
+                if (parent->usage() == DataUsage::Intermediate || parent->usage() == DataUsage::Temp) {
+                    const auto dtopParent = parent->getTopParentData();
+                    const auto dchunk = getChunk(dtopParent);
+                    decreaseChunkUsage(dchunk, dtopParent);
+                }
+            }
+
             decreaseChunkUsage(chunk, topParent);
             break;
         }
index b99b538..81941de 100644 (file)
@@ -188,19 +188,15 @@ AllocationResult runAllocator(const Model& model, bool onlyCheckCMX) {
     // Clean up undeallocated shapes
     //
 
-    for (const auto& data : model->datas()) {
-        if (data->childDataToShapeEdges().empty()) {
-            continue;
-        }
-
-        if (data->usage() != DataUsage::Intermediate) {
+    for (auto data : model->datas()) {
+        if (data->usage() != DataUsage::Output) {
             continue;
         }
 
-        for (const auto& dataToShapeEdge : data->childDataToShapeEdges()) {
-            if (dataToShapeEdge->child()->usage() == DataUsage::Output) {
-                allocator.freeData(data);
-                break;
+        if (const auto& parentEdge = data->parentDataToShapeEdge()) {
+            const auto& parent = parentEdge->parent();
+            if (parent->usage() == DataUsage::Intermediate && (!onlyCheckCMX || parent->memReqs() == MemoryType::CMX)) {
+                allocator.freeData(parent);
             }
         }
     }