// // Copyright © 2017 Arm Ltd. All rights reserved. // See LICENSE file in the project root for full license information. // #include "ClWorkloadFactory.hpp" #include "armnn/Exceptions.hpp" #include "armnn/Utils.hpp" #include #include "CpuTensorHandle.hpp" #include "Layer.hpp" #ifdef ARMCOMPUTECL_ENABLED #include #include #include #include "backends/MemCopyWorkload.hpp" #include "backends/ClTensorHandle.hpp" #include "ClWorkloads.hpp" #endif #include "MakeWorkloadHelper.hpp" #include #include #include namespace armnn { bool ClWorkloadFactory::IsLayerSupported(const Layer& layer, DataType dataType, std::string& outReasonIfUnsupported) { return IWorkloadFactory::IsLayerSupported(Compute::GpuAcc, layer, dataType, outReasonIfUnsupported); } #ifdef ARMCOMPUTECL_ENABLED ClWorkloadFactory::ClWorkloadFactory() : m_MemoryManager(std::make_unique()) { } std::unique_ptr ClWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const { return std::make_unique(tensorInfo); } std::unique_ptr ClWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent, TensorShape const& subTensorShape, unsigned int const* subTensorOrigin) const { BOOST_ASSERT(parent.GetType() == ITensorHandle::CL); arm_compute::Coordinates coords; arm_compute::TensorShape shape = armcomputetensorutils::BuildArmComputeTensorShape(subTensorShape); 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])); } return std::make_unique(static_cast(parent).GetTensor(), shape, coords); } std::unique_ptr ClWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info, m_MemoryManager.Get()); } std::unique_ptr ClWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateFullyConnected( const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info, m_MemoryManager.Get()); } std::unique_ptr ClWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info, m_MemoryManager.Get()); } std::unique_ptr ClWorkloadFactory::CreateDepthwiseConvolution2d( const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateMultiplication( const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateBatchNormalization( const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor, const WorkloadInfo& info) const { if (descriptor.m_Inputs.empty() || !descriptor.m_Inputs[0]) { throw InvalidArgumentException("ClWorkloadFactory: Invalid null input for MemCopy workload"); } // Create a workload that will copy tensor data from the inputs, which can have a number of different formats, // to CL tensors. switch (descriptor.m_Inputs[0]->GetType()) { case ITensorHandle::Cpu: return MakeWorkload(descriptor, info); #if ARMCOMPUTENEON_ENABLED case ITensorHandle::Neon: { return MakeWorkload(descriptor, info); } #endif default: throw InvalidArgumentException("ClWorkloadFactory: Destination type not supported for MemCopy Workload."); } } std::unique_ptr ClWorkloadFactory::CreateResizeBilinear( const ResizeBilinearQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateFakeQuantization( const FakeQuantizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } std::unique_ptr ClWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { return MakeWorkload(descriptor, info); } void ClWorkloadFactory::Finalize() { m_MemoryManager.Finalize(); } #else // #if ARMCOMPUTECL_ENABLED ClWorkloadFactory::ClWorkloadFactory() { } std::unique_ptr ClWorkloadFactory::CreateTensorHandle(const TensorInfo& tensorInfo) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateSubTensorHandle(ITensorHandle& parent, TensorShape const& subTensorShape, unsigned int const* subTensorOrigin) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateInput(const InputQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateOutput(const OutputQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateActivation(const ActivationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateSoftmax(const SoftmaxQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateSplitter(const SplitterQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateMerger(const MergerQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateFullyConnected(const FullyConnectedQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreatePermute(const PermuteQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreatePooling2d(const Pooling2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateDepthwiseConvolution2d( const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateNormalization(const NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateAddition(const AdditionQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateMultiplication(const MultiplicationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateBatchNormalization( const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateMemCopy(const MemCopyQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateResizeBilinear(const ResizeBilinearQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateFakeQuantization(const FakeQuantizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateL2Normalization(const L2NormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateConstant(const ConstantQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateReshape(const ReshapeQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } std::unique_ptr ClWorkloadFactory::CreateFloor(const FloorQueueDescriptor& descriptor, const WorkloadInfo& info) const { return nullptr; } void ClWorkloadFactory::Finalize() { } #endif // #if ARMCOMPUTECL_ENABLED } // namespace armnn