From 7909c53e3b91f96a12f2d587741575d4d1becdce Mon Sep 17 00:00:00 2001 From: Francis Murtagh Date: Thu, 28 Jan 2021 14:25:15 +0000 Subject: IVGCVSW-4874 Provide LayerSupportHandle to frontend users * Add test for new IsBackendRegistered member function of Handle * Move deprecated messages to new frontend API of LayerSupportHandle * Update delegate to use dot operator for IsXXXLayerSupported Signed-off-by: Francis Murtagh Change-Id: I70d7166e207a10e4b3583a827ca0dda2169bcba1 !android-nn-driver:4940 --- include/armnn/BackendHelper.hpp | 412 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 410 insertions(+), 2 deletions(-) (limited to 'include/armnn/BackendHelper.hpp') diff --git a/include/armnn/BackendHelper.hpp b/include/armnn/BackendHelper.hpp index 6a6c8b9c15..3d0632da5e 100644 --- a/include/armnn/BackendHelper.hpp +++ b/include/armnn/BackendHelper.hpp @@ -11,7 +11,415 @@ namespace armnn { -/// Convenience function to retrieve the ILayerSupport for a backend -std::shared_ptr GetILayerSupportByBackendId(const armnn::BackendId& backend); +// This handle calls its own IsXXXLayerSupported() functions which then call the polymorphic +// ILayerSupport::IsXXXLayerSupported() at the framework level so there is no risk of VTable misalignment. +// This is to make ILayerSupport in its abstract form a solely Backend interface alongside a +// separate ABI stable frontend class free of virtual functions via an added layer of indirection. +class LayerSupportHandle +{ +public: + explicit LayerSupportHandle(std::shared_ptr layerSupport) + : m_LayerSupport(std::move(layerSupport)) {}; + + bool IsBackendRegistered() const; + + ARMNN_DEPRECATED_MSG("Use IsElementwiseUnarySupported instead") + bool IsAbsSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsActivationSupported(const TensorInfo& input, + const TensorInfo& output, + const ActivationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsAdditionSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsArgMinMaxSupported(const TensorInfo& input, + const TensorInfo& output, + const ArgMinMaxDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsBatchNormalizationSupported(const TensorInfo& input, + const TensorInfo& output, + const TensorInfo& mean, + const TensorInfo& var, + const TensorInfo& beta, + const TensorInfo& gamma, + const BatchNormalizationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsBatchToSpaceNdSupported(const TensorInfo& input, + const TensorInfo& output, + const BatchToSpaceNdDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsComparisonSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + const ComparisonDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConcatSupported(const std::vector inputs, + const TensorInfo& output, + const OriginsDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConstantSupported(const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConvertBf16ToFp32Supported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConvertFp32ToBf16Supported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConvertFp16ToFp32Supported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConvertFp32ToFp16Supported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsConvolution2dSupported(const TensorInfo& input, + const TensorInfo& output, + const Convolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional& biases, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDebugSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDepthToSpaceSupported(const TensorInfo& input, + const TensorInfo& output, + const DepthToSpaceDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDepthwiseConvolutionSupported( + const TensorInfo& input, + const TensorInfo& output, + const DepthwiseConvolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional& biases, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDequantizeSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDetectionPostProcessSupported(const TensorInfo& boxEncodings, + const TensorInfo& scores, + const TensorInfo& anchors, + const TensorInfo& detectionBoxes, + const TensorInfo& detectionClasses, + const TensorInfo& detectionScores, + const TensorInfo& numDetections, + const DetectionPostProcessDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDilatedDepthwiseConvolutionSupported( + const TensorInfo& input, + const TensorInfo& output, + const DepthwiseConvolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional& biases, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsDivisionSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsElementwiseUnarySupported(const TensorInfo& input, + const TensorInfo& output, + const ElementwiseUnaryDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsComparisonSupported instead") + bool IsEqualSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsFakeQuantizationSupported(const TensorInfo& input, + const FakeQuantizationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsFillSupported(const TensorInfo& input, + const TensorInfo& output, + const FillDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsFloorSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsFullyConnectedSupported(const TensorInfo& input, + const TensorInfo& output, + const TensorInfo& weights, + const TensorInfo& biases, + const FullyConnectedDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsGatherSupported with descriptor instead") + bool IsGatherSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsGatherSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + const GatherDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsComparisonSupported instead") + bool IsGreaterSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& ouput, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsInputSupported(const TensorInfo& input, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsInstanceNormalizationSupported( + const TensorInfo& input, + const TensorInfo& output, + const InstanceNormalizationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsL2NormalizationSupported(const TensorInfo& input, + const TensorInfo& output, + const L2NormalizationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsLogicalBinarySupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + const LogicalBinaryDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsLogicalUnarySupported(const TensorInfo& input, + const TensorInfo& output, + const ElementwiseUnaryDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsLogSoftmaxSupported(const TensorInfo& input, + const TensorInfo& output, + const LogSoftmaxDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsLstmSupported(const TensorInfo& input, + const TensorInfo& outputStateIn, + const TensorInfo& cellStateIn, + const TensorInfo& scratchBuffer, + const TensorInfo& outputStateOut, + const TensorInfo& cellStateOut, + const TensorInfo& output, + const LstmDescriptor& descriptor, + const LstmInputParamsInfo& paramsInfo, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMaximumSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMeanSupported(const TensorInfo& input, + const TensorInfo& output, + const MeanDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMemCopySupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMemImportSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMergeSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsConcatSupported instead") + bool IsMergerSupported(const std::vector inputs, + const TensorInfo& output, + const OriginsDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMinimumSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsMultiplicationSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsNormalizationSupported(const TensorInfo& input, + const TensorInfo& output, + const NormalizationDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsOutputSupported(const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsPadSupported(const TensorInfo& input, + const TensorInfo& output, + const PadDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsPermuteSupported(const TensorInfo& input, + const TensorInfo& output, + const PermuteDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsPooling2dSupported(const TensorInfo& input, + const TensorInfo& output, + const Pooling2dDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsPreCompiledSupported(const TensorInfo& input, + const PreCompiledDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsPreluSupported(const TensorInfo& input, + const TensorInfo& alpha, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsQuantizeSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsQLstmSupported(const TensorInfo& input, + const TensorInfo& previousOutputIn, + const TensorInfo& previousCellStateIn, + const TensorInfo& outputStateOut, + const TensorInfo& cellStateOut, + const TensorInfo& output, + const QLstmDescriptor& descriptor, + const LstmInputParamsInfo& paramsInfo, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsQuantizedLstmSupported(const TensorInfo& input, + const TensorInfo& previousCellStateIn, + const TensorInfo& previousOutputIn, + const TensorInfo& cellStateOut, + const TensorInfo& output, + const QuantizedLstmInputParamsInfo& paramsInfo, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsRankSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsReshapeSupported(const TensorInfo& input, + const TensorInfo& output, + const ReshapeDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsResizeSupported instead") + bool IsResizeBilinearSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsResizeSupported(const TensorInfo& input, + const TensorInfo& output, + const ResizeDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsElementwiseUnarySupported instead") + bool IsRsqrtSupported(const TensorInfo& input, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSliceSupported(const TensorInfo& input, + const TensorInfo& output, + const SliceDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSoftmaxSupported(const TensorInfo& input, + const TensorInfo& output, + const SoftmaxDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSpaceToBatchNdSupported(const TensorInfo& input, + const TensorInfo& output, + const SpaceToBatchNdDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSpaceToDepthSupported(const TensorInfo& input, + const TensorInfo& output, + const SpaceToDepthDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + ARMNN_DEPRECATED_MSG("Use IsSplitterSupported with outputs instead") + bool IsSplitterSupported(const TensorInfo& input, + const ViewsDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSplitterSupported(const TensorInfo& input, + const std::vector>& outputs, + const ViewsDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsStackSupported(const std::vector& inputs, + const TensorInfo& output, + const StackDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsStandInSupported(const std::vector& inputs, + const std::vector& outputs, + const StandInDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + + bool IsStridedSliceSupported(const TensorInfo& input, + const TensorInfo& output, + const StridedSliceDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSubtractionSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsSwitchSupported(const TensorInfo& input0, + const TensorInfo& input1, + const TensorInfo& output0, + const TensorInfo& output1, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsTransposeConvolution2dSupported( + const TensorInfo& input, + const TensorInfo& output, + const TransposeConvolution2dDescriptor& descriptor, + const TensorInfo& weights, + const Optional& biases, + Optional reasonIfUnsupported = EmptyOptional()); + + bool IsTransposeSupported(const TensorInfo& input, + const TensorInfo& output, + const TransposeDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()); + +private: + std::shared_ptr m_LayerSupport; +}; + +/// Convenience function to retrieve the ILayerSupportHandle for a backend +LayerSupportHandle GetILayerSupportByBackendId(const armnn::BackendId& backend); } -- cgit v1.2.1