// // Copyright © 2017 Arm Ltd. All rights reserved. // SPDX-License-Identifier: MIT // #include "NeonTensorHandleFactory.hpp" #include "NeonTensorHandle.hpp" #include "Layer.hpp" #include #include namespace armnn { using FactoryId = ITensorHandleFactory::FactoryId; std::unique_ptr NeonTensorHandleFactory::CreateSubTensorHandle(ITensorHandle& parent, const TensorShape& subTensorShape, const unsigned int* subTensorOrigin) const { const arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape); arm_compute::Coordinates coords; coords.set_num_dimensions(subTensorShape.GetNumDimensions()); for (unsigned int i = 0; i < subTensorShape.GetNumDimensions(); ++i) { // Arm compute indexes tensor coords in reverse order. unsigned int revertedIndex = subTensorShape.GetNumDimensions() - i - 1; coords.set(i, boost::numeric_cast(subTensorOrigin[revertedIndex])); } const arm_compute::TensorShape parentShape = armcomputetensorutils::BuildArmComputeTensorShape(parent.GetShape()); if (!::arm_compute::error_on_invalid_subtensor(__func__, __FILE__, __LINE__, parentShape, coords, shape)) { return nullptr; } return std::make_unique( PolymorphicDowncast(&parent), shape, coords); } std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const { return NeonTensorHandleFactory::CreateTensorHandle(tensorInfo, true); } std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo, DataLayout dataLayout) const { return NeonTensorHandleFactory::CreateTensorHandle(tensorInfo, dataLayout, true); } std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo, const bool IsMemoryManaged) const { auto tensorHandle = std::make_unique(tensorInfo); if (IsMemoryManaged) { tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup()); } // If we are not Managing the Memory then we must be importing tensorHandle->SetImportEnabledFlag(!IsMemoryManaged); tensorHandle->SetImportFlags(GetImportFlags()); return tensorHandle; } std::unique_ptr NeonTensorHandleFactory::CreateTensorHandle(const TensorInfo& tensorInfo, DataLayout dataLayout, const bool IsMemoryManaged) const { auto tensorHandle = std::make_unique(tensorInfo, dataLayout); if (IsMemoryManaged) { tensorHandle->SetMemoryGroup(m_MemoryManager->GetInterLayerMemoryGroup()); } // If we are not Managing the Memory then we must be importing tensorHandle->SetImportEnabledFlag(!IsMemoryManaged); tensorHandle->SetImportFlags(GetImportFlags()); return tensorHandle; } const FactoryId& NeonTensorHandleFactory::GetIdStatic() { static const FactoryId s_Id(NeonTensorHandleFactoryId()); return s_Id; } const FactoryId& NeonTensorHandleFactory::GetId() const { return GetIdStatic(); } bool NeonTensorHandleFactory::SupportsSubTensors() const { return true; } MemorySourceFlags NeonTensorHandleFactory::GetExportFlags() const { return 0; } MemorySourceFlags NeonTensorHandleFactory::GetImportFlags() const { return 0; } std::vector NeonTensorHandleFactory::GetCapabilities(const IConnectableLayer* layer, const IConnectableLayer* connectedLayer, CapabilityClass capabilityClass) { IgnoreUnused(connectedLayer); std::vector capabilities; if (capabilityClass == CapabilityClass::PaddingRequired) { auto search = paddingRequiredLayers.find((PolymorphicDowncast(layer))->GetType()); if ( search != paddingRequiredLayers.end()) { Capability paddingCapability(CapabilityClass::PaddingRequired, true); capabilities.push_back(paddingCapability); } } return capabilities; } } // namespace armnn