}
}
+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) {
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());
// 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;
}
// 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);
}
}
}