Find the handle factory for the input layer which results in fewest required copies.
| 1529 | |
| 1530 | // Find the handle factory for the input layer which results in fewest required copies. |
| 1531 | ITensorHandleFactory::FactoryId CalculateSlotOptionForInput(BackendsMap& backends, |
| 1532 | OutputSlot& slot, |
| 1533 | TensorHandleFactoryRegistry& registry, |
| 1534 | bool importEnabled) |
| 1535 | { |
| 1536 | Layer& layer = slot.GetOwningLayer(); |
| 1537 | |
| 1538 | if (layer.GetType() != LayerType::Input) |
| 1539 | { |
| 1540 | throw armnn::Exception("layer must be of type \"Input\"."); |
| 1541 | } |
| 1542 | |
| 1543 | // Explicitly select the tensorhandle factory for InputLayer because the rules for it are slightly different. It |
| 1544 | // doesn't matter which backend it is assigned to because they all use the same implementation, which |
| 1545 | // requires Map/Unmap support. This means that, so long as the handle type supports map/unmap semantics, we can |
| 1546 | // select a factory with maximum compatibility with the layers connected to the InputLayer. |
| 1547 | |
| 1548 | // First ensure the from backends can support the TensorHandeAPI |
| 1549 | auto frmBackend = backends.find(layer.GetBackendId()); |
| 1550 | if (frmBackend == backends.end() || |
| 1551 | !frmBackend->second->SupportsTensorAllocatorAPI()) |
| 1552 | { |
| 1553 | return ITensorHandleFactory::LegacyFactoryId; |
| 1554 | } |
| 1555 | |
| 1556 | // Go through all connections to the output slot and determine the TensorHandleFactory which results in the |
| 1557 | // fewest copies. |
| 1558 | std::map<ITensorHandleFactory::FactoryId, int> factoryScores; |
| 1559 | int topScore = 0; |
| 1560 | ITensorHandleFactory::FactoryId topChoice = ITensorHandleFactory::LegacyFactoryId; |
| 1561 | |
| 1562 | for (auto&& connection : slot.GetConnections()) |
| 1563 | { |
| 1564 | |
| 1565 | const Layer& connectedLayer = connection->GetOwningLayer(); |
| 1566 | |
| 1567 | auto toBackend = backends.find(connectedLayer.GetBackendId()); |
| 1568 | if (toBackend == backends.end()) |
| 1569 | { |
| 1570 | throw armnn::Exception("Backend id not found for the connected layer"); |
| 1571 | } |
| 1572 | |
| 1573 | if (!toBackend->second.get()->SupportsTensorAllocatorAPI()) |
| 1574 | { |
| 1575 | // The destination backend does not support the tensor allocator API, move to the next one |
| 1576 | continue; |
| 1577 | } |
| 1578 | |
| 1579 | auto dstPrefs = toBackend->second.get()->GetHandleFactoryPreferences(); |
| 1580 | for (auto&& dst : dstPrefs) |
| 1581 | { |
| 1582 | // Input layers use the mem copy workload or import, so the selected factory must |
| 1583 | // support either the map/unmap API or Import API |
| 1584 | ITensorHandleFactory* factory = registry.GetFactory(dst); |
| 1585 | if (importEnabled && factory->GetImportFlags() == 0) |
| 1586 | { |
| 1587 | continue; |
| 1588 | } |
no test coverage detected