pax_global_header00006660000000000000000000000064144677224120014523gustar00rootroot0000000000000052 comment=ef0f3e7ac2d49d5eb36adb45c12b3b64fb8dd46f armnn-23.08/000077500000000000000000000000001446772241200126525ustar00rootroot00000000000000armnn-23.08/Android.bp000066400000000000000000000003001446772241200145460ustar00rootroot00000000000000// // Copyright © 2017 ARM Ltd. All rights reserved. // SPDX-License-Identifier: MIT // // Dummy Android.bp file to keep backward compatibility with previous // build systems/environments. armnn-23.08/Android.mk000066400000000000000000000545551446772241200146010ustar00rootroot00000000000000# # Copyright © 2017-2023 ARM Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # LOCAL_PATH := $(call my-dir) ARMNN_ANDROID_MK_ENABLED := 1 ifeq ($(ARMNN_ANDROID_MK_ENABLE),0) ARMNN_ANDROID_MK_ENABLED := 0 endif ifeq ($(ARMNN_ANDROID_MK_ENABLED),1) # Configure these paths if you move the source or Khronos headers ARMNN_GENERATED_HEADER_PATH := $(LOCAL_PATH)/generated OPENCL_HEADER_PATH := $(LOCAL_PATH)/../clframework/include NN_HEADER_PATH := $(LOCAL_PATH)/../../../../frameworks/ml/nn/runtime/include ARMNN_HEADER_PATH := $(LOCAL_PATH)/include ARMNN_PROFILING_INCLUDE_PATH := $(LOCAL_PATH)/profiling ARMNN_PROFILING_CLIENT_INCLUDE_PATH := $(LOCAL_PATH)/profiling/client/include ARMNN_PROFILING_COMMON_INCLUDE_PATH := $(LOCAL_PATH)/profiling/common/include ARMNN_TIMELINE_DECODER_INCLUDE_PATH := $(LOCAL_PATH)/src/timelineDecoder ARMNN_THIRD_PARTY_INCLUDE_PATH := $(LOCAL_PATH)/third-party ARMNN_MAIN_HEADER_PATH := $(LOCAL_PATH)/src ARMNN_SOURCE_HEADER_PATH := $(LOCAL_PATH)/src/armnn ARMNN_SOURCE_UTILS_HEADER_PATH := $(LOCAL_PATH)/src/armnnUtils ARMNN_TEST_UTILS_SOURCE_PATH := $(LOCAL_PATH)/src/armnnTestUtils ARMNN_BACKENDS_HEADER_PATH := $(LOCAL_PATH)/src/backends ARMNN_PROFILING_HEADER_PATH := $(LOCAL_PATH)/src/profiling ARMNN_SERIALIZER_HEADER_PATH := $(LOCAL_PATH)/src/armnnSerializer ARMNN_DESERIALIZER_HEADER_PATH := $(LOCAL_PATH)/src/armnnDeserializer # find the common.mk and backend.mk files in the backend source folders ARMNN_BACKEND_COMMON_MAKEFILE_LOCAL_PATHS := $(wildcard $(LOCAL_PATH)/src/backends/*/common.mk) ARMNN_BACKEND_COMMON_MAKEFILE_PATHS := $(subst $(LOCAL_PATH),,$(ARMNN_BACKEND_COMMON_MAKEFILE_LOCAL_PATHS)) ARMNN_BACKEND_COMMON_MAKEFILE_DIRS := $(subst /common.mk,,$(ARMNN_BACKEND_COMMON_MAKEFILE_PATHS)) ARMNN_BACKEND_MAKEFILE_LOCAL_PATHS := $(wildcard $(LOCAL_PATH)/src/backends/*/backend.mk) ARMNN_BACKEND_MAKEFILE_PATHS := $(subst $(LOCAL_PATH),,$(ARMNN_BACKEND_MAKEFILE_LOCAL_PATHS)) ARMNN_BACKEND_MAKEFILE_DIRS := $(subst /backend.mk,,$(ARMNN_BACKEND_MAKEFILE_PATHS)) ############## # libarmnn.a # ############## include $(CLEAR_VARS) LOCAL_MODULE := libarmnn ifeq ($(Q_OR_LATER),1) # "eng" is deprecated in Android Q LOCAL_MODULE_TAGS := optional else LOCAL_MODULE_TAGS := eng optional endif LOCAL_ARM_MODE := arm LOCAL_PROPRIETARY_MODULE := true # Placeholder to hold all backend source files and include paths, common and specific to the backends ARMNN_BACKEND_SOURCES := ARMNN_BACKEND_INCLUDES := # # Iterate through the backend common and specific include paths, include them into the # current makefile and append the sources held by the COMMON_SOURCES and BACKEND_SOURCES variable # (included from the given makefile) to the ARMNN_BACKEND_SOURCES list # and optional include paths set by BACKEND_INCLUDES to the ARMNN_BACKEND_INCLUDES list # $(foreach mkPath,$(ARMNN_BACKEND_COMMON_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/common.mk)\ $(eval ARMNN_BACKEND_SOURCES := $(ARMNN_BACKEND_SOURCES)\ $(patsubst %,$(mkPath)/%,$(COMMON_SOURCES)))) $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk)\ $(eval ARMNN_BACKEND_SOURCES := $(ARMNN_BACKEND_SOURCES)\ $(patsubst %,$(mkPath)/%,$(BACKEND_SOURCES)))) $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk)\ $(eval ARMNN_BACKEND_INCLUDES += $(BACKEND_INCLUDES))) # Mark source files as dependent on Android.mk and backend makefiles LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk \ $(ARMNN_BACKEND_MAKEFILE_LOCAL_PATHS) LOCAL_EXPORT_C_INCLUDES := \ $(ARMNN_PROFILING_INCLUDE_PATH) \ $(ARMNN_PROFILING_COMMON_INCLUDE_PATH) \ $(ARMNN_PROFILING_CLIENT_INCLUDE_PATH) \ $(ARMNN_MAIN_HEADER_PATH) \ $(ARMNN_SOURCE_HEADER_PATH) \ $(ARMNN_TIMELINE_DECODER_INCLUDE_PATH) \ $(ARMNN_THIRD_PARTY_INCLUDE_PATH) \ $(ARMNN_SOURCE_UTILS_HEADER_PATH) \ $(ARMNN_PROFILING_HEADER_PATH) \ $(ARMNN_BACKENDS_HEADER_PATH) \ $(ARMNN_SERIALIZER_HEADER_PATH) \ $(ARMNN_DESERIALIZER_HEADER_PATH) LOCAL_C_INCLUDES := \ $(OPENCL_HEADER_PATH) \ $(NN_HEADER_PATH) \ $(ARMNN_GENERATED_HEADER_PATH) \ $(ARMNN_PROFILING_INCLUDE_PATH) \ $(ARMNN_PROFILING_COMMON_INCLUDE_PATH) \ $(ARMNN_PROFILING_CLIENT_INCLUDE_PATH) \ $(ARMNN_HEADER_PATH) \ $(ARMNN_TIMELINE_DECODER_INCLUDE_PATH) \ $(ARMNN_THIRD_PARTY_INCLUDE_PATH) \ $(ARMNN_MAIN_HEADER_PATH) \ $(ARMNN_SOURCE_HEADER_PATH) \ $(ARMNN_SOURCE_UTILS_HEADER_PATH) \ $(ARMNN_PROFILING_HEADER_PATH) \ $(ARMNN_BACKENDS_HEADER_PATH) \ $(ARMNN_SERIALIZER_HEADER_PATH) \ $(ARMNN_DESERIALIZER_HEADER_PATH) \ $(ARMNN_BACKEND_INCLUDES) LOCAL_SRC_FILES := \ $(ARMNN_BACKEND_SOURCES) \ profiling/common/src/CommandHandlerFunctor.cpp \ profiling/common/src/CommandHandlerKey.cpp \ profiling/common/src/CommandHandlerRegistry.cpp \ profiling/common/src/CommonProfilingUtils.cpp \ profiling/common/src/CounterDirectory.cpp \ profiling/common/src/LabelsAndEventClasses.cpp \ profiling/common/src/Logging.cpp \ profiling/common/src/NetworkSockets.cpp \ profiling/common/src/PacketVersionResolver.cpp \ profiling/common/src/Processes.cpp \ profiling/common/src/SwTrace.cpp \ profiling/common/src/Threads.cpp \ profiling/client/src/ActivateTimelineReportingCommandHandler.cpp \ profiling/client/src/BufferManager.cpp \ profiling/client/src/CommandHandler.cpp \ profiling/client/src/ConnectionAcknowledgedCommandHandler.cpp \ profiling/client/src/CounterIdMap.cpp \ profiling/client/src/DeactivateTimelineReportingCommandHandler.cpp \ profiling/client/src/FileOnlyProfilingConnection.cpp \ profiling/client/src/Holder.cpp \ profiling/client/src/IProfilingService.cpp \ profiling/client/src/PacketBuffer.cpp \ profiling/client/src/PeriodicCounterCapture.cpp \ profiling/client/src/PeriodicCounterSelectionCommandHandler.cpp \ profiling/client/src/PerJobCounterSelectionCommandHandler.cpp \ profiling/client/src/ProfilingConnectionDumpToFileDecorator.cpp \ profiling/client/src/ProfilingConnectionFactory.cpp \ profiling/client/src/ProfilingService.cpp \ profiling/client/src/ProfilingStateMachine.cpp \ profiling/client/src/ProfilingUtils.cpp \ profiling/client/src/RegisterBackendCounters.cpp \ profiling/client/src/RequestCounterDirectoryCommandHandler.cpp \ profiling/client/src/SendCounterPacket.cpp \ profiling/client/src/SendThread.cpp \ profiling/client/src/SendTimelinePacket.cpp \ profiling/client/src/SocketProfilingConnection.cpp \ profiling/client/src/TimelinePacketWriterFactory.cpp \ profiling/client/src/TimelineUtilityMethods.cpp \ profiling/client/src/backends/BackendProfiling.cpp \ profiling/client/src/backends/IBackendProfiling.cpp \ profiling/server/src/timelineDecoder/DirectoryCaptureCommandHandler.cpp \ profiling/server/src/timelineDecoder/TimelineCaptureCommandHandler.cpp \ profiling/server/src/timelineDecoder/TimelineDecoder.cpp \ profiling/server/src/timelineDecoder/TimelineDirectoryCaptureCommandHandler.cpp \ src/armnn/ArmNNProfilingServiceInitialiser.cpp \ src/armnn/BackendHelper.cpp \ src/armnn/BackendRegistry.cpp \ src/armnn/Descriptors.cpp \ src/armnn/Exceptions.cpp \ src/armnn/Graph.cpp \ src/armnn/ILayerSupport.cpp \ src/armnn/InternalTypes.cpp \ src/armnn/JsonPrinter.cpp \ src/armnn/Layer.cpp \ src/armnn/LoadedNetwork.cpp \ src/armnn/Logging.cpp \ src/armnn/Network.cpp \ src/armnn/NetworkUtils.cpp \ src/armnn/Observable.cpp \ src/armnn/Optimizer.cpp \ src/armnn/OutputHandler.cpp \ src/armnn/ProfilingEvent.cpp \ src/armnn/Profiling.cpp \ src/armnn/Runtime.cpp \ src/armnn/SerializeLayerParameters.cpp \ src/armnn/SubgraphView.cpp \ src/armnn/SubgraphViewSelector.cpp \ src/armnn/Tensor.cpp \ src/armnn/Threadpool.cpp \ src/armnn/TypesUtils.cpp \ src/armnn/Utils.cpp \ src/armnn/WallClockTimer.cpp \ src/armnn/WorkingMemHandle.cpp \ src/armnnUtils/CompatibleTypes.cpp \ src/armnnUtils/DataLayoutIndexed.cpp \ src/armnnUtils/DotSerializer.cpp \ src/armnnUtils/FloatingPointConverter.cpp \ src/armnnUtils/HeapProfiling.cpp \ src/armnnUtils/LeakChecking.cpp \ src/armnnUtils/ParserHelper.cpp \ src/armnnUtils/Permute.cpp \ src/armnnUtils/TensorUtils.cpp \ src/armnnUtils/VerificationHelpers.cpp \ src/armnnUtils/Filesystem.cpp \ src/armnnUtils/ProfilingOptionsConverter.cpp \ src/armnnUtils/Transpose.cpp \ src/armnn/layers/ActivationLayer.cpp \ src/armnn/layers/AdditionLayer.cpp \ src/armnn/layers/ArgMinMaxLayer.cpp \ src/armnn/layers/BatchMatMulLayer.cpp \ src/armnn/layers/BatchNormalizationLayer.cpp \ src/armnn/layers/BatchToSpaceNdLayer.cpp \ src/armnn/layers/CastLayer.cpp \ src/armnn/layers/ChannelShuffleLayer.cpp \ src/armnn/layers/ComparisonLayer.cpp \ src/armnn/layers/ConcatLayer.cpp \ src/armnn/layers/ConstantLayer.cpp \ src/armnn/layers/Convolution2dLayer.cpp \ src/armnn/layers/Convolution3dLayer.cpp \ src/armnn/layers/ConvertFp16ToFp32Layer.cpp \ src/armnn/layers/ConvertFp32ToFp16Layer.cpp \ src/armnn/layers/DebugLayer.cpp \ src/armnn/layers/DepthToSpaceLayer.cpp \ src/armnn/layers/DepthwiseConvolution2dLayer.cpp \ src/armnn/layers/DequantizeLayer.cpp \ src/armnn/layers/DetectionPostProcessLayer.cpp \ src/armnn/layers/DivisionLayer.cpp \ src/armnn/layers/ElementwiseBaseLayer.cpp \ src/armnn/layers/ElementwiseBinaryLayer.cpp \ src/armnn/layers/ElementwiseUnaryLayer.cpp \ src/armnn/layers/FakeQuantizationLayer.cpp \ src/armnn/layers/FillLayer.cpp \ src/armnn/layers/FloorLayer.cpp \ src/armnn/layers/FullyConnectedLayer.cpp \ src/armnn/layers/GatherLayer.cpp \ src/armnn/layers/GatherNdLayer.cpp \ src/armnn/layers/InputLayer.cpp \ src/armnn/layers/InstanceNormalizationLayer.cpp \ src/armnn/layers/L2NormalizationLayer.cpp \ src/armnn/layers/LogicalBinaryLayer.cpp \ src/armnn/layers/LogSoftmaxLayer.cpp \ src/armnn/layers/LstmLayer.cpp \ src/armnn/layers/MapLayer.cpp \ src/armnn/layers/MaximumLayer.cpp \ src/armnn/layers/MeanLayer.cpp \ src/armnn/layers/MemCopyLayer.cpp \ src/armnn/layers/MemImportLayer.cpp \ src/armnn/layers/MergeLayer.cpp \ src/armnn/layers/MinimumLayer.cpp \ src/armnn/layers/MultiplicationLayer.cpp \ src/armnn/layers/NormalizationLayer.cpp \ src/armnn/layers/OutputLayer.cpp \ src/armnn/layers/PadLayer.cpp \ src/armnn/layers/PermuteLayer.cpp \ src/armnn/layers/Pooling2dLayer.cpp \ src/armnn/layers/Pooling3dLayer.cpp \ src/armnn/layers/PreCompiledLayer.cpp \ src/armnn/layers/PreluLayer.cpp \ src/armnn/layers/QLstmLayer.cpp \ src/armnn/layers/QuantizeLayer.cpp \ src/armnn/layers/QuantizedLstmLayer.cpp \ src/armnn/layers/RankLayer.cpp \ src/armnn/layers/ReduceLayer.cpp \ src/armnn/layers/ReshapeLayer.cpp \ src/armnn/layers/ResizeLayer.cpp \ src/armnn/layers/ReverseV2Layer.cpp \ src/armnn/layers/ShapeLayer.cpp \ src/armnn/layers/SliceLayer.cpp \ src/armnn/layers/SoftmaxLayer.cpp \ src/armnn/layers/SpaceToBatchNdLayer.cpp \ src/armnn/layers/SpaceToDepthLayer.cpp \ src/armnn/layers/SplitterLayer.cpp \ src/armnn/layers/StackLayer.cpp \ src/armnn/layers/StandInLayer.cpp \ src/armnn/layers/StridedSliceLayer.cpp \ src/armnn/layers/SubtractionLayer.cpp \ src/armnn/layers/SwitchLayer.cpp \ src/armnn/layers/TileLayer.cpp \ src/armnn/layers/TransposeConvolution2dLayer.cpp \ src/armnn/layers/TransposeLayer.cpp \ src/armnn/layers/UnidirectionalSequenceLstmLayer.cpp \ src/armnn/layers/UnmapLayer.cpp \ src/armnnSerializer/Serializer.cpp \ src/armnnSerializer/SerializerUtils.cpp \ src/armnnDeserializer/Deserializer.cpp LOCAL_STATIC_LIBRARIES := \ libflatbuffers-framework \ arm_compute_library LOCAL_SHARED_LIBRARIES := \ liblog LOCAL_CFLAGS := \ -std=$(CPP_VERSION) \ -fexceptions \ -Wno-unused-parameter \ -frtti \ -DFMT_HEADER_ONLY LOCAL_LDFLAGS += \ -Wl,-Map=libarmnnMapFile.map # The variable to enable/disable the CL backend (ARMNN_COMPUTE_CL_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_COMPUTE_CL_ENABLED),1) LOCAL_CFLAGS += \ -DARMCOMPUTECL_ENABLED endif # ARMNN_COMPUTE_CL_ENABLED == 1 # The variable to enable/disable the NEON backend (ARMNN_COMPUTE_NEON_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_COMPUTE_NEON_ENABLED),1) LOCAL_CFLAGS += \ -DARMCOMPUTENEON_ENABLED endif # ARMNN_COMPUTE_NEON_ENABLED == 1 # The variable to enable/disable the REFERENCE backend (ARMNN_REF_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_REF_ENABLED),1) LOCAL_CFLAGS += \ -DARMNNREF_ENABLED endif # ARMNN_REF_ENABLED == 1 ifeq ($(Q_OR_LATER),1) LOCAL_CFLAGS += \ -DARMNN_MIXED_PRECISION_FP16_POOLING endif # PLATFORM_VERSION == Q or later include $(BUILD_STATIC_LIBRARY) ############### # armnn-tests # ############### include $(CLEAR_VARS) LOCAL_MODULE := armnn-tests ifeq ($(Q_OR_LATER),1) # "eng" is deprecated in Android Q LOCAL_MODULE_TAGS := optional else LOCAL_MODULE_TAGS := eng optional endif LOCAL_ARM_MODE := arm LOCAL_PROPRIETARY_MODULE := true # placeholder to hold all backend unit test source files ARMNN_BACKEND_TEST_SOURCES := ARMNN_BACKEND_TEST_INCLUDES := # # iterate through the backend common and specific include paths, include them into the current # makefile and append the sources held by the COMMON_TEST_SOURCES and BACKEND_TEST_SOURCES # (included from the given makefile) to the ARMNN_BACKEND_TEST_SOURCES list # $(foreach mkPath,$(ARMNN_BACKEND_COMMON_MAKEFILE_DIRS), \ $(eval include $(LOCAL_PATH)/$(mkPath)/common.mk) \ $(eval ARMNN_BACKEND_TEST_SOURCES := $(ARMNN_BACKEND_TEST_SOURCES) \ $(patsubst %,$(mkPath)/%,$(COMMON_TEST_SOURCES)))) $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS), \ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk) \ $(eval ARMNN_BACKEND_TEST_SOURCES := $(ARMNN_BACKEND_TEST_SOURCES) \ $(patsubst %,$(mkPath)/%,$(BACKEND_TEST_SOURCES)))) $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk)\ $(eval ARMNN_BACKEND_TEST_INCLUDES += $(BACKEND_TEST_INCLUDES))) # Placeholder to hold all backend link files. ARMNN_BACKEND_TEST_STATIC_LIBRARIES := ARMNN_BACKEND_TEST_SHARED_LIBRARIES := # Iterate through the Arm NN backends and specific include paths, include them into the # current makefile and append the linkfiles held by # the optional BACKEND_STATIC_LIBRARIES and optional BACKEND_SHARED_LIBRARIES variable # (included from the given makefile) to # the ARMNN_BACKEND_STATIC_LIBRARIES and ARMNN_BACKEND_SHARED_LIBRARIES lists $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk)\ $(eval ARMNN_BACKEND_TEST_STATIC_LIBRARIES += $(BACKEND_TEST_STATIC_LIBRARIES))) $(foreach mkPath,$(ARMNN_BACKEND_MAKEFILE_DIRS),\ $(eval include $(LOCAL_PATH)/$(mkPath)/backend.mk)\ $(eval ARMNN_BACKEND_TEST_SHARED_LIBRARIES += $(BACKEND_TEST_SHARED_LIBRARIES))) # Mark source files as dependent on Android.mk LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_C_INCLUDES := \ $(OPENCL_HEADER_PATH) \ $(NN_HEADER_PATH) \ $(ARMNN_GENERATED_HEADER_PATH) \ $(ARMNN_PROFILING_INCLUDE_PATH) \ $(ARMNN_PROFILING_COMMON_INCLUDE_PATH) \ $(ARMNN_PROFILING_CLIENT_INCLUDE_PATH) \ $(ARMNN_HEADER_PATH) \ $(ARMNN_TIMELINE_DECODER_INCLUDE_PATH) \ $(ARMNN_THIRD_PARTY_INCLUDE_PATH) \ $(ARMNN_MAIN_HEADER_PATH) \ $(ARMNN_SOURCE_HEADER_PATH) \ $(ARMNN_SOURCE_UTILS_HEADER_PATH) \ $(ARMNN_TEST_UTILS_SOURCE_PATH) \ $(ARMNN_PROFILING_HEADER_PATH) \ $(ARMNN_BACKENDS_HEADER_PATH) \ $(ARMNN_SERIALIZER_HEADER_PATH) \ $(ARMNN_DESERIALIZER_HEADER_PATH) \ $(ARMNN_BACKEND_INCLUDES) LOCAL_CFLAGS := \ -std=$(CPP_VERSION) \ -fexceptions \ -frtti \ # The variable to enable/disable the CL backend (ARMNN_COMPUTE_CL_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_COMPUTE_CL_ENABLED),1) LOCAL_CFLAGS += \ -DARMCOMPUTECL_ENABLED endif # ARMNN_COMPUTE_CL_ENABLED == 1 # The variable to enable/disable the NEON backend (ARMNN_COMPUTE_NEON_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_COMPUTE_NEON_ENABLED),1) LOCAL_CFLAGS += \ -DARMCOMPUTENEON_ENABLED endif # ARMNN_COMPUTE_NEON_ENABLED == 1 # The variable to enable/disable the REFERENCE backend (ARMNN_REF_ENABLED) is declared in android-nn-driver/Android.mk ifeq ($(ARMNN_REF_ENABLED),1) LOCAL_CFLAGS += \ -DARMNNREF_ENABLED endif # ARMNN_REF_ENABLED == 1 LOCAL_SRC_FILES := \ $(ARMNN_BACKEND_TEST_SOURCES) \ src/armnn/test/ConstTensorLayerVisitor.cpp \ src/armnn/test/EndToEndTest.cpp \ src/armnn/ExecutionFrame.cpp \ src/armnn/test/ExecutionFrameTest.cpp \ src/armnn/test/FloatingPointConverterTest.cpp \ src/armnn/test/FlowControl.cpp \ src/armnn/test/GraphTests.cpp \ src/armnn/test/InferOutputTests.cpp \ src/armnn/test/InstrumentTests.cpp \ src/armnn/test/LayerTests.cpp \ src/armnnUtils/ModelAccuracyChecker.cpp \ src/armnn/test/ModelAccuracyCheckerTest.cpp \ src/armnn/test/NetworkTests.cpp \ src/armnn/test/ObservableTest.cpp \ src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp \ src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp \ src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp \ src/armnn/test/optimizations/FuseActivationTests.cpp \ src/armnn/test/optimizations/InsertDebugLayerTests.cpp \ src/armnn/test/optimizations/MovePermuteUpTests.cpp \ src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp \ src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp \ src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp \ src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp \ src/armnn/test/optimizations/PermuteAsReshapeTests.cpp \ src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp \ src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp \ src/armnn/test/optimizations/TransposeAsReshapeTests.cpp \ src/armnn/test/OptimizerTests.cpp \ src/armnn/test/OptionalTest.cpp \ src/armnn/test/ProfilerTests.cpp \ src/armnn/test/ProfilingEventTest.cpp \ src/armnnUtils/PrototxtConversions.cpp \ src/armnnUtils/test/PrototxtConversionsTest.cpp \ src/armnn/test/SubgraphViewTests.cpp \ src/armnn/test/TensorHandleStrategyTest.cpp \ src/armnn/test/TensorTest.cpp \ src/armnn/test/TestInputOutputLayerVisitor.cpp \ src/armnn/test/TestLayerVisitor.cpp \ src/armnn/test/TestNameAndDescriptorLayerVisitor.cpp \ src/armnn/test/TestNameOnlyLayerVisitor.cpp \ src/armnn/test/UtilsTests.cpp \ src/armnnUtils/test/ParserHelperTest.cpp \ src/armnnUtils/test/QuantizeHelperTest.cpp \ src/armnnUtils/test/TensorUtilsTest.cpp \ src/armnnTestUtils/CommonTestUtils.cpp \ src/armnnTestUtils/GraphUtils.cpp \ src/armnnTestUtils/MockBackend.cpp \ src/armnnTestUtils/MockMemoryManager.cpp \ src/armnnTestUtils/MockTensorHandle.cpp \ src/armnnTestUtils/MockTensorHandleFactory.cpp \ src/armnnTestUtils/TensorCopyUtils.cpp \ src/armnnTestUtils/TestUtils.cpp \ src/armnnTestUtils/UnitTests.cpp \ src/profiling/test/BufferTests.cpp \ src/profiling/test/FileOnlyProfilingDecoratorTests.cpp \ src/profiling/test/PrintPacketHeaderHandler.cpp \ src/profiling/test/ProfilingConnectionDumpToFileDecoratorTests.cpp \ src/profiling/test/ProfilingGuidTest.cpp \ src/profiling/test/ProfilingTests.cpp \ src/profiling/test/ProfilingTestUtils.cpp \ src/profiling/test/SendCounterPacketTests.cpp \ src/profiling/test/SendTimelinePacketTests.cpp \ src/profiling/test/TestTimelinePacketHandler.cpp \ src/profiling/test/TimelineModel.cpp \ src/profiling/test/TimelinePacketTests.cpp \ src/profiling/test/TimelineUtilityMethodsTests.cpp \ src/armnnSerializer/test/ActivationSerializationTests.cpp \ src/armnnSerializer/test/ComparisonSerializationTests.cpp \ src/armnnSerializer/test/LstmSerializationTests.cpp \ src/armnnSerializer/test/SerializerTests.cpp \ src/armnnSerializer/test/SerializerTestUtils.cpp ifeq ($(ARMNN_REF_ENABLED),1) LOCAL_SRC_FILES += \ src/armnn/test/DebugCallbackTest.cpp \ src/armnn/test/RuntimeTests.cpp endif LOCAL_STATIC_LIBRARIES := \ libneuralnetworks_common \ libflatbuffers-framework \ arm_compute_library \ $(ARMNN_BACKEND_TEST_STATIC_LIBRARIES) LOCAL_WHOLE_STATIC_LIBRARIES := libarmnn LOCAL_SHARED_LIBRARIES := \ libbase \ libhidlbase \ libhidltransport \ libhidlmemory \ liblog \ libutils \ android.hardware.neuralnetworks@1.0 \ android.hidl.allocator@1.0 \ android.hidl.memory@1.0 \ $(ARMNN_BACKEND_TEST_SHARED_LIBRARIES) ifeq ($(ARMNN_INCLUDE_LIBOPENCL),1) LOCAL_SHARED_LIBRARIES += \ libOpenCL endif include $(BUILD_EXECUTABLE) endif # ARMNN_ENABLE armnn-23.08/Arm_NN_horizontal_blue.png000066400000000000000000000402341446772241200177550ustar00rootroot00000000000000PNG  IHDRwTd+ pHYsgRYiTXtXML:com.adobe.xmp v*9IDATxg!B1%mZQ_C =Zh C 5PL ^ Qbzz `lm~82^ֻ+)=ϝ{Gw==6050L^u$,xk5X y9\gj+R} Q50p4I`,pUe;"s \SJ)TzFrG$tlj`4qB̎$uG%x2pXTJ)T y|`f LIitykV\ |J)j@&w? 8Єٞun\iksORJ)TZ/ـ+-GW -[:7ļO\ļǧHw#+#-ɢZxPRJ)Ո|=QLnDNҪl`ш|XΏ!(<"468T`fJ)jP~;Y{ X8G=p 8Y25 $Z۵ǁ]qW 沁ˈy [qJ)2n;Hs.[f82u F^ r+ags*Ray>Ps1g:GJ\gH6v0b\gȽr]kiRٟl:f(RJ>;ϟXp=@j4.&Qi1Ǒ-1O5SJ)RN6kbE] ;,܍3=:-]G9OʵǺJ)JI^ ?1]Ed$il/p Y>`Ҹ[ o#J)Tnykcu]qtmi?++Z68RJ)&wK\,~Jq֏3;~Z)ܨRC)R@;Tf11g:tuz' "_*R)crz+ Z3ڴ[mkRJ:yLf۽8M+kK-5IoSB)RLLʏ?q|JtuZ,(AӟRJ) /V& ifx}ҵ+KC FĭRJ)CK׮K)M -(5X/80RJ)53z=<N>x]{@i84nRJkr&!Iwpw;^_M[ճ7?O$RJ)krVQC>`Q%2w^>6sIH|?k\DWJ)TܹǘLm {n_g8sWyc G5RJ)gr'0h<H3z㘗W^J)2:%!6<o7<=ޭqWUFS6_qMͯRJ)Z%BfF; U<췛t):f0RJ)iN;MArX 9יĹRJ)Յ~YPo "͟ ڄjF\&̩RJ)y[ %N]p5Ł9k> i_;Q%O1jrHo݅AH: iIQ\dVJ)T g8s`q\g|1Mw-b8/RJ,wϝ/l7udN[p3)ĢRJ7Ӏ $>pz'sD7*_ ajVRJ)|&wvFVeqo8fD+}r x(jBt@Xʪ`}K)K%N=d8\gbpd`i\Db.45 |BDy0`C5s;u%\ l=%ledHFfvWWpϛfd0ҹgA` L<<|؄xK 0<0i%ru LK=r-'sP,4BXZ)y,z`h`ωQM\XX9Un_ {mLjxς<9_uLi9P,MVGfH  E: Y{dOi?U >>Bbpu1ΞeiuJxq-4׮io?OBWA Œiɵ60m[cD$#v.uM4_:'(M79X`͸;)K?83.KZ<,J5btfE)4@_]I$&un|QQ L~1F)|bѲde\wH `i^<un< ip ?QhObHly7QpUX$@Z+ RO;mr0/&֮mHOAtTsX7PX?sZM/d<7^+K3?Vy#?h41뼄yG3kGeMS)JlԳ!PA7bƽѾJt@Bjց=_>wKd_>Fa }9u1j 'b^Qq"#mWOh6Z@\(V:BtlAĕF6Cj͂xxי~Z?ܘP\K<$2q9q1oMs֮ xRSLC΅fG0~|xꭿFjʩKP]Z _y @4I֩VѻJYUNM$^K)^[6dvI1SG?Vߘ##ZFK@>gz&.: 6,B>Z=ުN/KV+ $hɝ/00)(3u |qr)x@pɞaֆlq }}?ςZ8 |JcId*ҭ if :oWm* 7/4^A܈t/TVG&q"3ҷk ʪB]R9@L4IwNYTr>_v@ryYʷ Jl s!#BJuxI :!<adu &:ow{lѩFͣ.^:?W %z6K9ӳq)ub{ϿdV[1)cڐ"ǛW+廳Q#YH|PuP-kA<%v-T¿=np>ppM\=\ dkQ7:M\k\矸ΊHw!bnO`]{3YMs$3>\GLwi # _J,I1իiS25O<dB5rq<(^ʯ hn~? ¼F ;IX6~ljƓ̇:[F :7:IJX`H_]g*3?/i%\H~ 1Oqo޼k5ee$3;y՝b)m1C 9hfS#nOZ{#p3A͡$`c\Ǵfc}3  lA \e&ta;3-\["aؽ]r@,&pU+2zZb?CZߥR<'w.=x\ۗ/rjF`ŬC:N័GY?Y:sgsvcs97]뜕u)> |}{4{%q*yDHERr[M9=t\:ٯhRfN<( / UVKyr R/7g/a)ۑu%ۦQ9akeЦ̕/zg=}ΣI^ȽđVf LZ)_ *K{<߃77G@_@]As7b#oY3880: ܄Zf9Nw":C'pVdt&y6ω-S~̘`By-{M?Ij|u.P,m1ij:Cӏ\D*N:#⼖Y<meakl .0HNgvY,M²7vI$x0O&&|$ܒt9~DHYRgWZwn⪕k&[BلNHqQR~P,mC'Hrվ;|٨VC LuF ̞a>NY9h(:g7 u^u@GϳUfwA2m':$v3lTZ=8Dlsa|HJ!_j{So$ \gb"Rܸr`>zN)KLU+N =/5)t`}\=3h Zx⑽O;Dy> cHuVɝϗ(EXVWdmcw?;khݚJ=h<1wzA riJV\q&$uJy.?P,rHVA+)c桤n'q?[:񾹺9HiS&aK̗߯Fm):Wğ>C [pŠmk*NÑC y,WnJ"9_:}~x7(fViJT" |n^\(K9\VʷXVeiCVLܟP !mL$QfׇrWhNQ{bsk=$]wb, Θ Y6JʐwSY]W"}SWDV=5i./Ky횉ZFZn\e׆I<7IW[FQm8o~hX`fs3}ĶLWۺf[_""MLqqI%q3|dqO} j޿Huҏ*4Vww;`LV5ېr&F'Ԓfy 9)j"Fs`v"e>h{{CwLKiº Ҩa")đ]ܲ:ix!*RlK3JY~)'R'!ឭsiBdYߣT+3i@& Ӑ}difu386B 5gp}{} z<lk pᨼ;zMvnYl:~^7Yj%<6~ݿ݅biʯj| \)Չj4{,4poXߗ&xΥӬo>CO&5$(¸ޟh3c'&BϷY>V]8(PJVʏ"IKR9+ lGOJy"҂^MYGf=ۤRD3kxbxSB`i[?ap/E.8%ӟoD+M$d+rZ)?୊$-U>j44@qv!ڀ' xCz_Dc1[Z OcPMqgif@ŭS\A$̤еR*G_ nmB4 V3Dc5Mf`~Iy( U+sF~r8VeKBB¸l+0r ?abA؏ 9mDlqlD x,ȿTRkC ӎ'ϪSӔFjf`SVxC"M--jAGU%=R25}p#. \@s/C2qlRȡ;2 H|n`Ok%VR#p7{ߊdypd{ƝR=~lHѝ j|v!SR Ҧg{w.W.K׊#:/)P,rHVGLsQJt|Dx>(0d]Gu]x$-"+ny7UA4DhcFyyRMWPm9mH @f^ \1/3ows&6y`MV9wqlGrbTasjAzƵ%߼DKY݀lPJoc~lCVO?V4pvE <:X(4_\g!}dۗO8N=n鱭 h|ڞLkfuܪx_Wݝ>י_#^ieGa#O:x0ComMAV@"z? #!O_u&n6oo"l%q ¥h0cGb[%ŐH"-B. yBy?i駔R-Z)W R Izzbi#iIÒۀ/-^3H_SS|ZSN=>(ItF7/pP20Ykqxۺvs'dRJVO֒Y'Ϫj@qi=$u1t1o>A9}lA ᨩ_o>IamE)LU+Gܫ =kLFa ۊ~׶Kfgo6wV= ٯZ~ )ʝj|A; kr%i۪~G!{MD} ,j8f#Z}# y'Jv\=iW${E+:VʗdG+V#?:MzmEyI` 9 9jUrV7dJ'uzJTªhJMdo{ #w&[R#w%WH4Dy`M,3u8*)VʧHYER)57MQ[zmt8=Hg}UZRaީߵJ\R} X9%RQ$Y=HR~Igu/jRe)c)8dbQӹ۸Uio:O6q^Tq pqAjJ$Wĸ pT>j[a^4lk ? t(1uePE:#oyi|)srPwMշI84}'%H'ޣa}Bׯg?U+ibiov [j`XZ-^Gik{b[Qn 970o| u|qaπű)Sxjfno* \>?ϟ;?:/QJϟ iaV@YHy:\513uR)KRJirW_XD^RsAxXp5֟n55*}?\R(KU+mabi&we_ G ,m5`<a1?#ƶM+RJ)Dz.܏ԣ+TpXǥ"&0ۚ#pykTĶ>@V+XQTJ)Tca20{`gl+[eNJݸ u%QkY_)Rkra[o'ñHب hel롄cOiԬj ǠRJvܙ:/K<-ox9G _.4\q(RgyMF\eQ^ow\&%b&"5p|RJ^']4DJti0P*Qtnakƶ&mbRJ)e(nx}zM\ȷ#H+NNilN?_RJcrgG6ӟ]AE13$)?\RJ)δIɂI]jQ$a3MMikRJ:yL1>=\A8;0`iq<.MZADPJ)T>1[Z)@"TG׮Th \f0$nRJ_r'L6BΛR4^Z*QtUk&^H)u܉qvI<  `8$^4~# G78RJ)&w^Ah7s\!F1taL.p cM'фcPJ)T;=% 87كp)HQ$6cG_dkׂpn_󧱭K(RZ>;zxpvၱy[#= zՀc G^{nRJu+ɝ"˜3 C" #ݕN^y/lÑN)J]O"; hTn< ,aN2-m=<5'#FFN9>0N)Rҩ}Y;-e+] R@`|2)* ydql.IżtSV=nRJ^/ݬHybd$ GYb{l''jZ{ uYXga[żRJ) KYх'ձ2B>OD5 Kb[vL)j<U7'v*atb*&vJ)T?OdD;?;c[oelBJmibRZ#ŶbHӮYQsuzA(RMk$w%P¼j¶8I9kBcPJ)z(<_Mלt6ُ`^RJъPp"phf jKF4a/{0RJ)КtA0JWFLFǷ \'V\<49RJ)ՀN`*_+NnDλ[ l , c S)R1~r7$y; mE˻X_V`t I:NA9ҲrlSJ)TzNr^FC , ]0K*v!l륦ǚi*6,ҎmX$}55RJ)Հ·mH vIENDB`armnn-23.08/Arm_NN_horizontal_blue.png.license000066400000000000000000000001461446772241200213740ustar00rootroot00000000000000# # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/BuildGuideAndroidNDK.md000066400000000000000000000364441446772241200170620ustar00rootroot00000000000000# How to use the Android NDK to build Arm NN - [Introduction](#introduction) - [Initial Setup](#initial-setup) - [Download the Android NDK and make a standalone toolchain](#download-the-android-ndk-and-make-a-standalone-toolchain) - [Install Cmake](#install-cmake) - [Build Flatbuffers](#build-flatbuffers) - [Download Arm NN](#download-arm-nn) - [Get And Build TFLite](#get-and-build-tflite) - [Build Arm Compute Library](#build-arm-compute-library) - [Build Arm NN](#build-arm-nn) - [Build Standalone Sample Dynamic Backend](#build-standalone-sample-dynamic-backend) - [Run the Arm NN unit tests on an Android device](#run-the-arm-nn-unit-tests-on-an-android-device) ## Introduction These are step-by-step instructions for using the Android NDK to build Arm NN. They have been tested on a clean installation of Ubuntu 18.04 and 20.04, and should also work with other OS versions. The instructions show how to build the Arm NN core library and its dependencies. For ease of use there is a shell script version of this guide located in the scripts directory called [build_android_ndk_guide.sh](scripts/build_android_ndk_guide.sh). Run the script with a -h flag to see the command line parameters. The shell script version of this guide (build_android_ndk_guide.sh) also provides user the option to use the Arm NN and ComputeLibrary available in your BASE_DIR, instead of downloading a new version. BASE_DIR is path to the script file, which is armnn/scripts/. ## Initial Setup First, we need to specify the Android version and the directories you want to build Arm NN in and to install some applications required to build Arm NN and its dependencies. ```bash export ANDROID_API=30 export WORKING_DIR=$HOME/armnn-devenv export NDK_DIR=$WORKING_DIR/android-ndk-r25 export NDK_TOOLCHAIN_ROOT=$NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64 export PATH=$NDK_TOOLCHAIN_ROOT/bin/:$PATH ``` You may want to append the above export variables commands to your `~/.bashrc` (or `~/.bash_profile` in macOS). The ANDROID_API variable should be set to the Android API version number you are using. For example, "30" for Android R. The WORKING_DIR can be any directory you have write permissions to. ### Required Applications Git is required to obtain Arm NN. If this has not been already installed then install it using: ```bash sudo apt install git ``` Arm Compute Library requires SCons. If this has not been already installed then install it using: ```bash sudo apt install scons ``` CMake is required to build Arm NN and its dependencies. If this has not been already installed then install it using: ```bash sudo apt install cmake ``` ## Download the Android NDK and make a standalone toolchain Download the Android NDK from [the official website](https://developer.android.com/ndk/downloads/index.html): ```bash mkdir -p $WORKING_DIR cd $WORKING_DIR # For Mac OS, change the NDK download link accordingly. wget https://dl.google.com/android/repository/android-ndk-r25-linux.zip unzip android-ndk-r25-linux.zip ``` With Android NDK-25, you no longer need to use the make_standalone_toolchain script to create a toolchain for a specific version of Android. Android's current preference is for you to just specify the architecture and operating system while setting the compiler and just use the ndk directory. ## Install Cmake Cmake 3.19rc3 or later is required to build Arm NN. If you are using Ubuntu 20.04 the command given in [Initial Setup](#initial-setup) should install a usable version. If you're using Ubuntu 18.04 you may need to compile cmake yourself. ```bash cd $WORKING_DIR sudo apt-get install libssl-dev wget https://github.com/Kitware/CMake/releases/download/v3.19.0-rc3/cmake-3.19.0-rc3.tar.gz tar -zxvf cmake-3.19.0-rc3.tar.gz cd cmake-3.19.0-rc3 ./bootstrap --prefix=$WORKING_DIR/cmake/install make all install cd.. ``` ## Build Flatbuffers Download Flatbuffers: ```bash cd $WORKING_DIR wget https://github.com/google/flatbuffers/archive/v2.0.6.tar.gz tar xf v2.0.6.tar.gz ``` Build Flatbuffers for x86: ```bash cd $WORKING_DIR/flatbuffers-2.0.6 rm -f CMakeCache.txt rm -rf build-x86 mkdir build-x86 cd build-x86 rm -rf $WORKING_DIR/flatbuffers-x86 mkdir $WORKING_DIR/flatbuffers-x86 CXXFLAGS="-fPIC" $CMAKE .. \ -DFLATBUFFERS_BUILD_FLATC=1 \ -DCMAKE_INSTALL_PREFIX:PATH=$WORKING_DIR/flatbuffers-x86 make all install -j16 ``` Note: -fPIC is added to allow users to use the libraries in shared objects. Build Flatbuffers for Android: ```bash cd $WORKING_DIR/flatbuffers-2.0.6 rm -f CMakeCache.txt rm -rf build-android mkdir build-android cd build-android rm -rf $WORKING_DIR/flatbuffers-android mkdir $WORKING_DIR/flatbuffers-android CC=/usr/bin/aarch64-linux-gnu-gcc CXX=/usr/bin/aarch64-linux-gnu-g++ \ CXXFLAGS="-fPIC" \ cmake .. \ -DCMAKE_ANDROID_NDK=$NDK_DIR \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=$ANDROID_API \ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \ -DCMAKE_CXX_FLAGS=--std=c++14 \ -DFLATBUFFERS_BUILD_FLATC=OFF \ -DCMAKE_BUILD_TYPE=Release \ -DFLATBUFFERS_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=$WORKING_DIR/flatbuffers-android make all install -j16 ``` ## Download Arm NN Clone Arm NN: ```bash cd $WORKING_DIR git clone https://github.com/ARM-software/armnn.git ``` Checkout the Arm NN branch: ```bash cd armnn git checkout git pull ``` For example, if you want to check out the 23.02 release branch: ```bash cd armnn git checkout branches/armnn_23_02 git pull ``` ## Get And Build TFLite This optional step is only required if you intend to build the TFLite delegate or parser for Arm NN. First clone Tensorflow manually and check out the version Arm NN was tested with: ```bash cd $WORKING_DIR git clone https://github.com/tensorflow/tensorflow.git cd tensorflow git fetch && git checkout "6f692f73cb2043b4a0b0446539cd8c15b3dd9220" ``` Or use the script that Arm NN provides: ```bash git fetch && git checkout $(../armnn/scripts/get_tensorflow.sh -p) ``` Next, set variable TFLITE_ROOT_DIR and build Tensorflow Lite: ```bash export TFLITE_ROOT_DIR=$WORKING_DIR/tensorflow/tensorflow/lite cd $WORKING_DIR mkdir -p tflite-out/android cd tflite-out/android CMARGS="-DTFLITE_ENABLE_XNNPACK=OFF \ -DFLATBUFFERS_BUILD_FLATC=OFF \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_TESTING=OFF" CMARGS="$CMARGS -DCMAKE_TOOLCHAIN_FILE=$NDK_DIR/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=arm64-v8a \ -DANDROID_PLATFORM=$ANDROID_API" cmake $CMARGS $TFLITE_ROOT_DIR cd $WORKING_DIR cmake --build tflite-out/android -j 16 ``` Now generate the Tensorflow Lite Schema for the TFLite parser: ```bash cd $WORKING_DIR mkdir -p $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema SCHEMA_LOCATION=$WORKING_DIR/tensorflow/tensorflow/lite/schema/schema.fbs cp $SCHEMA_LOCATION $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema cd $WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema $WORKING_DIR/flatbuffers-x86/bin/flatc -c --gen-object-api --reflect-types --reflect-names schema.fbs ``` ## Build Arm Compute Library Clone Arm Compute Library: ```bash cd $WORKING_DIR git clone https://github.com/ARM-software/ComputeLibrary.git ``` Checkout Arm Compute Library release tag: ```bash cd ComputeLibrary git checkout ``` For example, if you want to check out the 23.02 release tag: ```bash cd ComputeLibrary git checkout v23.02 ``` Arm NN and Arm Compute Library are developed closely together. To use a particular version of Arm NN you will need a compatible version of ACL. Arm NN provides a script that downloads the version of Arm Compute Library that Arm NN was tested with: ```bash git checkout $(../armnn/scripts/get_compute_library.sh -p) ``` Build the Arm Compute Library: ```bash scons arch=arm64-v8a os=android toolchain_prefix=llvm- compiler_prefix=aarch64-linux-android$ANDROID_API- \ neon=1 opencl=1 embed_kernels=1 extra_cxx_flags="-fPIC" \ benchmark_tests=0 validation_tests=0 -j16 ``` ## Build Arm NN Build Arm NN: ```bash mkdir $WORKING_DIR/armnn/build cd $WORKING_DIR/armnn/build CXX=aarch64-linux-android$ANDROID_API-clang++ \ CC=aarch64-linux-android$ANDROID_API-clang \ CXX_FLAGS="-fPIE -fPIC" \ cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_ANDROID_NDK=$NDK_DIR \ -DNDK_VERSION=r25 \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=$ANDROID_API \ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \ -DCMAKE_SYSROOT=$WORKING_DIR/android-ndk-r25/toolchains/llvm/prebuilt/linux-x86_64/sysroot \ -DARMCOMPUTE_ROOT=$WORKING_DIR/ComputeLibrary \ -DARMCOMPUTE_BUILD_DIR=$WORKING_DIR/ComputeLibrary/build \ -DARMCOMPUTENEON=1 -DARMCOMPUTECL=1 -DARMNNREF=1 \ -DFLATBUFFERS_INCLUDE_PATH=$WORKING_DIR/flatbuffers-x86/include \ -DFLATBUFFERS_ROOT=$WORKING_DIR/flatbuffers-android \ -DFLATC_DIR=$WORKING_DIR/flatbuffers-x86 \ -DBUILD_UNIT_TESTS=1 \ -DBUILD_TESTS=1 \ -fexception \ ``` To include the Arm NN TFLite delegate add these arguments to the above list: ```bash -DBUILD_ARMNN_TFLITE_DELEGATE=1 \ -DTENSORFLOW_ROOT=$WORKING_DIR/tensorflow \ -DTFLITE_LIB_ROOT=$WORKING_DIR/tflite-out/android \ -DTFLITE_ROOT_DIR=$WORKING_DIR/tensorflow/tensorflow/lite \ ``` To include the Arm NN TFLite Parser add these arguments to the above list: ```bash -DBUILD_TF_LITE_PARSER=1 \ -DTF_LITE_GENERATED_PATH=$WORKING_DIR/tflite-out/tensorflow/tensorflow/lite/schema \ -DTENSORFLOW_ROOT=$WORKING_DIR/tensorflow \ -DTFLITE_LIB_ROOT=$WORKING_DIR/tflite-out/android \ ``` To include standalone sample dynamic backend tests, add these arguments to enable the tests and the dynamic backend path to the CMake command: ```bash -DSAMPLE_DYNAMIC_BACKEND=1 \ -DDYNAMIC_BACKEND_PATHS=$SAMPLE_DYNAMIC_BACKEND_PATH # Where $SAMPLE_DYNAMIC_BACKEND_PATH is the path where libArm_SampleDynamic_backend.so library file is pushed ``` * Run the build ```bash make -j16 ``` ## Build Standalone Sample Dynamic Backend This step is optional. The sample dynamic backend is located in armnn/src/dynamic/sample ```bash mkdir build cd build ``` * Use CMake to configure the build environment, update the following script and run it from the armnn/src/dynamic/sample/build directory to set up the Arm NN build: ```bash #!/bin/bash CXX=aarch64-linux-android$ANDROID_API-clang++ \ CC=aarch64-linux-android$ANDROID_API-clang \ CXX_FLAGS="-fPIE -fPIC" \ cmake \ -DCMAKE_C_COMPILER_WORKS=TRUE \ -DCMAKE_CXX_COMPILER_WORKS=TRUE \ -DCMAKE_ANDROID_NDK=$NDK_DIR \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=$ANDROID_API \ -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \ -DCMAKE_SYSROOT=$WORKING_DIR/android-ndk-r25/toolchains/llvm/prebuilt/linux-x86_64/sysroot \ -DCMAKE_CXX_FLAGS=--std=c++14 \ -DCMAKE_EXE_LINKER_FLAGS="-pie -llog" \ -DCMAKE_MODULE_LINKER_FLAGS="-llog" \ -DARMNN_PATH=$WORKING_DIR/armnn/build/libarmnn.so .. ``` * Run the build ```bash make ``` ## Run the Arm NN unit tests on an Android device * Push the build results to an Android device and make symbolic links for shared libraries: Currently adb version we have used for testing is 1.0.41. ```bash adb push libarmnn.so /data/local/tmp/ adb push libtimelineDecoder.so /data/local/tmp/ adb push libtimelineDecoderJson.so /data/local/tmp/ adb push GatordMock /data/local/tmp/ adb push libarmnnBasePipeServer.so /data/local/tmp/ adb push libarmnnTestUtils.so /data/local/tmp/ adb push UnitTests /data/local/tmp/ adb push $NDK_DIR/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so /data/local/tmp/ ``` * Push the files needed for the unit tests (they are a mix of files, directories and symbolic links): ```bash adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/testSharedObject adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/testSharedObject/* /data/local/tmp/src/backends/backendsCommon/test/testSharedObject/ adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/testDynamicBackend adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/testDynamicBackend/* /data/local/tmp/src/backends/backendsCommon/test/testDynamicBackend/ adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath1 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath1/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath1/ adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/ adb shell ln -s Arm_CpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1 adb shell ln -s Arm_CpuAcc_backend.so.1 /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1.2 adb shell ln -s Arm_CpuAcc_backend.so.1.2 /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_CpuAcc_backend.so.1.2.3 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath2/Arm_GpuAcc_backend.so /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/ adb shell ln -s nothing /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath2/Arm_no_backend.so adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath3 adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath5 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath5/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath5/ adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath6 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath6/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath6/ adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath7 adb shell mkdir -p /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath9 adb push -p $WORKING_DIR/armnn/build/src/backends/backendsCommon/test/backendsTestPath9/* /data/local/tmp/src/backends/backendsCommon/test/backendsTestPath9/ adb shell mkdir -p /data/local/tmp/src/backends/dynamic/reference adb push -p $WORKING_DIR/armnn/build/src/backends/dynamic/reference/Arm_CpuRef_backend.so /data/local/tmp/src/backends/dynamic/reference/ ``` If the standalone sample dynamic tests are enabled, also push libArm_SampleDynamic_backend.so library file to the folder specified as $SAMPLE_DYNAMIC_BACKEND_PATH when Arm NN is built. This is the example when $SAMPLE_DYNAMIC_BACKEND_PATH is specified as /data/local/tmp/dynamic/sample/: ```bash adb shell mkdir -p /data/local/tmp/dynamic/sample/ adb push -p $WORKING_DIR/armnn/src/dynamic/sample/build/libArm_SampleDynamic_backend.so /data/local/tmp/dynamic/sample/ ``` If the delegate was built, push the delegate unit tests too. ```bash adb push $WORKING_DIR/armnn/build/delegate/DelegateUnitTests /data/local/tmp/ adb push $WORKING_DIR/armnn/build/delegate/libarmnnDelegate.so /data/local/tmp/ ``` Run Arm NN unit tests: ```bash adb shell 'LD_LIBRARY_PATH=/data/local/tmp:/vendor/lib64:/vendor/lib64/egl /data/local/tmp/UnitTests' ``` If the delegate was built run Arm Delegate NN unit tests: ```bash adb shell 'LD_LIBRARY_PATH=/data/local/tmp:/vendor/lib64:/vendor/lib64/egl /data/local/tmp/DelegateUnitTests' ``` If libarmnnUtils.a is present in `$WORKING_DIR/armnn/build/` and the unit tests run without failure then the build was successful. armnn-23.08/BuildGuideAndroidNDK.md.license000066400000000000000000000001531446772241200204670ustar00rootroot00000000000000# # Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/CMakeLists.txt000066400000000000000000001267451446772241200154310ustar00rootroot00000000000000# # Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved. # Copyright © 2020 NXP # SPDX-License-Identifier: MIT # cmake_minimum_required (VERSION 3.7.0) project(armnn) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(additional_cmake_files) list(APPEND additional_cmake_files cmake/ArmnnVersion.cmake cmake/ClassicDelegateVersion.cmake cmake/OpaqueDelegateVersion.cmake cmake/ParserVersion.cmake cmake/Utils.cmake cmake/GlobalConfig.cmake cmake/AddDllCopyCommands.cmake cmake/ArmnnTestUtilsVersion.cmake) foreach(cmake_file ${additional_cmake_files}) include(${cmake_file}) endforeach() cmake_policy(SET CMP0057 NEW) # If the root of the tensorflow source tree has not been specified # and we are trying to build the tensorflow lite parser make # our best guess as to where it will be i.e. one directory above # the one this CMakeLists.txt file lives in, in a subdirectory # called tensorflow if (BUILD_TF_LITE_PARSER AND "${TENSORFLOW_ROOT}" STREQUAL "") set(TENSORFLOW_ROOT "${PROJECT_SOURCE_DIR}/../tensorflow" CACHE INTERNAL "") message(STATUS "Set TENSORFLOW_ROOT: ${TENSORFLOW_ROOT}") else() message(STATUS "TENSORFLOW_ROOT: ${TENSORFLOW_ROOT}") endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/delegate/cmake/Modules/") set(as_subproject Armnn) macro(find_package) if(NOT ${ARGV0} IN_LIST as_subproject) _find_package(${ARGV}) endif() endmacro() if (DYNAMIC_BACKEND_PATHS) # It's expected to have the format: DYNAMIC_BACKEND_PATHS="PATH_1:PATH_2...:PATH_N" add_definitions('-DDYNAMIC_BACKEND_PATHS="${DYNAMIC_BACKEND_PATHS}"') endif() include(GNUInstallDirs) add_subdirectory(profiling/common/src) add_subdirectory(profiling/client/src) if(ARMNN_SAMPLE_APPS_ENABLED) add_subdirectory(samples) endif() add_subdirectory(src/armnnTfLiteParser) add_subdirectory(src/armnnSerializer) add_subdirectory(src/armnnDeserializer) if(BUILD_UNIT_TESTS) add_subdirectory(src/armnnTestUtils) endif() if (BUILD_TESTS) add_subdirectory(tests) endif() # Include the additional cmake files in their own target so that they will appear nicely in IDEs add_custom_target(AdditionalCMakeFiles SOURCES ${additional_cmake_files}) set(armnnUtils_sources) list(APPEND armnnUtils_sources include/armnnUtils/CompatibleTypes.hpp include/armnnUtils/DataLayoutIndexed.hpp include/armnnUtils/Permute.hpp include/armnnUtils/Filesystem.hpp include/armnnUtils/FloatingPointComparison.hpp include/armnnUtils/FloatingPointConverter.hpp include/armnnUtils/QuantizeHelper.hpp include/armnnUtils/TContainer.hpp include/armnnUtils/TensorUtils.hpp include/armnnUtils/Transpose.hpp src/armnnUtils/BFloat16.hpp src/armnnUtils/CompatibleTypes.cpp src/armnnUtils/Filesystem.cpp src/armnnUtils/GraphTopologicalSort.hpp src/armnnUtils/Half.hpp src/armnnUtils/Permute.cpp src/armnnUtils/DataLayoutIndexed.cpp src/armnnUtils/DotSerializer.cpp src/armnnUtils/DotSerializer.hpp src/armnnUtils/HeapProfiling.cpp src/armnnUtils/HeapProfiling.hpp src/armnnUtils/LeakChecking.cpp src/armnnUtils/LeakChecking.hpp src/armnnUtils/ModelAccuracyChecker.cpp src/armnnUtils/ModelAccuracyChecker.hpp src/armnnUtils/FloatingPointConverter.cpp src/armnnUtils/VerificationHelpers.hpp src/armnnUtils/VerificationHelpers.cpp src/armnnUtils/ParserHelper.hpp src/armnnUtils/ParserHelper.cpp src/armnnUtils/ParserPrototxtFixture.hpp src/armnnUtils/ProfilingOptionsConverter.hpp src/armnnUtils/ProfilingOptionsConverter.cpp src/armnnUtils/PrototxtConversions.hpp src/armnnUtils/PrototxtConversions.cpp src/armnnUtils/TensorIOUtils.hpp src/armnnUtils/TensorUtils.cpp src/armnnUtils/Transpose.cpp ) add_library_ex(armnnUtils STATIC ${armnnUtils_sources}) target_include_directories(armnnUtils PRIVATE src/backends) if(BUILD_ONNX_PARSER) set(armnn_onnx_parser_sources) list(APPEND armnn_onnx_parser_sources include/armnnOnnxParser/IOnnxParser.hpp include/armnnOnnxParser/Version.hpp src/armnnOnnxParser/OnnxParser.hpp src/armnnOnnxParser/OnnxParser.cpp ${ONNX_GENERATED_SOURCES}/onnx/onnx.pb.cc ) # The generated onnx protobuf .cc files are not warning clean and we can't fix them. if(COMPILER_IS_GNU_LIKE) set_source_files_properties(${ONNX_GENERATED_SOURCES}/onnx/onnx.pb.cc PROPERTIES COMPILE_FLAGS "-Wno-conversion -Wno-sign-conversion") endif() add_library_ex(armnnOnnxParser SHARED ${armnn_onnx_parser_sources}) target_include_directories(armnnOnnxParser PRIVATE src/armnnUtils) target_link_libraries(armnnOnnxParser armnn) # Protobuf target_link_libraries(armnnOnnxParser ${PROTOBUF_LIBRARIES}) set_target_properties(armnnOnnxParser PROPERTIES VERSION ${ONNX_PARSER_LIB_VERSION} SOVERSION ${ONNX_PARSER_LIB_SOVERSION}) endif() list(APPEND armnn_sources include/armnn/ArmNN.hpp include/armnn/BackendHelper.hpp include/armnn/BackendId.hpp include/armnn/BackendOptions.hpp include/armnn/BackendRegistry.hpp include/armnn/Conversion.hpp include/armnn/Deprecated.hpp include/armnn/Descriptors.hpp include/armnn/DescriptorsFwd.hpp include/armnn/Exceptions.hpp include/armnn/backends/ILayerSupport.hpp include/armnn/backends/ICustomAllocator.hpp include/armnn/IAsyncExecutionCallback.hpp include/armnn/INetwork.hpp include/armnn/IProfiler.hpp include/armnn/IRuntime.hpp include/armnn/IStrategy.hpp include/armnn/IWorkingMemHandle.hpp include/armnn/Logging.hpp include/armnn/LstmParams.hpp include/armnn/MemorySources.hpp include/armnn/NetworkFwd.hpp include/armnn/Optional.hpp include/armnn/QuantizedLstmParams.hpp include/armnn/StrategyBase.hpp include/armnn/Tensor.hpp include/armnn/TensorFwd.hpp include/armnn/Threadpool.hpp include/armnn/Types.hpp include/armnn/TypesUtils.hpp include/armnn/Utils.hpp include/armnn/Version.hpp include/armnn/utility/Assert.hpp include/armnn/utility/IgnoreUnused.hpp include/armnn/utility/NumericCast.hpp include/armnn/utility/PolymorphicDowncast.hpp include/armnn/utility/StringUtils.hpp include/armnn/utility/TransformIterator.hpp include/armnn/backends/SubgraphView.hpp src/armnn/layers/LayerCloneBase.hpp src/armnn/layers/LayerWithParameters.hpp src/armnn/layers/ActivationLayer.hpp src/armnn/layers/ActivationLayer.cpp src/armnn/layers/AdditionLayer.hpp src/armnn/layers/AdditionLayer.cpp src/armnn/layers/ArgMinMaxLayer.hpp src/armnn/layers/ArgMinMaxLayer.cpp src/armnn/layers/BatchMatMulLayer.hpp src/armnn/layers/BatchMatMulLayer.cpp src/armnn/layers/BatchNormalizationLayer.hpp src/armnn/layers/BatchNormalizationLayer.cpp src/armnn/layers/BatchToSpaceNdLayer.hpp src/armnn/layers/BatchToSpaceNdLayer.cpp src/armnn/layers/CastLayer.hpp src/armnn/layers/CastLayer.cpp src/armnn/layers/ChannelShuffleLayer.hpp src/armnn/layers/ChannelShuffleLayer.cpp src/armnn/layers/ComparisonLayer.hpp src/armnn/layers/ComparisonLayer.cpp src/armnn/layers/ConcatLayer.hpp src/armnn/layers/ConcatLayer.cpp src/armnn/layers/ConstantLayer.hpp src/armnn/layers/ConstantLayer.cpp src/armnn/layers/Convolution2dLayer.hpp src/armnn/layers/Convolution2dLayer.cpp src/armnn/layers/Convolution3dLayer.hpp src/armnn/layers/Convolution3dLayer.cpp src/armnn/layers/ConvertFp16ToFp32Layer.hpp src/armnn/layers/ConvertFp16ToFp32Layer.cpp src/armnn/layers/ConvertFp32ToFp16Layer.hpp src/armnn/layers/ConvertFp32ToFp16Layer.cpp src/armnn/layers/DebugLayer.hpp src/armnn/layers/DebugLayer.cpp src/armnn/layers/DepthToSpaceLayer.hpp src/armnn/layers/DepthToSpaceLayer.cpp src/armnn/layers/DepthwiseConvolution2dLayer.hpp src/armnn/layers/DepthwiseConvolution2dLayer.cpp src/armnn/layers/DequantizeLayer.hpp src/armnn/layers/DequantizeLayer.cpp src/armnn/layers/DetectionPostProcessLayer.hpp src/armnn/layers/DetectionPostProcessLayer.cpp src/armnn/layers/ElementwiseBaseLayer.hpp src/armnn/layers/ElementwiseBaseLayer.cpp src/armnn/layers/ElementwiseBinaryLayer.hpp src/armnn/layers/ElementwiseBinaryLayer.cpp src/armnn/layers/ElementwiseUnaryLayer.hpp src/armnn/layers/ElementwiseUnaryLayer.cpp src/armnn/layers/FakeQuantizationLayer.hpp src/armnn/layers/FakeQuantizationLayer.cpp src/armnn/layers/FillLayer.hpp src/armnn/layers/FillLayer.cpp src/armnn/layers/FloorLayer.hpp src/armnn/layers/FloorLayer.cpp src/armnn/layers/FullyConnectedLayer.hpp src/armnn/layers/FullyConnectedLayer.cpp src/armnn/layers/GatherLayer.cpp src/armnn/layers/GatherLayer.hpp src/armnn/layers/GatherNdLayer.cpp src/armnn/layers/GatherNdLayer.hpp src/armnn/layers/InputLayer.hpp src/armnn/layers/InputLayer.cpp src/armnn/layers/InstanceNormalizationLayer.hpp src/armnn/layers/InstanceNormalizationLayer.cpp src/armnn/layers/L2NormalizationLayer.hpp src/armnn/layers/L2NormalizationLayer.cpp src/armnn/layers/LogicalBinaryLayer.hpp src/armnn/layers/LogicalBinaryLayer.cpp src/armnn/layers/LogSoftmaxLayer.hpp src/armnn/layers/LogSoftmaxLayer.cpp src/armnn/layers/LstmLayer.cpp src/armnn/layers/LstmLayer.hpp src/armnn/layers/MapLayer.cpp src/armnn/layers/MapLayer.hpp src/armnn/layers/MaximumLayer.cpp src/armnn/layers/MaximumLayer.hpp src/armnn/layers/MeanLayer.hpp src/armnn/layers/MeanLayer.cpp src/armnn/layers/MemCopyLayer.hpp src/armnn/layers/MemCopyLayer.cpp src/armnn/layers/MemImportLayer.hpp src/armnn/layers/MemImportLayer.cpp src/armnn/layers/MergeLayer.hpp src/armnn/layers/MergeLayer.cpp src/armnn/layers/MinimumLayer.cpp src/armnn/layers/MinimumLayer.hpp src/armnn/layers/MultiplicationLayer.hpp src/armnn/layers/MultiplicationLayer.cpp src/armnn/layers/NormalizationLayer.hpp src/armnn/layers/NormalizationLayer.cpp src/armnn/layers/OutputLayer.hpp src/armnn/layers/OutputLayer.cpp src/armnn/layers/PadLayer.hpp src/armnn/layers/PadLayer.cpp src/armnn/layers/PermuteLayer.hpp src/armnn/layers/PermuteLayer.cpp src/armnn/layers/Pooling2dLayer.hpp src/armnn/layers/Pooling2dLayer.cpp src/armnn/layers/Pooling3dLayer.hpp src/armnn/layers/Pooling3dLayer.cpp src/armnn/layers/QuantizeLayer.cpp src/armnn/layers/QuantizeLayer.hpp src/armnn/layers/QLstmLayer.hpp src/armnn/layers/QLstmLayer.cpp src/armnn/layers/QuantizedLstmLayer.hpp src/armnn/layers/QuantizedLstmLayer.cpp src/armnn/layers/DivisionLayer.cpp src/armnn/layers/DivisionLayer.hpp src/armnn/layers/PreCompiledLayer.hpp src/armnn/layers/PreCompiledLayer.cpp src/armnn/layers/PreluLayer.hpp src/armnn/layers/PreluLayer.cpp src/armnn/layers/RankLayer.hpp src/armnn/layers/RankLayer.cpp src/armnn/layers/ReduceLayer.hpp src/armnn/layers/ReduceLayer.cpp src/armnn/layers/ReshapeLayer.hpp src/armnn/layers/ReshapeLayer.cpp src/armnn/layers/ResizeLayer.hpp src/armnn/layers/ResizeLayer.cpp src/armnn/layers/ReverseV2Layer.hpp src/armnn/layers/ReverseV2Layer.cpp src/armnn/layers/ShapeLayer.cpp src/armnn/layers/ShapeLayer.hpp src/armnn/layers/SliceLayer.cpp src/armnn/layers/SliceLayer.hpp src/armnn/layers/SoftmaxLayer.hpp src/armnn/layers/SoftmaxLayer.cpp src/armnn/layers/SpaceToBatchNdLayer.hpp src/armnn/layers/SpaceToBatchNdLayer.cpp src/armnn/layers/SpaceToDepthLayer.hpp src/armnn/layers/SpaceToDepthLayer.cpp src/armnn/layers/SplitterLayer.hpp src/armnn/layers/SplitterLayer.cpp src/armnn/layers/StackLayer.hpp src/armnn/layers/StackLayer.cpp src/armnn/layers/StandInLayer.cpp src/armnn/layers/StandInLayer.hpp src/armnn/layers/StridedSliceLayer.cpp src/armnn/layers/StridedSliceLayer.hpp src/armnn/layers/SubtractionLayer.cpp src/armnn/layers/SubtractionLayer.hpp src/armnn/layers/SwitchLayer.cpp src/armnn/layers/SwitchLayer.hpp src/armnn/layers/TileLayer.cpp src/armnn/layers/TileLayer.hpp src/armnn/layers/TransposeConvolution2dLayer.cpp src/armnn/layers/TransposeConvolution2dLayer.hpp src/armnn/layers/TransposeLayer.hpp src/armnn/layers/TransposeLayer.cpp src/armnn/layers/UnidirectionalSequenceLstmLayer.cpp src/armnn/layers/UnidirectionalSequenceLstmLayer.hpp src/armnn/layers/UnmapLayer.cpp src/armnn/layers/UnmapLayer.hpp src/armnn/ArmNNProfilingServiceInitialiser.cpp src/armnn/ArmNNProfilingServiceInitialiser.hpp src/armnn/AsyncExecutionCallback.cpp src/armnn/AsyncExecutionCallback.hpp src/armnn/BackendRegistry.cpp src/armnn/BackendSettings.hpp src/armnn/BackendHelper.cpp src/armnn/Descriptors.cpp src/armnn/DeviceSpec.hpp src/armnn/DllExport.hpp src/armnn/Exceptions.cpp src/armnn/ExecutionData.hpp src/armnn/ExecutionFrame.cpp src/armnn/ExecutionFrame.hpp src/armnn/Graph.cpp src/armnn/Graph.hpp src/armnn/IGraphObservable.hpp src/armnn/ILayerSupport.cpp src/armnn/Instrument.hpp src/armnn/InternalTypes.cpp src/armnn/InternalTypes.hpp src/armnn/ISubgraphViewConverter.hpp src/armnn/JsonPrinter.cpp src/armnn/JsonPrinter.hpp src/armnn/Layer.cpp src/armnn/LayerFwd.hpp src/armnn/Layer.hpp src/armnn/LayersFwd.hpp src/armnn/LayerSupportCommon.hpp src/armnn/LoadedNetwork.cpp src/armnn/LoadedNetwork.hpp src/armnn/Logging.cpp src/armnn/Network.cpp src/armnn/Network.hpp src/armnn/NetworkUtils.cpp src/armnn/NetworkUtils.hpp src/armnn/Observable.cpp src/armnn/Observable.hpp src/armnn/Optimizer.cpp src/armnn/Optimizer.hpp src/armnn/OutputHandler.cpp src/armnn/OutputHandler.hpp src/armnn/Profiling.cpp src/armnn/ProfilingEvent.cpp src/armnn/ProfilingDetails.hpp src/armnn/ProfilingEvent.hpp src/armnn/Profiling.hpp src/armnn/Runtime.cpp src/armnn/Runtime.hpp src/armnn/RangeTracker.cpp src/armnn/RangeTracker.hpp src/armnn/ResolveType.hpp src/armnn/SerializeLayerParameters.cpp src/armnn/SerializeLayerParameters.hpp src/armnn/SubgraphView.cpp src/armnn/SubgraphViewSelector.cpp src/armnn/SubgraphViewSelector.hpp src/armnn/Tensor.cpp src/armnn/Threadpool.cpp src/armnn/TypesUtils.cpp src/armnn/Utils.cpp src/armnn/WallClockTimer.cpp src/armnn/WallClockTimer.hpp src/armnn/WorkingMemDescriptor.hpp src/armnn/WorkingMemHandle.cpp src/armnn/WorkingMemHandle.hpp src/armnn/optimizations/AddBroadcastReshapeLayer.hpp src/armnn/optimizations/AddDebug.hpp src/armnn/optimizations/All.hpp src/armnn/optimizations/ConvertConstants.hpp src/armnn/optimizations/ConvertFp32NetworkToFp16.hpp src/armnn/optimizations/FoldPadIntoLayer2d.hpp src/armnn/optimizations/MovePermuteUp.hpp src/armnn/optimizations/MoveTransposeUp.hpp src/armnn/optimizations/Optimization.hpp src/armnn/optimizations/OptimizeConsecutiveReshapes.hpp src/armnn/optimizations/OptimizeInverseConversions.hpp src/armnn/optimizations/OptimizeInversePermutes.hpp src/armnn/optimizations/PermuteAndBatchToSpaceAsDepthToSpace.hpp src/armnn/optimizations/PermuteAsReshape.hpp src/armnn/optimizations/SquashEqualSiblings.hpp third-party/cxxopts/cxxopts.hpp third-party/ghc/filesystem.hpp third-party/half/half.hpp third-party/mapbox/optional.hpp third-party/mapbox/recursive_wrapper.hpp third-party/mapbox/variant.hpp third-party/mapbox/variant_cast.hpp third-party/mapbox/variant_io.hpp third-party/mapbox/variant_visitor.hpp ) # Files used for Streamline-based profiling backend if(PROFILING_BACKEND_STREAMLINE) list(APPEND armnn_sources ${GATOR_ROOT}/annotate/streamline_annotate.h ${GATOR_ROOT}/annotate/streamline_annotate.c) endif() # the backends under src/backends extend the list of # object libs armnn to include in the build include(src/backends/backends.cmake) foreach(lib ${armnnLibraries}) message(STATUS "Adding object library dependency to armnn: ${lib}") list(APPEND armnn_sources $) endforeach() # The delegate needs to be placed after armnnLibraries has been fully populated. The armnn_delegate_jni library # requires a static armnn build. # Explanation: # Because backends are added as object libraries they won't be linked to armnn when building armnn statically. # A target that uses a static armnn library has to link to the object libraries in the variable armnnLibraries # manually to include all symbols from backends. if (BUILD_CLASSIC_DELEGATE OR BUILD_OPAQUE_DELEGATE) set(ARMNN_SUB_PROJECT ON) set(ARMNN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(delegate) endif() if (BUILD_CLASSIC_DELEGATE) add_definitions(-DARMNN_TFLITE_DELEGATE) endif() if (BUILD_OPAQUE_DELEGATE) add_definitions(-DARMNN_TFLITE_OPAQUE_DELEGATE) endif() if (BUILD_SHARED_LIBS) add_library_ex(armnn SHARED ${armnn_sources}) else() add_library(armnn STATIC ${armnn_sources}) endif() target_compile_definitions(armnn PRIVATE "ARMNN_COMPILING_DLL") # Generate a map file for all build modes set_property(TARGET armnn APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Map=libarmnnMapFile.map") message(STATUS "Linker will generate mapfile ") target_include_directories(armnn PUBLIC $ $ PRIVATE src/armnn src/armnnUtils src/backends src/profiling profiling/common/include profiling/client/include ) # Link fmt third-party library add_subdirectory(third-party/fmt) target_link_libraries(armnn PUBLIC fmt) target_link_libraries(armnn PUBLIC armnnUtils) target_link_libraries(armnn PUBLIC pipeCommon) target_link_libraries(armnn PUBLIC pipeClient) if(NOT BUILD_BARE_METAL AND NOT EXECUTE_NETWORK_STATIC) target_link_libraries(armnn PUBLIC ${CMAKE_DL_LIBS}) endif() if ("${CMAKE_SYSTEM_NAME}" STREQUAL Windows) target_link_libraries(armnn PUBLIC Ws2_32.lib) endif() if(BUILD_ONNX_PARSER) install(TARGETS armnnOnnxParser LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(ARMCOMPUTENEON OR ARMCOMPUTECL) target_link_libraries(armnn PUBLIC ${ARMCOMPUTE_LIBRARIES}) endif() # Flatbuffers is not included in armnn if the armnnSerializer is not present # Required to target link both flatbuffers and tosa_serialization_lib to armnn if(ARMNNTOSACOMMON) if (FLATBUFFERS_LIBRARY) target_link_libraries(armnn PUBLIC ${FLATBUFFERS_LIBRARY}) else() # Use PATH_SUFFIXES to help find separate libs for debug/release on Windows builds find_library(FLATBUFFERS_LIBRARY_DEBUG NAMES flatbuffers HINTS ${FLATBUFFERS_BUILD_DIR} PATH_SUFFIXES "Debug") find_library(FLATBUFFERS_LIBRARY_RELEASE NAMES flatbuffers HINTS ${FLATBUFFERS_BUILD_DIR} PATH_SUFFIXES "Release") target_link_libraries(armnn PUBLIC debug ${FLATBUFFERS_LIBRARY_DEBUG} optimized ${FLATBUFFERS_LIBRARY_RELEASE}) endif() if (TOSA_SERIALIZATION_LIB) target_link_libraries(armnn PUBLIC -Wl,--whole-archive ${TOSA_SERIALIZATION_LIB} -Wl,--no-whole-archive) else() find_library(TOSA_SERIALIZATION_LIB NAMES libtosa_serialization_lib.a tosa_serialization_lib HINTS ${TOSA_SERIALIZATION_LIB_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "TOSA serialization library set to ${TOSA_SERIALIZATION_LIB}") target_link_libraries(armnn PUBLIC -Wl,--whole-archive ${TOSA_SERIALIZATION_LIB} -Wl,--no-whole-archive) endif() endif() if (ARMNNTOSAREF) if (TOSA_REFERENCE_MODEL_LIB) target_link_libraries(armnn PUBLIC -Wl,--whole-archive ${TOSA_REFERENCE_MODEL_LIB} -Wl,--no-whole-archive) else() find_library(TOSA_REFERENCE_MODEL_LIB NAMES libtosa_reference_model_lib.a tosa_reference_model_lib HINTS ${TOSA_REFERENCE_MODEL_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "TOSA Reference Model set to ${TOSA_REFERENCE_MODEL_LIB}") target_link_libraries(armnn PUBLIC -Wl,--whole-archive ${TOSA_REFERENCE_MODEL_LIB} -Wl,--no-whole-archive) endif() endif() if(PROFILING_BACKEND_STREAMLINE AND (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android))) target_link_libraries(armnn PUBLIC ${CMAKE_THREAD_LIBS_INIT}) endif() set_target_properties(armnn PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION}) if(BUILD_UNIT_TESTS) set(unittest_sources) list(APPEND unittest_sources src/armnn/test/CloneTests.cpp src/armnn/test/ConstTensorLayerVisitor.hpp src/armnn/test/ConstTensorLayerVisitor.cpp src/armnn/test/EndToEndTest.cpp src/armnn/test/ExecutionFrameTest.cpp src/armnn/test/FloatingPointConverterTest.cpp src/armnn/test/FlowControl.cpp src/armnn/test/GraphTests.cpp src/armnn/test/InstrumentTests.cpp src/armnn/test/LayerTests.cpp src/armnn/test/InferOutputTests.cpp src/armnn/test/InferOutputTests.hpp src/armnn/test/ModelAccuracyCheckerTest.cpp src/armnn/test/NetworkTests.cpp src/armnn/test/ObservableTest.cpp src/armnn/test/OptimizerTests.cpp src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp src/armnn/test/optimizations/ConvertConstDequantisationLayersToConstLayersTest.cpp src/armnn/test/optimizations/ConvertConstPermuteLayersToConstLayersTest.cpp src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp src/armnn/test/optimizations/FoldPadIntoQuantizedAveragePooling2DTests.cpp src/armnn/test/optimizations/FoldPadTests.cpp src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp src/armnn/test/optimizations/FuseActivationTests.cpp src/armnn/test/optimizations/InsertDebugLayerTests.cpp src/armnn/test/optimizations/MovePermuteUpTests.cpp src/armnn/test/optimizations/MoveTransposeUpTests.cpp src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp src/armnn/test/optimizations/PermuteAsReshapeTests.cpp src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp src/armnn/test/optimizations/TransposeAsReshapeTests.cpp src/armnn/test/OptionalTest.cpp src/armnn/test/ProfilerTests.cpp src/armnn/test/ProfilingEventTest.cpp src/armnn/test/ShapeInferenceTests.cpp src/armnn/test/SubgraphViewTests.cpp src/armnn/test/TensorHandleStrategyTest.cpp src/armnn/test/TensorTest.cpp src/armnn/test/TestInputOutputLayerVisitor.cpp src/armnn/test/TestInputOutputLayerVisitor.hpp src/armnn/test/TestLayerVisitor.cpp src/armnn/test/TestLayerVisitor.hpp src/armnn/test/TestNameOnlyLayerVisitor.cpp src/armnn/test/TestNameOnlyLayerVisitor.hpp src/armnn/test/TestNameAndDescriptorLayerVisitor.hpp src/armnn/test/TestNameAndDescriptorLayerVisitor.cpp src/armnn/test/UtilityTests.cpp src/armnn/test/UtilsTests.cpp src/armnnUtils/test/FloatingPointComparisonTest.cpp src/armnnUtils/test/ParserHelperTest.cpp src/armnnUtils/test/PrototxtConversionsTest.cpp src/armnnUtils/test/QuantizeHelperTest.cpp src/armnnUtils/test/TensorUtilsTest.cpp src/armnnUtils/test/TransformIteratorTest.cpp src/profiling/test/BufferTests.cpp src/profiling/test/FileOnlyProfilingDecoratorTests.cpp src/profiling/test/PrintPacketHeaderHandler.cpp src/profiling/test/PrintPacketHeaderHandler.hpp src/profiling/test/ProfilingConnectionDumpToFileDecoratorTests.cpp src/profiling/test/ProfilingGuidTest.cpp src/profiling/test/ProfilingMocks.hpp src/profiling/test/ProfilingTests.cpp src/profiling/test/ProfilingTests.hpp src/profiling/test/ProfilingTestUtils.cpp src/profiling/test/ProfilingTestUtils.hpp src/profiling/test/RequestCountersPacketHandler.cpp src/profiling/test/RequestCountersPacketHandler.hpp src/profiling/test/SendCounterPacketTests.cpp src/profiling/test/SendCounterPacketTests.hpp src/profiling/test/TestTimelinePacketHandler.cpp src/profiling/test/TestTimelinePacketHandler.hpp src/profiling/test/TimelineModel.cpp src/profiling/test/TimelineModel.hpp src/profiling/test/SendTimelinePacketTests.cpp src/profiling/test/TimelinePacketTests.cpp src/profiling/test/TimelineUtilityMethodsTests.cpp third-party/doctest/doctest.h ) if(ARMNNREF) list(APPEND unittest_sources src/armnn/test/optimizations/FuseBatchNormTests.cpp src/armnn/test/DebugCallbackTest.cpp src/armnn/test/RuntimeTests.cpp src/armnn/test/RuntimeTests.hpp ) endif() if(BUILD_TF_LITE_PARSER AND ARMNNREF) list(APPEND unittest_sources src/armnnTfLiteParser/test/Activations.cpp src/armnnTfLiteParser/test/Addition.cpp src/armnnTfLiteParser/test/ArgMinMax.cpp src/armnnTfLiteParser/test/AvgPool2D.cpp src/armnnTfLiteParser/test/BatchMatMul.cpp src/armnnTfLiteParser/test/BatchToSpaceND.cpp src/armnnTfLiteParser/test/Cast.cpp src/armnnTfLiteParser/test/Comparison.cpp src/armnnTfLiteParser/test/Concatenation.cpp src/armnnTfLiteParser/test/Constant.cpp src/armnnTfLiteParser/test/Conv2D.cpp src/armnnTfLiteParser/test/Conv3D.cpp src/armnnTfLiteParser/test/DepthwiseConvolution2D.cpp src/armnnTfLiteParser/test/DepthToSpace.cpp src/armnnTfLiteParser/test/Dequantize.cpp src/armnnTfLiteParser/test/DetectionPostProcess.cpp src/armnnTfLiteParser/test/Div.cpp src/armnnTfLiteParser/test/ElementWiseUnary.cpp src/armnnTfLiteParser/test/ExpandDims.cpp src/armnnTfLiteParser/test/FloorDiv.cpp src/armnnTfLiteParser/test/FullyConnected.cpp src/armnnTfLiteParser/test/Gather.cpp src/armnnTfLiteParser/test/GatherNd.cpp src/armnnTfLiteParser/test/L2Normalization.cpp src/armnnTfLiteParser/test/LeakyRelu.cpp src/armnnTfLiteParser/test/LoadScopeDynamicTensor.cpp src/armnnTfLiteParser/test/LocalResponseNormalization.cpp src/armnnTfLiteParser/test/Maximum.cpp src/armnnTfLiteParser/test/MaxPool2D.cpp src/armnnTfLiteParser/test/Mean.cpp src/armnnTfLiteParser/test/Minimum.cpp src/armnnTfLiteParser/test/MirrorPad.cpp src/armnnTfLiteParser/test/Multiplication.cpp src/armnnTfLiteParser/test/Pack.cpp src/armnnTfLiteParser/test/Pad.cpp src/armnnTfLiteParser/test/PadV2.cpp src/armnnTfLiteParser/test/Power.cpp src/armnnTfLiteParser/test/Prelu.cpp src/armnnTfLiteParser/test/Reduce.cpp src/armnnTfLiteParser/test/Reshape.cpp src/armnnTfLiteParser/test/ReshapeDynamic.cpp src/armnnTfLiteParser/test/ResizeBilinear.cpp src/armnnTfLiteParser/test/ResizeNearestNeighbor.cpp src/armnnTfLiteParser/test/ReverseV2.cpp src/armnnTfLiteParser/test/Quantize.cpp src/armnnTfLiteParser/test/Softmax.cpp src/armnnTfLiteParser/test/SpaceToBatchND.cpp src/armnnTfLiteParser/test/Shape.cpp src/armnnTfLiteParser/test/Slice.cpp src/armnnTfLiteParser/test/Split.cpp src/armnnTfLiteParser/test/SplitV.cpp src/armnnTfLiteParser/test/Squeeze.cpp src/armnnTfLiteParser/test/Square.cpp src/armnnTfLiteParser/test/SquaredDifference.cpp src/armnnTfLiteParser/test/StridedSlice.cpp src/armnnTfLiteParser/test/Sub.cpp src/armnnTfLiteParser/test/Sum.cpp src/armnnTfLiteParser/test/Tile.cpp src/armnnTfLiteParser/test/TransposeConv.cpp src/armnnTfLiteParser/test/Transpose.cpp src/armnnTfLiteParser/test/Unpack.cpp src/armnnTfLiteParser/test/Unsupported.cpp src/armnnTfLiteParser/test/LoadModel.cpp src/armnnTfLiteParser/test/GetBuffer.cpp src/armnnTfLiteParser/test/OutputShapeOfSqueeze.cpp src/armnnTfLiteParser/test/InputOutputTensorNames.cpp src/armnnTfLiteParser/test/GetTensorIds.cpp src/armnnTfLiteParser/test/GetSubgraphInputsOutputs.cpp src/armnnTfLiteParser/test/GetInputsOutputs.cpp src/armnnTfLiteParser/test/TfLiteParser.cpp ) # Generate SchemaText.cpp file which contains the TfLite schema text as a # static C-array of bytes. This is needed at runtime for TfLite parser tests. add_custom_command( OUTPUT SchemaText.cpp COMMAND cp ${TF_LITE_SCHEMA_INCLUDE_PATH}/schema.fbs g_TfLiteSchemaText COMMAND xxd -i g_TfLiteSchemaText SchemaText.cpp WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${TF_LITE_SCHEMA_INCLUDE_PATH}/schema.fbs ) list(APPEND unittest_sources ${CMAKE_CURRENT_BINARY_DIR}/SchemaText.cpp) endif() if(BUILD_ONNX_PARSER AND ARMNNREF) list(APPEND unittest_sources src/armnnOnnxParser/test/Addition.cpp src/armnnOnnxParser/test/BatchNorm.cpp src/armnnOnnxParser/test/Clip.cpp src/armnnOnnxParser/test/Concat.cpp src/armnnOnnxParser/test/Const.cpp src/armnnOnnxParser/test/Constructor.cpp src/armnnOnnxParser/test/Conv2D.cpp src/armnnOnnxParser/test/CreateNetwork.cpp src/armnnOnnxParser/test/DepthConv.cpp src/armnnOnnxParser/test/Flatten.cpp src/armnnOnnxParser/test/FullyConnected.cpp src/armnnOnnxParser/test/Gather.cpp src/armnnOnnxParser/test/Gemm.cpp src/armnnOnnxParser/test/GetInputsOutputs.cpp src/armnnOnnxParser/test/LoadScopeDynamicTensor.cpp src/armnnOnnxParser/test/OnnxParserTestUtils.cpp src/armnnOnnxParser/test/OnnxParserTestUtils.hpp src/armnnOnnxParser/test/Pooling.cpp src/armnnOnnxParser/test/Relu.cpp src/armnnOnnxParser/test/Reshape.cpp src/armnnOnnxParser/test/Shape.cpp src/armnnOnnxParser/test/Unsqueeze.cpp ) endif() if(BUILD_ARMNN_SERIALIZER AND ARMNNREF) enable_language(ASM) list(APPEND unittest_sources src/armnnSerializer/test/ActivationSerializationTests.cpp src/armnnSerializer/test/ComparisonSerializationTests.cpp src/armnnSerializer/test/LstmSerializationTests.cpp src/armnnSerializer/test/SerializerTests.cpp src/armnnSerializer/test/SerializerTestUtils.cpp src/armnnSerializer/test/SerializerTestUtils.hpp src/armnnDeserializer/test/DeserializeAbs.cpp src/armnnDeserializer/test/DeserializeActivation.cpp src/armnnDeserializer/test/DeserializeAdd.cpp src/armnnDeserializer/test/DeserializeArgMinMax.cpp src/armnnDeserializer/test/DeserializeBatchMatMul.cpp src/armnnDeserializer/test/DeserializeBatchToSpaceNd.cpp src/armnnDeserializer/test/DeserializeBatchNormalization.cpp src/armnnDeserializer/test/DeserializeCast.cpp src/armnnDeserializer/test/DeserializeChannelShuffle.cpp src/armnnDeserializer/test/DeserializeComparison.cpp src/armnnDeserializer/test/DeserializeConstant.cpp src/armnnDeserializer/test/DeserializeConvolution2d.cpp src/armnnDeserializer/test/DeserializeConvolution3d.cpp src/armnnDeserializer/test/DeserializeDepthToSpace.cpp src/armnnDeserializer/test/DeserializeDepthwiseConv2d.cpp src/armnnDeserializer/test/DeserializeElementWiseBinary.cpp src/armnnDeserializer/test/DeserializeDivision.cpp src/armnnDeserializer/test/DeserializeFill.cpp src/armnnDeserializer/test/DeserializeFloor.cpp src/armnnDeserializer/test/DeserializeFullyConnected.cpp src/armnnDeserializer/test/DeserializeGather.cpp src/armnnDeserializer/test/DeserializeGatherNd.cpp src/armnnDeserializer/test/DeserializeInstanceNormalization.cpp src/armnnDeserializer/test/DeserializeL2Normalization.cpp src/armnnDeserializer/test/DeserializeLogSoftmax.cpp src/armnnDeserializer/test/DeserializeMean.cpp src/armnnDeserializer/test/DeserializeMultiplication.cpp src/armnnDeserializer/test/DeserializeNormalization.cpp src/armnnDeserializer/test/DeserializePad.cpp src/armnnDeserializer/test/DeserializePermute.cpp src/armnnDeserializer/test/DeserializePooling2d.cpp src/armnnDeserializer/test/DeserializePooling3d.cpp src/armnnDeserializer/test/DeserializeRank.cpp src/armnnDeserializer/test/DeserializeReduceSum.cpp src/armnnDeserializer/test/DeserializeReshape.cpp src/armnnDeserializer/test/DeserializeResizeBilinear.cpp src/armnnDeserializer/test/DeserializeReverseV2.cpp src/armnnDeserializer/test/DeserializeRsqrt.cpp src/armnnDeserializer/test/DeserializeShape.cpp src/armnnDeserializer/test/DeserializeSlice.cpp src/armnnDeserializer/test/DeserializeSpaceToBatchNd.cpp src/armnnDeserializer/test/DeserializeStridedSlice.cpp src/armnnDeserializer/test/DeserializeSubtraction.cpp src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp src/armnnDeserializer/test/SchemaSerialize.s ) set_source_files_properties(src/armnnDeserializer/test/SchemaSerialize.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp") endif() if(BUILD_GATORD_MOCK) list(APPEND unittest_sources tests/profiling/gatordmock/tests/GatordMockTests.cpp ) endif() if(BUILD_TIMELINE_DECODER) list(APPEND unittest_sources src/timelineDecoder/tests/JSONTimelineDecoderTests.cpp profiling/server/src/timelineDecoder/tests/TimelineTests.cpp ) endif() if(BUILD_BASE_PIPE_SERVER) list(APPEND unittest_sources profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp ) endif() if(BUILD_TESTS) list(APPEND unittest_sources ./tests/ExecuteNetwork/FileComparisonExecutor.hpp ./tests/ExecuteNetwork/FileComparisonExecutor.cpp ./tests/ExecuteNetwork/test/FileComparisonExecutorTests.cpp ./tests/NetworkExecutionUtils/NetworkExecutionUtils.cpp ./tests/NetworkExecutionUtils/test/NetworkExecutionUtilsTests.cpp) endif() foreach(lib ${armnnUnitTestLibraries}) message(STATUS "Adding object library dependency to UnitTests: ${lib}") list(APPEND unittest_sources $) endforeach() add_executable(UnitTests ${unittest_sources}) target_include_directories(UnitTests PRIVATE delegate/common/include src/armnn src/armnnUtils src/armnnTestUtils src/backends src/profiling tests) if(VALGRIND_FOUND) if(HEAP_PROFILING OR LEAK_CHECKING) message(STATUS "Valgrind is disabled for heap profiling and leak checking builds.") else() # Valgrind works with gperftools version number <= 2.4 target_compile_definitions(UnitTests PRIVATE "WITH_VALGRIND=1") endif() endif() target_link_libraries(UnitTests ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(UnitTests armnn) target_link_libraries(UnitTests armnnTestUtils) if(BUILD_GATORD_MOCK) target_link_libraries(UnitTests gatordMockService) endif() if(BUILD_TIMELINE_DECODER) target_link_libraries(UnitTests timelineDecoder) target_link_libraries(UnitTests timelineDecoderJson) endif() if(BUILD_TF_LITE_PARSER) target_include_directories(UnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}") target_include_directories(UnitTests SYSTEM PRIVATE "${FLATBUFFERS_INCLUDE_PATH}") target_link_libraries(UnitTests armnnTfLiteParser) endif() if(BUILD_ARMNN_SERIALIZER AND ARMNNREF) target_include_directories(UnitTests SYSTEM PRIVATE generated) target_include_directories(UnitTests SYSTEM PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/armnnSerializer) target_include_directories(UnitTests SYSTEM PRIVATE "${FLATBUFFERS_INCLUDE_PATH}") target_link_libraries(UnitTests armnnSerializer) endif() if(BUILD_ONNX_PARSER) target_link_libraries(UnitTests armnnOnnxParser) endif() if(BUILD_BASE_PIPE_SERVER) target_link_libraries(UnitTests armnnBasePipeServer) endif() addDllCopyCommands(UnitTests) endif() if (BUILD_ARMNN_SERIALIZER AND (BUILD_TF_LITE_PARSER OR BUILD_ONNX_PARSER) AND ARMNNREF) set(ArmnnConverter_sources src/armnnConverter/ArmnnConverter.cpp) add_executable_ex(ArmnnConverter ${ArmnnConverter_sources}) target_include_directories(ArmnnConverter PRIVATE src/armnn) target_include_directories(ArmnnConverter PRIVATE src/armnnUtils) if(BUILD_ONNX_PARSER) target_link_libraries(ArmnnConverter armnnOnnxParser) endif() if(BUILD_TF_LITE_PARSER) target_link_libraries(ArmnnConverter armnnTfLiteParser) endif() target_link_libraries(ArmnnConverter armnnSerializer) target_link_libraries(ArmnnConverter armnn) target_link_libraries(ArmnnConverter ${CMAKE_THREAD_LIBS_INIT}) addDllCopyCommands(ArmnnConverter) install(TARGETS ArmnnConverter RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if(BUILD_BASE_PIPE_SERVER) add_subdirectory(profiling/server/src/basePipeServer) endif() if(BUILD_TIMELINE_DECODER) add_subdirectory(profiling/server/src/timelineDecoder) add_subdirectory(src/timelineDecoder) endif() if(BUILD_GATORD_MOCK AND NOT BUILD_BASE_PIPE_SERVER) message(ERROR, "In order to build GatordMock you must set BUILD_BASE_PIPE_SERVER = YES") endif() if(BUILD_GATORD_MOCK AND NOT BUILD_TIMELINE_DECODER) message(ERROR, "In order to build GatordMock you must set BUILD_TIMELINE_DECODER = YES") endif() if(BUILD_GATORD_MOCK) set(gatord_mock_sources) list(APPEND gatord_mock_sources tests/profiling/gatordmock/CommandFileParser.hpp tests/profiling/gatordmock/CommandFileParser.cpp tests/profiling/gatordmock/CommandLineProcessor.hpp tests/profiling/gatordmock/CommandLineProcessor.cpp tests/profiling/gatordmock/GatordMockService.hpp tests/profiling/gatordmock/GatordMockService.cpp tests/profiling/gatordmock/PeriodicCounterCaptureCommandHandler.cpp tests/profiling/gatordmock/PeriodicCounterCaptureCommandHandler.hpp tests/profiling/gatordmock/PeriodicCounterSelectionResponseHandler.cpp tests/profiling/gatordmock/PeriodicCounterSelectionResponseHandler.hpp tests/profiling/gatordmock/StreamMetadataCommandHandler.cpp tests/profiling/gatordmock/StreamMetadataCommandHandler.hpp tests/profiling/gatordmock/StubCommandHandler.hpp ) add_library_ex(gatordMockService STATIC ${gatord_mock_sources}) target_include_directories(gatordMockService PRIVATE profiling/common/include profiling/client/include profiling/server/src/basePipeServer src/armnnUtils src/profiling src/timelineDecoder) if(BUILD_UNIT_TESTS) target_include_directories(UnitTests PRIVATE tests/profiling/gatordmock) target_include_directories(UnitTests PRIVATE src/backends/backendsCommon/test) endif() add_executable_ex(GatordMock tests/profiling/gatordmock/GatordMockMain.cpp) target_include_directories(GatordMock PRIVATE profiling/common/include profiling/client/include profiling/server/src/basePipeServer src/armnnUtils src/profiling src/timelineDecoder) target_link_libraries(GatordMock PUBLIC armnn armnnBasePipeServer timelineDecoder gatordMockService) if(Threads_FOUND AND (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android))) target_link_libraries(GatordMock PUBLIC ${CMAKE_THREAD_LIBS_INIT}) endif() endif() #################################################### # export targets set(armnn_export_targets) list(APPEND armnn_export_targets armnn armnnUtils ) install( TARGETS ${armnn_export_targets} EXPORT armnn-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) #################################################### ## Set export alias set_target_properties(armnn PROPERTIES EXPORT_NAME Armnn ) ## Export target scrips install( EXPORT armnn-targets FILE ArmnnTargets.cmake NAMESPACE Armnn:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) #################################################### ## Create ArmnnConfig.cmake include(CMakePackageConfigHelpers) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}) message(STATUS "CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}" ) message(STATUS "CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}" ) configure_package_config_file( ${CMAKE_CURRENT_LIST_DIR}/cmake/ArmnnConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/ArmnnConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) #################################################### ## Install Armnn config file install( FILES ${CMAKE_CURRENT_BINARY_DIR}/ArmnnConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) #################################################### ## Export from build tree export( EXPORT armnn-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/ArmnnTargets.cmake NAMESPACE Armnn:: ) add_library(Armnn::Armnn ALIAS armnn) add_library(Armnn::armnnUtils ALIAS armnnUtils) #################################################### ## Build Python bindings if (BUILD_PYTHON_WHL OR BUILD_PYTHON_SRC) add_subdirectory(python/pyarmnn) endif() armnn-23.08/CONTRIBUTING.md000066400000000000000000000063601446772241200151100ustar00rootroot00000000000000# Contribution Guidelines The Arm NN project is open for external contributors and welcomes contributions. Arm NN is licensed under the [MIT license](https://spdx.org/licenses/MIT.html) and all accepted contributions must have the same license. Below is an overview on contributing code to ArmNN. For more details on contributing to Arm NN see the [Contributing page](https://mlplatform.org/contributing/) on the [MLPlatform.org](https://mlplatform.org/) website. ## Contributing code to Arm NN - All code reviews are performed on [Linaro ML Platform Gerrit](https://review.mlplatform.org) - GitHub account credentials are required for creating an account on ML Platform - Setup Arm NN git repo - git clone https://review.mlplatform.org/ml/armnn - cd armnn - git checkout main - git pull (not required upon initial clone but good practice before creating a patch) - git config user.name "FIRST_NAME SECOND_NAME" - git config user.email your@email.address - Commit using sign-off and push patch for code review - git commit -s - git push origin HEAD:refs/for/main - Patch will appear on ML Platform Gerrit [here](https://review.mlplatform.org/q/is:open+project:ml/armnn+branch:main) - See below for adding details of copyright notice and developer certificate of origin sign off ## Developer Certificate of Origin (DCO) Before the Arm NN project accepts your contribution, you need to certify its origin and give us your permission. To manage this process we use Developer Certificate of Origin (DCO) V1.1 (https://developercertificate.org/). To indicate that you agree to the the terms of the DCO, you "sign off" your contribution by adding a line with your name and e-mail address to every git commit message: Signed-off-by: John Doe You must use your real name, no pseudonyms or anonymous contributions are accepted. ## In File Copyright Notice In each source file, include the following copyright notice: // // Copyright © ` ` and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // Note: if an existing file does not conform, update it when you next modify it, as convenient. ## Releases Official Arm NN releases are published through the official [Arm NN Github repository](https://github.com/ARM-software/armnn). ## Development repository The Arm NN development repository is hosted on the [mlplatform.org git repository](https://git.mlplatform.org/ml/armnn.git/) hosted by [Linaro](https://www.linaro.org/). ## Code reviews Contributions must go through code review. Code reviews are performed through the [mlplatform.org Gerrit server](https://review.mlplatform.org). Contributors need to signup to this Gerrit server with their GitHub account credentials. Only reviewed contributions can go to the main branch of Arm NN. ## Continuous integration Contributions to Arm NN go through testing at the Arm CI system. All unit, integration and regression tests must pass before a contribution gets merged to the Arm NN main branch. ## Communications We encourage all Arm NN developers to subscribe to the [Arm NN developer mailing list](https://lists.linaro.org/mailman3/lists/armnn-dev.lists.linaro.org/). armnn-23.08/CONTRIBUTING.md.license000066400000000000000000000001531446772241200165230ustar00rootroot00000000000000# # Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/InstallationViaAptRepository.md000066400000000000000000000230241446772241200210430ustar00rootroot00000000000000# How to install ArmNN via our APT repository on Ubuntu's Launchpad * [Introduction](#introduction) * [Add the Ubuntu Launchpad PPA to your system](#add-the-ubuntu-launchpad-ppa-to-your-system) * [Outline of available packages](#outline-of-available-packages) + [x86_64](#x86_64) + [arm64](#arm64) + [armhf](#armhf) * [Install desired combination of packages](#install-desired-combination-of-packages) * [Installation of specific ABI versioned packages](#installation-of-specific-abi-versioned-packages) * [Uninstall packages](#uninstall-packages) ## Introduction These are the step by step instructions on how to install the Arm NN core, TensorflowLite Parser as well as PyArmNN for x86_64, Arm64 and Armhf for Ubuntu 20.04. The packages will also be added to Debian Bullseye, their progress can be tracked here: https://tracker.debian.org/pkg/armnn. ## Add the Ubuntu Launchpad PPA to your system * Add the PPA to your sources using a command contained in software-properties-common package: ``` sudo apt install software-properties-common sudo add-apt-repository ppa:armnn/ppa sudo apt update ``` * More information about our PPA and the Ubuntu Launchpad service can be found at [launchpad.net](https://launchpad.net/~armnn/+archive/ubuntu/ppa) ## Outline of available packages We provide a number of packages for each architecture; x86_64, aarch64 and armhf as outlined below. ARMNN_MAJOR_VERSION: This is the ABI version of the Arm NN source that has been packaged based on include/armnn/Version.hpp. ARMNN_RELEASE_VERSION: This is the marketing release version based on the date source was released on github e.g. 20.11. PACKAGE_VERSION: This is the version of the source package used to build the binaries packages from. ### x86_64 * Runtime Packages ``` libarmnn-cpuref-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb libarmnntfliteparser{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb libarmnn{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb python3-pyarmnn_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb ``` * Development Packages ``` libarmnn-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb libarmnntfliteparser-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb ``` * Dependency Packages (These are empty packages that provide a user-friendly name for other packages they will install) ``` armnn-latest-all_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb armnn-latest-ref_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb ``` ### arm64 * Runtime Packages ``` libarmnn-aclcommon{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnn-cpuacc-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnn-cpuref-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnn-gpuacc-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnntfliteparser{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnn{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb python3-pyarmnn_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb ``` * Development Packages ``` libarmnn-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb libarmnntfliteparser-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb ``` * Dependency Packages (These are empty packages that provide a user-friendly name for other packages they will install) ``` armnn-latest-all_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb armnn-latest-cpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb armnn-latest-cpu-gpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb armnn-latest-cpu-gpu-ref_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb armnn-latest-gpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb armnn-latest-ref_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_arm64.deb ``` ### armhf * Runtime Packages ``` libarmnn-aclcommon{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnn-cpuacc-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnn-cpuref-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnn-gpuacc-backend{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnntfliteparser{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnn{ARMNN_MAJOR_VERSION}_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb python3-pyarmnn_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb ``` * Development Packages ``` libarmnn-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb libarmnntfliteparser-dev_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb ``` * Dependency Packages (These are empty packages that provide a user-friendly name for other packages they will install) ``` armnn-latest-all_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb armnn-latest-cpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb armnn-latest-cpu-gpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb armnn-latest-cpu-gpu-ref_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb armnn-latest-gpu_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_armhf.deb armnn-latest-ref_{ARMNN_RELEASE_VERSION}-{PACKAGE_VERSION}_amd64.deb ``` ## Install desired combination of packages The easiest way to install all of the available packages for your systems architecture is to run the command: ``` sudo apt-get install -y python3-pyarmnn armnn-latest-all # Verify installation via python: python3 -c "import pyarmnn as ann;print(ann.GetVersion())" # Returns '{ARMNN_MAJOR_VERSION}.0.0' e.g. 33.0.0 ``` This will install PyArmNN and the three backends for Neon (CpuAcc), OpenCL (GpuAcc) and our Reference Backend. It will also install their dependencies including the arm-compute-library package along with the Tensorflow Lite Parser and it's dependency Arm NN Core. If the user does not wish to use PyArmNN they can go up a level of dependencies and instead just install the armnn-latest-all package: ``` # Install ArmNN Core, CpuAcc Backend, GpuAcc Backend and Reference Backend as well as the TensorFlow Lite Parser: # (This will only install CpuAcc and GpuAcc Backends on arm64 and armhf architectures) sudo apt-get install -y armnn-latest-all # Install ArmNN Core, CpuAcc Backend as well as the TensorFlow Lite Parser: sudo apt-get install -y armnn-latest-cpu # Install ArmNN Core, CpuAcc Backend, GpuAcc Backend as well as the TensorFlow Lite Parser: sudo apt-get install -y armnn-latest-cpu-gpu # Install ArmNN Core, GpuAcc Backend as well as the TensorFlow Lite Parser: sudo apt-get install -y armnn-latest-gpu # Install ArmNN Core, Reference Backend as well as the TensorFlow Lite Parser: sudo apt-get install -y armnn-latest-ref ``` ## Installation of specific ABI versioned packages Due to Debian Packaging requiring the pristine tarball from our Github release, the version on Launchpad may not align with the released version on Github depending on the complexity of newly added features. In order to check for the latest available Arm NN version use apt-cache search: ``` apt-cache search libarmnn # This returns a list of matching packages including versions from previous releases libarmnn-cpuref-backend23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-cpuref-backend24 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-dev - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnntfliteparser-dev - Arm NN is an inference engine for CPUs, GPUs and NPUs # Note: removal of dash to suit debian naming conventions libarmnn-tfliteparser23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnntfliteparser24 - Arm NN is an inference engine for CPUs, GPUs and NPUs # Note: removal of dash to suit debian naming conventions libarmnntfliteparser24.5 - Arm NN is an inference engine for CPUs, GPUs and NPUs # Note: removal of dash to suit debian naming conventions libarmnn23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn24 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn25 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn30 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-aclcommon23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnnaclcommon24 - Arm NN is an inference engine for CPUs, GPUs and NPUs # Note: removal of dash to suit debian naming conventions libarmnn-cpuacc-backend23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-cpuacc-backend24 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-gpuacc-backend23 - Arm NN is an inference engine for CPUs, GPUs and NPUs libarmnn-gpuacc-backend24 - Arm NN is an inference engine for CPUs, GPUs and NPUs # Export the ARMNN_MAJOR_VERSION to the latest visible e.g. libarmnn30 to allow installation using the below examples export ARMNN_MAJOR_VERSION=30 # As the Tensorflow Lite Parser is now ABI stable it will have a different version to ARMNN_MAJOR_VERSION please choose latest version: apt-cache search libarmnntfliteparser # Returns e.g. libarmnntfliteparser24.5 so we then export that version, for reference this comes from include/armnnTfLiteParser/Version.hpp: export TFLITE_PARSER_VERSION=24.5 sudo apt-get install -y libarmnntfliteparser${TFLITE_PARSER_VERSION} libarmnn-cpuacc-backend${ARMNN_MAJOR_VERSION} ``` ## Uninstall packages The easiest way to uninstall all of the previously installed packages is to run the command: ``` sudo apt-get purge -y armnn-latest-all sudo apt autoremove -y armnn-latest-all ``` armnn-23.08/InstallationViaAptRepository.md.license000066400000000000000000000001531446772241200224620ustar00rootroot00000000000000# # Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/LICENSE000066400000000000000000000020551446772241200136610ustar00rootroot00000000000000MIT License Copyright (c) 2017 ARM Limited. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. armnn-23.08/LICENSE.spdx000066400000000000000000032731171446772241200146520ustar00rootroot00000000000000SPDXVersion: SPDX-2.1 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: armnn DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-785b703b-da92-41e9-983f-49a5a3b5e86f Creator: Person: Anonymous () Creator: Organization: Anonymous () Creator: Tool: reuse-1.0.0 Created: 2022-08-03T11:04:56Z CreatorComment: This document was created automatically using available reuse information consistent with REUSE. Relationship: SPDXRef-DOCUMENT describes SPDXRef-6023602810befa9adda44114844d090b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2716bc1ed4229fa725d3289dfebf305f Relationship: SPDXRef-DOCUMENT describes SPDXRef-950af7814f60dff224a7339016ce4409 Relationship: SPDXRef-DOCUMENT describes SPDXRef-18a4ee19fb06cc5465a5fcc777a7a952 Relationship: SPDXRef-DOCUMENT describes SPDXRef-55f81d8bea83439b3f936bdedcc55a94 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d83608cde56b57c282a0a44afa00afca Relationship: SPDXRef-DOCUMENT describes SPDXRef-222d74ae2fe2f2148ce9a94df369b13f Relationship: SPDXRef-DOCUMENT describes SPDXRef-6183423a33583910cd705460e23d1c2c Relationship: SPDXRef-DOCUMENT describes SPDXRef-147dd65486ab91d9c3c92070f0bfdeb0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d19cb67c02cdc8f9c00eeb76fdcdd134 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b64916999b60ed22cbccc11a6b816c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-baad5b3523a8732aacdc1fe3cf64b04a Relationship: SPDXRef-DOCUMENT describes SPDXRef-624364757b1697c1a55b6b60e3e55fa2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-18349d5ab3dd6391bf5d61a0c2755d4f Relationship: SPDXRef-DOCUMENT describes SPDXRef-377c55a4be6c94fa2b9813a0f36bf4a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc5969daa319b470977a431a00cf4f16 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5c6ee2ac2ba1893a37eefb34fed2d71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-eb36eacc7b9241e70c9f54516582420f Relationship: SPDXRef-DOCUMENT describes SPDXRef-837a18c08c2d04bb81ddaffa8b84dcbb Relationship: SPDXRef-DOCUMENT describes SPDXRef-8bf0f42e05bcafbe435014031da15e8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-fe28f70021fc8da11eff54d9b99dda13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6a5e70f15dac6fb31fe98ef5645ff7f5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-28a54198bdc3b3a27c17ccb11cf71ac0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ba7bc52c8ce23c3e0b1fa5009f4a281e Relationship: SPDXRef-DOCUMENT describes SPDXRef-0b3b6e0c108eaad7768baa8b7379d3ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-c93fb1fdc823b6a2b8b761652ce430df Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f70d3aecd124d339e737b57b30a2b03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-27f40b5508c15da36b82f53a064224c0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6fb27b4a8e2df11b17c4d762de6a4f0e Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d7a95debcae6d157134aefb80304d46 Relationship: SPDXRef-DOCUMENT describes SPDXRef-39551805529c27b1bde13eeac9f464d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a747183d7e76019a303746173439a8e Relationship: SPDXRef-DOCUMENT describes SPDXRef-ef0fcbdeb8b53fba3ceeb78cbe4712fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-709f9d106a488d4d928768b4331d61d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b85668a909962a920c0c42a64d92cde Relationship: SPDXRef-DOCUMENT describes SPDXRef-ddef91242442f6595d3a45f59f2a5019 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e4acb3b492847bcb1ada1739967ab9fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-5732785cadaee05bc465316a2d754b19 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bea5ea61fccab687697623bafc6db9f Relationship: SPDXRef-DOCUMENT describes SPDXRef-be771c115b82534d5f584e73a007dc89 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f696c863191a010480fffc433fa358d Relationship: SPDXRef-DOCUMENT describes SPDXRef-18d7d8a7f0d763775bc479aab1826b34 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3937c3ac76264ae6724e690dd5af86d Relationship: SPDXRef-DOCUMENT describes SPDXRef-e96002734486b25a5b013442b5d2a811 Relationship: SPDXRef-DOCUMENT describes SPDXRef-93231a98368d89d6823f74713db1f290 Relationship: SPDXRef-DOCUMENT describes SPDXRef-46a6f10f158b9ed5856bbb3cc1f0c25b Relationship: SPDXRef-DOCUMENT describes SPDXRef-7b07232ebe2e964cc1cbce447038dce4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d2648cdc71a540081e07cdc3b03e8df Relationship: SPDXRef-DOCUMENT describes SPDXRef-071e82e8bb410f4c032b63e850c32107 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4b32a296696c454a45be5c23969d14b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-03e556e023a69eaabddaa30fc6530d38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-622f38ccb8fb6927bd8f67f4bdbcb221 Relationship: SPDXRef-DOCUMENT describes SPDXRef-17ba82a7b80069147634ee0382974ee4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5786ab28ea5251eacbee1d6141c60729 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cbcb0020dc4202e20387760b79b7ac97 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bee44d419a0009c6fe4163410125de26 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5143e1ba9a1a741f7741082fcf0e51f4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d0e559795ded1fcf28b88b030b810ee Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1160acb8390cca7883d8433394885a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4023b843f1902d5032b089fd6433bb62 Relationship: SPDXRef-DOCUMENT describes SPDXRef-406a32dc2822989afc2fa1016dcd8c3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-2aa5d544cd83b88d036985eb4985c8f0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-56b57976e6c0023a433d2bf784354107 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c865759124054b3d9690988201d8667a Relationship: SPDXRef-DOCUMENT describes SPDXRef-fd34fe8f3eb5f64ee8d05455210dea4d Relationship: SPDXRef-DOCUMENT describes SPDXRef-95e5230322cdbb3298467a2be714913c Relationship: SPDXRef-DOCUMENT describes SPDXRef-ecae718d841d0f1c62f8154380fc4a74 Relationship: SPDXRef-DOCUMENT describes SPDXRef-316796d5f95d41cf2fcf278927a0c260 Relationship: SPDXRef-DOCUMENT describes SPDXRef-291ec06a8c517a515acdd55cf24e59bd Relationship: SPDXRef-DOCUMENT describes SPDXRef-924090d4e3413fc1179413ac15b164dc Relationship: SPDXRef-DOCUMENT describes SPDXRef-07f3e43e6d6e4da5406b4e6c0737eef6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c084d7ac60b0ff4712e93b1b6b60ced Relationship: SPDXRef-DOCUMENT describes SPDXRef-aca1b95401a3aac6cc5f0cc46dc46e1e Relationship: SPDXRef-DOCUMENT describes SPDXRef-78cb088cdd94ea053448965d05689f90 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c831b02c9e058829ebc7346620f5116 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5745d1a6674b29e4ff881abec8d38c71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-eca91d2e0dbf9b3168db1e62453189d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4958234547c5cc90197188e6ecc74a8b Relationship: SPDXRef-DOCUMENT describes SPDXRef-7150428d6f37f43ed75ee835c2704c40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-049f74820d880d1ae61c7219b0167324 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a2f8ecc27add60cad8366093fe4aee71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-463407f93e084b215c320458df46f0eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-af05cb4be78868615c7c7c8be1d7b349 Relationship: SPDXRef-DOCUMENT describes SPDXRef-92df2be7e6eb31b4bd219c4b5cfd2e2e Relationship: SPDXRef-DOCUMENT describes SPDXRef-844e7b6e8c7ac58794aba524e225b3fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4e6819ba8c783e8d61000961d6079b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-56a39190072e6e1e8f7ae254890d8f8b Relationship: SPDXRef-DOCUMENT describes SPDXRef-64fc2c3597c2c14a4a6477e327775fb7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5df350fbaacdaaf0f999b7996b645e54 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ca734a01fe1aaf500e8043484c2286f Relationship: SPDXRef-DOCUMENT describes SPDXRef-3fe4679a0bfa445267ff49c2e98c34f2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49051496a1f4201851f3b575b9666b28 Relationship: SPDXRef-DOCUMENT describes SPDXRef-21cf587d1f2798224603c389255053c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8366eabf4bc5729a5cb9f21f0d84a60a Relationship: SPDXRef-DOCUMENT describes SPDXRef-db9041313278b52d7adbd65baebeaac7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ccafb8b8a72ea8b2ebce72e75350a322 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6bda2fb8f15053f556ba3a0dffb38f6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec712171c20b1ac911d33be000dc8f31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4196333956958db71dc86c223d27c1a Relationship: SPDXRef-DOCUMENT describes SPDXRef-b6e2b30853335edb9ceeede889b34389 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae594ffb7c7abd1c3cbea16ee41d6c5d Relationship: SPDXRef-DOCUMENT describes SPDXRef-14dfc132136b3d36e46dfe929169d334 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bc09f6047661cfcd37757c28c7c70cd7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-340cd15c249a2725c5acbb5adec79227 Relationship: SPDXRef-DOCUMENT describes SPDXRef-69d2291d0a4842922cafd2f9ff4e5f01 Relationship: SPDXRef-DOCUMENT describes SPDXRef-23925a9b93bff0e7bd227e9fcb09557a Relationship: SPDXRef-DOCUMENT describes SPDXRef-31c5df0fb286e66f02569de52b7ef66f Relationship: SPDXRef-DOCUMENT describes SPDXRef-b4eecc848bcb4f388e048784a7e51a83 Relationship: SPDXRef-DOCUMENT describes SPDXRef-275732a24d049c6bce713dc7ef378f91 Relationship: SPDXRef-DOCUMENT describes SPDXRef-84afdb4424efd7a623be68e04b7be3d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-be075a7f0e34ab7a8e642c815c1e15c7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ba22d347607084af53cf9672b396153d Relationship: SPDXRef-DOCUMENT describes SPDXRef-4d764f9c61f9d125a1b67be237f43d98 Relationship: SPDXRef-DOCUMENT describes SPDXRef-697abc821c8ccf65314d232cbe844fab Relationship: SPDXRef-DOCUMENT describes SPDXRef-16e51c8a37943e3bf9321f1441fdb03d Relationship: SPDXRef-DOCUMENT describes SPDXRef-81bac3d810e573c0a0cd0f3f97575477 Relationship: SPDXRef-DOCUMENT describes SPDXRef-462eafd975bf8ee032199ef82b4713ff Relationship: SPDXRef-DOCUMENT describes SPDXRef-01b3fbb9cf5c27b7a2b98d6077099968 Relationship: SPDXRef-DOCUMENT describes SPDXRef-035d490690a1e863176c07eb838192a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ebe84cb3f475aae8a50bc5cd27004d51 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d09b93ffe6d1d7cfe9bb310dcc027ee2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cc5d8b58bd11a8f69569d3b65a7cac0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d15f67108c8007f5d00422b4c3ebed6a Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf0ceaf275f52bfc9be22e4361d6bd72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-808b601fbe330720c395297a3114bdb4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-be5ea2a16e6d10c74c147ced503cb132 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b406acd762ee51208dfaa86a474cbf07 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1fca025261962e59aae7801d93cae29 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8b128c1224edc70fe4741bbd19ded421 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8525c5833f9bd8b29c5ece83bb202a50 Relationship: SPDXRef-DOCUMENT describes SPDXRef-52d250b4efa1948c81a9ac051395dcdf Relationship: SPDXRef-DOCUMENT describes SPDXRef-88c9bf9f48a98f824c7cd1ff1bb54225 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15e8abd5f62204a48a56ca5907c28682 Relationship: SPDXRef-DOCUMENT describes SPDXRef-811c839d4968cc46366abea465daff4d Relationship: SPDXRef-DOCUMENT describes SPDXRef-2f539be802a8c3735adb533dab8d75b9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-655680fa059cc25c9e64b87f30e1c0df Relationship: SPDXRef-DOCUMENT describes SPDXRef-890e048054559d3eca2c323e480a76ae Relationship: SPDXRef-DOCUMENT describes SPDXRef-5765c2772e5c5dac4e589eac7735c8a1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7a2226e756c37fa3bbd6562333fa4dfd Relationship: SPDXRef-DOCUMENT describes SPDXRef-6a512b79ad312257c596762cf75bfb6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-93ffa49b856ce7c43aaf27c6ec2d9ff5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2268a2edbc30628438f92498de2225e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ee74e4cb09a2df299d7c15e35d2f508 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3ac40bc6995be55bb77c516e0f322289 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c02a53c0dff3cc467a77860778f458d Relationship: SPDXRef-DOCUMENT describes SPDXRef-2782f9d13151eb4bda656218b9310314 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9da8f34b430b73ca05040b633ab40c5c Relationship: SPDXRef-DOCUMENT describes SPDXRef-a0d9ef5c4147a64677c95837dbf6bb06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4e6472d2fb27fb84a9a93987cd978b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-02f7fc1615e16121fa5e9ecc4fa90369 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ccd283c7232315fb5065dfa3aa4bf38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e67a57918c5cd6579a56c602488857b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b13af8e00647bca576af50bf50a1325f Relationship: SPDXRef-DOCUMENT describes SPDXRef-bd7014edfd08a7bc79a3f81fd846469c Relationship: SPDXRef-DOCUMENT describes SPDXRef-b06c380b204a3b86849d8a2c8f202a9a Relationship: SPDXRef-DOCUMENT describes SPDXRef-c9eb58b9d7797576c0c3e1c321eedebc Relationship: SPDXRef-DOCUMENT describes SPDXRef-984a0d4f1ec03b12233e724bb2a74c6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5314ce79cc4fdef8e604d5c2964e440 Relationship: SPDXRef-DOCUMENT describes SPDXRef-18cb53a29a306d727ab50cb29029cc8c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f931dbf85dcf823e7cf46e8383434997 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0587b7e6e3de22163a1faec89c338dec Relationship: SPDXRef-DOCUMENT describes SPDXRef-57bf9804a831c590b5dfce98bd1019eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-25ff29be8d645f810109a115e3d1ad5c Relationship: SPDXRef-DOCUMENT describes SPDXRef-bb9b3cf242e8bbffe31055afabc0829e Relationship: SPDXRef-DOCUMENT describes SPDXRef-374eb3d1f119fc3e634c384c6eb017ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-06f335742c9a044e83f4fa0cc9d69463 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57a5d58a596f1e1a29700867e5f221b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6587800e04e080cb263c70a74a19dff Relationship: SPDXRef-DOCUMENT describes SPDXRef-48789b43da1cf1605daaaa28eafe8eca Relationship: SPDXRef-DOCUMENT describes SPDXRef-7f090eb5a694e55199ac6f8a9d0971e6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-44a506056cad10c6440448784d242bdc Relationship: SPDXRef-DOCUMENT describes SPDXRef-d91f0c74b941c8c204132e416a01775d Relationship: SPDXRef-DOCUMENT describes SPDXRef-bec604c530385a921bda5e874e1a38c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-37da0792772e2f9ff20ef7a113570008 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4fac56c74732c64c327d1965e27e7bba Relationship: SPDXRef-DOCUMENT describes SPDXRef-81e0456179fe12b28b775a00a5a63085 Relationship: SPDXRef-DOCUMENT describes SPDXRef-df7c8edbac51d09228a43de731b92f1a Relationship: SPDXRef-DOCUMENT describes SPDXRef-c033ab1056d66e0389d2e895e04b615f Relationship: SPDXRef-DOCUMENT describes SPDXRef-b03496ca75b63bc9d91cf7a7f3994198 Relationship: SPDXRef-DOCUMENT describes SPDXRef-20634915d2bb89e51171a3057f63351a Relationship: SPDXRef-DOCUMENT describes SPDXRef-c6e3b4efaae6ef86e9668a3af1d53b33 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d8b2bf119a8934cd2c43eabf91eab15 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5848bd50e9f7a20e35e9f245b22c2b60 Relationship: SPDXRef-DOCUMENT describes SPDXRef-453d464178066a4e9ae36723f23e809a Relationship: SPDXRef-DOCUMENT describes SPDXRef-85842a0f8479bab19864a5228e4dd62b Relationship: SPDXRef-DOCUMENT describes SPDXRef-52b61cf31f6cdff85940f7ccc22db2c0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9626375a8f997ba0ff64aa61fc4a44cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-3aa611584eeefa99aa279c52da94ece9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aae546393bc61c2c810011fc28e17ce7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bcbc423beaab4bd2e5553b1849c4cb0c Relationship: SPDXRef-DOCUMENT describes SPDXRef-b4807d1bbfb169bc26f9f8bd0549f2ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-4e249be5d144050575fbc333f19cf686 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea1f65529a7b258fd23c70715fdd1df0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7915ab1fdec123e081bb1671cfabb9c Relationship: SPDXRef-DOCUMENT describes SPDXRef-4b434569c913eb9a1b6595c6fd1324a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b93410f72f6f79cd4239ff887cddfeae Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c76aa97157521116d548dbb2078d300 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6d2a7e7db6e4a8824855699f8e839b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c90c111fb5cdac15a06abf18cdf0d026 Relationship: SPDXRef-DOCUMENT describes SPDXRef-74f8f81276b72c31c5c9e4960c4d2bd4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2184e5a0708aa766db8bc52fc1aa097b Relationship: SPDXRef-DOCUMENT describes SPDXRef-22b84d3e68ab310b3b12346e20682d86 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9713f4401c136b86a5364c9a6e949ab3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-036dfa4e9e7030701f3c0800c0b34857 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c929da3941cd5206297d3f71f3dc1268 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3e59a6808e6542798641b279db567a8c Relationship: SPDXRef-DOCUMENT describes SPDXRef-85347965817dee49a9069f95a0c7bf3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0fd0a0708b67bf47e4a3128423377a1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-669360bec941715162189513323f0f80 Relationship: SPDXRef-DOCUMENT describes SPDXRef-daf59ac41d0b66841c4789bf2bd6d5d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-577ed1a12b84ba0442f86bd4996ea0d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fd56004c5d665eb6aeead560cd7b4490 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4b207205c0f2f00f82391795948dc3ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-73367e08d231bc73927d040b015c78ed Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c5b6742097135a450794635d7e5260e Relationship: SPDXRef-DOCUMENT describes SPDXRef-0d822d1bea653177d7e3ef8eaa2f4468 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a34ebf679d2f81db779a1812bd48ffe6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c911e958306740e8bef1e84896a7cb6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-017dd91fe47c63b7a552a5934330cfa5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f4c9275a97afc4ea7d0d75b6ad9adbc Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae1fef0339e823ea7e8030ef8c7deb2f Relationship: SPDXRef-DOCUMENT describes SPDXRef-1bba16495ec65feeffb3853091382b0d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1ff699ace677280b40567ee697615ddb Relationship: SPDXRef-DOCUMENT describes SPDXRef-497156755db3505a3ffccd3d9b240359 Relationship: SPDXRef-DOCUMENT describes SPDXRef-27574b1eb008ee594b123d29dd1f41eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-2fd65619ad7b409d9bf8ebea3930e0b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ae94cc7bdbaa65761ff4567fbf36ed7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-16d0f893b7265a5457d195b7eb50cce0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-73f8b2f0169be050bd2b7b9da83f303c Relationship: SPDXRef-DOCUMENT describes SPDXRef-5a316e248fe3597da659d1f1fbabefa3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a48cb12197a0726592257392cb1cad5a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d01077cb2b0910bc9394f3e4068a1a42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d603625141db81a72febe03ad2e6190 Relationship: SPDXRef-DOCUMENT describes SPDXRef-09fede25e361a4ce406f7032d16f62f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5077449105c25abaf6df95abc76ba6cb Relationship: SPDXRef-DOCUMENT describes SPDXRef-b77f66fea01de3d0f2eb509a2096f3e0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a49a9897137d941aa55fd88afa662124 Relationship: SPDXRef-DOCUMENT describes SPDXRef-369c086f736b8d2ff6fa9bd07bce2334 Relationship: SPDXRef-DOCUMENT describes SPDXRef-de89fb90c1c7ceccc35912042bf489b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49d672e33f88b03d7179107cea51b101 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fd406362ae9c920b71b40fc357ae7d3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ba4b7c394a35cc307370bffde1185a8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f28a05edf58c48af1c0775bc205a068d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b87822b94e48dcce298a3570da14e261 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c5e73a6b9f8a21363ece108c74abcad Relationship: SPDXRef-DOCUMENT describes SPDXRef-7314042d5aa20cf334534f3fb4666b4a Relationship: SPDXRef-DOCUMENT describes SPDXRef-870d9a794100998cb559e4466fb9edd0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-24c5615c7d4446cb7366553efc547612 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7f8cb4e693f95b08b6a56a3e61354a6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-f4d555dc139c4a0981a6e3f4ec973c06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-288b0d422410ca1289b5a26fc3fca0db Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5f60c986c236d55b8cba5c7724d13eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-7871ccaeeeba454dc55f356c6e274803 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8647a0ec290d43201ccbe8453d63fdfd Relationship: SPDXRef-DOCUMENT describes SPDXRef-1bae5332b46406efa7647c95b14d5b78 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8174f588ce851fd76a22ee8cf033e6ae Relationship: SPDXRef-DOCUMENT describes SPDXRef-d90085e5a9c43293fbd7a4644de3f318 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8312df544d22f63dd1ee7e82dcb26345 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fc3b8df0ca788749dfb47c1ba7516053 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f42be57e940025f214e294e8250892b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f8bb51ad000201418d0593aa0d15e27 Relationship: SPDXRef-DOCUMENT describes SPDXRef-25f6f26f20c41a8d22c6e80c8410b194 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e963f7dd8a5af36677f4af4742411dd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a7852ed6c24a170a7dfa613831cc3b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8fc984e236dc65f646facb2fa5b9a55 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bfc4900c50d1d0afcfb2475636b82e50 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bbf3fe9206794b5709ad1afb1c851628 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2477be897381a899a3ffc2e170fdf0a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0dcb8d5f79927858bc200f22b097ba57 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6291a3e21e5d8dbcd16a048951054175 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b61c74e3864d89a40018e2068b07438 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a09f95a7326eea1266468fe0c131abec Relationship: SPDXRef-DOCUMENT describes SPDXRef-95493cb4194c83fdba4c6695322d380c Relationship: SPDXRef-DOCUMENT describes SPDXRef-aa6b8effac65b9a35b095764ce97b693 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57d4ca46eb1c9223869b5f331d1e21e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c7e1332f04c488b7effccaa244a68eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-0105038ada8320c2f3155c268e81ddf4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0d4767dc06f6001d99bd55b314d4a93 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fd7fb35e094198556d9aeff9d539f329 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3012262ada3561e8506cd1727cf3930 Relationship: SPDXRef-DOCUMENT describes SPDXRef-350dcf5fd8e3d13311db13b6b89246de Relationship: SPDXRef-DOCUMENT describes SPDXRef-87989149cd3c9d0d90bd934a4ce0a512 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ab5411faa5653b8afa3bafeb56d86994 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6c933f9de0c920d3296acfc51cfe73a Relationship: SPDXRef-DOCUMENT describes SPDXRef-40c4507c86bc4320e48fc906204b1e55 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3793f660e284ceed388c0fed4005fb5d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f6456dd8260bd35814858ba8478c4f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8bb768841df3744610ac08d923eff4d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d6ab6e439ebe39368e8ef8c541c1b3c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9c8efda9a1671e6875706ee02c0157d3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8f26b3663f06d13ae91d27b7fe5b5ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-c21ca4db0ae181f149f1a69c013424d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-507757364c56fba7ef9614968b2025d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea39992153a0cf67010b33227cfbce31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ecdde789f6e0810712b37b3a5e3a5e5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-491a8bd6dbf907c25d899f3b701b76d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3eeeb9b5be756cf90676dc11e9a3aa9f Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d61509f283b695c1ca4135e7b5e6cda Relationship: SPDXRef-DOCUMENT describes SPDXRef-2ecc6aabfa87d2d56172f9db42de1d07 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1bddaa7ad081b0828846a924fb079a8c Relationship: SPDXRef-DOCUMENT describes SPDXRef-9456bd83018d840c63b8133088c62aba Relationship: SPDXRef-DOCUMENT describes SPDXRef-0b8755f199ecf80a6f2525d7bd6ad524 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7466252420314d39314cfba125fcd7d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-372901489c127b649ed9dce4e2c77b1d Relationship: SPDXRef-DOCUMENT describes SPDXRef-203d47f20e482a108d38f8a7a36c6a60 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ffe1adeb0c86f8b21d7b381f5c7fd7e7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c114312cca7401bab2a45a63de92b3b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57099a78548ae165561e9f6be2384b03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c68107bd3f55d8722d3f642b22e6437 Relationship: SPDXRef-DOCUMENT describes SPDXRef-809948d3d959068fe40be1513ae1de5e Relationship: SPDXRef-DOCUMENT describes SPDXRef-417502f7717fb4dede7a3dd0d82ade65 Relationship: SPDXRef-DOCUMENT describes SPDXRef-53f921512e218e6c177c1af8f643853b Relationship: SPDXRef-DOCUMENT describes SPDXRef-bb93b6234c7527c5df98038f75f0d8be Relationship: SPDXRef-DOCUMENT describes SPDXRef-8ee87e342cfec8c857806162e2661d6f Relationship: SPDXRef-DOCUMENT describes SPDXRef-aef07b02cea4fcca79ef15ae82b18084 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d92c16efad6846e086ec1ebaff4ec54a Relationship: SPDXRef-DOCUMENT describes SPDXRef-8386cdb406dec88a8ba9d7318772463b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d3ce28732264f66fb50dbaf29875f10 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2c12c86031977a5b5a0dcba8109e977 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c433342e4f80f442f6ef20b2b2501ab Relationship: SPDXRef-DOCUMENT describes SPDXRef-052bbf27cf3b1420b3f60287a0d1c840 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a497d4ddc2cb9fdc97767ce31ed06059 Relationship: SPDXRef-DOCUMENT describes SPDXRef-91d6731cb80d1048e03d3c17b735c7ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f5b8b810e047df7da0b5641698690ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca9f7d9fc1efb5429a1c594bb772b473 Relationship: SPDXRef-DOCUMENT describes SPDXRef-711c080ba3c98a074fad06cb50e5b6f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd599b8f7672c9c3bef1ffd4f2eba9e7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee5f165e945d51cf9bc330f31aadbc6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b8149bc848f3acb0cf532ac961a73112 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0621201d37684b8dae44188559f8f7c1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8af8a1d6cc0526474a0824358e66c93 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c53fc4ef8bb144a4e45a4fb0eada9eb9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ff4854d53696acae1e27b6fd12f29062 Relationship: SPDXRef-DOCUMENT describes SPDXRef-59582e2e4bb1b03582d04dd28a292f3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-b3f6c43a8a4d03311a792a3db94f4c13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a15f1fe8c6969839a7314a1d605d0091 Relationship: SPDXRef-DOCUMENT describes SPDXRef-37d4349306fba75126950b47e027e97f Relationship: SPDXRef-DOCUMENT describes SPDXRef-b9011353f40aa4f02af2be97bbb93a1a Relationship: SPDXRef-DOCUMENT describes SPDXRef-8515376c0712acecc1f899f5de64a6d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cae59145cf63ae2d26b71653fd50a67 Relationship: SPDXRef-DOCUMENT describes SPDXRef-022a3a87a77a951af94a928b1a82aae9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-71e73f6ccb13ea72e80535bbaf006d38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d9d96ac9596c6d07e81f6a0531f2df3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-657def78e8f0beb695b4363d3e56e3f2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea04bd7d16ff6d3db01413c23f304b68 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e5e1b9700534aded64ed53a7bd8c402b Relationship: SPDXRef-DOCUMENT describes SPDXRef-b093428329e47539dc8c6819441415e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-31e8b32609e4f65b6bcb9c1c6ea53ab0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-845bf920ebacbc90e426206bbbe15ddb Relationship: SPDXRef-DOCUMENT describes SPDXRef-1dde8c18f36c49d306b42fbf1608f4c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-254e06c2394f3ebcdd0e26b3be4514d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d13412476b4044f84cd18f53ca1c88d Relationship: SPDXRef-DOCUMENT describes SPDXRef-482b10939a13197e000c9abc18e5e51a Relationship: SPDXRef-DOCUMENT describes SPDXRef-6fc2788a79c37b02d999c42222aa68ae Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e3f7f85171a36512cd90c57e6b5bb72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-69685f924949f0f8e1c43ba3bc823ed3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0c8fb7205afb2bb2edcdcce11d14837b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a44c30bb360fcbe1235b0758438e8dfe Relationship: SPDXRef-DOCUMENT describes SPDXRef-04be48e5946c485cf69c5264d145a025 Relationship: SPDXRef-DOCUMENT describes SPDXRef-32940ec161aa36636984b06ce19d3b65 Relationship: SPDXRef-DOCUMENT describes SPDXRef-19f3d10b669fc4a9458180e385c1f9c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e12ce9ff1edd2016eff3f31023d0b586 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d3fb69c41fc6964ed9585070422aa06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ddde5096724350041ee7d45be5866e6b Relationship: SPDXRef-DOCUMENT describes SPDXRef-5668759438ea5da759e18a4b9d34bc88 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f23526b0528c1335d9cb8b0e2f9080bd Relationship: SPDXRef-DOCUMENT describes SPDXRef-f213ada95b133fa3eb2832352ee85f74 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0d73041a5c25d6c0ea7dbf25a2ffb2e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5d8219499ac3d1a662306d125ec442d Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca662aa7003632dcb30390a601100ce8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-afc4745bd774917800b18c6c954a0cf3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d224e55b2a950e7bd2476356b01565b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-005c486f067c4cc0e813b4b8f9f29f4f Relationship: SPDXRef-DOCUMENT describes SPDXRef-a0f63acb85b71ccc670969177087a662 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7075c998ec0ad4a94bc52768f8d4d4c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-149a2bdfefaf38845219bcea018a3ba8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d949605578db9eb80b3247f15e14bb0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-cceab02a6b447bd3ee80235d14cfb347 Relationship: SPDXRef-DOCUMENT describes SPDXRef-46f7ffe4598fb14832066bfebfa3152c Relationship: SPDXRef-DOCUMENT describes SPDXRef-44a673e49edb5f491ad61da44f0506d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-488ec9954e10f0c8dbbb2f995b9ff973 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e80b85f651f2966b95b46a932716fc3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-e8bacb542639aa0d6036fbcac5a0b7fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-8fc53488bc893a63739b5c8491e94661 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b15218ddc90b9e718bb43aa960c117ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-69a327b5a40641f124cb5916686a97e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-35497387c43cffab91c1e328860c3de7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7172d1972e0c5c2f7f226fabffa917c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-401aa962a93592e57d2051c1e4715f3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-388c55487c9b13aef42a652e9eb55017 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8aa2907f45d06cd9f750f1193e22e34e Relationship: SPDXRef-DOCUMENT describes SPDXRef-30c729db95c8e02829c05eca4190f220 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c21b207d7d1ee6f08d2d060a31f95742 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc76e4f3f6160e814066e074c2a853ab Relationship: SPDXRef-DOCUMENT describes SPDXRef-8fdb571f00520e9b48db689d40a37735 Relationship: SPDXRef-DOCUMENT describes SPDXRef-92fff58b3c98a372ac195a2cacb9c3c2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7f54604d7a67eba09565d340682a1c66 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3903e112cba5cc159fb362297954f07e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1b3858b97c1833d6689267dc2a0a559e Relationship: SPDXRef-DOCUMENT describes SPDXRef-4172c7df734de31388e829446b3c3ae7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4bebb5b63d40ded4138d36a2585f792a Relationship: SPDXRef-DOCUMENT describes SPDXRef-7a90d68dfb2b645dbb98e61756729a6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b3b4e2735e72cbd1a244e4a30a618b66 Relationship: SPDXRef-DOCUMENT describes SPDXRef-947dd198f1b01839241f02abd81ddd4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-76b759edaa01af2b9c7e1cc17437c78d Relationship: SPDXRef-DOCUMENT describes SPDXRef-af4cf847d2b4c16c4fe481f9d732d29a Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd689e9bbee3e6339afd6ef95e31f7a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bec59b455955e5de25fcdc64c3264064 Relationship: SPDXRef-DOCUMENT describes SPDXRef-365388e25532bbddd54c2dc699c94b9b Relationship: SPDXRef-DOCUMENT describes SPDXRef-672ddecb31077bab003b0c623503f3f0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-572a5c1ffac9d6d5dc7cb36900afefdb Relationship: SPDXRef-DOCUMENT describes SPDXRef-18e52a36289fc58e47d5f21a54a830dc Relationship: SPDXRef-DOCUMENT describes SPDXRef-229815858c494b3ebf0f8bd186b57ca5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9470c9e1f943a307c5eaf89d1ba77188 Relationship: SPDXRef-DOCUMENT describes SPDXRef-96df8eaeec5fa26ea69802e6eb5ce207 Relationship: SPDXRef-DOCUMENT describes SPDXRef-36a0b6f4cbdb2a027a50c319c33a87b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1e7333d3a692488a3eb0f02be17e5bee Relationship: SPDXRef-DOCUMENT describes SPDXRef-1262972ce58a600c8c72d2bde4ec42ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-20af0782d7f379f2969dd334c6ebc641 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4465e1c6a47b8b26cc921dbb17dcd8e Relationship: SPDXRef-DOCUMENT describes SPDXRef-497ffc94ef3b734ba4ef685cc1e00923 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca9dcf09ce7a78c71f743e8e17de56af Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e1ba53bb4d0bbf1c8d54371af7984ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-639428f22f5c0634702d4e4f74b6a594 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a00f83cb6e97e7098ebec8ecdb317d17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8a5018f5bf520f022f0284fcb0a45fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-4922e5d9cbfc39a4f349ee03f6cd6991 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5880b683ebe88769b0920cd8a43acad1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dacf18b7417605c58f0c95924e22ab69 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d3dbb9d55dfb2e69e53540d29090db85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2fba8fe2c6e55f7fd963ad4738541095 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a74b268d3cb8bc80c647c944caa51b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ab876cd140330d940188ae4b7e59de7d Relationship: SPDXRef-DOCUMENT describes SPDXRef-4e3a455ac22224a4886f3aa8df4a9be6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ede59973cd6325312506a61c5fb99528 Relationship: SPDXRef-DOCUMENT describes SPDXRef-befc0678b22a4b933e058978e018c7a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-39387ca0054ebb3deb42a7f21f7bb390 Relationship: SPDXRef-DOCUMENT describes SPDXRef-888af6ba8660cc1f771cf90b2a0cafe1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a48b38c149fab4b72079e904501128d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1d441556d8fc8de1734c1fca19e82034 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a3665f9392f50cda3cbc2e4cc6b133d4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee5b58f949a975b0b3d9e1f0447ca300 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a2a403dfc946f17220abf36e73274650 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d46b209457e0e564a2279733723eb7e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5084bf78c1e38d19616e994631cea31c Relationship: SPDXRef-DOCUMENT describes SPDXRef-138fb2007dac779817d743bfb7fe25e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c9e2f75d3fad2a801fe5f056145d99d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b421759201d2107dbec29d82741ddd07 Relationship: SPDXRef-DOCUMENT describes SPDXRef-052b8f0c6ce5a6b91c00e38e7ec7e28e Relationship: SPDXRef-DOCUMENT describes SPDXRef-89f74ef11f67c6dac90b69f87ff6d508 Relationship: SPDXRef-DOCUMENT describes SPDXRef-371de54e69a41e25a72f75f2bccf4e88 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b390edd3bec003039e5b1f42371c367 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9858839b87f00c57a2ad83e7e337a03d Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a0d98b1d672e625daebe620667b6894 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4919871e8239fb6be712350d9e20778a Relationship: SPDXRef-DOCUMENT describes SPDXRef-2da07eaf9c68bd74b1273ecf17362da4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a547bf4951b19ae7ad6ea1a248b6f960 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fce60349cd8bffca6f0b60676147a01e Relationship: SPDXRef-DOCUMENT describes SPDXRef-6e9ec2f78bbeab335a33339b1a0e355c Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d1e88659363ed7288e025e6f2e8cab4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4fd4a0f0bcb71ecb6a5027647e7da645 Relationship: SPDXRef-DOCUMENT describes SPDXRef-30c9ee7a0dce1116c8ce4c2fd2239e64 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b41038ba2d7e138d22f91254b5cdb1a8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cac41d3cc0553dc11edc7f4b7b22763c Relationship: SPDXRef-DOCUMENT describes SPDXRef-7928f2e3bf4360528fcca23ced62396a Relationship: SPDXRef-DOCUMENT describes SPDXRef-90ab4a23878dd16e3a776be58e001f83 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b4f79d389222cc6d229e2be6a203ea19 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ebc697b78555fed7c5f2e8a56851cf2d Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c2955bb4d2ad8c12ecd7780e8088c7f Relationship: SPDXRef-DOCUMENT describes SPDXRef-71644ab27228168938641c11d82bc426 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd7355e62e0a66783c05985b9ed45738 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87d51466e07ab3c217ffbfe6a01c1249 Relationship: SPDXRef-DOCUMENT describes SPDXRef-df073203a19a70080da785e926665ebc Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c722d0d709b74e10fe2a0f0f91aa9fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb9c5392e3a64e083a8f6d119a650d75 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8388ea018fdb79a95e3e7320cce01ba0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d066fafdb4a6021928e33b5d0d8234a Relationship: SPDXRef-DOCUMENT describes SPDXRef-81af5f57aa7f4c1505835c74aa2ba235 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2b8e97e7ee080b5f665025d04c581451 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c453741e60005dfdc0c5270429feaf09 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d5cd8a7a548222e39982edaf35d2268a Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd7ba0a86aa2c4da5851c4169cedd6e8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-16696d1de96c9f531db1447b487aaa74 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bae875f6d1f9581920ffa2c00c212072 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c22390f6c845e2ff98cf01e02fe02ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-8baab4251bbbc07534a6cf1662b2085c Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a8d0646054f104534b3ab4c0c5b3dcc Relationship: SPDXRef-DOCUMENT describes SPDXRef-dae95b6d38785b994bc2882ff507cf41 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f20ea45393b2162387c5d4996e0c7ea6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e06eb2ae5ce61c8ff0b463846b6db3a Relationship: SPDXRef-DOCUMENT describes SPDXRef-9947a6cc5149b2e24175f684df2c7618 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fb829195149705d43dc6cffbbdbb1e98 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82bcd6c81180fa526245bd1b26a2f4c5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bde9e6bdf8b63156d2814df29f1ef393 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e026f0b9db7299206c858ca345dfdac6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf68a0c206555030ddd829c8844787d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6646709040c57b775c2179b89e3d35d Relationship: SPDXRef-DOCUMENT describes SPDXRef-df4e04588464ef073a2d1af99151c18d Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a6797d0f2d351c80e7f28790f42110c Relationship: SPDXRef-DOCUMENT describes SPDXRef-53196a5a5f7e7cb214f522e171cf5e71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-22d147a786da158db7ca96e3374dc4f5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf22b0e4ffbbec5bf521665b369430e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f7afa3505b0d4d4d5d1517d1aab27dd2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-52435e0a7389b713f53fb5543a7e0273 Relationship: SPDXRef-DOCUMENT describes SPDXRef-db206dc4eccaf92ecc3fcac0496a38a8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a43c7af377209742221957eb094ca75e Relationship: SPDXRef-DOCUMENT describes SPDXRef-68e3103103d3d1b5d071543a0d6ed25f Relationship: SPDXRef-DOCUMENT describes SPDXRef-3281600fb4d1daaf20cabb006161804b Relationship: SPDXRef-DOCUMENT describes SPDXRef-68a65b5f5c244e4b940dc825fe964e80 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f71b0e1aec9215660cca8db257822af4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6cc9acb31b251b62ef3597f558374567 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7f5e9264e8d7fed5b18227695c13e9bd Relationship: SPDXRef-DOCUMENT describes SPDXRef-ff44429858ef02c5c450ca2987342d1d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a716e819b0fff85abca0605a576ac4c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e415800177f74d9257ab4e3c1445457 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ef5d74603f85e6d4397723ac3229ca01 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9cf78592246e686186cb0c217d3f3107 Relationship: SPDXRef-DOCUMENT describes SPDXRef-63f7bd113aff490ffa2c1b6382cff00b Relationship: SPDXRef-DOCUMENT describes SPDXRef-b0335bd8f38d05d7038cc593f07726e8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0cdb922f7d7ed906d3702946bec5acc0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c4b3ce6cc9e2e0a5992af8cce0415b02 Relationship: SPDXRef-DOCUMENT describes SPDXRef-989cb431b75059772fda5a9fa812051c Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a43b63a5e5ee302f24c2bca786b2568 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e2cb50b1b305501d2b6802919d6fdb7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-42dac01f930694a9cdba57562c45fd2b Relationship: SPDXRef-DOCUMENT describes SPDXRef-181b47701def10224441a14dd71533a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a81febdb9022caf0dcac23d298abbfd Relationship: SPDXRef-DOCUMENT describes SPDXRef-10758186651ab9a33cf1b4b6d51ff3d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ff005bb04364ce552bab414d95d3a86f Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b2845049fd1a8415e559b8dd81287b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e9af1258f3d861c5f4704da0af81383 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ddd23882c9cc0c4201bb2c8849509383 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7035514c0ddcb8e4acc1cc5ab1cfae9a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f4ce531a32f90497e860585698056d11 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c3594cd4b7a29056267323de24b613fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-f40537cb9837e0d95e07b578607bf0e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c264bcf2d29af1511b9a576b8ebbd7de Relationship: SPDXRef-DOCUMENT describes SPDXRef-00ef70819ad0e9fd2ec4d5f1462c1141 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8b2d833db3153d2513deded1110c5385 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c6f0d0a046d25283a06e6676e2dc9291 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bddb6be6ea0a238b40be6bc819d1ec93 Relationship: SPDXRef-DOCUMENT describes SPDXRef-27ae9304388ab829277c68a4ed2f6f4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-bac70bf29a3b92c6c3083ac7d8f6bb75 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dcbf8bd21e39e513d33898038837553c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f32f5a755e029e9fff3e2d68e35f501d Relationship: SPDXRef-DOCUMENT describes SPDXRef-d7501342edf76668a776121f3d228113 Relationship: SPDXRef-DOCUMENT describes SPDXRef-448edb9f6b007d095a74d7582d61b7b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2e810f156dd29a4e8cc181506623a65a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0e5791fe010460f23afd51ea0c2ca3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-999c44c06c037ab241af9972594910d8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb19a20311685f238f20de7fc3d9f497 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57414982d972203a4a5b15f4f3e10992 Relationship: SPDXRef-DOCUMENT describes SPDXRef-42b94778be5dc923fa2500632f83999a Relationship: SPDXRef-DOCUMENT describes SPDXRef-31b12eb924dbd0c582df04042001e766 Relationship: SPDXRef-DOCUMENT describes SPDXRef-51945e5eb97ea2f83e8b8f87bf7416fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-cbb068dde8b6eab4d40ca768bb139343 Relationship: SPDXRef-DOCUMENT describes SPDXRef-43d0efd536842b8965022f9aace24f06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4a96e51a1722acc182a5d8c94d1ed868 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2158d8a46473b9092893d20a0913c67 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8f01b197176d2129341e0f9a0315036f Relationship: SPDXRef-DOCUMENT describes SPDXRef-4be2c1f40857d13aff3120dd2c0bc3b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-00e03efe88ba3846363f1092b75bd4f4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-05f0d1345e86e49182b125c42a794285 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7b298bd7b7c07c17b7aaac744ed78b78 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8551b3ecbf1152e9a0499cc1db6102c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-601fde10e9f354d47a036d528ca8ecb9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e442df35b220df7e58156e4883dd860 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b63cb50adab6fcd5b8e56a6cf1bb171b Relationship: SPDXRef-DOCUMENT describes SPDXRef-920eb9d6db5b4847f95babfe51a9da64 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4cb68f5ca4149577b122a550f7265b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8e40444bc6632cc59c79dde8373edb99 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a1a6598a707689c554a7c43de8737b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d008fcac89e6de1fab26f11b68cb03e Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc91e39052fc2e69b27cdf951f8d7e82 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8076d4dde8cb05dc6d7ab8ab3f428cd2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d553a72d49ac5680603576088f70bbc Relationship: SPDXRef-DOCUMENT describes SPDXRef-df6d67a34e1c5aca69631e329bf1b347 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd660cbb1408c02f8b84736cd75ad0b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-beadb21bfef94a3a50d8132e1bdae5f8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cfca6ed615d89731db1bb2878526c87b Relationship: SPDXRef-DOCUMENT describes SPDXRef-768e22a6d018a0c6234dc9cffe9d92fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-35f245ae7f86eb7fabf43fc88d54a601 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d85342700d84a50260ac796634e931fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f051799eacf87d7a87e1867602b6981 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57d170c243c54b513f27573764b6fa89 Relationship: SPDXRef-DOCUMENT describes SPDXRef-64889f0454ee8ad2c57a5c9578c55371 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d776a5f24a0b05e348485b096abab4b Relationship: SPDXRef-DOCUMENT describes SPDXRef-95078301f4baaefaa6f32369301b9eda Relationship: SPDXRef-DOCUMENT describes SPDXRef-89dbded08bba866a65f1b9b08a212cff Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c97683da8fadf097efcacb784121aad Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d8a908e6ef872ff22853220ed97719e Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc62d231f240014d32c2537306bfaf26 Relationship: SPDXRef-DOCUMENT describes SPDXRef-daa2860a520202e677a23a63e5dd280d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1eb909a37f3c0a1b0b4fb7a6bb533f95 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9ec1b591ac52b537a490a8784d4dbd40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ce72d924806596e1a3840c314c6ba5eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-79dcd8374fe581c25b32de1b97166455 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ab637a3e1ab7b42cea169dbfee29c201 Relationship: SPDXRef-DOCUMENT describes SPDXRef-22062fc6959c3f1b48f345430d5e49ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-926b743ba23bb19816a350868dbd0e38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-203823ef038c5321218b668f2c36bd50 Relationship: SPDXRef-DOCUMENT describes SPDXRef-43951c61004ac2aa3ece1738225e0a24 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0210de5f2231ff8f13570d850a9277b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0e3031b968326ad845e1692887e306e Relationship: SPDXRef-DOCUMENT describes SPDXRef-eb982c905276147f396610b9cce80d1e Relationship: SPDXRef-DOCUMENT describes SPDXRef-6329451f9b119c106ca8814116608860 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dcfb46a140c6e8968fbaf23b515a73ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d2977bb861158e4097218d229aef02a Relationship: SPDXRef-DOCUMENT describes SPDXRef-06f5fa016999c7379d1c11a6c29c2a24 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0c7400bf777f4c8bf3f98730b7ade89 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c415e6dd3d6e5c189d6c09334ee0c47b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c57646e16ff5c5dc45f0d0b43921078 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ea31c2f326b4ac12686da6de3e6afbd Relationship: SPDXRef-DOCUMENT describes SPDXRef-a60195d98b3dbf560cb55329cab65917 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8bec549f62231b750238b5c6093e5f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9f6acb6a01da79d2a8518f46bfa18926 Relationship: SPDXRef-DOCUMENT describes SPDXRef-440137c760dceabbc73f205348cf47f7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-97794aea3fbd704490de9ce685cc2bde Relationship: SPDXRef-DOCUMENT describes SPDXRef-e5541fd55b17c9f5233e4430cce20629 Relationship: SPDXRef-DOCUMENT describes SPDXRef-525af756052624e0d427ed01c41a49b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-73202ee886666b19a5609d3a94ed312e Relationship: SPDXRef-DOCUMENT describes SPDXRef-343f6e570775f6c985608f511f4607d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a91302d5fcb8e2d37c5c9ad98ec4e379 Relationship: SPDXRef-DOCUMENT describes SPDXRef-38cfd69f8179231e17f1f2efcb9c62af Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8c426fff47fe00159a6a93bcb2f553c Relationship: SPDXRef-DOCUMENT describes SPDXRef-fe2e5c411321df462d0e3ffd3b5cc26f Relationship: SPDXRef-DOCUMENT describes SPDXRef-955b7cb297e532882572274cc579390c Relationship: SPDXRef-DOCUMENT describes SPDXRef-c0599cad2845b99759ec542d87bc32fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c26c31598a7357bdfa531297425a4a7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b0a9d64d270f46ec638fdd1bf7ed15b Relationship: SPDXRef-DOCUMENT describes SPDXRef-dad39dff72ed3198f24faa705c8a6501 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a49007a07c4c2d0a6602eed9ff95a09 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f71e9235335df1ab87e849868dfd2ea4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b8581ca4efb1cbbd37a04b61c9ba0d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2eda12225aa1af43bc59caaa534958fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b4d3337d57a5e61489e7d5a4c5d2c4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-2460aab4701257f7a752ba8a67912a91 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec80992359df54f7d29f586b063f0025 Relationship: SPDXRef-DOCUMENT describes SPDXRef-50449a8ab732246726a8c19f838066b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3ac85d9d7e2535f3723143a37e9acc58 Relationship: SPDXRef-DOCUMENT describes SPDXRef-207fccfbab38b30d9f4f485544940669 Relationship: SPDXRef-DOCUMENT describes SPDXRef-571f37b4cd8e6b130e1181bc40acaf2c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f04e390923d4b39d13b60fc05b5b5e5e Relationship: SPDXRef-DOCUMENT describes SPDXRef-47efcb54fbe0b1ec0ca5619645bd2fec Relationship: SPDXRef-DOCUMENT describes SPDXRef-9645aba63403293c9f87203cd53e35fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-08b53d7c666b8ec97ddef233895e6476 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b717e61983d0335a6e916842e2c8d00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b03d3c48672230826cba391d033fbaaf Relationship: SPDXRef-DOCUMENT describes SPDXRef-456d255c1f522e31727091519759d7a7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-baba663d5cb786fddda364940f1c5345 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57a50e2b431a5323da71f8b1b4fa5dfc Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3f2248e9c62144ad7a1737b22e349f0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-436a094cfd97fbb91cf82f050fbeafe8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-42c2b2f40a99dcc1b7b824973736df55 Relationship: SPDXRef-DOCUMENT describes SPDXRef-757c138c4e5972aec39907e20ef98b39 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6f604f0ae6a4789074466d6ce9f4654 Relationship: SPDXRef-DOCUMENT describes SPDXRef-400e52b67a631fb2c3a28da80c1bb799 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f97c1d014e6b4f0d23c3339583e7bae Relationship: SPDXRef-DOCUMENT describes SPDXRef-3cc2683dd68fbdac603f036e555b423b Relationship: SPDXRef-DOCUMENT describes SPDXRef-7583072fa916d77c3011be34b300a859 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d857c4e02eaee3500b308e3bade6486 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8236ab289cb02732eba23c9bbf02104 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fb560880c2801791daef42009cd45c6f Relationship: SPDXRef-DOCUMENT describes SPDXRef-f662e956015c3f98ef7973088a36cb3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-c255d82c4008e62c54f9d0e9fe0f59ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-51b3d6ee29ed55bc7e17f34f845b5ee5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7b426845e996f7e0b6b47eca64fba10 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f5e1de6eb753120e3560fcaefe81bc07 Relationship: SPDXRef-DOCUMENT describes SPDXRef-760bf0bab9b605c29c944aea40b8cd4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb703e1449108cdaeef77f1e67ec9095 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d1ec6d40f23078a35c9131a1da39e72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15116fd6090151debe3165877ee9ffd1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-390509a0f29e0743333dc27fe388bca4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c3cbd9e36e135e07bd092c310a3f3540 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ddf315290fab094837d7d026567584d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4eeb6c729fe70791e30808312bc9dfef Relationship: SPDXRef-DOCUMENT describes SPDXRef-e7ec254e8520c037ef7a8c454036fc4f Relationship: SPDXRef-DOCUMENT describes SPDXRef-3382c8d205db5a8eb388ca8ddc13af50 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8f2090e6350a435f6376e25fe790f542 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5a51b84da83f26d4cdb9ec55bf7d6d73 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b6aa1ca39b8f6af95b1e52d06716598 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3fd267450c33f89fa978d09cb400954b Relationship: SPDXRef-DOCUMENT describes SPDXRef-c044ca75ed19106cef6765246440c356 Relationship: SPDXRef-DOCUMENT describes SPDXRef-af3bc546238e631232c75b3197e28068 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9947aac05e91e72b9d70c69855d49ae5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3f0d8e70b3d0fbfb0c3d27a416588ef Relationship: SPDXRef-DOCUMENT describes SPDXRef-8590d214e6ce096325b3343fd447780b Relationship: SPDXRef-DOCUMENT describes SPDXRef-0f52bbe2bbc72bd570a87fa616c00384 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8178f08ed3ae1b20da210a6f8c4bdf20 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6c803e85acb9df0581181e6fe1138505 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0492ce4786f79f71387aea19afa168e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87ca24297ef0a5761ae80cc29c94663e Relationship: SPDXRef-DOCUMENT describes SPDXRef-dda78375a7875b44040a143ca4ea5bc6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-36a1fc3d076b02e651cee8aec7acffc4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d4df10b9b7e5e0bce30a2e00808848a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8080e9e6e353ae4249929526d2f11da Relationship: SPDXRef-DOCUMENT describes SPDXRef-7aa60d658b293bceba9041829284c38d Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0547b5eb88960e332d35408289dd99d Relationship: SPDXRef-DOCUMENT describes SPDXRef-37c9e5537f872656c0892d499639f465 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cef6101489e501a5d8287ddcb83073d1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-34352f4f8440297b69c7ae16d733adaa Relationship: SPDXRef-DOCUMENT describes SPDXRef-98f61b7544fb47e38764d74d23176d17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e82eef673e44c67dcf9bb0f558ab00b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-315a79e672bba559f99acf585aac1580 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1ad45a346bea4d95b56340e92b206ff8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a95479c55d2d3b9592724bd0f82791b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ba2e2efc094e8e1db92ea4d0343fc48 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0fa0fbb43bf5a63f4beedd528fa2e198 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8b03aa9f3d781e311921df83d964a847 Relationship: SPDXRef-DOCUMENT describes SPDXRef-591ef6200b87589ec8e2efede6f76e8c Relationship: SPDXRef-DOCUMENT describes SPDXRef-8fcd4dc8d0ac737e964a07391353c2ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-93aa6862a5dbf093592e9adcd18e65e5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4b0d26ac6b9107b11b706552213c563b Relationship: SPDXRef-DOCUMENT describes SPDXRef-9027e961d2e8116aafb8a060df9e7c84 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2716a9a72d47cb49f23e90162777407f Relationship: SPDXRef-DOCUMENT describes SPDXRef-eea31fd15277b063a0cad43b24c3a082 Relationship: SPDXRef-DOCUMENT describes SPDXRef-10d7775f0081cf5ebcad0564e1a6771f Relationship: SPDXRef-DOCUMENT describes SPDXRef-d540552c041624ef1df66f76adf0ee77 Relationship: SPDXRef-DOCUMENT describes SPDXRef-319f438aee8730f551da3e3f91a33cc7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-45bcd545949a90a1c6fc3e38bf56c37b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a927de17fc4645f0358523e2a1e647a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a8cc20df16ac4b76d4266c03628dc908 Relationship: SPDXRef-DOCUMENT describes SPDXRef-952e236d3d5064b7679a831725426427 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d073d3e2e38843f2ae1ffd63ccb3ca6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-56a6c45a1ddb6f4452dadd23bfbf6070 Relationship: SPDXRef-DOCUMENT describes SPDXRef-990b12c3e5bcd56325f879d97cb155e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-45aa83d7d5299bb6bba349a5f6d9f253 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b75f61f50420f83af505ad802ea1255f Relationship: SPDXRef-DOCUMENT describes SPDXRef-178b11b781a33125f80c7a7f9a338041 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a2dc90bed3255d00365a4e8f1514296 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3f2f51df25f176be8635370bb3909288 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d9e4bd149c655f998dfe6bdb76593b48 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d69c6daa53dda82a019abd3a38c723d0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7488b00f65298d4943d2e1f885101a0c Relationship: SPDXRef-DOCUMENT describes SPDXRef-3ee61341dce5be792676bd19b5960467 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c8519ab59e5c219d2a7ca40372e25ba Relationship: SPDXRef-DOCUMENT describes SPDXRef-949f7a792b6ec7d24c30354218c66347 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7582f29c33f3750415fff5a6cb783323 Relationship: SPDXRef-DOCUMENT describes SPDXRef-558d9f55d95bd3569aad9d44f8443294 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b40eece2aafb29a8fa8ba0e0bd14dd2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b325904d00783bd0755057d3fb71eed4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a8f4ee0ec1e8ab623ac0c8e80b1c25ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-3fe02d927785c331b377427b4cffed60 Relationship: SPDXRef-DOCUMENT describes SPDXRef-35bf0d3e516235a210c804027574ef51 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d89136cd6a42560a3070acc8bfea3a7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-faa72adf2d36bd3816cd6add2f855abe Relationship: SPDXRef-DOCUMENT describes SPDXRef-e91a67130a3d7f17c940afd6a49f90ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-b5edcc0eb5c832320d389413a6544e94 Relationship: SPDXRef-DOCUMENT describes SPDXRef-155243f2d5696f2616c1892521fcb157 Relationship: SPDXRef-DOCUMENT describes SPDXRef-336386178b668f83656a4be63542b406 Relationship: SPDXRef-DOCUMENT describes SPDXRef-76986c67647f0e920734d0ab7957041d Relationship: SPDXRef-DOCUMENT describes SPDXRef-0b2ec2bcbd54f67843edddd9619858cd Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a4a2d388bc7b1bd4f44dae48c413e18 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2334d8bc4b4af905620dc3d8f2ed5c95 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b197a1fd5f2a691fd0d87c7a7244802 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ab3c6860fb47c56e3b8a3a48e4217dd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-26f6cb1caaf6236db88a65d83feb144c Relationship: SPDXRef-DOCUMENT describes SPDXRef-1aff26a1c628a7335e71d7e1670f90ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-0df0052bb2cad44144080026b253258e Relationship: SPDXRef-DOCUMENT describes SPDXRef-b3a1c29bdcf8550d38d46c7caf474f8b Relationship: SPDXRef-DOCUMENT describes SPDXRef-643e0e1ffc2e8a3978669142b4c1c0db Relationship: SPDXRef-DOCUMENT describes SPDXRef-aafac79bc7d40b0f0017e8a4a8186788 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ffb042a79dbc8281bbe43433a5aaac4a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4717fc7554f5f536e35bc412ba779ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-1677eec4470f8a38ba6cea8bfaba2580 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5901de01741211f26858aaa800ad6234 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0d0b45dfb438d347d92be515367dfbe0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0fa42f5d62e27184e79c2d0773f8c13e Relationship: SPDXRef-DOCUMENT describes SPDXRef-21f5d85b410ddb634344828d831eedd0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3022b7bbfe03d2f86d0325f1b970154b Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd822eaa74957781dd56182d0ed06a6c Relationship: SPDXRef-DOCUMENT describes SPDXRef-83e041096e65e0db574c0a6a79e2a5fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-70df466c875d66b91255f57fe2fea1ba Relationship: SPDXRef-DOCUMENT describes SPDXRef-96ca34722e202a1a92ac80f9fd85e990 Relationship: SPDXRef-DOCUMENT describes SPDXRef-45d36224db0009ac9ef1dc641fd0b406 Relationship: SPDXRef-DOCUMENT describes SPDXRef-14014b1f92ef68fe9b1f6f5446402bdb Relationship: SPDXRef-DOCUMENT describes SPDXRef-5113ff2aade07edff72b78537d641629 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b0fc78a05c84a059abef171053795381 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1bcdd433f3122d3b2893070dc3166f2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82974e5756642587053820a074343045 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4418cabcf35591c1be5b7041bc4843a4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e17fde662f18c286e47ff29bcdc4035b Relationship: SPDXRef-DOCUMENT describes SPDXRef-b8477159a2d10c1d723311f6a14851de Relationship: SPDXRef-DOCUMENT describes SPDXRef-7adb9c97b80bf9c7d3744dfd86243cdf Relationship: SPDXRef-DOCUMENT describes SPDXRef-d977601b4b231eee09059d540e56e0b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e30c9e79c98a290580b7830d6a4dbd29 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ef251b376c4fdeafe85f2f59f0e327b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d4271a25f28192cc75bbc410cc93a29 Relationship: SPDXRef-DOCUMENT describes SPDXRef-50223a6c2b4bc6cdae12af40375c85eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-67a80b3dbb5a98abf9a2d0f5af5e8f5e Relationship: SPDXRef-DOCUMENT describes SPDXRef-a2c8ce8ddd767bbd0feb4ee3d4b6cdf8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4a5559009e6c379aa8ad9073792e2674 Relationship: SPDXRef-DOCUMENT describes SPDXRef-26b5426bdc6faa3641c02c365ad0868b Relationship: SPDXRef-DOCUMENT describes SPDXRef-77db75c556e78dea668e0877b8de39f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-449d02a1336495e6d27b81d314415d95 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7b1761a0e8e579fd506f7a3a054a900b Relationship: SPDXRef-DOCUMENT describes SPDXRef-8fb341c07d81eca71d4c2ef948860846 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c387fc195142d9b23a2550d3be0b9ae8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d37b6fa0840411c3fb37295624003cd7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d3705a850005f67342e7b23a20903c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1a12e660154665d988d249407198b80 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5789d776e359440e023ebdee6cfc2aa Relationship: SPDXRef-DOCUMENT describes SPDXRef-a46031c3d412b08ead55bfcb78dcafbd Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e4ae9750c550944009c6a953ee38913 Relationship: SPDXRef-DOCUMENT describes SPDXRef-617b0ba70f55d9e288142c77e935f3e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb35a2c81e0600c7ebd529317b2d608b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a030e81586139348bed8d6b1211e90f7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fc68a320ddd8f4289b1c3f6faf2e5167 Relationship: SPDXRef-DOCUMENT describes SPDXRef-920404bc1ab3c597a02fc69d6bc28589 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4dcb94bafc65de4d880f53bf2ee41b53 Relationship: SPDXRef-DOCUMENT describes SPDXRef-70b2259bd66c3666de55b1c179b11c57 Relationship: SPDXRef-DOCUMENT describes SPDXRef-681ffbb7c9a792e9300cb0be0fa2c144 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2617e9c119c11734058c8f4e0e5a1014 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1a1aaf270a1e004a4767d7edb72f70b Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d2f82b24dbdb839030f3fb8e6b6f670 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1b16c54510d70ae90160af8cba356bf Relationship: SPDXRef-DOCUMENT describes SPDXRef-f536e48c9727ae37fd463bd0cf0d890f Relationship: SPDXRef-DOCUMENT describes SPDXRef-e0bc475f36a0953926a5462e4486a8bc Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8a73f7e85ce916d0f79abc20bf041b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-59e708e9fa9dc3c58fdf4605bfc27b4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f775ff5acd00c3535c8981d5042cd9ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-061b724c148e28f991c4e237adc7c2fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-0f79a4b9917e3f13360b4e042a976288 Relationship: SPDXRef-DOCUMENT describes SPDXRef-27e01c37626591d7aef0a8e2522fe51c Relationship: SPDXRef-DOCUMENT describes SPDXRef-bd9b6338e6607a1f90e27d0ea69f99a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8570a310f9f0a5c082bbcebd00e245e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1251a6dca6649eee23f5828e4c6048a7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-917774ebca102b2e42dacab1c86a380b Relationship: SPDXRef-DOCUMENT describes SPDXRef-3cfffaf79a0e0ca7aea946d5f850e8bb Relationship: SPDXRef-DOCUMENT describes SPDXRef-d5ff86531b540f5736ee8f114a7c3f79 Relationship: SPDXRef-DOCUMENT describes SPDXRef-30fbe21ae8c3bb9d4d61807227cfe561 Relationship: SPDXRef-DOCUMENT describes SPDXRef-47e0b2d2e9f33cfedd3560ef81d5fe04 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2126e659e47cbce0c17b172549a063e Relationship: SPDXRef-DOCUMENT describes SPDXRef-16d87a7e9c8e40cbeda02cc9cde5e3a7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-01672cdb760694eb9835d3deac6ce53a Relationship: SPDXRef-DOCUMENT describes SPDXRef-037fae5b7dc3077c3901e21f97bfabad Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a50c80c85adbd110eee66f5778d427e Relationship: SPDXRef-DOCUMENT describes SPDXRef-73273140c3e31f7a27f6458f89d7e97a Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f4d489bf90b3c98516f40dd4713fb3d Relationship: SPDXRef-DOCUMENT describes SPDXRef-52885c33731258dc6a6ef2aeaece1575 Relationship: SPDXRef-DOCUMENT describes SPDXRef-09deba9ce72df7b2f9d15ea47c04c8eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-be091217d1ed9fbda558dbcfe6a36609 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0ef1ec22957a356cac2712b5f0b5af6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-46bc4b6d841cc8a3a84adb10e8feec0d Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e9e190f5cfaa2f8decf360157edea5b Relationship: SPDXRef-DOCUMENT describes SPDXRef-bc83a3af86350dd6d25d5a28700d9e2b Relationship: SPDXRef-DOCUMENT describes SPDXRef-db784ccd99ca547c643904db00e4ddb3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bc861b1faa042975bb4237ba76e16594 Relationship: SPDXRef-DOCUMENT describes SPDXRef-06bfbaf28639ca411124195177c3f84a Relationship: SPDXRef-DOCUMENT describes SPDXRef-72d26f9775582d6ad44d965cb34459c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bdd6c59e856ff1beae64036dfae31462 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8631a6c9fff531d51a53fac9aa8dc589 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8093a05f88a7291b153443a2e86bf2e Relationship: SPDXRef-DOCUMENT describes SPDXRef-477511e3aaf3967b99aeff4bde284d46 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d24f213ab624b3beb2c313a709d009a Relationship: SPDXRef-DOCUMENT describes SPDXRef-125b06a144e147ab30b05a419b544d75 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b64944074a2a36e3aa857ae6431f70d0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b94c7591a0fd3bbd83acf4b7a8c667bf Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7b98061ddfa2895af6ab9003d6d7a0a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6bdad3d6efba7209ca0ea25f3b0a4ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-80104f8c25f438eb2531733814760099 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9517aed545e9956647ffeee6d5e8355e Relationship: SPDXRef-DOCUMENT describes SPDXRef-4d29da73febbb647fcf0e97355cf3c87 Relationship: SPDXRef-DOCUMENT describes SPDXRef-48b7edd20658bdeec7cffb269246a91d Relationship: SPDXRef-DOCUMENT describes SPDXRef-7a7a85fc2053d079c8110828abab0b14 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cf94ff2c80a5fead96e06f20b82a5fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3784dbe05340956dd9addb5d0c950ae Relationship: SPDXRef-DOCUMENT describes SPDXRef-bbb92e6b4d1505463fb5c4eb9d73364f Relationship: SPDXRef-DOCUMENT describes SPDXRef-935dbd7a0040e8d27eed472aa83a0061 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1925f0cd2caa98608b47075dc7aeffb Relationship: SPDXRef-DOCUMENT describes SPDXRef-d62c7c9a0a7d665b78ff5f9f60ced49c Relationship: SPDXRef-DOCUMENT describes SPDXRef-de7dac068fd27ae100672a3130bbb290 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cc68e8554cedad8f49df8700cfa21352 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d4438aee03b00dd4b7f64da21691b8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-4fcea599229143925d1f7979ef09a08d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b15734202a9f66941f5252d8f51c60ef Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea17516d26f36fa6ce11619788b73d59 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f85e5ab848da3a8a8356af5b60daafc Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c6f35347e7f94c98641fc8d93625850 Relationship: SPDXRef-DOCUMENT describes SPDXRef-848dec76597eca02ee4d32145fe7eea2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d9f72a8345d4c8360c293392249b4d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fde48fe00484d34a93803cfa680390be Relationship: SPDXRef-DOCUMENT describes SPDXRef-d057582fe890c99807bbabc9302ec87a Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a155d049f91532473f7ccb34eafce7b Relationship: SPDXRef-DOCUMENT describes SPDXRef-07f0c90558033e9976f5922c5b74b9d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aec6e3b80470c118cb1e69b2a32e37c7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8be3d24e6a49967d997f5209581e9d83 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3ebfa2b47d04a802d9173ac58ef735d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15b9d7738a66146289d17120b27a1d00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b6e41211144f8e66e6d47f381be0a30d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1fe1cb445a56434201058d9bd88a6d3d Relationship: SPDXRef-DOCUMENT describes SPDXRef-66b0f5fb5cfcd45c6dc35f5c8e7b6983 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ce31920388f854521bbae675e880741 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8aa8882ad8585dfff87fae8e782694b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cff93282c2066054f58048299a3c2ddc Relationship: SPDXRef-DOCUMENT describes SPDXRef-37aff185fc35f01a4763e44729cefecf Relationship: SPDXRef-DOCUMENT describes SPDXRef-a719fc86fd2c1fda685b601282d78157 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c7c001fceac637ae09bb97c7ded0737 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8668fab43ed975d9faf966b8b48a2969 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bdef01da1a8285a345dd9c07ebc3edbc Relationship: SPDXRef-DOCUMENT describes SPDXRef-52bcc3ffbcb697b0ca8f461d78f29f33 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6652488e601da43ac5e44a9ab247d03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-512f10dfb5d0a84176de79e9f1f70f3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bbb12ee72fa485797f63732accc59f3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c867d5d1355fc3139161b4c38cf3bb5a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8dd08ab228c47072990d6d0d3f39dd0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aef8561d372929bdefbaadec527bcb2f Relationship: SPDXRef-DOCUMENT describes SPDXRef-1fbb9b0f1918fe4560a406ceb948e78d Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4e7701975b80c8e0903569be10371f3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-998873148ff7def5b657e2a1583dba80 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c0e684a7ad6cb79ced04b31ffb55720 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ddf598e2ba657e34f71041fb92419f7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fca6fc8516a15b2fd55d830f79043437 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea8a36fcba5a38f716041af0b1c94a17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-61766ad4e8b8c421378588447332a135 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15e3408424ac4ea93bd184221032be12 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7883afa7005f1185af7ddebe94fa700 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bd3c32772bc017f2e840632a01027c6c Relationship: SPDXRef-DOCUMENT describes SPDXRef-e4adf301dbe005a9ebeabac67ab7e81c Relationship: SPDXRef-DOCUMENT describes SPDXRef-99e549fe4a934446b77d06df097cf03c Relationship: SPDXRef-DOCUMENT describes SPDXRef-d3583421e19614c31a86a242ad432093 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e7f40b824ee00f035c4d2be624d35a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f91fc6e4ba548a288b3f9de5d5157135 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c6c735ed714670e31a35f6593dff42c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-642361ddfa19dc416b5c025eaa55517d Relationship: SPDXRef-DOCUMENT describes SPDXRef-303e48eef28afcda90c8cc988c06b8d1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-929969246935494684f8eb7cdaf0a233 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a5ae06d16a38800a28e745ceda60472 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b2c24e670fad8588fe9af380f41c9903 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b39574a9e92e5b3b3bf2bff8bd3065d Relationship: SPDXRef-DOCUMENT describes SPDXRef-6488e068c43dab1882d069d7b85f462f Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e1d27c0cada3511a456838d6e12ad4b Relationship: SPDXRef-DOCUMENT describes SPDXRef-871e70782a072c6ce986088173fb3366 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0b917241e92ce6543df839741a5b0b22 Relationship: SPDXRef-DOCUMENT describes SPDXRef-347df8ef9c0195ace467408abf2f17af Relationship: SPDXRef-DOCUMENT describes SPDXRef-7a38bc2ff3ae29e296fce24a62553588 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e84f49b041e7265cbc823e5c54de2c5b Relationship: SPDXRef-DOCUMENT describes SPDXRef-34e1a1730156b4a4f288d48cb64b0279 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2af59cffa64038bf5367f5d0a9dfeadf Relationship: SPDXRef-DOCUMENT describes SPDXRef-e780cc7c1382c4733bec16ccf8fac94e Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2f3e695bcbfa89ae3624551bf33174a Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c03cab27aadc0277fbc94a5c7e0f54a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ea238a1a008025970bd6e8f2ac3d4757 Relationship: SPDXRef-DOCUMENT describes SPDXRef-487ee13f6a3c7498aa7462d69d0107a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-452f54bc8ef5c7f5e3d51cbf2eddb234 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3579e803c32a8e6e43ff6888b42f1352 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49cdc95e575d548726d1eb83de2e503c Relationship: SPDXRef-DOCUMENT describes SPDXRef-dbec4150192060559965cfc695470a45 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9979e84e2b11ca86c11aab4dbcfedf58 Relationship: SPDXRef-DOCUMENT describes SPDXRef-07f59ff0438ada2e5ceef856ac509d41 Relationship: SPDXRef-DOCUMENT describes SPDXRef-eaa6d0b4aa04c6df26fd6735c395c648 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dabcf434cc2b35648a1591a66e7fd4e8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49ef268907a091a4cb7c8f9fd1aa26d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0f03547b3b147ae27d2408b07b396e59 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b0ca5cf873a78914bcb619f370cc1d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0b53c85c64b5c50413f69c82ea70dba0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a686a8b30ee89f84595be3f7a44a4fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-b509fa4708962896410bcdb2c9a0e59b Relationship: SPDXRef-DOCUMENT describes SPDXRef-3a2fcca5af3ca457fd708c115ac7f7fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf1082aef16eac920c2e147a7ee537d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9c34997c0e03e062ff0b7f6a1b9789d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb964294b5246fa56735db74dec23817 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cca1fa5c2deb752562af55d315e7cee6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-72f9646710b13881a017d0b9b4735e6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-b5f0a14347b28617173abf0e3972e6ba Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d9aee4f18db7802ff088a521eee8d52 Relationship: SPDXRef-DOCUMENT describes SPDXRef-620414e52487dc3ab534633ed4960dd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d49232efd3b18c11a9aae996afb44ff Relationship: SPDXRef-DOCUMENT describes SPDXRef-59ea2fd2056f413c84219dd0e035f422 Relationship: SPDXRef-DOCUMENT describes SPDXRef-997451434d0c50e5baa18e8336f417ef Relationship: SPDXRef-DOCUMENT describes SPDXRef-69195a002c945fa748d54026a04f9303 Relationship: SPDXRef-DOCUMENT describes SPDXRef-758ad8748326a34c170a5b7fc080c54b Relationship: SPDXRef-DOCUMENT describes SPDXRef-33d76c4ba01b535f7c71468f3a1cb39d Relationship: SPDXRef-DOCUMENT describes SPDXRef-333b0050c7589d8f764c464c64280c64 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d28726e11d15ed666800cbb543475824 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9777225a5ae7d559afba7ec98a0bc8b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ce78e8edfbae5e019e1e6a2f929f78ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1744287818571168b8e1ceb06f63efa Relationship: SPDXRef-DOCUMENT describes SPDXRef-e175768053fc6be460e86524daaacdde Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c60a44e333d5b4eabce18de09d87bec Relationship: SPDXRef-DOCUMENT describes SPDXRef-32362214355b5ed7e4184a9672b62328 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2ab9de22be2f238c68debb4ea4df848 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a62365da57765c4a735a441b7678ea4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-831214c4395f2748b39204986406c2df Relationship: SPDXRef-DOCUMENT describes SPDXRef-667005602050e3aa16c22530fae17327 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2e4b5d52ed63c3b5b9d5fa254f2aae4b Relationship: SPDXRef-DOCUMENT describes SPDXRef-69df37a5239e2441443a32f6537612bd Relationship: SPDXRef-DOCUMENT describes SPDXRef-056671e4b9c697e5431295a4d0155219 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4dc78efb6efb0b1bac382cc48c9e014a Relationship: SPDXRef-DOCUMENT describes SPDXRef-90e6906fd6c4a2ddeb714bed2b8ff8c0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d50d55ddc5553c3ce5afd2fe3d13b40d Relationship: SPDXRef-DOCUMENT describes SPDXRef-c31a514fc8c7d3a19552203cc892fc4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-440bf8c766cf1ade68f4aae5b70dd66f Relationship: SPDXRef-DOCUMENT describes SPDXRef-97f6090a1b404e431701397d7504f8d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-736867bca7ba76a8b4932df91ef34774 Relationship: SPDXRef-DOCUMENT describes SPDXRef-af90e2bebafdadaa0dd9afd063052966 Relationship: SPDXRef-DOCUMENT describes SPDXRef-523ea0375a6440c1f066958bd5ff7688 Relationship: SPDXRef-DOCUMENT describes SPDXRef-74fe4506e0d5e9ed1a402e2e5392a603 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82e4edbb03471780f2966ea2c76a59b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d71a1fd4ed9e26a98dd88902e0fd50c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6631380eeaff7a1c048617648780031d Relationship: SPDXRef-DOCUMENT describes SPDXRef-e38c2d8d27e5ce6d632dc7fe0d405854 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8ae8499083cb07f7b48601277b1f3f03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-03ac7dc60a33c20f0b3256e950a92140 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bb1498e3e2fc00606a2ab762eb73107c Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3969cd41f5c4104c78ed01e3b2c83b0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6425a8d1548b4fc62a8922991a19d00b Relationship: SPDXRef-DOCUMENT describes SPDXRef-95fd52078f8e7eb0ea6c5910762b24cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-a94161169f4b7a2ae13b6e4ad785f16e Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d28a9d1969939fcb244e42d913ae77f Relationship: SPDXRef-DOCUMENT describes SPDXRef-36426469d6a49f75656ee2cecc038a59 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c6ee199406598ddd020ec75689d62b43 Relationship: SPDXRef-DOCUMENT describes SPDXRef-297240360f6efd5bdda8fd3049d442bb Relationship: SPDXRef-DOCUMENT describes SPDXRef-592ee81372a16f2149310f4872319019 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4e480d6a4463300d93717e1dca179440 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f75082878330a8afae4efb123ffc634 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d807221a38316cfdf1e75ca4c72ed843 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1647c9a9753cffbc36d9aa0fa713e3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf4e8663d37dabac7dbeff8b3f1dac90 Relationship: SPDXRef-DOCUMENT describes SPDXRef-727a099a1df40d260cc9df3b558949dc Relationship: SPDXRef-DOCUMENT describes SPDXRef-00670c85beffa14d7541e1d0c0f5d0d3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-89091123ede77e27d324a17830131870 Relationship: SPDXRef-DOCUMENT describes SPDXRef-778183f267992b10d6b3863a4b4949c1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-282c0d60c12c7e4a4bc406c4c814a0e1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-52074d7a9657cdfe265d545c2def42fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-70e100136c8ae975ced537662f7022b0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ffcd3adf7965b603151864eb1217f679 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b6d9ab3ccb5d1bc07cc2bc8a09931f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2e79e3c2751a4ddec263dc177d7d5152 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0f2514b3d4c7f27d5819a95d5c111159 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a12a276277913c5a48ec2e8c5ceaa4d8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15bcaaaa16f14d84777552f40c806930 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec20f1addc8ac5b02434b548f4fb61fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-db4d4a2402fffff7a2f889f30c8f41db Relationship: SPDXRef-DOCUMENT describes SPDXRef-d7e96884c94f4d4931436ff18fad21fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-b5d204322b1601196e83a37eef97cc57 Relationship: SPDXRef-DOCUMENT describes SPDXRef-045c945f6a0c6eca401b67ca42234aeb Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d33395fbba22a2f63dd1f7146d53d00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-da7df4639d4e9d9888e98d48ca44bcc1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-db3ef856b541653a80dc78499af30203 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a9ebe26e5d16f9a86aeae14788d832fc Relationship: SPDXRef-DOCUMENT describes SPDXRef-6974148e0d028984e0925b6a82560cec Relationship: SPDXRef-DOCUMENT describes SPDXRef-0be1612cb20c5a2cee06ccbf55ee5301 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b38b4880635dedb5b59f384300716a1b Relationship: SPDXRef-DOCUMENT describes SPDXRef-bbdd3cb7c393da436f63dc59f5ca6b68 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1622d1f3df523c0b56e98d897b352bd Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4ff9f9b51e52f06dcd24cfbd69e0cb2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d9e3100e555e417fc1c8684ae6f5f9c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-df2f8585b2a5355b099443f493778972 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2cc388d80c611ea95af98edb09be890b Relationship: SPDXRef-DOCUMENT describes SPDXRef-37642520a25683c05677f3e83094c997 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f2daf8bd8103927e02548e904246851e Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c48258efd3baefe576f1923c19e9460 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c3805c3c13aea279f4d478a0bfe48c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3b071a25de3a7fab79883e977142743 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae4f32a37824b92800c765862e36b7a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8125755acdddce07692bd272934c8d0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-0444e019840d9f8a9b1b8845ff07e638 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a98cedfed1b7eadcd88a08e765f2265c Relationship: SPDXRef-DOCUMENT describes SPDXRef-4156916512aa6e2ab970a87acd97816b Relationship: SPDXRef-DOCUMENT describes SPDXRef-561afacf5b13ec8996f93b1ea4603dd9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-40c02735083d0de13b3c7fd4c168b9f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6edbeebc4c7e05d301c563a83e0ffc31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7de359179ca0f924b4b99b332bd6edc0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-43ca87e8ee3407d7c38dd46b5e9397fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-e7b2c7f17868ce4b303b31726e35aacb Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c716d71d74e8bbe550531938544a197 Relationship: SPDXRef-DOCUMENT describes SPDXRef-47781aff2a91261b8d4b8460a12b558d Relationship: SPDXRef-DOCUMENT describes SPDXRef-8e4bfd0d8aedcbb460f62b3311827495 Relationship: SPDXRef-DOCUMENT describes SPDXRef-305dc34da5c737ac14982a362da19d14 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c48c86011e15dbb24034ff02a2078eec Relationship: SPDXRef-DOCUMENT describes SPDXRef-d5366582c50f363a33a148da182dd937 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7631dbe0e79fc5333a5acef2b517cd5d Relationship: SPDXRef-DOCUMENT describes SPDXRef-36b1c2ee985a9fb4f93ae5a657ce0879 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aec48f603796c87dd26237f0bdb9591c Relationship: SPDXRef-DOCUMENT describes SPDXRef-746c6862b7ffc4978d8a989bddcd9e0e Relationship: SPDXRef-DOCUMENT describes SPDXRef-b9f88b722591273c19cb340c1513702c Relationship: SPDXRef-DOCUMENT describes SPDXRef-e8979b2da617ebc9320db5d4520a33da Relationship: SPDXRef-DOCUMENT describes SPDXRef-4b76630558e6ed02a61cd0e68efa0f7f Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3972bd2f2b38b820af285f455ce97db Relationship: SPDXRef-DOCUMENT describes SPDXRef-57266048d7194cdbd1b51174daf96f82 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3babaaeecbc6fcaf69c400b39f20e73 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f15a7377e565d8c665335777d73da366 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3500309f6bc54749fb796747eb3b1310 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d7a70a7136da7d48655c9e3ebe8853af Relationship: SPDXRef-DOCUMENT describes SPDXRef-e021759e55e82754b579fa79c1e297eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-e5ebd2b262bfd27870522cb5b0effbcc Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca1dd747f4498fa6ad24a140743fca6b Relationship: SPDXRef-DOCUMENT describes SPDXRef-d5312f523312b3e7dbdefee73efb896b Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8faf64fdf01ae900016f717c3fddebf Relationship: SPDXRef-DOCUMENT describes SPDXRef-c07a5854e82c0a861bc8044bc3d8b8e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c74b287d7882038abaa1c7c9db9ef906 Relationship: SPDXRef-DOCUMENT describes SPDXRef-616923a245853fe381fcddd8bba0a8cd Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4d882dc4676876e3f169e30c0d2a566 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bef9f62e2520993297e2cc3ec4af52a Relationship: SPDXRef-DOCUMENT describes SPDXRef-533ab6e19521b1869b93e506949f8539 Relationship: SPDXRef-DOCUMENT describes SPDXRef-19904d3d217ff608ed99c87c3357c72a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f9b39967da1bad9a7f384032ce84a2d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f80ad17d1c98c6688a896c6a534de290 Relationship: SPDXRef-DOCUMENT describes SPDXRef-01fdc07cec2950496852abdf6cb71619 Relationship: SPDXRef-DOCUMENT describes SPDXRef-154698a4ebb04e1d834e91628973e2c5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-561943aeb02d6806ab15b84f300709af Relationship: SPDXRef-DOCUMENT describes SPDXRef-98be45e76e65a4a15e90c0786ef2d279 Relationship: SPDXRef-DOCUMENT describes SPDXRef-83a318630f2b967569e5d507255e1c71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68d2dbd565708ef1b09b4eba1cf010a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa631c868069a1f67f611f5a8eb886a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-600cd1dd20c748e0ed826fe0fb4e0499 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c773a4c50394862ac124d83502296f6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e34474a8e8d9254f2a3d3397d937577 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8681b1fe2e3b1dbb48329d4e558feee5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ef419477589153a581e242ff00ca5216 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d90da361a2e73fa8d0824a63b35f7b13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cd02748801a0a7048dece0cda14e456 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7168ce96a660325c582764feb02fe245 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0991de977f38744d540721611704e115 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bce6fb8b57e28a89707ef496c2be8a7c Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d7f7adc7d11dd02ec4f1926a4a9b2e7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5a3499fbf85a3a9f73adcc61467ee5c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-28bffc0be494918db2dda80a72f53d7a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d3e7593d870be35ab1fef93b08588986 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d9656d1ac8aa770b0c1207a80e264987 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d4e98b6aeab9e8a797dfcf3651648e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f4ba93de908321a0b8105346a053f3fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-900308e9dd0baca9a87d4a2f445b7cbb Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a367460fd2e80a2e8fe5e911cc34900 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f8ec1c75580a24533ea5607768f6942 Relationship: SPDXRef-DOCUMENT describes SPDXRef-de93454e77b40a0ad04a2af75c2f4f94 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2030ee620b2a71a83b47cd29786d2c72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd79c0a02325a975cd70c97027c6f58e Relationship: SPDXRef-DOCUMENT describes SPDXRef-76dd4380155710547df23f3fd6360e6b Relationship: SPDXRef-DOCUMENT describes SPDXRef-393e1c9985a3849b8320d8c4a236d9d0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6fb847d5d5fb7b556863eb0e65fca737 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7b50a9c9e91a98d089ab6b7283ef48fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-08856d23b17d0d5d89c2ac3ca7534cfd Relationship: SPDXRef-DOCUMENT describes SPDXRef-bcbf8e357e21e763be583f525f11e66e Relationship: SPDXRef-DOCUMENT describes SPDXRef-f7b4e17b026f597357be0dcb7995c114 Relationship: SPDXRef-DOCUMENT describes SPDXRef-272ebe0ddb3a2dc05bde49666f6a93c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a3cea5e21450936919287aacd62d4072 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aeaa491f3ae344951f793fe968b2e8e9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8efc707d4238f0aa78d79eb7b79f0d85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c791f5c8eb28d83ff9f0c494f449e444 Relationship: SPDXRef-DOCUMENT describes SPDXRef-55851c3a85ffd1c3390c2b77d9373308 Relationship: SPDXRef-DOCUMENT describes SPDXRef-75a754b80fd701aea3aac04c9e467d12 Relationship: SPDXRef-DOCUMENT describes SPDXRef-086cccc6c60a32b03374987b411de6fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2647b09c768c78d2e59144f9a11499b Relationship: SPDXRef-DOCUMENT describes SPDXRef-d068711946e221474d4fd9ccc180b59d Relationship: SPDXRef-DOCUMENT describes SPDXRef-189e20aef970ad2429b03dda1be60495 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f59a023f61adb12c830b0e02d9ae2330 Relationship: SPDXRef-DOCUMENT describes SPDXRef-93287c1ec6b60872641de4102fedbd17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6691b95c63544ebac3fc2d1feb88c574 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c07f6f31f2f4cf29c3cded7171c96c6a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac4277f9c44d4c80d666db2487f9aab6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-677abf83b02da4ce06743446b2823d6a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d10ce364c8cdd972acfe6c34eeaa30d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b37be1f4be594a98930d95cf34d0048c Relationship: SPDXRef-DOCUMENT describes SPDXRef-3caf529b6c5998907797539a65ece0cb Relationship: SPDXRef-DOCUMENT describes SPDXRef-67d71fdad8de83de1ef65ac357edb547 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5dfff9bcff48ae2fc1a465b4323f96f6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-91effadd677b2a96881e693a32da9fba Relationship: SPDXRef-DOCUMENT describes SPDXRef-870fb7050f30edb5510ca582192bf850 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0167cf00451baa96e6a922880ea2de5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-21cbd480114abf5d67dae57a88eb69b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0648152ccc3465d9fa3426324ffc1cf6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5691459b45470842a3beed5fcc2daf95 Relationship: SPDXRef-DOCUMENT describes SPDXRef-882e1427005aa536fa0b1576e00a9eb3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-85fbbe6eda731f45706548d6b74c3c96 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b21eb4379d50060da79219c091a93cc6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3ca685f66702812e2a83926dec023238 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6fef8cdbcce2f3c140efdb2a7cc07e88 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d32e2b6025d51945cdba48e0507e53fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-4d7e42e5e939e92b557d93e3e1a87bdd Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7bad576353032d65fa41ce5e93e40e6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9dc265e5f45538e26763d5bc43fed764 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c48e5859598a1b6bf3c21b9e3db11c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a9d4ec617a354628374952baf7e9bc6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8ef42e6f930766abebd828ef665d82a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-61f86f4e83fe37c91526420b0d93b02d Relationship: SPDXRef-DOCUMENT describes SPDXRef-e0bbc8c70965f159d3f1f6dec5e04df2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c17da1e918b934ef742ba9d0e5a5355d Relationship: SPDXRef-DOCUMENT describes SPDXRef-ff56173f5ebd0292d2f9fe95b0b5b2ff Relationship: SPDXRef-DOCUMENT describes SPDXRef-42b64692e765b041623f87af4ce8c655 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8463fc82f0eb9a0fa136c494e763341e Relationship: SPDXRef-DOCUMENT describes SPDXRef-5960d0b8b6f7b6a9050a819f0a2a3a67 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ad0aec8e15ae4f3f61d95e5866e25af3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-37d582521bbbc127ed63ec6a54caf059 Relationship: SPDXRef-DOCUMENT describes SPDXRef-287336ed5017e040f9b90288c71e6012 Relationship: SPDXRef-DOCUMENT describes SPDXRef-640de422f5b49570c873c22c400c8628 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f903772610a8df7882b6414220a0c5f2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-af42848ab3a2ca326e9904fba972758d Relationship: SPDXRef-DOCUMENT describes SPDXRef-25b7e29b86a6a876bc38445027062c54 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f7b9e7d65b561eae53f173d1c65cb3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-63e0933bcc37477172d11a7462967bb0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-83afb2d6f5f7077c8ca9d2467e411b6a Relationship: SPDXRef-DOCUMENT describes SPDXRef-dec81256a513a2a876b77608d01561a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6e22304b4ae922b07beed0df0ff988f6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f7957a4033acf5320f2e5cc7452c740a Relationship: SPDXRef-DOCUMENT describes SPDXRef-b76a6818f15697e20400198d3ee87f38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b20a5de0761874bf992f6adb39e86bf5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b76e14c7e8cd2835de8c034c9a137d33 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9674ba7c6efd36f61be71c9f96361022 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c83e2a8e56e26c5f1c2fa0af54bc574 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b3389919e928cd5e5ed170f3dd7b838 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68677398b424c4c2553a4d15d58e08a1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a3a26a32760aa1eb5fb1095f49a58326 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aa090829d83e61ac3b08b617c7137cd7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d3d7229e286688fbb83c6ef2c0c831ff Relationship: SPDXRef-DOCUMENT describes SPDXRef-4d06d2479d7012088b494d9658ccd140 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d3287b706ad3e9bb82e51145f4dc818 Relationship: SPDXRef-DOCUMENT describes SPDXRef-84f4ac538b12f7e3253fff55ae866002 Relationship: SPDXRef-DOCUMENT describes SPDXRef-431be145505fe5c61d3506bb41e24295 Relationship: SPDXRef-DOCUMENT describes SPDXRef-208768851c9971da24255a4ed79092ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-8aa8f7216b80bd9acc11dc8bba052387 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1369d63fc0fed22223a890d2f077e706 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ed37a746d54c68843482caeba32b346e Relationship: SPDXRef-DOCUMENT describes SPDXRef-4abc123562249792032735bf62ba5e79 Relationship: SPDXRef-DOCUMENT describes SPDXRef-38987a65503eb5a9524e58dc4a3868de Relationship: SPDXRef-DOCUMENT describes SPDXRef-97f1d247177f71c06042358a131b8cb7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-744bb8f2414d3589e51e28a17b018903 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c5f870c7275c3a533697116e906331b Relationship: SPDXRef-DOCUMENT describes SPDXRef-826f2ddaae96e6e3bdcab4e3eca0fef8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cfe0c8c27dfc0576c868ad56ba7eea9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-63b658f17bc7912e4e2c01049d01eaf3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-13f0523a604fdeb44a636f2539a6caf6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-afe7cf1da458dade0db62254b59ad0b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-552de4752516fae084f3386dd3722633 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d25b032dfabf6f2fb04c4a87b072fc7e Relationship: SPDXRef-DOCUMENT describes SPDXRef-fafaa78fda48dec7f4c40bf9226180c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8d56114211ac5c27efe9845bbf9639e Relationship: SPDXRef-DOCUMENT describes SPDXRef-7686c7a519267a1661ac14a509927c23 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68b57ec970d141cc38ecb8b8e17127fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-b094846b8e43016e474ea25556e2746d Relationship: SPDXRef-DOCUMENT describes SPDXRef-34cd2204b1c381e8fdc418c6282e1a71 Relationship: SPDXRef-DOCUMENT describes SPDXRef-59b976aa69ff75660184ef830f3e4df2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7ba900b74dcae60cb5c32af101fa9806 Relationship: SPDXRef-DOCUMENT describes SPDXRef-345e3dd92474ef6f0be155df349b25c2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f72142a1222ef96ee9be1e32af697a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c95102af7c35480ac427526ecf55051 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c5c896a01f9b699afbf142dfaa03b93c Relationship: SPDXRef-DOCUMENT describes SPDXRef-5aa23bca4b3cc3befa1b7bb1cdf1a110 Relationship: SPDXRef-DOCUMENT describes SPDXRef-811da0005f934972e7706210c48a2392 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4611fce318663a5e78d7ae429053acd5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-78cd85bd23e2e4b3186bbff775217383 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cbad57266003d9ce60d11b9ab3811f44 Relationship: SPDXRef-DOCUMENT describes SPDXRef-862a3b96c8132a2ebfef0dfeff72feba Relationship: SPDXRef-DOCUMENT describes SPDXRef-728bb4f8468e39a2c26375217b65ad85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c1ed00d466ddc695a610dd49357c2464 Relationship: SPDXRef-DOCUMENT describes SPDXRef-931650da45c639d57771b7e2184fe6b9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee3b50399d108cda9b5a9ee6c5115170 Relationship: SPDXRef-DOCUMENT describes SPDXRef-32670750c51b00648e55765f8e32d153 Relationship: SPDXRef-DOCUMENT describes SPDXRef-deeff0c235cd5145cfc1b0aea3600ada Relationship: SPDXRef-DOCUMENT describes SPDXRef-415315ad75775526bd650767c17279d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-af0ed63bdb210686e4a68a68defc3d72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2cdba4e6af39a3cac7be7d4b8a15468f Relationship: SPDXRef-DOCUMENT describes SPDXRef-cef53841703945300e9cc9ed8b789363 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c52e0b11f099a2ccd95867182b6bdff9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c564252c7243c34f3ad119255918f5a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3f4de1717b5aaa5a41b705feac4210bf Relationship: SPDXRef-DOCUMENT describes SPDXRef-d38c01c57cda2e9b6ed5139385c37678 Relationship: SPDXRef-DOCUMENT describes SPDXRef-800e1f2d530801220ec551ce88da80a3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e6216eeead0ec25239c87dcf9abaace Relationship: SPDXRef-DOCUMENT describes SPDXRef-f212e58ea54318c77e1f7cba76cdf0eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-c90c84e9e4170cc4bc519295dee4917d Relationship: SPDXRef-DOCUMENT describes SPDXRef-d7c8d5f4c0dae7ec8e3d6d15a3da9aa4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-91b8d88d506edb8baf88d65e585e998a Relationship: SPDXRef-DOCUMENT describes SPDXRef-5885d50423f678c02248e2f7f4f22110 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ba0064ed3a6ebc212782df8bcd23f408 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e392f630286009aecc246113f45e01a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c09a1e7e5480ddc6c7abfad057b1de3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-31691b44df1b72347c6d29fe3784a750 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d094a1e74429e73b0f0ee56928a4a360 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7e331ca1126f76978474c3a6b914ab2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc4ec4c4c7a9712330eb2a0134092584 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5492b1e1b5c7db47c10e6424aa66455b Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c085806c3e0cddaed6da113da16eabf Relationship: SPDXRef-DOCUMENT describes SPDXRef-5a269eb9f4fded16b8c39b24623d148c Relationship: SPDXRef-DOCUMENT describes SPDXRef-8ead90986f3f58830952a8efd4786b86 Relationship: SPDXRef-DOCUMENT describes SPDXRef-755e749196741fd098850226233244c4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bd699a9d6b7f81b1f0aac8cdac5f489f Relationship: SPDXRef-DOCUMENT describes SPDXRef-03dc2e0e69f5ec954a277ccda138f56e Relationship: SPDXRef-DOCUMENT describes SPDXRef-3cc575c47fc32781b16b17f69cff3283 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4554deacc0a0e24bf486b18e7968366e Relationship: SPDXRef-DOCUMENT describes SPDXRef-ff93a989ed68a542262affd7285dc4b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd7629f4ecb470dc86fd12fcd18670b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-613e7273440218c6ee8359cc37dd32f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d02f2c493dc690ce74077ccf3a1d8d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-917a7d2479c459d58fde9ac46838343c Relationship: SPDXRef-DOCUMENT describes SPDXRef-51242110dd44646f12296f33f40795be Relationship: SPDXRef-DOCUMENT describes SPDXRef-00d8566083dbee3a160b29ac9c176bfe Relationship: SPDXRef-DOCUMENT describes SPDXRef-545d692250846a02a068e2be20569170 Relationship: SPDXRef-DOCUMENT describes SPDXRef-20f5bca9468eb3e39414b461719aa8e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2aa56c9d69d7e142d69df6760a5e0cb4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b00c9d9162fa3efd4ef6333446aac9b Relationship: SPDXRef-DOCUMENT describes SPDXRef-de503f246d9a20cc474651315a12d80e Relationship: SPDXRef-DOCUMENT describes SPDXRef-c552f2cc24bc1a5cffe2f759443dcbd0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-91d65e001c16f3629552b32d0a8fc2cb Relationship: SPDXRef-DOCUMENT describes SPDXRef-df3bdcbacb0cab1b3950bcd799ac32b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9aea31b05f94e7da0a84af35c0d68c47 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c253263d854977bc5a1b2959ae4678cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-ceb8f49c6419c06b6772fd7ea2071b6b Relationship: SPDXRef-DOCUMENT describes SPDXRef-02a36a190d696eebe32a05679d7f2ba6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3034e6fd9f790a5d0518b787564c6f4d Relationship: SPDXRef-DOCUMENT describes SPDXRef-8105720df5f75353db5149864e6da717 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6e9dc1f93d584d0552f1237b2762450a Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2f5b078ad9755ad46e8189ac52661e6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9118f2021c95c03b64e73d3c3acd421b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a63a9c72a5ba401cd3765495caac319e Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6878fffc152c7fec86b58f67774eb8b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2def72f9013bb5876cc3f1ceee1bad12 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fed3941274ad99ddc1ba5f0501c2a747 Relationship: SPDXRef-DOCUMENT describes SPDXRef-85b76120f3aa509205938b71a5c8912f Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c96b7b7c4dc16d054d7a8002cb08dae Relationship: SPDXRef-DOCUMENT describes SPDXRef-9f297dbdf1ca0fe2531e7950aa23aea4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-41a6f1ac426c896057aab3ed1eeeac81 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d2ac56850cf58d110493c3c57c56547 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac0fa9abba905e00d7355a02f20cbab7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc6cf6fa5836182ac7739f145253c3d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-91f5132429a652e8ae91e32cec43e28c Relationship: SPDXRef-DOCUMENT describes SPDXRef-319a657448660e29f97fafe0b5a1a4e9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-83be2ec870789f585d321cd56241a7f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68f13c9248dbab47a6ca83d878aff372 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3469e99da6f6e230d5eee6481a65a065 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1cc8e42c125572b2aed2ea8176ce1232 Relationship: SPDXRef-DOCUMENT describes SPDXRef-01507161bf3b5e1ee73acfcd1664d31e Relationship: SPDXRef-DOCUMENT describes SPDXRef-2803628b54b40511aacb4a3bd4163946 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d3a88686aa52195b8e5cadf3fe237eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c878e776d05114dd7da6c20673198b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-57bae1380132d1a0036b0683d9e9c409 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e6656d25696c6b90606927736c3561b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6d23087347ea211b2035e9f1f6ef37e Relationship: SPDXRef-DOCUMENT describes SPDXRef-74f3a9258a4eb2759b97671f2b33c0f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-974d006525d8ce53c004bd0508355fa1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-75c573fd15f7ad159b3245d218415cbe Relationship: SPDXRef-DOCUMENT describes SPDXRef-fdd67b5e016f98007f84e30b6e239e7f Relationship: SPDXRef-DOCUMENT describes SPDXRef-36b84c5f182e34566a03a8fae04a4e85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e6140658206acdeb42f3001d443a90b0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-21a1313b3520189370a237dadc63bd28 Relationship: SPDXRef-DOCUMENT describes SPDXRef-28e9de4d792d746ce6c63025d7acf51e Relationship: SPDXRef-DOCUMENT describes SPDXRef-5672b240488dc6806451c92bf38261ae Relationship: SPDXRef-DOCUMENT describes SPDXRef-66a3240a34c1177f67849a3ddc946950 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a4b79abdb24d0aef680c77788783f06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e6ffe13a8e84128a992cc0adade430c7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2303bfb1aed6b6839b602ad574a88d8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-df7171868a8214dec5e6ffe19b19490b Relationship: SPDXRef-DOCUMENT describes SPDXRef-f2993d88b14e629e4e06430677310960 Relationship: SPDXRef-DOCUMENT describes SPDXRef-442001dbe522260b8b108186da733569 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9cb4e1356b16a6c27af0baaf1078397a Relationship: SPDXRef-DOCUMENT describes SPDXRef-aab70103d66041a1b6be7e773e7da801 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a4d633884573140a373b063533162af Relationship: SPDXRef-DOCUMENT describes SPDXRef-511ab7ce85e73610ea3cdc120c82860a Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f4ded710fe84c45fe75c123fcc30b31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-501ac7f8c89cbc085791b16bf0d6bd92 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b8003fc0a64ea17624d4cd21f86470a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d45100252cefee0134370260ab1a5ca2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a43fb599e520c03e68739f5f79bfc993 Relationship: SPDXRef-DOCUMENT describes SPDXRef-86ce88ca6251283f34ba1ee3782fd798 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f4210cd64cb11d1afc2a0c2897452f9e Relationship: SPDXRef-DOCUMENT describes SPDXRef-85906328eecf9fdabfc69acdd8216470 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82772f5a8b5be11eac906e12e4237b57 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b88b0c48da1d6aba89d94ba308638e69 Relationship: SPDXRef-DOCUMENT describes SPDXRef-191c7251a9474ff5902c4e34262d4350 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1ddf24a462b56af37cf1cb0078d8bb42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3e83c3481e1bcfa1f7f79a36f9e232fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-b24a2d113be2c68e4b66e88ac323c11c Relationship: SPDXRef-DOCUMENT describes SPDXRef-c44a92e039a38a36bfa267a90f6183d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf001dc0eae05b9da9c24ae56db4f440 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8be84bbc06f02a893a3545e653708b1e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1831b4525969d1d39de744756e27f9a4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e5b2328ec9979b354cd18edb1680784 Relationship: SPDXRef-DOCUMENT describes SPDXRef-286087eee6282e0786f982aa8a7ff209 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7bda5af556d935564e2ceacdcc37f6a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fee2f7a4f92daa642b53b6288d96bfb0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1955cf1807e99d00b41e9702b03dd178 Relationship: SPDXRef-DOCUMENT describes SPDXRef-960b06e2a90822f903e68ba37b9e0ae1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac60a99c59d8c979c89137d68881b53e Relationship: SPDXRef-DOCUMENT describes SPDXRef-981040ec422173e115e8af473f35dd67 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf9a7063e604d206021629e6f06f1106 Relationship: SPDXRef-DOCUMENT describes SPDXRef-07bbd884dba8aac37afe644b79267461 Relationship: SPDXRef-DOCUMENT describes SPDXRef-76960fd7f2bcd9044f6aa34751b9813f Relationship: SPDXRef-DOCUMENT describes SPDXRef-08a85a0e1ad6c4d40234e62a5f344a2f Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a9dd5b0350d0c7b8971f7a3512160d1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15e7bd9a9d579dcbbb20d6d44537929c Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3442316f30dc2aa49a48f9e5cee5ce4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3670e5aa24d403783dedd348f9754c03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7209aa2a921f71851cbde505f2f8ef45 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8df06019420ee0cd6b60ed3e06db2c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e81b80ec2500e234fd420be9a221f688 Relationship: SPDXRef-DOCUMENT describes SPDXRef-63eb0769b3a20557829572ce5d4ebe9a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f227ebd1528c21c47177440c34ca8b3f Relationship: SPDXRef-DOCUMENT describes SPDXRef-af3bafdf283dcd3e84821f05998f68ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-e4ba9afc4e794f8c7845fae882b7dddb Relationship: SPDXRef-DOCUMENT describes SPDXRef-e21f2e60af1090a99fd58da3f8eebe62 Relationship: SPDXRef-DOCUMENT describes SPDXRef-edfb9135286981e74137c143fe4bfa8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-fc7624bad3019682bead6f05dc75a354 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c40670478fed97085eadabae1ea1433 Relationship: SPDXRef-DOCUMENT describes SPDXRef-709c09fdc0f525b21390c01ef2ed1d23 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8fbabdcac65e65e0043b2cd76d1c399 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f244fbf943cbc383f129d30e1d7a53a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dadc004a2570aa5de7f6c83335e64a8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac51a272d55770c8d518ab14be343070 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6843182002a60ccf1a23effaa21702d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f28e0efab22d3ff9f7ca3a425b0c5959 Relationship: SPDXRef-DOCUMENT describes SPDXRef-906f340f4243d5a97b9424d015c13493 Relationship: SPDXRef-DOCUMENT describes SPDXRef-02a3679f2a8da502d644f99fdb96241a Relationship: SPDXRef-DOCUMENT describes SPDXRef-bd12bd47e530ee9a01ab7afa81c3d6b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-62d2b181e2d8b178911eef6a10f4573f Relationship: SPDXRef-DOCUMENT describes SPDXRef-e90c90ab58f584c593f327f8248f7cbc Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd27b8a76eb83d9e8aca5f4c16b76e1a Relationship: SPDXRef-DOCUMENT describes SPDXRef-56325ebfaa51cb5ddb4b12e84e35692b Relationship: SPDXRef-DOCUMENT describes SPDXRef-4d105cf8a5901e1e188a89956157ada9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-89b880e01136e841d3fb2bbc37e5b88a Relationship: SPDXRef-DOCUMENT describes SPDXRef-4a158c09058197e717e287fa21cd4675 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b087be5b7c50f9fc8ee11dd81dd3e971 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2ffa86f2b39682ce217d39d18bd6e75e Relationship: SPDXRef-DOCUMENT describes SPDXRef-d06ebaaf09dceece9f3d5ba4ad78a751 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc827d4dcbc2311bcc13ebfeb139eebf Relationship: SPDXRef-DOCUMENT describes SPDXRef-6439c0e8e7178c0cbe25ff1f19eb1291 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9808ef0ac73cb13248dbb52ac4576435 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f337e8ccdee4c74e760231ca2b777254 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8064f2a2eddba2214314f497ec392dc9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6b1c9a715dbbfb02f4687518f29fe4e1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1367b484912363cfc024a2db802b0d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9055769e7ec35f62b78614a2f1e7c5aa Relationship: SPDXRef-DOCUMENT describes SPDXRef-3acfe9cb2f07fbdc3844f24220026e3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-deefec14f05575116cd8181f1b04f1fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e8741c0413dbd73ca33ce65fdba97c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bc9a700f54b071512abdcc70724b8dd1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-40c7edc949bb5bed038db1f2440f1045 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1aa921fd1b32c5b3b24c9793f41af4b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1d0aa811fbab961676d547f930292406 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3de6cd2855dc1e28cb85061b147e1bd1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d5f585a41fbaf802020069228afea3f5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a20dc238eebfa9bd2d62d4aaed0468e7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0478a40f7df77d9d3e136ee065452d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-33d506b84ef49ab757207210b039b056 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e24ba104e9abfc872d6a8d51fe8427fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-03672273fcf2ea837ff9a8c6239e9e98 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5b66eb0b83588981069db75532ac68d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8129812d957cddb5a60af5e1496d395 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4330fb886d09bbe474da0adc0b77ec5e Relationship: SPDXRef-DOCUMENT describes SPDXRef-35ebef5feed9a0feb44687d834554a29 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7308e53c506912506b871ad8b3795e93 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b8d5091bccfcb1aaedbe1516bf395762 Relationship: SPDXRef-DOCUMENT describes SPDXRef-05f1b03201606499def90274e8d91e3a Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c338b5843c961a8a68156a1b8993f56 Relationship: SPDXRef-DOCUMENT describes SPDXRef-85a06ff458a9f404b1bdb0e6a4f1c507 Relationship: SPDXRef-DOCUMENT describes SPDXRef-88816b64ea3c4a30204bcdd0f3f85bce Relationship: SPDXRef-DOCUMENT describes SPDXRef-7280269d2d0a2f6451954d6c35c992b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e89e5a2078cab5d9704ff12e69881bda Relationship: SPDXRef-DOCUMENT describes SPDXRef-f705cf3f98928eda7ff480b78dc432c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee974d8c28319a1602bfbd50997a53f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ffc788557a8e34013d2359aa14548a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-74a48c511cabc08ba8723b0de68ade99 Relationship: SPDXRef-DOCUMENT describes SPDXRef-60c0e605150ff45cdf34cbc1b279dcf7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b8b9f765e606ffeccfbf12ae76222f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c09e379fc7d2d67bc511d7e9394e177 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d725638e383a68522f9f5ec24a0bf9d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2bb0ce05b8e2e00b95192bbbb1562ff8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8eaa905f99b3a6c18d15a4851000236d Relationship: SPDXRef-DOCUMENT describes SPDXRef-e563552e3286e1778f5122115cd17fe1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68eb7b72d6eec69c9515078b3326ed44 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d33d05a428ced7a75e357a545210eaee Relationship: SPDXRef-DOCUMENT describes SPDXRef-f349280a78bc35bf7b105bc5e4d6c4f8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ea510fee768f0f0b747eb8daacd08f0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e0aeb8c81dfe8514622b0e7040ed453 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1cd7c610d4ea616534e481be22913d41 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cfc7483950e45f514a800cc09d1b74dd Relationship: SPDXRef-DOCUMENT describes SPDXRef-d765e0774088ea2284a2898fd1f1e1d7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-54b6e817c3f0bbd72e7a27eb5fa337b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f953ac0559a0f836e605e18d521e2552 Relationship: SPDXRef-DOCUMENT describes SPDXRef-238bf9fcdae987ddbb23f44ace3af5f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e38e3d66e83d77ebd056f4a5aa86ac5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf40a61fd07ded06e8f26ec18e697458 Relationship: SPDXRef-DOCUMENT describes SPDXRef-025b7b87e703ed569328a4c391b8c4a4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-370eb9ff35555564d09f6a0d250f29a4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-18f21196bce0404da7790a7ea9295869 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0d87307f5f22224f635dac1352325d08 Relationship: SPDXRef-DOCUMENT describes SPDXRef-397cb712b4d6b91b62257004ceba8ceb Relationship: SPDXRef-DOCUMENT describes SPDXRef-50234d937cd1c18c485b988e42d224b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-421e659e72ef4dd64ae488c0649a697f Relationship: SPDXRef-DOCUMENT describes SPDXRef-56a0282471f9d61d223eb5792c51ccc4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bbfa62f35882e177907c97e2f8b6f6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-cbe17ce4cf5b8dcba65f9386c3d01060 Relationship: SPDXRef-DOCUMENT describes SPDXRef-22c2c707ea760b872aaa374be72c3ced Relationship: SPDXRef-DOCUMENT describes SPDXRef-a4fa9688aef4189ab92085544f9b3fa8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-18a28150b4daa8edea8e512a30b8b9e0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9883850baa6e90e5098d9f25130c9572 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fe036d2f616072acbb81c968efeae5eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-dbfd5f6240435174c3f56249a6480e14 Relationship: SPDXRef-DOCUMENT describes SPDXRef-00edbb27c19f5cd8a57ed3c662e855eb Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf4368e76d4ee34d61252c108ebaad13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4fc7c1f7dd984ee07027270c9e4b8dd3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d975327a93bbc219da13a780d438fd46 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4060b6174b022219ff97c9d7616575bb Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2a99d798bc7cc84fcb55506aeb16db2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49dc376254d4217a09c73dd41a1469ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-f92542c2d133684a2ef2205aab2b68d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fe14bd44137b60fcbffc65f7eb25b41f Relationship: SPDXRef-DOCUMENT describes SPDXRef-66ecd24ccba118d1c90003e49e11910d Relationship: SPDXRef-DOCUMENT describes SPDXRef-3a3a0406f0d843567aed179cf990365d Relationship: SPDXRef-DOCUMENT describes SPDXRef-aa2b99601d0a9253dd525557732305e0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-155f1f02986401fc997311b9d57a6925 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e55030f79e244a5cccb3eb60ecb6994d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1cdb0673cda42d06b8ed83b8ea020ecb Relationship: SPDXRef-DOCUMENT describes SPDXRef-7215764cdd22a5f10f3f410aea4d76b6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4ff916e5066e50f78fb6ccef12b8fab Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0aeba32810c9982feb3996c84789d51 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1f9fa7152fa1d40de181f073a310e87 Relationship: SPDXRef-DOCUMENT describes SPDXRef-afbe2ce2ea88769557a863d05f5e8388 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b6c3bc4a531741bbec547aa03cee971e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1dc24a15097cc8fd54c0faf5c0e44227 Relationship: SPDXRef-DOCUMENT describes SPDXRef-77ea47c699c842d8c793389ed3dac535 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2afb33ad4faed6c383035a27bb5c6b19 Relationship: SPDXRef-DOCUMENT describes SPDXRef-49d168d06b41f44947c2f6f6952b86a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-25f350006b3a3c56fbf62c537f9c27fe Relationship: SPDXRef-DOCUMENT describes SPDXRef-b04213afa81574872ef77209dad46596 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7765aa1c7161cf703fe413cc3b88e00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-725877209134c96688c4edf384f289a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c7345a20f5097690e1ba7804efcc966c Relationship: SPDXRef-DOCUMENT describes SPDXRef-28a6dd1d713a3093dcaec8fc5780d9fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-83f8de2bb3ac2180d56538b78587789d Relationship: SPDXRef-DOCUMENT describes SPDXRef-c7b702a25e71e801552f193d0bfdca8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-99b2917d5af60a5af769496051d7ab5f Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e1688218548451876a9e361c5098d4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-261a7603addae4a871dd524f096e3cc8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-07252b31cd16e981a89837fbfefa3bdb Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6a0f065f968c2e70a7b9e40313a40c1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-501a34f1d2abf903069dda7f59619668 Relationship: SPDXRef-DOCUMENT describes SPDXRef-179897d6270100da605a4855a046ac01 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d12e02af8ad4343a35111ae9da80f13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b91579b39170cdea0bf515a6ad3adbfc Relationship: SPDXRef-DOCUMENT describes SPDXRef-481123e480df12b561a9d758eb215354 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d33bbdebf4d312750fde24fc43e35b12 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b0b015f33756bcc6ef882643c2483620 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a6b5db59a20b1fd6c75e4d74d34aaa0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-940593ba19731ddccfc83be6bb493b92 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8477db727a7d8d3a12af53a8a5f473b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4147b063229cda8c46b2af147fdc00a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-974ad148f2210d42842f7e3b4235126d Relationship: SPDXRef-DOCUMENT describes SPDXRef-6759060b10d5e7330fd50c31a409595e Relationship: SPDXRef-DOCUMENT describes SPDXRef-67cb844f9b31e1c6e0f24e3637a35fe0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dbfc395f61c09626bf7cdac3066169e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-32f080b3db8033925500641ef21f6f4d Relationship: SPDXRef-DOCUMENT describes SPDXRef-7adc4938c0254c5eb0fa35011ac9f43d Relationship: SPDXRef-DOCUMENT describes SPDXRef-e49c33369449f7c6f87cf7e9fbaef629 Relationship: SPDXRef-DOCUMENT describes SPDXRef-facc77d7c39be1a31eedeff3775967c2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1b5133cd094ed723df05c955abfa416 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0093cb09fe19314a3a8418578f10011a Relationship: SPDXRef-DOCUMENT describes SPDXRef-246f77b1dde2189b86db9858d67b9c42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a47c2b3f0446894e5a5cfe1b2d60434 Relationship: SPDXRef-DOCUMENT describes SPDXRef-868aaf203860f118c643129f4109c6cb Relationship: SPDXRef-DOCUMENT describes SPDXRef-176120ae47c8ccbb29ce76ac9559b346 Relationship: SPDXRef-DOCUMENT describes SPDXRef-16fe6f11fbcb92c5a4410cbdf0610b0f Relationship: SPDXRef-DOCUMENT describes SPDXRef-e1388d9fd73258b43791dd2a7418b361 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1ce7d9650cbeaaf61b93ed5b23a73656 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1104be30a12d4d3b6120ae626392c7b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d60e7c41576398cf0e39b77621a0581 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e62e205d295f5d7afb3c216fdb63bca0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4e4bb3566a6d91170f6572758c801a21 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d165426a220201c677af63f1735adb6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec8e37b8d6d76471aff8c2d4756663dd Relationship: SPDXRef-DOCUMENT describes SPDXRef-759c1bb1f1e19df20a5e7a71685bd3de Relationship: SPDXRef-DOCUMENT describes SPDXRef-8efd92cedb5c004f26f02a979266d35b Relationship: SPDXRef-DOCUMENT describes SPDXRef-772e19718e96a5e630d3e10371f18664 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ede1879524d5f833b04ac625761ea79 Relationship: SPDXRef-DOCUMENT describes SPDXRef-132fa788f3cf5d631e6557dc630204a5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-86b5c91acba34d3c58b77044a1405708 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87686c631b3a8bcade1c88817b1dbbcc Relationship: SPDXRef-DOCUMENT describes SPDXRef-aef137f39fc8832e526f08c17127db51 Relationship: SPDXRef-DOCUMENT describes SPDXRef-61aff72d8670bf654ca9a70dca6b3e0e Relationship: SPDXRef-DOCUMENT describes SPDXRef-993947b01b3bbc3c7f3a94c6843b20cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-7bc0b4954ba40a0253c04c417fcddd14 Relationship: SPDXRef-DOCUMENT describes SPDXRef-916fc558cf14bd91a03c46f0fd30de0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-170612e9c908a0827d402b02a084b4b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-588cc32456ee820f5b1ada0a346acf86 Relationship: SPDXRef-DOCUMENT describes SPDXRef-31094b49ed0ab90075830f94369d0e06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c7c27ec14ce9fa19c1726aa7a025818 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f2a56ab2d108c68c24ea72853c24128 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aaaee1d9978b314c3aacdb37a72ed886 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cc3658e2e60ae8b9929c7e3954e6fa83 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa3d29d94fc327628225f85f70f2ec0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a59f0b912c66832cdec44f51c90fae4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-816b08ee2ebef39b11ae9f069ff803e7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-61a4dfc649dcf71b94eb70f2d7b8b4e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d37929f3e0b2abcda6a8180ccbcb2b66 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1a2648b90fd1f428e4c047b232d2d43 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e3d3e0218869b1ea76a326f97071a32 Relationship: SPDXRef-DOCUMENT describes SPDXRef-496dce594d5abd765cbdbf66a8336477 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e1bb1a0d986e9d15d9ac5aea36e60e6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0feb3eceb043b614fe70821eadf3e9f Relationship: SPDXRef-DOCUMENT describes SPDXRef-6050934de9c83db00916e56c36670fd8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa8037dc46e168a95e0818bf06436a09 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f7bdc199c7c4ed778415f5927f88f67 Relationship: SPDXRef-DOCUMENT describes SPDXRef-36d7a070b6ded647a9db66fe768cb9ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-42de95307399437b22525510a838b471 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c94e9536fc5c0536fe01ccb31206b94 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7729d890052be88c46b19081eaae60d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a27f0148e1057b25ebd7e2d9249e6997 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cc03bc5fe8e4172c15f03ff9074a0764 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c0d52d74490013e0693021701fa2c3b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1c6ae748fd92d788a18c0b67a3155f9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87a5546851086483207fc660f3954025 Relationship: SPDXRef-DOCUMENT describes SPDXRef-163f455ff65dba069b1717ae5592efc7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0afbda35e04428429da6f44e269db6fb Relationship: SPDXRef-DOCUMENT describes SPDXRef-38cf061cdb375da018f3b95467f72d45 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c0bc90f6965cb772bf5c422707a11754 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cad0a2ee2ce18218056622cd134c88d Relationship: SPDXRef-DOCUMENT describes SPDXRef-135b581cbee4d7043c12cd1a6ce10e11 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c0e8588426dace1774e513dccc634d89 Relationship: SPDXRef-DOCUMENT describes SPDXRef-08c1a45a356f67644e2696e1ae245cbb Relationship: SPDXRef-DOCUMENT describes SPDXRef-bec64b4847fdbdddf85a55927f8b1681 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8acb259e83d72eaa2cf6af613f310fbf Relationship: SPDXRef-DOCUMENT describes SPDXRef-01fa86e1b5f4ad955fb02dc3b4482bf2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bf7e95d3b7c09df696c4e60bdb85abf Relationship: SPDXRef-DOCUMENT describes SPDXRef-a45568e09138f703af19299cf8c3f5aa Relationship: SPDXRef-DOCUMENT describes SPDXRef-d53aef9215450fcc88029c9c65525a42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a5e09642951660713357fbfc92fc206 Relationship: SPDXRef-DOCUMENT describes SPDXRef-292f0be3f8d3ecb9c18317be40d5056f Relationship: SPDXRef-DOCUMENT describes SPDXRef-c772772e57dd1450a26e02e4d7d303e4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-348d239afec4fb2c8749204c6fe6e3f7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3a019ad5530a961ef353462ccb057a1d Relationship: SPDXRef-DOCUMENT describes SPDXRef-4796bf0552a6b5f602ec580e5ff6d68a Relationship: SPDXRef-DOCUMENT describes SPDXRef-f79077ad83d917d48b7c2897153a1cfe Relationship: SPDXRef-DOCUMENT describes SPDXRef-770a36b3831d9d1b345847b1f22282c1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3240ccd168e59f0508f448c4faf3408e Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e641abe49d8d87018a2470544c60399 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d89a25c9011d1686d5ae4a8bc66a8dac Relationship: SPDXRef-DOCUMENT describes SPDXRef-6f7b50ed105ca9a9547596dfbaff2bd1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f85e1c5b675851c15845c8362b3e61ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-c3cb109813b52deea8527ffb4deb6a59 Relationship: SPDXRef-DOCUMENT describes SPDXRef-961bd79fb7c72a61ae53f4ed6a16da77 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c8436eedce60ea344b31fcd6083bff42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-254e2517067aeda2cc635513ae3641d4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-51ef8cd4bffa38fe35d4b6c59d18bd05 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b382c3415279a02e3ac655a81f56bfc9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a2421ae34c48ce704554bbc2bb7f8c2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e914b34d9c43edec151919397f54d49 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d9752b38155a853e2076bdeab95e9885 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1b43d6ef49ebe3e9b5155650f4241699 Relationship: SPDXRef-DOCUMENT describes SPDXRef-17a1f02ee5e72f0caff5d7838e71e21b Relationship: SPDXRef-DOCUMENT describes SPDXRef-16f970f0651be48f50c731f4eca938ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-62e6d0e251f3f606e3c199d8ff872121 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f7992df4051d894bd286f0906ccab219 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f2edbc89596d0b1027ea2e562d62bb16 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a44ddd2c2c0d8515d384692bfb30505d Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf272d7bcfef0a51971b61cc1e678af4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c53f0b2a895db52d35f118ec8d140a77 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e55d342ef9d0ac9ecdd787fcb92fe644 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a894a646b47aba55eabe27855e8c7443 Relationship: SPDXRef-DOCUMENT describes SPDXRef-80877ad90f7706b5843137967f85cbad Relationship: SPDXRef-DOCUMENT describes SPDXRef-aa5425403601563dd60509153424f430 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b2d32669618ad08f3c374b970ad5170 Relationship: SPDXRef-DOCUMENT describes SPDXRef-994120fa466f651e28a230c6b9bbbab4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1ba8a6df5e4827beb08ac0450cb1ae2f Relationship: SPDXRef-DOCUMENT describes SPDXRef-6113af341d78cff3f17c8687dc89cb5f Relationship: SPDXRef-DOCUMENT describes SPDXRef-2e4b6a8572be7c9756fb1a1aa15e0e12 Relationship: SPDXRef-DOCUMENT describes SPDXRef-78a390e7f750e109701ae326ab658a61 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae85e98a6cba421b883d32ec60756a55 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7313828096558e4720318bbd84e0591 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b945defafdadaf6b2914d99aab1026ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-e57cf738d200455e9e7288bb29771ae3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6f5bc7843c5104601768329e2f6cef20 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1dfb09309862146e9a4fc6599fcf0bd4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd2ccab8789fd1696d432c86a79e06d0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e1346fef67def6172f7d2e74a977f40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-775a0aa3fc3fadd27efba8e87af038b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c50f4e0d55ca657ec5f1ce17632ef3f Relationship: SPDXRef-DOCUMENT describes SPDXRef-0adf0e1f0f01c8a93c9954b8a49c5293 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3aeb049061a3acbc7dc3ef305d278d74 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b4a6ba2a3de96bd719545da688c3dda6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-974aa77a7daa1507775cdae641b7211f Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d5e5a06d677ce73218e36b1cf25352a Relationship: SPDXRef-DOCUMENT describes SPDXRef-e36c02a90302c32df7336701861fea5c Relationship: SPDXRef-DOCUMENT describes SPDXRef-b6059b2bf4ecd52e971d898960a3e80e Relationship: SPDXRef-DOCUMENT describes SPDXRef-8f67c2de4a7ab105648d68f6572d0750 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8c71834308deaaaf3c24b21be297f64a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec850e8960b24fb03d22ba1098859d29 Relationship: SPDXRef-DOCUMENT describes SPDXRef-916bd77aa5c7ccf1884660fe203624b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1e93444f7787c35fbd8f5ca25d875935 Relationship: SPDXRef-DOCUMENT describes SPDXRef-148e8a1d7544fbdc5ef863ee635b56a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a5f5251a17aa4196df0a281143b6a82 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf146a9e5a0b0986c716235a09f34550 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6a59b892dd60c51ce9e2a18d04a13f62 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b9963ac5995ddb6a502328cc1f128e25 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b7351c15379d357df2abc50cb7226ca6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a82c88355eb0e23fdd37326055b99b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e4865b631c9433727ce45ce57dd4629f Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd68a87e9c541619663bfc3b08ac517b Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1fa711d07ac354e876ee754e0ad454d Relationship: SPDXRef-DOCUMENT describes SPDXRef-bbb76a0ab95aa17ee0384851f4935d62 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cbeb24e25ab8d22e9b4c509062862d46 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68822f70d7ca5a0111adafb2661d3a8c Relationship: SPDXRef-DOCUMENT describes SPDXRef-79a3b6943f9002a742f9a8eb667a6cf3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f77ec75069e018573c9ef51789dc8285 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c7d92fc5516e3b7815b4e9c32e50985 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6acf1cfa5abed3f1ae6130368221fd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e1870264779bfc2607deb2c466fe2cb Relationship: SPDXRef-DOCUMENT describes SPDXRef-1536847692782f15a052d0c2525ce57e Relationship: SPDXRef-DOCUMENT describes SPDXRef-575dff72e63958f81f8802ff8367dccc Relationship: SPDXRef-DOCUMENT describes SPDXRef-31d2979ab26c2a059166c325fe283594 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9fb897e84cad01857b37197bb0f89a42 Relationship: SPDXRef-DOCUMENT describes SPDXRef-238d206a3728fa4faef7139f76666ce5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-65d8483046c4bf10167441d61a2154a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a820c537156b908ed3c292238f755cc Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb7d4835596d04b56c1539436b9ee699 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c4e41111a4b82f76779a0224208aade Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8ce51fb2698154d46fc7f1b963426ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-dcdcb0388221954fb3e7072936c05ebf Relationship: SPDXRef-DOCUMENT describes SPDXRef-a121375e2fb62f03d43a40bc0f9d69e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-389e837211be78033b1e14d65371e8d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82fbdc2be852ebe1776b024967229b32 Relationship: SPDXRef-DOCUMENT describes SPDXRef-873d14286580a45e1df30507d0c46532 Relationship: SPDXRef-DOCUMENT describes SPDXRef-626f59d993fb7f824abdc1fbf596c425 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c93c30cd210dbbd17b9cda261f961dd1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7915b2f07ad0ab2d7c50c45ad6b78b37 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2836acc4838dec7872d3e070b715790c Relationship: SPDXRef-DOCUMENT describes SPDXRef-db282e8551a124bdd2c718559ff3d552 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d6d530994596d1db72bce57539420f0c Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc857c98a37a02230c68fa88468b3e40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee1ca5d67ca019189c459d3438bc4804 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f37da61fa9503ad9acd798017996c57b Relationship: SPDXRef-DOCUMENT describes SPDXRef-7007ab8f3e6dcf6b15cdc0d7e62b2b5c Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e30231ce644427d4f82d29d9803387b Relationship: SPDXRef-DOCUMENT describes SPDXRef-a8255f02b5436a90be2082981add6a58 Relationship: SPDXRef-DOCUMENT describes SPDXRef-69a0103b832f8df33cbd0a95506e4603 Relationship: SPDXRef-DOCUMENT describes SPDXRef-082468f3c14799b874d8faf4dde9b8d9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2f10ee4ac5dc09ed78f93832d25f4bb3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a370deb8bb71649c52b0085d94b6fd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c2554df6cf3ba0277e78f999f57f022 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fc803922cdd113f4c576230ddd6b6cd0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-76e87788d83af18cf2f46ab37bd1ddc6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ebf8bbaba5041c7fdbe9d68e89e22b0f Relationship: SPDXRef-DOCUMENT describes SPDXRef-0d9c93501c6abdef0ccf7392aeaf9eae Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2608f7fc11a1f40f620b8ac3cd52deb Relationship: SPDXRef-DOCUMENT describes SPDXRef-28c3d6004c9a6a6094d6b9caf42638be Relationship: SPDXRef-DOCUMENT describes SPDXRef-3f3d8a668347abf26f2f0287bc7cb4d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d6db83b326be6baed008a8fc98331a1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-179c82cdf15cf97d19b82f805ad8dac2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a13155dddbf7f064f9bf399374a94bb3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f97d8885919f561835c1927e6d0a763f Relationship: SPDXRef-DOCUMENT describes SPDXRef-5ff70ac1e64cb4bd328a381eddfd3fa4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-13364337050aa83013a3c0c0e28f8380 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d0f23f759884fbc64317c91773879d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2b05b42cb004f64ed48cbeefbfab97f5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8eb0d1a0933df180a96fa5583eaa5f3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd2903d2b46ee91e64eb512f171552c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2f0277159cfa721c8051b30795ca6319 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8f4a910bb39468e4186e867aabaaef13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2266c29216df8767d3f96032a8eb0320 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d980a0681681d026d179c636bbb18760 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ded58306b8c6480d850778f12d72e696 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7574c9bad885b5af463fa7d37884fad1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-672d54b85baf3ae5a77057c8c8bbe432 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cacbab71e5c8e9407f5754fa3feb2718 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8de24247f9ac6cd8ddd5f500a7d1892d Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ed327417e1e86b099697d794b7fb8a0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dfb70b4fd08f7e7c74c867da08ffc2ab Relationship: SPDXRef-DOCUMENT describes SPDXRef-7df00e3984218b2870e7d4a08677cc76 Relationship: SPDXRef-DOCUMENT describes SPDXRef-959897fe5773080a76888a4007b66ade Relationship: SPDXRef-DOCUMENT describes SPDXRef-9ce9bd1f90c3810b41320f13f616b2ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-8723717ef1f14703b08c4b3e50b2ca2b Relationship: SPDXRef-DOCUMENT describes SPDXRef-9f2a9313e5a1ad15f4cf8d956fd38c37 Relationship: SPDXRef-DOCUMENT describes SPDXRef-00cd66cfcbf09f1c0ec184c8c7723038 Relationship: SPDXRef-DOCUMENT describes SPDXRef-cfd048c0f0f330e3ef9b544db265e48f Relationship: SPDXRef-DOCUMENT describes SPDXRef-df38dcd65f33cf3a4a594213624e8ff0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-83d8a4b26db040af6e8fb6701cc23a3e Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d48f50f911572a1411d648e16800196 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b016e5f217f85f28e00606031a4412f8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-744a53a33e81cb7a04c4f97271f0e439 Relationship: SPDXRef-DOCUMENT describes SPDXRef-28abef070c9ee21aa9c29c727e5fc832 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4fef05a528ee005648040fec0709ebe3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-55d7961e0970fd57ae982ae95d565328 Relationship: SPDXRef-DOCUMENT describes SPDXRef-03e6a30cec4e910670075526e52b5319 Relationship: SPDXRef-DOCUMENT describes SPDXRef-55626d6d17fb5d176e70bca01b0a7c85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4cbeaad23f6e26789207bfb61d1709f6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-810c41fade94b0733d454bb38dd48a89 Relationship: SPDXRef-DOCUMENT describes SPDXRef-862cf98dfca1332f35f1167541e9815d Relationship: SPDXRef-DOCUMENT describes SPDXRef-f6fac2bc75b94b957683bba7389100e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a08f1d17894125450bade5d5580b8c72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b80cbffa89f06039c98af89b43616139 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a6f58344d79ffabd8c52ff8598aa6644 Relationship: SPDXRef-DOCUMENT describes SPDXRef-77c6e6be59f605f37863e8dce85fcfcf Relationship: SPDXRef-DOCUMENT describes SPDXRef-95f436dbb17632fa7b549c34e16d7351 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3cf2b627184fcbc79f1de0d2ab34beb2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-76e5ccc29fc83a055bf534deace5cd0f Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d818f38496914fa2d5420b16843b9fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-779e810740afc16a6d64017130825747 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e11cba9897024ad4fd8a118eb6d93d8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec5a5ab88610b89fc9736d43ff5b0a94 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1bc59ef35a5050cfce2e6866d6156ea2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d63d57670a9ded7feae33e4a185c7fdf Relationship: SPDXRef-DOCUMENT describes SPDXRef-6e20fec2842e80c60da26f65f6cc1e8e Relationship: SPDXRef-DOCUMENT describes SPDXRef-53a41db3dc012f87455ebeed43011786 Relationship: SPDXRef-DOCUMENT describes SPDXRef-640abe1fa9b8b87228b0a21a64b5ea31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-29b30af3bdf03ba2bb2eaa44f9510014 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aa0d5592afd76423909cf117a4a04a30 Relationship: SPDXRef-DOCUMENT describes SPDXRef-520bce09bfd0168c6128112f083c74b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-12f913d22faaedfa5c90e9fd7562e48e Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a0d78cd1e7ca2ee54ceca16001c3d77 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a81d1569962efad1492484084da2995f Relationship: SPDXRef-DOCUMENT describes SPDXRef-d99778ae9f0fb090a5552bebeca1b69a Relationship: SPDXRef-DOCUMENT describes SPDXRef-3240029248bce7fc6cbb384e5c4727c7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-14d860974cd114a05436c5892462676b Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f01b49e2404f5ae11fddf7bcd4b5223 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c36e538bfb5aaf6e7466c3481254e92e Relationship: SPDXRef-DOCUMENT describes SPDXRef-0029ca92d68e4edbc0ae70f5c178b24a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac120e01baaa145254b1f9f92b3a7b8e Relationship: SPDXRef-DOCUMENT describes SPDXRef-527d31f033858afb8f0e588c025569ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-1e2d88c2c8fb98f646d75a434defcd60 Relationship: SPDXRef-DOCUMENT describes SPDXRef-73d804dae502ff21344913c6ce677e08 Relationship: SPDXRef-DOCUMENT describes SPDXRef-487f70bafa5d29eed61db2b458af8a5f Relationship: SPDXRef-DOCUMENT describes SPDXRef-174af76267ad8c5b1fb0aeab988b3b73 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6993a3cc52274e9a7047fa217c75a86d Relationship: SPDXRef-DOCUMENT describes SPDXRef-8202889ffd9e0956c455560991590978 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca9ad54de2bf3d0f181b97193f23e2b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0fae2250cf15eb53565cccfae4678258 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7f731f823be6184ee552cd662ae6a63b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2f336f2ee29e68bfdf359d8bda5a80ba Relationship: SPDXRef-DOCUMENT describes SPDXRef-056aae0c8c5f38bdc7660b4bed7bf012 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0d30656028758ef5ab0f8cf3b09b4cc Relationship: SPDXRef-DOCUMENT describes SPDXRef-2384c1eb5b736fc1d7c03030007a6523 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1572bd0b0786c9bda6f3b5a4cd6b3a8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bcce30ccf456059fc39ca99472ddcc47 Relationship: SPDXRef-DOCUMENT describes SPDXRef-24f5e9e13c13c9d03a0673921944c074 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5e219e6613f2e55e2c0ffabff84e1600 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6345dc307e2448f36a5640344dfd377c Relationship: SPDXRef-DOCUMENT describes SPDXRef-6569791eb0b54ca30a8b1b3498c52654 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c7fe1e2e477aa9059d827cc628055b72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-abc5c08f2a73db50f946ee19c6790145 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5d4499a75aa1917a8fb9c31cc063476b Relationship: SPDXRef-DOCUMENT describes SPDXRef-b3f49d3cec6dd0164507095f89afbd44 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a79c8d71d5ac7c6c77b91deea26819a Relationship: SPDXRef-DOCUMENT describes SPDXRef-0c1d75c8ac0b0383f0441bda77c5e1ad Relationship: SPDXRef-DOCUMENT describes SPDXRef-3a5a119f931ff532776e9f44fdf865cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-6c47bc02b131820d9cf7931be2cddcd9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e33975ef0a7d4d7bb756dc221e5a8410 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b441871b4100ac3ba52c9d24fcfe8601 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1084dfc626d2f321fb95dce65ed024b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-19ca13e602d0bf232b6e2b2b86fd36cc Relationship: SPDXRef-DOCUMENT describes SPDXRef-cc4c790524390a11b1a035029847da3d Relationship: SPDXRef-DOCUMENT describes SPDXRef-806ec779ddc919bc01ed469acdab64ea Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d58e4386164cdcb847914c86de8061f Relationship: SPDXRef-DOCUMENT describes SPDXRef-170619d068bd5ad9ca0cd7af2f8aa01f Relationship: SPDXRef-DOCUMENT describes SPDXRef-87c6f9ea3e4f66e57e5f824b4233b2d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-06ee1ba1e1d6b705a67eb82b3390f9ac Relationship: SPDXRef-DOCUMENT describes SPDXRef-d4c942b280a65cdb060752d89aac9c31 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c02e63b7770270f7b08f9fc20af6c595 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d37872d7ea1d5a58350248ac6ed58d8b Relationship: SPDXRef-DOCUMENT describes SPDXRef-c80058b223e79bd1d006d606cee2f632 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82d72303e6791579ea24ef972aa04946 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b4035771154f76e38bce74876202fe5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c780271efa5ab01e58e76dd69e11164d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a30b535b3067e7df850d7bb37f859b27 Relationship: SPDXRef-DOCUMENT describes SPDXRef-022838d029c287d17ae79d40f79dc913 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6c3961849659f7dc91afc11e1132ef72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-80f61960db2f9c43cd15702aad36a222 Relationship: SPDXRef-DOCUMENT describes SPDXRef-457ad98c6842a454c67b33d1d5d99b2c Relationship: SPDXRef-DOCUMENT describes SPDXRef-a25b0f4ccb81f99f6b818b5cde54cef3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9c4f6013dd37c855c2e8c81f45d9d676 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e463add4c047661e2754dba83151b37 Relationship: SPDXRef-DOCUMENT describes SPDXRef-db0c435f13eca8ed5700a3e18b3d0176 Relationship: SPDXRef-DOCUMENT describes SPDXRef-42cfa4503b6af696008c6e33f5d70f7d Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1f1ecaaba8ac246be7ed7a999705556 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c819f8e675887174720d390589b5a08d Relationship: SPDXRef-DOCUMENT describes SPDXRef-040ffc258f22c4adfc98d789accd5e43 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c7f74a9c5c3f64753b02e051da1027b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-802a2c771652bd8fd724427f082f7452 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0f10431516b07a07f196d37a1124646 Relationship: SPDXRef-DOCUMENT describes SPDXRef-71c8a1ebaa1d390e782f3e53648e7b07 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c306e046835cd296a3ae842d783311f8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c71786f88ba5fe144f72e3a29bbeb1e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a1b73c6e1bec952bf7c806e8cbad91d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b9b3c348448533b1ae243f63eadd6db3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-784d5653828bae64364386a9856fc124 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dee912dc21ee4799a176e633f22ba29f Relationship: SPDXRef-DOCUMENT describes SPDXRef-3df0411710e68d958c7c09593dee76bc Relationship: SPDXRef-DOCUMENT describes SPDXRef-0a16de12bf5a0567f0523f0c5213bfe0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5051613237f295afa6dd95f5884fd2c8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-97b1b5df13a4eecddee1932e0f5f6ba8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1e0aeec076ed2d2c6dc139b366a2d7fd Relationship: SPDXRef-DOCUMENT describes SPDXRef-29ac2f8f8d6f4eb0520b1bf4b404de96 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fef4188fd87f511ad313b5b6f9ba4375 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1fd32e6835719510ec89515353f16b5a Relationship: SPDXRef-DOCUMENT describes SPDXRef-b5b7c3bb5f845d71035546c3481b677e Relationship: SPDXRef-DOCUMENT describes SPDXRef-3f5b2547ef502fca6ae6279c18f664be Relationship: SPDXRef-DOCUMENT describes SPDXRef-f5ca5b629b681a6ffa91e9566aa9bbaa Relationship: SPDXRef-DOCUMENT describes SPDXRef-c870e7382831b13e2d877cd6ce261457 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d4a774f198d815a08f0a829f0e9673c Relationship: SPDXRef-DOCUMENT describes SPDXRef-78fd649b8c0526c0ec455387d4d78571 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8d0b841d1f98d385e6faf290088abdbb Relationship: SPDXRef-DOCUMENT describes SPDXRef-473c8911ab3aebcb5d43041207818698 Relationship: SPDXRef-DOCUMENT describes SPDXRef-41f16aa9f373c7130509e4c33a2fb3a2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8e5b0b3ede2bf14dc7c63050dd6e6cf6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ec619ee5ea13662b5fccda4fe6d6c99e Relationship: SPDXRef-DOCUMENT describes SPDXRef-16bdab73392f548ce4b9a7c692b50bf2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-afc33db8c69189030d91908f6a131736 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2dd59dec8bed934b60d3893349e8cc39 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6865c09f4b96627bb053c6962db21908 Relationship: SPDXRef-DOCUMENT describes SPDXRef-20f2a6ab0f3aacc2dc90eefaf660d82d Relationship: SPDXRef-DOCUMENT describes SPDXRef-752d323c08d1b4e372242adb1c460438 Relationship: SPDXRef-DOCUMENT describes SPDXRef-540a03ccade1fead0cd7d9c33fb754d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0884a6f89f9562425b96739defedc25d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c8367bd1e45d14993b1c781aa1644f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dcca9c54b74dfba7f0933d657bef19c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2def26b3c32df96f6f7558a6055b0cf6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d368d97c1550809399188a31e7e49219 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9ef7a4e98c5eda00ee02b7156778a223 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2d0eba3c3e34a57886fc371149dc6f52 Relationship: SPDXRef-DOCUMENT describes SPDXRef-791087ac99e14596121b88a4fc79e9b2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-56f13f08f4b19e259ae6ddd280ccbc77 Relationship: SPDXRef-DOCUMENT describes SPDXRef-32e6e3ad59e3fec80c043168760ccac5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0da39e9bfc40c4f4b48c5876c7be2228 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8864453396fda104e392910940bb27de Relationship: SPDXRef-DOCUMENT describes SPDXRef-92f34bcc5680ef1f71b49952c96c4b6d Relationship: SPDXRef-DOCUMENT describes SPDXRef-74baed07e7c0097e813405e063e585b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1d7f068b4796ff4a48d49457a25a15b Relationship: SPDXRef-DOCUMENT describes SPDXRef-6f009c00d52e8721c2b5bb0877aefe88 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f5b5d2472fe70fb27944e10e8e8b9788 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dbf7cd36d5dcabdb0b640a9a0072d4e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0e0e8450165ae5bd1ec6f153cf0e7eec Relationship: SPDXRef-DOCUMENT describes SPDXRef-95810a89309e0fb19eddf0a8218ced82 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b40543eeb1c373d34f0d466bbae434d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bcbde09f7f6a88b66c4a0930e0738d5f Relationship: SPDXRef-DOCUMENT describes SPDXRef-405f1e36e08a8153f9e8ec3846719cfa Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c298eb484863f540f3c7214efa32463 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0f75612a1c967171487285b36e7c2c50 Relationship: SPDXRef-DOCUMENT describes SPDXRef-547473d45a797e662c36204f8d63cd5d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7ff50e0a05365c10b75a8f2265bb3df Relationship: SPDXRef-DOCUMENT describes SPDXRef-df54e8729f72a7e0107bfb4124f562cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-3fd9091fbf43a525cc7b2e77aff0cfa3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-48e73fe0f00fe0fb08b15631bbf60fd2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dee8e27886f06162fa6536248607a937 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ce98ed39ae34b0d175961d5d9234ecf4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6dd3302214e3aaeb19745d3479c9402b Relationship: SPDXRef-DOCUMENT describes SPDXRef-3d31023a3ed945741bf4e1e04def5cf5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8a685adac362e1b09b33fbd11b82e898 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c76760099495c2be1f13e5d47cc8a24 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b34aa1406010b4071cc114301f020319 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c4f7119a824ca774964ea9238f9e9213 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7e5b9258a563675f4bc76e753153300d Relationship: SPDXRef-DOCUMENT describes SPDXRef-d2439b00519ddb2511ac4fe2f57ddbd9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-573ea3ee2c42fca1a9493ea7d2f1ceae Relationship: SPDXRef-DOCUMENT describes SPDXRef-9b4455896965e5d27ad0032fdc660cab Relationship: SPDXRef-DOCUMENT describes SPDXRef-68f668ad659454cd78427d7f601bd9d5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f17babc320da30972a19078105da194 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87cb21e39edf1fda58fe56a198e9a2bc Relationship: SPDXRef-DOCUMENT describes SPDXRef-c327b7a6e944ec429ecc9cff2486a2b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-32f17f92fedabbfdaf86e508d262ca5e Relationship: SPDXRef-DOCUMENT describes SPDXRef-943b58b1d1fb93230a396423b4f9fae7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c26ace27d958d9176f97c3089242efec Relationship: SPDXRef-DOCUMENT describes SPDXRef-e73ca993a44b43b25ad546d09d77d921 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e78a25f6821a3bfaa088f53f60785ef0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-337a4f06bad916d50327ecde24baf3b3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1b98f416fcd1c99fdd37de41cc829b9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae8ca64467bb380b0a45953726cec492 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d104d62c2027b524813451e2f09bf893 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d93437c13e60952ecfe9363f6b790b68 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a5c522cc3c2c09ed1115e1132c08ce6c Relationship: SPDXRef-DOCUMENT describes SPDXRef-fcc8c59ee819eb8dd1d590acf3afa73a Relationship: SPDXRef-DOCUMENT describes SPDXRef-ecedd6580991173a098444e7b0bc2942 Relationship: SPDXRef-DOCUMENT describes SPDXRef-920265e262715b8175e72918a13e88f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-44fee6e6a520dc1dc52a0a913ae98890 Relationship: SPDXRef-DOCUMENT describes SPDXRef-eda9f4d14ac6bccb19a62ddb228084c6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c6e2adfd2292db7559aec2786c94af91 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c76219737bacf504112df1105bcbce0f Relationship: SPDXRef-DOCUMENT describes SPDXRef-e65ccb2e1be9849128b489c6006f1ffb Relationship: SPDXRef-DOCUMENT describes SPDXRef-2bbcae3fe3318befc148e5c60fe0bb78 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4cc7816e122b4f804c92a4be09137ae1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf64feefb45402a1ece7cd5584778cf3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8214ef8cfd192fd1c7454d99ef450f80 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f2ae33e8eb011ee58c2d09499ea5bdc3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8dd9151e2a0b1a89d6224d68a959ac2f Relationship: SPDXRef-DOCUMENT describes SPDXRef-e19079db2f93281a66018eb657ba20f6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82337c35a3b6e5bebe5b0a59291e7908 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7717a99273759d5f81f526cb6a462ed1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f35970cd7c46d7b3fdafc80e12786824 Relationship: SPDXRef-DOCUMENT describes SPDXRef-bf0a5fc441dae45f51cd9a0cdb8aab62 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7c0d459be569f5f125578f63b95b4381 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1913a73ba8f8c7483866a784e45e5037 Relationship: SPDXRef-DOCUMENT describes SPDXRef-049a5a921335f6d491d3e8bc42c4d2ee Relationship: SPDXRef-DOCUMENT describes SPDXRef-920c558b3fed91eddc3853e590cabb0c Relationship: SPDXRef-DOCUMENT describes SPDXRef-b372a4f8782ca35674c8fcba60b91e1f Relationship: SPDXRef-DOCUMENT describes SPDXRef-80d143c4c355fbed1917af97ca0500ee Relationship: SPDXRef-DOCUMENT describes SPDXRef-de4dd9a3d8fe083d70f1ecb80b7a28e2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-68b14268ac5faf2a9d3cf36c8cffacbc Relationship: SPDXRef-DOCUMENT describes SPDXRef-a7f211f226e787a6ed3d46dd11929913 Relationship: SPDXRef-DOCUMENT describes SPDXRef-721081ee5e66c0b615f1c4d5e9e52f3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-849e259e210af3a81f93846458797fc7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e9c1f543ab0a4fd63e45d9aefe9957f1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-15256e96680dd668b94e8fcd1a298104 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1fc6eee2f4567398ce7b3f447b733cdd Relationship: SPDXRef-DOCUMENT describes SPDXRef-f0c2510a0df8b33890698d4c66b3346f Relationship: SPDXRef-DOCUMENT describes SPDXRef-589a177ea060dcebf6080262ad7507d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-979e121aec1daa8ffb2e91d37497d22e Relationship: SPDXRef-DOCUMENT describes SPDXRef-c17bc45fe8e9ecfe699e57c463f61d69 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2b39c59bb5d108271e6ac718eafc6677 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9a3a14f0b010765a95845d8c9cdd6a8d Relationship: SPDXRef-DOCUMENT describes SPDXRef-b1caf40b62be07d5f1656e52bbf13484 Relationship: SPDXRef-DOCUMENT describes SPDXRef-53abb0eaec77793655baed90ba5498cf Relationship: SPDXRef-DOCUMENT describes SPDXRef-a470ae12c98a082586981fa7512db2fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-a3bfcd19be45a7560bce560aaca3ff09 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e90d38c4a562d02d8f9625551ec663f7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e4ae6ca0476a1b6da6a880ae3a7b8de1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2792712d05eba2025039df667744a025 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c98c80b07e79d528353ead6ced9e46a Relationship: SPDXRef-DOCUMENT describes SPDXRef-df78927cba1f348412ba383b7fee013e Relationship: SPDXRef-DOCUMENT describes SPDXRef-6ca038bd55e0558a50de908de3e5be2b Relationship: SPDXRef-DOCUMENT describes SPDXRef-88cd5e89c69636f73786f0271752684c Relationship: SPDXRef-DOCUMENT describes SPDXRef-affd847516b2f957940ad072e8dc3628 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3c2906ee62fc7838dfbe603fe7b5addf Relationship: SPDXRef-DOCUMENT describes SPDXRef-f632f212cb44422844a6d60cf16a5b48 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3b2ebe4ad4ed2635be764cd18f7e3f1f Relationship: SPDXRef-DOCUMENT describes SPDXRef-511712638158a83b0dbfb24427e43f4e Relationship: SPDXRef-DOCUMENT describes SPDXRef-daac5d00e2e47da21897bbdd42dbad8d Relationship: SPDXRef-DOCUMENT describes SPDXRef-20ef9d012db5911f644347e9575496cc Relationship: SPDXRef-DOCUMENT describes SPDXRef-e2598e157f998bc0b4ab4e39a780c334 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9ee134ac36d702fe2d22d5b0f22f88a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d3335525f99847166d088d7c2f6ec6b Relationship: SPDXRef-DOCUMENT describes SPDXRef-add295261dc1f41d84cb99b2cd555c8a Relationship: SPDXRef-DOCUMENT describes SPDXRef-d8f2f4578165ea0e54f7cd2249df0f8d Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa6aa5a5335cfa2d190f3fb5b6db18e9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c28db1b4df4fac8c80465e4e1f1642fc Relationship: SPDXRef-DOCUMENT describes SPDXRef-32dc3ae635e9c013704da8a970ddf3a6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-14549c7fd01a6845cdf40d7642706dd6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-67a47c97dedbedc00deb6ec5d8153a3c Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf1dcabfd2c831a9001c5eeabde00322 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e39445d8a0bf29194213b50e9f522e69 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6962131ff9e6c5b8fd9870633ac11877 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e00871db584a32037cd6fdaed23ceb59 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1b2031053408d2882c2553d3bba80c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-03892a6ee288721c90f3d956146c4eb6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5694b590351195e46e05e135e81246da Relationship: SPDXRef-DOCUMENT describes SPDXRef-91a07fb080745073954ef230615c3906 Relationship: SPDXRef-DOCUMENT describes SPDXRef-252b123bb27c41b54b7813429ae22f05 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a8e9567fb92e28bd5c2457b197580aab Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc604730c20864c6702c6a2944cf2e48 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6a2a0f65f70dba3d80e55b58fc4c411e Relationship: SPDXRef-DOCUMENT describes SPDXRef-2856576895282fb4bdc7090b0c2c10b9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-29ade1e0685453e29324279d19bf7a85 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1791282a8698ce0760505c46d9f6ab72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-98267dd84dfa750b5f95b4c3837d7150 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c8ccab643e3897d9edef6bcce17f702 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f9279c63d8109b7d45d3e6ddc0facd6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-45ccbeaef7242f9fe49786fd69bcb3ff Relationship: SPDXRef-DOCUMENT describes SPDXRef-67245fffe0fca5e22b4f16ee2f1f0003 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3bccd0e52816a0c39c6fd25732d7a4fa Relationship: SPDXRef-DOCUMENT describes SPDXRef-48a81033cecf81a00e43871443ccea38 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f1bf064a0a28a848bbee8022946d6f4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-cefbfc01e125035523706ff64aaebc47 Relationship: SPDXRef-DOCUMENT describes SPDXRef-82c74a57ae85de23f1137db4c8dbda61 Relationship: SPDXRef-DOCUMENT describes SPDXRef-da4eae501dc1050fc453df71108f3df1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f8735ba34d68463bcf78679f2ef3e17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-af2f3af0174ac2143da732be6be353c7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-31828871ed5de3ecf08b3a1ae07b59f3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2c12b3d3dcb8c767b42ae1158ac5d4d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fee59f80d58432c63e568d3fe5ba3417 Relationship: SPDXRef-DOCUMENT describes SPDXRef-54720d87b38b234eba5906700046671c Relationship: SPDXRef-DOCUMENT describes SPDXRef-d315f47067981889ea4ee03e246ac5db Relationship: SPDXRef-DOCUMENT describes SPDXRef-77966834ad953bb82519d2f7e4cd0abb Relationship: SPDXRef-DOCUMENT describes SPDXRef-670d4e27bb119cd896fb4976b3fe52ab Relationship: SPDXRef-DOCUMENT describes SPDXRef-bb1c93c10117ea3e9e3eb02610370a2b Relationship: SPDXRef-DOCUMENT describes SPDXRef-261057fcc0ab2f20a67daf4b9e65499c Relationship: SPDXRef-DOCUMENT describes SPDXRef-58c47b8160ab9fc55cef1d739b1cf81f Relationship: SPDXRef-DOCUMENT describes SPDXRef-9e9b4cdd52e97b4215a2111fde8c4183 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1e56a88e781740f0165a6a23f3c61d40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-817462c6fceaa49e3444e2cef953de21 Relationship: SPDXRef-DOCUMENT describes SPDXRef-620c6e3f1f7ff7bd8031f23e1a5227e3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d586e0c1a9c9fcf49e3dc7c335dc8b2d Relationship: SPDXRef-DOCUMENT describes SPDXRef-1aebe5f71944d24192d7509a70fad0b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3607484298296090b118162a3de2fb53 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0dd0cac7192ff559a7d7a2e0ebefff19 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d1605924cf8b30d9ac34c379a13c4841 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3da77b6626ba190df12009f2e75cefa Relationship: SPDXRef-DOCUMENT describes SPDXRef-64c09d482e8fc6cd80346c89d1fe430f Relationship: SPDXRef-DOCUMENT describes SPDXRef-607184b3d6febf4f66ccff01cff8597d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a89995c89e724b5fdd90b5cf30a1e0b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-34ad943cfcf1615ba250cce27fe30f08 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1a94299cf2b7fe916e0052573c1f4a36 Relationship: SPDXRef-DOCUMENT describes SPDXRef-1f66d2417a307f752ccebc5a3f6c6998 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dbb5a794997374d80c5adc43a50806f0 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2735248e6a9cf7b385a9a013429f2a91 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6e87f896b8951fc89dc4aec561bd599f Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ae940fe4b73deb03108c31b8569747b Relationship: SPDXRef-DOCUMENT describes SPDXRef-e3ba2ed0f6f8c6c343c3581490538a20 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f68f087e17977ef7a118336507372f16 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9183dd066ad3b6c1480b82259535a5e1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c553441fec6a47f1bfcbca45ed054f0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-2038c8361bfe6ba6cb903a3998f891c9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b2a37c155f169567bfc16825bbb8ef1f Relationship: SPDXRef-DOCUMENT describes SPDXRef-2ce039985365f9f2bc0bfd0cbaff486e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1416a4a4a97b805646c7b51ef72e3877 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6dda1fe889f5e5616191fbdcc2cb8451 Relationship: SPDXRef-DOCUMENT describes SPDXRef-8cf6f08d59caecb5508d243832b71a1a Relationship: SPDXRef-DOCUMENT describes SPDXRef-81a3b2e870c541d1b9672f79bf477b95 Relationship: SPDXRef-DOCUMENT describes SPDXRef-aba7ec2cf3f92b30c5b906f551ce5611 Relationship: SPDXRef-DOCUMENT describes SPDXRef-efb17461ecb3af1ad98a02d8b7fbc4ce Relationship: SPDXRef-DOCUMENT describes SPDXRef-a862cdfcc39b29dea04403144aec64b7 Relationship: SPDXRef-DOCUMENT describes SPDXRef-87637dbc2ccd6f438d7b69dc28a8a104 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6d63ecc6305cf43b23f948704dbe9030 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f9c35b8cc88155af58c4fdb8f6bdbd0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-11bdc89255c47ae42c8648f1e17084f3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3a799526632fc357777b93c5beb30a79 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a9d55c8358d03bb9e3a6d4f67aebe05f Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae30d322bb7f73ca555673957054e259 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f902511b1e5d98761106d92ad151207b Relationship: SPDXRef-DOCUMENT describes SPDXRef-ca20731eb6df1ef9b92cab3df99d2d40 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dee6ad0a6a93ed1feef8f4bbadc266b4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-322437b665d045b4ba93f4d9641b08a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa98a4095c1344335433f1bfea42b8d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6be6038dd203a01e5c57403ef9c6f397 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4bcebce0b3c46d6fa54643005aa6331d Relationship: SPDXRef-DOCUMENT describes SPDXRef-5c21615d3a81ebdefbc428b75055ca2c Relationship: SPDXRef-DOCUMENT describes SPDXRef-05ba6714af9d7232f79e93647091e192 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d72c7dfa9fe7b377b09d5b88b6f0d5d Relationship: SPDXRef-DOCUMENT describes SPDXRef-635c37383133f427a9aab004a60e26b1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-05e11ccdaeb397f1f8b14f28861abb00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a0cbbf4b5ea20316c47d8d8bb85a5722 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7a6f769e42a04a71caeb48290a49229c Relationship: SPDXRef-DOCUMENT describes SPDXRef-20c56ef497bc7b6f18ca3e9c96769e63 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f3081df03c0838fb968adfc61fb2c204 Relationship: SPDXRef-DOCUMENT describes SPDXRef-85e7eaf3f955b39f1b181b3c5fac24cc Relationship: SPDXRef-DOCUMENT describes SPDXRef-f47851034c2193f27aa0c98dd491e6db Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf97905c4e7cc9ce86e7fb3c5263b4d2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f5965acbb583def2ee92f4fcc4e4ea4 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2a6be72aa1394c254837c7c7491d3ef3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-01dbf0ee30aeabd66278ce6ed75ad01e Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d46db12adcb6a049a039b9a9afdbae1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-743023d30abfdfdd84c1dcd40b07d1a9 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2672ea7c206528b4b7346bd469cdaaab Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c7e2066ab19eb93da3b93e32413be7a Relationship: SPDXRef-DOCUMENT describes SPDXRef-6b41dd7ba14400cddc8ea468e73fb39d Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1e751b09dac1ef8e15f06879492b63f Relationship: SPDXRef-DOCUMENT describes SPDXRef-7552ceb2a6696cb5115c87f459089d78 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d02f3fe908c059de4aa7b5aa957b5a97 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d2a73d591530023265a63b26725dfb1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ad65eaa87bc8751c4176b47026ecdd5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-062f76f2bc58ddba94c1ce4cb5d2d804 Relationship: SPDXRef-DOCUMENT describes SPDXRef-0617fc7405942ddf154be7a41aeeaf6e Relationship: SPDXRef-DOCUMENT describes SPDXRef-58b08276a97ccf72fa55c44417e1a70b Relationship: SPDXRef-DOCUMENT describes SPDXRef-05943e15e55600d3c41622bf1ae4733a Relationship: SPDXRef-DOCUMENT describes SPDXRef-981abadb97e42fb4c9dabb83369a9c54 Relationship: SPDXRef-DOCUMENT describes SPDXRef-47aaf4174a808208e814d6de769be190 Relationship: SPDXRef-DOCUMENT describes SPDXRef-496e37e69c8a84a47d20b94bc95c41d8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5dd68e226c16a197c7ac6c0f895ae8ec Relationship: SPDXRef-DOCUMENT describes SPDXRef-ab126e8a1e4aca3dcc4c700cd2ff4920 Relationship: SPDXRef-DOCUMENT describes SPDXRef-3230239ee0eb33414d9d7817809f3a72 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ee0545c4fe52d93217b7a02e1b0c95c3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-a1501ae5739d735c4183fff39184d847 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2e88264a79f56bdc26e50691a8b5884e Relationship: SPDXRef-DOCUMENT describes SPDXRef-1cf2b68c17e4bc998b93276ee710a410 Relationship: SPDXRef-DOCUMENT describes SPDXRef-53af0493e4a9cccc08ccc664135b5e03 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4f1db5f114aae513247b1cdd2a1875b5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc09b90ee5a2b46037353ced487d15ab Relationship: SPDXRef-DOCUMENT describes SPDXRef-ac2ec7f9c924435dc85ca24b35eb8eae Relationship: SPDXRef-DOCUMENT describes SPDXRef-ade7e83efacc00a4b9c4763114f87217 Relationship: SPDXRef-DOCUMENT describes SPDXRef-eac69f4a097865e0ecaf3b06f1d08644 Relationship: SPDXRef-DOCUMENT describes SPDXRef-03d948463c1b04127991dac3decd674b Relationship: SPDXRef-DOCUMENT describes SPDXRef-cb0ed08a465f0b83314cf9900628eee5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-699e286cd37e13cae7018a2f6ee49094 Relationship: SPDXRef-DOCUMENT describes SPDXRef-925d70b0aca419f6bc87c6e3e0786d09 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ccec4dd63b1c6adff0dcd277c43e3d82 Relationship: SPDXRef-DOCUMENT describes SPDXRef-43a00c1709fa96704ecc540d601fa4bc Relationship: SPDXRef-DOCUMENT describes SPDXRef-d14486bd85f1430dae1a0e161e9a330a Relationship: SPDXRef-DOCUMENT describes SPDXRef-cd753294c4d8f7619071801170b55e13 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e783e4dce1e39dbfcc4b167faba3dc4c Relationship: SPDXRef-DOCUMENT describes SPDXRef-cf0829c8ec3d41e3e630703f06fd77ef Relationship: SPDXRef-DOCUMENT describes SPDXRef-4c454f0d07bdf86bfc7ff71278740553 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c3d8a4a4df0f5c482df9157183b66b78 Relationship: SPDXRef-DOCUMENT describes SPDXRef-ae48bce53e1adfe774552333d9764716 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b22c05797254a66ef96119b10ffd3220 Relationship: SPDXRef-DOCUMENT describes SPDXRef-19be4b2d069cfbe79d4ba6ae89f6a522 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4e9d7952418a48416199479cf64f33b8 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b74af3e1ca6277aed97f8f0f2f70d948 Relationship: SPDXRef-DOCUMENT describes SPDXRef-fe1a417d10adc1e99195d01760ef9e4b Relationship: SPDXRef-DOCUMENT describes SPDXRef-f19377967a984f8168b929ca5db9e98b Relationship: SPDXRef-DOCUMENT describes SPDXRef-daa2aedac21fc35708315747beb3773d Relationship: SPDXRef-DOCUMENT describes SPDXRef-05f10c5952cbc130ddb7a4eeea0cb54f Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d3bf8e9ff8dfbba4c6785df8f3502df Relationship: SPDXRef-DOCUMENT describes SPDXRef-1c84ef30ebcc6c6dbc0bd9fdb7064654 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5abbfda2a154d8b318f15998035fd031 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2b07660d3745a0559a14ebf790837326 Relationship: SPDXRef-DOCUMENT describes SPDXRef-6a489ac0cc97cee3f197fce0fc69dd4e Relationship: SPDXRef-DOCUMENT describes SPDXRef-e537d1dfc42f71ff5f3021dc9bfb4062 Relationship: SPDXRef-DOCUMENT describes SPDXRef-84a3f3aedcb2641a9c00a3b85fe5ca0b Relationship: SPDXRef-DOCUMENT describes SPDXRef-ede19289d84680c81b610e727937c417 Relationship: SPDXRef-DOCUMENT describes SPDXRef-025117bce796ae5f57a1adacb22e6479 Relationship: SPDXRef-DOCUMENT describes SPDXRef-c31bc0adba1a3e3aba7c338f3e6dde06 Relationship: SPDXRef-DOCUMENT describes SPDXRef-539cecf64030b12747eaa06c04decbed Relationship: SPDXRef-DOCUMENT describes SPDXRef-8fc030afa4c36db52f1d0e9f2d1e117e Relationship: SPDXRef-DOCUMENT describes SPDXRef-dc9e545e6c9db3ac4315fc5823e689ca Relationship: SPDXRef-DOCUMENT describes SPDXRef-e584f2c7a01b34d8f850d1c1ac96724f Relationship: SPDXRef-DOCUMENT describes SPDXRef-d0be843fde4f6bf0e65ec6201808a95b Relationship: SPDXRef-DOCUMENT describes SPDXRef-fa0cf0de82389b292a98816626bf6603 Relationship: SPDXRef-DOCUMENT describes SPDXRef-12ec4f38b97645adbe64913b5f6afce2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-784fb8508d7d335f0ecfb34f07186dc2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4141e34a6df2067b1312d17839f2d6dd Relationship: SPDXRef-DOCUMENT describes SPDXRef-f8c65e2f6894d199db41d2ae03fe4fab Relationship: SPDXRef-DOCUMENT describes SPDXRef-65bd4d4b28de33e2b3521ad9ce1fdedc Relationship: SPDXRef-DOCUMENT describes SPDXRef-94773817148e0752c81be1de90a93994 Relationship: SPDXRef-DOCUMENT describes SPDXRef-9d5b542a3c0e92caff3afb38ea5ad59f Relationship: SPDXRef-DOCUMENT describes SPDXRef-2600348527d13adeb805dd415263025f Relationship: SPDXRef-DOCUMENT describes SPDXRef-38d36d5dbaeeb581f80af51976513ab5 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4233f40a4fbf9212e003cda62e27ab00 Relationship: SPDXRef-DOCUMENT describes SPDXRef-4ba702f3d1c10f677980279ea1bfc643 Relationship: SPDXRef-DOCUMENT describes SPDXRef-b45e06703cb000d657dd5869b5724a17 Relationship: SPDXRef-DOCUMENT describes SPDXRef-803176aa68ced439985fabea21a876c2 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7d933f8e99db1f8066473548e4052c65 Relationship: SPDXRef-DOCUMENT describes SPDXRef-e71d50499c037f781800cfe5904303c1 Relationship: SPDXRef-DOCUMENT describes SPDXRef-f5a71992824c9ab610639ec567b733ef Relationship: SPDXRef-DOCUMENT describes SPDXRef-2048bf5d696988588995627a24f49d4d Relationship: SPDXRef-DOCUMENT describes SPDXRef-331a7b257251ce799c6da9ec8bb291ed Relationship: SPDXRef-DOCUMENT describes SPDXRef-dd5df8338676fedc44e37885fb799be3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-66727670855bf2d7b636f1314d8c3c74 Relationship: SPDXRef-DOCUMENT describes SPDXRef-d85de8c871031398f320a0f7b68a8035 Relationship: SPDXRef-DOCUMENT describes SPDXRef-2280ccf5f1f6ce87a312f5173a6c6af6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-58002b6ce4a9b1b68d749b9fe5aa7ae3 Relationship: SPDXRef-DOCUMENT describes SPDXRef-5f504a269cf85600c3c5708ae474cb73 Relationship: SPDXRef-DOCUMENT describes SPDXRef-abcc5e189206fb91dcb36c64934b57d6 Relationship: SPDXRef-DOCUMENT describes SPDXRef-7249ccf15147ac232de4237b85ca124c ##### Source dependencies # Header only libraries from the armnn source repository third-party folder # NOTE: fmt has a small .cc file that needs to be compiled in order to work hence the libfmt.a below in the static dependencies PackageName: cxxopts SPDXID: SPDXRef-cxxopts FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText: Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck PackageName: doctest SPDXID: SPDXRef-doctest FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText: Copyright (c) 2016-2021 Viktor Kirilov PackageName: fmt SPDXID: SPDXRef-fmt FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText: Copyright (c) 2012 - present, Victor Zverovich PackageName: ghc SPDXID: SPDXRef-ghc FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText: Copyright (c) 2018, Steffen Schümann PackageName: half SPDXID: SPDXRef-half FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText:Copyright (c) 2012-2017 Christian Rau PackageName: MapBox SPDXID: SPDXRef-MapBox FilesAnalyzed: true PackageLicenseConcluded: BSD-3-Clause PackageLicenseInfoFromFiles: BSD-3-Clause PackageLicenseDeclared: BSD-3-Clause PackageCopyrightText: Copyright (c) MapBox All rights reserved. PackageName: stb SPDXID: SPDXRef-stb FilesAnalyzed: true PackageLicenseConcluded: MIT PackageLicenseInfoFromFiles: MIT PackageLicenseDeclared: MIT PackageCopyrightText: Copyright (c) 2017 Sean Barrett ##### Individual Files FileName: ./Android.bp SPDXID: SPDXRef-6023602810befa9adda44114844d090b FileChecksum: SHA1: 8181f188f6d5c1bfde1256daf5c6cd39dd7b8987 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd. All rights reserved. FileName: ./Android.mk SPDXID: SPDXRef-2716bc1ed4229fa725d3289dfebf305f FileChecksum: SHA1: 22c385a1bedb462228b3511d9876f38a8cea4a69 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd. All rights reserved. FileName: ./BuildGuideAndroidNDK.md SPDXID: SPDXRef-950af7814f60dff224a7339016ce4409 FileChecksum: SHA1: 39d573fad2cc91dac6a4996df981719dc8be02a6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./BuildGuideCrossCompilation.md SPDXID: SPDXRef-18a4ee19fb06cc5465a5fcc777a7a952 FileChecksum: SHA1: de78e061d8bd4d26d70db25a0b6f21aed1166dcb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./CMakeLists.txt SPDXID: SPDXRef-55f81d8bea83439b3f936bdedcc55a94 FileChecksum: SHA1: 4da05c939972b22c6e8c2bce2c74cc6d5dfcefa9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./CONTRIBUTING.md SPDXID: SPDXRef-d83608cde56b57c282a0a44afa00afca FileChecksum: SHA1: bb0d99a00287989561dfdce436004e09b4e7278c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./InstallationViaAptRepository.md SPDXID: SPDXRef-222d74ae2fe2f2148ce9a94df369b13f FileChecksum: SHA1: 87af0b56ecbe07306d3fdcf9f1b5c86f4f1d2a2b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./README.md SPDXID: SPDXRef-6183423a33583910cd705460e23d1c2c FileChecksum: SHA1: 6cf55a425943820812924324836ff221ce706065 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./SECURITY.md SPDXID: SPDXRef-147dd65486ab91d9c3c92070f0bfdeb0 FileChecksum: SHA1: 5c7051d2c36aa1671d35aa1ef5f830be26929c47 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./build-tool/scripts/build-armnn.sh SPDXID: SPDXRef-d19cb67c02cdc8f9c00eeb76fdcdd134 FileChecksum: SHA1: 333c675e0effa1311715094bcfb34c3c5e21a6ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./build-tool/scripts/common.sh SPDXID: SPDXRef-3b64916999b60ed22cbccc11a6b816c3 FileChecksum: SHA1: 2e415ad9e5a9a4c1ffd650ed4619526032009ea7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./build-tool/scripts/setup-armnn.sh SPDXID: SPDXRef-baad5b3523a8732aacdc1fe3cf64b04a FileChecksum: SHA1: bab9f29fbedd2b818a1fdd9c717b7dcb3dfbd535 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./build-tool/scripts/validation.sh SPDXID: SPDXRef-624364757b1697c1a55b6b60e3e55fa2 FileChecksum: SHA1: 95b7ee6e419de8bede6427cb6d5c2b751f72bcc6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/AddDllCopyCommands.cmake SPDXID: SPDXRef-18349d5ab3dd6391bf5d61a0c2755d4f FileChecksum: SHA1: d4feee62134dfd11ec5f0e1f603b7d0593615f8d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/ArmnnConfig.cmake.in SPDXID: SPDXRef-377c55a4be6c94fa2b9813a0f36bf4a6 FileChecksum: SHA1: b21f78bc9981b23d221981fc5db49ab57947b0e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/ArmnnTestUtilsVersion.cmake SPDXID: SPDXRef-dc5969daa319b470977a431a00cf4f16 FileChecksum: SHA1: 1f7fefc8f92a34a387d432180978b0f6cb6c8115 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/ArmnnVersion.cmake SPDXID: SPDXRef-a5c6ee2ac2ba1893a37eefb34fed2d71 FileChecksum: SHA1: 3cba391449afc3ce3a156b81767e76f6effb7afb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./cmake/DelegateVersion.cmake SPDXID: SPDXRef-eb36eacc7b9241e70c9f54516582420f FileChecksum: SHA1: 06cff7a1c13f84c737267a33c32654b8bf2be2e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/GlobalConfig.cmake SPDXID: SPDXRef-837a18c08c2d04bb81ddaffa8b84dcbb FileChecksum: SHA1: d25717bc83509ba8e7523ef088d1171eb708c610 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/ParserVersion.cmake SPDXID: SPDXRef-8bf0f42e05bcafbe435014031da15e8a FileChecksum: SHA1: b4cfd1eb7d9d8c6dfe9293506e49ed0da04d64d9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./cmake/Utils.cmake SPDXID: SPDXRef-fe28f70021fc8da11eff54d9b99dda13 FileChecksum: SHA1: bd074ce85a73f1bd028cf83041ee19fb7cf19a82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/BuildGuideNative.md SPDXID: SPDXRef-6a5e70f15dac6fb31fe98ef5645ff7f5 FileChecksum: SHA1: 9c550a239c1b92286b38e980f704fe1188dc55c7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/CMakeLists.txt SPDXID: SPDXRef-28a54198bdc3b3a27c17ccb11cf71ac0 FileChecksum: SHA1: e98325c86304ea4475c034da0a57dcaddcb27e98 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/DelegateQuickStartGuide.md SPDXID: SPDXRef-ba7bc52c8ce23c3e0b1fa5009f4a281e FileChecksum: SHA1: 6670525d68a11ce710e2a7d4c7f93d32ac5d0811 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020, 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/README.md SPDXID: SPDXRef-0b3b6e0c108eaad7768baa8b7379d3ea FileChecksum: SHA1: 9acefec6bcf15b466d74ea0aece614bf3d4e7531 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/armnnDelegateJNI/CMakeLists.txt SPDXID: SPDXRef-c93fb1fdc823b6a2b8b761652ce430df FileChecksum: SHA1: 1edcd9443217a56d53f1f141736b52db1f09860c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/armnnDelegateJNI/README.md SPDXID: SPDXRef-4f70d3aecd124d339e737b57b30a2b03 FileChecksum: SHA1: 3c62dd9736b9c26ff1f70e826b49d9fddf6ec021 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./delegate/armnnDelegateJNI/src/armnn_delegate_jni.cpp SPDXID: SPDXRef-27f40b5508c15da36b82f53a064224c0 FileChecksum: SHA1: cdeeda6f559ee880ef168017c7d26e4b17d0e0bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/armnnDelegateJNI/version_script SPDXID: SPDXRef-6fb27b4a8e2df11b17c4d762de6a4f0e FileChecksum: SHA1: 68d4aac706b77c218feac1d15d58ecdee986f55d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/cmake/Modules/ArmnnDelegateConfig.cmake.in SPDXID: SPDXRef-3d7a95debcae6d157134aefb80304d46 FileChecksum: SHA1: 68b0033db181a496e398c8660ff8b6410d751c58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/cmake/Modules/FindFlatbuffers.cmake SPDXID: SPDXRef-39551805529c27b1bde13eeac9f464d7 FileChecksum: SHA1: 3e7639b3bcc91c12d90d5271e0508f5a433ae93f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/cmake/Modules/FindTfLite.cmake SPDXID: SPDXRef-9a747183d7e76019a303746173439a8e FileChecksum: SHA1: bcb5bb05aa572624ab980a87a500637636f7f71d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/cmake/Modules/FindTfLiteSrc.cmake SPDXID: SPDXRef-ef0fcbdeb8b53fba3ceeb78cbe4712fe FileChecksum: SHA1: 0bc2b37eb42d6b28e4bdbd828547da55909e4250 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/include/DelegateOptions.hpp SPDXID: SPDXRef-709f9d106a488d4d928768b4331d61d9 FileChecksum: SHA1: 391f8d61d0a563d1e282e71dcf3c5724e23ab42c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/include/Version.hpp SPDXID: SPDXRef-5b85668a909962a920c0c42a64d92cde FileChecksum: SHA1: 483687f800850e8325efebf4988df7da6c75a3c9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/include/armnn_delegate.hpp SPDXID: SPDXRef-ddef91242442f6595d3a45f59f2a5019 FileChecksum: SHA1: 9472932ce257d5ccb91a705306c86bd256083004 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/conftest.py SPDXID: SPDXRef-e4acb3b492847bcb1ada1739967ab9fd FileChecksum: SHA1: dfe03ed99560488015ba0d041bae8ab6be49bf61 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/pytest.ini SPDXID: SPDXRef-5732785cadaee05bc465316a2d754b19 FileChecksum: SHA1: dd3eb4fb0a2f51e9309d49a8d2d6af3349702117 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/test_data/conv2d.tflite SPDXID: SPDXRef-3bea5ea61fccab687697623bafc6db9f FileChecksum: SHA1: dca92651354b3492a08549058f96e45a9268befb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/test_data/fallback_model.tflite SPDXID: SPDXRef-be771c115b82534d5f584e73a007dc89 FileChecksum: SHA1: dfa0398309155c5975f8b403495852bb0f72899d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/test_data/fp32_model.tflite SPDXID: SPDXRef-1f696c863191a010480fffc433fa358d FileChecksum: SHA1: 9a0edae08ca8c81b70adf79a6158f293fec545e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/test_data/mock_model.tflite SPDXID: SPDXRef-18d7d8a7f0d763775bc479aab1826b34 FileChecksum: SHA1: ddee978acb39ff276d0676296ae21acbb6203149 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/test_external_delegate.py SPDXID: SPDXRef-f3937c3ac76264ae6724e690dd5af86d FileChecksum: SHA1: 402d9a17f5606ea5404e21a7f3141a15d56f64f5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/python/test/utils.py SPDXID: SPDXRef-e96002734486b25a5b013442b5d2a811 FileChecksum: SHA1: 4bd91096be28172398a316d9d2fc6014e7d4a3c7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Activation.hpp SPDXID: SPDXRef-93231a98368d89d6823f74713db1f290 FileChecksum: SHA1: d0e44f3752f6eeaeaad647bc4d3eb4705cf975c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/ArgMinMax.hpp SPDXID: SPDXRef-46a6f10f158b9ed5856bbb3cc1f0c25b FileChecksum: SHA1: a9fac62136c5a4a9a5a540a4e1519427914b2d29 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/BatchSpace.hpp SPDXID: SPDXRef-7b07232ebe2e964cc1cbce447038dce4 FileChecksum: SHA1: 953be73f31c1af7c3fe0a6572817e42c6b04e50a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Comparison.hpp SPDXID: SPDXRef-8d2648cdc71a540081e07cdc3b03e8df FileChecksum: SHA1: c031d9f8740f46d1178617047f2c6f79862e7368 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Control.hpp SPDXID: SPDXRef-071e82e8bb410f4c032b63e850c32107 FileChecksum: SHA1: cc63ec7d12f72eb619c7d470cdbe7dd331106f9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Convolution.hpp SPDXID: SPDXRef-4b32a296696c454a45be5c23969d14b4 FileChecksum: SHA1: e33dcfcdb341438c1dead7b6d295bb3ad6fc21ca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/DelegateOptions.cpp SPDXID: SPDXRef-03e556e023a69eaabddaa30fc6530d38 FileChecksum: SHA1: db6b0739f9bff87d6a7b04db053b84d2e9d03fa5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/DelegateUtils.hpp SPDXID: SPDXRef-622f38ccb8fb6927bd8f67f4bdbcb221 FileChecksum: SHA1: 6ccd46e0441c929de72f618d480b62d42c68cea3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/ElementwiseBinary.hpp SPDXID: SPDXRef-17ba82a7b80069147634ee0382974ee4 FileChecksum: SHA1: e02b5e0e6fac8c5c8f6e9f1fe58c4bbd0f648a82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/ElementwiseUnary.hpp SPDXID: SPDXRef-5786ab28ea5251eacbee1d6141c60729 FileChecksum: SHA1: 837888dfadfda316d6e41471b3773ae27a5f244b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Fill.hpp SPDXID: SPDXRef-cbcb0020dc4202e20387760b79b7ac97 FileChecksum: SHA1: e7dad061558464149629d8478dddcfae3513a3fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/FullyConnected.hpp SPDXID: SPDXRef-bee44d419a0009c6fe4163410125de26 FileChecksum: SHA1: 45632965d64245efa8316ceda639eb85c4e87e1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Gather.hpp SPDXID: SPDXRef-5143e1ba9a1a741f7741082fcf0e51f4 FileChecksum: SHA1: 7aff670ba5b1bf0d902a64211085118273ff4111 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/GatherNd.hpp SPDXID: SPDXRef-3d0e559795ded1fcf28b88b030b810ee FileChecksum: SHA1: 6bd372e7718074a05ea59f3dde4f17d247bd60b1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/LogicalBinary.hpp SPDXID: SPDXRef-f1160acb8390cca7883d8433394885a6 FileChecksum: SHA1: 62b91621956620e954c20627b8312e71b99d2c21 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Lstm.hpp SPDXID: SPDXRef-4023b843f1902d5032b089fd6433bb62 FileChecksum: SHA1: 892ff7ebc3a93e20615829cbf49459bb2f5c779a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/MultiLayerFacade.hpp SPDXID: SPDXRef-406a32dc2822989afc2fa1016dcd8c3e FileChecksum: SHA1: 35e1861733979d65e7f842c01ea4bc398a3c5f68 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Normalization.hpp SPDXID: SPDXRef-2aa5d544cd83b88d036985eb4985c8f0 FileChecksum: SHA1: 1e4b6e3a271b2b49646b47ed016382fd6ac4b555 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Pack.hpp SPDXID: SPDXRef-56b57976e6c0023a433d2bf784354107 FileChecksum: SHA1: 1bda436a7e9ca4559b64b6a860d277214706f392 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Pad.hpp SPDXID: SPDXRef-c865759124054b3d9690988201d8667a FileChecksum: SHA1: 7d3107bcf1f780f1470acf10926275c9e300e08f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Pooling.hpp SPDXID: SPDXRef-fd34fe8f3eb5f64ee8d05455210dea4d FileChecksum: SHA1: f504cab8d7d1bdebc0532ce87ad31125870a3378 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Prelu.hpp SPDXID: SPDXRef-95e5230322cdbb3298467a2be714913c FileChecksum: SHA1: 8aa37670d5101939dfe0d5481aebde6ffba6a5e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Quantization.hpp SPDXID: SPDXRef-ecae718d841d0f1c62f8154380fc4a74 FileChecksum: SHA1: e958b1f58176a169dd74651e13f243b42e3f6830 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Redefine.hpp SPDXID: SPDXRef-316796d5f95d41cf2fcf278927a0c260 FileChecksum: SHA1: b4ac305f90914ca6b3a79b9d39361d6df5a8639d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Reduce.hpp SPDXID: SPDXRef-291ec06a8c517a515acdd55cf24e59bd FileChecksum: SHA1: 4446c3f9c00a374dcd71a7a896f4b55b3910720d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Resize.hpp SPDXID: SPDXRef-924090d4e3413fc1179413ac15b164dc FileChecksum: SHA1: f8c156dabc2b6e50073eb8b40d74b94be443c556 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Round.hpp SPDXID: SPDXRef-07f3e43e6d6e4da5406b4e6c0737eef6 FileChecksum: SHA1: 762af806898f3f120a5726495194c6a9a06dd5c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Shape.hpp SPDXID: SPDXRef-4c084d7ac60b0ff4712e93b1b6b60ced FileChecksum: SHA1: 1f44906e4650d813157fc08b4103ee4a19c03777 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/SharedFunctions.cpp SPDXID: SPDXRef-aca1b95401a3aac6cc5f0cc46dc46e1e FileChecksum: SHA1: e31cd0005305a543c6bcb2d7cec82b01ce408780 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/SharedFunctions.hpp SPDXID: SPDXRef-78cb088cdd94ea053448965d05689f90 FileChecksum: SHA1: 3d3d81f25410020288bb9d58da204877c737f4ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Slice.hpp SPDXID: SPDXRef-5c831b02c9e058829ebc7346620f5116 FileChecksum: SHA1: 359ffc07b6dcecb36384fcdcc3c3e4f7c72a9932 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Softmax.hpp SPDXID: SPDXRef-5745d1a6674b29e4ff881abec8d38c71 FileChecksum: SHA1: 959557491c3452e6321f9c3ce32134587814c01b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/SpaceDepth.hpp SPDXID: SPDXRef-eca91d2e0dbf9b3168db1e62453189d9 FileChecksum: SHA1: 951d8d0b580ffe89770380e599eb264de9170499 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Split.hpp SPDXID: SPDXRef-4958234547c5cc90197188e6ecc74a8b FileChecksum: SHA1: 0c45cf9637f86b8522bf8665d7271e068b59adb0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Transpose.hpp SPDXID: SPDXRef-7150428d6f37f43ed75ee835c2704c40 FileChecksum: SHA1: 115f28fcc5319b5be534999d8ce4575641aad0b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/UnidirectionalSequenceLstm.hpp SPDXID: SPDXRef-049f74820d880d1ae61c7219b0167324 FileChecksum: SHA1: a2d952fc7c338b4d6d87aa7fe3363853687731aa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/Unpack.hpp SPDXID: SPDXRef-a2f8ecc27add60cad8366093fe4aee71 FileChecksum: SHA1: 1fbc6622098b5e2f60576e5a8d43ce85ada8039e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/armnn_delegate.cpp SPDXID: SPDXRef-463407f93e084b215c320458df46f0eb FileChecksum: SHA1: 34d2587c3b911cfa2bd9f9f2ce32d9faa73b0f52 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/armnn_external_delegate.cpp SPDXID: SPDXRef-af05cb4be78868615c7c7c8be1d7b349 FileChecksum: SHA1: 480c8083564e47516f06ccc45f6de43567492923 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ActivationTest.cpp SPDXID: SPDXRef-92df2be7e6eb31b4bd219c4b5cfd2e2e FileChecksum: SHA1: b7c624dbed401ff52863cfbc8cac19ec0c5156c9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ActivationTestHelper.hpp SPDXID: SPDXRef-844e7b6e8c7ac58794aba524e225b3fd FileChecksum: SHA1: abbf6b77d54b8dc4d7cf2828829a65174fba5f95 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ArgMinMaxTest.cpp SPDXID: SPDXRef-a4e6819ba8c783e8d61000961d6079b3 FileChecksum: SHA1: e82910b6e708b2f37c6017bc3d7bd5a521a0582a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ArgMinMaxTestHelper.hpp SPDXID: SPDXRef-56a39190072e6e1e8f7ae254890d8f8b FileChecksum: SHA1: c9e97ec41cc33a27ef1ba21f7c5977b8aa1b24cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ArmnnDelegateTest.cpp SPDXID: SPDXRef-64fc2c3597c2c14a4a6477e327775fb7 FileChecksum: SHA1: a0f4592d3240ec04fd31ecc2f1a15cd57ae9a1ce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/BatchSpaceTest.cpp SPDXID: SPDXRef-5df350fbaacdaaf0f999b7996b645e54 FileChecksum: SHA1: b574a18dc165ab3ab0f7757a76835dffd0e033ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/BatchSpaceTestHelper.hpp SPDXID: SPDXRef-6ca734a01fe1aaf500e8043484c2286f FileChecksum: SHA1: a2e650b6822f91c7eeb2f1ba670f9d32df840324 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/CastTest.cpp SPDXID: SPDXRef-3fe4679a0bfa445267ff49c2e98c34f2 FileChecksum: SHA1: cc90e986e22ac9809f33e8d00c78b4db93fc334f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/CastTestHelper.hpp SPDXID: SPDXRef-49051496a1f4201851f3b575b9666b28 FileChecksum: SHA1: 922c303abf4c715c7e80fc2a93411b75e3ba3acd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ComparisonTest.cpp SPDXID: SPDXRef-21cf587d1f2798224603c389255053c8 FileChecksum: SHA1: 203725bbe745e3784e001d40376d9c7dc84b417b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ComparisonTestHelper.hpp SPDXID: SPDXRef-8366eabf4bc5729a5cb9f21f0d84a60a FileChecksum: SHA1: 763998e15f8043d4fb323ef0f494d8277af43339 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ControlTest.cpp SPDXID: SPDXRef-db9041313278b52d7adbd65baebeaac7 FileChecksum: SHA1: b6ffb4b1f264d585a9e0ad2fd164e03f6b46619e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ControlTestHelper.hpp SPDXID: SPDXRef-ccafb8b8a72ea8b2ebce72e75350a322 FileChecksum: SHA1: 0203b3bcdb971753513bbebd6caf00975b2ad29f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Convolution2dTest.cpp SPDXID: SPDXRef-6bda2fb8f15053f556ba3a0dffb38f6e FileChecksum: SHA1: 4c0ef572a7a80bc7f590f98b6736397d20bb01d3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Convolution3dTest.cpp SPDXID: SPDXRef-ec712171c20b1ac911d33be000dc8f31 FileChecksum: SHA1: 11cd73051bee218568564279f4f81696aeb07ff9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ConvolutionTestHelper.hpp SPDXID: SPDXRef-a4196333956958db71dc86c223d27c1a FileChecksum: SHA1: 2c1bcdc46bb38821eaa45c45242d9631ca719e47 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/DelegateOptionsTest.cpp SPDXID: SPDXRef-b6e2b30853335edb9ceeede889b34389 FileChecksum: SHA1: 5d68c229897811168bc2459076393f1f80778227 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/DelegateOptionsTestHelper.hpp SPDXID: SPDXRef-ae594ffb7c7abd1c3cbea16ee41d6c5d FileChecksum: SHA1: a3ee4566fcff06398c073c0cab64cf5d9e730cbc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/DepthwiseConvolution2dTest.cpp SPDXID: SPDXRef-14dfc132136b3d36e46dfe929169d334 FileChecksum: SHA1: 61cc7d3777a4f6fc827dc5c8e1d40b828c2f61e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ElementwiseBinaryTest.cpp SPDXID: SPDXRef-bc09f6047661cfcd37757c28c7c70cd7 FileChecksum: SHA1: 1ea598bc5babd0a1135f2308972df6c681d1c16e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ElementwiseBinaryTestHelper.hpp SPDXID: SPDXRef-340cd15c249a2725c5acbb5adec79227 FileChecksum: SHA1: 21168abb15143339cd0b861b7b4ad2c848bc0176 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ElementwiseUnaryTest.cpp SPDXID: SPDXRef-69d2291d0a4842922cafd2f9ff4e5f01 FileChecksum: SHA1: 588129fb9098f0beb5b630f8476372c6b61048d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ElementwiseUnaryTestHelper.hpp SPDXID: SPDXRef-23925a9b93bff0e7bd227e9fcb09557a FileChecksum: SHA1: 91c3a99389d9acb489f2d86272ab86aa943db318 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/FillTest.cpp SPDXID: SPDXRef-31c5df0fb286e66f02569de52b7ef66f FileChecksum: SHA1: f3db06878f5680b59b150726bdf5b37ca157f4b1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/FillTestHelper.hpp SPDXID: SPDXRef-b4eecc848bcb4f388e048784a7e51a83 FileChecksum: SHA1: ee0298c73028bf2bc40a8d1095fe9423bbbf5fb1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/FullyConnectedTest.cpp SPDXID: SPDXRef-275732a24d049c6bce713dc7ef378f91 FileChecksum: SHA1: a1b32cf664b16966ae76c90634cfa3ed94e11e36 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/FullyConnectedTestHelper.hpp SPDXID: SPDXRef-84afdb4424efd7a623be68e04b7be3d7 FileChecksum: SHA1: 464d7813742868b3b919a8c8f935ba3ed280f530 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/GatherNdTest.cpp SPDXID: SPDXRef-be075a7f0e34ab7a8e642c815c1e15c7 FileChecksum: SHA1: 0727ac2ee8fe417da157fff32cca40477f9e5fe8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/GatherNdTestHelper.hpp SPDXID: SPDXRef-ba22d347607084af53cf9672b396153d FileChecksum: SHA1: fe1fb38be3f5d0a02c03c2026c514d0f5b141f3c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/GatherTest.cpp SPDXID: SPDXRef-4d764f9c61f9d125a1b67be237f43d98 FileChecksum: SHA1: 627c7122094a00e63099a00a253637648b8a0068 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/GatherTestHelper.hpp SPDXID: SPDXRef-697abc821c8ccf65314d232cbe844fab FileChecksum: SHA1: 138ee4504e714025b88d83df30c74cca250956cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/LogicalTest.cpp SPDXID: SPDXRef-16e51c8a37943e3bf9321f1441fdb03d FileChecksum: SHA1: 5269d1d272c4dd1e74e1667cda1dbba751eaf3c2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/LogicalTestHelper.hpp SPDXID: SPDXRef-81bac3d810e573c0a0cd0f3f97575477 FileChecksum: SHA1: 3e8978f742d9e4cd3163eefcd4a65e857a7df4d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/LstmTest.cpp SPDXID: SPDXRef-462eafd975bf8ee032199ef82b4713ff FileChecksum: SHA1: fa7e9ece18d42f0d29511513306a84d30d5be5d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/LstmTestHelper.hpp SPDXID: SPDXRef-01b3fbb9cf5c27b7a2b98d6077099968 FileChecksum: SHA1: 31c56935d2e072f3d1931e2316a94de2b87927e7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/MirrorPadTest.cpp SPDXID: SPDXRef-035d490690a1e863176c07eb838192a0 FileChecksum: SHA1: fb59f10e81a1f990c7a9d03d0511a998a0c4319f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/NeonDelegateTests_NDK_Issue.cpp SPDXID: SPDXRef-ebe84cb3f475aae8a50bc5cd27004d51 FileChecksum: SHA1: 3e2ab066d17fea30e9b986c7d54fba4d095ef403 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/NormalizationTest.cpp SPDXID: SPDXRef-d09b93ffe6d1d7cfe9bb310dcc027ee2 FileChecksum: SHA1: 3dfe79e239268fb58415fe1d2957ba80c7717375 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/NormalizationTestHelper.hpp SPDXID: SPDXRef-8cc5d8b58bd11a8f69569d3b65a7cac0 FileChecksum: SHA1: 25db3557439e658c93866a4a646fc49168e13587 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PackTest.cpp SPDXID: SPDXRef-d15f67108c8007f5d00422b4c3ebed6a FileChecksum: SHA1: a4eb9d1056477f762a1f4fffaa7b8262b0f89959 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PackTestHelper.hpp SPDXID: SPDXRef-bf0ceaf275f52bfc9be22e4361d6bd72 FileChecksum: SHA1: 2d8e83ef2265e6eb7554991c83d5ef2b664df0db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PadTest.cpp SPDXID: SPDXRef-808b601fbe330720c395297a3114bdb4 FileChecksum: SHA1: 216c3a3e2ffcaa84ce07d7b41c4d09f110273c81 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PadTestHelper.hpp SPDXID: SPDXRef-be5ea2a16e6d10c74c147ced503cb132 FileChecksum: SHA1: 4de676aa20448f45efc705fcea33268df518d015 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Pooling2dTest.cpp SPDXID: SPDXRef-b406acd762ee51208dfaa86a474cbf07 FileChecksum: SHA1: e4cf26a70a32d9f58ceecaab690503109471a198 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Pooling2dTestHelper.hpp SPDXID: SPDXRef-d1fca025261962e59aae7801d93cae29 FileChecksum: SHA1: da7ce7361dcdaf5800a0e67e690863776dfc9fd4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Pooling3dTest.cpp SPDXID: SPDXRef-8b128c1224edc70fe4741bbd19ded421 FileChecksum: SHA1: c69002bcfa22e97e1a923e6a0a41fc0c64088d4e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/Pooling3dTestHelper.hpp SPDXID: SPDXRef-8525c5833f9bd8b29c5ece83bb202a50 FileChecksum: SHA1: a508a79844c3a363747f4aaaf994ef5cce7d1288 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PreluTest.cpp SPDXID: SPDXRef-52d250b4efa1948c81a9ac051395dcdf FileChecksum: SHA1: 4fa47b86aa252b6a8f45fe9c4077cd4088f6eed6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/PreluTestHelper.hpp SPDXID: SPDXRef-88c9bf9f48a98f824c7cd1ff1bb54225 FileChecksum: SHA1: adef3ac31cf7477135bc66d80298ba9de6925fe6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/QuantizationTest.cpp SPDXID: SPDXRef-15e8abd5f62204a48a56ca5907c28682 FileChecksum: SHA1: ed4542c7059a54bc1edaf2cd8c8a5b0a0d0d6faa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/QuantizationTestHelper.hpp SPDXID: SPDXRef-811c839d4968cc46366abea465daff4d FileChecksum: SHA1: b8263e7247b94caf45e469994ab1424f3d8c775a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/RedefineTestHelper.hpp SPDXID: SPDXRef-2f539be802a8c3735adb533dab8d75b9 FileChecksum: SHA1: 4cfb2aed9a5c25ec1910e3fb1658a61c5492df6b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ReduceTest.cpp SPDXID: SPDXRef-655680fa059cc25c9e64b87f30e1c0df FileChecksum: SHA1: ddc8da98ef365f6214d3cc159f82cace38529fe9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ReduceTestHelper.hpp SPDXID: SPDXRef-890e048054559d3eca2c323e480a76ae FileChecksum: SHA1: dc59b57ff73b0246db897fcfc21881db1c697eff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ReshapeTest.cpp SPDXID: SPDXRef-5765c2772e5c5dac4e589eac7735c8a1 FileChecksum: SHA1: dc3ea3ea2e8846e7e1e356117a92ca78d5e5e55a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ResizeTest.cpp SPDXID: SPDXRef-7a2226e756c37fa3bbd6562333fa4dfd FileChecksum: SHA1: bcdaa8e4f19c986d67d079344b3ac9c05379f0a1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ResizeTestHelper.hpp SPDXID: SPDXRef-6a512b79ad312257c596762cf75bfb6d FileChecksum: SHA1: d14c65997df19cffa046f5e8e88eb4b18f765ff8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/RoundTest.cpp SPDXID: SPDXRef-93ffa49b856ce7c43aaf27c6ec2d9ff5 FileChecksum: SHA1: 653a4186763d5f1e8aafec94d180699c79e0ff1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/RoundTestHelper.hpp SPDXID: SPDXRef-2268a2edbc30628438f92498de2225e3 FileChecksum: SHA1: 4d52b062091c5fba054c281cd9726645b24d0b65 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ShapeTest.cpp SPDXID: SPDXRef-6ee74e4cb09a2df299d7c15e35d2f508 FileChecksum: SHA1: e909722c6f184f459da79aab6da78c82ddaccf69 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/ShapeTestHelper.hpp SPDXID: SPDXRef-3ac40bc6995be55bb77c516e0f322289 FileChecksum: SHA1: 25b962dfd259464221f1b3a85e7906197aa64d58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SliceTest.cpp SPDXID: SPDXRef-2c02a53c0dff3cc467a77860778f458d FileChecksum: SHA1: 4b5f34448bd6616cd1e45aec1b5edc8db82db138 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SliceTestHelper.hpp SPDXID: SPDXRef-2782f9d13151eb4bda656218b9310314 FileChecksum: SHA1: 252e9d9a0eac69837dacd8658f4d615ee6ab927f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SoftmaxTest.cpp SPDXID: SPDXRef-9da8f34b430b73ca05040b633ab40c5c FileChecksum: SHA1: e5be1bf7b7def89f1dd3ba4e1878be16263e7e7f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SoftmaxTestHelper.hpp SPDXID: SPDXRef-a0d9ef5c4147a64677c95837dbf6bb06 FileChecksum: SHA1: dc572d5dd26454c50690bf729fdc51b87ab4049c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SpaceDepthTest.cpp SPDXID: SPDXRef-d4e6472d2fb27fb84a9a93987cd978b4 FileChecksum: SHA1: ab799789c9a23e2bf72ee11195887490391d0862 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SpaceDepthTestHelper.hpp SPDXID: SPDXRef-02f7fc1615e16121fa5e9ecc4fa90369 FileChecksum: SHA1: ac4c5af9cc088a32f696e7a24cc055e41c182fe2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SplitTest.cpp SPDXID: SPDXRef-6ccd283c7232315fb5065dfa3aa4bf38 FileChecksum: SHA1: abfa511775cfcf269b65c90b1150ee02fa63aa80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/SplitTestHelper.hpp SPDXID: SPDXRef-e67a57918c5cd6579a56c602488857b2 FileChecksum: SHA1: b72bb4e99afba2a429a90c3e8d24fdf2fcd6c1c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/TestUtils.cpp SPDXID: SPDXRef-b13af8e00647bca576af50bf50a1325f FileChecksum: SHA1: 6d3a56428a61e45d810003f8ed6dcf19301b4583 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/TestUtils.hpp SPDXID: SPDXRef-bd7014edfd08a7bc79a3f81fd846469c FileChecksum: SHA1: 4819b2a3b6c779e5eca74102498e17e99e884450 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/TransposeTest.cpp SPDXID: SPDXRef-b06c380b204a3b86849d8a2c8f202a9a FileChecksum: SHA1: f8de21779e147f7b2f4463a0cd307da8aedadb09 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/TransposeTestHelper.hpp SPDXID: SPDXRef-c9eb58b9d7797576c0c3e1c321eedebc FileChecksum: SHA1: 69adabea34d85d8973912319e6261323390c6dd7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/UnidirectionalSequenceLstmTest.cpp SPDXID: SPDXRef-984a0d4f1ec03b12233e724bb2a74c6e FileChecksum: SHA1: 6e864787ef5011585fa5a62ceeb103af1b7039cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/UnidirectionalSequenceLstmTestHelper.hpp SPDXID: SPDXRef-a5314ce79cc4fdef8e604d5c2964e440 FileChecksum: SHA1: 9f0f24224f79a2c461eed66875a21102534c5cf2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/UnpackTest.cpp SPDXID: SPDXRef-18cb53a29a306d727ab50cb29029cc8c FileChecksum: SHA1: 31eda45415728dc2032b84caea1334cf08d6c2aa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./delegate/src/test/UnpackTestHelper.hpp SPDXID: SPDXRef-f931dbf85dcf823e7cf46e8383434997 FileChecksum: SHA1: 05c949b62c51c29810e56e6b4067032493312e03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./docker/README.md SPDXID: SPDXRef-0587b7e6e3de22163a1faec89c338dec FileChecksum: SHA1: 24e1dedc87e424159cf5da147cb4e13fd219ac8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./docker/x86_64/Dockerfile SPDXID: SPDXRef-57bf9804a831c590b5dfce98bd1019eb FileChecksum: SHA1: 5523e19f386756295a4ace9b47b7e9e546de64ee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/01_00_quick_start.dox SPDXID: SPDXRef-25ff29be8d645f810109a115e3d1ad5c FileChecksum: SHA1: 96c906c3a4a061cebf740df55db2b4ec2f59eefa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/02_operator_list.dox SPDXID: SPDXRef-bb9b3cf242e8bbffe31055afabc0829e FileChecksum: SHA1: 22631fad4b01ab912f8622ff9eb0dd1fe8bb344d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/03_build_guides.dox SPDXID: SPDXRef-374eb3d1f119fc3e634c384c6eb017ea FileChecksum: SHA1: d3599be20346f4d391cd97d3c3b1a4e8c66cc073 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/04_contributor.dox SPDXID: SPDXRef-06f335742c9a044e83f4fa0cc9d69463 FileChecksum: SHA1: 85c496fc4d6e310b4275c32d70c47d98b1945d59 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/05_00_software_components.dox SPDXID: SPDXRef-57a5d58a596f1e1a29700867e5f221b1 FileChecksum: SHA1: c5452e700d49effda232c29db9f47bbffb06e10b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/05_01_parsers.dox SPDXID: SPDXRef-a6587800e04e080cb263c70a74a19dff FileChecksum: SHA1: 0f8d99be48331cede5d4a5d6e579f72d7322a471 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/05_02_deserializer_serializer.dox SPDXID: SPDXRef-48789b43da1cf1605daaaa28eafe8eca FileChecksum: SHA1: 598533db54919119347abc31d7c0a8e6ca481a1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./docs/05_03_delegate.dox SPDXID: SPDXRef-7f090eb5a694e55199ac6f8a9d0971e6 FileChecksum: SHA1: 0590d93f27f92e877956ae703655c767c88f8b87 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2022 ARM Limited and Contributors. All rights reserved. FileName: ./docs/Arm_NN_horizontal_blue.png SPDXID: SPDXRef-44a506056cad10c6440448784d242bdc FileChecksum: SHA1: e5eb9bb108d12c684207a080ba5bc34b68c37a9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/Doxyfile SPDXID: SPDXRef-d91f0c74b941c8c204132e416a01775d FileChecksum: SHA1: 7b158ee2aa630b8da8aef881ffb2c188508f75db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2020 ARM Limited. FileName: ./docs/FAQ.md SPDXID: SPDXRef-bec604c530385a921bda5e874e1a38c3 FileChecksum: SHA1: d42c80ff7e20baa48fda8ba0f765c6b883e70d2d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/PerformanceChart.png SPDXID: SPDXRef-37da0792772e2f9ff20ef7a113570008 FileChecksum: SHA1: 1c786a48d1522e564b5e344f595f387078474ea5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/header.xhtml SPDXID: SPDXRef-4fac56c74732c64c327d1965e27e7bba FileChecksum: SHA1: cc06f7eb0011a6b455708e9ce7b7b7c778d94eec LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2020 ARM Limited. --> FileName: ./docs/pyarmnn.png SPDXID: SPDXRef-81e0456179fe12b28b775a00a5a63085 FileChecksum: SHA1: 59cf761e53994614f6422d6cd8207fe3590ac803 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./docs/stylesheet.css SPDXID: SPDXRef-df7c8edbac51d09228a43de731b92f1a FileChecksum: SHA1: 5d8fa4257500079284b10bf34e16f2c6267dd993 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2020 ARM Limited. */ FileName: ./include/armnn/ArmNN.hpp SPDXID: SPDXRef-c033ab1056d66e0389d2e895e04b615f FileChecksum: SHA1: cb25240bf13b5535559a8eaadbb5311dc7015ab1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/BackendHelper.hpp SPDXID: SPDXRef-b03496ca75b63bc9d91cf7a7f3994198 FileChecksum: SHA1: daf8226ad6da16f2188fef5fa0e3da61e4d7081a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/BackendId.hpp SPDXID: SPDXRef-20634915d2bb89e51171a3057f63351a FileChecksum: SHA1: 348c9a075ca2b64fe1b81d7c15657abc25c387a9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/BackendOptions.hpp SPDXID: SPDXRef-c6e3b4efaae6ef86e9668a3af1d53b33 FileChecksum: SHA1: c35fe5ad9a557f68d9f360cb3f33bad93132d265 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnn/BackendRegistry.hpp SPDXID: SPDXRef-6d8b2bf119a8934cd2c43eabf91eab15 FileChecksum: SHA1: 4346f0730a75d94ad0f1771dd380960e7848615a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Conversion.hpp SPDXID: SPDXRef-5848bd50e9f7a20e35e9f245b22c2b60 FileChecksum: SHA1: b3ec3bc1b55bb8103c7563029047b0459d004d55 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/Deprecated.hpp SPDXID: SPDXRef-453d464178066a4e9ae36723f23e809a FileChecksum: SHA1: 6ed15ad6c6211d5604ec575dab7a9be7811caf46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Descriptors.hpp SPDXID: SPDXRef-85842a0f8479bab19864a5228e4dd62b FileChecksum: SHA1: 6884e8f3de46067b62cadc671a99c6cef270cca8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/DescriptorsFwd.hpp SPDXID: SPDXRef-52b61cf31f6cdff85940f7ccc22db2c0 FileChecksum: SHA1: 94c0b1793293a3e7ebe8acfe09a8cef504701069 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/Exceptions.hpp SPDXID: SPDXRef-9626375a8f997ba0ff64aa61fc4a44cf FileChecksum: SHA1: f4582fab5d6d78e9519232c400e8bfa60d0f527e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/IAsyncExecutionCallback.hpp SPDXID: SPDXRef-3aa611584eeefa99aa279c52da94ece9 FileChecksum: SHA1: 837f50cefddbd4efd7a349994db5144b29bb1e1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/INetwork.hpp SPDXID: SPDXRef-aae546393bc61c2c810011fc28e17ce7 FileChecksum: SHA1: a1f9d48e51025123ffc1611035c3783cbaba7a46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/IProfiler.hpp SPDXID: SPDXRef-bcbc423beaab4bd2e5553b1849c4cb0c FileChecksum: SHA1: 86ec99ec7b2b5499c1de02db5117f1de944c4ca4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/IRuntime.hpp SPDXID: SPDXRef-b4807d1bbfb169bc26f9f8bd0549f2ec FileChecksum: SHA1: d0c60c0947b93a4169d377aa0b1f7334e4ae753c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/IStrategy.hpp SPDXID: SPDXRef-4e249be5d144050575fbc333f19cf686 FileChecksum: SHA1: c60198ba69581261b990af9a013f9980acbe767f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/IWorkingMemHandle.hpp SPDXID: SPDXRef-ea1f65529a7b258fd23c70715fdd1df0 FileChecksum: SHA1: aae2a27adb4b765058cdbef79705cf445bae1647 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/LayerSupport.hpp SPDXID: SPDXRef-b7915ab1fdec123e081bb1671cfabb9c FileChecksum: SHA1: 65ac163a38f3a2f7d6836e386c39c86d5a3dcd6a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Logging.hpp SPDXID: SPDXRef-4b434569c913eb9a1b6595c6fd1324a5 FileChecksum: SHA1: e660a698034680b008e046d3c910afd87e759a3c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/LstmParams.hpp SPDXID: SPDXRef-b93410f72f6f79cd4239ff887cddfeae FileChecksum: SHA1: 9ff9cd67783b07bcb24ac4ddbd3ad21e079b3c0b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/MemorySources.hpp SPDXID: SPDXRef-7c76aa97157521116d548dbb2078d300 FileChecksum: SHA1: 1a7cbf4f4c9bc0bb38baa14bb18ce07c00150cc6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/NetworkFwd.hpp SPDXID: SPDXRef-a6d2a7e7db6e4a8824855699f8e839b1 FileChecksum: SHA1: 2a65bcf3fd2806d73788a60f9e1e2d64e6ac4055 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Optional.hpp SPDXID: SPDXRef-c90c111fb5cdac15a06abf18cdf0d026 FileChecksum: SHA1: ef0121f1d1a76d854bb3226e2eb521d1fa65b52a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/QuantizedLstmParams.hpp SPDXID: SPDXRef-74f8f81276b72c31c5c9e4960c4d2bd4 FileChecksum: SHA1: 05ada50b8aeea2d79fceb83fd50bfa997aa3f676 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/StrategyBase.hpp SPDXID: SPDXRef-2184e5a0708aa766db8bc52fc1aa097b FileChecksum: SHA1: cd3e7490d896ea79ec1808a2bdc9211edfbff86a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/Tensor.hpp SPDXID: SPDXRef-22b84d3e68ab310b3b12346e20682d86 FileChecksum: SHA1: 3ace256624cc073f74a482e2fec54dae45d60cd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/TensorFwd.hpp SPDXID: SPDXRef-9713f4401c136b86a5364c9a6e949ab3 FileChecksum: SHA1: 568df51c8632223a92841b8f2533cfc49cc96bdf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Threadpool.hpp SPDXID: SPDXRef-036dfa4e9e7030701f3c0800c0b34857 FileChecksum: SHA1: 6e7331c1c385ead66b56eab1ea7c87c7f2c35cd3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/Types.hpp SPDXID: SPDXRef-c929da3941cd5206297d3f71f3dc1268 FileChecksum: SHA1: 89582aa926d647abce976013cf91ce06059a8b57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/TypesUtils.hpp SPDXID: SPDXRef-3e59a6808e6542798641b279db567a8c FileChecksum: SHA1: fb756469af2c8a099d17c6c5082b4bfcc025717d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Utils.hpp SPDXID: SPDXRef-85347965817dee49a9069f95a0c7bf3c FileChecksum: SHA1: 432cdb11c8515e81490a0da705fdaa16c360f543 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/Version.hpp SPDXID: SPDXRef-f0fd0a0708b67bf47e4a3128423377a1 FileChecksum: SHA1: d92112b3f1d732fcf2e5e3ccd8582fad1235dbb9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/CMakeLists.txt SPDXID: SPDXRef-669360bec941715162189513323f0f80 FileChecksum: SHA1: 2dbaa5a016a07fe3accde6b2c840ed09b9303744 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/DynamicBackend.hpp SPDXID: SPDXRef-daf59ac41d0b66841c4789bf2bd6d5d5 FileChecksum: SHA1: 01daa38fb7f11404448ed85eb5d39a9e0f0f3eb0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/IBackendContext.hpp SPDXID: SPDXRef-577ed1a12b84ba0442f86bd4996ea0d7 FileChecksum: SHA1: 5d7e2fe56debdce972ef46ba691b0fb9ea0389c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/IBackendInternal.hpp SPDXID: SPDXRef-fd56004c5d665eb6aeead560cd7b4490 FileChecksum: SHA1: d963c484e6299d3b02978d6ae898568654d1157f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/ICustomAllocator.hpp SPDXID: SPDXRef-4b207205c0f2f00f82391795948dc3ac FileChecksum: SHA1: 4dc99c989a5e171d7445e9c562b37ee73e60ea6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/ILayerSupport.hpp SPDXID: SPDXRef-73367e08d231bc73927d040b015c78ed FileChecksum: SHA1: 6e688d206ed2196f883125c5dd2213086254a3cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/IMemoryManager.hpp SPDXID: SPDXRef-8c5b6742097135a450794635d7e5260e FileChecksum: SHA1: 7ee94ec203bb171ebacd213078b5c3d5c31bb8c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/IMemoryOptimizerStrategy.hpp SPDXID: SPDXRef-0d822d1bea653177d7e3ef8eaa2f4468 FileChecksum: SHA1: 1eaf429fd9840eec1bb24c97045561990e69d829 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/ITensorHandle.hpp SPDXID: SPDXRef-a34ebf679d2f81db779a1812bd48ffe6 FileChecksum: SHA1: 33c812d93b3cd5216a3eb0ea055c3b09754770c7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/ITensorHandleFactory.hpp SPDXID: SPDXRef-2c911e958306740e8bef1e84896a7cb6 FileChecksum: SHA1: 3758b3c720d62e415c2859ab7be55d8de1329557 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/IWorkload.hpp SPDXID: SPDXRef-017dd91fe47c63b7a552a5934330cfa5 FileChecksum: SHA1: d79367d624ee478e23e434f650976fbbf2ae1c52 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/MemCopyWorkload.hpp SPDXID: SPDXRef-4f4c9275a97afc4ea7d0d75b6ad9adbc FileChecksum: SHA1: 92aea07061b27a7a2a9236ee882971550e1456c7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/OptimizationViews.hpp SPDXID: SPDXRef-ae1fef0339e823ea7e8030ef8c7deb2f FileChecksum: SHA1: 05c0218fbcc7b194765a2a46218a5fb54b6e1416 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/SubgraphView.hpp SPDXID: SPDXRef-1bba16495ec65feeffb3853091382b0d FileChecksum: SHA1: 015c549f0a6507c3bb075ba92aeec79e1fbf5387 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnn/backends/TensorHandle.hpp SPDXID: SPDXRef-1ff699ace677280b40567ee697615ddb FileChecksum: SHA1: a866cb56f08b4ef945501f9c1b5330aa24173621 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/TensorHandleFwd.hpp SPDXID: SPDXRef-497156755db3505a3ffccd3d9b240359 FileChecksum: SHA1: 2855c2f1df72ae4b99ccbb3724278f7f72920b82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/Workload.hpp SPDXID: SPDXRef-27574b1eb008ee594b123d29dd1f41eb FileChecksum: SHA1: 33b36fd8ea517008fbaa820420bab3c3d4116820 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/WorkloadData.hpp SPDXID: SPDXRef-2fd65619ad7b409d9bf8ebea3930e0b3 FileChecksum: SHA1: 3cd5c3ee6fab34fb4cfc730ef14aed5f929f49a2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/WorkloadFactory.hpp SPDXID: SPDXRef-5ae94cc7bdbaa65761ff4567fbf36ed7 FileChecksum: SHA1: 6e6f4b33fb7c3cc9e7d52eabaf23382daa7caa1c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/backends/WorkloadInfo.hpp SPDXID: SPDXRef-16d0f893b7265a5457d195b7eb50cce0 FileChecksum: SHA1: b764116e8bffce32fcaf68ae1eaa3200a1cec4d9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/profiling/ArmNNProfiling.hpp SPDXID: SPDXRef-73f8b2f0169be050bd2b7b9da83f303c FileChecksum: SHA1: caaa0c41602d54443d24e8274493c3deb6b9327a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/utility/Assert.hpp SPDXID: SPDXRef-5a316e248fe3597da659d1f1fbabefa3 FileChecksum: SHA1: 7b57130c67ad97d154a250610903b8b7220a0028 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/utility/IgnoreUnused.hpp SPDXID: SPDXRef-a48cb12197a0726592257392cb1cad5a FileChecksum: SHA1: dad1b4d6eb9ab0edebaceb2f45b56bbfc6d7b8cc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/utility/NumericCast.hpp SPDXID: SPDXRef-d01077cb2b0910bc9394f3e4068a1a42 FileChecksum: SHA1: 0ed132bc389594328694df1890edbe69986169a7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnn/utility/PolymorphicDowncast.hpp SPDXID: SPDXRef-7d603625141db81a72febe03ad2e6190 FileChecksum: SHA1: 93faafc3d51c18209fe4421177152624a85c01bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./include/armnn/utility/StringUtils.hpp SPDXID: SPDXRef-09fede25e361a4ce406f7032d16f62f1 FileChecksum: SHA1: 99272982d85ebce8cd61160a85dc1c9c869fde53 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./include/armnn/utility/Timer.hpp SPDXID: SPDXRef-5077449105c25abaf6df95abc76ba6cb FileChecksum: SHA1: 10943f40007ffabded17debb6c1393ca5f586545 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./include/armnn/utility/TransformIterator.hpp SPDXID: SPDXRef-b77f66fea01de3d0f2eb509a2096f3e0 FileChecksum: SHA1: 3d03afe96a46c4397409e98f0accb808ed1d953f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnDeserializer/IDeserializer.hpp SPDXID: SPDXRef-a49a9897137d941aa55fd88afa662124 FileChecksum: SHA1: 8e8dbdc013fa21d1fb4c621fbb497519d2f68e3f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnnOnnxParser/IOnnxParser.hpp SPDXID: SPDXRef-369c086f736b8d2ff6fa9bd07bce2334 FileChecksum: SHA1: efed059a1ac564f781befd1e31796499332464f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnnOnnxParser/Version.hpp SPDXID: SPDXRef-de89fb90c1c7ceccc35912042bf489b3 FileChecksum: SHA1: 49d40aad685ecaeb419f5704d349ab24dae90fd0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnSerializer/ISerializer.hpp SPDXID: SPDXRef-49d672e33f88b03d7179107cea51b101 FileChecksum: SHA1: 9c57b58a1a2abfed35c44360c54c73e23d636446 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnnTestUtils/DataLayoutUtils.hpp SPDXID: SPDXRef-fd406362ae9c920b71b40fc357ae7d3c FileChecksum: SHA1: 02c38fc46f51a148009d2f3b6c3f785e32f67be1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/LayerTestResult.hpp SPDXID: SPDXRef-4ba4b7c394a35cc307370bffde1185a8 FileChecksum: SHA1: 4e13bd284e113708b1866d697c9985e07e8620db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/MemCopyTestImpl.hpp SPDXID: SPDXRef-f28a05edf58c48af1c0775bc205a068d FileChecksum: SHA1: 5cf2fac38a1e4a3208975e210908eb0d06666532 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/MockBackend.hpp SPDXID: SPDXRef-b87822b94e48dcce298a3570da14e261 FileChecksum: SHA1: 49120e51152b5240524bf938d2d46cb2107971df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/MockMemoryManager.hpp SPDXID: SPDXRef-4c5e73a6b9f8a21363ece108c74abcad FileChecksum: SHA1: 8da3754073152ef79c2c62408a1dbb349317e7be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/MockTensorHandle.hpp SPDXID: SPDXRef-7314042d5aa20cf334534f3fb4666b4a FileChecksum: SHA1: aec548e019290c2370a53392e9de4866d490b770 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/PredicateResult.hpp SPDXID: SPDXRef-870d9a794100998cb559e4466fb9edd0 FileChecksum: SHA1: ba5486b2fd7769fb54b1d578359b50db7e8a8404 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/TensorCopyUtils.hpp SPDXID: SPDXRef-24c5615c7d4446cb7366553efc547612 FileChecksum: SHA1: 9ece2c498be17e64b275b01ca74c8246cd3b1570 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/TensorHelpers.hpp SPDXID: SPDXRef-7f8cb4e693f95b08b6a56a3e61354a6e FileChecksum: SHA1: d600728d1f1bde0928b12fcca341faf168cacc87 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/Version.hpp SPDXID: SPDXRef-f4d555dc139c4a0981a6e3f4ec973c06 FileChecksum: SHA1: 3133fcdd09a4406f87192c6ac31f1f6a539963c8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTestUtils/WorkloadTestUtils.hpp SPDXID: SPDXRef-288b0d422410ca1289b5a26fc3fca0db FileChecksum: SHA1: 76270ed0690ab96c06fede2a19116fe623a8f04a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnTfLiteParser/ITfLiteParser.hpp SPDXID: SPDXRef-a5f60c986c236d55b8cba5c7724d13eb FileChecksum: SHA1: 05d3eaf20f393ffb4548c35bb9350d484f39b928 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnnTfLiteParser/Version.hpp SPDXID: SPDXRef-7871ccaeeeba454dc55f356c6e274803 FileChecksum: SHA1: 89dae40c4d2b3e1193695aa604c13941505aaa45 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnUtils/CompatibleTypes.hpp SPDXID: SPDXRef-8647a0ec290d43201ccbe8453d63fdfd FileChecksum: SHA1: af66dc966b67453fb6f2525c2fee45f75eccd31d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnUtils/DataLayoutIndexed.hpp SPDXID: SPDXRef-1bae5332b46406efa7647c95b14d5b78 FileChecksum: SHA1: 33b5e52d3efdc483f3dfc8f82a8cc224357e10c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/Filesystem.hpp SPDXID: SPDXRef-8174f588ce851fd76a22ee8cf033e6ae FileChecksum: SHA1: 101cf09ef2262fbe719cfc940983c4588bf98e62 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./include/armnnUtils/FloatingPointComparison.hpp SPDXID: SPDXRef-d90085e5a9c43293fbd7a4644de3f318 FileChecksum: SHA1: 362494b2e16c8562782c8c9c192f6bed27869337 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/FloatingPointConverter.hpp SPDXID: SPDXRef-8312df544d22f63dd1ee7e82dcb26345 FileChecksum: SHA1: b17c14cea87fbceceb9347c16cb44eff292b3b46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/Permute.hpp SPDXID: SPDXRef-fc3b8df0ca788749dfb47c1ba7516053 FileChecksum: SHA1: eb93d79249d2416fd469ae1adfb4957577ee2bcf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/QuantizeHelper.hpp SPDXID: SPDXRef-f42be57e940025f214e294e8250892b6 FileChecksum: SHA1: 1ffc662eb55e218f0c3385584c346b7d477fa844 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/TContainer.hpp SPDXID: SPDXRef-5f8bb51ad000201418d0593aa0d15e27 FileChecksum: SHA1: dc2e9b21aa587b899cb6e84743ac75186bbc4e97 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/TensorUtils.hpp SPDXID: SPDXRef-25f6f26f20c41a8d22c6e80c8410b194 FileChecksum: SHA1: 7d86cae7c6e22d3184392d4c111dd1a5e617600e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./include/armnnUtils/Transpose.hpp SPDXID: SPDXRef-e963f7dd8a5af36677f4af4742411dd6 FileChecksum: SHA1: 13bae5cd76060b484812ba95f564e5ea190e34fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/CMakeLists.txt SPDXID: SPDXRef-2a7852ed6c24a170a7dfa613831cc3b1 FileChecksum: SHA1: e4f30b93f94be9af60633e64ec97a6963563bdba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/buildpipe.sh SPDXID: SPDXRef-f8fc984e236dc65f646facb2fa5b9a55 FileChecksum: SHA1: 8f142db9a10f8ded17a4916d55ca04c1f6a563e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/CounterIdMap.hpp SPDXID: SPDXRef-bfc4900c50d1d0afcfb2475636b82e50 FileChecksum: SHA1: 109df142bbdcb6cbf36a0957f2b776c066d750a5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/CounterStatus.hpp SPDXID: SPDXRef-bbf3fe9206794b5709ad1afb1c851628 FileChecksum: SHA1: ae8fa91217907782f5f7391866dd7e65d9888b83 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/CounterValue.hpp SPDXID: SPDXRef-2477be897381a899a3ffc2e170fdf0a0 FileChecksum: SHA1: 9e348ce739d2e4fe2ea49ae580fe8d612c194a89 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/Holder.hpp SPDXID: SPDXRef-0dcb8d5f79927858bc200f22b097ba57 FileChecksum: SHA1: f94ae57f88318563edbe7b4b1be07f8807b78647 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/ICounterValues.hpp SPDXID: SPDXRef-6291a3e21e5d8dbcd16a048951054175 FileChecksum: SHA1: d6c30fba1a9b269ce4884b33dd57760d2ca76b44 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/IInitialiseProfilingService.hpp SPDXID: SPDXRef-3b61c74e3864d89a40018e2068b07438 FileChecksum: SHA1: 3b4bc4ed019ed60039c6edaf214094c36e1e3062 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/ILocalPacketHandler.hpp SPDXID: SPDXRef-a09f95a7326eea1266468fe0c131abec FileChecksum: SHA1: ae6cce4b6bbcb12b324d8f6ae57a7a271c938b7e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/IProfilingService.hpp SPDXID: SPDXRef-95493cb4194c83fdba4c6695322d380c FileChecksum: SHA1: 09ebde0944df2747ecbe4b4879a9f8c0d2c6bcb1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/IProfilingServiceStatus.hpp SPDXID: SPDXRef-aa6b8effac65b9a35b095764ce97b693 FileChecksum: SHA1: dbabf9575a3f8b780a58096e0ef0a7f701c44c2c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/IReportStructure.hpp SPDXID: SPDXRef-57d4ca46eb1c9223869b5f331d1e21e3 FileChecksum: SHA1: f0b65c6dd4ddd2661b33e43b5ce45e482525f56a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/ISendCounterPacket.hpp SPDXID: SPDXRef-1c7e1332f04c488b7effccaa244a68eb FileChecksum: SHA1: cd280238e5ef59779305f4314e0f1884de95043c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/ISendTimelinePacket.hpp SPDXID: SPDXRef-0105038ada8320c2f3155c268e81ddf4 FileChecksum: SHA1: b07154eac51e22003dbc73e3c8ff65388099b07c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/ProfilingOptions.hpp SPDXID: SPDXRef-f0d4767dc06f6001d99bd55b314d4a93 FileChecksum: SHA1: b10f1ba6552da548903d4da65b5c703ed21f1d5d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/ProfilingState.hpp SPDXID: SPDXRef-fd7fb35e094198556d9aeff9d539f329 FileChecksum: SHA1: 3d9d01a95df77e7d6bc11526fb0eed20273a33a2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/TimelineUtilityMethods.hpp SPDXID: SPDXRef-e3012262ada3561e8506cd1727cf3930 FileChecksum: SHA1: 569a0d5ee55a5006fe7a4edf96f4f0823a1b3b29 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/include/Timestamp.hpp SPDXID: SPDXRef-350dcf5fd8e3d13311db13b6b89246de FileChecksum: SHA1: 39b099cd2788e3a6bbd279a9a9d1d02b21e5f5f4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/backends/IBackendProfiling.hpp SPDXID: SPDXRef-87989149cd3c9d0d90bd934a4ce0a512 FileChecksum: SHA1: 92ce6dbb684ac7031869436918ffb4073f603d63 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/include/backends/IBackendProfilingContext.hpp SPDXID: SPDXRef-ab5411faa5653b8afa3bafeb56d86994 FileChecksum: SHA1: 2579dce691361f8bb1a4ca1d3daa66b4a9aad520 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/ActivateTimelineReportingCommandHandler.cpp SPDXID: SPDXRef-f6c933f9de0c920d3296acfc51cfe73a FileChecksum: SHA1: af161cef35c576631dd81e784cd83c200e1f521e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ActivateTimelineReportingCommandHandler.hpp SPDXID: SPDXRef-40c4507c86bc4320e48fc906204b1e55 FileChecksum: SHA1: 99e44dcbda49190f284ea9eb993bab725e4252a6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/BufferManager.cpp SPDXID: SPDXRef-3793f660e284ceed388c0fed4005fb5d FileChecksum: SHA1: 6e8b5a3d89246d109dbde519051dcfdb9ea59736 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/BufferManager.hpp SPDXID: SPDXRef-1f6456dd8260bd35814858ba8478c4f1 FileChecksum: SHA1: 12a9cf705690a06fe7d304724fa2fd746ac69af0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/CMakeLists.txt SPDXID: SPDXRef-8bb768841df3744610ac08d923eff4d2 FileChecksum: SHA1: b35680ba01f5474d95f5a62ee712156264c6d328 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/CommandHandler.cpp SPDXID: SPDXRef-d6ab6e439ebe39368e8ef8c541c1b3c8 FileChecksum: SHA1: 6d1ff259a1f50f546289c18652f61de728ca9026 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/CommandHandler.hpp SPDXID: SPDXRef-9c8efda9a1671e6875706ee02c0157d3 FileChecksum: SHA1: 2fdf5c47ee768f8d0a9ecce09374aeb50156a212 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ConnectionAcknowledgedCommandHandler.cpp SPDXID: SPDXRef-d8f26b3663f06d13ae91d27b7fe5b5ad FileChecksum: SHA1: 56772cd83f0216a147ae51880a430796bf11f4e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ConnectionAcknowledgedCommandHandler.hpp SPDXID: SPDXRef-c21ca4db0ae181f149f1a69c013424d9 FileChecksum: SHA1: c5e365481a3c89cd3ec642635e0b3d9975491a0c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/CounterIdMap.cpp SPDXID: SPDXRef-507757364c56fba7ef9614968b2025d6 FileChecksum: SHA1: 5dbd40c24b59261c128a33ca123730d330040080 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/DeactivateTimelineReportingCommandHandler.cpp SPDXID: SPDXRef-ea39992153a0cf67010b33227cfbce31 FileChecksum: SHA1: 659e5d4f08a38b5f6f460d497a7f3367b3205144 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/DeactivateTimelineReportingCommandHandler.hpp SPDXID: SPDXRef-5ecdde789f6e0810712b37b3a5e3a5e5 FileChecksum: SHA1: 392f3035b079db6d2710075732fdf4491e720c54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/FileOnlyProfilingConnection.cpp SPDXID: SPDXRef-491a8bd6dbf907c25d899f3b701b76d5 FileChecksum: SHA1: e7ac3a413dd472a6bfe4ff6d04878599e5ab5989 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/FileOnlyProfilingConnection.hpp SPDXID: SPDXRef-3eeeb9b5be756cf90676dc11e9a3aa9f FileChecksum: SHA1: aef7909e158a96a1fc8e1c4e77385cfdcab22c84 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/Holder.cpp SPDXID: SPDXRef-2d61509f283b695c1ca4135e7b5e6cda FileChecksum: SHA1: af8e0be2e67f64958a46d07642f64d6151b1e2b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IBufferManager.hpp SPDXID: SPDXRef-2ecc6aabfa87d2d56172f9db42de1d07 FileChecksum: SHA1: 93d1a896c5bdf67e2ed01645d3883203e49e17b2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IConsumer.hpp SPDXID: SPDXRef-1bddaa7ad081b0828846a924fb079a8c FileChecksum: SHA1: 9a95798a42690a1da8b91814f1dacb1ccb8a4ac6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/INotifyBackends.hpp SPDXID: SPDXRef-9456bd83018d840c63b8133088c62aba FileChecksum: SHA1: db1fd1c191c5339bfa3dba84de4196b6c73ce65e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IPacketBuffer.hpp SPDXID: SPDXRef-0b8755f199ecf80a6f2525d7bd6ad524 FileChecksum: SHA1: 45e50737270303394fc13d4b8042385bdfe6adce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IPeriodicCounterCapture.hpp SPDXID: SPDXRef-7466252420314d39314cfba125fcd7d2 FileChecksum: SHA1: 8ee198295c6dc00de52bbcd843720a3eff4f7d2b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IProfilingConnection.hpp SPDXID: SPDXRef-372901489c127b649ed9dce4e2c77b1d FileChecksum: SHA1: 70f9f4640ec52264caefb51e2690a41daadca138 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IProfilingConnectionFactory.hpp SPDXID: SPDXRef-203d47f20e482a108d38f8a7a36c6a60 FileChecksum: SHA1: c5f28e9136dce6bdb49798368a90e9a05c743e99 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/IProfilingService.cpp SPDXID: SPDXRef-ffe1adeb0c86f8b21d7b381f5c7fd7e7 FileChecksum: SHA1: 54331dcd610df2f4d085f85ff98bb6572fd1a86d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ISendThread.hpp SPDXID: SPDXRef-c114312cca7401bab2a45a63de92b3b3 FileChecksum: SHA1: e7645c598cbcb161042dabbb679ab84fb4a3db6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/NullProfilingConnection.hpp SPDXID: SPDXRef-57099a78548ae165561e9f6be2384b03 FileChecksum: SHA1: a7e6ea6e0e7014fbd987f4b87879efd4ec3dede9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/PacketBuffer.cpp SPDXID: SPDXRef-4c68107bd3f55d8722d3f642b22e6437 FileChecksum: SHA1: 4fa1bd22a78fe91f6ce9f384b7d66f2529403d4e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/PacketBuffer.hpp SPDXID: SPDXRef-809948d3d959068fe40be1513ae1de5e FileChecksum: SHA1: 610b70949b013cd7cb12a0fc9d8323cd61188e5c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/PerJobCounterSelectionCommandHandler.cpp SPDXID: SPDXRef-417502f7717fb4dede7a3dd0d82ade65 FileChecksum: SHA1: ac364df19e9ede2d7fca0776c04ec30e20839472 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/PerJobCounterSelectionCommandHandler.hpp SPDXID: SPDXRef-53f921512e218e6c177c1af8f643853b FileChecksum: SHA1: 79a39c196df0fd7f21f7cb8271497b9dbaaacccf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/PeriodicCounterCapture.cpp SPDXID: SPDXRef-bb93b6234c7527c5df98038f75f0d8be FileChecksum: SHA1: dff9a8d39a331faecafe721803df248abb99c036 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/PeriodicCounterCapture.hpp SPDXID: SPDXRef-8ee87e342cfec8c857806162e2661d6f FileChecksum: SHA1: 22d408a1dbd058784124365e1cbf68a50bff0d36 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/PeriodicCounterSelectionCommandHandler.cpp SPDXID: SPDXRef-aef07b02cea4fcca79ef15ae82b18084 FileChecksum: SHA1: f28d1e43cc9868ec33ce95a0c10dc4ba928131be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/PeriodicCounterSelectionCommandHandler.hpp SPDXID: SPDXRef-d92c16efad6846e086ec1ebaff4ec54a FileChecksum: SHA1: d6e408a41771dce2f35f2f40bd2ef45343544db1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingConnectionDumpToFileDecorator.cpp SPDXID: SPDXRef-8386cdb406dec88a8ba9d7318772463b FileChecksum: SHA1: 3ec72ad9c758bb4f07343e4fc40c14699c21945f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingConnectionDumpToFileDecorator.hpp SPDXID: SPDXRef-2d3ce28732264f66fb50dbaf29875f10 FileChecksum: SHA1: 8dfe9c4e1415914d3c2c8f7276619cbba0529393 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingConnectionFactory.cpp SPDXID: SPDXRef-e2c12c86031977a5b5a0dcba8109e977 FileChecksum: SHA1: a11e6e15fba2c6926d63e7dcf698495b997d19be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingConnectionFactory.hpp SPDXID: SPDXRef-4c433342e4f80f442f6ef20b2b2501ab FileChecksum: SHA1: 8ca90cabf32b4940f0eb0f2a9d5cca0ea5183752 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingService.cpp SPDXID: SPDXRef-052bbf27cf3b1420b3f60287a0d1c840 FileChecksum: SHA1: 8ad8e88319fd85241809e53290f03ed5a4db184c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingService.hpp SPDXID: SPDXRef-a497d4ddc2cb9fdc97767ce31ed06059 FileChecksum: SHA1: 2db03b46f83ae72c75e2176f659f83dc91dafca0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingStateMachine.cpp SPDXID: SPDXRef-91d6731cb80d1048e03d3c17b735c7ce FileChecksum: SHA1: 9ae964442663480190f6ed5f46d3511b7070dd9a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/ProfilingStateMachine.hpp SPDXID: SPDXRef-5f5b8b810e047df7da0b5641698690ad FileChecksum: SHA1: f2fcd6d712a6fa1a597dc7ec872d96ef1b5c9c98 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/ProfilingUtils.cpp SPDXID: SPDXRef-ca9f7d9fc1efb5429a1c594bb772b473 FileChecksum: SHA1: 9e5fed5e734093780f22bab10a8533d9c91d3c9f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/ProfilingUtils.hpp SPDXID: SPDXRef-711c080ba3c98a074fad06cb50e5b6f9 FileChecksum: SHA1: 9fa6f71079f8d266ce023ef2eaeb7ca778ad6cce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/RegisterBackendCounters.cpp SPDXID: SPDXRef-dd599b8f7672c9c3bef1ffd4f2eba9e7 FileChecksum: SHA1: 0a3a9c1c14b0e7e38539f70eac74091e3ebb9651 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/RegisterBackendCounters.hpp SPDXID: SPDXRef-ee5f165e945d51cf9bc330f31aadbc6d FileChecksum: SHA1: 8b4eb67dbc0b76a0c53c16b3c08b1a06a399c27f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/RequestCounterDirectoryCommandHandler.cpp SPDXID: SPDXRef-b8149bc848f3acb0cf532ac961a73112 FileChecksum: SHA1: aa1296ccd6bb4b55b692f1c777a653c861d42d02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/RequestCounterDirectoryCommandHandler.hpp SPDXID: SPDXRef-0621201d37684b8dae44188559f8f7c1 FileChecksum: SHA1: dc1049f9ee7dc95c5eac256828962a7adf8d789f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/SendCounterPacket.cpp SPDXID: SPDXRef-c8af8a1d6cc0526474a0824358e66c93 FileChecksum: SHA1: 10f1dcdcc115411c1ad3ddadc25f5fc0f52b8a3c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SendCounterPacket.hpp SPDXID: SPDXRef-c53fc4ef8bb144a4e45a4fb0eada9eb9 FileChecksum: SHA1: 1e6278017881dc3345bfc9f3e3ca0e17460fdd80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SendThread.cpp SPDXID: SPDXRef-ff4854d53696acae1e27b6fd12f29062 FileChecksum: SHA1: bab71395bd0e3266de3b4a9098b86ff304e807e8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SendThread.hpp SPDXID: SPDXRef-59582e2e4bb1b03582d04dd28a292f3e FileChecksum: SHA1: c5972e7d85878270e7b9212f105aa060a8c46fc7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/SendTimelinePacket.cpp SPDXID: SPDXRef-b3f6c43a8a4d03311a792a3db94f4c13 FileChecksum: SHA1: 093c8513a952ee3a003fb50fa6d5bda46bcbd71d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SendTimelinePacket.hpp SPDXID: SPDXRef-a15f1fe8c6969839a7314a1d605d0091 FileChecksum: SHA1: e104ba355add6aa6561a8cb8f012f9622ba7b6df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SocketProfilingConnection.cpp SPDXID: SPDXRef-37d4349306fba75126950b47e027e97f FileChecksum: SHA1: ad8fd8cbe77e9a5271e2488010c8c0ae53e68db8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/SocketProfilingConnection.hpp SPDXID: SPDXRef-b9011353f40aa4f02af2be97bbb93a1a FileChecksum: SHA1: 5446e75bfca77663bf36996cc011d5e8ce986c38 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/TimelinePacketWriterFactory.cpp SPDXID: SPDXRef-8515376c0712acecc1f899f5de64a6d5 FileChecksum: SHA1: ec398a802fa3094e8d070a8c1d3320b7c92c5573 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/TimelinePacketWriterFactory.hpp SPDXID: SPDXRef-8cae59145cf63ae2d26b71653fd50a67 FileChecksum: SHA1: 3d0ee09de94e228f7b447c0d61caa8395ee84324 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/TimelineUtilityMethods.cpp SPDXID: SPDXRef-022a3a87a77a951af94a928b1a82aae9 FileChecksum: SHA1: b3eaa450edcb37e69cfe39c80271dba3469fb158 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/client/src/backends/BackendProfiling.cpp SPDXID: SPDXRef-71e73f6ccb13ea72e80535bbaf006d38 FileChecksum: SHA1: 2ebf2da11afdcd91ea0d8d8767d31d93968f7525 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/backends/BackendProfiling.hpp SPDXID: SPDXRef-6d9d96ac9596c6d07e81f6a0531f2df3 FileChecksum: SHA1: 71ea2094702e08c8d9f08bcbd8ec403dfd8834fe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/client/src/backends/IBackendProfiling.cpp SPDXID: SPDXRef-657def78e8f0beb695b4363d3e56e3f2 FileChecksum: SHA1: e9ee597776edd1ff05a49afd4caf0e98788fe899 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Assert.hpp SPDXID: SPDXRef-ea04bd7d16ff6d3db01413c23f304b68 FileChecksum: SHA1: 093a4be4ef96ed652c5d03cce5ed53bba1fa15bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/CommandHandlerFunctor.hpp SPDXID: SPDXRef-e5e1b9700534aded64ed53a7bd8c402b FileChecksum: SHA1: 019fda08b64454baf5fb1667f3d8d787c7c871c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/CommandHandlerKey.hpp SPDXID: SPDXRef-b093428329e47539dc8c6819441415e4 FileChecksum: SHA1: 946f1bd9b8b968a3d9390b5b3d35f6db9b7c75c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/CommandHandlerRegistry.hpp SPDXID: SPDXRef-31e8b32609e4f65b6bcb9c1c6ea53ab0 FileChecksum: SHA1: efaf174e220583966c6237084cde4b7bb556f1dc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/CommonProfilingUtils.hpp SPDXID: SPDXRef-845bf920ebacbc90e426206bbbe15ddb FileChecksum: SHA1: 830789e9540b4fac947a11c239f0ae3f5ed8dcb7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Constants.hpp SPDXID: SPDXRef-1dde8c18f36c49d306b42fbf1608f4c4 FileChecksum: SHA1: 7af7df0f96a18da24088e268d542255cf746385c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Conversion.hpp SPDXID: SPDXRef-254e06c2394f3ebcdd0e26b3be4514d6 FileChecksum: SHA1: f80b22c25259da541c2fd80c052b64e1f653ecad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Counter.hpp SPDXID: SPDXRef-6d13412476b4044f84cd18f53ca1c88d FileChecksum: SHA1: 3bdbe9339c960015e1f5a8ea5d8db4de3eeecafd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/CounterDirectory.hpp SPDXID: SPDXRef-482b10939a13197e000c9abc18e5e51a FileChecksum: SHA1: 4fe5d458fcb061f40696ef35b7c7653b65c2ec86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/DllExport.hpp SPDXID: SPDXRef-6fc2788a79c37b02d999c42222aa68ae FileChecksum: SHA1: a54a476520d5ca6c05a2b3709c0a5868bb08abe0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/EncodeVersion.hpp SPDXID: SPDXRef-0e3f7f85171a36512cd90c57e6b5bb72 FileChecksum: SHA1: 5c5dc81b4c58656c069e97dcd61b2c91b9b2a92a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/ICounterDirectory.hpp SPDXID: SPDXRef-69685f924949f0f8e1c43ba3bc823ed3 FileChecksum: SHA1: a690f9413db40b1366daeb94524847093cfdc3c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/ICounterRegistry.hpp SPDXID: SPDXRef-0c8fb7205afb2bb2edcdcce11d14837b FileChecksum: SHA1: 4e3704ba7ac6a2ee5b1fb589614d161e2c9bf096 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/IProfilingGuidGenerator.hpp SPDXID: SPDXRef-a44c30bb360fcbe1235b0758438e8dfe FileChecksum: SHA1: a2352dfb48da65504dec277e4543f48a1cf3898b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/IgnoreUnused.hpp SPDXID: SPDXRef-04be48e5946c485cf69c5264d145a025 FileChecksum: SHA1: 25224d15be0374ce40733bb2fb5af85960848fd4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/LabelsAndEventClasses.hpp SPDXID: SPDXRef-32940ec161aa36636984b06ce19d3b65 FileChecksum: SHA1: 8645e08bf673338553fe2c6b2a5b274ba26bbced LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Logging.hpp SPDXID: SPDXRef-19f3d10b669fc4a9458180e385c1f9c4 FileChecksum: SHA1: 4306825676865b6b7d52a7b6941a3051a5cd6021 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/NetworkSockets.hpp SPDXID: SPDXRef-e12ce9ff1edd2016eff3f31023d0b586 FileChecksum: SHA1: 7b239b158bb437d806e8fecf3057c8cff5041ba5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/NumericCast.hpp SPDXID: SPDXRef-8d3fb69c41fc6964ed9585070422aa06 FileChecksum: SHA1: 5af7215c4aa22c8d795155e055cac88646de5398 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Optional.hpp SPDXID: SPDXRef-ddde5096724350041ee7d45be5866e6b FileChecksum: SHA1: e897889822937ba5c2cfe7389d9e3d5fdf5abdc8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./profiling/common/include/Packet.hpp SPDXID: SPDXRef-5668759438ea5da759e18a4b9d34bc88 FileChecksum: SHA1: 4926b1ff777d116153aa50b654084f14e178d174 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/PacketVersionResolver.hpp SPDXID: SPDXRef-f23526b0528c1335d9cb8b0e2f9080bd FileChecksum: SHA1: 546f1b10ef94f733822f7cadc1130e47010da34b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Processes.hpp SPDXID: SPDXRef-f213ada95b133fa3eb2832352ee85f74 FileChecksum: SHA1: 5d86e578d482c9994fb0bb4393b2f7b85eaeac17 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/ProfilingException.hpp SPDXID: SPDXRef-0d73041a5c25d6c0ea7dbf25a2ffb2e3 FileChecksum: SHA1: 2dd301b2401412d287563504475cd176ebfdd07a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/ProfilingGuid.hpp SPDXID: SPDXRef-a5d8219499ac3d1a662306d125ec442d FileChecksum: SHA1: f028f4f5c0dde99a16c25b3317666607c88b055c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/ProfilingGuidGenerator.hpp SPDXID: SPDXRef-ca662aa7003632dcb30390a601100ce8 FileChecksum: SHA1: 456d4ece637dee009ffb5321c3598dd699d51ce5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/SocketConnectionException.hpp SPDXID: SPDXRef-afc4745bd774917800b18c6c954a0cf3 FileChecksum: SHA1: 92d8c33fb54c6c64e6c9ee78ad6d4610552376d3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/SwTrace.hpp SPDXID: SPDXRef-d224e55b2a950e7bd2476356b01565b1 FileChecksum: SHA1: 49f968e05950fb141abef8c81bbfe515e2b3889c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/TargetEndianess.hpp SPDXID: SPDXRef-005c486f067c4cc0e813b4b8f9f29f4f FileChecksum: SHA1: aaba2fdd17071fdd24a939ef0c0172f18544480e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/Threads.hpp SPDXID: SPDXRef-a0f63acb85b71ccc670969177087a662 FileChecksum: SHA1: ebc9680329b1cb0c9ffc09b19058d6e3ca95f62f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/include/WindowsWrapper.hpp SPDXID: SPDXRef-7075c998ec0ad4a94bc52768f8d4d4c8 FileChecksum: SHA1: 188d054702b8bdab7c1d00523eadc0bf074a9f40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CMakeLists.txt SPDXID: SPDXRef-149a2bdfefaf38845219bcea018a3ba8 FileChecksum: SHA1: 55383b10ec3cc90a1674ddbaa2bd2230b25ecba9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CommandHandlerFunctor.cpp SPDXID: SPDXRef-d949605578db9eb80b3247f15e14bb0b FileChecksum: SHA1: cf870d6fd8b8bfe725721d60c31e3ae57a837c1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CommandHandlerKey.cpp SPDXID: SPDXRef-cceab02a6b447bd3ee80235d14cfb347 FileChecksum: SHA1: 05be2b8dea60034e604182df3a50c6dc285da660 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CommandHandlerRegistry.cpp SPDXID: SPDXRef-46f7ffe4598fb14832066bfebfa3152c FileChecksum: SHA1: 14a04975eda51f072d3cb28e2b73b1d262b8ba3e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CommonProfilingUtils.cpp SPDXID: SPDXRef-44a673e49edb5f491ad61da44f0506d6 FileChecksum: SHA1: 65eb3a86f10418afcf36d82e5d558ee53430626c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/CounterDirectory.cpp SPDXID: SPDXRef-488ec9954e10f0c8dbbb2f995b9ff973 FileChecksum: SHA1: 762622c1c179c5066ab47d149248b99481d21270 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/LabelsAndEventClasses.cpp SPDXID: SPDXRef-e80b85f651f2966b95b46a932716fc3c FileChecksum: SHA1: 1fc3129422611d521b456d1a4132484f4b44ab68 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/Logging.cpp SPDXID: SPDXRef-e8bacb542639aa0d6036fbcac5a0b7fd FileChecksum: SHA1: 5df21e2f0495ee4fe79da586d730f82d2f7c56f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/NetworkSockets.cpp SPDXID: SPDXRef-8fc53488bc893a63739b5c8491e94661 FileChecksum: SHA1: cae3e4e228e08acbee220e10803796a7ac01a77a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/PacketVersionResolver.cpp SPDXID: SPDXRef-b15218ddc90b9e718bb43aa960c117ec FileChecksum: SHA1: 035a68f2af0736cfb15ce3fb7fea751bb8b3d218 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/Processes.cpp SPDXID: SPDXRef-69a327b5a40641f124cb5916686a97e3 FileChecksum: SHA1: ab36b14ac01d9bcb6ee67b5e082acf82824dc56b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/SwTrace.cpp SPDXID: SPDXRef-35497387c43cffab91c1e328860c3de7 FileChecksum: SHA1: 60854d6039a8d6db352a2d6d0273dfb35fe3c652 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/common/src/Threads.cpp SPDXID: SPDXRef-7172d1972e0c5c2f7f226fabffa917c9 FileChecksum: SHA1: 2b94226df7d93e28231b3fd64800385876b82cd2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/basePipeServer/BasePipeServer.hpp SPDXID: SPDXRef-401aa962a93592e57d2051c1e4715f3e FileChecksum: SHA1: 5a9b7663419b2648d536f39170f16dd76dda2220 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/basePipeServer/ConnectionHandler.hpp SPDXID: SPDXRef-388c55487c9b13aef42a652e9eb55017 FileChecksum: SHA1: 911219dc723f5b0fb2a4caa715ff465730c137e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/timelineDecoder/DirectoryCaptureCommandHandler.hpp SPDXID: SPDXRef-8aa2907f45d06cd9f750f1193e22e34e FileChecksum: SHA1: 13971f1ffab1c3982e6b54e5c59a3a50fc84cc31 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/timelineDecoder/ITimelineDecoder.hpp SPDXID: SPDXRef-30c729db95c8e02829c05eca4190f220 FileChecksum: SHA1: 69a3514b21217281ac96708739fdf0e2a3555e1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/timelineDecoder/TimelineCaptureCommandHandler.hpp SPDXID: SPDXRef-c21b207d7d1ee6f08d2d060a31f95742 FileChecksum: SHA1: 82998f17327c675bc2f81f74435fdda58f1f7fb2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/timelineDecoder/TimelineDecoder.hpp SPDXID: SPDXRef-dc76e4f3f6160e814066e074c2a853ab FileChecksum: SHA1: 294c0592bb8346db18060c78740836e797fb05ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/include/timelineDecoder/TimelineDirectoryCaptureCommandHandler.hpp SPDXID: SPDXRef-8fdb571f00520e9b48db689d40a37735 FileChecksum: SHA1: 3691e730f140c1e1b32292c1e2cfdc30a34c18ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/basePipeServer/BasePipeServer.cpp SPDXID: SPDXRef-92fff58b3c98a372ac195a2cacb9c3c2 FileChecksum: SHA1: 2a6bf3462c0f062ba745e75d76d983604c9e1ccb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/basePipeServer/CMakeLists.txt SPDXID: SPDXRef-7f54604d7a67eba09565d340682a1c66 FileChecksum: SHA1: 40724a0a971ea1967b510cd6e2eb9afba949de54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/basePipeServer/ConnectionHandler.cpp SPDXID: SPDXRef-3903e112cba5cc159fb362297954f07e FileChecksum: SHA1: e211d4cc56a32efc9e43ae123123cf85ea79da2d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/basePipeServer/tests/BasePipeServerTests.cpp SPDXID: SPDXRef-1b3858b97c1833d6689267dc2a0a559e FileChecksum: SHA1: deccd1736b5607e6007ad02d6a54626d04d3aa32 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/CMakeLists.txt SPDXID: SPDXRef-4172c7df734de31388e829446b3c3ae7 FileChecksum: SHA1: db3649fafee7497a176c1fabc78b1d0fe015191d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/DirectoryCaptureCommandHandler.cpp SPDXID: SPDXRef-4bebb5b63d40ded4138d36a2585f792a FileChecksum: SHA1: 29781b3e2b03fcc252e91a439b2d02de454703bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/TimelineCaptureCommandHandler.cpp SPDXID: SPDXRef-7a90d68dfb2b645dbb98e61756729a6d FileChecksum: SHA1: e319e5df49481d3ddbbcfa97d7bf70020216b33b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/TimelineDecoder.cpp SPDXID: SPDXRef-b3b4e2735e72cbd1a244e4a30a618b66 FileChecksum: SHA1: c563275f9d1652f7b17cba442b71398279a785ce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/TimelineDirectoryCaptureCommandHandler.cpp SPDXID: SPDXRef-947dd198f1b01839241f02abd81ddd4c FileChecksum: SHA1: 41fc5640ca8ab205891b8876cb2799fe8dd33ef3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/server/src/timelineDecoder/tests/TimelineTests.cpp SPDXID: SPDXRef-76b759edaa01af2b9c7e1cc17437c78d FileChecksum: SHA1: de61dac5e7febc92da82bbbbd110a046eed81837 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./profiling/toolchain-x86-ubuntu-mingw64.cmake SPDXID: SPDXRef-af4cf847d2b4c16c4fe481f9d732d29a FileChecksum: SHA1: 02c70908b4c9ee11f593deaeef9ae79b79435e86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/.gitignore SPDXID: SPDXRef-cd689e9bbee3e6339afd6ef95e31f7a6 FileChecksum: SHA1: c219483e5b910bf9fa18bca5714a21d6694c37d5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/CMakeLists.txt SPDXID: SPDXRef-bec59b455955e5de25fcdc64c3264064 FileChecksum: SHA1: 648c0f02701220784993e0763f452b38c3f72ebb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP FileName: ./python/pyarmnn/README.md SPDXID: SPDXRef-365388e25532bbddd54c2dc699c94b9b FileChecksum: SHA1: e088ba40866decb37e58b71da2618bfcb2d42b08 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/conftest.py SPDXID: SPDXRef-672ddecb31077bab003b0c623503f3f0 FileChecksum: SHA1: d42230ab4869c8d8b061da0031ffb322158c55e7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/docs_conf/config.mako SPDXID: SPDXRef-572a5c1ffac9d6d5dc7cb36900afefdb FileChecksum: SHA1: fe278f06cb94ca0400a1233cf0abaab5ee52fc80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/audio_capture.py SPDXID: SPDXRef-18e52a36289fc58e47d5f21a54a830dc FileChecksum: SHA1: 36bb97e96f200376f30c7b39bb6189877fdf2adc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/cv_utils.py SPDXID: SPDXRef-229815858c494b3ebf0f8bd186b57ca5 FileChecksum: SHA1: aa6f5b7771a26c4e6e18607b7bf5d4f7048ece8f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/mfcc.py SPDXID: SPDXRef-9470c9e1f943a307c5eaf89d1ba77188 FileChecksum: SHA1: a4628f817dd7c742defeab8323e820ad096992d2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/network_executor.py SPDXID: SPDXRef-96df8eaeec5fa26ea69802e6eb5ce207 FileChecksum: SHA1: 09e945766e62d6c3719870f9ade51372ca89c2f1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/network_executor_tflite.py SPDXID: SPDXRef-36a0b6f4cbdb2a027a50c319c33a87b2 FileChecksum: SHA1: b6c7910edd60350e42df1e8e67310dce71454b50 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/common/utils.py SPDXID: SPDXRef-1e7333d3a692488a3eb0f02be17e5bee FileChecksum: SHA1: 2b9192e419670cfea18348e82026a0b1100fda91 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/image_classification/README.md SPDXID: SPDXRef-1262972ce58a600c8c72d2bde4ec42ea FileChecksum: SHA1: d132f9d4f69681c388ed6258e5f08f60ff9f564b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/image_classification/example_utils.py SPDXID: SPDXRef-20af0782d7f379f2969dd334c6ebc641 FileChecksum: SHA1: 546c03704e0bf6df0b384453db20f6dfc33e1852 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 NXP and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/image_classification/onnx_mobilenetv2.py SPDXID: SPDXRef-d4465e1c6a47b8b26cc921dbb17dcd8e FileChecksum: SHA1: 545a126a83a58732f0b9da1c982032736f3627ef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 NXP and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/image_classification/requirements.txt SPDXID: SPDXRef-497ffc94ef3b734ba4ef685cc1e00923 FileChecksum: SHA1: aad9a9258e5cb798caa985c24bde0c1ab356ebb8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/image_classification/tflite_mobilenetv1_quantized.py SPDXID: SPDXRef-ca9dcf09ce7a78c71f743e8e17de56af FileChecksum: SHA1: 2cd74e04baedb182b4b716425ac3ba647b933d47 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 NXP and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/keyword_spotting/README.md SPDXID: SPDXRef-5e1ba53bb4d0bbf1c8d54371af7984ad FileChecksum: SHA1: 33ea8df1a2dfede1ab38b0445638b01451005e07 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/keyword_spotting/audio_utils.py SPDXID: SPDXRef-639428f22f5c0634702d4e4f74b6a594 FileChecksum: SHA1: 8d1943574b0d19ab11ab482947f354067fb52104 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/keyword_spotting/requirements.txt SPDXID: SPDXRef-a00f83cb6e97e7098ebec8ecdb317d17 FileChecksum: SHA1: 625d097ca1db96cdfd5aae3cac1e0ef2401565b8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/keyword_spotting/run_audio_classification.py SPDXID: SPDXRef-d8a5018f5bf520f022f0284fcb0a45fb FileChecksum: SHA1: 26858ced7195a12dc0dfe5dd6f021275c6aa14c9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/README.md SPDXID: SPDXRef-4922e5d9cbfc39a4f349ee03f6cd6991 FileChecksum: SHA1: 7a970e6a93d066936b38ce74a080a29855fa8fb8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/requirements.txt SPDXID: SPDXRef-5880b683ebe88769b0920cd8a43acad1 FileChecksum: SHA1: 40b6f11f496bce60ea66adf1760eedf5b09449d3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/run_video_file.py SPDXID: SPDXRef-dacf18b7417605c58f0c95924e22ab69 FileChecksum: SHA1: 893b10e1306eb651bb5258595210d6ee391f9bce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/run_video_stream.py SPDXID: SPDXRef-d3dbb9d55dfb2e69e53540d29090db85 FileChecksum: SHA1: 144e7f300a54f9b4d374ae5acde6007e613b7b67 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/ssd.py SPDXID: SPDXRef-2fba8fe2c6e55f7fd963ad4738541095 FileChecksum: SHA1: 8f0687b370b5549ce1a77ee098f8571d17120a16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/style_transfer.py SPDXID: SPDXRef-0a74b268d3cb8bc80c647c944caa51b2 FileChecksum: SHA1: 9f1f971459b4e92602ee15d61e1f031db011a11c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/object_detection/yolo.py SPDXID: SPDXRef-ab876cd140330d940188ae4b7e59de7d FileChecksum: SHA1: 73f1687f9e8675708555898935982acfaba7707f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/README.md SPDXID: SPDXRef-4e3a455ac22224a4886f3aa8df4a9be6 FileChecksum: SHA1: 6c8fd242e1648f1841f57fb9c3137e04e1cd57b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/audio_utils.py SPDXID: SPDXRef-ede59973cd6325312506a61c5fb99528 FileChecksum: SHA1: 36ffa6da6bbd268c5352b9baf8c73fe48cba9059 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/requirements.txt SPDXID: SPDXRef-befc0678b22a4b933e058978e018c7a5 FileChecksum: SHA1: 3382d00b96347a142d434805cb78f387d5b3d1c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/run_audio_file.py SPDXID: SPDXRef-39387ca0054ebb3deb42a7f21f7bb390 FileChecksum: SHA1: 5d442c8f5c3b7a927e8b88c42f9efe7aad0ca94a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/tests/conftest.py SPDXID: SPDXRef-888af6ba8660cc1f771cf90b2a0cafe1 FileChecksum: SHA1: 6c085ef5f46c5f324f0d3fd2405394548934a675 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/tests/test_decoder.py SPDXID: SPDXRef-2a48b38c149fab4b72079e904501128d FileChecksum: SHA1: 631e6a5ecbfc522afd04d9ef6b13255b7173a5f3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/tests/testdata/inference_output.npy SPDXID: SPDXRef-1d441556d8fc8de1734c1fca19e82034 FileChecksum: SHA1: ad7a9428e2a26340af4036fdc0aaaba188298da6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/tests/testdata/quick_brown_fox_16000khz.wav SPDXID: SPDXRef-a3665f9392f50cda3cbc2e4cc6b133d4 FileChecksum: SHA1: 8c9f42162ce080a3572359020f03638cae0a0056 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/speech_recognition/wav2letter_mfcc.py SPDXID: SPDXRef-ee5b58f949a975b0b3d9e1f0447ca300 FileChecksum: SHA1: ed110a464714e0826ccbb0c7cff11c8e042d78b8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/conftest.py SPDXID: SPDXRef-a2a403dfc946f17220abf36e73274650 FileChecksum: SHA1: dd07b3aecf3b75ff294ebbb1b6d10bf7fadfc47a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/context.py SPDXID: SPDXRef-d46b209457e0e564a2279733723eb7e2 FileChecksum: SHA1: cc4bc7d110468593a5e8e8fcb6e5b40980239519 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/test_common_utils.py SPDXID: SPDXRef-5084bf78c1e38d19616e994631cea31c FileChecksum: SHA1: 5bac5a72e3ed976e54d7019b4fd919df531e93c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/test_mfcc.py SPDXID: SPDXRef-138fb2007dac779817d743bfb7fe25e4 FileChecksum: SHA1: a0d560ea136a1ddc32317504639ba2b7e19e1c64 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/test_network_executor.py SPDXID: SPDXRef-c9e2f75d3fad2a801fe5f056145d99d5 FileChecksum: SHA1: 34752b1ba35052e1d8acf0a78d91cf432faed807 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/test_style_transfer.py SPDXID: SPDXRef-b421759201d2107dbec29d82741ddd07 FileChecksum: SHA1: 70547a3c3c1185fdd6a81dbeecb210a5cfbe0340 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/examples/tests/testdata/labelmap.txt SPDXID: SPDXRef-052b8f0c6ce5a6b91c00e38e7ec7e28e FileChecksum: SHA1: be50d25ae70969250c162522656796ed31d1fc39 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/pylintconfig SPDXID: SPDXRef-89f74ef11f67c6dac90b69f87ff6d508 FileChecksum: SHA1: 2c0de0b54bbbb1b83a3bf7a787621fa49bfa1b90 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/scripts/download_test_resources.py SPDXID: SPDXRef-371de54e69a41e25a72f75f2bccf4e88 FileChecksum: SHA1: 7195098489999343206a5e3115fc9231e396e384 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP FileName: ./python/pyarmnn/scripts/generate_docs.py SPDXID: SPDXRef-9b390edd3bec003039e5b1f42371c367 FileChecksum: SHA1: 53e5d84c5654cedb54332e54c3b677fc64883dcb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/scripts/requirements.txt SPDXID: SPDXRef-9858839b87f00c57a2ad83e7e337a03d FileChecksum: SHA1: ead481e6237d1026444d7f84ad211691577bff57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. Copyright © 2020 NXP. All rights reserved. FileName: ./python/pyarmnn/setup.py SPDXID: SPDXRef-2a0d98b1d672e625daebe620667b6894 FileChecksum: SHA1: 17c8d3e5121f195b64e8f4e0fabba6095b9d4a8d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. Copyright © 2020 NXP and Contributors. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/__init__.py SPDXID: SPDXRef-4919871e8239fb6be712350d9e20778a FileChecksum: SHA1: 55f6b00458e743e45a80779296d7ce56fd1596cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_generated/__init__.py SPDXID: SPDXRef-2da07eaf9c68bd74b1273ecf17362da4 FileChecksum: SHA1: 122017db02c3e504c484c94fcd426e7b4ba2dcef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_quantization/__init__.py SPDXID: SPDXRef-a547bf4951b19ae7ad6ea1a248b6f960 FileChecksum: SHA1: 44af215401f8335445ec31395609ffbc259e9604 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_quantization/quantize_and_dequantize.py SPDXID: SPDXRef-fce60349cd8bffca6f0b60676147a01e FileChecksum: SHA1: 11a0c69da6eea2d2651c8eb0b27f05bb42f00ebe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_tensor/__init__.py SPDXID: SPDXRef-6e9ec2f78bbeab335a33339b1a0e355c FileChecksum: SHA1: 49a633fe31424e87c6c45ba68ae0f6a16eec3c34 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_tensor/const_tensor.py SPDXID: SPDXRef-2d1e88659363ed7288e025e6f2e8cab4 FileChecksum: SHA1: 66e27455e6f87601b316c5833ec16645fd016016 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_tensor/tensor.py SPDXID: SPDXRef-4fd4a0f0bcb71ecb6a5027647e7da645 FileChecksum: SHA1: 0253aa07b4e795c8669641db16fb3baaf8e82a6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_tensor/workload_tensors.py SPDXID: SPDXRef-30c9ee7a0dce1116c8ce4c2fd2239e64 FileChecksum: SHA1: 61f9507085afb47a31aed284f2f39964e0d93f82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_utilities/__init__.py SPDXID: SPDXRef-b41038ba2d7e138d22f91254b5cdb1a8 FileChecksum: SHA1: 534dd5fa6539989d5318df91565c09e06450aeda LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_utilities/profiling_helper.py SPDXID: SPDXRef-cac41d3cc0553dc11edc7f4b7b22763c FileChecksum: SHA1: 9d4b6c7e1aed74a4c78fd5b802f35c016ad3d14d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/_version.py SPDXID: SPDXRef-7928f2e3bf4360528fcca23ced62396a FileChecksum: SHA1: d69ad69f6d46f7d6942bbde4faf2e0a076f2c55d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/armnn.i SPDXID: SPDXRef-90ab4a23878dd16e3a776be58e001f83 FileChecksum: SHA1: e10fe588c2f974d6d904d0428779344302f8e3f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/armnn_deserializer.i SPDXID: SPDXRef-b4f79d389222cc6d229e2be6a203ea19 FileChecksum: SHA1: 145ff0f12e31ba93b8c7a51a8a6d17cb8b869f6a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/armnn_onnxparser.i SPDXID: SPDXRef-ebc697b78555fed7c5f2e8a56851cf2d FileChecksum: SHA1: a4d6c8c827916873d8173640afefb3cc7a89d30a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/armnn_tfliteparser.i SPDXID: SPDXRef-3c2955bb4d2ad8c12ecd7780e8088c7f FileChecksum: SHA1: 429bc35ca86cea75f3669d56667d3d3857e09121 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/armnn_version.i SPDXID: SPDXRef-71644ab27228168938641c11d82bc426 FileChecksum: SHA1: 9cb197836b9724f2d1867caef5dcd1580e27335a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_backend.i SPDXID: SPDXRef-cd7355e62e0a66783c05985b9ed45738 FileChecksum: SHA1: b082d9e21614c1f2d70c3d2be4a3430c2ab71b03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_backend_opt.i SPDXID: SPDXRef-87d51466e07ab3c217ffbfe6a01c1249 FileChecksum: SHA1: ac921e7ff5e59922a9629494f14f250fa16aa999 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_descriptors.i SPDXID: SPDXRef-df073203a19a70080da785e926665ebc FileChecksum: SHA1: 5316b686dff932f592b66c85b06770aaf7a84b99 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_lstmparam.i SPDXID: SPDXRef-3c722d0d709b74e10fe2a0f0f91aa9fd FileChecksum: SHA1: e4002cf3ad13a5c6baae6d10b02b5983bfc48f86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_network.i SPDXID: SPDXRef-cb9c5392e3a64e083a8f6d119a650d75 FileChecksum: SHA1: 0e96698ed994e024049dbfbb9f4eeda01a2945e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_profiler.i SPDXID: SPDXRef-8388ea018fdb79a95e3e7320cce01ba0 FileChecksum: SHA1: a3727de36e0daa6cc5d4f7a45d7ef73b3b4a4eb8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_runtime.i SPDXID: SPDXRef-8d066fafdb4a6021928e33b5d0d8234a FileChecksum: SHA1: 7687a8a8ed51c817f649b17cab899e42ab1f6f0d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_tensor.i SPDXID: SPDXRef-81af5f57aa7f4c1505835c74aa2ba235 FileChecksum: SHA1: b42c87ce3f02daa938c581fb971b7ea430e4a5af LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_types.i SPDXID: SPDXRef-2b8e97e7ee080b5f665025d04c581451 FileChecksum: SHA1: 7cd7cf07b40c8c3104482f70a8fc8a42d5753e3f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/modules/armnn_types_utils.i SPDXID: SPDXRef-c453741e60005dfdc0c5270429feaf09 FileChecksum: SHA1: ca89eaa9102fb541cdb7767ca81c52f012fbdc38 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/standard_header.i SPDXID: SPDXRef-d5cd8a7a548222e39982edaf35d2268a FileChecksum: SHA1: 850798689ed4b925fbeb016c0d6ba2d07bad5368 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/model_options.i SPDXID: SPDXRef-cd7ba0a86aa2c4da5851c4169cedd6e8 FileChecksum: SHA1: 60eedb443bb191228eb828fc098ef9b8cefce59e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/network_optimize.i SPDXID: SPDXRef-16696d1de96c9f531db1447b487aaa74 FileChecksum: SHA1: 0a4bf70542b8436477e867e71814a373583d261e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/permutation_vector.i SPDXID: SPDXRef-bae875f6d1f9581920ffa2c00c212072 FileChecksum: SHA1: 9d10c6c0a3a3dff935282715b2bf755ecada80bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/tensor_memory.i SPDXID: SPDXRef-3c22390f6c845e2ff98cf01e02fe02ce FileChecksum: SHA1: bb7be21750d06b8004eddbc85e1f3cff854c3d12 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/tensor_shape.i SPDXID: SPDXRef-8baab4251bbbc07534a6cf1662b2085c FileChecksum: SHA1: be8d666484e20dd77cfb40f0ea00b377aa858d22 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/src/pyarmnn/swig/typemaps/vectors.i SPDXID: SPDXRef-0a8d0646054f104534b3ab4c0c5b3dcc FileChecksum: SHA1: 1576e8aaab1229c4439aaa122f0bf7a0b104c61b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/swig_generate.py SPDXID: SPDXRef-dae95b6d38785b994bc2882ff507cf41 FileChecksum: SHA1: 18a7c0b29fdc23aa8303d7184e314d064c2fc194 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_const_tensor.py SPDXID: SPDXRef-f20ea45393b2162387c5d4996e0c7ea6 FileChecksum: SHA1: fe6a27dd48d7dd743e9dd33823c2e8f250ce2006 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_descriptors.py SPDXID: SPDXRef-9e06eb2ae5ce61c8ff0b463846b6db3a FileChecksum: SHA1: ccc41f83165df97d35d9fbe9d19deec8209b9bcd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/test/test_deserializer.py SPDXID: SPDXRef-9947a6cc5149b2e24175f684df2c7618 FileChecksum: SHA1: 822442eed741b73e10be50c82d867eda213eec16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/test/test_generated.py SPDXID: SPDXRef-fb829195149705d43dc6cffbbdbb1e98 FileChecksum: SHA1: 4b87b57524dd131c8f85733b71e13c7e1ca998a8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/test/test_iconnectable.py SPDXID: SPDXRef-82bcd6c81180fa526245bd1b26a2f4c5 FileChecksum: SHA1: a46d747fb01da591ce9007d9c64977d2d1a6b835 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_modeloption.py SPDXID: SPDXRef-bde9e6bdf8b63156d2814df29f1ef393 FileChecksum: SHA1: 8962b161065c432b8f1f261bcafd01923795851f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/test/test_network.py SPDXID: SPDXRef-e026f0b9db7299206c858ca345dfdac6 FileChecksum: SHA1: 85321a6d038e96f4cb8b7c0e3df23ef5750e2fff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./python/pyarmnn/test/test_onnx_parser.py SPDXID: SPDXRef-bf68a0c206555030ddd829c8844787d5 FileChecksum: SHA1: efa4f3c8428ef129d2ec6f408d0ac3b8a071a0f5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_profiling_utilities.py SPDXID: SPDXRef-f6646709040c57b775c2179b89e3d35d FileChecksum: SHA1: 990958338d5c7cbb8d515500100457cc638e38e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_quantize_and_dequantize.py SPDXID: SPDXRef-df4e04588464ef073a2d1af99151c18d FileChecksum: SHA1: 11e92c76bce4e25d0069ad6788d957d4926bef04 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_runtime.py SPDXID: SPDXRef-2a6797d0f2d351c80e7f28790f42110c FileChecksum: SHA1: 27d6d6bde977aa810b94fab640e1d3ee8e82c1c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_setup.py SPDXID: SPDXRef-53196a5a5f7e7cb214f522e171cf5e71 FileChecksum: SHA1: 5a3ccab27547e5a2019cbd8d8514afb39e01ba40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_supported_backends.py SPDXID: SPDXRef-22d147a786da158db7ca96e3374dc4f5 FileChecksum: SHA1: 4a19fc8fd2a3e73d5535601dc54ca09d46be3d6a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_tensor.py SPDXID: SPDXRef-cf22b0e4ffbbec5bf521665b369430e3 FileChecksum: SHA1: 22b34aad1e359e49cc9e75af098176bc665a6963 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_tensor_conversion.py SPDXID: SPDXRef-f7afa3505b0d4d4d5d1517d1aab27dd2 FileChecksum: SHA1: 6dab59b819c0ba7bc7c9f1bc7f355972c044ddcd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_tensor_info.py SPDXID: SPDXRef-52435e0a7389b713f53fb5543a7e0273 FileChecksum: SHA1: 699dc5db6a4679c4d6b2fd0adf86d79f3350d038 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_tensor_shape.py SPDXID: SPDXRef-db206dc4eccaf92ecc3fcac0496a38a8 FileChecksum: SHA1: bf85e86c082eb963616756927b60e1e23a1fbdd6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_tflite_parser.py SPDXID: SPDXRef-a43c7af377209742221957eb094ca75e FileChecksum: SHA1: 20ae48d2fa05c65452560bf8dee9f9ed3a2e6d75 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_types.py SPDXID: SPDXRef-68e3103103d3d1b5d071543a0d6ed25f FileChecksum: SHA1: ae77f98c55305b572eab9aad240a92ce90448484 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/test/test_version.py SPDXID: SPDXRef-3281600fb4d1daaf20cabb006161804b FileChecksum: SHA1: fb930cd4f9237a5899f527a520ce789889ed5237 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright 2020 NXP Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./python/pyarmnn/tox.ini SPDXID: SPDXRef-68a65b5f5c244e4b940dc825fe964e80 FileChecksum: SHA1: 9e48db88df6df717c9675987666b8ed46428046e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/AsyncExecutionSample.cpp SPDXID: SPDXRef-f71b0e1aec9215660cca8db257822af4 FileChecksum: SHA1: 8440e7204287132a304d8ceed36be9f5deca1342 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/BareMetalDeserializedGraph.cpp SPDXID: SPDXRef-6cc9acb31b251b62ef3597f558374567 FileChecksum: SHA1: a2a82b78a6ac1b9560b0be07e2a381d212fc342c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/CMakeLists.txt SPDXID: SPDXRef-7f5e9264e8d7fed5b18227695c13e9bd FileChecksum: SHA1: 8f902e641c1beb23b464aa5a9a94541a8ece7618 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/CustomMemoryAllocatorSample.cpp SPDXID: SPDXRef-ff44429858ef02c5c450ca2987342d1d FileChecksum: SHA1: ea592259c50fa0df04f5dea5b2c3b58de5d82317 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/DynamicSample.cpp SPDXID: SPDXRef-a716e819b0fff85abca0605a576ac4c9 FileChecksum: SHA1: d5fe836126bda297b591efa4fcfa34cf71656f1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./samples/ImageClassification/README.md SPDXID: SPDXRef-7e415800177f74d9257ab4e3c1445457 FileChecksum: SHA1: a582c3d119c4d643f7d1e9139334ff118e7578dc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ImageClassification/requirements.txt SPDXID: SPDXRef-ef5d74603f85e6d4397723ac3229ca01 FileChecksum: SHA1: 7a48010d593816a763727d06888a3dc2e12ed330 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ImageClassification/run_classifier.py SPDXID: SPDXRef-9cf78592246e686186cb0c217d3f3107 FileChecksum: SHA1: 06f585e708c9559f0c8e6095fec444af1679c781 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/CMakeLists.txt SPDXID: SPDXRef-63f7bd113aff490ffa2c1b6382cff00b FileChecksum: SHA1: 58c5417d2ac7caec0f424c7ae37f7d76cec96992 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/Readme.md SPDXID: SPDXRef-b0335bd8f38d05d7038cc593f07726e8 FileChecksum: SHA1: ca22a723eac49a5cf9438d4f08ffb4a3f17dbd93 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/cmake/unit_tests.cmake SPDXID: SPDXRef-0cdb922f7d7ed906d3702946bec5acc0 FileChecksum: SHA1: ca53cedcf76e808512320db22072af98a163e03f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/include/Decoder.hpp SPDXID: SPDXRef-c4b3ce6cc9e2e0a5992af8cce0415b02 FileChecksum: SHA1: 0db6d23fddbf2f07f9955a4b5850d5d5e5b89eea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/include/DsCNNPreprocessor.hpp SPDXID: SPDXRef-989cb431b75059772fda5a9fa812051c FileChecksum: SHA1: f8aaf9be1bd931968d310ab71b11e5da328a25a2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/include/DsCnnMfcc.hpp SPDXID: SPDXRef-1a43b63a5e5ee302f24c2bca786b2568 FileChecksum: SHA1: 22f04846d1bfc197b89cfc4630411d79e5780d7b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/include/KeywordSpottingPipeline.hpp SPDXID: SPDXRef-9e2cb50b1b305501d2b6802919d6fdb7 FileChecksum: SHA1: 954323e6f03ee3dcf33b60967276eb6a0de45643 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/src/Decoder.cpp SPDXID: SPDXRef-42dac01f930694a9cdba57562c45fd2b FileChecksum: SHA1: 974fcc728123ec49d88abb2b9cc6ae60d6ca9b28 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/src/DsCNNPreprocessor.cpp SPDXID: SPDXRef-181b47701def10224441a14dd71533a9 FileChecksum: SHA1: 9e6f9ad02a9156fa99efacb4b467d2884c0b41c2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/src/KeywordSpottingPipeline.cpp SPDXID: SPDXRef-1a81febdb9022caf0dcac23d298abbfd FileChecksum: SHA1: 3e6a56ce362894fe6973690c9025b2f43fb07876 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/src/Main.cpp SPDXID: SPDXRef-10758186651ab9a33cf1b4b6d51ff3d5 FileChecksum: SHA1: c1e7534981d1f6312cf289afd3b6ba8d1aacf57f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/test/DecoderTest.cpp SPDXID: SPDXRef-ff005bb04364ce552bab414d95d3a86f FileChecksum: SHA1: 89a20c37e31f880737ebcf86ab0d26f39a4f1919 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/KeywordSpotting/test/KeywordSpottingPipelineTest.cpp SPDXID: SPDXRef-9b2845049fd1a8415e559b8dd81287b5 FileChecksum: SHA1: 649103f77f49bf4260fb4b9a581335c90ecff11c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/CMakeLists.txt SPDXID: SPDXRef-0e9af1258f3d861c5f4704da0af81383 FileChecksum: SHA1: b22b16b47d4db71ccd090d6c479734a85349791c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/Readme.md SPDXID: SPDXRef-ddd23882c9cc0c4201bb2c8849509383 FileChecksum: SHA1: f431ed82e5e0878294ea034b56f2c8b438a05219 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/cmake/unit_tests.cmake SPDXID: SPDXRef-7035514c0ddcb8e4acc1cc5ab1cfae9a FileChecksum: SHA1: 7be0dd8cfcd0d7596fcbc15bfd8dfb91825feb74 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/BoundingBox.hpp SPDXID: SPDXRef-f4ce531a32f90497e860585698056d11 FileChecksum: SHA1: 8b4de7bea7bf517b091277db8e6b3f66f400595d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/DetectedObject.hpp SPDXID: SPDXRef-c3594cd4b7a29056267323de24b613fd FileChecksum: SHA1: bbaa6456ae5ebfd92e7922e6af1b1b9897b46e50 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/IDetectionResultDecoder.hpp SPDXID: SPDXRef-f40537cb9837e0d95e07b578607bf0e2 FileChecksum: SHA1: 9b596691ba86cb368dc2b302d089fe2d682ce49e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/ImageUtils.hpp SPDXID: SPDXRef-c264bcf2d29af1511b9a576b8ebbd7de FileChecksum: SHA1: e477477f2fa4e0936ebb5be79665d2c5a20aa958 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/NonMaxSuppression.hpp SPDXID: SPDXRef-00ef70819ad0e9fd2ec4d5f1462c1141 FileChecksum: SHA1: 8a755933be7243af6d813928f91fc50fcb75c461 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/ObjectDetectionPipeline.hpp SPDXID: SPDXRef-8b2d833db3153d2513deded1110c5385 FileChecksum: SHA1: 8ac0c3d1fcb1cde239a17ef4f10019165f9bff91 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/SSDResultDecoder.hpp SPDXID: SPDXRef-c6f0d0a046d25283a06e6676e2dc9291 FileChecksum: SHA1: 265a066d93ad9f0a7b628cdd5b515d47661839a9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/YoloResultDecoder.hpp SPDXID: SPDXRef-bddb6be6ea0a238b40be6bc819d1ec93 FileChecksum: SHA1: e792b229ef1633751d42a9e005f240a0a58bcd7d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/include/delegate/ArmnnNetworkExecutor.hpp SPDXID: SPDXRef-27ae9304388ab829277c68a4ed2f6f4c FileChecksum: SHA1: 54db9d001737cee66ce6d1f9c01b8d14b775062c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/BoundingBox.cpp SPDXID: SPDXRef-bac70bf29a3b92c6c3083ac7d8f6bb75 FileChecksum: SHA1: eabb0a5770848990ab06a2b72e6f2483944044b0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/DetectedObject.cpp SPDXID: SPDXRef-dcbf8bd21e39e513d33898038837553c FileChecksum: SHA1: 5b5ba8b721234614280699f18e0e117b0eb24b78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/ImageUtils.cpp SPDXID: SPDXRef-f32f5a755e029e9fff3e2d68e35f501d FileChecksum: SHA1: 4e8635cfd7b926b480e149b00d4be2cd515a8475 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/Main.cpp SPDXID: SPDXRef-d7501342edf76668a776121f3d228113 FileChecksum: SHA1: 6af8776c3e980053ab7d8864d36187d3ea26eee2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/NonMaxSuppression.cpp SPDXID: SPDXRef-448edb9f6b007d095a74d7582d61b7b1 FileChecksum: SHA1: 94e41c76b9caf2b7143d165d99a19975454752c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/ObjectDetectionPipeline.cpp SPDXID: SPDXRef-2e810f156dd29a4e8cc181506623a65a FileChecksum: SHA1: eb547739deb350e5de783ec58570ccf2520d185f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/SSDResultDecoder.cpp SPDXID: SPDXRef-f0e5791fe010460f23afd51ea0c2ca3e FileChecksum: SHA1: 37590457fed8636de7d1998e29fdb67863af57cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/src/YoloResultDecoder.cpp SPDXID: SPDXRef-999c44c06c037ab241af9972594910d8 FileChecksum: SHA1: 01e94cffe666b2b5873ecbcdd377f6c49e6628ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/BoundingBoxTests.cpp SPDXID: SPDXRef-cb19a20311685f238f20de7fc3d9f497 FileChecksum: SHA1: ac3a052ad7be418ac962878410bb1ce0bbb4a9bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/FrameReaderTest.cpp SPDXID: SPDXRef-57414982d972203a4a5b15f4f3e10992 FileChecksum: SHA1: c7893c10905ab070c2fb65b7e9a1cd34eeb2a8e7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/ImageUtilsTest.cpp SPDXID: SPDXRef-42b94778be5dc923fa2500632f83999a FileChecksum: SHA1: 6936705cd5b1d66a30a389e418037830273dcec2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/NMSTests.cpp SPDXID: SPDXRef-31b12eb924dbd0c582df04042001e766 FileChecksum: SHA1: 6aa212d63a96902f31eaf29acc8d1fa435e936e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/PipelineTest.cpp SPDXID: SPDXRef-51945e5eb97ea2f83e8b8f87bf7416fd FileChecksum: SHA1: 116a0218f7b91f5915fa38f93fb3ca9f128b0b43 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/ObjectDetection/test/delegate/ArmnnDelegateNetworkExecutorTest.cpp SPDXID: SPDXRef-cbb068dde8b6eab4d40ca768bb139343 FileChecksum: SHA1: e99738e90b596878d95efa5b8393da3d1a4d647f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/PreImportMemorySample.cpp SPDXID: SPDXRef-43d0efd536842b8965022f9aace24f06 FileChecksum: SHA1: e14ae09506444d0596e6cd81139f3a2ed0c91dd3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SimpleSample.cpp SPDXID: SPDXRef-4a96e51a1722acc182a5d8c94d1ed868 FileChecksum: SHA1: 059b241b080fba9f284458eef39d08ebc9071c73 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./samples/SpeechRecognition/CMakeLists.txt SPDXID: SPDXRef-e2158d8a46473b9092893d20a0913c67 FileChecksum: SHA1: 21cd006abcb13a16b4a286e6d84d834783d74988 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/Readme.md SPDXID: SPDXRef-8f01b197176d2129341e0f9a0315036f FileChecksum: SHA1: 18d53e8d751e1dc5cf1f99b3b996688c8c3858dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/cmake/unit_tests.cmake SPDXID: SPDXRef-4be2c1f40857d13aff3120dd2c0bc3b5 FileChecksum: SHA1: 2b9bbed315b939af81f6919a89119821f760e650 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/include/Decoder.hpp SPDXID: SPDXRef-00e03efe88ba3846363f1092b75bd4f4 FileChecksum: SHA1: e80e21b985d26f5a800753b436c99713dfb0b946 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/include/SpeechRecognitionPipeline.hpp SPDXID: SPDXRef-05f0d1345e86e49182b125c42a794285 FileChecksum: SHA1: 1b656c38423fa310ea8b419533976a025f9d7f1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/include/Wav2LetterMFCC.hpp SPDXID: SPDXRef-7b298bd7b7c07c17b7aaac744ed78b78 FileChecksum: SHA1: 5376c6ec73cabd1c3cc1f7c0daba811ada0d22ef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/include/Wav2LetterPreprocessor.hpp SPDXID: SPDXRef-8551b3ecbf1152e9a0499cc1db6102c8 FileChecksum: SHA1: 22b3b6eef9de8a3615f1745084fb6ca5e3ef38f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/src/Decoder.cpp SPDXID: SPDXRef-601fde10e9f354d47a036d528ca8ecb9 FileChecksum: SHA1: 394aedb4522f0c760b281932e38316c550cb0711 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/src/Main.cpp SPDXID: SPDXRef-0e442df35b220df7e58156e4883dd860 FileChecksum: SHA1: faa3f5c8be138b731b45e374a3a3675472e261e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/src/SpeechRecognitionPipeline.cpp SPDXID: SPDXRef-b63cb50adab6fcd5b8e56a6cf1bb171b FileChecksum: SHA1: e691a53bfa72af8a9ad2de4a0475e25e91b150a4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/src/Wav2LetterMFCC.cpp SPDXID: SPDXRef-920eb9d6db5b4847f95babfe51a9da64 FileChecksum: SHA1: 205dad8283fe254f050c949e1a8cf721b6c78e47 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/src/Wav2LetterPreprocessor.cpp SPDXID: SPDXRef-a4cb68f5ca4149577b122a550f7265b3 FileChecksum: SHA1: bb0a82f9409085eb078e5c9cbebaea89baad6504 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/test/DecoderTest.cpp SPDXID: SPDXRef-8e40444bc6632cc59c79dde8373edb99 FileChecksum: SHA1: 0d7ab332841e654443cabf6bce1e74f9367f2105 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/test/MFCCTest.cpp SPDXID: SPDXRef-9a1a6598a707689c554a7c43de8737b8 FileChecksum: SHA1: 90025db256a504d3d1a8a173d54386383277c5d7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/SpeechRecognition/test/PreprocessTest.cpp SPDXID: SPDXRef-6d008fcac89e6de1fab26f11b68cb03e FileChecksum: SHA1: 2512722f330c3e04a5c05cff0dd4cb80ca0fcafe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/cmake/aarch64-toolchain.cmake SPDXID: SPDXRef-dc91e39052fc2e69b27cdf951f8d7e82 FileChecksum: SHA1: 17e9fe5b89d5a9cd8e1fb74e5f082aaf12cb61fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/cmake/arm-linux-gnueabihf-toolchain.cmake SPDXID: SPDXRef-8076d4dde8cb05dc6d7ab8ab3f428cd2 FileChecksum: SHA1: ee3d18a5a2429e5f27d355efc0895c42c519d055 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/cmake/find_armnn.cmake SPDXID: SPDXRef-9d553a72d49ac5680603576088f70bbc FileChecksum: SHA1: 8c155f627ba206079eae4831ada370f0f470797a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/cmake/find_catch.cmake SPDXID: SPDXRef-df6d67a34e1c5aca69631e329bf1b347 FileChecksum: SHA1: 3a4688ae55d6dd6e41ec5ae137b7585f1a682511 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/cmake/find_opencv.cmake SPDXID: SPDXRef-dd660cbb1408c02f8b84736cd75ad0b7 FileChecksum: SHA1: b0ee92714d00b37a66e8dd510f848438cc9a1686 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/ArmnnUtils/ArmnnNetworkExecutor.hpp SPDXID: SPDXRef-beadb21bfef94a3a50d8132e1bdae5f8 FileChecksum: SHA1: ba5df67db2c83ad41752b432ffd82b24c52832dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Audio/AudioCapture.hpp SPDXID: SPDXRef-cfca6ed615d89731db1bb2878526c87b FileChecksum: SHA1: f0f153d8bbbb07f803d73887b7b0687be54a3703 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Audio/DataStructures.hpp SPDXID: SPDXRef-768e22a6d018a0c6234dc9cffe9d92fb FileChecksum: SHA1: e46d2f889638e87b14815aea25434c1279c55854 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Audio/MFCC.hpp SPDXID: SPDXRef-35f245ae7f86eb7fabf43fc88d54a601 FileChecksum: SHA1: 06764b43612b216674145189c6fb405b8e39a828 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Audio/MathUtils.hpp SPDXID: SPDXRef-d85342700d84a50260ac796634e931fe FileChecksum: SHA1: 1789fdda915a3b79c34931cbea09e32729d47c83 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Audio/SlidingWindow.hpp SPDXID: SPDXRef-4f051799eacf87d7a87e1867602b6981 FileChecksum: SHA1: 151278c620d360b15dce99d33adade6113a22dbc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/CVUtils/CvVideoFileWriter.hpp SPDXID: SPDXRef-57d170c243c54b513f27573764b6fa89 FileChecksum: SHA1: 99abdf5a64970860dfc50fa89cface9ec1eb9069 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/CVUtils/CvVideoFrameReader.hpp SPDXID: SPDXRef-64889f0454ee8ad2c57a5c9578c55371 FileChecksum: SHA1: 0d17089dc645787062426a263e833796a411a120 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/CVUtils/CvWindowOutput.hpp SPDXID: SPDXRef-8d776a5f24a0b05e348485b096abab4b FileChecksum: SHA1: 1da517ca575f3740d0dc9f471ce9aa2d76fd93ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/CVUtils/IFrameOutput.hpp SPDXID: SPDXRef-95078301f4baaefaa6f32369301b9eda FileChecksum: SHA1: edb234fc5bde321e1f76a1702ff66a40afe337b3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/CVUtils/IFrameReader.hpp SPDXID: SPDXRef-89dbded08bba866a65f1b9b08a212cff FileChecksum: SHA1: a6496f4737912881d9c539dd1ba1ca13789ac8e7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Utils/CmdArgsParser.hpp SPDXID: SPDXRef-1c97683da8fadf097efcacb784121aad FileChecksum: SHA1: 9a3997c325a515346f8cd179d8006b806e4226da LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Utils/Profiling.hpp SPDXID: SPDXRef-9d8a908e6ef872ff22853220ed97719e FileChecksum: SHA1: 4248c7cded8c6104bb46cc4de49c17ac9337e73c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/include/Utils/Types.hpp SPDXID: SPDXRef-dc62d231f240014d32c2537306bfaf26 FileChecksum: SHA1: 687356b1dd4e84752645abe0365e8ff511be2f37 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/Audio/AudioCapture.cpp SPDXID: SPDXRef-daa2860a520202e677a23a63e5dd280d FileChecksum: SHA1: 27e031c2fc587e69dd1328be49b7c62dd3b36835 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/Audio/MFCC.cpp SPDXID: SPDXRef-1eb909a37f3c0a1b0b4fb7a6bb533f95 FileChecksum: SHA1: aa9b7026fce1b38eb00607c0833f0c0561985f17 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/Audio/MathUtils.cpp SPDXID: SPDXRef-9ec1b591ac52b537a490a8784d4dbd40 FileChecksum: SHA1: 4adb34056f516af60d7a23b7bb172498df39cfc8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/CVUtils/CvVideoFileWriter.cpp SPDXID: SPDXRef-ce72d924806596e1a3840c314c6ba5eb FileChecksum: SHA1: 5aeb506b09dbc356e4b47252ace3dbf3576fe79e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/CVUtils/CvVideoFrameReader.cpp SPDXID: SPDXRef-79dcd8374fe581c25b32de1b97166455 FileChecksum: SHA1: 8a773398b5d13048eaaef8bdd73c6d9fa53dd3a6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/CVUtils/CvWindowOutput.cpp SPDXID: SPDXRef-ab637a3e1ab7b42cea169dbfee29c201 FileChecksum: SHA1: ca00e6e3438c688658fcea127fb89ddc0e7d0332 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/src/Utils/CmdArgsParser.cpp SPDXID: SPDXRef-22062fc6959c3f1b48f345430d5e49ea FileChecksum: SHA1: f256de9aca885157329e30048b7fa28734c4c9bc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/test/Audio/AudioCaptureTest.cpp SPDXID: SPDXRef-926b743ba23bb19816a350868dbd0e38 FileChecksum: SHA1: 4e0e6466aaf9fcc7ba2bba266869687b8fd2ae9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/common/test/Audio/MathUtilsTest.cpp SPDXID: SPDXRef-203823ef038c5321218b668f2c36bd50 FileChecksum: SHA1: d731b792081d2e4924db50b70ac9af47a854402f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/examples.dox SPDXID: SPDXRef-43951c61004ac2aa3ece1738225e0a24 FileChecksum: SHA1: c3e63fc63af6b44554c89356aad9362aaf5f9bdd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. FileName: ./samples/serialized/Readme.md SPDXID: SPDXRef-0210de5f2231ff8f13570d850a9277b7 FileChecksum: SHA1: c72579c51dfa2f1c2589dcb4b5745d40ff9929ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./samples/serialized/ssd_mobilenet_v1.armnn SPDXID: SPDXRef-f0e3031b968326ad845e1692887e306e FileChecksum: SHA1: b547f4a2b2ce116caaad9edc919d4e3df25c28e9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./scripts/generate_spdx.sh SPDXID: SPDXRef-eb982c905276147f396610b9cce80d1e FileChecksum: SHA1: 6bf2b0bae26f0ec2a99357bfd1c39c2b4affb1c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./scripts/generate_tensorflow_protobuf.sh SPDXID: SPDXRef-6329451f9b119c106ca8814116608860 FileChecksum: SHA1: 2c99edecc24bfcd8a6aeb561b65d463844f2b698 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./scripts/get_compute_library.sh SPDXID: SPDXRef-dcfb46a140c6e8968fbaf23b515a73ce FileChecksum: SHA1: 7dacdb9d7a033c0b21c9335243117d23a383679e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./scripts/get_tensorflow.sh SPDXID: SPDXRef-9d2977bb861158e4097218d229aef02a FileChecksum: SHA1: 8a39e21d91a45300139eb6298c28f5fb615f9fd2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/Android.bp.off SPDXID: SPDXRef-06f5fa016999c7379d1c11a6c29c2a24 FileChecksum: SHA1: b89ffdf851ba866adaf2cd32599d9e54f758bfa5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/BuildGuideShimSupportLibrary.md SPDXID: SPDXRef-d0c7400bf777f4c8bf3f98730b7ade89 FileChecksum: SHA1: af69a943a4de0222cea7166bf955b079a1c5ed1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./shim/config/android.hardware.neuralnetworks-shim-service-armnn.rc SPDXID: SPDXRef-c415e6dd3d6e5c189d6c09334ee0c47b FileChecksum: SHA1: f6c1628a745fc6a57c6fcdffb4c30950be775006 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./shim/config/android.hardware.neuralnetworks-shim-service-armnn.xml SPDXID: SPDXRef-2c57646e16ff5c5dc45f0d0b43921078 FileChecksum: SHA1: 9fb02e74357a14ae8996be70109e03ca10c52efa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. --> FileName: ./shim/shimservice.cpp SPDXID: SPDXRef-4ea31c2f326b4ac12686da6de3e6afbd FileChecksum: SHA1: d9415d413108e74102c05653a1f5ec3a8f41b9be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/CMakeLists.txt SPDXID: SPDXRef-a60195d98b3dbf560cb55329cab65917 FileChecksum: SHA1: d9bab7ce9c5dc672283d2bce9a6054648ab74821 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/README.md SPDXID: SPDXRef-c8bec549f62231b750238b5c6093e5f1 FileChecksum: SHA1: 1a44e082bc0c299a5f309dc547c38e36bc6ec3af LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnDevice.cpp SPDXID: SPDXRef-9f6acb6a01da79d2a8518f46bfa18926 FileChecksum: SHA1: da069528074388f0327f5008a38a9e75accfd633 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnDevice.hpp SPDXID: SPDXRef-440137c760dceabbc73f205348cf47f7 FileChecksum: SHA1: 881b49bb33ad5d148068ee2dbe85e5c46d2f38c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnDriver.hpp SPDXID: SPDXRef-97794aea3fbd704490de9ce685cc2bde FileChecksum: SHA1: 144eec5eadd4b2feb6483c1c01b915751efedd2d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnDriverImpl.cpp SPDXID: SPDXRef-e5541fd55b17c9f5233e4430cce20629 FileChecksum: SHA1: 4af778a697011528e86b3ec7ca716de923a0a0bc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnDriverImpl.hpp SPDXID: SPDXRef-525af756052624e0d427ed01c41a49b6 FileChecksum: SHA1: bf3cf1aa777851ac3ad4e85df2e8367689aa5fcf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnPreparedModel.cpp SPDXID: SPDXRef-73202ee886666b19a5609d3a94ed312e FileChecksum: SHA1: bf6f8ef38895b11978652b36ee8eecdbdd000847 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ArmnnPreparedModel.hpp SPDXID: SPDXRef-343f6e570775f6c985608f511f4607d5 FileChecksum: SHA1: ab141746719d6ea90f20ee141bf9a2ab9a30c562 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/CanonicalUtils.cpp SPDXID: SPDXRef-a91302d5fcb8e2d37c5c9ad98ec4e379 FileChecksum: SHA1: 18c2f74e1d11ed355414943fbc8c34de8ce4c785 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/CanonicalUtils.hpp SPDXID: SPDXRef-38cfd69f8179231e17f1f2efcb9c62af FileChecksum: SHA1: c641f4378894dc152b2fc9d38ca158ba61d6b3ba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ConversionUtils.cpp SPDXID: SPDXRef-c8c426fff47fe00159a6a93bcb2f553c FileChecksum: SHA1: a456e9b7c0f107a16326798a3b346990bb8b0c54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ConversionUtils.hpp SPDXID: SPDXRef-fe2e5c411321df462d0e3ffd3b5cc26f FileChecksum: SHA1: 1a93f9056a26ad6c4862fa4ca8cf59d2fce24e65 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/Converter.cpp SPDXID: SPDXRef-955b7cb297e532882572274cc579390c FileChecksum: SHA1: f7d6badbcb89893761175beb12a5071fbc1395a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/Converter.hpp SPDXID: SPDXRef-c0599cad2845b99759ec542d87bc32fa FileChecksum: SHA1: 15fa03cd907d75ec6d541fd7b70ecb4312376dac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/DriverOptions.cpp SPDXID: SPDXRef-3c26c31598a7357bdfa531297425a4a7 FileChecksum: SHA1: 2cbab5beb4cf768534972896377f7ddbf0b8102a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/DriverOptions.hpp SPDXID: SPDXRef-9b0a9d64d270f46ec638fdd1bf7ed15b FileChecksum: SHA1: 03b40d51d8c5aa4afb0f588b660b2515889a3110 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ModelToINetworkTransformer.cpp SPDXID: SPDXRef-dad39dff72ed3198f24faa705c8a6501 FileChecksum: SHA1: 791a32ab2a88b6659b5370ed0dd47c55d2bb1384 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/ModelToINetworkTransformer.hpp SPDXID: SPDXRef-9a49007a07c4c2d0a6602eed9ff95a09 FileChecksum: SHA1: af419aac48c20722bf00f7565cf33effe875a0d0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/canonical/SystemPropertiesUtils.hpp SPDXID: SPDXRef-f71e9235335df1ab87e849868dfd2ea4 FileChecksum: SHA1: 46a60143b828d0c2ff2324ffe57291e333fc0a9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/scripts/NeuralNetworks.patch SPDXID: SPDXRef-5b8581ca4efb1cbbd37a04b61c9ba0d6 FileChecksum: SHA1: d8d2346c59282b01b83babc258f74ec4585a049e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/scripts/clone_aosp_libs.sh SPDXID: SPDXRef-2eda12225aa1af43bc59caaa534958fb FileChecksum: SHA1: d28b6ac6841c9c19312bc77d8094e312a8c11d6b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./shim/sl/scripts/libbase_logging_cpp.patch SPDXID: SPDXRef-9b4d3337d57a5e61489e7d5a4c5d2c4c FileChecksum: SHA1: ab9668a438a86373eb2e947aa0d773a50c989c09 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./shim/sl/scripts/modify_aosp_libs.sh SPDXID: SPDXRef-2460aab4701257f7a752ba8a67912a91 FileChecksum: SHA1: 785b2c6165ca39c40f5aaff1bf436a78268eff3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 ARM Ltd and Contributors. All rights reserved. FileName: ./shim/sl/support_library_service.cpp SPDXID: SPDXRef-ec80992359df54f7d29f586b063f0025 FileChecksum: SHA1: 4466d66b3b8b174b876a3e6eb8398432f7f12d09 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/ArmNNProfilingServiceInitialiser.cpp SPDXID: SPDXRef-50449a8ab732246726a8c19f838066b5 FileChecksum: SHA1: dc9f25d17dc7680ec21d6d0cd8e69c78d77614f3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./src/armnn/ArmNNProfilingServiceInitialiser.hpp SPDXID: SPDXRef-3ac85d9d7e2535f3723143a37e9acc58 FileChecksum: SHA1: cec7a9f775784e62922f991bcde178546d4386af LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./src/armnn/AsyncExecutionCallback.cpp SPDXID: SPDXRef-207fccfbab38b30d9f4f485544940669 FileChecksum: SHA1: b8242399cfd4719c332019328fad01a386b87ec9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/AsyncExecutionCallback.hpp SPDXID: SPDXRef-571f37b4cd8e6b130e1181bc40acaf2c FileChecksum: SHA1: 2b62b1412f6c763827ac2535ea2110566718cf40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/BackendHelper.cpp SPDXID: SPDXRef-f04e390923d4b39d13b60fc05b5b5e5e FileChecksum: SHA1: 0bf7e2360d925b28099942edd9beeadbb7fe43b6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/BackendRegistry.cpp SPDXID: SPDXRef-47efcb54fbe0b1ec0ca5619645bd2fec FileChecksum: SHA1: 5808b844c0d1e30c889682e68bebdebdb1f606f4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/BackendSettings.hpp SPDXID: SPDXRef-9645aba63403293c9f87203cd53e35fe FileChecksum: SHA1: e09a18a0f785f8d6f5a9a4fb44e3b4590c60827a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/CompatibleTypes.hpp SPDXID: SPDXRef-08b53d7c666b8ec97ddef233895e6476 FileChecksum: SHA1: 8f9c3bf242f17084a1c5a67bac71b7d2f52c7f55 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Descriptors.cpp SPDXID: SPDXRef-9b717e61983d0335a6e916842e2c8d00 FileChecksum: SHA1: ec3e1cee92abd46703aea700715ced998dcb88d9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/DeviceSpec.hpp SPDXID: SPDXRef-b03d3c48672230826cba391d033fbaaf FileChecksum: SHA1: 8408a466078f76b352fe65bc188d85bbf9eecfaa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/DllExport.hpp SPDXID: SPDXRef-456d255c1f522e31727091519759d7a7 FileChecksum: SHA1: a54a476520d5ca6c05a2b3709c0a5868bb08abe0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/Exceptions.cpp SPDXID: SPDXRef-baba663d5cb786fddda364940f1c5345 FileChecksum: SHA1: 90cd3dcce029d2760a680312cd29a6e7a7d94040 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ExecutionData.hpp SPDXID: SPDXRef-57a50e2b431a5323da71f8b1b4fa5dfc FileChecksum: SHA1: 2a4aa407a9f760264813b44a0ea665f2a1edf0de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/ExecutionFrame.cpp SPDXID: SPDXRef-e3f2248e9c62144ad7a1737b22e349f0 FileChecksum: SHA1: a0a12542af5c7304673176ca643c03f421c98d8f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ExecutionFrame.hpp SPDXID: SPDXRef-436a094cfd97fbb91cf82f050fbeafe8 FileChecksum: SHA1: 54a33c9d78febbb169df6d91a4f11d1a3cbbdccb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Graph.cpp SPDXID: SPDXRef-42c2b2f40a99dcc1b7b824973736df55 FileChecksum: SHA1: a314b12a3f6890ab33495e386fc7e3e4e313ab1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Graph.hpp SPDXID: SPDXRef-757c138c4e5972aec39907e20ef98b39 FileChecksum: SHA1: 70bf83657ff605d7a26779d1494e13a47bbff767 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/IGraphObservable.hpp SPDXID: SPDXRef-a6f604f0ae6a4789074466d6ce9f4654 FileChecksum: SHA1: fc31e2f8d0ae65b51ecc11dc6c84cc20eb0f591a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ILayerSupport.cpp SPDXID: SPDXRef-400e52b67a631fb2c3a28da80c1bb799 FileChecksum: SHA1: 8f0957cadabe249f316ed786458be92726144f41 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/ISubgraphViewConverter.hpp SPDXID: SPDXRef-4f97c1d014e6b4f0d23c3339583e7bae FileChecksum: SHA1: ac55b01310a661ed76be97d905c1263cce11128c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Instrument.hpp SPDXID: SPDXRef-3cc2683dd68fbdac603f036e555b423b FileChecksum: SHA1: 1a0833b56d188012a024451931d79c479550040d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/InternalTypes.cpp SPDXID: SPDXRef-7583072fa916d77c3011be34b300a859 FileChecksum: SHA1: 51063844cb9dfeda0fc9497d55f2711372ca2f11 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/InternalTypes.hpp SPDXID: SPDXRef-8d857c4e02eaee3500b308e3bade6486 FileChecksum: SHA1: 01a4b423a421c8ac59e992b0c518b599fcb12eef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/JsonPrinter.cpp SPDXID: SPDXRef-f8236ab289cb02732eba23c9bbf02104 FileChecksum: SHA1: e3e06be11508c1348d3e78b6f3e68e41e1f50c94 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/JsonPrinter.hpp SPDXID: SPDXRef-fb560880c2801791daef42009cd45c6f FileChecksum: SHA1: 2ca89f6125a94c2039e5aef581513b8320649ad6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/JsonUtils.hpp SPDXID: SPDXRef-f662e956015c3f98ef7973088a36cb3c FileChecksum: SHA1: a99018d056d2cbf594af7ad60d66f177e9631e53 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Layer.cpp SPDXID: SPDXRef-c255d82c4008e62c54f9d0e9fe0f59ea FileChecksum: SHA1: 953b2a8e0113ed504ee54d061d119b28f979e14a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Layer.hpp SPDXID: SPDXRef-51b3d6ee29ed55bc7e17f34f845b5ee5 FileChecksum: SHA1: c957036eac14904937e88cbe89331e3761522c9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/LayerFwd.hpp SPDXID: SPDXRef-a7b426845e996f7e0b6b47eca64fba10 FileChecksum: SHA1: 8160b074898013d19a53c81623bf3ec61e014ccb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/LayerSupportCommon.hpp SPDXID: SPDXRef-f5e1de6eb753120e3560fcaefe81bc07 FileChecksum: SHA1: 7eade5897732f599efce0c590628e7b8e31e3870 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/LayersFwd.hpp SPDXID: SPDXRef-760bf0bab9b605c29c944aea40b8cd4c FileChecksum: SHA1: adda1c2ae5b37d40b060befaf5ada6647f809ce1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/LoadedNetwork.cpp SPDXID: SPDXRef-cb703e1449108cdaeef77f1e67ec9095 FileChecksum: SHA1: e2785535fb6999c2bb42093285a5c0a108ded24a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/LoadedNetwork.hpp SPDXID: SPDXRef-7d1ec6d40f23078a35c9131a1da39e72 FileChecksum: SHA1: 01bdf1179ee8c3ca4e8cc879cbe0caffd4745883 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Logging.cpp SPDXID: SPDXRef-15116fd6090151debe3165877ee9ffd1 FileChecksum: SHA1: 8204ffd60aa92d201d1a6f2053d6b1011629a72c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Network.cpp SPDXID: SPDXRef-390509a0f29e0743333dc27fe388bca4 FileChecksum: SHA1: e5fe4aa32854baf17266e5e33403d8254d40e6e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Network.hpp SPDXID: SPDXRef-c3cbd9e36e135e07bd092c310a3f3540 FileChecksum: SHA1: b54db08463c36c7ce1cd918b08652472480197ed LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/NetworkUtils.cpp SPDXID: SPDXRef-ddf315290fab094837d7d026567584d2 FileChecksum: SHA1: 51ad17e25da93e10a9d086fee713558d932ab143 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/NetworkUtils.hpp SPDXID: SPDXRef-4eeb6c729fe70791e30808312bc9dfef FileChecksum: SHA1: 6fb9ec1bdcd5c85551ae984e191fe7f51f57d268 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Observable.cpp SPDXID: SPDXRef-e7ec254e8520c037ef7a8c454036fc4f FileChecksum: SHA1: 5454234e7d1a58b04229673dc4d1094cb800eedc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Observable.hpp SPDXID: SPDXRef-3382c8d205db5a8eb388ca8ddc13af50 FileChecksum: SHA1: 7cde24674eb0e0b98f7abf6def2dc714083dd9e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/OptimizedNetworkImpl.hpp SPDXID: SPDXRef-8f2090e6350a435f6376e25fe790f542 FileChecksum: SHA1: a88fe1cff521b0ea977cca02afab1e6dd3b60d9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Optimizer.cpp SPDXID: SPDXRef-5a51b84da83f26d4cdb9ec55bf7d6d73 FileChecksum: SHA1: fd337a91b6235bf0e90bedab44e785983763726a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Optimizer.hpp SPDXID: SPDXRef-3b6aa1ca39b8f6af95b1e52d06716598 FileChecksum: SHA1: b38b6fd3fc7bb295efc7ba77338202ec939cf22f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/OutputHandler.cpp SPDXID: SPDXRef-3fd267450c33f89fa978d09cb400954b FileChecksum: SHA1: d8b5c412fc340f2cdf5e89e792efd81b5c4ce554 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/OutputHandler.hpp SPDXID: SPDXRef-c044ca75ed19106cef6765246440c356 FileChecksum: SHA1: 0102229dc18ae7cf87b9e90d6eb3737a237fd6c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Profiling.cpp SPDXID: SPDXRef-af3bc546238e631232c75b3197e28068 FileChecksum: SHA1: de0cc9ca4e46eec34fbfec8f635d13f940d1daed LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Profiling.hpp SPDXID: SPDXRef-9947aac05e91e72b9d70c69855d49ae5 FileChecksum: SHA1: c9b680059fd4806b013c516a9b33dc6d0db63f49 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ProfilingDetails.hpp SPDXID: SPDXRef-f3f0d8e70b3d0fbfb0c3d27a416588ef FileChecksum: SHA1: a8889b52ddb93fa019e74fdb764e856bca9e96fe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/ProfilingEvent.cpp SPDXID: SPDXRef-8590d214e6ce096325b3343fd447780b FileChecksum: SHA1: 3222c50221e6da491adf9f253503d7d0b5f17acc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ProfilingEvent.hpp SPDXID: SPDXRef-0f52bbe2bbc72bd570a87fa616c00384 FileChecksum: SHA1: 32f41c4f2fadbfc77ac825e3235617aba8957f78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/RangeTracker.cpp SPDXID: SPDXRef-8178f08ed3ae1b20da210a6f8c4bdf20 FileChecksum: SHA1: d5807571b76414f36614f906a926a72b7fc55641 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/RangeTracker.hpp SPDXID: SPDXRef-6c803e85acb9df0581181e6fe1138505 FileChecksum: SHA1: aacbc1fff0e5cfee4e7092c8590896e24c3e494c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/ResolveType.hpp SPDXID: SPDXRef-0492ce4786f79f71387aea19afa168e4 FileChecksum: SHA1: 0970e525e6b85f87ece98b4abd4759e9a8c65523 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Runtime.cpp SPDXID: SPDXRef-87ca24297ef0a5761ae80cc29c94663e FileChecksum: SHA1: b543a8601fda814458ed3f513332e751fcdebf33 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/Runtime.hpp SPDXID: SPDXRef-dda78375a7875b44040a143ca4ea5bc6 FileChecksum: SHA1: 3c97b40777b53e9855af4b34b372aa45f74727ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/SerializeLayerParameters.cpp SPDXID: SPDXRef-36a1fc3d076b02e651cee8aec7acffc4 FileChecksum: SHA1: 4ed52205bf319c5931f7f88e09eb8bc99a24d04a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/SerializeLayerParameters.hpp SPDXID: SPDXRef-8d4df10b9b7e5e0bce30a2e00808848a FileChecksum: SHA1: 4b5045ffb34137b1a9eb9ffd42e4d054ca92ff2d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/SubgraphView.cpp SPDXID: SPDXRef-d8080e9e6e353ae4249929526d2f11da FileChecksum: SHA1: 78e18dd55dad21ebeceb1be61953290fab61257a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/SubgraphView.hpp SPDXID: SPDXRef-7aa60d658b293bceba9041829284c38d FileChecksum: SHA1: 10b18b456f532747a42232055627faa695d37e3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/SubgraphViewSelector.cpp SPDXID: SPDXRef-f0547b5eb88960e332d35408289dd99d FileChecksum: SHA1: 1068b2abcedf5292b146e5f696d9c2a405b7622d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/SubgraphViewSelector.hpp SPDXID: SPDXRef-37c9e5537f872656c0892d499639f465 FileChecksum: SHA1: 2d353f60bbb773b02432ddc3f396be4bace2503a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Tensor.cpp SPDXID: SPDXRef-cef6101489e501a5d8287ddcb83073d1 FileChecksum: SHA1: cbe837745a6253adf558133863a4e381bd67fe7b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Threadpool.cpp SPDXID: SPDXRef-34352f4f8440297b69c7ae16d733adaa FileChecksum: SHA1: 0f6f8936e48f7b15e15325d7b51b8db34b945f84 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/TypesUtils.cpp SPDXID: SPDXRef-98f61b7544fb47e38764d74d23176d17 FileChecksum: SHA1: fc37305bbbc8805ae4bea6f52b9ef470f75f5bb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/Utils.cpp SPDXID: SPDXRef-e82eef673e44c67dcf9bb0f558ab00b6 FileChecksum: SHA1: 5184d8c5fdada6b21d39a78998ac59b0ed5e083c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/WallClockTimer.cpp SPDXID: SPDXRef-315a79e672bba559f99acf585aac1580 FileChecksum: SHA1: 067af1068474fe9ccfedca5d366623778b007895 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/WallClockTimer.hpp SPDXID: SPDXRef-1ad45a346bea4d95b56340e92b206ff8 FileChecksum: SHA1: 16bed23fb2c7de3e679623d69e57571f50d645b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/WorkingMemDescriptor.hpp SPDXID: SPDXRef-a95479c55d2d3b9592724bd0f82791b3 FileChecksum: SHA1: 44c7080755cb228a492f6051522219690c10259b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/WorkingMemHandle.cpp SPDXID: SPDXRef-5ba2e2efc094e8e1db92ea4d0343fc48 FileChecksum: SHA1: c5055c6ce8638e826385844525bbbbc2720cd1e3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/WorkingMemHandle.hpp SPDXID: SPDXRef-0fa0fbb43bf5a63f4beedd528fa2e198 FileChecksum: SHA1: f86e29c4ceed663ffaa6f3b0d997398c5bd9a413 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/AbsLayer.cpp SPDXID: SPDXRef-8b03aa9f3d781e311921df83d964a847 FileChecksum: SHA1: 24af68cc19252ccd87ce7e4614c82c2addd07fee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/AbsLayer.hpp SPDXID: SPDXRef-591ef6200b87589ec8e2efede6f76e8c FileChecksum: SHA1: 72c7237a90265b0a487905ab8c60c2bc66a12cc5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ActivationLayer.cpp SPDXID: SPDXRef-8fcd4dc8d0ac737e964a07391353c2ac FileChecksum: SHA1: 9a01f7401d1787154fb821973c14acb70236103b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ActivationLayer.hpp SPDXID: SPDXRef-93aa6862a5dbf093592e9adcd18e65e5 FileChecksum: SHA1: 532c51112ba9a8106f72d6ffd2d7b994154efbd8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/AdditionLayer.cpp SPDXID: SPDXRef-4b0d26ac6b9107b11b706552213c563b FileChecksum: SHA1: 1a3bcd9a95227c38979e98451e6c0cdbcb9e1518 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/AdditionLayer.hpp SPDXID: SPDXRef-9027e961d2e8116aafb8a060df9e7c84 FileChecksum: SHA1: 92bff5e278690463f876e29d146d372f832d1603 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ArgMinMaxLayer.cpp SPDXID: SPDXRef-2716a9a72d47cb49f23e90162777407f FileChecksum: SHA1: bd3888f58f3d519cb7dbe726e5c52cd681b750f0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ArgMinMaxLayer.hpp SPDXID: SPDXRef-eea31fd15277b063a0cad43b24c3a082 FileChecksum: SHA1: f3b1ac4695926c9439e78ae092cccf56aa1123c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchMatMulLayer.cpp SPDXID: SPDXRef-10d7775f0081cf5ebcad0564e1a6771f FileChecksum: SHA1: 40cccc20bef5e36e5770f8685d8eafaa3151a395 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchMatMulLayer.hpp SPDXID: SPDXRef-d540552c041624ef1df66f76adf0ee77 FileChecksum: SHA1: 16ba287eb09e398f1653923f8d78f2349b25b924 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchNormalizationLayer.cpp SPDXID: SPDXRef-319f438aee8730f551da3e3f91a33cc7 FileChecksum: SHA1: ad996c6eef968fbdaeb4cee385b0473ccf8d6d72 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchNormalizationLayer.hpp SPDXID: SPDXRef-45bcd545949a90a1c6fc3e38bf56c37b FileChecksum: SHA1: acba026af400914245f9eb966f1fedaf6a9eb215 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchToSpaceNdLayer.cpp SPDXID: SPDXRef-a927de17fc4645f0358523e2a1e647a9 FileChecksum: SHA1: 758865d11d55d5b2c296270939bc67b366bf86d2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/BatchToSpaceNdLayer.hpp SPDXID: SPDXRef-a8cc20df16ac4b76d4266c03628dc908 FileChecksum: SHA1: fbac9b1d4e25ce676be4f6f37c94c5512710170d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/CastLayer.cpp SPDXID: SPDXRef-952e236d3d5064b7679a831725426427 FileChecksum: SHA1: 254591d602229d4321f948c99be3a264bae8d702 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/CastLayer.hpp SPDXID: SPDXRef-3d073d3e2e38843f2ae1ffd63ccb3ca6 FileChecksum: SHA1: e87e025c01b8c8f3f74f09db7c3776be859ceee8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ChannelShuffleLayer.cpp SPDXID: SPDXRef-56a6c45a1ddb6f4452dadd23bfbf6070 FileChecksum: SHA1: de726b38dd4262d530bc9f8d84c9ddf7b3a0b464 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ChannelShuffleLayer.hpp SPDXID: SPDXRef-990b12c3e5bcd56325f879d97cb155e2 FileChecksum: SHA1: 086c2e9db287403a48ba3529fa6fe209d67dab67 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ComparisonLayer.cpp SPDXID: SPDXRef-45aa83d7d5299bb6bba349a5f6d9f253 FileChecksum: SHA1: 03e2cfca67a4e30733f778c0f222ce8410af9c9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ComparisonLayer.hpp SPDXID: SPDXRef-b75f61f50420f83af505ad802ea1255f FileChecksum: SHA1: 08c55bf00d64b58cc30e006a26e6f63cc8024450 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConcatLayer.cpp SPDXID: SPDXRef-178b11b781a33125f80c7a7f9a338041 FileChecksum: SHA1: 5667d0d86286cc42f8c336906aa5151a70809f64 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConcatLayer.hpp SPDXID: SPDXRef-1a2dc90bed3255d00365a4e8f1514296 FileChecksum: SHA1: 90db48a75f329c87892c5948cbd095517306fbd7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConstantLayer.cpp SPDXID: SPDXRef-3f2f51df25f176be8635370bb3909288 FileChecksum: SHA1: 2a9dbc5395b5b3cfa1cc1a9be9530ba998371b6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConstantLayer.hpp SPDXID: SPDXRef-d9e4bd149c655f998dfe6bdb76593b48 FileChecksum: SHA1: 6049e93683051007e7cac28c47aa529a629fca86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertBf16ToFp32Layer.cpp SPDXID: SPDXRef-d69c6daa53dda82a019abd3a38c723d0 FileChecksum: SHA1: c5a9a048a9beb1734fd9475e72025b96475c6213 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertBf16ToFp32Layer.hpp SPDXID: SPDXRef-7488b00f65298d4943d2e1f885101a0c FileChecksum: SHA1: e1bd545d01da4145a091ba027e1e2f457c6e7841 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp16ToFp32Layer.cpp SPDXID: SPDXRef-3ee61341dce5be792676bd19b5960467 FileChecksum: SHA1: c9a787c62eae7cb83edfacb0708a68b1595cf0ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp16ToFp32Layer.hpp SPDXID: SPDXRef-4c8519ab59e5c219d2a7ca40372e25ba FileChecksum: SHA1: 8711cc3b79c3c8f191cb9086c70a6c91dc8cf3fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp32ToBf16Layer.cpp SPDXID: SPDXRef-949f7a792b6ec7d24c30354218c66347 FileChecksum: SHA1: 604613a801a21a41db258c50d2d6e4c8babda602 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp32ToBf16Layer.hpp SPDXID: SPDXRef-7582f29c33f3750415fff5a6cb783323 FileChecksum: SHA1: 82c1c9e6d2680a17d343a1c8a41a41792f4d7804 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp32ToFp16Layer.cpp SPDXID: SPDXRef-558d9f55d95bd3569aad9d44f8443294 FileChecksum: SHA1: 428f091fe32fd3e126676d908424239aeec7d381 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ConvertFp32ToFp16Layer.hpp SPDXID: SPDXRef-5b40eece2aafb29a8fa8ba0e0bd14dd2 FileChecksum: SHA1: 52050c0c77e4b8eab75dc5140b3973d8b4d7705b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Convolution2dLayer.cpp SPDXID: SPDXRef-b325904d00783bd0755057d3fb71eed4 FileChecksum: SHA1: 8261029d4ca5a951bb00ade9d7a762c81c1d267d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Convolution2dLayer.hpp SPDXID: SPDXRef-a8f4ee0ec1e8ab623ac0c8e80b1c25ce FileChecksum: SHA1: 8d5ea77df2151c9cbeb1b5a1893a0db4ff1ace2b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Convolution3dLayer.cpp SPDXID: SPDXRef-3fe02d927785c331b377427b4cffed60 FileChecksum: SHA1: aaeb80cbf8aee1ad1a20a0625dba0ed5fd2f66b8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Convolution3dLayer.hpp SPDXID: SPDXRef-35bf0d3e516235a210c804027574ef51 FileChecksum: SHA1: 2f5643328ab53e1fce2103cd3d38885c7d765033 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DebugLayer.cpp SPDXID: SPDXRef-7d89136cd6a42560a3070acc8bfea3a7 FileChecksum: SHA1: 8c849002414a28266075399d2b24ae57882a5c2e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DebugLayer.hpp SPDXID: SPDXRef-faa72adf2d36bd3816cd6add2f855abe FileChecksum: SHA1: 8cd0e9ab256c8857edc37b0313875570a57bd25c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DepthToSpaceLayer.cpp SPDXID: SPDXRef-e91a67130a3d7f17c940afd6a49f90ad FileChecksum: SHA1: 74287f8cb9aa25ca8aa58664e430589049d0e39c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DepthToSpaceLayer.hpp SPDXID: SPDXRef-b5edcc0eb5c832320d389413a6544e94 FileChecksum: SHA1: b503531a6bbe4ec246683a9e627c9bbf343080e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DepthwiseConvolution2dLayer.cpp SPDXID: SPDXRef-155243f2d5696f2616c1892521fcb157 FileChecksum: SHA1: 974b7cdc1d52a8c489fd7aa33852d9721c372028 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DepthwiseConvolution2dLayer.hpp SPDXID: SPDXRef-336386178b668f83656a4be63542b406 FileChecksum: SHA1: 71eeba5eeddd29f156a4d7d43125c32121bcdb01 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DequantizeLayer.cpp SPDXID: SPDXRef-76986c67647f0e920734d0ab7957041d FileChecksum: SHA1: 0c0453ff21222e336c97cf0e02c1b19ffad8c392 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DequantizeLayer.hpp SPDXID: SPDXRef-0b2ec2bcbd54f67843edddd9619858cd FileChecksum: SHA1: c32ddaf6e9744735e85006d4036f8daf8211eea1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DetectionPostProcessLayer.cpp SPDXID: SPDXRef-9a4a2d388bc7b1bd4f44dae48c413e18 FileChecksum: SHA1: 3c627667841e649133ec82efd1e3388a4ee2c93f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DetectionPostProcessLayer.hpp SPDXID: SPDXRef-2334d8bc4b4af905620dc3d8f2ed5c95 FileChecksum: SHA1: cf07a58850c0df9151ee4e33a9691e16e32dd252 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DivisionLayer.cpp SPDXID: SPDXRef-5b197a1fd5f2a691fd0d87c7a7244802 FileChecksum: SHA1: a26e9183709fb997f41ebad45343897c7404212f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/DivisionLayer.hpp SPDXID: SPDXRef-ab3c6860fb47c56e3b8a3a48e4217dd6 FileChecksum: SHA1: 2b1cc3933bd17ab5905e9d1c5d1443ee6be6a63e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ElementwiseBaseLayer.cpp SPDXID: SPDXRef-26f6cb1caaf6236db88a65d83feb144c FileChecksum: SHA1: a26f6e1dc58cf0d48b1e3bf7ca1cf1ce2dec6cb3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ElementwiseBaseLayer.hpp SPDXID: SPDXRef-1aff26a1c628a7335e71d7e1670f90ac FileChecksum: SHA1: 0a021bc0ad2ed7b463472f8c4a1f77448ee3eccc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ElementwiseUnaryLayer.cpp SPDXID: SPDXRef-0df0052bb2cad44144080026b253258e FileChecksum: SHA1: 553d88878010e4aefbc6708b09bcda1657f586aa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ElementwiseUnaryLayer.hpp SPDXID: SPDXRef-b3a1c29bdcf8550d38d46c7caf474f8b FileChecksum: SHA1: 9a33ddd749aba426fff2ad48664cfa06a9220ece LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FakeQuantizationLayer.cpp SPDXID: SPDXRef-643e0e1ffc2e8a3978669142b4c1c0db FileChecksum: SHA1: 4f8dbe8fb8c00b97466bb46e98d55d7c1a456c1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FakeQuantizationLayer.hpp SPDXID: SPDXRef-aafac79bc7d40b0f0017e8a4a8186788 FileChecksum: SHA1: 0d80473518293f537ccdd9947f6509aa59094b14 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FillLayer.cpp SPDXID: SPDXRef-ffb042a79dbc8281bbe43433a5aaac4a FileChecksum: SHA1: 1338e167f2fe5b1049794b1005d7790b642e7aa2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FillLayer.hpp SPDXID: SPDXRef-d4717fc7554f5f536e35bc412ba779ac FileChecksum: SHA1: 18465250d6cc5e66c943c96fa0f8d105ad40a669 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FloorLayer.cpp SPDXID: SPDXRef-1677eec4470f8a38ba6cea8bfaba2580 FileChecksum: SHA1: 958001409bf5539fc188494086911089cdce3734 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FloorLayer.hpp SPDXID: SPDXRef-5901de01741211f26858aaa800ad6234 FileChecksum: SHA1: 88b1dfcf1e31b13a3059f4910f6d28f6a9b74ce4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FullyConnectedLayer.cpp SPDXID: SPDXRef-0d0b45dfb438d347d92be515367dfbe0 FileChecksum: SHA1: 78756d9006f43771a308b5e8190b5232d45abea6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/FullyConnectedLayer.hpp SPDXID: SPDXRef-0fa42f5d62e27184e79c2d0773f8c13e FileChecksum: SHA1: 78f2b84e58fe0db9ce781c2a257c51604ff994cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/GatherLayer.cpp SPDXID: SPDXRef-21f5d85b410ddb634344828d831eedd0 FileChecksum: SHA1: 2d6f5aeb09da91baa2b46aa6a2619619f14ad89a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/GatherLayer.hpp SPDXID: SPDXRef-3022b7bbfe03d2f86d0325f1b970154b FileChecksum: SHA1: ae951fabb8c9eabcddc4d00b90627988445a94be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/GatherNdLayer.cpp SPDXID: SPDXRef-dd822eaa74957781dd56182d0ed06a6c FileChecksum: SHA1: ab7d5a11ddd24a7eeb0f6766985b8cd833c99297 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/GatherNdLayer.hpp SPDXID: SPDXRef-83e041096e65e0db574c0a6a79e2a5fa FileChecksum: SHA1: 5c7aaeaf91d0c848f4ce9acbb217ea53824a7d70 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/InputLayer.cpp SPDXID: SPDXRef-70df466c875d66b91255f57fe2fea1ba FileChecksum: SHA1: b726691b8f82e9570bb411ae4097848b5069a4df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/InputLayer.hpp SPDXID: SPDXRef-96ca34722e202a1a92ac80f9fd85e990 FileChecksum: SHA1: 5c0e2fc348d7fec775220d6ea4251db526a31ff1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/InstanceNormalizationLayer.cpp SPDXID: SPDXRef-45d36224db0009ac9ef1dc641fd0b406 FileChecksum: SHA1: dd9e3eb765aa5e17709f68aadf82f75a2dc92f1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/InstanceNormalizationLayer.hpp SPDXID: SPDXRef-14014b1f92ef68fe9b1f6f5446402bdb FileChecksum: SHA1: 75480a0757fe7231010c52f0d493635a19716017 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/L2NormalizationLayer.cpp SPDXID: SPDXRef-5113ff2aade07edff72b78537d641629 FileChecksum: SHA1: 137fba8e163885d68f927d04a2b365f48c471ff4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/L2NormalizationLayer.hpp SPDXID: SPDXRef-b0fc78a05c84a059abef171053795381 FileChecksum: SHA1: 5faa47bc927af5f7e572f33bb240fe7131829a16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LayerCloneBase.hpp SPDXID: SPDXRef-a1bcdd433f3122d3b2893070dc3166f2 FileChecksum: SHA1: 45d859ca5e050728d419e39afd3db181ecb737d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LayerWithParameters.hpp SPDXID: SPDXRef-82974e5756642587053820a074343045 FileChecksum: SHA1: 3eac421a7aefb876390f2b439b36d18b842d1e98 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/layers/LogSoftmaxLayer.cpp SPDXID: SPDXRef-4418cabcf35591c1be5b7041bc4843a4 FileChecksum: SHA1: 814714e400bde30f6c1bae1e813f03b84c3a11bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LogSoftmaxLayer.hpp SPDXID: SPDXRef-e17fde662f18c286e47ff29bcdc4035b FileChecksum: SHA1: 394b068427f783f0819ac272e27cbbbe17d02dde LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LogicalBinaryLayer.cpp SPDXID: SPDXRef-b8477159a2d10c1d723311f6a14851de FileChecksum: SHA1: 7136a161ed6cff12e78c1da0db95d351b0e2b12e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LogicalBinaryLayer.hpp SPDXID: SPDXRef-7adb9c97b80bf9c7d3744dfd86243cdf FileChecksum: SHA1: 468848907cea0cb5af0f68a8fb68e62db23b0bf7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LstmLayer.cpp SPDXID: SPDXRef-d977601b4b231eee09059d540e56e0b1 FileChecksum: SHA1: e8dcfd4da986c41cc3b2b6b8de7d5dca37f2ed26 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LstmLayer.hpp SPDXID: SPDXRef-e30c9e79c98a290580b7830d6a4dbd29 FileChecksum: SHA1: 7d66c7446237ec18723795a6288454cca5656426 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/LstmParameters.hpp SPDXID: SPDXRef-ef251b376c4fdeafe85f2f59f0e327b5 FileChecksum: SHA1: 34030fd4b34d42caa262b5bbd50db6247e6fac16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MapLayer.cpp SPDXID: SPDXRef-3d4271a25f28192cc75bbc410cc93a29 FileChecksum: SHA1: c493dfa07a2c3ac44c04b11ea523a83190f190a2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MapLayer.hpp SPDXID: SPDXRef-50223a6c2b4bc6cdae12af40375c85eb FileChecksum: SHA1: 16269103d04e2217b1fab3558c970b8f0e9fd61e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MaximumLayer.cpp SPDXID: SPDXRef-67a80b3dbb5a98abf9a2d0f5af5e8f5e FileChecksum: SHA1: 6852fb5776cc0c01869f1109804027f9a97e7c81 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MaximumLayer.hpp SPDXID: SPDXRef-a2c8ce8ddd767bbd0feb4ee3d4b6cdf8 FileChecksum: SHA1: 445e23d5672a389ba7108110a23330c836af2691 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MeanLayer.cpp SPDXID: SPDXRef-4a5559009e6c379aa8ad9073792e2674 FileChecksum: SHA1: a032f6fe48a970f2a3a7281c480182ffec61eb1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MeanLayer.hpp SPDXID: SPDXRef-26b5426bdc6faa3641c02c365ad0868b FileChecksum: SHA1: 494e9653b1a6bf14dd9bdd515df2b1108ed39c60 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MemCopyLayer.cpp SPDXID: SPDXRef-77db75c556e78dea668e0877b8de39f9 FileChecksum: SHA1: ac04213fba627042dd1975d102a14d8ca07f3bc6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MemCopyLayer.hpp SPDXID: SPDXRef-449d02a1336495e6d27b81d314415d95 FileChecksum: SHA1: 188897b556a0fcae07d64251b7e73715d1f86986 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MemImportLayer.cpp SPDXID: SPDXRef-7b1761a0e8e579fd506f7a3a054a900b FileChecksum: SHA1: fa544475a733610b458e3313450b8d1b8ddc631e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MemImportLayer.hpp SPDXID: SPDXRef-8fb341c07d81eca71d4c2ef948860846 FileChecksum: SHA1: 5238fa4c299439a7266204e5e38fabc984dc277f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MergeLayer.cpp SPDXID: SPDXRef-c387fc195142d9b23a2550d3be0b9ae8 FileChecksum: SHA1: f3ea571109cf991c3dd7dfa442fc6bd7fd1370c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MergeLayer.hpp SPDXID: SPDXRef-d37b6fa0840411c3fb37295624003cd7 FileChecksum: SHA1: b615cc2ff5f2c7ead193f41c5b4d9bb802e549cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MergerLayer.hpp SPDXID: SPDXRef-8d3705a850005f67342e7b23a20903c9 FileChecksum: SHA1: d0bbaf41bbdeb0398bf943f603369411e344a0c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MinimumLayer.cpp SPDXID: SPDXRef-b1a12e660154665d988d249407198b80 FileChecksum: SHA1: 4ce9d4d128de2de2489b26e17f8a55b49b6ac99b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MinimumLayer.hpp SPDXID: SPDXRef-a5789d776e359440e023ebdee6cfc2aa FileChecksum: SHA1: f78c7de19871e62feb1f496964fb3a03aed6eca3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MultiplicationLayer.cpp SPDXID: SPDXRef-a46031c3d412b08ead55bfcb78dcafbd FileChecksum: SHA1: 93890b40cbcdd3bd073fb0a11538a5952ccd6660 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/MultiplicationLayer.hpp SPDXID: SPDXRef-7e4ae9750c550944009c6a953ee38913 FileChecksum: SHA1: 9417329f6b866b5f12b23156955f7a3b1594f5ed LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/NormalizationLayer.cpp SPDXID: SPDXRef-617b0ba70f55d9e288142c77e935f3e4 FileChecksum: SHA1: ba5ee6199be96822c7f08aaac721568e302d0c95 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/NormalizationLayer.hpp SPDXID: SPDXRef-cb35a2c81e0600c7ebd529317b2d608b FileChecksum: SHA1: c3572fc70795042947b8b7e5e71facaa6078d615 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/OutputLayer.cpp SPDXID: SPDXRef-a030e81586139348bed8d6b1211e90f7 FileChecksum: SHA1: d7f92214be55e9ee16a62a20856798a485064a7d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/OutputLayer.hpp SPDXID: SPDXRef-fc68a320ddd8f4289b1c3f6faf2e5167 FileChecksum: SHA1: 8df66bb2b9f7dedbec1d740c7f0e390499117d02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PadLayer.cpp SPDXID: SPDXRef-920404bc1ab3c597a02fc69d6bc28589 FileChecksum: SHA1: f012578e7f9ce2bdd9b3f48981f4d43d292a2195 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PadLayer.hpp SPDXID: SPDXRef-4dcb94bafc65de4d880f53bf2ee41b53 FileChecksum: SHA1: f2a0868ff48dd6d44d5ddf7820d02c5afbd4a14b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PermuteLayer.cpp SPDXID: SPDXRef-70b2259bd66c3666de55b1c179b11c57 FileChecksum: SHA1: f1b4a9eace19962c69a252e642d2fef0e616a1d9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PermuteLayer.hpp SPDXID: SPDXRef-681ffbb7c9a792e9300cb0be0fa2c144 FileChecksum: SHA1: f0e5da93451ef2372d8ed94c6b3bb87ec57e23fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Pooling2dLayer.cpp SPDXID: SPDXRef-2617e9c119c11734058c8f4e0e5a1014 FileChecksum: SHA1: c6c98c53492425ec9d8680dee56bd65faa4809e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Pooling2dLayer.hpp SPDXID: SPDXRef-b1a1aaf270a1e004a4767d7edb72f70b FileChecksum: SHA1: 8a8cfedc6f8170e1482f85921d8ad368e3ad27be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Pooling3dLayer.cpp SPDXID: SPDXRef-3d2f82b24dbdb839030f3fb8e6b6f670 FileChecksum: SHA1: d3c2d38c5cf633b3f8216ce269e8f0f592b93bca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/Pooling3dLayer.hpp SPDXID: SPDXRef-f1b16c54510d70ae90160af8cba356bf FileChecksum: SHA1: 52be7a7e814dae01aa49c733babb2650bf29d2f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PreCompiledLayer.cpp SPDXID: SPDXRef-f536e48c9727ae37fd463bd0cf0d890f FileChecksum: SHA1: f510ea234567eaa306b21c07e0c737dc40d1aed3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PreCompiledLayer.hpp SPDXID: SPDXRef-e0bc475f36a0953926a5462e4486a8bc FileChecksum: SHA1: 58af43fc509913ec567150d2936d724dae3d7fa1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PreluLayer.cpp SPDXID: SPDXRef-c8a73f7e85ce916d0f79abc20bf041b1 FileChecksum: SHA1: 848926e5d176d52ee054e41ac4cac04bcf149f7f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/PreluLayer.hpp SPDXID: SPDXRef-59e708e9fa9dc3c58fdf4605bfc27b4c FileChecksum: SHA1: f2d93184364119f9f41ca9ac05397a74f2cff715 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QLstmLayer.cpp SPDXID: SPDXRef-f775ff5acd00c3535c8981d5042cd9ce FileChecksum: SHA1: 0bc9ff031d68db91d37a8ff31846271436f82042 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QLstmLayer.hpp SPDXID: SPDXRef-061b724c148e28f991c4e237adc7c2fe FileChecksum: SHA1: c36693cf208ba664f700fc42042cc80e61565222 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QuantizeLayer.cpp SPDXID: SPDXRef-0f79a4b9917e3f13360b4e042a976288 FileChecksum: SHA1: 1d741b2c92eb95c8bd95428672c0c2548478da5c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QuantizeLayer.hpp SPDXID: SPDXRef-27e01c37626591d7aef0a8e2522fe51c FileChecksum: SHA1: af8141579350b34ef560beb7efb520870307009b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QuantizedLstmLayer.cpp SPDXID: SPDXRef-bd9b6338e6607a1f90e27d0ea69f99a2 FileChecksum: SHA1: 5b5943bd633a058fb40cd47a4bf40487be6d63ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/QuantizedLstmLayer.hpp SPDXID: SPDXRef-d8570a310f9f0a5c082bbcebd00e245e FileChecksum: SHA1: 2216cc017c54891c70f0f9492f125bff5f7e3490 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/RankLayer.cpp SPDXID: SPDXRef-1251a6dca6649eee23f5828e4c6048a7 FileChecksum: SHA1: 5b9b2599cdf213f6813fa0886cbf830b824340ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/RankLayer.hpp SPDXID: SPDXRef-917774ebca102b2e42dacab1c86a380b FileChecksum: SHA1: c599419628d8eb044f5abbae3f8a96b7a4520885 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ReduceLayer.cpp SPDXID: SPDXRef-3cfffaf79a0e0ca7aea946d5f850e8bb FileChecksum: SHA1: b870c5e5581affbdaf69a0a42375f40318f5f7e8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ReduceLayer.hpp SPDXID: SPDXRef-d5ff86531b540f5736ee8f114a7c3f79 FileChecksum: SHA1: 2492047faa3f368ce90823a91eeedce5b03de036 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ReshapeLayer.cpp SPDXID: SPDXRef-30fbe21ae8c3bb9d4d61807227cfe561 FileChecksum: SHA1: 5871375ec8222866c867256c40a873ca435f85bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ReshapeLayer.hpp SPDXID: SPDXRef-47e0b2d2e9f33cfedd3560ef81d5fe04 FileChecksum: SHA1: 3862b26015f7dd8a6ccc3baae918431089bb274e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ResizeLayer.cpp SPDXID: SPDXRef-d2126e659e47cbce0c17b172549a063e FileChecksum: SHA1: e303d6202fc74210122cd24b18cdb31ba70ccda1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ResizeLayer.hpp SPDXID: SPDXRef-16d87a7e9c8e40cbeda02cc9cde5e3a7 FileChecksum: SHA1: 53a812be49b56321d558e0d77c280fc736a8e8b8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/RsqrtLayer.cpp SPDXID: SPDXRef-01672cdb760694eb9835d3deac6ce53a FileChecksum: SHA1: 418fd70a1aee1e35fa7a782d84b37c1b7cd12528 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/RsqrtLayer.hpp SPDXID: SPDXRef-037fae5b7dc3077c3901e21f97bfabad FileChecksum: SHA1: 9ec5ed22d8b6e6f89ea50902e9764c3bc9ff9dd9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ShapeLayer.cpp SPDXID: SPDXRef-9a50c80c85adbd110eee66f5778d427e FileChecksum: SHA1: 7bbd89995a05035a8d06e02b8921774ff02c303f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/ShapeLayer.hpp SPDXID: SPDXRef-73273140c3e31f7a27f6458f89d7e97a FileChecksum: SHA1: 00e17b2b17fde88d8040a4602dd77e6faf20bf06 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SliceLayer.cpp SPDXID: SPDXRef-1f4d489bf90b3c98516f40dd4713fb3d FileChecksum: SHA1: 30019c0dda86ecb8f7334a05daa265087527fa03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SliceLayer.hpp SPDXID: SPDXRef-52885c33731258dc6a6ef2aeaece1575 FileChecksum: SHA1: d46f93ea79e530f76d2de3e956b20cf0a79d2879 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SoftmaxLayer.cpp SPDXID: SPDXRef-09deba9ce72df7b2f9d15ea47c04c8eb FileChecksum: SHA1: d949dbeea6af506a6a521fe1b758d6359b8b44db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SoftmaxLayer.hpp SPDXID: SPDXRef-be091217d1ed9fbda558dbcfe6a36609 FileChecksum: SHA1: 24ee0770b8b2f9522ecb2be523d253cfd00ab95d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SpaceToBatchNdLayer.cpp SPDXID: SPDXRef-0ef1ec22957a356cac2712b5f0b5af6d FileChecksum: SHA1: ca5b86b2df1696638129e7a8db2546b5d9106941 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SpaceToBatchNdLayer.hpp SPDXID: SPDXRef-46bc4b6d841cc8a3a84adb10e8feec0d FileChecksum: SHA1: 23dad7522624d28fd256079a2453019e3ca4adb9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SpaceToDepthLayer.cpp SPDXID: SPDXRef-5e9e190f5cfaa2f8decf360157edea5b FileChecksum: SHA1: 3c3e45c6f990b4940f473ce7f2ca688d94a4bc99 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SpaceToDepthLayer.hpp SPDXID: SPDXRef-bc83a3af86350dd6d25d5a28700d9e2b FileChecksum: SHA1: 6a5a06fb61811211c0c01c47ec6e9b13377eaa31 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SplitterLayer.cpp SPDXID: SPDXRef-db784ccd99ca547c643904db00e4ddb3 FileChecksum: SHA1: 95b15ead3eee5524fb81715c745d3d5b54c0cd01 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SplitterLayer.hpp SPDXID: SPDXRef-bc861b1faa042975bb4237ba76e16594 FileChecksum: SHA1: 602cdeaabc343e7eb3dfd9963e12fd3be0eff52c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StackLayer.cpp SPDXID: SPDXRef-06bfbaf28639ca411124195177c3f84a FileChecksum: SHA1: c2fd09e319e8ac9a40f5de0f06ad8353f6d1ae24 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StackLayer.hpp SPDXID: SPDXRef-72d26f9775582d6ad44d965cb34459c4 FileChecksum: SHA1: 4a1a946cbcd2686223ccd96926f1835b0edaaa6f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StandInLayer.cpp SPDXID: SPDXRef-bdd6c59e856ff1beae64036dfae31462 FileChecksum: SHA1: 3429b709769c01ebf2b6c9359e7f360657ecb37a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StandInLayer.hpp SPDXID: SPDXRef-8631a6c9fff531d51a53fac9aa8dc589 FileChecksum: SHA1: 5fd038c2599201ee29d3d9abec0ef3f76d2449e1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StridedSliceLayer.cpp SPDXID: SPDXRef-c8093a05f88a7291b153443a2e86bf2e FileChecksum: SHA1: dea20edc60ba4516d5d262f61309da5d9193562f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/StridedSliceLayer.hpp SPDXID: SPDXRef-477511e3aaf3967b99aeff4bde284d46 FileChecksum: SHA1: a8d007c586791ea8aca4924224e4b4e245b9659c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SubtractionLayer.cpp SPDXID: SPDXRef-2d24f213ab624b3beb2c313a709d009a FileChecksum: SHA1: 9793645624941b39699a3d97c462fb48a54a184e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SubtractionLayer.hpp SPDXID: SPDXRef-125b06a144e147ab30b05a419b544d75 FileChecksum: SHA1: d3d75597b062441f363839ddd27cc4a8662c5518 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SwitchLayer.cpp SPDXID: SPDXRef-b64944074a2a36e3aa857ae6431f70d0 FileChecksum: SHA1: 1eee4afc8ec11ac93d590b92c005414d20e50c3f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/SwitchLayer.hpp SPDXID: SPDXRef-b94c7591a0fd3bbd83acf4b7a8c667bf FileChecksum: SHA1: 98c463702ead240c2a953a635f20adcaeb67f690 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/TransposeConvolution2dLayer.cpp SPDXID: SPDXRef-b7b98061ddfa2895af6ab9003d6d7a0a FileChecksum: SHA1: 21a0efe242c0f003e636c54495cc312e5a1078e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/TransposeConvolution2dLayer.hpp SPDXID: SPDXRef-f6bdad3d6efba7209ca0ea25f3b0a4ac FileChecksum: SHA1: 1da3ae1e6b45f2ad8a8b2eb20cfcd2a0eaef9201 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/TransposeLayer.cpp SPDXID: SPDXRef-80104f8c25f438eb2531733814760099 FileChecksum: SHA1: 6c8a3ea622ed4505ad4fe65eb2d1f536b0fd02f1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/TransposeLayer.hpp SPDXID: SPDXRef-9517aed545e9956647ffeee6d5e8355e FileChecksum: SHA1: df884938267c4888cf219dbeeeb921fc1408c61a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/UnidirectionalSequenceLstmLayer.cpp SPDXID: SPDXRef-4d29da73febbb647fcf0e97355cf3c87 FileChecksum: SHA1: 2143a7d1b1535bc02519771bd4e82e1362231265 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/UnidirectionalSequenceLstmLayer.hpp SPDXID: SPDXRef-48b7edd20658bdeec7cffb269246a91d FileChecksum: SHA1: cee6900ff4e84af7d2752ac1dab9eea29d568a02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/UnmapLayer.cpp SPDXID: SPDXRef-7a7a85fc2053d079c8110828abab0b14 FileChecksum: SHA1: ed02d3f36744038cced436bbb90184db5d9fc480 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/layers/UnmapLayer.hpp SPDXID: SPDXRef-8cf94ff2c80a5fead96e06f20b82a5fa FileChecksum: SHA1: 2f2dc677571f45c696d643be167c66ec226e818d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/AddBroadcastReshapeLayer.hpp SPDXID: SPDXRef-e3784dbe05340956dd9addb5d0c950ae FileChecksum: SHA1: ef7e5ea61f59c93af1611167f0eaaf084586e52e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/AddDebug.hpp SPDXID: SPDXRef-bbb92e6b4d1505463fb5c4eb9d73364f FileChecksum: SHA1: e4492c0519e2671784e903b60614ac99e59e82df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/All.hpp SPDXID: SPDXRef-935dbd7a0040e8d27eed472aa83a0061 FileChecksum: SHA1: d27534be57572e213ed59430ed6cc051bcb63828 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/ConvertConstDequantisationLayersToConstLayers.hpp SPDXID: SPDXRef-b1925f0cd2caa98608b47075dc7aeffb FileChecksum: SHA1: a8b6b0d74d71eee24d0bd2e333515e7070335191 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/ConvertConstPermuteLayersToConstLayers.hpp SPDXID: SPDXRef-d62c7c9a0a7d665b78ff5f9f60ced49c FileChecksum: SHA1: 717125e50e79c3b1958e5c7e04277fbdfde206c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/ConvertConstants.hpp SPDXID: SPDXRef-de7dac068fd27ae100672a3130bbb290 FileChecksum: SHA1: 200080ae4859c18c0452f8a88166cf8d77950c5b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/ConvertFp32NetworkToBf16.hpp SPDXID: SPDXRef-cc68e8554cedad8f49df8700cfa21352 FileChecksum: SHA1: 9939deafb4477fbf7dee9849409c999ea4e03c05 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/ConvertFp32NetworkToFp16.hpp SPDXID: SPDXRef-9d4438aee03b00dd4b7f64da21691b8a FileChecksum: SHA1: 7966dc8de375eb7edd63ccf96c5051724ced937d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/FoldPadIntoLayer2d.hpp SPDXID: SPDXRef-4fcea599229143925d1f7979ef09a08d FileChecksum: SHA1: bd936eb738909be220e8d05c86a5023da1c1d87e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/FuseBatchNorm.hpp SPDXID: SPDXRef-b15734202a9f66941f5252d8f51c60ef FileChecksum: SHA1: 3ca7cb47401619d9fb2d5dd5a47c185d48705684 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/FuseConvertFp32ToBf16IntoConstLayers.hpp SPDXID: SPDXRef-ea17516d26f36fa6ce11619788b73d59 FileChecksum: SHA1: 45dc67a9989fb7510ce77f9f2da640fd2fac17e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/MovePermuteUp.hpp SPDXID: SPDXRef-5f85e5ab848da3a8a8356af5b60daafc FileChecksum: SHA1: 8e6d450e52ad4c29bc4dd535201a6bb08252c666 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/MoveTransposeUp.hpp SPDXID: SPDXRef-4c6f35347e7f94c98641fc8d93625850 FileChecksum: SHA1: 5b3dbacd571d02c475f8ff0ede39c1329af7e8e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/Optimization.hpp SPDXID: SPDXRef-848dec76597eca02ee4d32145fe7eea2 FileChecksum: SHA1: deb4028c04c6574e61c36fb5241a41f0bfd1910d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/OptimizeConsecutiveReshapes.hpp SPDXID: SPDXRef-7d9f72a8345d4c8360c293392249b4d2 FileChecksum: SHA1: b8068ee9d388bfb02771e12a0700c70fb4455339 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/OptimizeInverseConversions.hpp SPDXID: SPDXRef-fde48fe00484d34a93803cfa680390be FileChecksum: SHA1: 78763355df89c34d67a9489ef08be708a6360b7f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/OptimizeInversePermutes.hpp SPDXID: SPDXRef-d057582fe890c99807bbabc9302ec87a FileChecksum: SHA1: ffdf7c82f7bba402ef41e0d3cc88f63b4370f9ca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/PermuteAndBatchToSpaceAsDepthToSpace.hpp SPDXID: SPDXRef-8a155d049f91532473f7ccb34eafce7b FileChecksum: SHA1: 1868bbe1db5dc2d9f9b42c9d524bddf82c198212 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/PermuteAsReshape.hpp SPDXID: SPDXRef-07f0c90558033e9976f5922c5b74b9d5 FileChecksum: SHA1: c11ea3b0deb270de00f9ebb2e7540383b716895b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/PermuteDepthwiseConv2dWeights.hpp SPDXID: SPDXRef-aec6e3b80470c118cb1e69b2a32e37c7 FileChecksum: SHA1: 919d66426296f9fc06b2bdea9ebc8ac568c40eaa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/RedirectMembersToConstantInputs.hpp SPDXID: SPDXRef-8be3d24e6a49967d997f5209581e9d83 FileChecksum: SHA1: d160fc42cde66a44c728d410ed43d985aa42ae97 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/optimizations/SquashEqualSiblings.hpp SPDXID: SPDXRef-3ebfa2b47d04a802d9173ac58ef735d2 FileChecksum: SHA1: cfabcfd34c7c6acf7aae1406b7260ef25cd91b55 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/optimizations/TransposeAsReshape.hpp SPDXID: SPDXRef-15b9d7738a66146289d17120b27a1d00 FileChecksum: SHA1: 288c0c4c9fc0c08c9265dbbb4865fd6c45214175 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/CloneTests.cpp SPDXID: SPDXRef-b6e41211144f8e66e6d47f381be0a30d FileChecksum: SHA1: 65628e6dccb636d1153955cdc587d3ad8023718f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/ConstTensorLayerVisitor.cpp SPDXID: SPDXRef-1fe1cb445a56434201058d9bd88a6d3d FileChecksum: SHA1: f75d26da659aef42c26a8bec752ec460bf019310 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/ConstTensorLayerVisitor.hpp SPDXID: SPDXRef-66b0f5fb5cfcd45c6dc35f5c8e7b6983 FileChecksum: SHA1: 2fcb0b21e44c9644f02ee6225524c46d18efa6a9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/CreateWorkload.hpp SPDXID: SPDXRef-5ce31920388f854521bbae675e880741 FileChecksum: SHA1: 0ac90b9a9e2dd6dc1c24f409fea237ffe886691b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/DebugCallbackTest.cpp SPDXID: SPDXRef-8aa8882ad8585dfff87fae8e782694b4 FileChecksum: SHA1: dfeed057e4e4258bac6aeff7edf2baf4320a6e76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/EndToEndTest.cpp SPDXID: SPDXRef-cff93282c2066054f58048299a3c2ddc FileChecksum: SHA1: 19305603e8e23dbc0176ace84b857b249d0eaf9f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/ExecutionFrameTest.cpp SPDXID: SPDXRef-37aff185fc35f01a4763e44729cefecf FileChecksum: SHA1: 1e039cc8e8e8bbcfc49337aafd68184a6a605017 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/FloatingPointConverterTest.cpp SPDXID: SPDXRef-a719fc86fd2c1fda685b601282d78157 FileChecksum: SHA1: 170b497eb4ae8412e86fc717221218a540c42d9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/FlowControl.cpp SPDXID: SPDXRef-3c7c001fceac637ae09bb97c7ded0737 FileChecksum: SHA1: 8cc42a8bbbab44aaf69f88df628d790b4b65b128 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/GraphTests.cpp SPDXID: SPDXRef-8668fab43ed975d9faf966b8b48a2969 FileChecksum: SHA1: 6ffb8e3f3a6c89a2ac859812f3c4ebb1642d00b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/GraphUtils.hpp SPDXID: SPDXRef-bdef01da1a8285a345dd9c07ebc3edbc FileChecksum: SHA1: 2320e6ddce3aea6f31d5cad5340b96fc0fb7fb18 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/InferOutputTests.cpp SPDXID: SPDXRef-52bcc3ffbcb697b0ca8f461d78f29f33 FileChecksum: SHA1: f6a3a82621b9363cebac25e835b9c995f3304156 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/InferOutputTests.hpp SPDXID: SPDXRef-a6652488e601da43ac5e44a9ab247d03 FileChecksum: SHA1: e5440dcba76a6be9a53d108a1c134e53fd9bf6b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/InstrumentTests.cpp SPDXID: SPDXRef-512f10dfb5d0a84176de79e9f1f70f3e FileChecksum: SHA1: a35eb341cc8937658ffe68118c3bf46044b4b36a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/ModelAccuracyCheckerTest.cpp SPDXID: SPDXRef-3bbb12ee72fa485797f63732accc59f3 FileChecksum: SHA1: ddf41537da443de39857e671eb39354c81c13028 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/NetworkTests.cpp SPDXID: SPDXRef-c867d5d1355fc3139161b4c38cf3bb5a FileChecksum: SHA1: 1eb405d52cf83c1d13ce4a9ceab609f480e5c5b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/ObservableTest.cpp SPDXID: SPDXRef-d8dd08ab228c47072990d6d0d3f39dd0 FileChecksum: SHA1: cd31b4f724cef206495c2654b74f8ccc1c541f5c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/OptimizerTests.cpp SPDXID: SPDXRef-aef8561d372929bdefbaadec527bcb2f FileChecksum: SHA1: 2eff2a0246e08b9e8cb3d53c0913871e4630733c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/OptionalTest.cpp SPDXID: SPDXRef-1fbb9b0f1918fe4560a406ceb948e78d FileChecksum: SHA1: a0be4b3f5f871f28ad92f716f2d9d2b19d111854 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/PredicateResult.hpp SPDXID: SPDXRef-d4e7701975b80c8e0903569be10371f3 FileChecksum: SHA1: a5c812310210fc045c6e3865f6d90839abe223cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/ProfilerTests.cpp SPDXID: SPDXRef-998873148ff7def5b657e2a1583dba80 FileChecksum: SHA1: 4715de272d07fb29d20f5702193509219132ba38 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/ProfilingEventTest.cpp SPDXID: SPDXRef-4c0e684a7ad6cb79ced04b31ffb55720 FileChecksum: SHA1: 0ff85e7bc2e679e2cfe857a63329ae8987606fb9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/RuntimeTests.cpp SPDXID: SPDXRef-4ddf598e2ba657e34f71041fb92419f7 FileChecksum: SHA1: bdb967ca3396c66fc362baa610209b67455abe54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/RuntimeTests.hpp SPDXID: SPDXRef-fca6fc8516a15b2fd55d830f79043437 FileChecksum: SHA1: 82c1c19024f65f6f3e6d435890bb6d941b82eefe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/ShapeInferenceTests.cpp SPDXID: SPDXRef-ea8a36fcba5a38f716041af0b1c94a17 FileChecksum: SHA1: 98c461b953f03a67625ad15043ecff178bb97e5f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/SubgraphViewTests.cpp SPDXID: SPDXRef-61766ad4e8b8c421378588447332a135 FileChecksum: SHA1: c0486dfd5bf09b8839938a65eed9477a839825dc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TensorHandleStrategyTest.cpp SPDXID: SPDXRef-15e3408424ac4ea93bd184221032be12 FileChecksum: SHA1: 3e72df5b0ffc89701b0b335d19a78b90b7c87e3a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TensorHelpers.hpp SPDXID: SPDXRef-a7883afa7005f1185af7ddebe94fa700 FileChecksum: SHA1: 2eca764b711479f02442b011f14a09a59dd115f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/TensorTest.cpp SPDXID: SPDXRef-bd3c32772bc017f2e840632a01027c6c FileChecksum: SHA1: 622a81a5115fc1953015e7a5a56428b8a70b4267 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TestInputOutputLayerVisitor.cpp SPDXID: SPDXRef-e4adf301dbe005a9ebeabac67ab7e81c FileChecksum: SHA1: 33ed423b79e91fe078f3e901253dcedd94aa4761 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TestInputOutputLayerVisitor.hpp SPDXID: SPDXRef-99e549fe4a934446b77d06df097cf03c FileChecksum: SHA1: fc58e238d610f968e4eba9673a825fa8462b751f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TestLayerVisitor.cpp SPDXID: SPDXRef-d3583421e19614c31a86a242ad432093 FileChecksum: SHA1: ca3814e32878a519488161f76bc69b1532342aba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TestLayerVisitor.hpp SPDXID: SPDXRef-5e7f40b824ee00f035c4d2be624d35a9 FileChecksum: SHA1: 93386ee5ef667ad06a3a633b434cbcf4bd4d9b8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/TestNameAndDescriptorLayerVisitor.cpp SPDXID: SPDXRef-f91fc6e4ba548a288b3f9de5d5157135 FileChecksum: SHA1: 59a7ef9807ca54c4256b66038b139d07c40104de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/TestNameAndDescriptorLayerVisitor.hpp SPDXID: SPDXRef-c6c735ed714670e31a35f6593dff42c4 FileChecksum: SHA1: 07dc2e30a2642984cb428f83858cc4a03bc57da9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/TestNameOnlyLayerVisitor.cpp SPDXID: SPDXRef-642361ddfa19dc416b5c025eaa55517d FileChecksum: SHA1: f7a9462eebc7d3d983a9fe581d30b65a107b4642 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/TestNameOnlyLayerVisitor.hpp SPDXID: SPDXRef-303e48eef28afcda90c8cc988c06b8d1 FileChecksum: SHA1: 5d534ffaaa5f6a2b84965a7bfd7463c78bf383e3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/TestUtils.hpp SPDXID: SPDXRef-929969246935494684f8eb7cdaf0a233 FileChecksum: SHA1: dd7ae13353ab68ff564c99dcbfcd3ccc5d17ac3b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/UnitTests.hpp SPDXID: SPDXRef-1a5ae06d16a38800a28e745ceda60472 FileChecksum: SHA1: e243a9b424eee91e9ece03f6deaafb9628e27229 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/UtilityTests.cpp SPDXID: SPDXRef-b2c24e670fad8588fe9af380f41c9903 FileChecksum: SHA1: 5a32c3c959cc82277bf360417372dbf96cce42d5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/UtilsTests.cpp SPDXID: SPDXRef-5b39574a9e92e5b3b3bf2bff8bd3065d FileChecksum: SHA1: fcef442d73e29aa43c8cf2f3492286908d04ec7e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/AddBroadcastReshapeLayerTests.cpp SPDXID: SPDXRef-6488e068c43dab1882d069d7b85f462f FileChecksum: SHA1: 43fc37a84742a6ec0dde04448146dc0cd3ae83e1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/ConvertConstDequantisationLayersToConstLayersTest.cpp SPDXID: SPDXRef-9e1d27c0cada3511a456838d6e12ad4b FileChecksum: SHA1: cced833d632ebc748e89eb4d48db5abfe26cba30 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/ConvertConstPermuteLayersToConstLayersTest.cpp SPDXID: SPDXRef-871e70782a072c6ce986088173fb3366 FileChecksum: SHA1: b299b7a2d96a92d0ec1a7fa26f186efe2a1f07cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/ConvertConstantsBFloatTests.cpp SPDXID: SPDXRef-0b917241e92ce6543df839741a5b0b22 FileChecksum: SHA1: a975518266fc5650c0921a87e6f4615f1694a102 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/ConvertConstantsFloatToHalfTests.cpp SPDXID: SPDXRef-347df8ef9c0195ace467408abf2f17af FileChecksum: SHA1: 73b5b4ed3eda5595073a9da523bdc6e7be954a75 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/ConvertConstantsHalfToFloatTests.cpp SPDXID: SPDXRef-7a38bc2ff3ae29e296fce24a62553588 FileChecksum: SHA1: f42532bc3f00f6f6ce9c5e7ed8296a42368654be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/FoldPadIntoQuantizedAveragePooling2DTests.cpp SPDXID: SPDXRef-e84f49b041e7265cbc823e5c54de2c5b FileChecksum: SHA1: a7e4066329ee891eab08a9e0a5bd50ee6b4d3990 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/FoldPadTests.cpp SPDXID: SPDXRef-34e1a1730156b4a4f288d48cb64b0279 FileChecksum: SHA1: 38e6b002d0dd7403d8e0b917dfee28f4442bb83e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/Fp32NetworkToBf16ConverterTests.cpp SPDXID: SPDXRef-2af59cffa64038bf5367f5d0a9dfeadf FileChecksum: SHA1: d6de6097f674f5225119ff226131e9ef32f807ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/Fp32NetworkToFp16ConverterTests.cpp SPDXID: SPDXRef-e780cc7c1382c4733bec16ccf8fac94e FileChecksum: SHA1: f1aba0890300fd0bcfa821463adcb0b0bce29de4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/FuseActivationTests.cpp SPDXID: SPDXRef-e2f3e695bcbfa89ae3624551bf33174a FileChecksum: SHA1: 5a76f9aae52ced0e8770bd7e19a9910a0182909f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/FuseBatchNormTests.cpp SPDXID: SPDXRef-5c03cab27aadc0277fbc94a5c7e0f54a FileChecksum: SHA1: 4dd3e51e8c1b61681b4ec3fb54827d4eb83d730f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/FuseConvertF32BF16IntoConstLayerTests.cpp SPDXID: SPDXRef-ea238a1a008025970bd6e8f2ac3d4757 FileChecksum: SHA1: bd9150f923d31994c584753b56eaa4069796ffd2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/InsertDebugLayerTests.cpp SPDXID: SPDXRef-487ee13f6a3c7498aa7462d69d0107a2 FileChecksum: SHA1: 1b65821854427b089603052026e5f6ab84c84260 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/MovePermuteUpTests.cpp SPDXID: SPDXRef-452f54bc8ef5c7f5e3d51cbf2eddb234 FileChecksum: SHA1: 98177487b15e1eaf5615cb50fde8c90322113712 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/MoveTransposeUpTests.cpp SPDXID: SPDXRef-3579e803c32a8e6e43ff6888b42f1352 FileChecksum: SHA1: 91aadf97de5141ac513e9e8eafa77c81cc7def79 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/OptimizeConsecutiveReshapesTests.cpp SPDXID: SPDXRef-49cdc95e575d548726d1eb83de2e503c FileChecksum: SHA1: 26cba7a66c78b2c7ababd8cfe7ed374a9cd94e9f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/OptimizeInverseConversionsTests.cpp SPDXID: SPDXRef-dbec4150192060559965cfc695470a45 FileChecksum: SHA1: c3178d51668452844edb9c9049bd6246177d1a14 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/OptimizeInversePermutesTests.cpp SPDXID: SPDXRef-9979e84e2b11ca86c11aab4dbcfedf58 FileChecksum: SHA1: bb58121e72fbc4b5d68eb1ba84d0ec1713a98950 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/PermuteAndBatchToSpaceAsDepthToSpaceTests.cpp SPDXID: SPDXRef-07f59ff0438ada2e5ceef856ac509d41 FileChecksum: SHA1: 4a5e293a6e6d9b25eacf4a9f409e824d29b9c366 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/PermuteAsReshapeTests.cpp SPDXID: SPDXRef-eaa6d0b4aa04c6df26fd6735c395c648 FileChecksum: SHA1: a792624c7e68655ff898b7f4d729d68f487a7180 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/PermuteDepthwiseConv2dWeightsTests.cpp SPDXID: SPDXRef-dabcf434cc2b35648a1591a66e7fd4e8 FileChecksum: SHA1: c31221445eb6e90a4aa81c4b76586105a401ff6f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/RedirectMembersToConstantInputsTests.cpp SPDXID: SPDXRef-49ef268907a091a4cb7c8f9fd1aa26d5 FileChecksum: SHA1: 77c2b57b130a0764669feeef1995f62565c66e5b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/ReduceMultipleAxesTests.cpp SPDXID: SPDXRef-0f03547b3b147ae27d2408b07b396e59 FileChecksum: SHA1: ed2de1dbbede596bd72e0e0414fc5ab269375dbe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnn/test/optimizations/SquashEqualSiblingsTests.cpp SPDXID: SPDXRef-9b0ca5cf873a78914bcb619f370cc1d6 FileChecksum: SHA1: b6693dba7aca5934e20d9d4b591d6b14a557a8e3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnn/test/optimizations/TransposeAsReshapeTests.cpp SPDXID: SPDXRef-0b53c85c64b5c50413f69c82ea70dba0 FileChecksum: SHA1: 2d3331923d44db25832b95554229b26159080629 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnConverter/ArmnnConverter.cpp SPDXID: SPDXRef-9a686a8b30ee89f84595be3f7a44a4fa FileChecksum: SHA1: 28cb838d2d8ccf31d47365736a2c0cb9ffc85295 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnConverter/README.md SPDXID: SPDXRef-b509fa4708962896410bcdb2c9a0e59b FileChecksum: SHA1: 402cf8cb18d5b96124fa2e13c601673482c5c6dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/CMakeLists.txt SPDXID: SPDXRef-3a2fcca5af3ca457fd708c115ac7f7fe FileChecksum: SHA1: a79639d57e06d90db0f6caa13a65c20bc6ebbe2a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/Deserializer.cpp SPDXID: SPDXRef-cf1082aef16eac920c2e147a7ee537d2 FileChecksum: SHA1: dd8d15072b2fd8437520b82e254c78c0a145e2b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/Deserializer.hpp SPDXID: SPDXRef-9c34997c0e03e062ff0b7f6a1b9789d9 FileChecksum: SHA1: cadc94883a24c3997f513547767dfbe1952594c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/README.md SPDXID: SPDXRef-cb964294b5246fa56735db74dec23817 FileChecksum: SHA1: 00e2261fc7ae805e00adbba5c3a6eab6fa5ca905 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeAbs.cpp SPDXID: SPDXRef-cca1fa5c2deb752562af55d315e7cee6 FileChecksum: SHA1: 952969b9dfb6c99527d747b9f0f25540273f2548 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeActivation.cpp SPDXID: SPDXRef-72f9646710b13881a017d0b9b4735e6e FileChecksum: SHA1: 36f0a463dbc854d323c99c504f8b689ad65d99d5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeAdd.cpp SPDXID: SPDXRef-b5f0a14347b28617173abf0e3972e6ba FileChecksum: SHA1: 3010a4bcac0f7a1a9031b299da469ece4120fcfe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeArgMinMax.cpp SPDXID: SPDXRef-3d9aee4f18db7802ff088a521eee8d52 FileChecksum: SHA1: 210f4e110ce80d6d32ac78c04f7fbc0f220bedc2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeBatchNormalization.cpp SPDXID: SPDXRef-620414e52487dc3ab534633ed4960dd6 FileChecksum: SHA1: 5f9eda06d172e9239322bb6f942af991e4fecbb2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeBatchToSpaceNd.cpp SPDXID: SPDXRef-5d49232efd3b18c11a9aae996afb44ff FileChecksum: SHA1: 2c3ab80b0c7aad5321a5546b65e9a414ba408451 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeCast.cpp SPDXID: SPDXRef-59ea2fd2056f413c84219dd0e035f422 FileChecksum: SHA1: 19f8d6118a00ba3f8eff14fb2ec9d51bb203496b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeChannelShuffle.cpp SPDXID: SPDXRef-997451434d0c50e5baa18e8336f417ef FileChecksum: SHA1: 8dd873feae5156f5c59f9aaac36203d56266dc02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeComparison.cpp SPDXID: SPDXRef-69195a002c945fa748d54026a04f9303 FileChecksum: SHA1: 54a90430088cd781e2d2fc5d1c984b9c7c79d388 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeConstant.cpp SPDXID: SPDXRef-758ad8748326a34c170a5b7fc080c54b FileChecksum: SHA1: 98d6b8486acccdb9e9c488744a5e0af9e1a306c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeConvolution2d.cpp SPDXID: SPDXRef-33d76c4ba01b535f7c71468f3a1cb39d FileChecksum: SHA1: 87153e2e7470d7feccebb9774338b75997afa563 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeConvolution3d.cpp SPDXID: SPDXRef-333b0050c7589d8f764c464c64280c64 FileChecksum: SHA1: de5876021635a76c48ab8848342209e9a681bd72 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeDepthToSpace.cpp SPDXID: SPDXRef-d28726e11d15ed666800cbb543475824 FileChecksum: SHA1: e700a5068784a16205e52c01f183da47195516de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeDepthwiseConv2d.cpp SPDXID: SPDXRef-9777225a5ae7d559afba7ec98a0bc8b6 FileChecksum: SHA1: 394a5f5559bb981136009e4badb2c12f0a82cdfa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeDivision.cpp SPDXID: SPDXRef-ce78e8edfbae5e019e1e6a2f929f78ad FileChecksum: SHA1: 53dd57e81bb189b98fbaf02ca4cc15e5c0b96039 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeElementwiseUnary.cpp SPDXID: SPDXRef-d1744287818571168b8e1ceb06f63efa FileChecksum: SHA1: ba04b93ab679fbe312d7ddf908f87028c7e7c254 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeFill.cpp SPDXID: SPDXRef-e175768053fc6be460e86524daaacdde FileChecksum: SHA1: c849134c402242c307b233e82ef3aac28800eee0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeFloor.cpp SPDXID: SPDXRef-4c60a44e333d5b4eabce18de09d87bec FileChecksum: SHA1: 438065bcea008f0af05e0ba3bc2a46e62bcae4b2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeFullyConnected.cpp SPDXID: SPDXRef-32362214355b5ed7e4184a9672b62328 FileChecksum: SHA1: 74888ff83f8353c4258bd10dc859dd736b568181 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeGather.cpp SPDXID: SPDXRef-d2ab9de22be2f238c68debb4ea4df848 FileChecksum: SHA1: 97971d8e88d9fb5963af7498349d20c5a8f3f506 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeGatherNd.cpp SPDXID: SPDXRef-8a62365da57765c4a735a441b7678ea4 FileChecksum: SHA1: 11a4db187b7534da5876ced0db7d92c7e6a5e3f0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeInstanceNormalization.cpp SPDXID: SPDXRef-831214c4395f2748b39204986406c2df FileChecksum: SHA1: c6b586fd2fb9077830b64ace41a4449300f131e1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeL2Normalization.cpp SPDXID: SPDXRef-667005602050e3aa16c22530fae17327 FileChecksum: SHA1: 267991f5896d0a810f6c7fba89e1d3bb00dce328 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeLogSoftmax.cpp SPDXID: SPDXRef-2e4b5d52ed63c3b5b9d5fa254f2aae4b FileChecksum: SHA1: caea01a4f9f13600feaa6e9723c9120750887cdb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeMean.cpp SPDXID: SPDXRef-69df37a5239e2441443a32f6537612bd FileChecksum: SHA1: 4067eeb2fda4dfe26f9a5621a6637e681d16368e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeMultiplication.cpp SPDXID: SPDXRef-056671e4b9c697e5431295a4d0155219 FileChecksum: SHA1: 1b8a4d0aeea16da6891d70679e81eadc2923d886 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeNormalization.cpp SPDXID: SPDXRef-4dc78efb6efb0b1bac382cc48c9e014a FileChecksum: SHA1: be2e541f35cb625919dcdbb3333e0886701d6c76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializePad.cpp SPDXID: SPDXRef-90e6906fd6c4a2ddeb714bed2b8ff8c0 FileChecksum: SHA1: 483806b51f0da6e673a3f5d49c5621d1a1f4bb7e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializePermute.cpp SPDXID: SPDXRef-d50d55ddc5553c3ce5afd2fe3d13b40d FileChecksum: SHA1: babbf98d9a786c15070111519aaff0a763920400 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializePooling2d.cpp SPDXID: SPDXRef-c31a514fc8c7d3a19552203cc892fc4c FileChecksum: SHA1: ea96dbc3c3405c9a044752a95ec32b370d0cb772 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializePooling3d.cpp SPDXID: SPDXRef-440bf8c766cf1ade68f4aae5b70dd66f FileChecksum: SHA1: f3eea01563e470b5704cbb6da071d8370aede0c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeRank.cpp SPDXID: SPDXRef-97f6090a1b404e431701397d7504f8d7 FileChecksum: SHA1: e5f074a71748be1dd35b5a6a850c6bb49778d202 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeReduceSum.cpp SPDXID: SPDXRef-736867bca7ba76a8b4932df91ef34774 FileChecksum: SHA1: f96b2c23f4dd5de28c4ea140667340119f87c41d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeReshape.cpp SPDXID: SPDXRef-af90e2bebafdadaa0dd9afd063052966 FileChecksum: SHA1: 375588889e71a813a3fde3d150fe5674b62e3840 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeResizeBilinear.cpp SPDXID: SPDXRef-523ea0375a6440c1f066958bd5ff7688 FileChecksum: SHA1: bb5adadd48cbe49c38b5da8239e7df66c2b356ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeRsqrt.cpp SPDXID: SPDXRef-74fe4506e0d5e9ed1a402e2e5392a603 FileChecksum: SHA1: 4b31797bbd698e75d0d01619ab9dacca31441cf5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeShape.cpp SPDXID: SPDXRef-82e4edbb03471780f2966ea2c76a59b4 FileChecksum: SHA1: 57ae5d0ffea8db43db452f688fa8d325ae1e7893 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeSlice.cpp SPDXID: SPDXRef-d71a1fd4ed9e26a98dd88902e0fd50c4 FileChecksum: SHA1: fa4b7af1b10850a3e7f35a932ca18fd0efa48514 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeSpaceToBatchNd.cpp SPDXID: SPDXRef-6631380eeaff7a1c048617648780031d FileChecksum: SHA1: 5e526dbc16a1947d79c961a6218a83ef578f2160 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeStridedSlice.cpp SPDXID: SPDXRef-e38c2d8d27e5ce6d632dc7fe0d405854 FileChecksum: SHA1: d6ecdfe4ff403181c18ef2cbef781ba80350a17b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeSubtraction.cpp SPDXID: SPDXRef-8ae8499083cb07f7b48601277b1f3f03 FileChecksum: SHA1: ddbcb0132dc46cd1bf2b955d369d2c2af4774cad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/DeserializeTranspose.cpp SPDXID: SPDXRef-03ac7dc60a33c20f0b3256e950a92140 FileChecksum: SHA1: cad8bf01fc3e3dda20b713980d371d2899a2332e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/ParserFlatbuffersSerializeFixture.hpp SPDXID: SPDXRef-bb1498e3e2fc00606a2ab762eb73107c FileChecksum: SHA1: 99975f1c0ec8b181cfbd8fad4a08526e75496368 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/SchemaSerialize.hpp SPDXID: SPDXRef-e3969cd41f5c4104c78ed01e3b2c83b0 FileChecksum: SHA1: a1235f73bff294f10fca6e7cbd8200eea2018ef4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnDeserializer/test/SchemaSerialize.s SPDXID: SPDXRef-6425a8d1548b4fc62a8922991a19d00b FileChecksum: SHA1: 554cd341f031f3f49fe46812ae5f7690ede7e128 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/OnnxParser.cpp SPDXID: SPDXRef-95fd52078f8e7eb0ea6c5910762b24cf FileChecksum: SHA1: 863c734f49af26c2d7a10dfbd3f6bcf34b0bd426 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/OnnxParser.hpp SPDXID: SPDXRef-a94161169f4b7a2ae13b6e4ad785f16e FileChecksum: SHA1: b9d112582c1eb3b89601a264a5695b9dca2ec473 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/README.md SPDXID: SPDXRef-5d28a9d1969939fcb244e42d913ae77f FileChecksum: SHA1: 1d8ed717f66567d367f14491be6a0ddde8dd79bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/Addition.cpp SPDXID: SPDXRef-36426469d6a49f75656ee2cecc038a59 FileChecksum: SHA1: 8ba3debd0a94ba73407e8dc0e0fd11424df9ded9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/BatchNorm.cpp SPDXID: SPDXRef-c6ee199406598ddd020ec75689d62b43 FileChecksum: SHA1: 605cb7db862dd741cd2860ec9bf4a3f7e620e08e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Clip.cpp SPDXID: SPDXRef-297240360f6efd5bdda8fd3049d442bb FileChecksum: SHA1: e60ba586295f84fed7a82d7cb08d2daf46a4b765 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Concat.cpp SPDXID: SPDXRef-592ee81372a16f2149310f4872319019 FileChecksum: SHA1: cf8f32658393a1533c9dcb512fdf32c4f4746f44 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/Const.cpp SPDXID: SPDXRef-4e480d6a4463300d93717e1dca179440 FileChecksum: SHA1: acd1c8ce97e17989b1892e24908957015b56b36a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Constructor.cpp SPDXID: SPDXRef-4f75082878330a8afae4efb123ffc634 FileChecksum: SHA1: 7aa55c16d6e391c12f93fb56433cc4bddeca4dd8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Conv2D.cpp SPDXID: SPDXRef-d807221a38316cfdf1e75ca4c72ed843 FileChecksum: SHA1: 3f3be418aed6c70a3060e9163941a422982f30cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/CreateNetwork.cpp SPDXID: SPDXRef-f1647c9a9753cffbc36d9aa0fa713e3c FileChecksum: SHA1: 9868d7a8d008af0877becb277954ccb3a4a45688 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/DepthConv.cpp SPDXID: SPDXRef-bf4e8663d37dabac7dbeff8b3f1dac90 FileChecksum: SHA1: 775d114fd38ad43f8e6d80312494f8bfe58e7f68 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Flatten.cpp SPDXID: SPDXRef-727a099a1df40d260cc9df3b558949dc FileChecksum: SHA1: 0304822c6a730c89de75071157f6ee7671ebb2fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/FullyConnected.cpp SPDXID: SPDXRef-00670c85beffa14d7541e1d0c0f5d0d3 FileChecksum: SHA1: f303ecfc3b977ccde4ef6ca2d52eb5235d196f05 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Gather.cpp SPDXID: SPDXRef-89091123ede77e27d324a17830131870 FileChecksum: SHA1: edbd8124b3a196f89cb14828c52d8a0e7ddcb35e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/Gemm.cpp SPDXID: SPDXRef-778183f267992b10d6b3863a4b4949c1 FileChecksum: SHA1: 6a509ee5c4357f60ed7a73c586131738cb98b199 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/GetInputsOutputs.cpp SPDXID: SPDXRef-282c0d60c12c7e4a4bc406c4c814a0e1 FileChecksum: SHA1: 52272b082a9b9af372ecc9f1be104ae558227571 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/LoadScopeDynamicTensor.cpp SPDXID: SPDXRef-52074d7a9657cdfe265d545c2def42fb FileChecksum: SHA1: 1af2ad5c00875efbe7dcc011ea1a79476cc2b86b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/OnnxParserTestUtils.cpp SPDXID: SPDXRef-70e100136c8ae975ced537662f7022b0 FileChecksum: SHA1: 2b1bed8dd38ba575decd77d088f5cb91c46b8b1a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/OnnxParserTestUtils.hpp SPDXID: SPDXRef-ffcd3adf7965b603151864eb1217f679 FileChecksum: SHA1: a04cb804edb187f2dc6f9e97e8693a9fcd0d12b3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/Pooling.cpp SPDXID: SPDXRef-5b6d9ab3ccb5d1bc07cc2bc8a09931f1 FileChecksum: SHA1: e5e5dcb713b3a575e5839d955d8366ae221669a1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/ProtoxtFixture.cpp SPDXID: SPDXRef-2e79e3c2751a4ddec263dc177d7d5152 FileChecksum: SHA1: 934be32bbb647e449fb9e06151e1f93bc4e6f895 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Relu.cpp SPDXID: SPDXRef-0f2514b3d4c7f27d5819a95d5c111159 FileChecksum: SHA1: 0db07862062246de18120eccef63913e1af38bf0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Reshape.cpp SPDXID: SPDXRef-a12a276277913c5a48ec2e8c5ceaa4d8 FileChecksum: SHA1: 26151a739c89577c8870f9bfdd477b700dd9142f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnOnnxParser/test/Shape.cpp SPDXID: SPDXRef-15bcaaaa16f14d84777552f40c806930 FileChecksum: SHA1: d712fd5e75ee98b372d5bf6f6d3ff7859798231c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnOnnxParser/test/Unsqueeze.cpp SPDXID: SPDXRef-ec20f1addc8ac5b02434b548f4fb61fb FileChecksum: SHA1: 85ea62eeaf671092e7c10773b3b5a78bff2020b0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/ArmnnSchema.fbs SPDXID: SPDXRef-db4d4a2402fffff7a2f889f30c8f41db FileChecksum: SHA1: fa48048419a308f3ab82e165e17f21b3a1f96bf3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/CMakeLists.txt SPDXID: SPDXRef-d7e96884c94f4d4931436ff18fad21fb FileChecksum: SHA1: cffc0a1ef10f5b7f219acbd62d1a0a0fc96ae3bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnSerializer/README.md SPDXID: SPDXRef-b5d204322b1601196e83a37eef97cc57 FileChecksum: SHA1: 788649b956fa430fad47fe33ba84a70237894b1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/Serializer.cpp SPDXID: SPDXRef-045c945f6a0c6eca401b67ca42234aeb FileChecksum: SHA1: 42b02c01e37d39aca784d6b1326b644fc04bcf91 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/Serializer.hpp SPDXID: SPDXRef-2d33395fbba22a2f63dd1f7146d53d00 FileChecksum: SHA1: 10009de80fe33946586c1580e2e229f5de9048b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/SerializerUtils.cpp SPDXID: SPDXRef-da7df4639d4e9d9888e98d48ca44bcc1 FileChecksum: SHA1: 784c9839e9e4267ae537bf47a037be539f6b646d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/SerializerUtils.hpp SPDXID: SPDXRef-db3ef856b541653a80dc78499af30203 FileChecksum: SHA1: 8eb65f052671a18c5f700f866f5af3a9237074b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnSerializer/test/ActivationSerializationTests.cpp SPDXID: SPDXRef-a9ebe26e5d16f9a86aeae14788d832fc FileChecksum: SHA1: 6bbd8f424a55cfd024fb26a701ee3ba4d68893dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnSerializer/test/ComparisonSerializationTests.cpp SPDXID: SPDXRef-6974148e0d028984e0925b6a82560cec FileChecksum: SHA1: 9f765698624cc90133577aa2c5a6331af94a91d2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/test/LstmSerializationTests.cpp SPDXID: SPDXRef-0be1612cb20c5a2cee06ccbf55ee5301 FileChecksum: SHA1: 753b43fb591a8fa28520cf90fc4e702876b6911b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/test/SerializerTestUtils.cpp SPDXID: SPDXRef-b38b4880635dedb5b59f384300716a1b FileChecksum: SHA1: 37811511fe2d4f80ae9462b9e0084a8c11b55723 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/test/SerializerTestUtils.hpp SPDXID: SPDXRef-bbdd3cb7c393da436f63dc59f5ca6b68 FileChecksum: SHA1: 9dd8949ff4803b94843f19e6e4cfb91b6b9f2162 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnSerializer/test/SerializerTests.cpp SPDXID: SPDXRef-d1622d1f3df523c0b56e98d897b352bd FileChecksum: SHA1: 3d101bc7fe5a469aabf01f7b94977d242daf839d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/CMakeLists.txt SPDXID: SPDXRef-a4ff9f9b51e52f06dcd24cfbd69e0cb2 FileChecksum: SHA1: a5c1e56c468c59d25f9cfae718e519cd07472725 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/CommonTestUtils.cpp SPDXID: SPDXRef-d9e3100e555e417fc1c8684ae6f5f9c4 FileChecksum: SHA1: 9b6babe8be3e744eef49917ce117cb91700e6623 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/CommonTestUtils.hpp SPDXID: SPDXRef-df2f8585b2a5355b099443f493778972 FileChecksum: SHA1: 9be2c33387cc2e9c123fddc6397a3676f07a5b7e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/CreateWorkload.hpp SPDXID: SPDXRef-2cc388d80c611ea95af98edb09be890b FileChecksum: SHA1: 0cc85fcebf969be8d546afc3f46e321c17016cee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/DataTypeUtils.hpp SPDXID: SPDXRef-37642520a25683c05677f3e83094c997 FileChecksum: SHA1: 67bdd0578d7f504f398f1df26327e2659e484956 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/GraphUtils.cpp SPDXID: SPDXRef-f2daf8bd8103927e02548e904246851e FileChecksum: SHA1: fa24dfdfe240f8caafef035669f5f619a5050edf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/GraphUtils.hpp SPDXID: SPDXRef-7c48258efd3baefe576f1923c19e9460 FileChecksum: SHA1: 038e01ba91138702d0f40e9683c01f9145cc6d14 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/MockBackend.cpp SPDXID: SPDXRef-3c3805c3c13aea279f4d478a0bfe48c3 FileChecksum: SHA1: b654cfbf262303f709e359a3af1fff076191796e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/MockMemoryManager.cpp SPDXID: SPDXRef-f3b071a25de3a7fab79883e977142743 FileChecksum: SHA1: 435cf73b8beaff86b6840e1656315befbbed20a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/MockTensorHandle.cpp SPDXID: SPDXRef-ae4f32a37824b92800c765862e36b7a5 FileChecksum: SHA1: d6c197851663b9ad4a1516f86d15a8f8da22e509 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/MockTensorHandleFactory.cpp SPDXID: SPDXRef-8125755acdddce07692bd272934c8d0b FileChecksum: SHA1: f2a398702af69b51885e5c1ffdcd02a632779658 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/MockTensorHandleFactory.hpp SPDXID: SPDXRef-0444e019840d9f8a9b1b8845ff07e638 FileChecksum: SHA1: e69de3b9bad3a75965f8ad372b355239961467fb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/TensorCopyUtils.cpp SPDXID: SPDXRef-a98cedfed1b7eadcd88a08e765f2265c FileChecksum: SHA1: ba900057c91d5cee2bd81dab4c79c1bc913750ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/TestUtils.cpp SPDXID: SPDXRef-4156916512aa6e2ab970a87acd97816b FileChecksum: SHA1: a86e2dd689c30c1c3d3d284d4a225d2d7a072d8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/TestUtils.hpp SPDXID: SPDXRef-561afacf5b13ec8996f93b1ea4603dd9 FileChecksum: SHA1: 15620d743da4d50f54b4eedc5dd584490ba54531 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/UnitTests.cpp SPDXID: SPDXRef-40c02735083d0de13b3c7fd4c168b9f9 FileChecksum: SHA1: 428372ebd28ebdca9da93d4b9e67e1f346f06ae9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTestUtils/UnitTests.hpp SPDXID: SPDXRef-6edbeebc4c7e05d301c563a83e0ffc31 FileChecksum: SHA1: 488c4d4e32ef97e27d68b1693ea84449226787a8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/CMakeLists.txt SPDXID: SPDXRef-7de359179ca0f924b4b99b332bd6edc0 FileChecksum: SHA1: 5ba179d3bed0e946cc8a627cd0cc49d38d62daf4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnTfLiteParser/README.md SPDXID: SPDXRef-43ca87e8ee3407d7c38dd46b5e9397fa FileChecksum: SHA1: 263b3fc61027ffd915e980a4ca62590919481f73 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/TfLiteParser.cpp SPDXID: SPDXRef-e7b2c7f17868ce4b303b31726e35aacb FileChecksum: SHA1: 5c2a6e544d4a2bede2433d30a970cc6fbc5fda0a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/TfLiteParser.hpp SPDXID: SPDXRef-3c716d71d74e8bbe550531938544a197 FileChecksum: SHA1: f63c73338175336830482d188132592a9357aaa0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Activations.cpp SPDXID: SPDXRef-47781aff2a91261b8d4b8460a12b558d FileChecksum: SHA1: 62117adfa80b6b9b97703702398fe11e4472ea0e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Addition.cpp SPDXID: SPDXRef-8e4bfd0d8aedcbb460f62b3311827495 FileChecksum: SHA1: 2d09ebb6fd4e58456e952ef70e9dcdc01001e581 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ArgMinMax.cpp SPDXID: SPDXRef-305dc34da5c737ac14982a362da19d14 FileChecksum: SHA1: 3f4f8a73d4775e4605247b1b4f4f72d710c24d4d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/AvgPool2D.cpp SPDXID: SPDXRef-c48c86011e15dbb24034ff02a2078eec FileChecksum: SHA1: 24da583ce35841dac9c134186f257d25d1d06d75 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/BatchToSpaceND.cpp SPDXID: SPDXRef-d5366582c50f363a33a148da182dd937 FileChecksum: SHA1: b14583ca83145b584f50bcc1ca64584760c4e5eb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Cast.cpp SPDXID: SPDXRef-7631dbe0e79fc5333a5acef2b517cd5d FileChecksum: SHA1: d1c0927c2f432bd4a764455a8d6dd9c75c3fb7ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Comparison.cpp SPDXID: SPDXRef-36b1c2ee985a9fb4f93ae5a657ce0879 FileChecksum: SHA1: da68889dcd3f632e814a5bc4950f2e563af1b936 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Concatenation.cpp SPDXID: SPDXRef-aec48f603796c87dd26237f0bdb9591c FileChecksum: SHA1: f6bdbdc1bd9dba040c300e49fe4278fa4bfef908 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Constant.cpp SPDXID: SPDXRef-746c6862b7ffc4978d8a989bddcd9e0e FileChecksum: SHA1: 9f43bc4161c37117dd2e23763c24a23d06f9ce3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Conv2D.cpp SPDXID: SPDXRef-b9f88b722591273c19cb340c1513702c FileChecksum: SHA1: 921f183218d07f5b3f8de16d2f7d3c242c4f192d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Conv3D.cpp SPDXID: SPDXRef-e8979b2da617ebc9320db5d4520a33da FileChecksum: SHA1: 03615a5a8d7f0e4954e35249e5468a1c6fdf3575 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/DepthToSpace.cpp SPDXID: SPDXRef-4b76630558e6ed02a61cd0e68efa0f7f FileChecksum: SHA1: e8b572929981a1741a75c6f52d035e109fa9a039 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/DepthwiseConvolution2D.cpp SPDXID: SPDXRef-f3972bd2f2b38b820af285f455ce97db FileChecksum: SHA1: 2e559a6a6f326e645a283d385f3876eda6a0117a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Dequantize.cpp SPDXID: SPDXRef-57266048d7194cdbd1b51174daf96f82 FileChecksum: SHA1: 710915fa6b8e8ab83c6bca29627e1fc76881869a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/DetectionPostProcess.cpp SPDXID: SPDXRef-f3babaaeecbc6fcaf69c400b39f20e73 FileChecksum: SHA1: 0501fb2358de968e12ce44a9ee155a4af7621ea9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Div.cpp SPDXID: SPDXRef-f15a7377e565d8c665335777d73da366 FileChecksum: SHA1: 2c7bfad4892f3a4f41232009f91f0b5bd824abc3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ElementWiseUnary.cpp SPDXID: SPDXRef-3500309f6bc54749fb796747eb3b1310 FileChecksum: SHA1: e3bf7cc19379de51d58e07cd3bc8a4469628831e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ExpandDims.cpp SPDXID: SPDXRef-d7a70a7136da7d48655c9e3ebe8853af FileChecksum: SHA1: a4764cf1bbc92eab3964fdf11555e929228d60b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd. All rights reserved. FileName: ./src/armnnTfLiteParser/test/FloorDiv.cpp SPDXID: SPDXRef-e021759e55e82754b579fa79c1e297eb FileChecksum: SHA1: 0ac2208ef23415716972de0d45ac3798705b0dd5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/FullyConnected.cpp SPDXID: SPDXRef-e5ebd2b262bfd27870522cb5b0effbcc FileChecksum: SHA1: 7c489d2d56cf4e8fa2fc09f492963b6a9c115d13 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Gather.cpp SPDXID: SPDXRef-ca1dd747f4498fa6ad24a140743fca6b FileChecksum: SHA1: 6da286aa36c5c30d4c305860a6f517ccbcab4f4c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/GatherNd.cpp SPDXID: SPDXRef-d5312f523312b3e7dbdefee73efb896b FileChecksum: SHA1: 5205eedac1f355f357797e567530e0547f699c24 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/GetBuffer.cpp SPDXID: SPDXRef-f8faf64fdf01ae900016f717c3fddebf FileChecksum: SHA1: 5df6bde4301de4dc881c55c04d4c9e1e37523b80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/GetInputsOutputs.cpp SPDXID: SPDXRef-c07a5854e82c0a861bc8044bc3d8b8e2 FileChecksum: SHA1: c3a0af99ec26731165a79bb67e5f01227ac361bc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/GetSubgraphInputsOutputs.cpp SPDXID: SPDXRef-c74b287d7882038abaa1c7c9db9ef906 FileChecksum: SHA1: 892c34bf9105e381c4158c28023bc3b84a8846c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/GetTensorIds.cpp SPDXID: SPDXRef-616923a245853fe381fcddd8bba0a8cd FileChecksum: SHA1: e471a7ca7a98cd7e1790f61fdf4df37bea9c2b7a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/InputOutputTensorNames.cpp SPDXID: SPDXRef-a4d882dc4676876e3f169e30c0d2a566 FileChecksum: SHA1: 205a6bbcc3ee39a6e7bb31825bb2b3ea2cfc86bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/L2Normalization.cpp SPDXID: SPDXRef-3bef9f62e2520993297e2cc3ec4af52a FileChecksum: SHA1: 2ff3f33c6d73381af19ef3f0aeafe8bfdf79a19c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/LeakyRelu.cpp SPDXID: SPDXRef-533ab6e19521b1869b93e506949f8539 FileChecksum: SHA1: 82a319027dcba0c6501b8fb8b9763760e753450d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/LoadModel.cpp SPDXID: SPDXRef-19904d3d217ff608ed99c87c3357c72a FileChecksum: SHA1: 5780183d78d9e38950e82c8140743053087479bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/LoadScopeDynamicTensor.cpp SPDXID: SPDXRef-f9b39967da1bad9a7f384032ce84a2d2 FileChecksum: SHA1: e9ad34da4769e14d4b5898684d8752990b013b78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/LocalResponseNormalization.cpp SPDXID: SPDXRef-f80ad17d1c98c6688a896c6a534de290 FileChecksum: SHA1: ebec4c6e4b4b5fb5909391d6f2c68c47e38a1cb0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/LogSoftmax.cpp SPDXID: SPDXRef-01fdc07cec2950496852abdf6cb71619 FileChecksum: SHA1: ba9e00df8df7d778046a97daaf91d9ecf9fad62b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/MaxPool2D.cpp SPDXID: SPDXRef-154698a4ebb04e1d834e91628973e2c5 FileChecksum: SHA1: 93cd49a4e4616186094b280888ccb2bf6e4fa367 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Maximum.cpp SPDXID: SPDXRef-561943aeb02d6806ab15b84f300709af FileChecksum: SHA1: 00ce46d918cba37c63a67b6b39c3c2c94537cb16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Mean.cpp SPDXID: SPDXRef-98be45e76e65a4a15e90c0786ef2d279 FileChecksum: SHA1: cda0bc5f5f08afb09dafa7d7e7b3c67973b95db3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Minimum.cpp SPDXID: SPDXRef-83a318630f2b967569e5d507255e1c71 FileChecksum: SHA1: abed236507dc993d80f22cf0963b881ca70b8cc5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/MirrorPad.cpp SPDXID: SPDXRef-68d2dbd565708ef1b09b4eba1cf010a0 FileChecksum: SHA1: 31a4beb303a9249d31df07e312efb723bcb263cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Multiplication.cpp SPDXID: SPDXRef-fa631c868069a1f67f611f5a8eb886a2 FileChecksum: SHA1: f43e557afaa8c75d7a455c15ab0a048f47da3422 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/OutputShapeOfSqueeze.cpp SPDXID: SPDXRef-600cd1dd20c748e0ed826fe0fb4e0499 FileChecksum: SHA1: beb894ae3ed2551fdd114de15bf8886ab188b24d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Pack.cpp SPDXID: SPDXRef-c773a4c50394862ac124d83502296f6d FileChecksum: SHA1: 84a5543b88b355d34866f8f3fe8e2d81a67640f9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Pad.cpp SPDXID: SPDXRef-9e34474a8e8d9254f2a3d3397d937577 FileChecksum: SHA1: b75bd4167c5c79507e420d0034be818eea3c0532 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/PadV2.cpp SPDXID: SPDXRef-8681b1fe2e3b1dbb48329d4e558feee5 FileChecksum: SHA1: 79a7addaa502c0c589c7da9932b0b4697db894c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ParserFlatbuffersFixture.hpp SPDXID: SPDXRef-ef419477589153a581e242ff00ca5216 FileChecksum: SHA1: fdeb4f16b2a42b7d1fc429eea402dc8b642bbcc5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Prelu.cpp SPDXID: SPDXRef-d90da361a2e73fa8d0824a63b35f7b13 FileChecksum: SHA1: e8b00d2121d8aa33f59bebeb97b29544f8938ca3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Prod.cpp SPDXID: SPDXRef-8cd02748801a0a7048dece0cda14e456 FileChecksum: SHA1: 58a4e5ea4b81b767d1c38fe760755cdb07d273b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Quantize.cpp SPDXID: SPDXRef-7168ce96a660325c582764feb02fe245 FileChecksum: SHA1: bc79daca766a866549b772a8edf15d1f9b46a4d0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Reduce.cpp SPDXID: SPDXRef-0991de977f38744d540721611704e115 FileChecksum: SHA1: c9334eff6906776d99a1732231ca984b95f0a9df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Reshape.cpp SPDXID: SPDXRef-bce6fb8b57e28a89707ef496c2be8a7c FileChecksum: SHA1: be288bde5c137bf226bdf6205ce50de5df716cbc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ReshapeDynamic.cpp SPDXID: SPDXRef-2d7f7adc7d11dd02ec4f1926a4a9b2e7 FileChecksum: SHA1: ef541b3372855600954f57eb81a8edfafb03ae1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ResizeBilinear.cpp SPDXID: SPDXRef-5a3499fbf85a3a9f73adcc61467ee5c9 FileChecksum: SHA1: 4eb4c064ee8988bf0b22fb7445dca49b727f8af0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/ResizeNearestNeighbor.cpp SPDXID: SPDXRef-28bffc0be494918db2dda80a72f53d7a FileChecksum: SHA1: 9862770c78adb4f1b836347f8cf02a4ff5f1f61b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Schema.hpp SPDXID: SPDXRef-d3e7593d870be35ab1fef93b08588986 FileChecksum: SHA1: 3a4a27208980fd2b8d5617e485a80dd46f4dcac2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Shape.cpp SPDXID: SPDXRef-d9656d1ac8aa770b0c1207a80e264987 FileChecksum: SHA1: aa2f25c41fd3c7c634237c4f30f0ad20f6c25f62 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Slice.cpp SPDXID: SPDXRef-2d4e98b6aeab9e8a797dfcf3651648e3 FileChecksum: SHA1: bf5fb2f7922e321855b506624336f129db8f135b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Softmax.cpp SPDXID: SPDXRef-f4ba93de908321a0b8105346a053f3fe FileChecksum: SHA1: ce81efba838cdec64c91347f0bf032c0de5c74e8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/SpaceToBatchND.cpp SPDXID: SPDXRef-900308e9dd0baca9a87d4a2f445b7cbb FileChecksum: SHA1: fe8c825921c0c11cd61209a5844dd49c3c47abd0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Split.cpp SPDXID: SPDXRef-1a367460fd2e80a2e8fe5e911cc34900 FileChecksum: SHA1: d1560d18ab3c6952fcb795772f82d571b2569324 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/SplitV.cpp SPDXID: SPDXRef-4f8ec1c75580a24533ea5607768f6942 FileChecksum: SHA1: c058359099b4ce1ac4bb59e8a5589ad35f0a7da5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Squeeze.cpp SPDXID: SPDXRef-de93454e77b40a0ad04a2af75c2f4f94 FileChecksum: SHA1: f4b01edfe9ff4cf928436cb33cb5b19a718733bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/StridedSlice.cpp SPDXID: SPDXRef-2030ee620b2a71a83b47cd29786d2c72 FileChecksum: SHA1: dd6ba6511ef5dbf5b4e32210ef20e0c52962e8e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Sub.cpp SPDXID: SPDXRef-dd79c0a02325a975cd70c97027c6f58e FileChecksum: SHA1: 98a33b3fbad4c2e118bf82ca557578ba763c46f6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Sum.cpp SPDXID: SPDXRef-76dd4380155710547df23f3fd6360e6b FileChecksum: SHA1: c2890f35e1fb332b7e31ea7a780bd21fb4af045e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/TfLiteParser.cpp SPDXID: SPDXRef-393e1c9985a3849b8320d8c4a236d9d0 FileChecksum: SHA1: 5f24b20c7b2e579b4ecbe8946909e04ee54dbf4b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Transpose.cpp SPDXID: SPDXRef-6fb847d5d5fb7b556863eb0e65fca737 FileChecksum: SHA1: cd85d0487c17adb3a85a5b2efa8839c780cc8258 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/TransposeConv.cpp SPDXID: SPDXRef-7b50a9c9e91a98d089ab6b7283ef48fd FileChecksum: SHA1: 1ba63be6d4ed37c999937652f00148239e1aeeda LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Unpack.cpp SPDXID: SPDXRef-08856d23b17d0d5d89c2ac3ca7534cfd FileChecksum: SHA1: b3e587e3df85ae1ec6c2c6be05ef1cec03bb382c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnTfLiteParser/test/Unsupported.cpp SPDXID: SPDXRef-bcbf8e357e21e763be583f525f11e66e FileChecksum: SHA1: a11839ad6efab6904979a5400f271eca6d9809b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnUtils/BFloat16.hpp SPDXID: SPDXRef-f7b4e17b026f597357be0dcb7995c114 FileChecksum: SHA1: 18510809b3288e52b516fcd66343ce0fcb4251cc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/CompatibleTypes.cpp SPDXID: SPDXRef-272ebe0ddb3a2dc05bde49666f6a93c9 FileChecksum: SHA1: e23c55e68ad8197ddf50ec8a9b3986be3a7daa86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnUtils/DataLayoutIndexed.cpp SPDXID: SPDXRef-a3cea5e21450936919287aacd62d4072 FileChecksum: SHA1: 332828fdb49b32375991bcb9ebfd7336cbeb9566 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/DotSerializer.cpp SPDXID: SPDXRef-aeaa491f3ae344951f793fe968b2e8e9 FileChecksum: SHA1: c5672968261b693ede29f856b2cec809263cc125 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/DotSerializer.hpp SPDXID: SPDXRef-8efc707d4238f0aa78d79eb7b79f0d85 FileChecksum: SHA1: 342da36d62071cdcfd3f9f043024f9f12538fca5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/Filesystem.cpp SPDXID: SPDXRef-c791f5c8eb28d83ff9f0c494f449e444 FileChecksum: SHA1: 1ec4a7b6b37113dbf015766afaaa6059eb0929d1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnUtils/FloatingPointConverter.cpp SPDXID: SPDXRef-55851c3a85ffd1c3390c2b77d9373308 FileChecksum: SHA1: 65aa943a04d275649a9485fa6673880d1ce0c966 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/GraphTopologicalSort.hpp SPDXID: SPDXRef-75a754b80fd701aea3aac04c9e467d12 FileChecksum: SHA1: 79fc673872e437259f417c95ca94e28759dc7a15 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/Half.hpp SPDXID: SPDXRef-086cccc6c60a32b03374987b411de6fd FileChecksum: SHA1: bb292c6426ea0090a5b8567ee515ecabfc06d937 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/HeapProfiling.cpp SPDXID: SPDXRef-d2647b09c768c78d2e59144f9a11499b FileChecksum: SHA1: 0dbad094d778e11cbff944a18e19ff3871f429de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/HeapProfiling.hpp SPDXID: SPDXRef-d068711946e221474d4fd9ccc180b59d FileChecksum: SHA1: b6e8836e3a045d643cce10ce9ff536c75fdd5f8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/LeakChecking.cpp SPDXID: SPDXRef-189e20aef970ad2429b03dda1be60495 FileChecksum: SHA1: 94935c5e999211ffd17c92176621fc6368f18e96 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/LeakChecking.hpp SPDXID: SPDXRef-f59a023f61adb12c830b0e02d9ae2330 FileChecksum: SHA1: c996c46462549f291b5c3459ca22653122887b1d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ModelAccuracyChecker.cpp SPDXID: SPDXRef-93287c1ec6b60872641de4102fedbd17 FileChecksum: SHA1: b7fb40c7acf05fcae827e31694394704f8699972 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ModelAccuracyChecker.hpp SPDXID: SPDXRef-6691b95c63544ebac3fc2d1feb88c574 FileChecksum: SHA1: b0cda693577d8758547b61f82df8f63eee9fc46f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ParserHelper.cpp SPDXID: SPDXRef-c07f6f31f2f4cf29c3cded7171c96c6a FileChecksum: SHA1: 14e4b8211de7c32cb47b6a97a68b6f896015accd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ParserHelper.hpp SPDXID: SPDXRef-ac4277f9c44d4c80d666db2487f9aab6 FileChecksum: SHA1: 4fc1a78f536d6fcbc8fa91a8f4f71b3d1ef20191 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ParserPrototxtFixture.hpp SPDXID: SPDXRef-677abf83b02da4ce06743446b2823d6a FileChecksum: SHA1: 71526d836ca32a02358e464c5d8bef0f56f4a226 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/Permute.cpp SPDXID: SPDXRef-d10ce364c8cdd972acfe6c34eeaa30d9 FileChecksum: SHA1: e46b6cd1da42424d31fd2fc405e7b6deead46737 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/ProfilingOptionsConverter.cpp SPDXID: SPDXRef-b37be1f4be594a98930d95cf34d0048c FileChecksum: SHA1: ffd57686937dfab3bd677aebf6b05cf92c32481c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnUtils/ProfilingOptionsConverter.hpp SPDXID: SPDXRef-3caf529b6c5998907797539a65ece0cb FileChecksum: SHA1: e061b57a6d957adb1cca392354e6e8ed59f76684 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/armnnUtils/PrototxtConversions.cpp SPDXID: SPDXRef-67d71fdad8de83de1ef65ac357edb547 FileChecksum: SHA1: e393b512c855cc977a59f1ca2bba07a2cb79b162 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/PrototxtConversions.hpp SPDXID: SPDXRef-5dfff9bcff48ae2fc1a465b4323f96f6 FileChecksum: SHA1: 259ec8001193e1108987b9fe637a59985d9d30bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/TensorIOUtils.hpp SPDXID: SPDXRef-91effadd677b2a96881e693a32da9fba FileChecksum: SHA1: 74e4f9cd120d9429add16c3c5ffb9e32dc30318b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/TensorUtils.cpp SPDXID: SPDXRef-870fb7050f30edb5510ca582192bf850 FileChecksum: SHA1: dc22faec721862cdfe0209b0d0d9ac92cb1d702d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/Transpose.cpp SPDXID: SPDXRef-d0167cf00451baa96e6a922880ea2de5 FileChecksum: SHA1: ea6de34627e667dcfd9253107bd0fa1b966ae9bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/VerificationHelpers.cpp SPDXID: SPDXRef-21cbd480114abf5d67dae57a88eb69b2 FileChecksum: SHA1: ef4f690d7407014930144e082c3d27d2fa30e16f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/VerificationHelpers.hpp SPDXID: SPDXRef-0648152ccc3465d9fa3426324ffc1cf6 FileChecksum: SHA1: 8433941ba30db9d11c50a5e50d9754ccbb00f360 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/FloatingPointComparisonTest.cpp SPDXID: SPDXRef-5691459b45470842a3beed5fcc2daf95 FileChecksum: SHA1: b4841105c3a1fce4ca5802f9fdcda548a50ef5d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/ParserHelperTest.cpp SPDXID: SPDXRef-882e1427005aa536fa0b1576e00a9eb3 FileChecksum: SHA1: 772ba58a67e3828ad9d4e574c4dea3c849175db7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/PrototxtConversionsTest.cpp SPDXID: SPDXRef-85fbbe6eda731f45706548d6b74c3c96 FileChecksum: SHA1: b8d43a884d234f28ba642cc3dac7d3c2e84d0133 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/QuantizeHelperTest.cpp SPDXID: SPDXRef-b21eb4379d50060da79219c091a93cc6 FileChecksum: SHA1: 62af58796a291f01629ed1634b7471da61823287 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/TensorUtilsTest.cpp SPDXID: SPDXRef-3ca685f66702812e2a83926dec023238 FileChecksum: SHA1: 14f0d6f3e852213e60733b5051dde7eb9e1a79f9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/armnnUtils/test/TransformIteratorTest.cpp SPDXID: SPDXRef-6fef8cdbcce2f3c140efdb2a7cc07e88 FileChecksum: SHA1: 7ba6f8cf16f5850876a7900e4641873cd328229e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/README.md SPDXID: SPDXRef-d32e2b6025d51945cdba48e0507e53fd FileChecksum: SHA1: 8959737bc13d7d562b443643f892221bbc188662 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/aclCommon/ArmComputeSubgraphUtils.hpp SPDXID: SPDXRef-4d7e42e5e939e92b557d93e3e1a87bdd FileChecksum: SHA1: 4eb3bf81598b2fe1ae3a2927e917ae4a7c5196e0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/aclCommon/ArmComputeTensorHandle.hpp SPDXID: SPDXRef-a7bad576353032d65fa41ce5e93e40e6 FileChecksum: SHA1: f543ddd60b8b07b376592bbd001a4f0581092fd5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/ArmComputeTensorUtils.cpp SPDXID: SPDXRef-9dc265e5f45538e26763d5bc43fed764 FileChecksum: SHA1: 854d663ab9e45123908865fb664a5bbae987b65f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/aclCommon/ArmComputeTensorUtils.hpp SPDXID: SPDXRef-1c48e5859598a1b6bf3c21b9e3db11c6 FileChecksum: SHA1: 602bf7f5dcdf55683e183a4892ea78de4b86af64 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/aclCommon/ArmComputeUtils.hpp SPDXID: SPDXRef-1a9d4ec617a354628374952baf7e9bc6 FileChecksum: SHA1: 1acde5f735ad10cc8c3ffa21499cbc04f259db34 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/BaseMemoryManager.cpp SPDXID: SPDXRef-8ef42e6f930766abebd828ef665d82a5 FileChecksum: SHA1: 0800418be059b979dabe60b20bb3b3c83f18e3b3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/BaseMemoryManager.hpp SPDXID: SPDXRef-61f86f4e83fe37c91526420b0d93b02d FileChecksum: SHA1: 41780e0708397a5eb247e97a1fc2abe0d9206cb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/CMakeLists.txt SPDXID: SPDXRef-e0bbc8c70965f159d3f1f6dec5e04df2 FileChecksum: SHA1: 03343149aade3d319545337f3708877df94f6f0d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/common.cmake SPDXID: SPDXRef-c17da1e918b934ef742ba9d0e5a5355d FileChecksum: SHA1: 5d93fe047ad80a18aae2b49de2a8f65babd640fb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/common.mk SPDXID: SPDXRef-ff56173f5ebd0292d2f9fe95b0b5b2ff FileChecksum: SHA1: 5a4a38b7c9a7e9cf58be60bdcd8ed5e4534e5fb3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd. All rights reserved. FileName: ./src/backends/aclCommon/test/ArmComputeTensorUtilsTests.cpp SPDXID: SPDXRef-42b64692e765b041623f87af4ce8c655 FileChecksum: SHA1: 02d9f96c4796454371705f21eced0dd8a47873ed LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/test/CMakeLists.txt SPDXID: SPDXRef-8463fc82f0eb9a0fa136c494e763341e FileChecksum: SHA1: 4c2533dfd709b19fe6e38c51e692029dc239fafc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/test/CreateWorkloadClNeon.hpp SPDXID: SPDXRef-5960d0b8b6f7b6a9050a819f0a2a3a67 FileChecksum: SHA1: 863ef2d6114cb90b93eda8675e278761c27a8446 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/aclCommon/test/MemCopyTestImpl.hpp SPDXID: SPDXRef-ad0aec8e15ae4f3f61d95e5866e25af3 FileChecksum: SHA1: 86cd1bd754696890c2fdcf2e9c3c24cf30ef0287 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/aclCommon/test/MemCopyTests.cpp SPDXID: SPDXRef-37d582521bbbc127ed63ec6a54caf059 FileChecksum: SHA1: 94c0122e48e57f75a95e6ade7cb5aeb5be7a0bcc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backends.cmake SPDXID: SPDXRef-287336ed5017e040f9b90288c71e6012 FileChecksum: SHA1: 60cefd777a9304757ec172b6f4b69b3fffb91467 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/CMakeLists.txt SPDXID: SPDXRef-640de422f5b49570c873c22c400c8628 FileChecksum: SHA1: b3e00ae1a95831f01d48b394120973978254dd57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/DefaultAllocator.hpp SPDXID: SPDXRef-f903772610a8df7882b6414220a0c5f2 FileChecksum: SHA1: 07b2cf82f52049d53f727eeff7b06b86d8d83b3e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/DynamicBackend.cpp SPDXID: SPDXRef-af42848ab3a2ca326e9904fba972758d FileChecksum: SHA1: accb98a61276d48b88d839931d1998a12ac6e44b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/DynamicBackend.hpp SPDXID: SPDXRef-25b7e29b86a6a876bc38445027062c54 FileChecksum: SHA1: 3e6429b7166c73520d51381ab4992bfe5af90df9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/DynamicBackendUtils.cpp SPDXID: SPDXRef-4f7b9e7d65b561eae53f173d1c65cb3c FileChecksum: SHA1: 4459283c4a312a600271dfa5def572b0e5daef47 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/DynamicBackendUtils.hpp SPDXID: SPDXRef-63e0933bcc37477172d11a7462967bb0 FileChecksum: SHA1: 954a69c6f8a7d3595db59049497116143344e9f0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/IBackendContext.hpp SPDXID: SPDXRef-83afb2d6f5f7077c8ca9d2467e411b6a FileChecksum: SHA1: 66450377857c0c94c56291de1d25f71da45d793b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/IBackendInternal.cpp SPDXID: SPDXRef-dec81256a513a2a876b77608d01561a5 FileChecksum: SHA1: 9b3c98d9f613fca67e0121c57e7d361055a65a9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/IMemoryManager.hpp SPDXID: SPDXRef-6e22304b4ae922b07beed0df0ff988f6 FileChecksum: SHA1: 8bd5fc16564c17d29fb99f8c0e57f22548b95aa2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/ITensorHandle.hpp SPDXID: SPDXRef-f7957a4033acf5320f2e5cc7452c740a FileChecksum: SHA1: e22bcac65761a3e8e23bfeddd593ac81f4311bc5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/ITensorHandleFactory.cpp SPDXID: SPDXRef-b76a6818f15697e20400198d3ee87f38 FileChecksum: SHA1: ca82f19cc27e42e3d6fb7a8d3c3dbf4f14d50659 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/ITensorHandleFactory.hpp SPDXID: SPDXRef-b20a5de0761874bf992f6adb39e86bf5 FileChecksum: SHA1: a2bbf53bfb31bddfc9c35c859befd8264c1e18e8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/LayerSupportBase.cpp SPDXID: SPDXRef-b76e14c7e8cd2835de8c034c9a137d33 FileChecksum: SHA1: bd437ac3c7f82eecbd6079f2dae0c34f99b3737c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/LayerSupportBase.hpp SPDXID: SPDXRef-9674ba7c6efd36f61be71c9f96361022 FileChecksum: SHA1: 56a92cc1d8f10e77fe7827ca7745766498ecadf6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/LayerSupportRules.hpp SPDXID: SPDXRef-5c83e2a8e56e26c5f1c2fa0af54bc574 FileChecksum: SHA1: 259506f7439d977a48e271e30f980e153d402374 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/MakeWorkloadHelper.hpp SPDXID: SPDXRef-3b3389919e928cd5e5ed170f3dd7b838 FileChecksum: SHA1: 2d39152b37f6a0257e3baa7a94fd3dce404d9f9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/MapWorkload.cpp SPDXID: SPDXRef-68677398b424c4c2553a4d15d58e08a1 FileChecksum: SHA1: b31d732b0da48be801356fd0f3006ec88560f9ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MapWorkload.hpp SPDXID: SPDXRef-a3a26a32760aa1eb5fb1095f49a58326 FileChecksum: SHA1: 7e1108a330a2f06adba0b7862cb7d0c7d138e745 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemCopyWorkload.cpp SPDXID: SPDXRef-aa090829d83e61ac3b08b617c7137cd7 FileChecksum: SHA1: 191bf6091a20fcf8f943334decddf76bb7815a40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemCopyWorkload.hpp SPDXID: SPDXRef-d3d7229e286688fbb83c6ef2c0c831ff FileChecksum: SHA1: 26e26bba58ed3acecb3a7d616e9f5af5f8d2cfae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemImportWorkload.cpp SPDXID: SPDXRef-4d06d2479d7012088b494d9658ccd140 FileChecksum: SHA1: 9dc1b2a668500e6ad0021a6c72ec9a3e34459103 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/MemImportWorkload.hpp SPDXID: SPDXRef-3d3287b706ad3e9bb82e51145f4dc818 FileChecksum: SHA1: fc6bbf8581a82a6011f4f33065f8d46f41e7e7ef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/MemSyncWorkload.cpp SPDXID: SPDXRef-84f4ac538b12f7e3253fff55ae866002 FileChecksum: SHA1: 8edf3497b136d74533739a039dd2cdf75b0cafc0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemSyncWorkload.hpp SPDXID: SPDXRef-431be145505fe5c61d3506bb41e24295 FileChecksum: SHA1: cbd65d2cfa60ce380fe3beadaf54f7169f4b0fd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemoryManager.cpp SPDXID: SPDXRef-208768851c9971da24255a4ed79092ec FileChecksum: SHA1: 48cb7bd221691f0ba490ab07d096466d92d1e916 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/MemoryManager.hpp SPDXID: SPDXRef-8aa8f7216b80bd9acc11dc8bba052387 FileChecksum: SHA1: 1146f5a8d40006f2abf85dda32a62402e321ac5e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/OptimizationViews.cpp SPDXID: SPDXRef-1369d63fc0fed22223a890d2f077e706 FileChecksum: SHA1: 2fd5a1d4c7335bef048ef9ef4a52b4b2624e3de8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/OptimizationViews.hpp SPDXID: SPDXRef-ed37a746d54c68843482caeba32b346e FileChecksum: SHA1: 6e99fb843d00367e295a1e5d9c5c37588c7c4e34 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/SubgraphUtils.hpp SPDXID: SPDXRef-4abc123562249792032735bf62ba5e79 FileChecksum: SHA1: 311837aae60f6eb39ba9c9c1360c12461b433229 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/TensorHandle.cpp SPDXID: SPDXRef-38987a65503eb5a9524e58dc4a3868de FileChecksum: SHA1: cb3314093204d7dbc4009f84eae0061ecdf61171 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/TensorHandle.hpp SPDXID: SPDXRef-97f1d247177f71c06042358a131b8cb7 FileChecksum: SHA1: 9970887968c41c1c93ff70a1215faaaccbfe9aea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/TensorHandleFactoryRegistry.cpp SPDXID: SPDXRef-744bb8f2414d3589e51e28a17b018903 FileChecksum: SHA1: 5ba7a78ddf11d6e5f4b0e53c03948dde3425e0ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/TensorHandleFactoryRegistry.hpp SPDXID: SPDXRef-2c5f870c7275c3a533697116e906331b FileChecksum: SHA1: 0382d6fba005fdf7d5ef9c85adcaf518f8470625 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/UnmapWorkload.cpp SPDXID: SPDXRef-826f2ddaae96e6e3bdcab4e3eca0fef8 FileChecksum: SHA1: e33bf2819763afcad9271f612fb9d255c4978da8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/UnmapWorkload.hpp SPDXID: SPDXRef-8cfe0c8c27dfc0576c868ad56ba7eea9 FileChecksum: SHA1: 83bae6a0b1ea125f5270df9e82a803a010ca38f4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/Workload.hpp SPDXID: SPDXRef-63b658f17bc7912e4e2c01049d01eaf3 FileChecksum: SHA1: 201e0220f5260cfa2381492a137116894e49d345 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadData.cpp SPDXID: SPDXRef-13f0523a604fdeb44a636f2539a6caf6 FileChecksum: SHA1: fff22e92093167dccdf10635559cd0f078944030 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadData.hpp SPDXID: SPDXRef-afe7cf1da458dade0db62254b59ad0b8 FileChecksum: SHA1: 6e22119dd1b1f962479b3e59af3a2c20ec5f3696 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadDataCollector.hpp SPDXID: SPDXRef-552de4752516fae084f3386dd3722633 FileChecksum: SHA1: 1f1e7df8a9095c6b5c2c6b96ce4a31b6df9de180 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadFactory.cpp SPDXID: SPDXRef-d25b032dfabf6f2fb04c4a87b072fc7e FileChecksum: SHA1: 578a46496f6751bde3fb4677fc4aef83dcdddd0f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadFactory.hpp SPDXID: SPDXRef-fafaa78fda48dec7f4c40bf9226180c6 FileChecksum: SHA1: a009558696cbc0391de2883fd13c256fea421f1c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadFactoryBase.hpp SPDXID: SPDXRef-d8d56114211ac5c27efe9845bbf9639e FileChecksum: SHA1: f0bf60c176df555fcac1ca77654e1bb907956df9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadInfo.hpp SPDXID: SPDXRef-7686c7a519267a1661ac14a509927c23 FileChecksum: SHA1: 0e25adc055d1f64f274472c14c2948365cf88186 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadUtils.cpp SPDXID: SPDXRef-68b57ec970d141cc38ecb8b8e17127fd FileChecksum: SHA1: b88c150167302ded6369bdcbc375738895fbc4d2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/WorkloadUtils.hpp SPDXID: SPDXRef-b094846b8e43016e474ea25556e2746d FileChecksum: SHA1: ebe4d6193d7e2529bff11f7e6751c253e325eb44 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/common.cmake SPDXID: SPDXRef-34cd2204b1c381e8fdc418c6282e1a71 FileChecksum: SHA1: 1f924b12d351c3ebf391095327ea60d402857e57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/common.mk SPDXID: SPDXRef-59b976aa69ff75660184ef830f3e4df2 FileChecksum: SHA1: 6bf24495df68af702260b54a3bd581285e7f2172 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/CMakeLists.txt SPDXID: SPDXRef-7ba900b74dcae60cb5c32af101fa9806 FileChecksum: SHA1: 41944e8f583e16de6cc9062a07927f1c6872604d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/MemoryOptimizerStrategyFactory.hpp SPDXID: SPDXRef-345e3dd92474ef6f0be155df349b25c2 FileChecksum: SHA1: 4fce0f149df77f25581bc93c04370b6f068fd878 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/MemoryOptimizerStrategyLibrary.hpp SPDXID: SPDXRef-4f72142a1222ef96ee9be1e32af697a5 FileChecksum: SHA1: 3fd4b9a3ada205c2fbfb989259b48d22e1503769 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/ConstantMemoryStrategy.cpp SPDXID: SPDXRef-7c95102af7c35480ac427526ecf55051 FileChecksum: SHA1: 8c0694213525cc03c2e99ac49ee40e25a8f1839c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/ConstantMemoryStrategy.hpp SPDXID: SPDXRef-c5c896a01f9b699afbf142dfaa03b93c FileChecksum: SHA1: ab576f22df0e7856aa1b74a02154b80b22651b51 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/SingleAxisPriorityList.cpp SPDXID: SPDXRef-5aa23bca4b3cc3befa1b7bb1cdf1a110 FileChecksum: SHA1: f467614582df88025690aadc9ce1fe460e0a937d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/SingleAxisPriorityList.hpp SPDXID: SPDXRef-811da0005f934972e7706210c48a2392 FileChecksum: SHA1: 24bf28fa3a9972a0f0c477d871669f8580adea2f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/StrategyValidator.cpp SPDXID: SPDXRef-4611fce318663a5e78d7ae429053acd5 FileChecksum: SHA1: 8d8da42d36d3398293b6f5fe815c6050f3a0e5df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/strategies/StrategyValidator.hpp SPDXID: SPDXRef-78cd85bd23e2e4b3186bbff775217383 FileChecksum: SHA1: 15ace67d13477c503714aa48a13eb36d3d2f2a76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/CMakeLists.txt SPDXID: SPDXRef-cbad57266003d9ce60d11b9ab3811f44 FileChecksum: SHA1: d79cf0ac80872d61b34634f23f9bbe4d99d7aa59 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/ConstMemoryStrategyTests.cpp SPDXID: SPDXRef-862a3b96c8132a2ebfef0dfeff72feba FileChecksum: SHA1: ba7f6b82f0d988dca93b4ad5f8b0368108fdcf9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/MemoryOptimizerStrategyLibraryTests.cpp SPDXID: SPDXRef-728bb4f8468e39a2c26375217b65ad85 FileChecksum: SHA1: dd44acaae7c90722157f7c3d6e345cf603115503 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/SingleAxisPriorityListTests.cpp SPDXID: SPDXRef-c1ed00d466ddc695a610dd49357c2464 FileChecksum: SHA1: 7ceb5bceed6c3344710c8752269015f3bd409ae0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/TestMemBlocks.hpp SPDXID: SPDXRef-931650da45c639d57771b7e2184fe6b9 FileChecksum: SHA1: c4ac0a97f1368a1ef70528e48254bd52c145e401 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/memoryOptimizerStrategyLibrary/test/ValidatorStrategyTests.cpp SPDXID: SPDXRef-ee3b50399d108cda9b5a9ee6c5115170 FileChecksum: SHA1: f42cd47a6848db333e3e2c21764f56c2c2513539 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/ActivationEndToEndTestImpl.hpp SPDXID: SPDXRef-32670750c51b00648e55765f8e32d153 FileChecksum: SHA1: 02bac867d92ff2f628d053fcfb3ed5800d79c429 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/ActivationFixture.hpp SPDXID: SPDXRef-deeff0c235cd5145cfc1b0aea3600ada FileChecksum: SHA1: bb649ad2f097f4901cddc65019b04e780954f175 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/ArgMinMaxEndToEndTestImpl.hpp SPDXID: SPDXRef-415315ad75775526bd650767c17279d6 FileChecksum: SHA1: b5a79d5f0a2c8e65761fb338b6fbe5c382dac01e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/BackendIdTests.cpp SPDXID: SPDXRef-af0ed63bdb210686e4a68a68defc3d72 FileChecksum: SHA1: 9ddcd3bcf36de444968fcf5b62e08789a50cdfa4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/BackendProfilingTests.cpp SPDXID: SPDXRef-2cdba4e6af39a3cac7be7d4b8a15468f FileChecksum: SHA1: a59cc8696b5c5bbafd882cb72cabbf152f737088 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/BackendRegistryTests.cpp SPDXID: SPDXRef-cef53841703945300e9cc9ed8b789363 FileChecksum: SHA1: 0187550655950aa6d41f81e5f942ebe0882b330e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/BatchToSpaceNdEndToEndTestImpl.hpp SPDXID: SPDXRef-c52e0b11f099a2ccd95867182b6bdff9 FileChecksum: SHA1: d5058cb19fdda735c4257c76af083ca707c83920 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/CMakeLists.txt SPDXID: SPDXRef-c564252c7243c34f3ad119255918f5a0 FileChecksum: SHA1: 61889bfab2b46b9e3551c0f4b55c90f978f678d4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/ChannelShuffleEndToEndTestImpl.hpp SPDXID: SPDXRef-3f4de1717b5aaa5a41b705feac4210bf FileChecksum: SHA1: 8a236bef5dfdcb2390b493fd12878f4bb8e36783 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/CommonTestUtils.hpp SPDXID: SPDXRef-d38c01c57cda2e9b6ed5139385c37678 FileChecksum: SHA1: 1bd4e99118569a162ecc2943d9175bfdf00c2759 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/ComparisonEndToEndTestImpl.hpp SPDXID: SPDXRef-800e1f2d530801220ec551ce88da80a3 FileChecksum: SHA1: bc3211b4bb1417bb4ce570ab439c0522f4becfc1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/CompatibilityTests.cpp SPDXID: SPDXRef-9e6216eeead0ec25239c87dcf9abaace FileChecksum: SHA1: e194a61506af5efd5f7acef2cf6b41ce8253b36f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/ConcatEndToEndTestImpl.hpp SPDXID: SPDXRef-f212e58ea54318c77e1f7cba76cdf0eb FileChecksum: SHA1: 9289ffde3285708df08c08beb1fba421e4415a5c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/Convolution3dEndToEndTestImpl.hpp SPDXID: SPDXRef-c90c84e9e4170cc4bc519295dee4917d FileChecksum: SHA1: e9c9f46b44ae45dc0245334cc559831872843341 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/CustomMemoryOptimizerStrategyTests.cpp SPDXID: SPDXRef-d7c8d5f4c0dae7ec8e3d6d15a3da9aa4 FileChecksum: SHA1: cade0e0581789600f9d5127bb834b8a872756e8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/DataLayoutUtils.hpp SPDXID: SPDXRef-91b8d88d506edb8baf88d65e585e998a FileChecksum: SHA1: 432ea995a1a2d05b564bfcbdb8352060f19c4025 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/DataTypeUtils.hpp SPDXID: SPDXRef-5885d50423f678c02248e2f7f4f22110 FileChecksum: SHA1: cad20100a7f2304b64b9c238cd7b500ac473ab8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/DefaultAsyncExecuteTest.cpp SPDXID: SPDXRef-ba0064ed3a6ebc212782df8bcd23f408 FileChecksum: SHA1: cab21d16f1588efae6f3794a504919aeb0273fbb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/DepthToSpaceEndToEndTestImpl.hpp SPDXID: SPDXRef-e392f630286009aecc246113f45e01a6 FileChecksum: SHA1: 8498251ddfcb3e42007a10c85d2d15953197de15 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp SPDXID: SPDXRef-4c09a1e7e5480ddc6c7abfad057b1de3 FileChecksum: SHA1: be1a38b0d8b67ad9add310e8759a41c73cacfd7b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/DequantizeEndToEndTestImpl.hpp SPDXID: SPDXRef-31691b44df1b72347c6d29fe3784a750 FileChecksum: SHA1: a9b51b4f994a5afd2846dbc5362e58f546c11390 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/DetectionPostProcessEndToEndTestImpl.hpp SPDXID: SPDXRef-d094a1e74429e73b0f0ee56928a4a360 FileChecksum: SHA1: a8af1319a36b574d68ff1635cac7b7a5b56f54c7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/DynamicBackendTests.cpp SPDXID: SPDXRef-b7e331ca1126f76978474c3a6b914ab2 FileChecksum: SHA1: 10c0a1a4a1da7d4e27379cd5fecd2ea6e3ae5655 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/DynamicBackendTests.hpp SPDXID: SPDXRef-dc4ec4c4c7a9712330eb2a0134092584 FileChecksum: SHA1: 909e59d077ac8f90a19d5a71f1a63ae77168bfd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp SPDXID: SPDXRef-5492b1e1b5c7db47c10e6424aa66455b FileChecksum: SHA1: 520bf17dbc7b6f575b4212f8e4f425c6c431fdb1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/EndToEndTestImpl.hpp SPDXID: SPDXRef-7c085806c3e0cddaed6da113da16eabf FileChecksum: SHA1: 0aea6655a08175c99847113a7672c4d1fa88b921 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/FillEndToEndTestImpl.hpp SPDXID: SPDXRef-5a269eb9f4fded16b8c39b24623d148c FileChecksum: SHA1: eeb7b29e8bc88e756c882b70faffa6056dc4f2ee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp SPDXID: SPDXRef-8ead90986f3f58830952a8efd4786b86 FileChecksum: SHA1: 2b81abdb844c7a30122e49bd5d62b1056f68d144 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/GatherEndToEndTestImpl.hpp SPDXID: SPDXRef-755e749196741fd098850226233244c4 FileChecksum: SHA1: 9d45371043e3a012c8a037fba7bd8d61486c8b31 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/GatherNdEndToEndTestImpl.hpp SPDXID: SPDXRef-bd699a9d6b7f81b1f0aac8cdac5f489f FileChecksum: SHA1: 0e53be1c904413c92f1241864e99dbbe425df4c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.cpp SPDXID: SPDXRef-03dc2e0e69f5ec954a277ccda138f56e FileChecksum: SHA1: 00ec6f9dabc30b7cce226277a1290f4a6ca9c3f5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/InstanceNormalizationEndToEndTestImpl.hpp SPDXID: SPDXRef-3cc575c47fc32781b16b17f69cff3283 FileChecksum: SHA1: c7556f4886add53df887ee9b1c103db5affc4760 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp SPDXID: SPDXRef-4554deacc0a0e24bf486b18e7968366e FileChecksum: SHA1: 526d9799bab597ed7f4d29f00e35132a14047996 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/JsonPrinterTestImpl.cpp SPDXID: SPDXRef-ff93a989ed68a542262affd7285dc4b6 FileChecksum: SHA1: b7a69abc94d7973f9090fc8529ee622554d86939 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/JsonPrinterTestImpl.hpp SPDXID: SPDXRef-dd7629f4ecb470dc86fd12fcd18670b5 FileChecksum: SHA1: ba195d3ea3547819fc8ac9ebe0e702b57ee00770 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/LayerReleaseConstantDataTest.cpp SPDXID: SPDXRef-613e7273440218c6ee8359cc37dd32f1 FileChecksum: SHA1: dff4861c7f0e99708e8fa6c44c7176f2f12c8de9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/LayerTests.hpp SPDXID: SPDXRef-5d02f2c493dc690ce74077ccf3a1d8d6 FileChecksum: SHA1: 836b6ccfc0b94eab0b4fbdeb12c7903f560bba0a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.cpp SPDXID: SPDXRef-917a7d2479c459d58fde9ac46838343c FileChecksum: SHA1: 12730d4b71944ccb98cb13a918769254fe8dd8ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/LogSoftmaxEndToEndTestImpl.hpp SPDXID: SPDXRef-51242110dd44646f12296f33f40795be FileChecksum: SHA1: db35c1e353cade2a4b34ff2743d45b52e8ff38f1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/MemoryManagerTests.cpp SPDXID: SPDXRef-00d8566083dbee3a160b29ac9c176bfe FileChecksum: SHA1: cc1615fe53cd386b10c63b665be548c1b092eba6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/MockBackendId.hpp SPDXID: SPDXRef-545d692250846a02a068e2be20569170 FileChecksum: SHA1: 96eb3e8d7b11ec23d10079928e4022dd1fac2e58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/OptimizationViewsTests.cpp SPDXID: SPDXRef-20f5bca9468eb3e39414b461719aa8e3 FileChecksum: SHA1: e5581eba65e58a417bdaeebe6fcbf45720ef25f1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/OptimizeSubgraphViewTests.cpp SPDXID: SPDXRef-2aa56c9d69d7e142d69df6760a5e0cb4 FileChecksum: SHA1: a44c91ac456c3686d549d4055472ca904059b08d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/OptimizedNetworkTests.cpp SPDXID: SPDXRef-3b00c9d9162fa3efd4ef6333446aac9b FileChecksum: SHA1: 5d756071254695eee2d55140c799b6e31842cd8c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/PreluEndToEndTestImpl.hpp SPDXID: SPDXRef-de503f246d9a20cc474651315a12d80e FileChecksum: SHA1: a665c8f1e2fa96041afe3830bbe9f0a762e3e548 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/QLstmEndToEndTestImpl.cpp SPDXID: SPDXRef-c552f2cc24bc1a5cffe2f759443dcbd0 FileChecksum: SHA1: 8cf7fd3c44e8430f2275bc0dd64156abbf504048 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/QLstmEndToEndTestImpl.hpp SPDXID: SPDXRef-91d65e001c16f3629552b32d0a8fc2cb FileChecksum: SHA1: 6128d7f912278c3a82d56fae5ee8e22511c530ba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.cpp SPDXID: SPDXRef-df3bdcbacb0cab1b3950bcd799ac32b7 FileChecksum: SHA1: 04421729e72a0bba4805daf2415bdf71e25b1ed6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/QuantizedLstmEndToEndTestImpl.hpp SPDXID: SPDXRef-9aea31b05f94e7da0a84af35c0d68c47 FileChecksum: SHA1: 1c8f516e562e1060a8f32f36e634d5c87b24eb02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/RankEndToEndTestImpl.hpp SPDXID: SPDXRef-c253263d854977bc5a1b2959ae4678cf FileChecksum: SHA1: 2ece0d51d98eacc9fbcc462a53dfd6774e8ecf42 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp SPDXID: SPDXRef-ceb8f49c6419c06b6772fd7ea2071b6b FileChecksum: SHA1: d94aedb5bbdf4e7ecb93d4c23c3657b24a9fef74 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/RuntimeTestImpl.hpp SPDXID: SPDXRef-02a36a190d696eebe32a05679d7f2ba6 FileChecksum: SHA1: 14549d8b38802dfcf7619e87d9c50f0de9f25967 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.cpp SPDXID: SPDXRef-3034e6fd9f790a5d0518b787564c6f4d FileChecksum: SHA1: 4bda74fa99d273a37b4b57ca29628cc12cb306fe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp SPDXID: SPDXRef-8105720df5f75353db5149864e6da717 FileChecksum: SHA1: 59953481e2c26cff6f080312b7bfa0d33e909a03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/SplitterEndToEndTestImpl.hpp SPDXID: SPDXRef-6e9dc1f93d584d0552f1237b2762450a FileChecksum: SHA1: f5fd60bf1ce1680b7aff19533d3126478af35252 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/StridedSliceAsyncEndToEndTest.hpp SPDXID: SPDXRef-e2f5b078ad9755ad46e8189ac52661e6 FileChecksum: SHA1: 4c999def63c3439aa8d6ae6ba15250b3267b9d7d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/TensorCopyUtils.hpp SPDXID: SPDXRef-9118f2021c95c03b64e73d3c3acd421b FileChecksum: SHA1: 76cf6f1744ed7c938dde350a78783fad38bd04f0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/TestDynamicBackend.cpp SPDXID: SPDXRef-a63a9c72a5ba401cd3765495caac319e FileChecksum: SHA1: 59b84742153c42bd7c9aeeb3d0337b2b5d1798d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/TestDynamicBackend.hpp SPDXID: SPDXRef-f6878fffc152c7fec86b58f67774eb8b FileChecksum: SHA1: d5be40d351fbeef0378e70ea8d9b8b6a6fa5e0c2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/TestSharedObject.cpp SPDXID: SPDXRef-2def72f9013bb5876cc3f1ceee1bad12 FileChecksum: SHA1: ab1c4f28473ecb19e7eefe1fa8121d36bf273ae4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/TestSharedObject.hpp SPDXID: SPDXRef-fed3941274ad99ddc1ba5f0501c2a747 FileChecksum: SHA1: 24a58353e9be6df5dfe91b9238729108dc302cd3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp SPDXID: SPDXRef-85b76120f3aa509205938b71a5c8912f FileChecksum: SHA1: 07dea456499b4a6921b82aed4146ed7c1f56cfd6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/WorkloadDataValidation.cpp SPDXID: SPDXRef-8c96b7b7c4dc16d054d7a8002cb08dae FileChecksum: SHA1: d3b2474400feba36665c4fdbd71c747285d31fcb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/WorkloadFactoryHelper.hpp SPDXID: SPDXRef-9f297dbdf1ca0fe2531e7950aa23aea4 FileChecksum: SHA1: 18ef19f8720a5d3171cea4bc304fc3994512ca77 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/WorkloadTestUtils.hpp SPDXID: SPDXRef-41a6f1ac426c896057aab3ed1eeeac81 FileChecksum: SHA1: f2cc2a7157df9804ebe92049d217ec01a511791a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/AbsTestImpl.cpp SPDXID: SPDXRef-8d2ac56850cf58d110493c3c57c56547 FileChecksum: SHA1: 69e5b5df2c44e8ca5131089bde3b10bb176e641d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/AbsTestImpl.hpp SPDXID: SPDXRef-ac0fa9abba905e00d7355a02f20cbab7 FileChecksum: SHA1: 5690b6ba5d48cd889d644eeb6af17d6d208d6d64 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ActivationTestImpl.cpp SPDXID: SPDXRef-dc6cf6fa5836182ac7739f145253c3d6 FileChecksum: SHA1: d2c002f84ba47ee56abf9c48b3d088838cc5df80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ActivationTestImpl.hpp SPDXID: SPDXRef-91f5132429a652e8ae91e32cec43e28c FileChecksum: SHA1: fd6cedc7b28f629e75e4c0e087abb63aaa5c283f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/AdditionTestImpl.cpp SPDXID: SPDXRef-319a657448660e29f97fafe0b5a1a4e9 FileChecksum: SHA1: 544e378c08f53acf0662c1deb96ac744e2b92e3b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/AdditionTestImpl.hpp SPDXID: SPDXRef-83be2ec870789f585d321cd56241a7f1 FileChecksum: SHA1: 5f2a065abb900dff7fc3fb96213f0d5fa072725e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.cpp SPDXID: SPDXRef-68f13c9248dbab47a6ca83d878aff372 FileChecksum: SHA1: d15a806576315aeae83913a9d46cd38ce78e5ecc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ArgMinMaxTestImpl.hpp SPDXID: SPDXRef-3469e99da6f6e230d5eee6481a65a065 FileChecksum: SHA1: f3b28158c154f2228d0a995581ece102275d3fb8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/BatchMatMulTestImpl.cpp SPDXID: SPDXRef-1cc8e42c125572b2aed2ea8176ce1232 FileChecksum: SHA1: 0f238ebf97d77a73b0b019f7a0e5f1ea9144ff1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/BatchMatMulTestImpl.hpp SPDXID: SPDXRef-01507161bf3b5e1ee73acfcd1664d31e FileChecksum: SHA1: 7415767312360f27cc155e18e9fdf922594086a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.cpp SPDXID: SPDXRef-2803628b54b40511aacb4a3bd4163946 FileChecksum: SHA1: eb9f6439fb1140e34b2e6319434e7d4c8ef14958 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/BatchNormalizationTestImpl.hpp SPDXID: SPDXRef-2d3a88686aa52195b8e5cadf3fe237eb FileChecksum: SHA1: 7d97a787ded02f38ce1400e847f1d75d97782361 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/BatchToSpaceNdTestImpl.hpp SPDXID: SPDXRef-8c878e776d05114dd7da6c20673198b8 FileChecksum: SHA1: e98cc6c47c0c7bce7a1433f6a7b7483dfe3d2f5f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/CastTestImpl.cpp SPDXID: SPDXRef-57bae1380132d1a0036b0683d9e9c409 FileChecksum: SHA1: 18c5959b1f35e2c75d386997afc5df37fa04b6f5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/CastTestImpl.hpp SPDXID: SPDXRef-e6656d25696c6b90606927736c3561b5 FileChecksum: SHA1: 15a634f8afc937631bd918681b0189beb853ffab LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.cpp SPDXID: SPDXRef-a6d23087347ea211b2035e9f1f6ef37e FileChecksum: SHA1: d44308c66f45e382cbefebb43d95aaa4f1abde25 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ChannelShuffleTestImpl.hpp SPDXID: SPDXRef-74f3a9258a4eb2759b97671f2b33c0f9 FileChecksum: SHA1: f7a909d4de749f1a75a78f740a2fa1766f79cd57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.cpp SPDXID: SPDXRef-974d006525d8ce53c004bd0508355fa1 FileChecksum: SHA1: dd6607ad083dfcd695639b74039ed158b365e482 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ComparisonTestImpl.hpp SPDXID: SPDXRef-75c573fd15f7ad159b3245d218415cbe FileChecksum: SHA1: 2fb42702e7d2552a0ad1d1adb3502ae03ab0c2ec LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConcatTestImpl.cpp SPDXID: SPDXRef-fdd67b5e016f98007f84e30b6e239e7f FileChecksum: SHA1: 8035612ca4f17834a583f421d5bc71284c78fb71 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConcatTestImpl.hpp SPDXID: SPDXRef-36b84c5f182e34566a03a8fae04a4e85 FileChecksum: SHA1: 120a6f9164590d97f4bca967a90796682a4ac423 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConstantTestImpl.cpp SPDXID: SPDXRef-e6140658206acdeb42f3001d443a90b0 FileChecksum: SHA1: faeba98ce2c4736ece19cbf0b792f5e303b0caff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConstantTestImpl.hpp SPDXID: SPDXRef-21a1313b3520189370a237dadc63bd28 FileChecksum: SHA1: 94ed2c6582b23390880dfe7b94f4174ff49e42c6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp SPDXID: SPDXRef-28e9de4d792d746ce6c63025d7acf51e FileChecksum: SHA1: a783d320c567a6a1afa868e9bf999b17cf523dca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.hpp SPDXID: SPDXRef-5672b240488dc6806451c92bf38261ae FileChecksum: SHA1: 6b588a0a64c702dc1e5a8ab53746de04b34ec87a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.cpp SPDXID: SPDXRef-66a3240a34c1177f67849a3ddc946950 FileChecksum: SHA1: c798e36fcc33c684c3d96852c60c3817a8c001de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Conv3dTestImpl.hpp SPDXID: SPDXRef-8a4b79abdb24d0aef680c77788783f06 FileChecksum: SHA1: dd614d8b221159c6e8623a7c4f40a8930f429c9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.cpp SPDXID: SPDXRef-e6ffe13a8e84128a992cc0adade430c7 FileChecksum: SHA1: 295b8edc1e6187cff9a6399034cc31028eac179d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertBf16ToFp32TestImpl.hpp SPDXID: SPDXRef-e2303bfb1aed6b6839b602ad574a88d8 FileChecksum: SHA1: a560e4866490e29a874edf5cb87a853928ac55da LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.cpp SPDXID: SPDXRef-df7171868a8214dec5e6ffe19b19490b FileChecksum: SHA1: 7c4cfc896b5ab6b577dc46b3d0ed515625708940 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp16ToFp32TestImpl.hpp SPDXID: SPDXRef-f2993d88b14e629e4e06430677310960 FileChecksum: SHA1: 67b396d0575d7666dad05e4734be8e6a5a9bae2c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.cpp SPDXID: SPDXRef-442001dbe522260b8b108186da733569 FileChecksum: SHA1: ac5652351a98289a8cff19d3bf40c998feffbc6a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp32ToBf16TestImpl.hpp SPDXID: SPDXRef-9cb4e1356b16a6c27af0baaf1078397a FileChecksum: SHA1: ad8f13a03af3e250ccb39fac097d1f9680518fdd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.cpp SPDXID: SPDXRef-aab70103d66041a1b6be7e773e7da801 FileChecksum: SHA1: b431146c7d14da9cd9630782becfee2472ddffbc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ConvertFp32ToFp16TestImpl.hpp SPDXID: SPDXRef-9a4d633884573140a373b063533162af FileChecksum: SHA1: f0eac8bfff1b20f62b19caae8d059955f7456291 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DebugTestImpl.cpp SPDXID: SPDXRef-511ab7ce85e73610ea3cdc120c82860a FileChecksum: SHA1: 286e7552a0e86c4624f448ee4192fc3ecb237846 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DebugTestImpl.hpp SPDXID: SPDXRef-1f4ded710fe84c45fe75c123fcc30b31 FileChecksum: SHA1: 74ca654275a08d3185bdd3be7bc140b87ea63034 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp SPDXID: SPDXRef-501ac7f8c89cbc085791b16bf0d6bd92 FileChecksum: SHA1: 62d27414fbc1fea336987f41c6384140fae159fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp SPDXID: SPDXRef-9b8003fc0a64ea17624d4cd21f86470a FileChecksum: SHA1: 58fa0f0b119e62cf928e9a2668ce23e67c4ad694 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.cpp SPDXID: SPDXRef-d45100252cefee0134370260ab1a5ca2 FileChecksum: SHA1: 953fedb88fe8918447de3096b3f561e4e76c3527 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DequantizeTestImpl.hpp SPDXID: SPDXRef-a43fb599e520c03e68739f5f79bfc993 FileChecksum: SHA1: 138ab9cb6e61fb173f8e41e3577a29fba37da638 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DetectionPostProcessTestImpl.hpp SPDXID: SPDXRef-86ce88ca6251283f34ba1ee3782fd798 FileChecksum: SHA1: dd7a20261446e69d66a2eaabc10909aa462f0dd7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DivisionTestImpl.cpp SPDXID: SPDXRef-f4210cd64cb11d1afc2a0c2897452f9e FileChecksum: SHA1: b27804e249a892f88a74d23f0371b2588af95f61 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/DivisionTestImpl.hpp SPDXID: SPDXRef-85906328eecf9fdabfc69acdd8216470 FileChecksum: SHA1: e8bf7d5c61cac20a1292c5f47403ebb846c65600 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ElementwiseTestImpl.hpp SPDXID: SPDXRef-82772f5a8b5be11eac906e12e4237b57 FileChecksum: SHA1: c0446d15ef59d610451a79389acf1011abfb8441 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.cpp SPDXID: SPDXRef-b88b0c48da1d6aba89d94ba308638e69 FileChecksum: SHA1: d7267533a782c3fc924b8e5efcbbc0dcda255491 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ElementwiseUnaryTestImpl.hpp SPDXID: SPDXRef-191c7251a9474ff5902c4e34262d4350 FileChecksum: SHA1: b841a431b0783685591ece4253a69bcb5babd18c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ExpTestImpl.cpp SPDXID: SPDXRef-1ddf24a462b56af37cf1cb0078d8bb42 FileChecksum: SHA1: 37edc64271a8a1c81fd0fc19fdb2e7c936208c8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ExpTestImpl.hpp SPDXID: SPDXRef-3e83c3481e1bcfa1f7f79a36f9e232fe FileChecksum: SHA1: ab67bfd702406fb87d6bcd6ba50bb7b0eed7d69f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.cpp SPDXID: SPDXRef-b24a2d113be2c68e4b66e88ac323c11c FileChecksum: SHA1: 1049289b1873a780b37aac008614867125c3b0cc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FakeQuantizationTestImpl.hpp SPDXID: SPDXRef-c44a92e039a38a36bfa267a90f6183d5 FileChecksum: SHA1: 9bffd7a46fa07dcbbb4486d476a8d6e64bc3f1ba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FillTestImpl.cpp SPDXID: SPDXRef-bf001dc0eae05b9da9c24ae56db4f440 FileChecksum: SHA1: 99fbb10d424107ec4143a4736ad417eed717af78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FillTestImpl.hpp SPDXID: SPDXRef-8be84bbc06f02a893a3545e653708b1e FileChecksum: SHA1: cd57f1b165cc64a94c0cc1cafa87d2b4bbeb12b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FloorTestImpl.cpp SPDXID: SPDXRef-1831b4525969d1d39de744756e27f9a4 FileChecksum: SHA1: 1824cfec2aba25e8e998066a3d1da1cc61830c80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FloorTestImpl.hpp SPDXID: SPDXRef-5e5b2328ec9979b354cd18edb1680784 FileChecksum: SHA1: 1623b35678db8023474c162af33c0bfc90429e8d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp SPDXID: SPDXRef-286087eee6282e0786f982aa8a7ff209 FileChecksum: SHA1: 1c139c752e4a9d240f931ce9545d2a4954efeccb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp SPDXID: SPDXRef-7bda5af556d935564e2ceacdcc37f6a5 FileChecksum: SHA1: 3daa4dfbc6f189f4bfffdcab4161b59c7501eaaa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/GatherNdTestImpl.cpp SPDXID: SPDXRef-fee2f7a4f92daa642b53b6288d96bfb0 FileChecksum: SHA1: c5506dfa95a7fdc51f38096c9219b4b58a8b41b4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/GatherNdTestImpl.hpp SPDXID: SPDXRef-1955cf1807e99d00b41e9702b03dd178 FileChecksum: SHA1: cdcdf8030e790dc56152a018364ccc10c519351f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/GatherTestImpl.cpp SPDXID: SPDXRef-960b06e2a90822f903e68ba37b9e0ae1 FileChecksum: SHA1: 1ac518877a6e29bc6453dd1304720dbacaf3350e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/GatherTestImpl.hpp SPDXID: SPDXRef-ac60a99c59d8c979c89137d68881b53e FileChecksum: SHA1: ccd4af77278490b80ff9f6593d598ae882b97278 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.cpp SPDXID: SPDXRef-981040ec422173e115e8af473f35dd67 FileChecksum: SHA1: e2c98130f7b33a04a3406c8f66291aa483bde23d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/InstanceNormalizationTestImpl.hpp SPDXID: SPDXRef-cf9a7063e604d206021629e6f06f1106 FileChecksum: SHA1: e8dad6b1a0c164e597695d507faf97ec7c3813d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.cpp SPDXID: SPDXRef-07bbd884dba8aac37afe644b79267461 FileChecksum: SHA1: 867e0011d5b76bb5ffff1e37d7a5f14b7d20e7d9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/L2NormalizationTestImpl.hpp SPDXID: SPDXRef-76960fd7f2bcd9044f6aa34751b9813f FileChecksum: SHA1: a7c622f20ca17bb106ab4e8b0936810a31b353c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LayerTestResult.hpp SPDXID: SPDXRef-08a85a0e1ad6c4d40234e62a5f344a2f FileChecksum: SHA1: c67305f621cdf3a8f59f8bb1c84be7cd5ac8983c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.cpp SPDXID: SPDXRef-1a9dd5b0350d0c7b8971f7a3512160d1 FileChecksum: SHA1: 097fea87d8d55163f17fba94ae4f73cc2b670429 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogSoftmaxTestImpl.hpp SPDXID: SPDXRef-15e7bd9a9d579dcbbb20d6d44537929c FileChecksum: SHA1: f047970e58c7ce9e1843c12416110efcc4d3d3fc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogTestImpl.cpp SPDXID: SPDXRef-f3442316f30dc2aa49a48f9e5cee5ce4 FileChecksum: SHA1: 4cd03842743c508a1a863a055f75380ddd00bba6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogTestImpl.hpp SPDXID: SPDXRef-3670e5aa24d403783dedd348f9754c03 FileChecksum: SHA1: 985fd37f1aa214362276b1786ca428333641c0da LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogicalTestImpl.cpp SPDXID: SPDXRef-7209aa2a921f71851cbde505f2f8ef45 FileChecksum: SHA1: 600eba3d59bdca6c12853d8570b9674843fd58b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LogicalTestImpl.hpp SPDXID: SPDXRef-d8df06019420ee0cd6b60ed3e06db2c3 FileChecksum: SHA1: c692fd430484d84368d504c119172808812f6a8a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LstmTestImpl.cpp SPDXID: SPDXRef-e81b80ec2500e234fd420be9a221f688 FileChecksum: SHA1: 6091f9019257cffdec488b8444455bd3a60bb03f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/LstmTestImpl.hpp SPDXID: SPDXRef-63eb0769b3a20557829572ce5d4ebe9a FileChecksum: SHA1: b7f99595d9f0101c475806029bdccf36c3c9ed26 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MaximumTestImpl.cpp SPDXID: SPDXRef-f227ebd1528c21c47177440c34ca8b3f FileChecksum: SHA1: 60abb0f1b8922e09ed238a8094aee8bf3ce0336d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MaximumTestImpl.hpp SPDXID: SPDXRef-af3bafdf283dcd3e84821f05998f68ad FileChecksum: SHA1: b5ed988e03644a316e3c58a09669f5ed0ed8e04a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MeanTestImpl.hpp SPDXID: SPDXRef-e4ba9afc4e794f8c7845fae882b7dddb FileChecksum: SHA1: 2adbce431630de69eaf9ab851fde83efbf788d9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MinimumTestImpl.cpp SPDXID: SPDXRef-e21f2e60af1090a99fd58da3f8eebe62 FileChecksum: SHA1: 3dc57bd6b367632f5f10d83e393a5c891d46eab8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MinimumTestImpl.hpp SPDXID: SPDXRef-edfb9135286981e74137c143fe4bfa8a FileChecksum: SHA1: 2ad0d8db477cb0e82cbb96bc16e1cfd85b25de82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.cpp SPDXID: SPDXRef-fc7624bad3019682bead6f05dc75a354 FileChecksum: SHA1: 6960a3b210c8177dce7038a829aa816a7b109064 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MirrorPadTestImpl.hpp SPDXID: SPDXRef-3c40670478fed97085eadabae1ea1433 FileChecksum: SHA1: e1ec656ca91aaf8e18069b87bacff84be968e15c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.cpp SPDXID: SPDXRef-709c09fdc0f525b21390c01ef2ed1d23 FileChecksum: SHA1: 92f1938abad34c5e571a58db1a26c1091a65d759 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/MultiplicationTestImpl.hpp SPDXID: SPDXRef-c8fbabdcac65e65e0043b2cd76d1c399 FileChecksum: SHA1: ab8a0f3512c41da589e673a90e06e24ee3c3b3bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/NegTestImpl.cpp SPDXID: SPDXRef-f244fbf943cbc383f129d30e1d7a53a0 FileChecksum: SHA1: 4073510366e7b5bcf10f84ce073aaa84a19834dc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/NegTestImpl.hpp SPDXID: SPDXRef-dadc004a2570aa5de7f6c83335e64a8a FileChecksum: SHA1: a6508e20fd20ac1bb14d23ab9ed70ae0f5d7e816 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.cpp SPDXID: SPDXRef-ac51a272d55770c8d518ab14be343070 FileChecksum: SHA1: 1378356b8747679f1196f10321d1ff50ded6f127 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/NormalizationTestImpl.hpp SPDXID: SPDXRef-6843182002a60ccf1a23effaa21702d6 FileChecksum: SHA1: d3500679b75265ab4c9c1115bd236b4cb031a2d5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/PadTestImpl.cpp SPDXID: SPDXRef-f28e0efab22d3ff9f7ca3a425b0c5959 FileChecksum: SHA1: f9156cd95390d77a6f7594495313d205f9317b48 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/PadTestImpl.hpp SPDXID: SPDXRef-906f340f4243d5a97b9424d015c13493 FileChecksum: SHA1: cc8b6722945f07405152d10afb4eca82c19a39e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/PermuteTestImpl.hpp SPDXID: SPDXRef-02a3679f2a8da502d644f99fdb96241a FileChecksum: SHA1: d52b27ae9d5b8eb587a9671aa264de40c1af4602 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.cpp SPDXID: SPDXRef-bd12bd47e530ee9a01ab7afa81c3d6b4 FileChecksum: SHA1: 86a38b18a3f2d97196af2dc99459689fed312ae5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Pooling2dTestImpl.hpp SPDXID: SPDXRef-62d2b181e2d8b178911eef6a10f4573f FileChecksum: SHA1: f9b7037b1e881b94ba276267fcf8e1789ac6ef16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.cpp SPDXID: SPDXRef-e90c90ab58f584c593f327f8248f7cbc FileChecksum: SHA1: a71077eb54ac0e40e50d3994dfa6589ae11a411c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/Pooling3dTestImpl.hpp SPDXID: SPDXRef-cd27b8a76eb83d9e8aca5f4c16b76e1a FileChecksum: SHA1: 59f188168cabd8f76b54d8287fbcc9c1b116d851 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/PreluTestImpl.hpp SPDXID: SPDXRef-56325ebfaa51cb5ddb4b12e84e35692b FileChecksum: SHA1: 6781f98de3953110e71cf5e0d3d73c4a8ff5d954 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.cpp SPDXID: SPDXRef-4d105cf8a5901e1e188a89956157ada9 FileChecksum: SHA1: 6303ee257b8c8be527e4d5e2a72f9f616ccbbf30 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/QuantizeTestImpl.hpp SPDXID: SPDXRef-89b880e01136e841d3fb2bbc37e5b88a FileChecksum: SHA1: af70e23a831046ad17489057491480a9da699a87 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/RankTestImpl.cpp SPDXID: SPDXRef-4a158c09058197e717e287fa21cd4675 FileChecksum: SHA1: 3e8529c10bb56092d7b5c0962004f027a20f4d37 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/RankTestImpl.hpp SPDXID: SPDXRef-b087be5b7c50f9fc8ee11dd81dd3e971 FileChecksum: SHA1: 410da70285cd86fe98ea07ea29ca30c346624538 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.cpp SPDXID: SPDXRef-2ffa86f2b39682ce217d39d18bd6e75e FileChecksum: SHA1: 2fa7c5b93b737b1fa44dce1012a944752e8bbfdc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReduceProdTestImpl.hpp SPDXID: SPDXRef-d06ebaaf09dceece9f3d5ba4ad78a751 FileChecksum: SHA1: 1447e5e490fd12e0cbddff8d6c8b551ac8d4b54b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.cpp SPDXID: SPDXRef-dc827d4dcbc2311bcc13ebfeb139eebf FileChecksum: SHA1: 390d091f7a41d71b51b80e326aae07d6defde77d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReduceSumTestImpl.hpp SPDXID: SPDXRef-6439c0e8e7178c0cbe25ff1f19eb1291 FileChecksum: SHA1: a823d9a92cc252cfe7d7bcf27a42733d93cc8191 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReductionTestImpl.cpp SPDXID: SPDXRef-9808ef0ac73cb13248dbb52ac4576435 FileChecksum: SHA1: ea880c9905cfe6427ab979b1269e5f94531f2f54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReductionTestImpl.hpp SPDXID: SPDXRef-f337e8ccdee4c74e760231ca2b777254 FileChecksum: SHA1: b7dc0a86896dfbf1a8f8603a37345943c44c3842 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.cpp SPDXID: SPDXRef-8064f2a2eddba2214314f497ec392dc9 FileChecksum: SHA1: df5e0d177aaa8e69ada04fce201bf4a98fbbcd27 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ReshapeTestImpl.hpp SPDXID: SPDXRef-6b1c9a715dbbfb02f4687518f29fe4e1 FileChecksum: SHA1: f68a54463d42e040d357bb9bcecbe43e66d66b89 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ResizeTestImpl.cpp SPDXID: SPDXRef-f1367b484912363cfc024a2db802b0d5 FileChecksum: SHA1: 4f61804257a2317a1605cd1c693113ed88f16f97 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ResizeTestImpl.hpp SPDXID: SPDXRef-9055769e7ec35f62b78614a2f1e7c5aa FileChecksum: SHA1: 8566bb6639710502fe8b3962c2f413b7de7decc5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.cpp SPDXID: SPDXRef-3acfe9cb2f07fbdc3844f24220026e3c FileChecksum: SHA1: c76b15bbdd9e8749b027ccac127b16c5bc33284a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/RsqrtTestImpl.hpp SPDXID: SPDXRef-deefec14f05575116cd8181f1b04f1fa FileChecksum: SHA1: 3bd275908337a8d7c3dcfe654eaaee6a65c21631 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ShapeTestImpl.cpp SPDXID: SPDXRef-7e8741c0413dbd73ca33ce65fdba97c6 FileChecksum: SHA1: 051620ede436132cf957bf9ed50645a7e50d7179 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/ShapeTestImpl.hpp SPDXID: SPDXRef-bc9a700f54b071512abdcc70724b8dd1 FileChecksum: SHA1: 5ec99cafdb31aeead1eecfea04e63b6ea89a10df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SinTestImpl.cpp SPDXID: SPDXRef-40c7edc949bb5bed038db1f2440f1045 FileChecksum: SHA1: 7f08ee088b1d26b62eb4d9cf7ef344a4174ccf91 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SinTestImpl.hpp SPDXID: SPDXRef-1aa921fd1b32c5b3b24c9793f41af4b8 FileChecksum: SHA1: 644dcb0cf3984ee995cd2e9fa5641a1e6149d335 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SliceTestImpl.cpp SPDXID: SPDXRef-1d0aa811fbab961676d547f930292406 FileChecksum: SHA1: 672f2a6cbe117792a5f8e061d341b319b9d6e00d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SliceTestImpl.hpp SPDXID: SPDXRef-3de6cd2855dc1e28cb85061b147e1bd1 FileChecksum: SHA1: 5571ac07545e9c06211148a83511ab40526147c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.cpp SPDXID: SPDXRef-d5f585a41fbaf802020069228afea3f5 FileChecksum: SHA1: 00582340c2e64e331e4459e189f1cab6fa4329b2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SoftmaxTestImpl.hpp SPDXID: SPDXRef-a20dc238eebfa9bd2d62d4aaed0468e7 FileChecksum: SHA1: e4e163e84c33f54d79f43c140be3be5660b57e41 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.cpp SPDXID: SPDXRef-f0478a40f7df77d9d3e136ee065452d7 FileChecksum: SHA1: 81421d4218fba8e72114724682cfa6c5d0146396 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SpaceToBatchNdTestImpl.hpp SPDXID: SPDXRef-33d506b84ef49ab757207210b039b056 FileChecksum: SHA1: 45ce319e4d7fb7566cdef79f9f0ed769bc2c7ff6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.cpp SPDXID: SPDXRef-e24ba104e9abfc872d6a8d51fe8427fb FileChecksum: SHA1: 37d974bb94969edbf8e6fc47f439c7b7b2612248 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SpaceToDepthTestImpl.hpp SPDXID: SPDXRef-03672273fcf2ea837ff9a8c6239e9e98 FileChecksum: SHA1: 1b4606fe953e7a5b1c80a79cf36cf7339e9fbd6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SplitterTestImpl.cpp SPDXID: SPDXRef-5b66eb0b83588981069db75532ac68d9 FileChecksum: SHA1: 54b563dc69005ed418fc0f5dd1c69ee8b9c0b4ef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SplitterTestImpl.hpp SPDXID: SPDXRef-c8129812d957cddb5a60af5e1496d395 FileChecksum: SHA1: b6901b56d0e5e40fd387576a729e45d207e900b0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SqrtTestImpl.cpp SPDXID: SPDXRef-4330fb886d09bbe474da0adc0b77ec5e FileChecksum: SHA1: ac1fbb2489805102771624e47cf7a27d400364d4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SqrtTestImpl.hpp SPDXID: SPDXRef-35ebef5feed9a0feb44687d834554a29 FileChecksum: SHA1: 51a3de4e5c43127cf671d5f3828745af49afca40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/StackTestImpl.cpp SPDXID: SPDXRef-7308e53c506912506b871ad8b3795e93 FileChecksum: SHA1: 6981e0dff5e2e7db05d22bd0bcb464bebc8866bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/StackTestImpl.hpp SPDXID: SPDXRef-b8d5091bccfcb1aaedbe1516bf395762 FileChecksum: SHA1: c3876599d87b0e1dd26dad228cb52da388fa7f27 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.cpp SPDXID: SPDXRef-05f1b03201606499def90274e8d91e3a FileChecksum: SHA1: ba87412431cadf13867c0954dc0540b6362b8e00 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/StridedSliceTestImpl.hpp SPDXID: SPDXRef-5c338b5843c961a8a68156a1b8993f56 FileChecksum: SHA1: fc693f386b2acd4947d13cf5ca5a4324e5300e36 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.cpp SPDXID: SPDXRef-85a06ff458a9f404b1bdb0e6a4f1c507 FileChecksum: SHA1: e2397ad046dc0e2bcc25287b0c56794beb773a06 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/SubtractionTestImpl.hpp SPDXID: SPDXRef-88816b64ea3c4a30204bcdd0f3f85bce FileChecksum: SHA1: 1c0293a8fdf6823c780fbc95eb4db043ce9ca668 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.cpp SPDXID: SPDXRef-7280269d2d0a2f6451954d6c35c992b1 FileChecksum: SHA1: fa4a2cbc554fda9abfc8c96b5b2591db16e6b521 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/TransposeConvolution2dTestImpl.hpp SPDXID: SPDXRef-e89e5a2078cab5d9704ff12e69881bda FileChecksum: SHA1: ea7c410fe147fab8981cb6f5e99b7a3efd826cf0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/TransposeTestImpl.hpp SPDXID: SPDXRef-f705cf3f98928eda7ff480b78dc432c6 FileChecksum: SHA1: f025a405120c0911684ff37ac15f18c9262d785d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.cpp SPDXID: SPDXRef-ee974d8c28319a1602bfbd50997a53f9 FileChecksum: SHA1: 6ee13678cc7cb101dfc7fd6f7bbbbec3ccd2639a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/layerTests/UnidirectionalSequenceLstmTestImpl.hpp SPDXID: SPDXRef-6ffc788557a8e34013d2359aa14548a5 FileChecksum: SHA1: a7623614b439f2150f1f2160f7055a0af663c3f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/mockBackend/MockImportBackend.cpp SPDXID: SPDXRef-74a48c511cabc08ba8723b0de68ade99 FileChecksum: SHA1: 710e58229c134b1af851588754a06aa862c601f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/mockBackend/MockImportBackend.hpp SPDXID: SPDXRef-60c0e605150ff45cdf34cbc1b279dcf7 FileChecksum: SHA1: 4a57cf70a0ac93f227f7d4815714dab161020f18 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/backendsCommon/test/mockBackend/MockImportLayerSupport.hpp SPDXID: SPDXRef-9b8b9f765e606ffeccfbf12ae76222f9 FileChecksum: SHA1: 5cb99aa2504418b279258a10715de47f22ef0230 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/CMakeLists.txt SPDXID: SPDXRef-2c09e379fc7d2d67bc511d7e9394e177 FileChecksum: SHA1: 9a130e730276de33bd6c5d8f5c0b94517ca47255 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackend.cpp SPDXID: SPDXRef-d725638e383a68522f9f5ec24a0bf9d9 FileChecksum: SHA1: a672306aee8efc1f0d2aca0f15acd3621320c7c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackend.hpp SPDXID: SPDXRef-2bb0ce05b8e2e00b95192bbbb1562ff8 FileChecksum: SHA1: a996298b039c1b25ee51db40222e05d9221ecdb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackendContext.cpp SPDXID: SPDXRef-8eaa905f99b3a6c18d15a4851000236d FileChecksum: SHA1: 9ed61bc47963a1f0cebcebfc03939e45b777f9ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackendContext.hpp SPDXID: SPDXRef-e563552e3286e1778f5122115cd17fe1 FileChecksum: SHA1: b0096143dd2f02f5ea2908ef60a64e0482d19ef2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackendDefaultAllocator.hpp SPDXID: SPDXRef-68eb7b72d6eec69c9515078b3326ed44 FileChecksum: SHA1: a5f774fb86be8895b78b98bba0e532ab87683f06 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClBackendId.hpp SPDXID: SPDXRef-d33d05a428ced7a75e357a545210eaee FileChecksum: SHA1: be1e3f58862f8263b29d8d37db52d122909403a1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClBackendModelContext.cpp SPDXID: SPDXRef-f349280a78bc35bf7b105bc5e4d6c4f8 FileChecksum: SHA1: 803046f785034344e3e08b58c8bf8ff27b90af9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClBackendModelContext.hpp SPDXID: SPDXRef-6ea510fee768f0f0b747eb8daacd08f0 FileChecksum: SHA1: 8f2f3fd4d9ba2075f6436224ead4cfca9fdaf999 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextControl.cpp SPDXID: SPDXRef-9e0aeb8c81dfe8514622b0e7040ed453 FileChecksum: SHA1: cbef5c67b2fd17de89f49ed7ae47f71700dd7cbe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClContextControl.hpp SPDXID: SPDXRef-1cd7c610d4ea616534e481be22913d41 FileChecksum: SHA1: 27f89add1028d6f12f1c042e470bb735f17bb33d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClContextDeserializer.cpp SPDXID: SPDXRef-cfc7483950e45f514a800cc09d1b74dd FileChecksum: SHA1: 302a1687c56518255e3496b0b8f946c0dffeddfc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextDeserializer.hpp SPDXID: SPDXRef-d765e0774088ea2284a2898fd1f1e1d7 FileChecksum: SHA1: 7111e946b8bd8b6df609c15af6078b4b1b098ec2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextSchema.fbs SPDXID: SPDXRef-54b6e817c3f0bbd72e7a27eb5fa337b3 FileChecksum: SHA1: fb630d71df1ff8001d6e3e959159c5fbdce96f93 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextSchema_generated.h SPDXID: SPDXRef-f953ac0559a0f836e605e18d521e2552 FileChecksum: SHA1: d07a98c74e2aa251133860b539675993103bbf97 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextSerializer.cpp SPDXID: SPDXRef-238bf9fcdae987ddbb23f44ace3af5f1 FileChecksum: SHA1: 98c203f8627390c2057a0612d66b61bd527b7e37 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClContextSerializer.hpp SPDXID: SPDXRef-5e38e3d66e83d77ebd056f4a5aa86ac5 FileChecksum: SHA1: dc3d93bdc044475b829246cbc79ba24e4013cfad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClImportTensorHandle.hpp SPDXID: SPDXRef-cf40a61fd07ded06e8f26ec18e697458 FileChecksum: SHA1: c232fa7d84bfed5e940305bbfbd09ebea7d5fb1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClImportTensorHandleFactory.cpp SPDXID: SPDXRef-025b7b87e703ed569328a4c391b8c4a4 FileChecksum: SHA1: 080c0826c6bb6aea39857dad8a3a4e5aa6e6236d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClImportTensorHandleFactory.hpp SPDXID: SPDXRef-370eb9ff35555564d09f6a0d250f29a4 FileChecksum: SHA1: 6e629c030bee65b0e79b5e545f64060a3c9379a8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClLayerSupport.cpp SPDXID: SPDXRef-18f21196bce0404da7790a7ea9295869 FileChecksum: SHA1: 81f38fbf06931a1bbd3aeab345f7e52706b63da1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClLayerSupport.hpp SPDXID: SPDXRef-0d87307f5f22224f635dac1352325d08 FileChecksum: SHA1: 98f4cc33efb1fed3c969e5f250af9f46079bd7cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClRegistryInitializer.cpp SPDXID: SPDXRef-397cb712b4d6b91b62257004ceba8ceb FileChecksum: SHA1: 3e7dd86fbfb8d3a5c66ebd99f34eb117df156802 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClTensorHandle.hpp SPDXID: SPDXRef-50234d937cd1c18c485b988e42d224b8 FileChecksum: SHA1: b3001d7362c9915e52b457917a53d9a680784f3a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClTensorHandleFactory.cpp SPDXID: SPDXRef-421e659e72ef4dd64ae488c0649a697f FileChecksum: SHA1: a79ded660997282391aa048051593183444ca27f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClTensorHandleFactory.hpp SPDXID: SPDXRef-56a0282471f9d61d223eb5792c51ccc4 FileChecksum: SHA1: 47ea0870ffde08e4cca67230824d79821ec32623 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/ClWorkloadFactory.cpp SPDXID: SPDXRef-3bbfa62f35882e177907c97e2f8b6f6e FileChecksum: SHA1: 9c8f6b698a5ca23a39365269e45a3469bc826fd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ClWorkloadFactory.hpp SPDXID: SPDXRef-cbe17ce4cf5b8dcba65f9386c3d01060 FileChecksum: SHA1: aaa9620b8687c510af93f8b9830e5402a7543dd2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/ICLTensorProxy.hpp SPDXID: SPDXRef-22c2c707ea760b872aaa374be72c3ced FileChecksum: SHA1: 1ff3062e61a58b2aaa36db9406a99b4fdc89e0d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/IClTensorHandle.hpp SPDXID: SPDXRef-a4fa9688aef4189ab92085544f9b3fa8 FileChecksum: SHA1: 3b8af372cacc0d45496c5c6ee0091c9e2b104ea2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/OpenClTimer.cpp SPDXID: SPDXRef-18a28150b4daa8edea8e512a30b8b9e0 FileChecksum: SHA1: 37569d73c5b934552925742a31193d833bce5c35 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/OpenClTimer.hpp SPDXID: SPDXRef-9883850baa6e90e5098d9f25130c9572 FileChecksum: SHA1: e00c7a89a304c44c6800e1e91b0fe1145c2f84cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/backend.cmake SPDXID: SPDXRef-fe036d2f616072acbb81c968efeae5eb FileChecksum: SHA1: 2e70c2fa30ba1fa5908448d745a324a297bbb157 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/backend.mk SPDXID: SPDXRef-dbfd5f6240435174c3f56249a6480e14 FileChecksum: SHA1: 28905a516d96ae3c3138d686b228cbee3b87c5a5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/CMakeLists.txt SPDXID: SPDXRef-00edbb27c19f5cd8a57ed3c662e855eb FileChecksum: SHA1: 804a7417dc1659565aa2329837854a4315111428 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClBackendTests.cpp SPDXID: SPDXRef-bf4368e76d4ee34d61252c108ebaad13 FileChecksum: SHA1: d8dac7ec5a0ec9dee1c8bfa1db59c71382c4b8e9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClContextControlFixture.hpp SPDXID: SPDXRef-4fc7c1f7dd984ee07027270c9e4b8dd3 FileChecksum: SHA1: f9a34bb44621f252e0d0b1b991cccb2c743256de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClContextSerializerTests.cpp SPDXID: SPDXRef-d975327a93bbc219da13a780d438fd46 FileChecksum: SHA1: 2801fc39754e185ff15f71cd7e20f018983bdd5f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClCreateWorkloadTests.cpp SPDXID: SPDXRef-4060b6174b022219ff97c9d7616575bb FileChecksum: SHA1: b84215733a1e34d7883c7784b00436c249867659 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClCustomAllocatorTests.cpp SPDXID: SPDXRef-d2a99d798bc7cc84fcb55506aeb16db2 FileChecksum: SHA1: bf2eff5f702af96a25bc16f82faae1bc31cfc653 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClEndToEndTests.cpp SPDXID: SPDXRef-49dc376254d4217a09c73dd41a1469ac FileChecksum: SHA1: 2431f7d89d95b6c514588025801f22835ef50067 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClFallbackTests.cpp SPDXID: SPDXRef-f92542c2d133684a2ef2205aab2b68d5 FileChecksum: SHA1: 5bc660a588535ea3599b8598b1a9b1cbded5162b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClImportTensorHandleFactoryTests.cpp SPDXID: SPDXRef-fe14bd44137b60fcbffc65f7eb25b41f FileChecksum: SHA1: f0c3b761bf6b11a329352985846b8a339cfaf9c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClImportTensorHandleTests.cpp SPDXID: SPDXRef-66ecd24ccba118d1c90003e49e11910d FileChecksum: SHA1: f45aa873d3c1a6ef0d4fe1d75da04adf2f7bed14 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClJsonPrinterTests.cpp SPDXID: SPDXRef-3a3a0406f0d843567aed179cf990365d FileChecksum: SHA1: 1050f44beebd02c30352b1db7e314d2225847311 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClLayerSupportTests.cpp SPDXID: SPDXRef-aa2b99601d0a9253dd525557732305e0 FileChecksum: SHA1: 75f5297bd993e1897c9305e244d107256ba27c16 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClLayerTests.cpp SPDXID: SPDXRef-155f1f02986401fc997311b9d57a6925 FileChecksum: SHA1: 83033977605a2e356f55b4115a507cd632ba5fc3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/ClMemCopyTests.cpp SPDXID: SPDXRef-e55030f79e244a5cccb3eb60ecb6994d FileChecksum: SHA1: 5e8fc7808375ad0f2bed18788078928e1ce80baa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClOptimizedNetworkTests.cpp SPDXID: SPDXRef-1cdb0673cda42d06b8ed83b8ea020ecb FileChecksum: SHA1: 87f57a77099dc4ac2a627ec49d5806073f154dce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClRuntimeTests.cpp SPDXID: SPDXRef-7215764cdd22a5f10f3f410aea4d76b6 FileChecksum: SHA1: 820391ccda7797a1a7c6f2a3fe1b96df8d7c84c9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ClWorkloadFactoryHelper.hpp SPDXID: SPDXRef-d4ff916e5066e50f78fb6ccef12b8fab FileChecksum: SHA1: 1a5575b1fec9db3d8ae3a29c12b301122ad1e7fe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/DefaultAllocatorTests.cpp SPDXID: SPDXRef-d0aeba32810c9982feb3996c84789d51 FileChecksum: SHA1: f7e89ee814903e8c4c8c3712ce230c14d10d42fe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/Fp16SupportTest.cpp SPDXID: SPDXRef-d1f9fa7152fa1d40de181f073a310e87 FileChecksum: SHA1: 1898ae446e74393b34a839bf3a31430e92b6bb25 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/test/ICLTensorProxyTests.cpp SPDXID: SPDXRef-afbe2ce2ea88769557a863d05f5e8388 FileChecksum: SHA1: 48d4bf5eb481bb6b5d2161e3002cd30eaca171b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/test/OpenClTimerTest.cpp SPDXID: SPDXRef-b6c3bc4a531741bbec547aa03cee971e FileChecksum: SHA1: 9e5f21c9af06cbb2f7e18514bf1740332be10d86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/workloads/CMakeLists.txt SPDXID: SPDXRef-1dc24a15097cc8fd54c0faf5c0e44227 FileChecksum: SHA1: ecfb4e2382200d72b40ff41836999db1c4851c2f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClAbsWorkload.cpp SPDXID: SPDXRef-77ea47c699c842d8c793389ed3dac535 FileChecksum: SHA1: 802627cf71a6494a2dee5516a6bf5a61efdb12d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClAbsWorkload.hpp SPDXID: SPDXRef-2afb33ad4faed6c383035a27bb5c6b19 FileChecksum: SHA1: 133c59c0eb4b3b433430b9323405d71eb93d0405 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClActivationWorkload.cpp SPDXID: SPDXRef-49d168d06b41f44947c2f6f6952b86a2 FileChecksum: SHA1: da7907745d0233583f912ef1c085d04a998da677 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClActivationWorkload.hpp SPDXID: SPDXRef-25f350006b3a3c56fbf62c537f9c27fe FileChecksum: SHA1: 36a8fc48aea84183514b9c7a256333efde871337 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClAdditionWorkload.cpp SPDXID: SPDXRef-b04213afa81574872ef77209dad46596 FileChecksum: SHA1: 7e45b66c867d5011d9ca27df5cdeb145f694d1e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/cl/workloads/ClAdditionWorkload.hpp SPDXID: SPDXRef-b7765aa1c7161cf703fe413cc3b88e00 FileChecksum: SHA1: e258aa11bdcde15903565ddee914c3b9a7081edd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClArgMinMaxWorkload.cpp SPDXID: SPDXRef-725877209134c96688c4edf384f289a5 FileChecksum: SHA1: 3822dea134a00acb7fdf7ae9283924895a31518d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClArgMinMaxWorkload.hpp SPDXID: SPDXRef-c7345a20f5097690e1ba7804efcc966c FileChecksum: SHA1: cf9f22f749ef5066dc123598f17918a9dcaeb711 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClBaseWorkload.hpp SPDXID: SPDXRef-28a6dd1d713a3093dcaec8fc5780d9fd FileChecksum: SHA1: 9cf49e929c169bf54f672be1f209d3320fa556ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClBatchNormalizationFloatWorkload.cpp SPDXID: SPDXRef-83f8de2bb3ac2180d56538b78587789d FileChecksum: SHA1: 503d069b1f5c08d2f607d1bb11afa747584abead LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClBatchNormalizationFloatWorkload.hpp SPDXID: SPDXRef-c7b702a25e71e801552f193d0bfdca8a FileChecksum: SHA1: c86a4f33cd3598f984d2c7cd90b1bdb056ccd746 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClBatchToSpaceNdWorkload.cpp SPDXID: SPDXRef-99b2917d5af60a5af769496051d7ab5f FileChecksum: SHA1: 5fa6795d13f9de1fa0302ae2f5a4a6bc13c2991a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClBatchToSpaceNdWorkload.hpp SPDXID: SPDXRef-7e1688218548451876a9e361c5098d4c FileChecksum: SHA1: 4467af754862ac1686d39f558410bde029aed933 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClCastWorkload.cpp SPDXID: SPDXRef-261a7603addae4a871dd524f096e3cc8 FileChecksum: SHA1: ab13647136aad23e5c5f17f1c6165b4a78797321 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClCastWorkload.hpp SPDXID: SPDXRef-07252b31cd16e981a89837fbfefa3bdb FileChecksum: SHA1: b166a2ddbb30605624070a6ff1dfefb43e88cb87 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClChannelShuffleWorkload.cpp SPDXID: SPDXRef-f6a0f065f968c2e70a7b9e40313a40c1 FileChecksum: SHA1: e6242cfe159316a59f6b7345197d97bcb03adc2c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClChannelShuffleWorkload.hpp SPDXID: SPDXRef-501a34f1d2abf903069dda7f59619668 FileChecksum: SHA1: 0762ee315cb7f716afa8248bca0c096aee5505d5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClComparisonWorkload.cpp SPDXID: SPDXRef-179897d6270100da605a4855a046ac01 FileChecksum: SHA1: 8c0cb1586b320182280bfcc853d54e020fcd9976 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClComparisonWorkload.hpp SPDXID: SPDXRef-6d12e02af8ad4343a35111ae9da80f13 FileChecksum: SHA1: 4c4c737d530a1f5ed9750da867798b77c4851156 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConcatWorkload.cpp SPDXID: SPDXRef-b91579b39170cdea0bf515a6ad3adbfc FileChecksum: SHA1: 5d24e29e06e0bfd7367395a8adff19584f6179e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConcatWorkload.hpp SPDXID: SPDXRef-481123e480df12b561a9d758eb215354 FileChecksum: SHA1: 420947a63a7b1a4255f82f2dbea5c6972e3a0ec8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConstantWorkload.cpp SPDXID: SPDXRef-d33bbdebf4d312750fde24fc43e35b12 FileChecksum: SHA1: 8a871e3927cadb416d5cf383a3c5463d583c5023 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConstantWorkload.hpp SPDXID: SPDXRef-b0b015f33756bcc6ef882643c2483620 FileChecksum: SHA1: f4867ea39207da1eb1f211e401d3451080323bb9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvertFp16ToFp32Workload.cpp SPDXID: SPDXRef-8a6b5db59a20b1fd6c75e4d74d34aaa0 FileChecksum: SHA1: 9dc049123bedd9d0c9449ac3dccaa0703309f7e0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvertFp16ToFp32Workload.hpp SPDXID: SPDXRef-940593ba19731ddccfc83be6bb493b92 FileChecksum: SHA1: 86d47ab222b6bb7dfbf94180d2b0dc7210afeae4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvertFp32ToFp16Workload.cpp SPDXID: SPDXRef-8477db727a7d8d3a12af53a8a5f473b4 FileChecksum: SHA1: eb9b8a66550d493b1816a007706208184937c53c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvertFp32ToFp16Workload.hpp SPDXID: SPDXRef-4147b063229cda8c46b2af147fdc00a2 FileChecksum: SHA1: 2ab0e48863ed907aa442100a4594ccaea2327a03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvolution2dWorkload.cpp SPDXID: SPDXRef-974ad148f2210d42842f7e3b4235126d FileChecksum: SHA1: 25508fef2d49b679da8421bc61271e1b547646f6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvolution2dWorkload.hpp SPDXID: SPDXRef-6759060b10d5e7330fd50c31a409595e FileChecksum: SHA1: 5bfda9e54bc1be17c56a37cf88671d23ddce1cb1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvolution3dWorkload.cpp SPDXID: SPDXRef-67cb844f9b31e1c6e0f24e3637a35fe0 FileChecksum: SHA1: e735d02d6cbf1f1d056df5fcfb878c9d5d832daf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClConvolution3dWorkload.hpp SPDXID: SPDXRef-dbfc395f61c09626bf7cdac3066169e4 FileChecksum: SHA1: 0e511dda4c33420682a358d7e5c59bac4bdae0ba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDepthToSpaceWorkload.cpp SPDXID: SPDXRef-32f080b3db8033925500641ef21f6f4d FileChecksum: SHA1: 31d73c055a5e8deeefd38d10aed07f3b3d519102 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDepthToSpaceWorkload.hpp SPDXID: SPDXRef-7adc4938c0254c5eb0fa35011ac9f43d FileChecksum: SHA1: 8d4b4f0badb059e10ef4b01c882f978d7febf23c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp SPDXID: SPDXRef-e49c33369449f7c6f87cf7e9fbaef629 FileChecksum: SHA1: ed378990011e1d1d42a66bf0cc024a0556a75577 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.hpp SPDXID: SPDXRef-facc77d7c39be1a31eedeff3775967c2 FileChecksum: SHA1: aec6e021bb2e4251c6202054eff845228ca56cca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDequantizeWorkload.cpp SPDXID: SPDXRef-a1b5133cd094ed723df05c955abfa416 FileChecksum: SHA1: 1b50cd3050b2557371638a2c9e6d42960dcdcf3b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDequantizeWorkload.hpp SPDXID: SPDXRef-0093cb09fe19314a3a8418578f10011a FileChecksum: SHA1: d7aef3cc6ebe66715cacce1033dfd20b39d27bcd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDivisionWorkload.cpp SPDXID: SPDXRef-246f77b1dde2189b86db9858d67b9c42 FileChecksum: SHA1: df959390a9f1523447ca5d15691c65a7175a0b63 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClDivisionWorkload.hpp SPDXID: SPDXRef-0a47c2b3f0446894e5a5cfe1b2d60434 FileChecksum: SHA1: 7386ad33cf921fc7a5765c926bf606d8bb9aa7e2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClExpWorkload.cpp SPDXID: SPDXRef-868aaf203860f118c643129f4109c6cb FileChecksum: SHA1: 9ca05e3abf20b5aa72b4412baf2436145e247292 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClExpWorkload.hpp SPDXID: SPDXRef-176120ae47c8ccbb29ce76ac9559b346 FileChecksum: SHA1: 2c6607a3d541245f8abbbba6613371e4a346d718 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFillWorkload.cpp SPDXID: SPDXRef-16fe6f11fbcb92c5a4410cbdf0610b0f FileChecksum: SHA1: 4a085f2ba52606e94f0ce248763474b6949f5dc3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFillWorkload.hpp SPDXID: SPDXRef-e1388d9fd73258b43791dd2a7418b361 FileChecksum: SHA1: cfa0da4fa08db168f630359b16cc7843162a8431 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFloorFloatWorkload.cpp SPDXID: SPDXRef-1ce7d9650cbeaaf61b93ed5b23a73656 FileChecksum: SHA1: d355d6eb1055b65a73da742585064d16529e7500 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFloorFloatWorkload.hpp SPDXID: SPDXRef-1104be30a12d4d3b6120ae626392c7b5 FileChecksum: SHA1: 42462b3947196862f2624cdeaef69b590ee99e63 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFullyConnectedWorkload.cpp SPDXID: SPDXRef-3d60e7c41576398cf0e39b77621a0581 FileChecksum: SHA1: 7cf50708c52536c7a4caf9051722e92be9f78bb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClFullyConnectedWorkload.hpp SPDXID: SPDXRef-e62e205d295f5d7afb3c216fdb63bca0 FileChecksum: SHA1: 4aa68d6b7b08651185aa558cde4c79d5ff1d92c0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClGatherNdWorkload.cpp SPDXID: SPDXRef-4e4bb3566a6d91170f6572758c801a21 FileChecksum: SHA1: 514ab5de8f740a461334fb162a693ea14ec5aa26 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClGatherNdWorkload.hpp SPDXID: SPDXRef-5d165426a220201c677af63f1735adb6 FileChecksum: SHA1: afefc589255b08ed4d847e8cfaee33067753bd57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClGatherWorkload.cpp SPDXID: SPDXRef-ec8e37b8d6d76471aff8c2d4756663dd FileChecksum: SHA1: 9cd207d48dd3c2b19b428711ff2124e75e864d76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClGatherWorkload.hpp SPDXID: SPDXRef-759c1bb1f1e19df20a5e7a71685bd3de FileChecksum: SHA1: 722baf0aed020dbb94dcbe5216ae29a29ed00cd6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClInstanceNormalizationWorkload.cpp SPDXID: SPDXRef-8efd92cedb5c004f26f02a979266d35b FileChecksum: SHA1: 570d16aba5f121b250b6af8aa5494a522666e9d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClInstanceNormalizationWorkload.hpp SPDXID: SPDXRef-772e19718e96a5e630d3e10371f18664 FileChecksum: SHA1: a0b09b6eb75301208f7bc3335f2e8f57d1bc8806 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClL2NormalizationFloatWorkload.cpp SPDXID: SPDXRef-5ede1879524d5f833b04ac625761ea79 FileChecksum: SHA1: eecee8a420069b7f5e964cdf1c2504e43371daa6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClL2NormalizationFloatWorkload.hpp SPDXID: SPDXRef-132fa788f3cf5d631e6557dc630204a5 FileChecksum: SHA1: ecd5caefb879d9fd74028284f4767b433a706615 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogSoftmaxWorkload.cpp SPDXID: SPDXRef-86b5c91acba34d3c58b77044a1405708 FileChecksum: SHA1: 6a8641fa55bf039f9a4c89ac63c4f86866a74c56 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogSoftmaxWorkload.hpp SPDXID: SPDXRef-87686c631b3a8bcade1c88817b1dbbcc FileChecksum: SHA1: 8afb4df1dbe7770c5f377cb8a404a382a0558f9a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogWorkload.cpp SPDXID: SPDXRef-aef137f39fc8832e526f08c17127db51 FileChecksum: SHA1: 3d34be71f0ac5fd3992a4ad62435a7977f4d3000 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogWorkload.hpp SPDXID: SPDXRef-61aff72d8670bf654ca9a70dca6b3e0e FileChecksum: SHA1: 4bb83bc34d8a76ef611c74cc92309c3dd1bd6d18 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalAndWorkload.cpp SPDXID: SPDXRef-993947b01b3bbc3c7f3a94c6843b20cf FileChecksum: SHA1: 50e5f03f006ac18a160a05b58a376bd12483c0c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalAndWorkload.hpp SPDXID: SPDXRef-7bc0b4954ba40a0253c04c417fcddd14 FileChecksum: SHA1: f9dd6dd1b872db1520626cf2fe1465a5146dd630 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalNotWorkload.cpp SPDXID: SPDXRef-916fc558cf14bd91a03c46f0fd30de0b FileChecksum: SHA1: 7bc91c45f3f5d0ec9967120c41498afc60eb658f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalNotWorkload.hpp SPDXID: SPDXRef-170612e9c908a0827d402b02a084b4b8 FileChecksum: SHA1: 75914c09bfe751423f134867c29ff6d9ebe87c63 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalOrWorkload.cpp SPDXID: SPDXRef-588cc32456ee820f5b1ada0a346acf86 FileChecksum: SHA1: 162ba961c724ea88653d88fd60e070c3be9daed4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLogicalOrWorkload.hpp SPDXID: SPDXRef-31094b49ed0ab90075830f94369d0e06 FileChecksum: SHA1: 1e655f50912d0208a7dca703a777c7655a6b6939 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLstmFloatWorkload.cpp SPDXID: SPDXRef-8c7c27ec14ce9fa19c1726aa7a025818 FileChecksum: SHA1: 83a35e781953a8d0ccc83a74a692e7893a31b175 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClLstmFloatWorkload.hpp SPDXID: SPDXRef-5f2a56ab2d108c68c24ea72853c24128 FileChecksum: SHA1: 15df4bf45b93a8bdb9e197b8352517789d95df1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMaximumWorkload.cpp SPDXID: SPDXRef-aaaee1d9978b314c3aacdb37a72ed886 FileChecksum: SHA1: f491a274d61f7ab73382784710e53fcb6b01a02b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMaximumWorkload.hpp SPDXID: SPDXRef-cc3658e2e60ae8b9929c7e3954e6fa83 FileChecksum: SHA1: e10da5181803674fcace5346d3db52a3227cf896 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMeanWorkload.cpp SPDXID: SPDXRef-fa3d29d94fc327628225f85f70f2ec0b FileChecksum: SHA1: ed1e980721745299896503ef512d3687f05142af LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMeanWorkload.hpp SPDXID: SPDXRef-1a59f0b912c66832cdec44f51c90fae4 FileChecksum: SHA1: 24de74360b0f2ff49bd8c28fe6d505ac8483de53 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMinimumWorkload.cpp SPDXID: SPDXRef-816b08ee2ebef39b11ae9f069ff803e7 FileChecksum: SHA1: 3f5f08316cc298c8d7cdfad13701c3e999b3acef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMinimumWorkload.hpp SPDXID: SPDXRef-61a4dfc649dcf71b94eb70f2d7b8b4e2 FileChecksum: SHA1: e6d3b39d892a495c1467f7694ae7bf3f5272e40e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMultiplicationWorkload.cpp SPDXID: SPDXRef-d37929f3e0b2abcda6a8180ccbcb2b66 FileChecksum: SHA1: 5bd52d18a8aecaed1a1f3498e649c5d77bc26942 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClMultiplicationWorkload.hpp SPDXID: SPDXRef-d1a2648b90fd1f428e4c047b232d2d43 FileChecksum: SHA1: 0bbd539397e6bd2a2e532a623f69b46d6b6efc66 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClNegWorkload.cpp SPDXID: SPDXRef-5e3d3e0218869b1ea76a326f97071a32 FileChecksum: SHA1: 837519a49092445ed9f1fd482e7907aead398abc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClNegWorkload.hpp SPDXID: SPDXRef-496dce594d5abd765cbdbf66a8336477 FileChecksum: SHA1: f1baad8ca9b87d8307e174179db82842e4e54ef9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClNormalizationFloatWorkload.cpp SPDXID: SPDXRef-0e1bb1a0d986e9d15d9ac5aea36e60e6 FileChecksum: SHA1: d646397325bd2844565478a49cd4af87f65b62e1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClNormalizationFloatWorkload.hpp SPDXID: SPDXRef-f0feb3eceb043b614fe70821eadf3e9f FileChecksum: SHA1: 75db34b513f2d3b98eb1c357ccb75e7b68a34f2a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPadWorkload.cpp SPDXID: SPDXRef-6050934de9c83db00916e56c36670fd8 FileChecksum: SHA1: fee98cb272ec3e177b373669304df8724a0ff583 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPadWorkload.hpp SPDXID: SPDXRef-fa8037dc46e168a95e0818bf06436a09 FileChecksum: SHA1: 3822db1d28758b46fbc02992e5223d88f6598d10 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPermuteWorkload.cpp SPDXID: SPDXRef-4f7bdc199c7c4ed778415f5927f88f67 FileChecksum: SHA1: d0947674bb44300f549d24cf762c11675e1c2eb2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPermuteWorkload.hpp SPDXID: SPDXRef-36d7a070b6ded647a9db66fe768cb9ec FileChecksum: SHA1: 3d81b6e78b0524bb6e83f0358b2807d721170bf2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPooling2dWorkload.cpp SPDXID: SPDXRef-42de95307399437b22525510a838b471 FileChecksum: SHA1: 5974855e746d7d6a68c4c4e1b14fcb65c92233b6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPooling2dWorkload.hpp SPDXID: SPDXRef-2c94e9536fc5c0536fe01ccb31206b94 FileChecksum: SHA1: b366990e75ae528b525ecfaa2067cae328590437 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPooling3dWorkload.cpp SPDXID: SPDXRef-b7729d890052be88c46b19081eaae60d FileChecksum: SHA1: 851e5473e43142da2a75278f10a207b5f09e8b7d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPooling3dWorkload.hpp SPDXID: SPDXRef-a27f0148e1057b25ebd7e2d9249e6997 FileChecksum: SHA1: 22723d470bb6d60a4c21959834b497231aee12d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPreluWorkload.cpp SPDXID: SPDXRef-cc03bc5fe8e4172c15f03ff9074a0764 FileChecksum: SHA1: 45d3339fbf1877bc8ddad5c56239bed3ec65d20c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClPreluWorkload.hpp SPDXID: SPDXRef-1c0d52d74490013e0693021701fa2c3b FileChecksum: SHA1: af2d01fa40a27c93ba8fc259de89277fc43c55d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQLstmWorkload.cpp SPDXID: SPDXRef-a1c6ae748fd92d788a18c0b67a3155f9 FileChecksum: SHA1: eef08482b26f8a1e78f768bd761875ae9d4ac621 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQLstmWorkload.hpp SPDXID: SPDXRef-87a5546851086483207fc660f3954025 FileChecksum: SHA1: c415663ed825e4a5c9c37a5155bfbb6c115f1d05 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQuantizeWorkload.cpp SPDXID: SPDXRef-163f455ff65dba069b1717ae5592efc7 FileChecksum: SHA1: e4d31ad25bd77ae6604707e493ea73881d0d54ff LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQuantizeWorkload.hpp SPDXID: SPDXRef-0afbda35e04428429da6f44e269db6fb FileChecksum: SHA1: a1fa5e9376c72c0926baa28902d5aa8a0691e61b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQuantizedLstmWorkload.cpp SPDXID: SPDXRef-38cf061cdb375da018f3b95467f72d45 FileChecksum: SHA1: 21acbf86ede7847c3da0a352906f8f96d44e36a2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClQuantizedLstmWorkload.hpp SPDXID: SPDXRef-c0bc90f6965cb772bf5c422707a11754 FileChecksum: SHA1: 1ae356977500f777a602c736069f26f9dbe07f0d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClRankWorkload.hpp SPDXID: SPDXRef-8cad0a2ee2ce18218056622cd134c88d FileChecksum: SHA1: 9c70f0392970b9882b169a92b9f15808ad373e58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClReduceWorkload.cpp SPDXID: SPDXRef-135b581cbee4d7043c12cd1a6ce10e11 FileChecksum: SHA1: 9bf085e23c8a3da2572cb535c5326b99cbdc432d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClReduceWorkload.hpp SPDXID: SPDXRef-c0e8588426dace1774e513dccc634d89 FileChecksum: SHA1: cf19fee355392cdacc1c9e72ec80aa1474edcc27 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClReshapeWorkload.cpp SPDXID: SPDXRef-08c1a45a356f67644e2696e1ae245cbb FileChecksum: SHA1: cd04828c52b5146975c9635dbd53888e691773c3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClReshapeWorkload.hpp SPDXID: SPDXRef-bec64b4847fdbdddf85a55927f8b1681 FileChecksum: SHA1: d0f7d6b17ef0395a5cce5ea38c1e952ff1d30d46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClResizeWorkload.cpp SPDXID: SPDXRef-8acb259e83d72eaa2cf6af613f310fbf FileChecksum: SHA1: 9180b25517ad4f28fe0dd5dd8af3e0917c91a6a8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClResizeWorkload.hpp SPDXID: SPDXRef-01fa86e1b5f4ad955fb02dc3b4482bf2 FileChecksum: SHA1: 6d6e86d2121ae7c9837c3c428dd5955cc2b0aeea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClRsqrtWorkload.cpp SPDXID: SPDXRef-3bf7e95d3b7c09df696c4e60bdb85abf FileChecksum: SHA1: 6464559a6b11c6186c725ebff0b57a5dcdbe030a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClRsqrtWorkload.hpp SPDXID: SPDXRef-a45568e09138f703af19299cf8c3f5aa FileChecksum: SHA1: f1723ace6fba5c2deda3688c7431e5ee0f8f35cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSinWorkload.cpp SPDXID: SPDXRef-d53aef9215450fcc88029c9c65525a42 FileChecksum: SHA1: 830bde3f500640f03a7439e745f8be0a0aa4abaf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSinWorkload.hpp SPDXID: SPDXRef-8a5e09642951660713357fbfc92fc206 FileChecksum: SHA1: 056c1fd8f821fa3f9ba09f66b367467d26249338 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSliceWorkload.cpp SPDXID: SPDXRef-292f0be3f8d3ecb9c18317be40d5056f FileChecksum: SHA1: e5942013eb133e6d82568da399c85657768251a6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSliceWorkload.hpp SPDXID: SPDXRef-c772772e57dd1450a26e02e4d7d303e4 FileChecksum: SHA1: 650aa3a70505cb8cd3c5e23cdaf774b6958c6b82 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSoftmaxWorkload.cpp SPDXID: SPDXRef-348d239afec4fb2c8749204c6fe6e3f7 FileChecksum: SHA1: 5ca742c27d14a3fe1c4036d947ee255974d09f58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSoftmaxWorkload.hpp SPDXID: SPDXRef-3a019ad5530a961ef353462ccb057a1d FileChecksum: SHA1: fae3683ff87586a63449ed27c77241a6d3a27c0f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSpaceToBatchNdWorkload.cpp SPDXID: SPDXRef-4796bf0552a6b5f602ec580e5ff6d68a FileChecksum: SHA1: 644088f486bd270b74b79f941d396b15094e004d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSpaceToBatchNdWorkload.hpp SPDXID: SPDXRef-f79077ad83d917d48b7c2897153a1cfe FileChecksum: SHA1: ac40da534e6693f0f065869283eab7b062f16a66 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSpaceToDepthWorkload.cpp SPDXID: SPDXRef-770a36b3831d9d1b345847b1f22282c1 FileChecksum: SHA1: 6a207a03a45a2897c3e0141da9bf5613b618fdd6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSpaceToDepthWorkload.hpp SPDXID: SPDXRef-3240ccd168e59f0508f448c4faf3408e FileChecksum: SHA1: 3db46373aab48c7f7a187aa70809a1195b2b1e57 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSplitterWorkload.cpp SPDXID: SPDXRef-9e641abe49d8d87018a2470544c60399 FileChecksum: SHA1: b544be77fbd2201e73bfb2f10b27f60766e30502 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSplitterWorkload.hpp SPDXID: SPDXRef-d89a25c9011d1686d5ae4a8bc66a8dac FileChecksum: SHA1: 55c86fc65693d928045ee07c6b84f98a71c7d505 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSqrtWorkload.cpp SPDXID: SPDXRef-6f7b50ed105ca9a9547596dfbaff2bd1 FileChecksum: SHA1: bc8a31f2ec013482e33b15d49e9f536f1bd2e472 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSqrtWorkload.hpp SPDXID: SPDXRef-f85e1c5b675851c15845c8362b3e61ec FileChecksum: SHA1: e17fe31b0ad27f7813dccf53835bf353fe01a6ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClStackWorkload.cpp SPDXID: SPDXRef-c3cb109813b52deea8527ffb4deb6a59 FileChecksum: SHA1: eda204c8406160ac126a33e9b65a4354f166c0ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClStackWorkload.hpp SPDXID: SPDXRef-961bd79fb7c72a61ae53f4ed6a16da77 FileChecksum: SHA1: b2f46738d8d1ea9321191c6d1ff8cc8c9c91187d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClStridedSliceWorkload.cpp SPDXID: SPDXRef-c8436eedce60ea344b31fcd6083bff42 FileChecksum: SHA1: 23b5a6b70982af91ca71f36bfc60d631bc8a8d44 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClStridedSliceWorkload.hpp SPDXID: SPDXRef-254e2517067aeda2cc635513ae3641d4 FileChecksum: SHA1: f2f4980a7a91f81f052ef437a8cd11a8e6528c46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSubtractionWorkload.cpp SPDXID: SPDXRef-51ef8cd4bffa38fe35d4b6c59d18bd05 FileChecksum: SHA1: 4e6821b38d3fd6ab1181043cca875466c4b92f5b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClSubtractionWorkload.hpp SPDXID: SPDXRef-b382c3415279a02e3ac655a81f56bfc9 FileChecksum: SHA1: c550b80b84e08cb7e451581c96bf7d4504db816c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClTransposeConvolution2dWorkload.cpp SPDXID: SPDXRef-1a2421ae34c48ce704554bbc2bb7f8c2 FileChecksum: SHA1: 1002141bded49b9f018d5f272d64f11e5f0f3e55 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClTransposeConvolution2dWorkload.hpp SPDXID: SPDXRef-5e914b34d9c43edec151919397f54d49 FileChecksum: SHA1: 3e5ce8fb1eb415446e2692cda1669b686059f0ee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClTransposeWorkload.cpp SPDXID: SPDXRef-d9752b38155a853e2076bdeab95e9885 FileChecksum: SHA1: b8286e60dad00448c3efe2761f0a02dae8a1055b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClTransposeWorkload.hpp SPDXID: SPDXRef-1b43d6ef49ebe3e9b5155650f4241699 FileChecksum: SHA1: 0f8f750b24f5db2e2719d23a1af5bb3d2320d8ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClUnidirectionalSequenceLstmFloatWorkload.cpp SPDXID: SPDXRef-17a1f02ee5e72f0caff5d7838e71e21b FileChecksum: SHA1: 795255ed264964dcbf0cb7050db3c665d1ce0dd7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClUnidirectionalSequenceLstmFloatWorkload.hpp SPDXID: SPDXRef-16f970f0651be48f50c731f4eca938ea FileChecksum: SHA1: 309509cd06095a5e37175ae7fff6b979a21e22f1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClWorkloadUtils.hpp SPDXID: SPDXRef-62e6d0e251f3f606e3c199d8ff872121 FileChecksum: SHA1: 7e83dc751c2d29cd34d706f778c0df9acf295743 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/cl/workloads/ClWorkloads.hpp SPDXID: SPDXRef-f7992df4051d894bd286f0906ccab219 FileChecksum: SHA1: 63f21550f4cb43fed280624078e3fd314f92f1df LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/dynamic/reference/CMakeLists.txt SPDXID: SPDXRef-f2edbc89596d0b1027ea2e562d62bb16 FileChecksum: SHA1: 6ae61f9c4028e981b21b070eba589d8d0ae6fd9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/dynamic/reference/RefDynamicBackend.cpp SPDXID: SPDXRef-a44ddd2c2c0d8515d384692bfb30505d FileChecksum: SHA1: 3714f3607f4c7d7d77cfc164c102c1b54b3a73a4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/dynamic/reference/RefDynamicBackend.hpp SPDXID: SPDXRef-bf272d7bcfef0a51971b61cc1e678af4 FileChecksum: SHA1: 182dc224f37552926bb90de4ab3ee63cb802568e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/CMakeLists.txt SPDXID: SPDXRef-c53f0b2a895db52d35f118ec8d140a77 FileChecksum: SHA1: 4f88db0e567982f12b85fc7d57b83f8dc6bb8b78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonBackend.cpp SPDXID: SPDXRef-e55d342ef9d0ac9ecdd787fcb92fe644 FileChecksum: SHA1: fe3a70514d114e13a2e5b8f0b5cec6de000d2f78 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonBackend.hpp SPDXID: SPDXRef-a894a646b47aba55eabe27855e8c7443 FileChecksum: SHA1: 062f093836bee4aeefa10660fd2791eaeaec8b7b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonBackendId.hpp SPDXID: SPDXRef-80877ad90f7706b5843137967f85cbad FileChecksum: SHA1: 32642b045bc4a8b3d9bd1a2207e5abf1eec133e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonBackendModelContext.cpp SPDXID: SPDXRef-aa5425403601563dd60509153424f430 FileChecksum: SHA1: 954816b3fa1959f0db21632758f6b2f9890a872b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/NeonBackendModelContext.hpp SPDXID: SPDXRef-9b2d32669618ad08f3c374b970ad5170 FileChecksum: SHA1: e006aa0785550e2ef2cca319e3494fc30b6964fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/NeonInterceptorScheduler.cpp SPDXID: SPDXRef-994120fa466f651e28a230c6b9bbbab4 FileChecksum: SHA1: 6faf3c6fedf8098baed0305175751bb13810b08a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonInterceptorScheduler.hpp SPDXID: SPDXRef-1ba8a6df5e4827beb08ac0450cb1ae2f FileChecksum: SHA1: 6c4a8179cd14278fa10d10d87477e6a7afe3afda LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonLayerSupport.cpp SPDXID: SPDXRef-6113af341d78cff3f17c8687dc89cb5f FileChecksum: SHA1: 083557fec8f053e875b4de8a6c5fe5ec47769168 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/NeonLayerSupport.hpp SPDXID: SPDXRef-2e4b6a8572be7c9756fb1a1aa15e0e12 FileChecksum: SHA1: e497a1be0babd147d9c09b2d9d1a961ade481257 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/NeonRegistryInitializer.cpp SPDXID: SPDXRef-78a390e7f750e109701ae326ab658a61 FileChecksum: SHA1: 24dc665ab6590c600cd3b6c8b2b6d91ed039e4a7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonTensorHandle.hpp SPDXID: SPDXRef-ae85e98a6cba421b883d32ec60756a55 FileChecksum: SHA1: 03b743a854647ebf5170dcba16bc4e8c7f31527e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonTensorHandleFactory.cpp SPDXID: SPDXRef-a7313828096558e4720318bbd84e0591 FileChecksum: SHA1: 17cd15efa4ca68ba1dfe7f0cbd3df24fe8599501 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonTensorHandleFactory.hpp SPDXID: SPDXRef-b945defafdadaf6b2914d99aab1026ce FileChecksum: SHA1: 8c748a07132932c7de51aa2436e299574650b908 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonTimer.cpp SPDXID: SPDXRef-e57cf738d200455e9e7288bb29771ae3 FileChecksum: SHA1: 35814a6c176e9c1333c8805a1101121fda989353 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonTimer.hpp SPDXID: SPDXRef-6f5bc7843c5104601768329e2f6cef20 FileChecksum: SHA1: e5a4361c58987b4edb80c101ccc2041ee5401943 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/NeonWorkloadFactory.cpp SPDXID: SPDXRef-1dfb09309862146e9a4fc6599fcf0bd4 FileChecksum: SHA1: 414bfe1ca37491a5be2dd5913494f216a447d42e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/NeonWorkloadFactory.hpp SPDXID: SPDXRef-cd2ccab8789fd1696d432c86a79e06d0 FileChecksum: SHA1: b3e4b49cd677a9c10bfffcc219551c4c0fffcfc4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/backend.cmake SPDXID: SPDXRef-5e1346fef67def6172f7d2e74a977f40 FileChecksum: SHA1: b5a39e6ef6586207c6e68d66f2a467f7933fbdb3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/backend.mk SPDXID: SPDXRef-775a0aa3fc3fadd27efba8e87af038b1 FileChecksum: SHA1: 1b30b90b1bdcd3602b0c0933b88a97e6e9cbce5d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/CMakeLists.txt SPDXID: SPDXRef-8c50f4e0d55ca657ec5f1ce17632ef3f FileChecksum: SHA1: 7d2297cc351fafdc3f68ebf976343f77d30aec28 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonBackendTests.cpp SPDXID: SPDXRef-0adf0e1f0f01c8a93c9954b8a49c5293 FileChecksum: SHA1: 542d2c5452fb6d32b5858d75a9438f688df3d071 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonCreateWorkloadTests.cpp SPDXID: SPDXRef-3aeb049061a3acbc7dc3ef305d278d74 FileChecksum: SHA1: 345e7af9d36d146d23ac530844492cadb2487322 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonEndToEndTests.cpp SPDXID: SPDXRef-b4a6ba2a3de96bd719545da688c3dda6 FileChecksum: SHA1: ee6b788115c743e56982525f2b90cdf51ed60bde LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonFallbackTests.cpp SPDXID: SPDXRef-974aa77a7daa1507775cdae641b7211f FileChecksum: SHA1: 6e472e09e397c935737b00e0260a2a83157f8733 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonJsonPrinterTests.cpp SPDXID: SPDXRef-2d5e5a06d677ce73218e36b1cf25352a FileChecksum: SHA1: cd54f00653f30043294483671a09fe565ea3c7b2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonLayerSupportTests.cpp SPDXID: SPDXRef-e36c02a90302c32df7336701861fea5c FileChecksum: SHA1: c04f39b95e7045b4e4f6951f2cda5454625df641 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonLayerTests.cpp SPDXID: SPDXRef-b6059b2bf4ecd52e971d898960a3e80e FileChecksum: SHA1: d6bd79c7aa181326ca2da80f1b5a259c90e58317 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonLayerTests_NDK_Bug.cpp SPDXID: SPDXRef-8f67c2de4a7ab105648d68f6572d0750 FileChecksum: SHA1: 9b2b92dcc7a30403d395950f10aa8556ec4c464c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonMemCopyTests.cpp SPDXID: SPDXRef-8c71834308deaaaf3c24b21be297f64a FileChecksum: SHA1: 79fb7ead87ca247b65244e9b1470520921315ad0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonOptimizedNetworkTests.cpp SPDXID: SPDXRef-ec850e8960b24fb03d22ba1098859d29 FileChecksum: SHA1: dc9108fd2ca2b465da3aed0a34228a70ab0f0fe4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonRuntimeTests.cpp SPDXID: SPDXRef-916bd77aa5c7ccf1884660fe203624b7 FileChecksum: SHA1: 4e1851040697dd1d4eee1890aa89933cadacd013 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonTensorHandleTests.cpp SPDXID: SPDXRef-1e93444f7787c35fbd8f5ca25d875935 FileChecksum: SHA1: a1999009998b4e08c9a27511aa441c0eeb556be2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/test/NeonTimerTest.cpp SPDXID: SPDXRef-148e8a1d7544fbdc5ef863ee635b56a2 FileChecksum: SHA1: 3a51bdd92680997297e921b81dc9dc7e5613cae7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/neon/test/NeonWorkloadFactoryHelper.hpp SPDXID: SPDXRef-0a5f5251a17aa4196df0a281143b6a82 FileChecksum: SHA1: d98c0e37524a981d57ea01332ad3f44aa9b40304 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/CMakeLists.txt SPDXID: SPDXRef-cf146a9e5a0b0986c716235a09f34550 FileChecksum: SHA1: 9b715d709c8eff236b05eb5b75793b214b6cc1c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonAbsWorkload.cpp SPDXID: SPDXRef-6a59b892dd60c51ce9e2a18d04a13f62 FileChecksum: SHA1: 079770dacd42a873a2ca7eff971af01cb96a0055 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonAbsWorkload.hpp SPDXID: SPDXRef-b9963ac5995ddb6a502328cc1f128e25 FileChecksum: SHA1: dd60750f315dcc4e65be61c7adf0dafb4cff4cc8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonActivationWorkload.cpp SPDXID: SPDXRef-b7351c15379d357df2abc50cb7226ca6 FileChecksum: SHA1: 405740a9cf3df629b8465570de1ba6cb5f0a2751 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonActivationWorkload.hpp SPDXID: SPDXRef-9a82c88355eb0e23fdd37326055b99b2 FileChecksum: SHA1: da871f2e0b50fa1ab0916b2eaf02d8c4826a436c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonAdditionWorkload.cpp SPDXID: SPDXRef-e4865b631c9433727ce45ce57dd4629f FileChecksum: SHA1: 9bd31624a62e08cf1ed87bd1ffa6743c32cbf81b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonAdditionWorkload.hpp SPDXID: SPDXRef-dd68a87e9c541619663bfc3b08ac517b FileChecksum: SHA1: 9fe55c1692687111a530adeaa7f787f338ecb2d7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonArgMinMaxWorkload.cpp SPDXID: SPDXRef-b1fa711d07ac354e876ee754e0ad454d FileChecksum: SHA1: a56bfedaaeb3f70918712bb557debaaf4af75ffa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonArgMinMaxWorkload.hpp SPDXID: SPDXRef-bbb76a0ab95aa17ee0384851f4935d62 FileChecksum: SHA1: 3e034fa64a3162a22b403233c4395e8f0387936d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonBaseWorkload.hpp SPDXID: SPDXRef-cbeb24e25ab8d22e9b4c509062862d46 FileChecksum: SHA1: 88d0cd2c6ff6a74f3f07284f344f40f462784c80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonBatchNormalizationWorkload.cpp SPDXID: SPDXRef-68822f70d7ca5a0111adafb2661d3a8c FileChecksum: SHA1: 59b56f3586f2ca652fb13ec4b0fffdafb592cb3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonBatchNormalizationWorkload.hpp SPDXID: SPDXRef-79a3b6943f9002a742f9a8eb667a6cf3 FileChecksum: SHA1: 2b7cfc9396ebb6a3db429decde10727421edc5ce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.cpp SPDXID: SPDXRef-f77ec75069e018573c9ef51789dc8285 FileChecksum: SHA1: 62a735ab42b27ac2088abddfaf9cee141514c606 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.hpp SPDXID: SPDXRef-4c7d92fc5516e3b7815b4e9c32e50985 FileChecksum: SHA1: fb7dafb2f0ba67422d176c364126500d1e5c7c3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonCastWorkload.cpp SPDXID: SPDXRef-f6acf1cfa5abed3f1ae6130368221fd6 FileChecksum: SHA1: 1a2ae54ecb3e5abe6c70bc1df198758b1f527794 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonCastWorkload.hpp SPDXID: SPDXRef-0e1870264779bfc2607deb2c466fe2cb FileChecksum: SHA1: 43652b0aedc28e4ad9c7692676d43cd075e44724 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonChannelShuffleWorkload.cpp SPDXID: SPDXRef-1536847692782f15a052d0c2525ce57e FileChecksum: SHA1: 5344265e2c707c495533460c86e58433030d7ab7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonChannelShuffleWorkload.hpp SPDXID: SPDXRef-575dff72e63958f81f8802ff8367dccc FileChecksum: SHA1: 371b405fe7e765109f114e19ef1dd0e2af6c3b5f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonComparisonWorkload.cpp SPDXID: SPDXRef-31d2979ab26c2a059166c325fe283594 FileChecksum: SHA1: fd01090f0367b66cd682232fa3ef55f7865c07e8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonComparisonWorkload.hpp SPDXID: SPDXRef-9fb897e84cad01857b37197bb0f89a42 FileChecksum: SHA1: 9adba40ee804cc4cb13956163460a212d56bf1cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConcatWorkload.cpp SPDXID: SPDXRef-238d206a3728fa4faef7139f76666ce5 FileChecksum: SHA1: 6bf39931a6e6fe3e0b7de33f6973fa35f0d04845 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConcatWorkload.hpp SPDXID: SPDXRef-65d8483046c4bf10167441d61a2154a9 FileChecksum: SHA1: 8af833f0fef2f5d2f864b876d134914ed62b5dbb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConstantWorkload.cpp SPDXID: SPDXRef-8a820c537156b908ed3c292238f755cc FileChecksum: SHA1: 761226ec0012ddd2a5e4e46a2076797242334d41 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConstantWorkload.hpp SPDXID: SPDXRef-cb7d4835596d04b56c1539436b9ee699 FileChecksum: SHA1: 7b90d698d088a595886a8895cad550eac1f97160 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertBf16ToFp32Workload.cpp SPDXID: SPDXRef-5c4e41111a4b82f76779a0224208aade FileChecksum: SHA1: c2f6d688dcbff9632f7193621b3c35f49402efe5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertBf16ToFp32Workload.hpp SPDXID: SPDXRef-f8ce51fb2698154d46fc7f1b963426ec FileChecksum: SHA1: 1b23e9db43fea0f9f4f9b5fe9e5f66a6ce5e2bf7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp16ToFp32Workload.cpp SPDXID: SPDXRef-dcdcb0388221954fb3e7072936c05ebf FileChecksum: SHA1: b927c826531f040b46d0b3c6939b7429ba5a76f6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp16ToFp32Workload.hpp SPDXID: SPDXRef-a121375e2fb62f03d43a40bc0f9d69e2 FileChecksum: SHA1: aca0c6b76e9cba6fff4d68cfe514c1ad2570037d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp32ToBf16Workload.cpp SPDXID: SPDXRef-389e837211be78033b1e14d65371e8d6 FileChecksum: SHA1: d42218a1d5e44735b59b1bf7437316076fd91fc9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp32ToBf16Workload.hpp SPDXID: SPDXRef-82fbdc2be852ebe1776b024967229b32 FileChecksum: SHA1: 2df42c2a2ef53d92d76403f4993835be5ab4603d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp32ToFp16Workload.cpp SPDXID: SPDXRef-873d14286580a45e1df30507d0c46532 FileChecksum: SHA1: ae0978918cb581a4e97840487f377c9ad8cdc732 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvertFp32ToFp16Workload.hpp SPDXID: SPDXRef-626f59d993fb7f824abdc1fbf596c425 FileChecksum: SHA1: 44b918115ed7e0c3dfc1e83d850a9046f09917b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvolution2dWorkload.cpp SPDXID: SPDXRef-c93c30cd210dbbd17b9cda261f961dd1 FileChecksum: SHA1: 0d5ec58d7ae312db874c57479e0a8cfc6edf17aa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvolution2dWorkload.hpp SPDXID: SPDXRef-7915b2f07ad0ab2d7c50c45ad6b78b37 FileChecksum: SHA1: b140b9b9d44ce522d2901af2cfcfdab0714a5fee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvolution3dWorkload.cpp SPDXID: SPDXRef-2836acc4838dec7872d3e070b715790c FileChecksum: SHA1: 6417e8883ab921f5d4177c63b79139b1a1dc19c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonConvolution3dWorkload.hpp SPDXID: SPDXRef-db282e8551a124bdd2c718559ff3d552 FileChecksum: SHA1: b2c48b19cf65cd2ddde6c5c9ca34b1cf08cf0fce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDepthToSpaceWorkload.cpp SPDXID: SPDXRef-d6d530994596d1db72bce57539420f0c FileChecksum: SHA1: 37d731ba37626787ced048789bc75daa38e3331e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDepthToSpaceWorkload.hpp SPDXID: SPDXRef-dc857c98a37a02230c68fa88468b3e40 FileChecksum: SHA1: 06198a250bc393683ed93162f8e1b80ecad60f9c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp SPDXID: SPDXRef-ee1ca5d67ca019189c459d3438bc4804 FileChecksum: SHA1: 08ef37ee9e35e66fb69a64ec5288310c3c97597f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.hpp SPDXID: SPDXRef-f37da61fa9503ad9acd798017996c57b FileChecksum: SHA1: 6dbea3a7147a06fc53689dee8b2a4b35f895ea91 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDequantizeWorkload.cpp SPDXID: SPDXRef-7007ab8f3e6dcf6b15cdc0d7e62b2b5c FileChecksum: SHA1: 22f82a31000d517d419e050b94fe1bc8f16d832c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDequantizeWorkload.hpp SPDXID: SPDXRef-7e30231ce644427d4f82d29d9803387b FileChecksum: SHA1: a7b8d89ebd3673478d43cc581be8d4e83365196e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDetectionPostProcessWorkload.cpp SPDXID: SPDXRef-a8255f02b5436a90be2082981add6a58 FileChecksum: SHA1: e0d08d96bf4e861b97e7dc26032296dc166e2bc1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDetectionPostProcessWorkload.hpp SPDXID: SPDXRef-69a0103b832f8df33cbd0a95506e4603 FileChecksum: SHA1: 74beec0f4671b38b2b09128c04c708ff48d38c38 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDivisionWorkload.cpp SPDXID: SPDXRef-082468f3c14799b874d8faf4dde9b8d9 FileChecksum: SHA1: 694b50b50c654ce5c4ea607e886a647e62878fd6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonDivisionWorkload.hpp SPDXID: SPDXRef-2f10ee4ac5dc09ed78f93832d25f4bb3 FileChecksum: SHA1: 2491e3c2fad682556b1565c98b3604d21ed2c544 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonExpWorkload.cpp SPDXID: SPDXRef-0a370deb8bb71649c52b0085d94b6fd6 FileChecksum: SHA1: b564840e1836ab230fc9981ef6473627a544c7cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonExpWorkload.hpp SPDXID: SPDXRef-5c2554df6cf3ba0277e78f999f57f022 FileChecksum: SHA1: 62166ef54d9fefde8d744ab332afe0b15f97a80a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFillWorkload.cpp SPDXID: SPDXRef-fc803922cdd113f4c576230ddd6b6cd0 FileChecksum: SHA1: ba73037b77c12cd260b41dc4f66aade352c1e33a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFillWorkload.hpp SPDXID: SPDXRef-76e87788d83af18cf2f46ab37bd1ddc6 FileChecksum: SHA1: 3d2f131e38c9b4fead6f3695551f8cd30b3bd889 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFloorFloatWorkload.cpp SPDXID: SPDXRef-ebf8bbaba5041c7fdbe9d68e89e22b0f FileChecksum: SHA1: 35db697faa97691c5c283c6c080cee6de98681c6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFloorFloatWorkload.hpp SPDXID: SPDXRef-0d9c93501c6abdef0ccf7392aeaf9eae FileChecksum: SHA1: b57d3964f2ba19de460ad8c9a630f5eff9733035 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFullyConnectedWorkload.cpp SPDXID: SPDXRef-d2608f7fc11a1f40f620b8ac3cd52deb FileChecksum: SHA1: 7e075630d815868665a9dd283d6d3a2cbeb275ab LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonFullyConnectedWorkload.hpp SPDXID: SPDXRef-28c3d6004c9a6a6094d6b9caf42638be FileChecksum: SHA1: 962a676967a73e62e69c74a1ba6411cccb30fc23 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonGatherNdWorkload.cpp SPDXID: SPDXRef-3f3d8a668347abf26f2f0287bc7cb4d5 FileChecksum: SHA1: b28bdb51d2c507c9b06acccf0f91115988fd9c9b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonGatherNdWorkload.hpp SPDXID: SPDXRef-5d6db83b326be6baed008a8fc98331a1 FileChecksum: SHA1: 2dad1688a2bdd5ccbaaa59fa23cddf755a17dcb2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonGatherWorkload.cpp SPDXID: SPDXRef-179c82cdf15cf97d19b82f805ad8dac2 FileChecksum: SHA1: 34bb47b8771c3ac16585921a29073ffb135c5545 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonGatherWorkload.hpp SPDXID: SPDXRef-a13155dddbf7f064f9bf399374a94bb3 FileChecksum: SHA1: 22fa5758ae8e43794e43da2538c2d1f48cd730e9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonInstanceNormalizationWorkload.cpp SPDXID: SPDXRef-f97d8885919f561835c1927e6d0a763f FileChecksum: SHA1: 31fac992c80bc4efdfbed538a8483d412463bef2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonInstanceNormalizationWorkload.hpp SPDXID: SPDXRef-5ff70ac1e64cb4bd328a381eddfd3fa4 FileChecksum: SHA1: 7652c7206f6879b6ef97c14188c0b30a744dc95a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonL2NormalizationFloatWorkload.cpp SPDXID: SPDXRef-13364337050aa83013a3c0c0e28f8380 FileChecksum: SHA1: c196897724c4487f65f3fae5241dfaa28486581e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonL2NormalizationFloatWorkload.hpp SPDXID: SPDXRef-8d0f23f759884fbc64317c91773879d6 FileChecksum: SHA1: 63f712c82d591a112bd805c53fcd5eca92d4230b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogSoftmaxWorkload.cpp SPDXID: SPDXRef-2b05b42cb004f64ed48cbeefbfab97f5 FileChecksum: SHA1: b829ac5de5b302465d866c89f807360798eb7781 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogSoftmaxWorkload.hpp SPDXID: SPDXRef-f8eb0d1a0933df180a96fa5583eaa5f3 FileChecksum: SHA1: 778b6b4f7255aa7d936fe0f7b54e1f53b65eb635 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogWorkload.cpp SPDXID: SPDXRef-dd2903d2b46ee91e64eb512f171552c8 FileChecksum: SHA1: 2fdfa6537fc7ddf4797d4ba3b8408d41328b0dfc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogWorkload.hpp SPDXID: SPDXRef-2f0277159cfa721c8051b30795ca6319 FileChecksum: SHA1: 1a58e210c452b3aed9a899d28aabaa93ad8e2825 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalAndWorkload.cpp SPDXID: SPDXRef-8f4a910bb39468e4186e867aabaaef13 FileChecksum: SHA1: 33ae5bcd7ec0a4d6aa6b8141b59a5604dd3d520b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalAndWorkload.hpp SPDXID: SPDXRef-2266c29216df8767d3f96032a8eb0320 FileChecksum: SHA1: 621ed9e57c5af0c7a81f8482d223d0de28da5d6c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalNotWorkload.cpp SPDXID: SPDXRef-d980a0681681d026d179c636bbb18760 FileChecksum: SHA1: 713dc9bd703fa8a76c8ea7e89c76e342bdc48421 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalNotWorkload.hpp SPDXID: SPDXRef-ded58306b8c6480d850778f12d72e696 FileChecksum: SHA1: 369f38698f01f2d88413402a336ad8ca731e7eec LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalOrWorkload.cpp SPDXID: SPDXRef-7574c9bad885b5af463fa7d37884fad1 FileChecksum: SHA1: 0c8bd5abe5fe8448df31c52962e369b59ca32000 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLogicalOrWorkload.hpp SPDXID: SPDXRef-672d54b85baf3ae5a77057c8c8bbe432 FileChecksum: SHA1: 5356b848a7c25c7f15bc70d62457564fb9bbce74 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLstmFloatWorkload.cpp SPDXID: SPDXRef-cacbab71e5c8e9407f5754fa3feb2718 FileChecksum: SHA1: d84a3f14b506e23693fd197ce642af812525e344 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonLstmFloatWorkload.hpp SPDXID: SPDXRef-8de24247f9ac6cd8ddd5f500a7d1892d FileChecksum: SHA1: bf20f15eb2a41af1d4df6a6c488a61a714a07f9f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMaximumWorkload.cpp SPDXID: SPDXRef-6ed327417e1e86b099697d794b7fb8a0 FileChecksum: SHA1: f4445a4bcb2005e19795e1e131115e38d5cd87be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMaximumWorkload.hpp SPDXID: SPDXRef-dfb70b4fd08f7e7c74c867da08ffc2ab FileChecksum: SHA1: ec60063d7683bfc6a26c16357855628c5795dd6a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMeanWorkload.cpp SPDXID: SPDXRef-7df00e3984218b2870e7d4a08677cc76 FileChecksum: SHA1: 510c78474c72dcaf6adcf6f5d780f1bf10121f25 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMeanWorkload.hpp SPDXID: SPDXRef-959897fe5773080a76888a4007b66ade FileChecksum: SHA1: cedbb4c0533692ff3236d1caede8058986a225db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMinimumWorkload.cpp SPDXID: SPDXRef-9ce9bd1f90c3810b41320f13f616b2ea FileChecksum: SHA1: 55a2246911d86aeeb03af07a8644f961a164afd9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMinimumWorkload.hpp SPDXID: SPDXRef-8723717ef1f14703b08c4b3e50b2ca2b FileChecksum: SHA1: 02a78c92bcbe00ba121442b448c3c210b6b3adb3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMultiplicationWorkload.cpp SPDXID: SPDXRef-9f2a9313e5a1ad15f4cf8d956fd38c37 FileChecksum: SHA1: c007b2b2ff1242e5e17bafe9b422df0f74871805 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonMultiplicationWorkload.hpp SPDXID: SPDXRef-00cd66cfcbf09f1c0ec184c8c7723038 FileChecksum: SHA1: 4ff877b05a33d95e3824dd90584c7e6ccf03260b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonNegWorkload.cpp SPDXID: SPDXRef-cfd048c0f0f330e3ef9b544db265e48f FileChecksum: SHA1: 9cf2b8993e79f3a154e1af4e724d2a478dc50524 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonNegWorkload.hpp SPDXID: SPDXRef-df38dcd65f33cf3a4a594213624e8ff0 FileChecksum: SHA1: a8150c54630a9b32141e8f198066def6b25414b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonNormalizationFloatWorkload.cpp SPDXID: SPDXRef-83d8a4b26db040af6e8fb6701cc23a3e FileChecksum: SHA1: 6d84d442fb8149bf11d1bebd248b1796c31fa70f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonNormalizationFloatWorkload.hpp SPDXID: SPDXRef-3d48f50f911572a1411d648e16800196 FileChecksum: SHA1: f795fb55fe61d83c291dbbf9ae3d7d057ac85982 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPadWorkload.cpp SPDXID: SPDXRef-b016e5f217f85f28e00606031a4412f8 FileChecksum: SHA1: 419dccde1b1570f0138a9817c61f4dc5d19f4803 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPadWorkload.hpp SPDXID: SPDXRef-744a53a33e81cb7a04c4f97271f0e439 FileChecksum: SHA1: 2e4ecc9dcfb8bf723646f5524487f7f10f74999e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPermuteWorkload.cpp SPDXID: SPDXRef-28abef070c9ee21aa9c29c727e5fc832 FileChecksum: SHA1: d6b63df73cc7d90927d84aa1f88214b53a3cffe2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPermuteWorkload.hpp SPDXID: SPDXRef-4fef05a528ee005648040fec0709ebe3 FileChecksum: SHA1: d6a6e8f78f447e32eb8235d25b879fd29628d563 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPooling2dWorkload.cpp SPDXID: SPDXRef-55d7961e0970fd57ae982ae95d565328 FileChecksum: SHA1: 2d6d8e6fc0292376698ec736946f964b2654287b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPooling2dWorkload.hpp SPDXID: SPDXRef-03e6a30cec4e910670075526e52b5319 FileChecksum: SHA1: 144bec6d558ff6fe2afd0c3c63d04e53af7cd062 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPooling3dWorkload.cpp SPDXID: SPDXRef-55626d6d17fb5d176e70bca01b0a7c85 FileChecksum: SHA1: 15b8474c30b1feb8a17e2b85570a0afabb88a925 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPooling3dWorkload.hpp SPDXID: SPDXRef-4cbeaad23f6e26789207bfb61d1709f6 FileChecksum: SHA1: 0824ead793b51a12d859b6afdedf1bab31aa8fb1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPreluWorkload.cpp SPDXID: SPDXRef-810c41fade94b0733d454bb38dd48a89 FileChecksum: SHA1: a9e5fcaaca51d8f68f6077d605797397ed6ba86d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonPreluWorkload.hpp SPDXID: SPDXRef-862cf98dfca1332f35f1167541e9815d FileChecksum: SHA1: 4f8e01d8c5bca73e4f41362ee6846014046d51ee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQLstmWorkload.cpp SPDXID: SPDXRef-f6fac2bc75b94b957683bba7389100e2 FileChecksum: SHA1: c9941bf22ade9f510e1eb0357587443dddac804d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQLstmWorkload.hpp SPDXID: SPDXRef-a08f1d17894125450bade5d5580b8c72 FileChecksum: SHA1: 02489af34cbb66d50299bd3727bc179e25d83f5c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQuantizeWorkload.cpp SPDXID: SPDXRef-b80cbffa89f06039c98af89b43616139 FileChecksum: SHA1: 537ab6bb0c510b8436b743d6121de96e2a0b011b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQuantizeWorkload.hpp SPDXID: SPDXRef-a6f58344d79ffabd8c52ff8598aa6644 FileChecksum: SHA1: 95024511e2724d08394ef8631c6f6ca7eb634966 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQuantizedLstmWorkload.cpp SPDXID: SPDXRef-77c6e6be59f605f37863e8dce85fcfcf FileChecksum: SHA1: 6ed79211a1e80eb186996348bf8a97dd13b788c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonQuantizedLstmWorkload.hpp SPDXID: SPDXRef-95f436dbb17632fa7b549c34e16d7351 FileChecksum: SHA1: 2891067bf7fbd306b827f466f1f515dbb04ac69e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonRankWorkload.hpp SPDXID: SPDXRef-3cf2b627184fcbc79f1de0d2ab34beb2 FileChecksum: SHA1: 3fea66478140ca3e23fa1a4c68a5fa7454e8c023 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonReduceWorkload.cpp SPDXID: SPDXRef-76e5ccc29fc83a055bf534deace5cd0f FileChecksum: SHA1: c01802bdc020f9ef4c088ffa7ada471b6a1c3fc4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonReduceWorkload.hpp SPDXID: SPDXRef-7d818f38496914fa2d5420b16843b9fd FileChecksum: SHA1: 59813d85103263c830869793390c977e37ffce1d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonReshapeWorkload.cpp SPDXID: SPDXRef-779e810740afc16a6d64017130825747 FileChecksum: SHA1: bbb260805a36a89f1914e0ae22ac258b1a99c3f5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonReshapeWorkload.hpp SPDXID: SPDXRef-5e11cba9897024ad4fd8a118eb6d93d8 FileChecksum: SHA1: 198fa9045750d2f26402d81d941995b5c8504715 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonResizeWorkload.cpp SPDXID: SPDXRef-ec5a5ab88610b89fc9736d43ff5b0a94 FileChecksum: SHA1: 7dd107485fa04374a31da4ad66e271d7b2857ead LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonResizeWorkload.hpp SPDXID: SPDXRef-1bc59ef35a5050cfce2e6866d6156ea2 FileChecksum: SHA1: c107de74c045f4688ada3fdf1f1882716c8b3b76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonRsqrtWorkload.cpp SPDXID: SPDXRef-d63d57670a9ded7feae33e4a185c7fdf FileChecksum: SHA1: 0bedc7a9789b91808d1e761166d278ed233728b1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonRsqrtWorkload.hpp SPDXID: SPDXRef-6e20fec2842e80c60da26f65f6cc1e8e FileChecksum: SHA1: 471e83a7dabf8a58f264af999bde15391a5add1f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSinWorkload.cpp SPDXID: SPDXRef-53a41db3dc012f87455ebeed43011786 FileChecksum: SHA1: 8fc625e0366038be8edf0274c8f2ae2e1ba76980 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSinWorkload.hpp SPDXID: SPDXRef-640abe1fa9b8b87228b0a21a64b5ea31 FileChecksum: SHA1: 9c42b464c28dcc023c993e002c50d2e618a6a381 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSliceWorkload.cpp SPDXID: SPDXRef-29b30af3bdf03ba2bb2eaa44f9510014 FileChecksum: SHA1: be7ffff0d72c356efd7360c57ec71a714e4c8f67 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSliceWorkload.hpp SPDXID: SPDXRef-aa0d5592afd76423909cf117a4a04a30 FileChecksum: SHA1: 17829aa2f44e098614abfb9c148ce3f03f20824f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSoftmaxWorkload.cpp SPDXID: SPDXRef-520bce09bfd0168c6128112f083c74b4 FileChecksum: SHA1: c0a1a6347ddb4a97fa024bbc0faf1fe73791ff9d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSoftmaxWorkload.hpp SPDXID: SPDXRef-12f913d22faaedfa5c90e9fd7562e48e FileChecksum: SHA1: 8ec8b988629b9e0041c1c8dcf377aee6c1ec9cb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSpaceToBatchNdWorkload.cpp SPDXID: SPDXRef-2a0d78cd1e7ca2ee54ceca16001c3d77 FileChecksum: SHA1: 73505fba440b4a57814397544e14ce75e9054ef3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSpaceToBatchNdWorkload.hpp SPDXID: SPDXRef-a81d1569962efad1492484084da2995f FileChecksum: SHA1: c89100b4a7a5f5bff23ad212254df8f924b5a98b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSpaceToDepthWorkload.cpp SPDXID: SPDXRef-d99778ae9f0fb090a5552bebeca1b69a FileChecksum: SHA1: eafe4fb8593c93fc30b01ed600eb9bab1626c447 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSpaceToDepthWorkload.hpp SPDXID: SPDXRef-3240029248bce7fc6cbb384e5c4727c7 FileChecksum: SHA1: 5b8d6da1acb355d0fb9309ccabadadc2db962356 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSplitterWorkload.cpp SPDXID: SPDXRef-14d860974cd114a05436c5892462676b FileChecksum: SHA1: f9f87c68883a64f73349d90295f65dbac16f3bd4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSplitterWorkload.hpp SPDXID: SPDXRef-1f01b49e2404f5ae11fddf7bcd4b5223 FileChecksum: SHA1: 5d36766aedfb449a6adafe1ccb910d801f6c862e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSqrtWorkload.cpp SPDXID: SPDXRef-c36e538bfb5aaf6e7466c3481254e92e FileChecksum: SHA1: 4aa97ffc5fd5338a086d63789a3f2d32f6d44214 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSqrtWorkload.hpp SPDXID: SPDXRef-0029ca92d68e4edbc0ae70f5c178b24a FileChecksum: SHA1: 28a9f8be2816e01bfac8ec14e14f2d0c6edff184 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonStackWorkload.cpp SPDXID: SPDXRef-ac120e01baaa145254b1f9f92b3a7b8e FileChecksum: SHA1: 3df13a4746e893d7cd4f59fd6344fc14bb5764c8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonStackWorkload.hpp SPDXID: SPDXRef-527d31f033858afb8f0e588c025569ec FileChecksum: SHA1: f556680e81474e8f47fcc234c14f04029426efe2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonStridedSliceWorkload.cpp SPDXID: SPDXRef-1e2d88c2c8fb98f646d75a434defcd60 FileChecksum: SHA1: 2df5c673ed6bf61675eda601f4f82ff5a81d7e02 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonStridedSliceWorkload.hpp SPDXID: SPDXRef-73d804dae502ff21344913c6ce677e08 FileChecksum: SHA1: be5849faecedb129deadb016a12ca6da801543c4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSubtractionWorkload.cpp SPDXID: SPDXRef-487f70bafa5d29eed61db2b458af8a5f FileChecksum: SHA1: ddc7692e317084fcb3f51b1af371018eea20109c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonSubtractionWorkload.hpp SPDXID: SPDXRef-174af76267ad8c5b1fb0aeab988b3b73 FileChecksum: SHA1: 0776ddcce0fb7010e590a681b3527a046a05ca33 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonTransposeConvolution2dWorkload.cpp SPDXID: SPDXRef-6993a3cc52274e9a7047fa217c75a86d FileChecksum: SHA1: 6584cbfdbeeb51abaa4abb97cfe4c3c7ee1243db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonTransposeConvolution2dWorkload.hpp SPDXID: SPDXRef-8202889ffd9e0956c455560991590978 FileChecksum: SHA1: 167df896410860d2619437dd888b123d5933c911 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonTransposeWorkload.cpp SPDXID: SPDXRef-ca9ad54de2bf3d0f181b97193f23e2b7 FileChecksum: SHA1: 92f48d16a7d20e8f77951850b7b1fe97077b48a9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonTransposeWorkload.hpp SPDXID: SPDXRef-0fae2250cf15eb53565cccfae4678258 FileChecksum: SHA1: a1db0180fd49da7d65c152c5e3ab2fc45c81ce45 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonUnidirectionalSequenceLstmFloatWorkload.cpp SPDXID: SPDXRef-7f731f823be6184ee552cd662ae6a63b FileChecksum: SHA1: 3db098a444680a353dfdec64341559ea0a4753b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonUnidirectionalSequenceLstmFloatWorkload.hpp SPDXID: SPDXRef-2f336f2ee29e68bfdf359d8bda5a80ba FileChecksum: SHA1: 4099d60d504b6796fa17d780b4c4d803a6e6fb39 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonUnidirectionalSequenceLstmWorkload.cpp SPDXID: SPDXRef-056aae0c8c5f38bdc7660b4bed7bf012 FileChecksum: SHA1: 9699ea9191f056ece92d069a9cf905eaa9a2a764 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonUnidirectionalSequenceLstmWorkload.hpp SPDXID: SPDXRef-d0d30656028758ef5ab0f8cf3b09b4cc FileChecksum: SHA1: 61de29ad6f4007b669c0a2de7d33f580bc11dc26 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonWorkloadUtils.hpp SPDXID: SPDXRef-2384c1eb5b736fc1d7c03030007a6523 FileChecksum: SHA1: b4ff696d38bb980b6d4a9bf22e3cf6d643ad9e4b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/neon/workloads/NeonWorkloads.hpp SPDXID: SPDXRef-f1572bd0b0786c9bda6f3b5a4cd6b3a8 FileChecksum: SHA1: 8e770e17c45b08989a0f719e07110949a1c68bc7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/CMakeLists.txt SPDXID: SPDXRef-bcce30ccf456059fc39ca99472ddcc47 FileChecksum: SHA1: cd06fd48e462f7fb1d4c51f69b4e7494009574be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefBackend.cpp SPDXID: SPDXRef-24f5e9e13c13c9d03a0673921944c074 FileChecksum: SHA1: d184212e560cdb8ad2db3fe82a3f10519d68628a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/RefBackend.hpp SPDXID: SPDXRef-5e219e6613f2e55e2c0ffabff84e1600 FileChecksum: SHA1: 9e51d455e3fdfd2fbd5867adeccffa315a9a0659 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/RefBackendId.hpp SPDXID: SPDXRef-6345dc307e2448f36a5640344dfd377c FileChecksum: SHA1: 29cee38482dc26ec6c020a50d9dbcb14141c0820 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefLayerSupport.cpp SPDXID: SPDXRef-6569791eb0b54ca30a8b1b3498c52654 FileChecksum: SHA1: 6c5d4884a12132d30c3edff7f4297a862f4ff234 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/RefLayerSupport.hpp SPDXID: SPDXRef-c7fe1e2e477aa9059d827cc628055b72 FileChecksum: SHA1: bc8384f81c7d36e477e730f49f2e4d9ebce42ff6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/RefMemoryManager.cpp SPDXID: SPDXRef-abc5c08f2a73db50f946ee19c6790145 FileChecksum: SHA1: dc66da1c947cd61fd6571869539d6b804e81f356 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefMemoryManager.hpp SPDXID: SPDXRef-5d4499a75aa1917a8fb9c31cc063476b FileChecksum: SHA1: 6ef6b2e9cd83f2bad25be425caccadf866ff22e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefRegistryInitializer.cpp SPDXID: SPDXRef-b3f49d3cec6dd0164507095f89afbd44 FileChecksum: SHA1: 965631b81437baf8758251decd9db70a3529d3eb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefTensorHandle.cpp SPDXID: SPDXRef-9a79c8d71d5ac7c6c77b91deea26819a FileChecksum: SHA1: 49e670f20ee7b41957515445f884578d6252545a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefTensorHandle.hpp SPDXID: SPDXRef-0c1d75c8ac0b0383f0441bda77c5e1ad FileChecksum: SHA1: f675470abb36f0c6d117bbc83df7f03748654083 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefTensorHandleFactory.cpp SPDXID: SPDXRef-3a5a119f931ff532776e9f44fdf865cf FileChecksum: SHA1: 5df6c09523ac1cd8948eb255dbe1c1eecafa614d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefTensorHandleFactory.hpp SPDXID: SPDXRef-6c47bc02b131820d9cf7931be2cddcd9 FileChecksum: SHA1: 36ed5fa2879bccb6938942c220559ae2fe8b06a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/RefWorkloadFactory.cpp SPDXID: SPDXRef-e33975ef0a7d4d7bb756dc221e5a8410 FileChecksum: SHA1: 3471a9446c16ce88f393d8a1140b059558160dce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/RefWorkloadFactory.hpp SPDXID: SPDXRef-b441871b4100ac3ba52c9d24fcfe8601 FileChecksum: SHA1: 34ee254e2fa21a3bf4210497389fc8feea391279 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/backend.cmake SPDXID: SPDXRef-1084dfc626d2f321fb95dce65ed024b1 FileChecksum: SHA1: 4f16a5cd1a7f2e583b03880f42cedb0a2b25291b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/backend.mk SPDXID: SPDXRef-19ca13e602d0bf232b6e2b2b86fd36cc FileChecksum: SHA1: 5ba9b64a3884d0f4589a73a6e12d337c6b3a0354 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 ARM Ltd. All rights reserved. FileName: ./src/backends/reference/test/ArgMinMaxTests.cpp SPDXID: SPDXRef-cc4c790524390a11b1a035029847da3d FileChecksum: SHA1: acd818a15451092a391078632e6f883735a95eba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/CMakeLists.txt SPDXID: SPDXRef-806ec779ddc919bc01ed469acdab64ea FileChecksum: SHA1: 7250d96f95a20bf1ae3f1e78c6df4b1f5ad37080 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefBackendTests.cpp SPDXID: SPDXRef-3d58e4386164cdcb847914c86de8061f FileChecksum: SHA1: 703a4d20de10e60936991af7bf9ba6b95bce0f15 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefCreateWorkloadTests.cpp SPDXID: SPDXRef-170619d068bd5ad9ca0cd7af2f8aa01f FileChecksum: SHA1: fad624e903fd7183308ac18c3a180c59401f2ebb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefDetectionPostProcessTests.cpp SPDXID: SPDXRef-87c6f9ea3e4f66e57e5f824b4233b2d2 FileChecksum: SHA1: 916b2b688efc8bb8b6d77b16b1381dfcbd739a29 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefEndToEndTests.cpp SPDXID: SPDXRef-06ee1ba1e1d6b705a67eb82b3390f9ac FileChecksum: SHA1: 952849467a39348cb1563bd856d316e25ef61a85 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefJsonPrinterTests.cpp SPDXID: SPDXRef-d4c942b280a65cdb060752d89aac9c31 FileChecksum: SHA1: d0bd0eff28ef3950cff870409f0199d8558e8fbd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefLayerSupportTests.cpp SPDXID: SPDXRef-c02e63b7770270f7b08f9fc20af6c595 FileChecksum: SHA1: 15534f5af9cd230914485d48967ac95bcdf9b84f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefLayerTests.cpp SPDXID: SPDXRef-d37872d7ea1d5a58350248ac6ed58d8b FileChecksum: SHA1: 63ff19fcb7acda54f1428fb06bc8cb2133257e40 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefMemCopyTests.cpp SPDXID: SPDXRef-c80058b223e79bd1d006d606cee2f632 FileChecksum: SHA1: fbb904c2bc192331ec231706f9d26779a512a137 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefMemoryManagerTests.cpp SPDXID: SPDXRef-82d72303e6791579ea24ef972aa04946 FileChecksum: SHA1: fea799b3f087e3d8d387d53b33e8906b9abd7457 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefOptimizedNetworkTests.cpp SPDXID: SPDXRef-3b4035771154f76e38bce74876202fe5 FileChecksum: SHA1: 6255bf3555b6f57759ba8b6c5ec2dab50bc96f25 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefPerAxisIteratorTests.cpp SPDXID: SPDXRef-c780271efa5ab01e58e76dd69e11164d FileChecksum: SHA1: b90a5463476d1f5c6a71c297d8c01d767a42ebea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefPerChannelDecoderTests.cpp SPDXID: SPDXRef-a30b535b3067e7df850d7bb37f859b27 FileChecksum: SHA1: 582453603ffcf0140e2135e2848a460b72fd31c1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/test/RefRuntimeTests.cpp SPDXID: SPDXRef-022838d029c287d17ae79d40f79dc913 FileChecksum: SHA1: 5dbe4d648540390a3ca92e7be9bad5098830e2d4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefTensorHandleTests.cpp SPDXID: SPDXRef-6c3961849659f7dc91afc11e1132ef72 FileChecksum: SHA1: a5d6c5fd72e6f5fd91737b5665db2794f4bf9c99 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/test/RefWorkloadFactoryHelper.hpp SPDXID: SPDXRef-80f61960db2f9c43cd15702aad36a222 FileChecksum: SHA1: 8da246d39f8a7c99891cf6a4e458bff73a1329c2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Abs.hpp SPDXID: SPDXRef-457ad98c6842a454c67b33d1d5d99b2c FileChecksum: SHA1: 0c584665b708e0df07e7abf2fc21fe1f3b8085ca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Activation.cpp SPDXID: SPDXRef-a25b0f4ccb81f99f6b818b5cde54cef3 FileChecksum: SHA1: fd1f2f31f7df2ed02229e23fa06665589b465ebe LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Activation.hpp SPDXID: SPDXRef-9c4f6013dd37c855c2e8c81f45d9d676 FileChecksum: SHA1: 18be1540c849b54bc845cd75b51c3b08339a0083 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/ArgMinMax.cpp SPDXID: SPDXRef-0e463add4c047661e2754dba83151b37 FileChecksum: SHA1: 80e3d61f7b977225f0365e8a236e02bc36d58dba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/ArgMinMax.hpp SPDXID: SPDXRef-db0c435f13eca8ed5700a3e18b3d0176 FileChecksum: SHA1: 9c0927ef4734945d6882e32fea87fc47e96ebf3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/BaseIterator.hpp SPDXID: SPDXRef-42cfa4503b6af696008c6e33f5d70f7d FileChecksum: SHA1: 771c304dcf4b91e9e95a92f118be956ec1e13a65 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/BatchMatMulImpl.cpp SPDXID: SPDXRef-d1f1ecaaba8ac246be7ed7a999705556 FileChecksum: SHA1: 43773f57c092e4a25f8e542a123164e74da1093b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/BatchMatMulImpl.hpp SPDXID: SPDXRef-c819f8e675887174720d390589b5a08d FileChecksum: SHA1: 151d6467b1140a6f4f27089a7ceeb1c4fe2c7249 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/BatchNormImpl.cpp SPDXID: SPDXRef-040ffc258f22c4adfc98d789accd5e43 FileChecksum: SHA1: 520c9e243b34458f57d34068eab8d53a810be7fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/BatchNormImpl.hpp SPDXID: SPDXRef-c7f74a9c5c3f64753b02e051da1027b2 FileChecksum: SHA1: 676781971ab3420be4da2de6c115a4adaf53a978 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/BatchToSpaceNd.cpp SPDXID: SPDXRef-802a2c771652bd8fd724427f082f7452 FileChecksum: SHA1: f11cb2796e77bc6687a5f0415b64b8152bee8246 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/BatchToSpaceNd.hpp SPDXID: SPDXRef-d0f10431516b07a07f196d37a1124646 FileChecksum: SHA1: 0ad6165eac9261ee6b67da2a6afd7192caa1e927 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Broadcast.cpp SPDXID: SPDXRef-71c8a1ebaa1d390e782f3e53648e7b07 FileChecksum: SHA1: 1f632f9094f4c3aa8f5943bdc21496d1b62c6332 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Broadcast.hpp SPDXID: SPDXRef-c306e046835cd296a3ae842d783311f8 FileChecksum: SHA1: 18630a36960282e7e6a127d4619058864ecb4537 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/CMakeLists.txt SPDXID: SPDXRef-5c71786f88ba5fe144f72e3a29bbeb1e FileChecksum: SHA1: c0e121552290c76c326fd4a7b907cc724bef7c73 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Concatenate.cpp SPDXID: SPDXRef-1a1b73c6e1bec952bf7c806e8cbad91d FileChecksum: SHA1: c381ad809a497a80aa1d1f92fd776b0d09a0e3e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Concatenate.hpp SPDXID: SPDXRef-b9b3c348448533b1ae243f63eadd6db3 FileChecksum: SHA1: 20b5ed466c1e56589a5d2d929c31f7eb85bb03b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Conv3dImpl.cpp SPDXID: SPDXRef-784d5653828bae64364386a9856fc124 FileChecksum: SHA1: 9fd148c7bbdd2810792874a4024c176279bb46dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Conv3dImpl.hpp SPDXID: SPDXRef-dee912dc21ee4799a176e633f22ba29f FileChecksum: SHA1: eba7872efef3a964c23438204d91cea4ff3df72d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/ConvImpl.cpp SPDXID: SPDXRef-3df0411710e68d958c7c09593dee76bc FileChecksum: SHA1: f24bdef03436eb368757efacd0a0adc242d5dbbf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/ConvImpl.hpp SPDXID: SPDXRef-0a16de12bf5a0567f0523f0c5213bfe0 FileChecksum: SHA1: 9140239146079127cf0d5fe8e38d4b6255bbcca3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Debug.cpp SPDXID: SPDXRef-5051613237f295afa6dd95f5884fd2c8 FileChecksum: SHA1: 389c23962bdcea13112f5e42d9757b069267a39f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Debug.hpp SPDXID: SPDXRef-97b1b5df13a4eecddee1932e0f5f6ba8 FileChecksum: SHA1: 508e806d9aa5937d07e0e46ce023bdf5dd2ba5bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Decoders.hpp SPDXID: SPDXRef-1e0aeec076ed2d2c6dc139b366a2d7fd FileChecksum: SHA1: 9025abfb63cc4fd2afa363f14b4bb622d675007b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/DepthToSpace.cpp SPDXID: SPDXRef-29ac2f8f8d6f4eb0520b1bf4b404de96 FileChecksum: SHA1: 7a076b92a11e8847fbd69c63dd2a7c6e8546f9c2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/DepthToSpace.hpp SPDXID: SPDXRef-fef4188fd87f511ad313b5b6f9ba4375 FileChecksum: SHA1: 56afe59cfb55e342fe19fde5a35f68674fa8f40b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Dequantize.cpp SPDXID: SPDXRef-1fd32e6835719510ec89515353f16b5a FileChecksum: SHA1: 658a6c86d67d75e319a0c07f229773c7429cf30d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Dequantize.hpp SPDXID: SPDXRef-b5b7c3bb5f845d71035546c3481b677e FileChecksum: SHA1: a3c80257c952f56c6d3d7ac947ae79779e274897 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/DetectionPostProcess.cpp SPDXID: SPDXRef-3f5b2547ef502fca6ae6279c18f664be FileChecksum: SHA1: 892354846d328e8c478ca00a01ad0b8086084fd2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/DetectionPostProcess.hpp SPDXID: SPDXRef-f5ca5b629b681a6ffa91e9566aa9bbaa FileChecksum: SHA1: 2f4b09abff7eb3726e102ecddf19f3cf361cb056 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/ElementwiseFunction.cpp SPDXID: SPDXRef-c870e7382831b13e2d877cd6ce261457 FileChecksum: SHA1: e0cca0cb05ddf51a9cac7b8eb7bd814985f374fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/ElementwiseFunction.hpp SPDXID: SPDXRef-7d4a774f198d815a08f0a829f0e9673c FileChecksum: SHA1: c109d1b8040e5fc37ba0dfb87d4ef57e77d5a657 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Encoders.hpp SPDXID: SPDXRef-78fd649b8c0526c0ec455387d4d78571 FileChecksum: SHA1: 828bc3f3784f45b716656dc623d12f36ba4fc495 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Exp.hpp SPDXID: SPDXRef-8d0b841d1f98d385e6faf290088abdbb FileChecksum: SHA1: 53a1ffe311508e9f4c237ec305fb0e30ea98d23b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Fill.cpp SPDXID: SPDXRef-473c8911ab3aebcb5d43041207818698 FileChecksum: SHA1: 7646526a1c4f7a047d87b0523651cc0b1e3c2051 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Fill.hpp SPDXID: SPDXRef-41f16aa9f373c7130509e4c33a2fb3a2 FileChecksum: SHA1: 76241bb8a7ab8f0453f753d854b56b23ca41d56d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/FullyConnected.cpp SPDXID: SPDXRef-8e5b0b3ede2bf14dc7c63050dd6e6cf6 FileChecksum: SHA1: 44deb6b98b8b53acb38c07206c525a4a8d96e398 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/FullyConnected.hpp SPDXID: SPDXRef-ec619ee5ea13662b5fccda4fe6d6c99e FileChecksum: SHA1: 20ceb26bbdc0b53918c744c0cbfb6e91730e05e6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Gather.cpp SPDXID: SPDXRef-16bdab73392f548ce4b9a7c692b50bf2 FileChecksum: SHA1: e651d6c2b044ba9f4635847ef1e323ba53b7c802 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Gather.hpp SPDXID: SPDXRef-afc33db8c69189030d91908f6a131736 FileChecksum: SHA1: 248d4f630ab34abbfdaa7a74b5a8684b7fda0acc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/InstanceNorm.cpp SPDXID: SPDXRef-2dd59dec8bed934b60d3893349e8cc39 FileChecksum: SHA1: c7dd7326ae2b7bf3c882e4d0e8eb65f70a17f756 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/InstanceNorm.hpp SPDXID: SPDXRef-6865c09f4b96627bb053c6962db21908 FileChecksum: SHA1: 5ecc3a9a88df1bfba98345bbab16a5d97bcfd9a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Log.hpp SPDXID: SPDXRef-20f2a6ab0f3aacc2dc90eefaf660d82d FileChecksum: SHA1: eb334d962105dcfec41f7ec78f88165ffc1597c5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/LogSoftmax.cpp SPDXID: SPDXRef-752d323c08d1b4e372242adb1c460438 FileChecksum: SHA1: d5bad2347b2c34f9cbf9378c2c6b10b9a52e72b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/LogSoftmax.hpp SPDXID: SPDXRef-540a03ccade1fead0cd7d9c33fb754d2 FileChecksum: SHA1: 07ddcf991b0be19281032dad30f58f121779016a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Lstm.cpp SPDXID: SPDXRef-0884a6f89f9562425b96739defedc25d FileChecksum: SHA1: fb3674390b0958f01d2025fbfb3f39ba919f1dd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Lstm.hpp SPDXID: SPDXRef-1c8367bd1e45d14993b1c781aa1644f1 FileChecksum: SHA1: da9314a8a3da80d449d8d2ef54e631ab6775b540 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/LstmUtils.cpp SPDXID: SPDXRef-dcca9c54b74dfba7f0933d657bef19c6 FileChecksum: SHA1: d3d3b1c9687fee108854cea0b52768930315b817 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/LstmUtils.hpp SPDXID: SPDXRef-2def26b3c32df96f6f7558a6055b0cf6 FileChecksum: SHA1: 7f5ca5093517dae0f93e9292adbc20e609ff51b9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Maximum.hpp SPDXID: SPDXRef-d368d97c1550809399188a31e7e49219 FileChecksum: SHA1: 7915cff0ecbb353225c7e703c472c9150d11b010 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Minimum.hpp SPDXID: SPDXRef-9ef7a4e98c5eda00ee02b7156778a223 FileChecksum: SHA1: 90ec7d098a8163d9f18f7f12b5d931f129181c77 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/MirrorPad.cpp SPDXID: SPDXRef-2d0eba3c3e34a57886fc371149dc6f52 FileChecksum: SHA1: 371e9faad0b4131d4daefc3baf5987e034fcd3ef LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/MirrorPad.hpp SPDXID: SPDXRef-791087ac99e14596121b88a4fc79e9b2 FileChecksum: SHA1: d8bfc6a1763ce7b61f946a18344dc1691ff0edd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Pad.cpp SPDXID: SPDXRef-56f13f08f4b19e259ae6ddd280ccbc77 FileChecksum: SHA1: fb390f99158cac947598daba73507da525f55c09 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Pad.hpp SPDXID: SPDXRef-32e6e3ad59e3fec80c043168760ccac5 FileChecksum: SHA1: 47ca72f9f523a55b37469e500d08fcc4f93c55ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Pooling2d.cpp SPDXID: SPDXRef-0da39e9bfc40c4f4b48c5876c7be2228 FileChecksum: SHA1: 6ba2d63c7dcee97b07c47df6d700afaa989165cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Pooling2d.hpp SPDXID: SPDXRef-8864453396fda104e392910940bb27de FileChecksum: SHA1: fa0ae8919a85c90a5a71d28478de6f60bc7e13b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Pooling3d.cpp SPDXID: SPDXRef-92f34bcc5680ef1f71b49952c96c4b6d FileChecksum: SHA1: c0af13f0800ed4a052a304462842513ece5f0da0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Pooling3d.hpp SPDXID: SPDXRef-74baed07e7c0097e813405e063e585b7 FileChecksum: SHA1: d5ed2ae6b77f96aa417a84169500f4cb853d66d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/PreluImpl.cpp SPDXID: SPDXRef-b1d7f068b4796ff4a48d49457a25a15b FileChecksum: SHA1: 4e17fbb83668f13a5f7266a4cd7430dcdc18bf51 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/PreluImpl.hpp SPDXID: SPDXRef-6f009c00d52e8721c2b5bb0877aefe88 FileChecksum: SHA1: 33ce981e269b64f6cbf4a2709c0de6cfe6bb6a4c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Reduce.cpp SPDXID: SPDXRef-f5b5d2472fe70fb27944e10e8e8b9788 FileChecksum: SHA1: 90f7139855b91038d261716decb41d5372898047 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Reduce.hpp SPDXID: SPDXRef-dbf7cd36d5dcabdb0b640a9a0072d4e2 FileChecksum: SHA1: dc3c2ac9b562cbbbcc70ac0f1ce526ce59e3f433 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefActivationWorkload.cpp SPDXID: SPDXRef-0e0e8450165ae5bd1ec6f153cf0e7eec FileChecksum: SHA1: e1cd74045b45b04c30756634a337911177fc8e9e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefActivationWorkload.hpp SPDXID: SPDXRef-95810a89309e0fb19eddf0a8218ced82 FileChecksum: SHA1: e6df197b9933c23129a8b17588692abac3ab75f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefArgMinMaxWorkload.cpp SPDXID: SPDXRef-b40543eeb1c373d34f0d466bbae434d6 FileChecksum: SHA1: 306f1f735fac9f7c0d2c3977fb5c05951f719dbd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefArgMinMaxWorkload.hpp SPDXID: SPDXRef-bcbde09f7f6a88b66c4a0930e0738d5f FileChecksum: SHA1: 8d188f06f923647f7e0fd28c88ec07276c0bacf8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBaseWorkload.hpp SPDXID: SPDXRef-405f1e36e08a8153f9e8ec3846719cfa FileChecksum: SHA1: 4a12735a93d0c5c32e0e927ce02035371f2403b1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchMatMulWorkload.cpp SPDXID: SPDXRef-7c298eb484863f540f3c7214efa32463 FileChecksum: SHA1: e4d58812d726b3b1d368f29a5b55530d26f34fb5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchMatMulWorkload.hpp SPDXID: SPDXRef-0f75612a1c967171487285b36e7c2c50 FileChecksum: SHA1: 7e453610f205bca0a78e3e4fe589752e1ed69002 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchNormalizationWorkload.cpp SPDXID: SPDXRef-547473d45a797e662c36204f8d63cd5d FileChecksum: SHA1: 314600d98dcfe0d1c792d81ec25506e09e99da75 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchNormalizationWorkload.hpp SPDXID: SPDXRef-a7ff50e0a05365c10b75a8f2265bb3df FileChecksum: SHA1: cceb362397ef697ca778b8c24660a6f2719fc28e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchToSpaceNdWorkload.cpp SPDXID: SPDXRef-df54e8729f72a7e0107bfb4124f562cf FileChecksum: SHA1: b0eb2d1e214e6ef85fc2843b662b8bfb63373988 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefBatchToSpaceNdWorkload.hpp SPDXID: SPDXRef-3fd9091fbf43a525cc7b2e77aff0cfa3 FileChecksum: SHA1: 730845f0d7c829f0c47c3d0798b950c8dfabc4f4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefCastWorkload.cpp SPDXID: SPDXRef-48e73fe0f00fe0fb08b15631bbf60fd2 FileChecksum: SHA1: 6b681f02f54f00ca9f485ddc237005469375f5e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefCastWorkload.hpp SPDXID: SPDXRef-dee8e27886f06162fa6536248607a937 FileChecksum: SHA1: f4b8eba864de959787460db951976ae2d3e4db42 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefChannelShuffleWorkload.cpp SPDXID: SPDXRef-ce98ed39ae34b0d175961d5d9234ecf4 FileChecksum: SHA1: eb08ce776480758c714b0acc760a4fb519360ae2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefChannelShuffleWorkload.hpp SPDXID: SPDXRef-6dd3302214e3aaeb19745d3479c9402b FileChecksum: SHA1: f204983806ed6cc8446234ccf26dcb594b9eecf3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefComparisonWorkload.cpp SPDXID: SPDXRef-3d31023a3ed945741bf4e1e04def5cf5 FileChecksum: SHA1: 34713900079c86115040ae40a7381b369f3dd1a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefComparisonWorkload.hpp SPDXID: SPDXRef-8a685adac362e1b09b33fbd11b82e898 FileChecksum: SHA1: 77ec0801ad2f153e14c38c250b8739d15aa05e5f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConcatWorkload.cpp SPDXID: SPDXRef-5c76760099495c2be1f13e5d47cc8a24 FileChecksum: SHA1: 95c406de65c1c9d7f709e8df1526d0c089db630a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConcatWorkload.hpp SPDXID: SPDXRef-b34aa1406010b4071cc114301f020319 FileChecksum: SHA1: 9061471afb8457631aad650c8ce722f561843970 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConstantWorkload.cpp SPDXID: SPDXRef-c4f7119a824ca774964ea9238f9e9213 FileChecksum: SHA1: b3798815d708f3aaf673a0cdc34392903ab0de99 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConstantWorkload.hpp SPDXID: SPDXRef-7e5b9258a563675f4bc76e753153300d FileChecksum: SHA1: 10329dd0438944fcdc83e79abdd9876726e4a396 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertBf16ToFp32Workload.cpp SPDXID: SPDXRef-d2439b00519ddb2511ac4fe2f57ddbd9 FileChecksum: SHA1: 3ff5adff610beace0b6e30327e550ce796c3f998 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertBf16ToFp32Workload.hpp SPDXID: SPDXRef-573ea3ee2c42fca1a9493ea7d2f1ceae FileChecksum: SHA1: 09be0709b835c7c252397e1514fda79bc9171f62 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp16ToFp32Workload.cpp SPDXID: SPDXRef-9b4455896965e5d27ad0032fdc660cab FileChecksum: SHA1: 611fafd613afb3128a93dfa89e9e686976755425 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp16ToFp32Workload.hpp SPDXID: SPDXRef-68f668ad659454cd78427d7f601bd9d5 FileChecksum: SHA1: c941f77d8230c38d1f5d2103395756b46fd641de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp32ToBf16Workload.cpp SPDXID: SPDXRef-5f17babc320da30972a19078105da194 FileChecksum: SHA1: f6e5233ec8c6c411c803f943a51cb4bc2e741165 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp32ToBf16Workload.hpp SPDXID: SPDXRef-87cb21e39edf1fda58fe56a198e9a2bc FileChecksum: SHA1: 2e388303034b0cacdabe8237b6277753a0db9c3d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp32ToFp16Workload.cpp SPDXID: SPDXRef-c327b7a6e944ec429ecc9cff2486a2b8 FileChecksum: SHA1: a9f4d020d5eb47fda68e9d876714b9de1d1a9765 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvertFp32ToFp16Workload.hpp SPDXID: SPDXRef-32f17f92fedabbfdaf86e508d262ca5e FileChecksum: SHA1: a601212b1fdac1922223164dd86ddb1251835992 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvolution2dWorkload.cpp SPDXID: SPDXRef-943b58b1d1fb93230a396423b4f9fae7 FileChecksum: SHA1: c518c57220b85b79fc915a0ad5ad3b12207cbc6d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvolution2dWorkload.hpp SPDXID: SPDXRef-c26ace27d958d9176f97c3089242efec FileChecksum: SHA1: e0e0ed7e99112de02d44bdde4aae817f6aab0b48 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvolution3dWorkload.cpp SPDXID: SPDXRef-e73ca993a44b43b25ad546d09d77d921 FileChecksum: SHA1: f8017be83bd29a500000fb266dd8c768b4a5d528 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefConvolution3dWorkload.hpp SPDXID: SPDXRef-e78a25f6821a3bfaa088f53f60785ef0 FileChecksum: SHA1: 441c013cc87d70adbd08a34ce0ed42da7b50a525 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDebugWorkload.cpp SPDXID: SPDXRef-337a4f06bad916d50327ecde24baf3b3 FileChecksum: SHA1: 684f7bb73bc966ba594e7c9857187da87373fb84 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDebugWorkload.hpp SPDXID: SPDXRef-b1b98f416fcd1c99fdd37de41cc829b9 FileChecksum: SHA1: f878409ff205e9fd8fc6c96fced308c3effb22b1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDepthToSpaceWorkload.cpp SPDXID: SPDXRef-ae8ca64467bb380b0a45953726cec492 FileChecksum: SHA1: ca039c9589e7b239f745ef439f1ee9c08c276d89 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDepthToSpaceWorkload.hpp SPDXID: SPDXRef-d104d62c2027b524813451e2f09bf893 FileChecksum: SHA1: 1d21b0d0f02faff00b592c931d916596366fb78a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDepthwiseConvolution2dWorkload.cpp SPDXID: SPDXRef-d93437c13e60952ecfe9363f6b790b68 FileChecksum: SHA1: 3cfbecd5377e240c3ef4ded02a98f1986bd648ad LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDepthwiseConvolution2dWorkload.hpp SPDXID: SPDXRef-a5c522cc3c2c09ed1115e1132c08ce6c FileChecksum: SHA1: 5bd1f20a383f521a76aeebd171a7eb9c7f948474 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDequantizeWorkload.cpp SPDXID: SPDXRef-fcc8c59ee819eb8dd1d590acf3afa73a FileChecksum: SHA1: cf2adabd88d90a3c544ce225441211c964b976ec LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDequantizeWorkload.hpp SPDXID: SPDXRef-ecedd6580991173a098444e7b0bc2942 FileChecksum: SHA1: c310e82cdfbaf6691e3feb3578bae4f79105245a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDetectionPostProcessWorkload.cpp SPDXID: SPDXRef-920265e262715b8175e72918a13e88f1 FileChecksum: SHA1: 458183081d7b01975e79df9db659028bb41f5739 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefDetectionPostProcessWorkload.hpp SPDXID: SPDXRef-44fee6e6a520dc1dc52a0a913ae98890 FileChecksum: SHA1: 89299a12c3fdf6c7ed403dae8b8e81ec0a5af037 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefElementwiseUnaryWorkload.cpp SPDXID: SPDXRef-eda9f4d14ac6bccb19a62ddb228084c6 FileChecksum: SHA1: cc74513bd90deddbd64c6a4e6effe4200b2b0205 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefElementwiseUnaryWorkload.hpp SPDXID: SPDXRef-c6e2adfd2292db7559aec2786c94af91 FileChecksum: SHA1: 7d940177211ddf203828fc7e1feedc83e05a8e64 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefElementwiseWorkload.cpp SPDXID: SPDXRef-c76219737bacf504112df1105bcbce0f FileChecksum: SHA1: 5d8907d6b59a25a9b3fcccaa41250dbbb037726d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefElementwiseWorkload.hpp SPDXID: SPDXRef-e65ccb2e1be9849128b489c6006f1ffb FileChecksum: SHA1: 4e924095541d0a1b7663761b3518ab998bc01ee2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFakeQuantizationFloat32Workload.cpp SPDXID: SPDXRef-2bbcae3fe3318befc148e5c60fe0bb78 FileChecksum: SHA1: 00e3f09015469edac7ddd7df5bc9cf1256ee2bba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFakeQuantizationFloat32Workload.hpp SPDXID: SPDXRef-4cc7816e122b4f804c92a4be09137ae1 FileChecksum: SHA1: a7dda85ff128d14c7245b5a436be1bddb0f2f9cb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFillWorkload.cpp SPDXID: SPDXRef-bf64feefb45402a1ece7cd5584778cf3 FileChecksum: SHA1: 38bd3e7ad1f6c845561b404179e8af93659b47ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFillWorkload.hpp SPDXID: SPDXRef-8214ef8cfd192fd1c7454d99ef450f80 FileChecksum: SHA1: 9a7aa646440182910154497c81d59d8ef0c0328a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFloorWorkload.cpp SPDXID: SPDXRef-f2ae33e8eb011ee58c2d09499ea5bdc3 FileChecksum: SHA1: 2e4af99f99410a1d57acf33fde3d58fb45d972d6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFloorWorkload.hpp SPDXID: SPDXRef-8dd9151e2a0b1a89d6224d68a959ac2f FileChecksum: SHA1: 402b57450a2bbcfcc6fbb9d9a40336ea8d802a21 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFullyConnectedWorkload.cpp SPDXID: SPDXRef-e19079db2f93281a66018eb657ba20f6 FileChecksum: SHA1: a729b1e7291014f1f9db7cc14fce86da8db2afe6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefFullyConnectedWorkload.hpp SPDXID: SPDXRef-82337c35a3b6e5bebe5b0a59291e7908 FileChecksum: SHA1: c3f51fdca18e295b98f7970d8ff588340279dfe1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefGatherNdWorkload.cpp SPDXID: SPDXRef-7717a99273759d5f81f526cb6a462ed1 FileChecksum: SHA1: af1ab4f8dd1db415cc39005c26826f6bcfa887a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefGatherNdWorkload.hpp SPDXID: SPDXRef-f35970cd7c46d7b3fdafc80e12786824 FileChecksum: SHA1: 26801f7bce82f59c2adc9c15536ff8e21eb5d50d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefGatherWorkload.cpp SPDXID: SPDXRef-bf0a5fc441dae45f51cd9a0cdb8aab62 FileChecksum: SHA1: 001920dd321634be22bc0d064dd14fccb6b484d1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefGatherWorkload.hpp SPDXID: SPDXRef-7c0d459be569f5f125578f63b95b4381 FileChecksum: SHA1: b95a1e7ad1534b6a4fa55dafa9b2f89673f447f7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefInstanceNormalizationWorkload.cpp SPDXID: SPDXRef-1913a73ba8f8c7483866a784e45e5037 FileChecksum: SHA1: 0dfeac3af5b3ccedb59018ed890b19ccec067b5e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefInstanceNormalizationWorkload.hpp SPDXID: SPDXRef-049a5a921335f6d491d3e8bc42c4d2ee FileChecksum: SHA1: 4bc4aecf51b6844d3f0de7e373801a7427ecf873 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefL2NormalizationWorkload.cpp SPDXID: SPDXRef-920c558b3fed91eddc3853e590cabb0c FileChecksum: SHA1: 28381a4c6bd01527b3be374b9d2fadce1fdc15b6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefL2NormalizationWorkload.hpp SPDXID: SPDXRef-b372a4f8782ca35674c8fcba60b91e1f FileChecksum: SHA1: 8fb0c5f622869f8768c7d38b09f591a4fe14f8f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogSoftmaxWorkload.cpp SPDXID: SPDXRef-80d143c4c355fbed1917af97ca0500ee FileChecksum: SHA1: 626f46a7f0dbe935656dd51809252dfdef41a832 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogSoftmaxWorkload.hpp SPDXID: SPDXRef-de4dd9a3d8fe083d70f1ecb80b7a28e2 FileChecksum: SHA1: da97f3bda704f2034283f11fd3b54a399215465d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogicalBinaryWorkload.cpp SPDXID: SPDXRef-68b14268ac5faf2a9d3cf36c8cffacbc FileChecksum: SHA1: a7cb7851c03863cab2386b60e60e3ddef502cb52 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogicalBinaryWorkload.hpp SPDXID: SPDXRef-a7f211f226e787a6ed3d46dd11929913 FileChecksum: SHA1: f33c5746a5f51af9fc1f9894568a2a6b2a79443f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogicalUnaryWorkload.cpp SPDXID: SPDXRef-721081ee5e66c0b615f1c4d5e9e52f3c FileChecksum: SHA1: 9dc80b49941e53457862fb25175e39791b8c26a7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLogicalUnaryWorkload.hpp SPDXID: SPDXRef-849e259e210af3a81f93846458797fc7 FileChecksum: SHA1: c5736ed980bca73a67586bf371d55ea5fb1f177e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLstmWorkload.cpp SPDXID: SPDXRef-e9c1f543ab0a4fd63e45d9aefe9957f1 FileChecksum: SHA1: 73f2fa552de7689c35b283d462fcbd77633a292a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefLstmWorkload.hpp SPDXID: SPDXRef-15256e96680dd668b94e8fcd1a298104 FileChecksum: SHA1: e4d1887d6119482e4f2b12b086e952edbf2f16e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefMeanWorkload.cpp SPDXID: SPDXRef-1fc6eee2f4567398ce7b3f447b733cdd FileChecksum: SHA1: 777fe45571d16e2a66d35932b1a235762dad04dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefMeanWorkload.hpp SPDXID: SPDXRef-f0c2510a0df8b33890698d4c66b3346f FileChecksum: SHA1: 89d8a5b97d2e07eea74a503b0df990a76d063a1b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefNormalizationWorkload.cpp SPDXID: SPDXRef-589a177ea060dcebf6080262ad7507d2 FileChecksum: SHA1: 2f8618af0704ef2607f552c4f393e85d34ef165d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefNormalizationWorkload.hpp SPDXID: SPDXRef-979e121aec1daa8ffb2e91d37497d22e FileChecksum: SHA1: 95cf10fdee4228ab847eaafac61c273c8950a4f6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPadWorkload.cpp SPDXID: SPDXRef-c17bc45fe8e9ecfe699e57c463f61d69 FileChecksum: SHA1: 1039929aa926b7cbb1da288e6110c6920e7be3e7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPadWorkload.hpp SPDXID: SPDXRef-2b39c59bb5d108271e6ac718eafc6677 FileChecksum: SHA1: 564f1568aa45eed50dbf7504a35f1d4f35a862bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPermuteWorkload.cpp SPDXID: SPDXRef-9a3a14f0b010765a95845d8c9cdd6a8d FileChecksum: SHA1: 7176cd6b650bbe46aa4364ae52772d9939e25770 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPermuteWorkload.hpp SPDXID: SPDXRef-b1caf40b62be07d5f1656e52bbf13484 FileChecksum: SHA1: c497996f6fd241b59a83cf111a99df942e8cd875 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPooling2dWorkload.cpp SPDXID: SPDXRef-53abb0eaec77793655baed90ba5498cf FileChecksum: SHA1: b923edb76edee8e1cbc27e0a69818ecb2f1ddd2b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPooling2dWorkload.hpp SPDXID: SPDXRef-a470ae12c98a082586981fa7512db2fa FileChecksum: SHA1: c10ef462f7f2253daa8f9dcaa4b2f9a66713258c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPooling3dWorkload.cpp SPDXID: SPDXRef-a3bfcd19be45a7560bce560aaca3ff09 FileChecksum: SHA1: bcf771d80c1f29ae1a1ff95980839f80aafddd45 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPooling3dWorkload.hpp SPDXID: SPDXRef-e90d38c4a562d02d8f9625551ec663f7 FileChecksum: SHA1: d69d982851c6f262a8889cf4c53b7a7c88e3b775 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPreluWorkload.cpp SPDXID: SPDXRef-e4ae6ca0476a1b6da6a880ae3a7b8de1 FileChecksum: SHA1: f7bf6e634ab261a772f99db9277b72eaab0526f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefPreluWorkload.hpp SPDXID: SPDXRef-2792712d05eba2025039df667744a025 FileChecksum: SHA1: 4ed8faf71b209809236add8163a65fd7cb6553bd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefQLstmWorkload.cpp SPDXID: SPDXRef-3c98c80b07e79d528353ead6ced9e46a FileChecksum: SHA1: ce0794decd9d47ff493b641e522ccb93d94591b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefQLstmWorkload.hpp SPDXID: SPDXRef-df78927cba1f348412ba383b7fee013e FileChecksum: SHA1: cb3c054df2ffef37dcd7e4f53c9528f25d9e5774 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefQuantizeWorkload.cpp SPDXID: SPDXRef-6ca038bd55e0558a50de908de3e5be2b FileChecksum: SHA1: aa5fdd975d5585b8b72b79be708d188d64bb3141 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefQuantizeWorkload.hpp SPDXID: SPDXRef-88cd5e89c69636f73786f0271752684c FileChecksum: SHA1: d2aa462bf8fe8ef602884a10a6cdd8ddc46a0bcc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefRankWorkload.hpp SPDXID: SPDXRef-affd847516b2f957940ad072e8dc3628 FileChecksum: SHA1: 667b5ef607872ce57c276f2b01ae14cf77aa18db LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefReduceWorkload.cpp SPDXID: SPDXRef-3c2906ee62fc7838dfbe603fe7b5addf FileChecksum: SHA1: 6f35d35ac705ebd595c97554e733d00243c9635e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefReduceWorkload.hpp SPDXID: SPDXRef-f632f212cb44422844a6d60cf16a5b48 FileChecksum: SHA1: 66d2ece062df3b943903d6818e81fe510a64ab46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Samsung Electronics Co Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefReshapeWorkload.cpp SPDXID: SPDXRef-3b2ebe4ad4ed2635be764cd18f7e3f1f FileChecksum: SHA1: d9390f3616a201f94243ed59acf30de6e66c85ae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefReshapeWorkload.hpp SPDXID: SPDXRef-511712638158a83b0dbfb24427e43f4e FileChecksum: SHA1: 76c41147dd4d7e3820074825da59950a0335d590 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefResizeWorkload.cpp SPDXID: SPDXRef-daac5d00e2e47da21897bbdd42dbad8d FileChecksum: SHA1: 795f89c9749bedfa29d2cbd40e9553fb732d39c6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefResizeWorkload.hpp SPDXID: SPDXRef-20ef9d012db5911f644347e9575496cc FileChecksum: SHA1: e99cfe4152afa511b862ae6f720997318f48eba0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefShapeWorkload.hpp SPDXID: SPDXRef-e2598e157f998bc0b4ab4e39a780c334 FileChecksum: SHA1: d33d5664bac37581dc0444ae53ec08e11264c18f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSliceWorkload.cpp SPDXID: SPDXRef-9ee134ac36d702fe2d22d5b0f22f88a6 FileChecksum: SHA1: bf28d202533ea83ea465477c108f7e1cc3e52624 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSliceWorkload.hpp SPDXID: SPDXRef-9d3335525f99847166d088d7c2f6ec6b FileChecksum: SHA1: 2449dbb8b0ea2350e00604946fc20d596f00facf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSoftmaxWorkload.cpp SPDXID: SPDXRef-add295261dc1f41d84cb99b2cd555c8a FileChecksum: SHA1: 8e044030c2ced91437dceaba54cf4b3fa4e3ce46 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSoftmaxWorkload.hpp SPDXID: SPDXRef-d8f2f4578165ea0e54f7cd2249df0f8d FileChecksum: SHA1: 2c77b216e15630282338c0e8be39827993203984 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSpaceToBatchNdWorkload.cpp SPDXID: SPDXRef-fa6aa5a5335cfa2d190f3fb5b6db18e9 FileChecksum: SHA1: a78a7409072b682fea6f2e300f2b11cea9bac6ce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSpaceToBatchNdWorkload.hpp SPDXID: SPDXRef-c28db1b4df4fac8c80465e4e1f1642fc FileChecksum: SHA1: 157fad117feb8d9849f80a291bc25a52e02c2b86 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSpaceToDepthWorkload.cpp SPDXID: SPDXRef-32dc3ae635e9c013704da8a970ddf3a6 FileChecksum: SHA1: 74b1268b1dd5c1273764087c311c0831dcd866fd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSpaceToDepthWorkload.hpp SPDXID: SPDXRef-14549c7fd01a6845cdf40d7642706dd6 FileChecksum: SHA1: 710bc66a88dba3f7e698f6b24d74a21aba415590 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSplitterWorkload.cpp SPDXID: SPDXRef-67a47c97dedbedc00deb6ec5d8153a3c FileChecksum: SHA1: 38e5ea3cdbd5901b840b51576bd3765c0f5b01ba LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefSplitterWorkload.hpp SPDXID: SPDXRef-cf1dcabfd2c831a9001c5eeabde00322 FileChecksum: SHA1: cc40b7f4ccc89dfa40f3f730ca96fd52e9596620 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefStackWorkload.cpp SPDXID: SPDXRef-e39445d8a0bf29194213b50e9f522e69 FileChecksum: SHA1: 5292fb7dd8a310f1eb4f60d30a4bf7173a201608 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefStackWorkload.hpp SPDXID: SPDXRef-6962131ff9e6c5b8fd9870633ac11877 FileChecksum: SHA1: 4817a439cb119314fb1def98fe4b8aab24e8800d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefStridedSliceWorkload.cpp SPDXID: SPDXRef-e00871db584a32037cd6fdaed23ceb59 FileChecksum: SHA1: 11e44a6e96109dfc779c8d68fc7b124204da0924 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefStridedSliceWorkload.hpp SPDXID: SPDXRef-a1b2031053408d2882c2553d3bba80c3 FileChecksum: SHA1: b9cd2dfb8ac749cb20a32d3201ef218f522fc7f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefTransposeConvolution2dWorkload.cpp SPDXID: SPDXRef-03892a6ee288721c90f3d956146c4eb6 FileChecksum: SHA1: b5632669c78e6533f4d8bee3d18074a74eb97fc0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefTransposeConvolution2dWorkload.hpp SPDXID: SPDXRef-5694b590351195e46e05e135e81246da FileChecksum: SHA1: 5af4910eeb84f673e08f7d349bffa446736fcfe6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefTransposeWorkload.cpp SPDXID: SPDXRef-91a07fb080745073954ef230615c3906 FileChecksum: SHA1: a0148b71e1ecc828589387d1c18b92ab6353c567 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefTransposeWorkload.hpp SPDXID: SPDXRef-252b123bb27c41b54b7813429ae22f05 FileChecksum: SHA1: b46ea43f4b961c3b375e60ec9ec8188573f7afc4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefUnidirectionalSequenceLstmWorkload.cpp SPDXID: SPDXRef-a8e9567fb92e28bd5c2457b197580aab FileChecksum: SHA1: 494ee097c1c7b8d0ddf7662f5c6bfa46659252bb LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefUnidirectionalSequenceLstmWorkload.hpp SPDXID: SPDXRef-dc604730c20864c6702c6a2944cf2e48 FileChecksum: SHA1: 0f55b308bc1974765d0668125a8afb0549f6e341 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/RefWorkloadUtils.hpp SPDXID: SPDXRef-6a2a0f65f70dba3d80e55b58fc4c411e FileChecksum: SHA1: 6621ed3f7f5ddd161d22a3fd35dc24b4cab9fd58 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/RefWorkloads.hpp SPDXID: SPDXRef-2856576895282fb4bdc7090b0c2c10b9 FileChecksum: SHA1: acfee6cb021afd86bfd82e4743993189374180b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Resize.cpp SPDXID: SPDXRef-29ade1e0685453e29324279d19bf7a85 FileChecksum: SHA1: 3c2c55cbf7a79f052c04db7c12ea9095560a3a54 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Resize.hpp SPDXID: SPDXRef-1791282a8698ce0760505c46d9f6ab72 FileChecksum: SHA1: 588ae47b4635ea1b2cf6d9050c98d3007a8bb677 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Rsqrt.hpp SPDXID: SPDXRef-98267dd84dfa750b5f95b4c3837d7150 FileChecksum: SHA1: e0b9f4e7798ab1fe1470b8ef58eb5c115d4d0023 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Sin.hpp SPDXID: SPDXRef-2c8ccab643e3897d9edef6bcce17f702 FileChecksum: SHA1: b142905515851ec4d33aa11bf43bbf3fe43cc983 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/backends/reference/workloads/Slice.cpp SPDXID: SPDXRef-f9279c63d8109b7d45d3e6ddc0facd6e FileChecksum: SHA1: 037f851f067599d0293e0aff220f0417505bb611 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Slice.hpp SPDXID: SPDXRef-45ccbeaef7242f9fe49786fd69bcb3ff FileChecksum: SHA1: a8ef68547b4eac077a5537a092b7a42370b88482 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Softmax.cpp SPDXID: SPDXRef-67245fffe0fca5e22b4f16ee2f1f0003 FileChecksum: SHA1: cf234d95d4b25da174eca921b962515b48778a45 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Softmax.hpp SPDXID: SPDXRef-3bccd0e52816a0c39c6fd25732d7a4fa FileChecksum: SHA1: 19c2b0c8fdba24b71c56e5b78edfaded7198f2e4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/SpaceToBatchNd.cpp SPDXID: SPDXRef-48a81033cecf81a00e43871443ccea38 FileChecksum: SHA1: 558cb2885c01c490125bc550bcc37931aae09071 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/SpaceToBatchNd.hpp SPDXID: SPDXRef-f1bf064a0a28a848bbee8022946d6f4c FileChecksum: SHA1: 96bd4cdc0a5a492b6f799ac262916691f56fe100 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/SpaceToDepth.cpp SPDXID: SPDXRef-cefbfc01e125035523706ff64aaebc47 FileChecksum: SHA1: 68deeadff71b0d7286407ab561c3aabc8b5f8d88 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/SpaceToDepth.hpp SPDXID: SPDXRef-82c74a57ae85de23f1137db4c8dbda61 FileChecksum: SHA1: e585cdfdebfd467db27f67a10c517d95f9e65b76 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Splitter.cpp SPDXID: SPDXRef-da4eae501dc1050fc453df71108f3df1 FileChecksum: SHA1: 0857c5de7b531ad1400d7c472dfdfff22d9e5554 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Splitter.hpp SPDXID: SPDXRef-5f8735ba34d68463bcf78679f2ef3e17 FileChecksum: SHA1: 9dbb75de514c2cae78ededcce7b60d24d6c0c7d8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Sqrt.hpp SPDXID: SPDXRef-af2f3af0174ac2143da732be6be353c7 FileChecksum: SHA1: 5534e721637fd3e69ba64bf445018a72a0d8e18b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Stack.cpp SPDXID: SPDXRef-31828871ed5de3ecf08b3a1ae07b59f3 FileChecksum: SHA1: dfb5af7aecd7bb285b5ea5cd078a9ab067c751b0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/Stack.hpp SPDXID: SPDXRef-2c12b3d3dcb8c767b42ae1158ac5d4d6 FileChecksum: SHA1: 2755ab083a78d1b7acbd0072a2b819e740beb42c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/StridedSlice.cpp SPDXID: SPDXRef-fee59f80d58432c63e568d3fe5ba3417 FileChecksum: SHA1: 92e8c1c276012b55c4bb021f250d03c8bb6c01de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/StridedSlice.hpp SPDXID: SPDXRef-54720d87b38b234eba5906700046671c FileChecksum: SHA1: f02e905f803d2c926f50167a5c1f00a29a2b3dcc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/StringMapping.cpp SPDXID: SPDXRef-d315f47067981889ea4ee03e246ac5db FileChecksum: SHA1: 1c1b5620e4283f3721850e69004635cc32935282 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/StringMapping.hpp SPDXID: SPDXRef-77966834ad953bb82519d2f7e4cd0abb FileChecksum: SHA1: 62e4ca72db4784c7abc31f8d2e10259c3c7c272e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/TensorBufferArrayView.hpp SPDXID: SPDXRef-670d4e27bb119cd896fb4976b3fe52ab FileChecksum: SHA1: 312315c24853263ee95d941650dcdd526a06806f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/TransposeConvolution2d.cpp SPDXID: SPDXRef-bb1c93c10117ea3e9e3eb02610370a2b FileChecksum: SHA1: 53c5dd1e0dd5a64d5a7ed665316bdc6d0eb8d377 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/backends/reference/workloads/TransposeConvolution2d.hpp SPDXID: SPDXRef-261057fcc0ab2f20a67daf4b9e65499c FileChecksum: SHA1: d6cae68f09733f2547a781c9f3610fe53dd943d7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./src/dynamic/README.md SPDXID: SPDXRef-58c47b8160ab9fc55cef1d739b1cf81f FileChecksum: SHA1: e9e68f8847b4b7011a44097bd56c644593af23f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019-2021 Arm Ltd and Contributors. All rights reserved. FileName: ./src/dynamic/sample/CMakeLists.txt SPDXID: SPDXRef-9e9b4cdd52e97b4215a2111fde8c4183 FileChecksum: SHA1: 63a527d4fd70e12a397cf17f613f6cc0be22a771 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicAdditionWorkload.cpp SPDXID: SPDXRef-1e56a88e781740f0165a6a23f3c61d40 FileChecksum: SHA1: 19c32065b1749026b1b9987206f1b747fc5d1271 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicAdditionWorkload.hpp SPDXID: SPDXRef-817462c6fceaa49e3444e2cef953de21 FileChecksum: SHA1: 882c70bf7c4e04ff00530eade298a08529d9eb31 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicBackend.cpp SPDXID: SPDXRef-620c6e3f1f7ff7bd8031f23e1a5227e3 FileChecksum: SHA1: c0f9eaea6e21aca5a3a2be3348d140a40d589f93 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicBackend.hpp SPDXID: SPDXRef-d586e0c1a9c9fcf49e3dc7c335dc8b2d FileChecksum: SHA1: 9f19e1aa4e08297284cb66cab6f8556a6e92b625 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicLayerSupport.cpp SPDXID: SPDXRef-1aebe5f71944d24192d7509a70fad0b5 FileChecksum: SHA1: 85cf3701dfa7c4865bd2134076630eaa15f1fc3c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicLayerSupport.hpp SPDXID: SPDXRef-3607484298296090b118162a3de2fb53 FileChecksum: SHA1: 6f748535f12b0ed8f469743341f02289e983278f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicTensorHandleFactory.cpp SPDXID: SPDXRef-0dd0cac7192ff559a7d7a2e0ebefff19 FileChecksum: SHA1: 5aa1eec04029d044c26421ea66fa5b1130a325b5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicTensorHandleFactory.hpp SPDXID: SPDXRef-d1605924cf8b30d9ac34c379a13c4841 FileChecksum: SHA1: 4f93815101942271181708427cfc6d586a78cf49 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicWorkloadFactory.cpp SPDXID: SPDXRef-e3da77b6626ba190df12009f2e75cefa FileChecksum: SHA1: ea3541cffb8a392ff5bc8d5c2194c707cd329bd9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleDynamicWorkloadFactory.hpp SPDXID: SPDXRef-64c09d482e8fc6cd80346c89d1fe430f FileChecksum: SHA1: 2af403caa1abb3c6a073af0bc53aef1187030478 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleMemoryManager.cpp SPDXID: SPDXRef-607184b3d6febf4f66ccff01cff8597d FileChecksum: SHA1: 134352f972d58ed83eba179d0a545f3416aa7827 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleMemoryManager.hpp SPDXID: SPDXRef-a89995c89e724b5fdd90b5cf30a1e0b5 FileChecksum: SHA1: 4743162bd0f4969ea6c8da2f0335cc78ce7b5972 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleTensorHandle.cpp SPDXID: SPDXRef-34ad943cfcf1615ba250cce27fe30f08 FileChecksum: SHA1: 377a331a205737e9f9745fde70140f47752e1cf6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/dynamic/sample/SampleTensorHandle.hpp SPDXID: SPDXRef-1a94299cf2b7fe916e0052573c1f4a36 FileChecksum: SHA1: c67de97409db4f5d5c1f224b487c319bd23957fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./src/profiling/test/BufferTests.cpp SPDXID: SPDXRef-1f66d2417a307f752ccebc5a3f6c6998 FileChecksum: SHA1: 751d646ad3afc27847bf92c7c6ecab719ba65f30 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/FileOnlyProfilingDecoratorTests.cpp SPDXID: SPDXRef-dbb5a794997374d80c5adc43a50806f0 FileChecksum: SHA1: 37e99add5d12956630461302b58fdfd3e2b00834 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/PrintPacketHeaderHandler.cpp SPDXID: SPDXRef-2735248e6a9cf7b385a9a013429f2a91 FileChecksum: SHA1: 45b104cd463e2b7f1f17c94a78c55aa7cc7824ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/PrintPacketHeaderHandler.hpp SPDXID: SPDXRef-6e87f896b8951fc89dc4aec561bd599f FileChecksum: SHA1: 143e76973ddac092db2783c2479ce4c1f289d940 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingConnectionDumpToFileDecoratorTests.cpp SPDXID: SPDXRef-4ae940fe4b73deb03108c31b8569747b FileChecksum: SHA1: 1ce4ae1ea917d720d55cff0b14ca81461a5d9d85 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingGuidTest.cpp SPDXID: SPDXRef-e3ba2ed0f6f8c6c343c3581490538a20 FileChecksum: SHA1: 3510ab332eae621bfd83e7e59cd23d261963d13f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd. All rights reserved. FileName: ./src/profiling/test/ProfilingMocks.hpp SPDXID: SPDXRef-f68f087e17977ef7a118336507372f16 FileChecksum: SHA1: b96ca75d4827516c12e5b99dd799061fd4ba5b8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingTestUtils.cpp SPDXID: SPDXRef-9183dd066ad3b6c1480b82259535a5e1 FileChecksum: SHA1: 7e4fb086c2a42ee015a9ff8e95b9ee302d6981dd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingTestUtils.hpp SPDXID: SPDXRef-c553441fec6a47f1bfcbca45ed054f0b FileChecksum: SHA1: ba53cef54a36b4d215ff35f07d53c1732c7addf6 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingTests.cpp SPDXID: SPDXRef-2038c8361bfe6ba6cb903a3998f891c9 FileChecksum: SHA1: 8ad2ef311d54bfbdb5caf01f1891719e3d9a029a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/ProfilingTests.hpp SPDXID: SPDXRef-b2a37c155f169567bfc16825bbb8ef1f FileChecksum: SHA1: 936c786e9c892f2a7ef613946d5defc402a6b1fc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/RequestCountersPacketHandler.cpp SPDXID: SPDXRef-2ce039985365f9f2bc0bfd0cbaff486e FileChecksum: SHA1: fb2f1dacdf95eb08d8055523d077759a74be7cbc LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/RequestCountersPacketHandler.hpp SPDXID: SPDXRef-1416a4a4a97b805646c7b51ef72e3877 FileChecksum: SHA1: c0b1bd0ea32eba88e79e07e41939e64bc2a5edb4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/SendCounterPacketTests.cpp SPDXID: SPDXRef-6dda1fe889f5e5616191fbdcc2cb8451 FileChecksum: SHA1: 8c0b2efe0755cbc8a9bcc132f9c32757e1adfe2f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/SendCounterPacketTests.hpp SPDXID: SPDXRef-8cf6f08d59caecb5508d243832b71a1a FileChecksum: SHA1: 46d4b97ac2bd949b9df24fc1b40eb243364063cf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/SendTimelinePacketTests.cpp SPDXID: SPDXRef-81a3b2e870c541d1b9672f79bf477b95 FileChecksum: SHA1: 4c17649544cf496802b99aa21ab93f2380341912 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TestTimelinePacketHandler.cpp SPDXID: SPDXRef-aba7ec2cf3f92b30c5b906f551ce5611 FileChecksum: SHA1: f7ca2f040433799cc55b059eeee5a4b00a571020 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TestTimelinePacketHandler.hpp SPDXID: SPDXRef-efb17461ecb3af1ad98a02d8b7fbc4ce FileChecksum: SHA1: f51047cbc86ab66331e33fa24c9f601fe69ee7fa LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TimelineModel.cpp SPDXID: SPDXRef-a862cdfcc39b29dea04403144aec64b7 FileChecksum: SHA1: 10cf2c0b0087ff09aae53551bf3814b72e7fa988 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TimelineModel.hpp SPDXID: SPDXRef-87637dbc2ccd6f438d7b69dc28a8a104 FileChecksum: SHA1: d7cfbf030bafbf4e9e3c645168042b9d73b78fb8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TimelinePacketTests.cpp SPDXID: SPDXRef-6d63ecc6305cf43b23f948704dbe9030 FileChecksum: SHA1: 27b69accf7a8e9e4b6babe28045306f9344c6d95 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/profiling/test/TimelineUtilityMethodsTests.cpp SPDXID: SPDXRef-f9c35b8cc88155af58c4fdb8f6bdbd0b FileChecksum: SHA1: 7f6454d357554820fcc92b93a0694b49c8916ff0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./src/timelineDecoder/CMakeLists.txt SPDXID: SPDXRef-11bdc89255c47ae42c8648f1e17084f3 FileChecksum: SHA1: 163ced47bc9eb92fef8cebdf4659f1ff3407f75c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/timelineDecoder/JSONTimelineDecoder.cpp SPDXID: SPDXRef-3a799526632fc357777b93c5beb30a79 FileChecksum: SHA1: f69fa3de884e23540c45e42ffc86df5026a6596f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/timelineDecoder/JSONTimelineDecoder.hpp SPDXID: SPDXRef-a9d55c8358d03bb9e3a6d4f67aebe05f FileChecksum: SHA1: 763a2cde1d0ec30a53e85266c26731d4b1d8c446 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./src/timelineDecoder/tests/JSONTimelineDecoderTests.cpp SPDXID: SPDXRef-ae30d322bb7f73ca555673957054e259 FileChecksum: SHA1: 9060388f116b754c85bc459bb42e247f07e6c887 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/CMakeLists.txt SPDXID: SPDXRef-f902511b1e5d98761106d92ad151207b FileChecksum: SHA1: 61b04a115d9adc58fc07e86f7c815865c090bdd1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/Cifar10Database.cpp SPDXID: SPDXRef-ca20731eb6df1ef9b92cab3df99d2d40 FileChecksum: SHA1: 652c82ec6ea8eefacd68c25967332f671e30145d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/Cifar10Database.hpp SPDXID: SPDXRef-dee6ad0a6a93ed1feef8f4bbadc266b4 FileChecksum: SHA1: 2b7e3f9b1cae3d6cbf24f741097495205ca4e10e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ClassifierTestCaseData.hpp SPDXID: SPDXRef-322437b665d045b4ba93f4d9641b08a9 FileChecksum: SHA1: 8c5d1b240fc72e5ca15e419acc1f7632a41ecc50 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/CxxoptsUtils.hpp SPDXID: SPDXRef-fa98a4095c1344335433f1bfea42b8d6 FileChecksum: SHA1: b32e76328d98ca694b7c571cc011355b9017fa1e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./tests/DeepSpeechV1Database.hpp SPDXID: SPDXRef-6be6038dd203a01e5c57403ef9c6f397 FileChecksum: SHA1: a5ec1dc93c2ab17e670df44dfaa6be358c03592e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/DeepSpeechV1InferenceTest.hpp SPDXID: SPDXRef-4bcebce0b3c46d6fa54643005aa6331d FileChecksum: SHA1: 2874d8b0d6c1ad9ca690fa5225c6c9fd013114a5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ExecuteNetwork/ArmNNExecutor.cpp SPDXID: SPDXRef-5c21615d3a81ebdefbc428b75055ca2c FileChecksum: SHA1: 291421a30fb20af235d688f79440b9be995f8e03 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ArmNNExecutor.hpp SPDXID: SPDXRef-05ba6714af9d7232f79e93647091e192 FileChecksum: SHA1: 0f7a1182a57fa0b501ebe7ccccd39500bb10ae87 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ExecuteNetwork.cpp SPDXID: SPDXRef-9d72c7dfa9fe7b377b09d5b88b6f0d5d FileChecksum: SHA1: a33b9e16d87140d4139839a0dacc089ba5c9b239 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ExecuteNetworkParams.cpp SPDXID: SPDXRef-635c37383133f427a9aab004a60e26b1 FileChecksum: SHA1: f11d6ffc28b935b1da976c5ae536bbb5a648f9f0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ExecuteNetworkParams.hpp SPDXID: SPDXRef-05e11ccdaeb397f1f8b14f28861abb00 FileChecksum: SHA1: db94acb4d0a9de1ecf5aed66c1325ef1896f92d1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ExecuteNetworkProgramOptions.cpp SPDXID: SPDXRef-a0cbbf4b5ea20316c47d8d8bb85a5722 FileChecksum: SHA1: c76b5662273c977c09bcf9a8a0fa598113a75623 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/ExecuteNetworkProgramOptions.hpp SPDXID: SPDXRef-7a6f769e42a04a71caeb48290a49229c FileChecksum: SHA1: c55bb801c491550c7b46ebb381dc39ed9e539c79 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/IExecutor.hpp SPDXID: SPDXRef-20c56ef497bc7b6f18ca3e9c96769e63 FileChecksum: SHA1: e72152b4fe6127525382deede04f0687d2b29eb4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/TfliteExecutor.cpp SPDXID: SPDXRef-f3081df03c0838fb968adfc61fb2c204 FileChecksum: SHA1: 30308bbd0a3b8d1626b9ed8cc2d4c5b570040fe4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ExecuteNetwork/TfliteExecutor.hpp SPDXID: SPDXRef-85e7eaf3f955b39f1b181b3c5fac24cc FileChecksum: SHA1: dc30ae2dea73fdfd7042aa3673c857cda09856f7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ImageCSVFileGenerator/ImageCSVFileGenerator.cpp SPDXID: SPDXRef-f47851034c2193f27aa0c98dd491e6db FileChecksum: SHA1: be4df2c3121b2ddb25645d690f0c341701c0a57d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ImageCSVFileGenerator/README.md SPDXID: SPDXRef-cf97905c4e7cc9ce86e7fb3c5263b4d2 FileChecksum: SHA1: 1d844730576689011f13a8a02e864f2fdfcb6e26 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ImagePreprocessor.cpp SPDXID: SPDXRef-4f5965acbb583def2ee92f4fcc4e4ea4 FileChecksum: SHA1: 1ae10f7d1828d8e042b9c75d71b7bd9e74e53021 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ImagePreprocessor.hpp SPDXID: SPDXRef-2a6be72aa1394c254837c7c7491d3ef3 FileChecksum: SHA1: 6d040ea207694f11dec23a6d7973e1fbc15fab7d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ImageTensorGenerator/ImageTensorGenerator.cpp SPDXID: SPDXRef-01dbf0ee30aeabd66278ce6ed75ad01e FileChecksum: SHA1: 20355807435b8600e75955105fea03622f62fd7b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ImageTensorGenerator/ImageTensorGenerator.hpp SPDXID: SPDXRef-9d46db12adcb6a049a039b9a9afdbae1 FileChecksum: SHA1: 70971cc286d5b937fd5f9838b5c43db65bd9e892 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ImageTensorGenerator/README.md SPDXID: SPDXRef-743023d30abfdfdd84c1dcd40b07d1a9 FileChecksum: SHA1: 3f099ccbdb64d22bded7192e37951c2b80a7b5ac LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/InferenceModel.hpp SPDXID: SPDXRef-2672ea7c206528b4b7346bd469cdaaab FileChecksum: SHA1: b42f42f5b15692e48d57371aa9b3b4ca971db488 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/InferenceTest.cpp SPDXID: SPDXRef-1c7e2066ab19eb93da3b93e32413be7a FileChecksum: SHA1: d4b8ad292ef59cfa880b6f96870cd556ae3b002d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/InferenceTest.hpp SPDXID: SPDXRef-6b41dd7ba14400cddc8ea468e73fb39d FileChecksum: SHA1: 81c65765c06d689ead0ba1ab28ff651ab0784c93 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/InferenceTest.inl SPDXID: SPDXRef-a1e751b09dac1ef8e15f06879492b63f FileChecksum: SHA1: ff388a34bb2dec558f42218be866525875cf5864 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/InferenceTestImage.cpp SPDXID: SPDXRef-7552ceb2a6696cb5115c87f459089d78 FileChecksum: SHA1: 18dac2159e38dfe57f5cc9587a20f07ee8906d60 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/InferenceTestImage.hpp SPDXID: SPDXRef-d02f3fe908c059de4aa7b5aa957b5a97 FileChecksum: SHA1: 0b5c2aff38490777ac5d00d2f5944c67914def8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/LstmCommon.hpp SPDXID: SPDXRef-9d2a73d591530023265a63b26725dfb1 FileChecksum: SHA1: d3f4da783f2ce5ee563cfde12dd2625c65ef2656 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/MemoryStrategyBenchmark/CMakeLists.txt SPDXID: SPDXRef-4ad65eaa87bc8751c4176b47026ecdd5 FileChecksum: SHA1: 382eea5dc2d42f2a1737084a3dc33ae84b42d05a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MemoryStrategyBenchmark/MemoryStrategyBenchmark.cpp SPDXID: SPDXRef-062f76f2bc58ddba94c1ce4cb5d2d804 FileChecksum: SHA1: e7357c28b65b56f6b5b4f93a8a5cd72015e1832d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MemoryStrategyBenchmark/TestBlocks.hpp SPDXID: SPDXRef-0617fc7405942ddf154be7a41aeeaf6e FileChecksum: SHA1: bc195e9247e5c5cd3a97b3c14bf4b0ac485b83bf LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MemoryStrategyBenchmark/TestStrategy.cpp SPDXID: SPDXRef-58b08276a97ccf72fa55c44417e1a70b FileChecksum: SHA1: 002941003591274fb92ec52745555d92ea6a751e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MemoryStrategyBenchmark/TestStrategy.hpp SPDXID: SPDXRef-05943e15e55600d3c41622bf1ae4733a FileChecksum: SHA1: 49011835e58787ffbd54a0f2c282a102ef998835 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MnistDatabase.cpp SPDXID: SPDXRef-981abadb97e42fb4c9dabb83369a9c54 FileChecksum: SHA1: e2c410140f64383386e222b8995dbb1ebd57262c LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/MnistDatabase.hpp SPDXID: SPDXRef-47aaf4174a808208e814d6de769be190 FileChecksum: SHA1: c84dddb55e516c54e8c9b5863a95a6f003f782cd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/MobileNetSsdDatabase.hpp SPDXID: SPDXRef-496e37e69c8a84a47d20b94bc95c41d8 FileChecksum: SHA1: c509a4180ebb1561ff4da818132d437f438c015f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/MobileNetSsdInferenceTest.hpp SPDXID: SPDXRef-5dd68e226c16a197c7ac6c0f895ae8ec FileChecksum: SHA1: a34edb71c365f34c73bc8817deeb97e3b638bc72 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ModelAccuracyTool-Armnn/ModelAccuracyTool-Armnn.cpp SPDXID: SPDXRef-ab126e8a1e4aca3dcc4c700cd2ff4920 FileChecksum: SHA1: 22559514fb28c7ee136877020d9b8b5ed66cc532 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/ModelAccuracyTool-Armnn/README.md SPDXID: SPDXRef-3230239ee0eb33414d9d7817809f3a72 FileChecksum: SHA1: 8e2791fccb58062fa8cc56af0d1da35b5e73bbc9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019, 2021 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/MultipleNetworksCifar10/MultipleNetworksCifar10.cpp SPDXID: SPDXRef-ee0545c4fe52d93217b7a02e1b0c95c3 FileChecksum: SHA1: 53c6fb9c546621a7230a6dec016f45f7182400de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/NetworkExecutionUtils/NetworkExecutionUtils.cpp SPDXID: SPDXRef-a1501ae5739d735c4183fff39184d847 FileChecksum: SHA1: 5c14f91124b5d4dd22b665b781f85d97678b072a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/NetworkExecutionUtils/NetworkExecutionUtils.hpp SPDXID: SPDXRef-2e88264a79f56bdc26e50691a8b5884e FileChecksum: SHA1: 6727c3e1876b62cfc40faad252b87e86b08f73f8 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2022 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/ObjectDetectionCommon.hpp SPDXID: SPDXRef-1cf2b68c17e4bc998b93276ee710a410 FileChecksum: SHA1: a8a9d85f3376e44741c20b17401f1e565a714d8b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/OnnxMnist-Armnn/OnnxMnist-Armnn.cpp SPDXID: SPDXRef-53af0493e4a9cccc08ccc664135b5e03 FileChecksum: SHA1: 9448882bd137fd3f80008625489987c70810e93b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/OnnxMnist-Armnn/Validation.txt SPDXID: SPDXRef-4f1db5f114aae513247b1cdd2a1875b5 FileChecksum: SHA1: 505798615a764984e01099a8fc5ffd22bc30b354 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/OnnxMobileNet-Armnn/OnnxMobileNet-Armnn.cpp SPDXID: SPDXRef-dc09b90ee5a2b46037353ced487d15ab FileChecksum: SHA1: 28f811ead9a70751796542af26518c9211a5c838 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/OnnxMobileNet-Armnn/Validation.txt SPDXID: SPDXRef-ac2ec7f9c924435dc85ca24b35eb8eae FileChecksum: SHA1: ff156f6176bda86f2e7106ec68ddeb04732accca LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/OnnxMobileNet-Armnn/labels.txt SPDXID: SPDXRef-ade7e83efacc00a4b9c4763114f87217 FileChecksum: SHA1: 5f3e02ac341b6c0822d6e6cf171d33d5750d6fc0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteBenchmark-Armnn/TfLiteBenchmark-Armnn.cpp SPDXID: SPDXRef-eac69f4a097865e0ecaf3b06f1d08644 FileChecksum: SHA1: 7c10ec6f51c8c64df4444c5a7dad214c7fdad80f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 STMicroelectronics and Contributors. All rights reserved. FileName: ./tests/TfLiteInceptionV3Quantized-Armnn/TfLiteInceptionV3Quantized-Armnn.cpp SPDXID: SPDXRef-03d948463c1b04127991dac3decd674b FileChecksum: SHA1: f379f686435404fb1d2ebf0f7d9d706ec2485593 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteInceptionV3Quantized-Armnn/Validation.txt SPDXID: SPDXRef-cb0ed08a465f0b83314cf9900628eee5 FileChecksum: SHA1: a84915f1ed57c54e196efa23a0c40439cafd145f LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteInceptionV4Quantized-Armnn/TfLiteInceptionV4Quantized-Armnn.cpp SPDXID: SPDXRef-699e286cd37e13cae7018a2f6ee49094 FileChecksum: SHA1: fc449d1c66daa09cf28afb01bf44c60618faf262 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteInceptionV4Quantized-Armnn/Validation.txt SPDXID: SPDXRef-925d70b0aca419f6bc87c6e3e0786d09 FileChecksum: SHA1: 10966b2f9057f8912137db6dda4900e6c758cd36 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteMnasNet-Armnn/TfLiteMnasNet-Armnn.cpp SPDXID: SPDXRef-ccec4dd63b1c6adff0dcd277c43e3d82 FileChecksum: SHA1: 424e528fd19f46d24f62b0f06b6ef01b9f4f0214 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteMobileNetQuantizedSoftmax-Armnn/TfLiteMobileNetQuantizedSoftmax-Armnn.cpp SPDXID: SPDXRef-43a00c1709fa96704ecc540d601fa4bc FileChecksum: SHA1: fd9a0d8fb3629969e180ac4b172065a4fca73057 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteMobileNetQuantizedSoftmax-Armnn/Validation.txt SPDXID: SPDXRef-d14486bd85f1430dae1a0e161e9a330a FileChecksum: SHA1: 6375e1651d57a9ba1b4525338f37a4b6e3e2d3f2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteMobileNetSsd-Armnn/TfLiteMobileNetSsd-Armnn.cpp SPDXID: SPDXRef-cd753294c4d8f7619071801170b55e13 FileChecksum: SHA1: afab4e26b5ae35e755c6910dfa684d5e490961b3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteMobilenetQuantized-Armnn/TfLiteMobilenetQuantized-Armnn.cpp SPDXID: SPDXRef-e783e4dce1e39dbfcc4b167faba3dc4c FileChecksum: SHA1: b4cec76ad54379df8ad2b6846385827c016419d1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteMobilenetQuantized-Armnn/Validation.txt SPDXID: SPDXRef-cf0829c8ec3d41e3e630703f06fd77ef FileChecksum: SHA1: 10966b2f9057f8912137db6dda4900e6c758cd36 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteMobilenetQuantized-Armnn/labels.txt SPDXID: SPDXRef-4c454f0d07bdf86bfc7ff71278740553 FileChecksum: SHA1: 5f3e02ac341b6c0822d6e6cf171d33d5750d6fc0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteMobilenetV2Quantized-Armnn/TfLiteMobilenetV2Quantized-Armnn.cpp SPDXID: SPDXRef-c3d8a4a4df0f5c482df9157183b66b78 FileChecksum: SHA1: 5c158af5e6b5de1f3369fdffa173a4c869b64a25 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteResNetV2-50-Quantized-Armnn/TfLiteResNetV2-50-Quantized-Armnn.cpp SPDXID: SPDXRef-ae48bce53e1adfe774552333d9764716 FileChecksum: SHA1: 9320be231e1a795598904a9472401849da4fdd85 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteResNetV2-Armnn/TfLiteResNetV2-Armnn.cpp SPDXID: SPDXRef-b22c05797254a66ef96119b10ffd3220 FileChecksum: SHA1: bfa71a096e95cb5e4f593a429dc693bb7a1a9571 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteVGG16Quantized-Armnn/TfLiteVGG16Quantized-Armnn.cpp SPDXID: SPDXRef-19be4b2d069cfbe79d4ba6ae89f6a522 FileChecksum: SHA1: 352f3c2fce9d28c0db169dcde6f89bf7672dc050 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteVGG16Quantized-Armnn/Validation.txt SPDXID: SPDXRef-4e9d7952418a48416199479cf64f33b8 FileChecksum: SHA1: 362e0bc03b6a9d6315400b374ed7728c994b3b5b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2018-2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/TfLiteYoloV3Big-Armnn/NMS.cpp SPDXID: SPDXRef-b74af3e1ca6277aed97f8f0f2f70d948 FileChecksum: SHA1: 3e603592f7041347d194ea90aed1c54b5ab545b7 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteYoloV3Big-Armnn/NMS.hpp SPDXID: SPDXRef-fe1a417d10adc1e99195d01760ef9e4b FileChecksum: SHA1: 2158b5f88c763f6f6dcb0318ade02687671d6543 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./tests/TfLiteYoloV3Big-Armnn/TfLiteYoloV3Big-Armnn.cpp SPDXID: SPDXRef-f19377967a984f8168b929ca5db9e98b FileChecksum: SHA1: 45492002d8c702edd5b3937d3f1cd9d3545ee414 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./tests/YoloDatabase.cpp SPDXID: SPDXRef-daa2aedac21fc35708315747beb3773d FileChecksum: SHA1: e1cd4405e80956675d32d657af21508b161833be LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/YoloDatabase.hpp SPDXID: SPDXRef-05f10c5952cbc130ddb7a4eeea0cb54f FileChecksum: SHA1: d43eaaee4172913db8bd83326b2c01957388a642 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/YoloInferenceTest.hpp SPDXID: SPDXRef-9d3bf8e9ff8dfbba4c6785df8f3502df FileChecksum: SHA1: 09c3a03c05777b6683a1610f2caff577f87febdd LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd. All rights reserved. FileName: ./tests/profiling/gatordmock/CommandFileParser.cpp SPDXID: SPDXRef-1c84ef30ebcc6c6dbc0bd9fdb7064654 FileChecksum: SHA1: 24f5f6dcc9c2b87c9653d5add46f6b3a2efa05ee LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/CommandFileParser.hpp SPDXID: SPDXRef-5abbfda2a154d8b318f15998035fd031 FileChecksum: SHA1: cc8a0c5d27d1d6ae4e8dda6f454bba35ced889a3 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/CommandLineProcessor.cpp SPDXID: SPDXRef-2b07660d3745a0559a14ebf790837326 FileChecksum: SHA1: 51bb48d485c0a8702f55cb8335878d9d98045397 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/CommandLineProcessor.hpp SPDXID: SPDXRef-6a489ac0cc97cee3f197fce0fc69dd4e FileChecksum: SHA1: 877763fe8e96620e7f3f696f1af741d794992a3b LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/CounterDirectory.hpp SPDXID: SPDXRef-e537d1dfc42f71ff5f3021dc9bfb4062 FileChecksum: SHA1: 391971ea89ffe581a6981220782b3128a1e8b9c9 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/GatordMockMain.cpp SPDXID: SPDXRef-84a3f3aedcb2641a9c00a3b85fe5ca0b FileChecksum: SHA1: 680301297efff8afa69a4e94312b0b20dfe55f97 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/GatordMockService.cpp SPDXID: SPDXRef-ede19289d84680c81b610e727937c417 FileChecksum: SHA1: 62d9594a2041f07f0b8c882f0c132be91eed0fae LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/GatordMockService.hpp SPDXID: SPDXRef-025117bce796ae5f57a1adacb22e6479 FileChecksum: SHA1: 7ea50026ba5a584a6c581d987cd8a79263ae604e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/PeriodicCounterCaptureCommandHandler.cpp SPDXID: SPDXRef-c31bc0adba1a3e3aba7c338f3e6dde06 FileChecksum: SHA1: 545739261280ba8ccc0edded9854eb8edc2e6189 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/PeriodicCounterCaptureCommandHandler.hpp SPDXID: SPDXRef-539cecf64030b12747eaa06c04decbed FileChecksum: SHA1: ad34773b62070271103ee95b26f89b7796dfc045 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/PeriodicCounterSelectionResponseHandler.cpp SPDXID: SPDXRef-8fc030afa4c36db52f1d0e9f2d1e117e FileChecksum: SHA1: 7726521ed06b2b0d8644fb4d6ce35c52182f1f4e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/PeriodicCounterSelectionResponseHandler.hpp SPDXID: SPDXRef-dc9e545e6c9db3ac4315fc5823e689ca FileChecksum: SHA1: 21c0fb40d45f6d8078a2fb83b44b4e8955cd17a5 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/StreamMetadataCommandHandler.cpp SPDXID: SPDXRef-e584f2c7a01b34d8f850d1c1ac96724f FileChecksum: SHA1: 7c8dba72ae81ea2afded660d08eac69cdedc7b8a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/StreamMetadataCommandHandler.hpp SPDXID: SPDXRef-d0be843fde4f6bf0e65ec6201808a95b FileChecksum: SHA1: 76e477b1f53ebd2d62fa778d6afbf71a3c42b19e LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2019 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/StubCommandHandler.hpp SPDXID: SPDXRef-fa0cf0de82389b292a98816626bf6603 FileChecksum: SHA1: 1e4e05b09049c3a94dc28a93a2023c007f0b99de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd and Contributors. All rights reserved. FileName: ./tests/profiling/gatordmock/tests/GatordMockTests.cpp SPDXID: SPDXRef-12ec4f38b97645adbe64913b5f6afce2 FileChecksum: SHA1: 8ac130a5c03d9eaab231959df025198a2b2fbd32 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2017 Arm Ltd and Contributors. All rights reserved. FileName: ./third-party/cxxopts/CHANGELOG.md SPDXID: SPDXRef-784fb8508d7d335f0ecfb34f07186dc2 FileChecksum: SHA1: e6c10f30fc0c2178727817b9cba998b7f2aa2a18 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2014 Jarryd Beck FileName: ./third-party/cxxopts/README.md SPDXID: SPDXRef-4141e34a6df2067b1312d17839f2d6dd FileChecksum: SHA1: 7c11cf8ce317a25849303453f116fae47003fde2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2014 Jarryd Beck FileName: ./third-party/cxxopts/cxxopts.hpp SPDXID: SPDXRef-f8c65e2f6894d199db41d2ae03fe4fab FileChecksum: SHA1: 1c442cb4734fc64e7bf08186de80210bcb2858ce LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2014, 2015, 2016, 2017 Jarryd Beck FileName: ./third-party/doctest/doctest.h SPDXID: SPDXRef-65bd4d4b28de33e2b3521ad9ce1fdedc FileChecksum: SHA1: 0fb30fc5bd9493ffed0dd78b9bc84e7eaedc1f11 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2016-2021 Viktor Kirilov FileName: ./third-party/fmt/CMakeLists.txt SPDXID: SPDXRef-94773817148e0752c81be1de90a93994 FileChecksum: SHA1: 80aff34282c869d07d5db2a7d74024481c000402 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright © 2020 Arm Ltd. All rights reserved. FileName: ./third-party/fmt/README.rst SPDXID: SPDXRef-9d5b542a3c0e92caff3afb38ea5ad59f FileChecksum: SHA1: c054df5431e53edbdf623040941718784bfc3008 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012 - present, Victor Zverovich FileName: ./third-party/fmt/core.h SPDXID: SPDXRef-2600348527d13adeb805dd415263025f FileChecksum: SHA1: e988630f3ff42b52dc45698c877e5c7fd9f03da2 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012 - present, Victor Zverovich FileName: ./third-party/fmt/format-inl.h SPDXID: SPDXRef-38d36d5dbaeeb581f80af51976513ab5 FileChecksum: SHA1: 6054f4244322c2f2cb8e957d8ca963ea7bcc6ae0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012 - 2016, Victor Zverovich FileName: ./third-party/fmt/format.h SPDXID: SPDXRef-4233f40a4fbf9212e003cda62e27ab00 FileChecksum: SHA1: 95e88efe19b9cad17595972dc4fcabe6f2ee54de LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012 - present, Victor Zverovich FileName: ./third-party/fmt/src/format.cc SPDXID: SPDXRef-4ba702f3d1c10f677980279ea1bfc643 FileChecksum: SHA1: af964f45dedb877dc2e4c8aa2adcc578685133ea LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012 - 2016, Victor Zverovich FileName: ./third-party/ghc/README.md SPDXID: SPDXRef-b45e06703cb000d657dd5869b5724a17 FileChecksum: SHA1: af15a2b6583390e1bd0c3ade0f10a3f7e8e92d49 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2018, Steffen Schümann FileName: ./third-party/ghc/filesystem.hpp SPDXID: SPDXRef-803176aa68ced439985fabea21a876c2 FileChecksum: SHA1: f153a74b700247265752c2d87cbff505c5141de4 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2018, Steffen Schümann FileName: ./third-party/half/ChangeLog.txt SPDXID: SPDXRef-7d933f8e99db1f8066473548e4052c65 FileChecksum: SHA1: c52f4c156e80d91de9f1376956b015b8029ab095 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012-2017 Christian Rau FileName: ./third-party/half/README.txt SPDXID: SPDXRef-e71d50499c037f781800cfe5904303c1 FileChecksum: SHA1: 0a015bcc772d2ca790892fd6101afadb4fdfc3e0 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012-2017 Christian Rau FileName: ./third-party/half/half.hpp SPDXID: SPDXRef-f5a71992824c9ab610639ec567b733ef FileChecksum: SHA1: 93acbfa61a6fd1aceddf28c56fa677a4be985b80 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2012-2017 Christian Rau FileName: ./third-party/mapbox/README.md SPDXID: SPDXRef-2048bf5d696988588995627a24f49d4d FileChecksum: SHA1: cd2c36509eb39ca5dd40713074a6965a33500124 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox 2016. All rights reserved. FileName: ./third-party/mapbox/optional.hpp SPDXID: SPDXRef-331a7b257251ce799c6da9ec8bb291ed FileChecksum: SHA1: 7e7ec51fca6325e50463fd51617c7f9f46e3e567 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox All rights reserved. FileName: ./third-party/mapbox/recursive_wrapper.hpp SPDXID: SPDXRef-dd5df8338676fedc44e37885fb799be3 FileChecksum: SHA1: 585e2581a89a3dc0230d21c9b049277146c85dab LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) 2002-2003 Copyright (c) MapBox All rights reserved. FileName: ./third-party/mapbox/variant.hpp SPDXID: SPDXRef-66727670855bf2d7b636f1314d8c3c74 FileChecksum: SHA1: 392a89ec746b0c1b58c9d9aa9ccceb794e61ecb0 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox All rights reserved. FileName: ./third-party/mapbox/variant_cast.hpp SPDXID: SPDXRef-d85de8c871031398f320a0f7b68a8035 FileChecksum: SHA1: 0e43dc41c29913e2095a84dcaf2b269b8354e362 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox All rights reserved. FileName: ./third-party/mapbox/variant_io.hpp SPDXID: SPDXRef-2280ccf5f1f6ce87a312f5173a6c6af6 FileChecksum: SHA1: 04fbd66e7df730e1b5e94991852fc9329470e8d7 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox All rights reserved. FileName: ./third-party/mapbox/variant_visitor.hpp SPDXID: SPDXRef-58002b6ce4a9b1b68d749b9fe5aa7ae3 FileChecksum: SHA1: 692fbcbdcf1477a436ca2e51938a8172d54059e5 LicenseConcluded: NOASSERTION LicenseInfoInFile: BSD-3-Clause FileCopyrightText: Copyright (c) MapBox All rights reserved. FileName: ./third-party/stb/stb_image.h SPDXID: SPDXRef-5f504a269cf85600c3c5708ae474cb73 FileChecksum: SHA1: 15f4a5ce36b201b4edf93726a32a31b438d16bc1 LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2017 Sean Barrett FileName: ./third-party/stb/stb_image_resize.h SPDXID: SPDXRef-abcc5e189206fb91dcb36c64934b57d6 FileChecksum: SHA1: 825f5bbecb78698b7d2c742023d03ce10f39539d LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2017 Sean Barrett FileName: ./third-party/stb/stb_image_write.h SPDXID: SPDXRef-7249ccf15147ac232de4237b85ca124c FileChecksum: SHA1: 623a20d8b2c21702a66ce127c2fb641d76b6916a LicenseConcluded: NOASSERTION LicenseInfoInFile: MIT FileCopyrightText: Copyright (c) 2017 Sean Barrett armnn-23.08/LICENSES/000077500000000000000000000000001446772241200140575ustar00rootroot00000000000000armnn-23.08/LICENSES/BSD-3-Clause.txt000066400000000000000000000026641446772241200166120ustar00rootroot00000000000000Copyright (c) . Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. armnn-23.08/LICENSES/MIT.txt000066400000000000000000000020661446772241200152550ustar00rootroot00000000000000MIT License Copyright (c) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. armnn-23.08/README.md000066400000000000000000000412741446772241200141410ustar00rootroot00000000000000
Arm NN Logo
* [Quick Start Guides](#quick-start-guides) * [Pre-Built Binaries](#pre-built-binaries) * [Software Overview](#software-overview) * [Get Involved](#get-involved) * [Contributions](#contributions) * [Disclaimer](#disclaimer) * [License](#license) * [Third-Party](#third-party) * [Build Flags](#build-flags) # Arm NN **Arm NN** is the **most performant** machine learning (ML) inference engine for Android and Linux, accelerating ML on **Arm Cortex-A CPUs and Arm Mali GPUs**. This ML inference engine is an open source SDK which bridges the gap between existing neural network frameworks and power-efficient Arm IP. Arm NN outperforms generic ML libraries due to **Arm architecture-specific optimizations** (e.g. SVE2) by utilizing **[Arm Compute Library (ACL)](https://github.com/ARM-software/ComputeLibrary/)**. To target Arm Ethos-N NPUs, Arm NN utilizes the [Ethos-N NPU Driver](https://github.com/ARM-software/ethos-n-driver-stack). For Arm Cortex-M acceleration, please see [CMSIS-NN](https://github.com/ARM-software/CMSIS_5). Arm NN is written using portable **C++14** and built using [CMake](https://cmake.org/) - enabling builds for a wide variety of target platforms, from a wide variety of host environments. **Python** developers can interface with Arm NN through the use of our **Arm NN TF Lite Delegate**. ## Quick Start Guides **The Arm NN TF Lite Delegate provides the widest ML operator support in Arm NN** and is an easy way to accelerate your ML model. To start using the TF Lite Delegate, first download the **[Pre-Built Binaries](#pre-built-binaries)** for the latest release of Arm NN. Using a Python interpreter, you can load your TF Lite model into the Arm NN TF Lite Delegate and run accelerated inference. Please see this **[Quick Start Guide](delegate/DelegateQuickStartGuide.md)** on GitHub or this more comprehensive **[Arm Developer Guide](https://developer.arm.com/documentation/102561/latest/)** for information on how to accelerate your TF Lite model using the Arm NN TF Lite Delegate. The fastest way to integrate Arm NN into an **Android app** is by using our **Arm NN AAR (Android Archive) file with Android Studio**. The AAR file nicely packages up the Arm NN TF Lite Delegate, Arm NN itself and ACL; ready to be integrated into your Android ML application. Using the AAR allows you to benefit from the **vast operator support** of the Arm NN TF Lite Delegate. We held an **[Arm AI Tech Talk](https://www.youtube.com/watch?v=Zu4v0nqq2FA)** on how to accelerate an ML Image Segmentation app in 5 minutes using this AAR file. To download the Arm NN AAR file, please see the **[Pre-Built Binaries](#pre-built-binaries)** section below. We also provide Debian packages for Arm NN, which are a quick way to start using Arm NN and the TF Lite Parser (albeit with less ML operator support than the TF Lite Delegate). There is an installation guide available [here](InstallationViaAptRepository.md) which provides instructions on how to install the Arm NN Core and the TF Lite Parser for Ubuntu 20.04. To build Arm NN from scratch, we provide the **[Arm NN Build Tool](build-tool/README.md)**. This tool consists of **parameterized bash scripts** accompanied by a **Dockerfile** for building Arm NN and its dependencies, including **[Arm Compute Library (ACL)](https://github.com/ARM-software/ComputeLibrary/)**. This tool replaces/supersedes the majority of the existing Arm NN build guides as a user-friendly way to build Arm NN. The main benefit of building Arm NN from scratch is the ability to **exactly choose which components to build, targeted for your ML project**.
## Pre-Built Binaries | Operating System | Architecture-specific Release Archive (Download) | |-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Android (AAR) | [![](https://img.shields.io/badge/download-android--aar-orange)](https://github.com/ARM-software/armnn/releases/download/v23.08/armnn_delegate_jni-23.08.aar) | | Android 10 "Q/Quince Tart" (API level 29) | [![](https://img.shields.io/badge/download-arm64--v8.2-a-blue)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-29-arm64-v8.2-a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8a-red)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-29-arm64-v8a.tar.gz) | | Android 11 "R/Red Velvet Cake" (API level 30) | [![](https://img.shields.io/badge/download-arm64--v8.2-a-blue)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-30-arm64-v8.2-a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8a-red)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-30-arm64-v8a.tar.gz) | | Android 12 "S/Snow Cone" (API level 31) | [![](https://img.shields.io/badge/download-arm64--v8.2-a-blue)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-31-arm64-v8.2-a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8a-red)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-31-arm64-v8a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8.6-a-purple)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-31-arm64-v8.6-a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8.6-a-sve-grey)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-31-arm64-v8.6-a-sve.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8.6-a-sve2-grey)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-31-arm64-v8.6-a-sve2.tar.gz) | | Android 13 "T/Tiramisu" (API level 32) | [![](https://img.shields.io/badge/download-arm64--v8.2-a-blue)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-32-arm64-v8.2-a.tar.gz) [![](https://img.shields.io/badge/download-arm64--v8a-red)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-android-32-arm64-v8a.tar.gz) | | Linux | [![](https://img.shields.io/badge/download-aarch64-green)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-linux-aarch64.tar.gz) [![](https://img.shields.io/badge/download-x86__64-yellow)](https://github.com/ARM-software/armnn/releases/download/v23.08/ArmNN-linux-x86_64.tar.gz) | **Note: Android 10 testing will be dropped from next release onwards.** ## Software Overview The Arm NN SDK supports ML models in **TensorFlow Lite** (TF Lite) and **ONNX** formats. **Arm NN's TF Lite Delegate** accelerates TF Lite models through **Python or C++ APIs**. Supported TF Lite operators are accelerated by Arm NN and any unsupported operators are delegated (fallback) to the reference TF Lite runtime - ensuring extensive ML operator support. **The recommended way to use Arm NN is to [convert your model to TF Lite format](https://www.tensorflow.org/lite/convert) and use the TF Lite Delegate.** Please refer to the [Quick Start Guides](#quick-start-guides) for more information on how to use the TF Lite Delegate. Arm NN also provides **TF Lite and ONNX parsers** which are C++ libraries for integrating TF Lite or ONNX models into your ML application. Please note that these parsers do not provide extensive ML operator coverage as compared to the Arm NN TF Lite Delegate. **Android** ML application developers have a number of options for using Arm NN: * Use our Arm NN AAR (Android Archive) file with **Android Studio** as described in the [Quick Start Guides](#quick-start-guides) section * Download and use our [Pre-Built Binaries](#pre-built-binaries) for the Android platform * Build Arm NN from scratch with the Android NDK using this [GitHub guide](BuildGuideAndroidNDK.md) Arm also provides an [Android-NN-Driver](https://github.com/ARM-software/android-nn-driver) which implements a hardware abstraction layer (HAL) for the Android NNAPI. When the Android NN Driver is integrated on an Android device, ML models used in Android applications will automatically be accelerated by Arm NN. **For more information about the Arm NN components, please refer to our [documentation](https://github.com/ARM-software/armnn/wiki/Documentation).** Arm NN is a key component of the [machine learning platform](https://mlplatform.org/), which is part of the [Linaro Machine Intelligence Initiative](https://www.linaro.org/news/linaro-announces-launch-of-machine-intelligence-initiative/). For FAQs and troubleshooting advice, see the [FAQ](docs/FAQ.md) or take a look at previous [GitHub Issues](https://github.com/ARM-software/armnn/issues). ## Get Involved The best way to get involved is by using our software. If you need help or encounter an issue, please raise it as a [GitHub Issue](https://github.com/ARM-software/armnn/issues). Feel free to have a look at any of our open issues too. We also welcome feedback on our documentation. Feature requests without a volunteer to implement them are closed, but have the 'Help wanted' label, these can be found [here](https://github.com/ARM-software/armnn/issues?q=is%3Aissue+label%3A%22Help+wanted%22+). Once you find a suitable Issue, feel free to re-open it and add a comment, so that Arm NN engineers know you are working on it and can help. When the feature is implemented the 'Help wanted' label will be removed. ## Contributions The Arm NN project welcomes contributions. For more details on contributing to Arm NN please see the [Contributing page](https://mlplatform.org/contributing/) on the [MLPlatform.org](https://mlplatform.org/) website, or see the [Contributor Guide](CONTRIBUTING.md). Particularly if you'd like to implement your own backend next to our CPU, GPU and NPU backends there are guides for backend development: [Backend development guide](src/backends/README.md), [Dynamic backend development guide](src/dynamic/README.md). ## Disclaimer The armnn/tests directory contains tests used during Arm NN development. Many of them depend on third-party IP, model protobufs and image files not distributed with Arm NN. The dependencies for some tests are available freely on the Internet, for those who wish to experiment, but they won't run out of the box. ## License Arm NN is provided under the [MIT](https://spdx.org/licenses/MIT.html) license. See [LICENSE](LICENSE) for more information. Contributions to this project are accepted under the same license. Individual files contain the following tag instead of the full license text. SPDX-License-Identifier: MIT This enables machine processing of license information based on the SPDX License Identifiers that are available here: http://spdx.org/licenses/ ## Inclusive language commitment Arm NN conforms to Arm's inclusive language policy and, to the best of our knowledge, does not contain any non-inclusive language. If you find something that concerns you, please email terms@arm.com ## Third-party Third party tools used by Arm NN: | Tool | License (SPDX ID) | Description | Version | Provenience | |----------------|-------------------|------------------------------------------------------------------|---------|--------------------------------------| | cxxopts | MIT | A lightweight C++ option parser library | 3.1.1 | https://github.com/jarro2783/cxxopts | | doctest | MIT | Header-only C++ testing framework | 2.4.6 | https://github.com/onqtam/doctest | | fmt | MIT | {fmt} is an open-source formatting library providing a fast and safe alternative to C stdio and C++ iostreams. | 8.30 | https://github.com/fmtlib/fmt | | ghc | MIT | A header-only single-file std::filesystem compatible helper library | 1.3.2 | https://github.com/gulrak/filesystem | | half | MIT | IEEE 754 conformant 16-bit half-precision floating point library | 1.12.0 | http://half.sourceforge.net | | mapbox/variant | BSD | A header-only alternative to 'boost::variant' | 1.1.3 | https://github.com/mapbox/variant | | stb | MIT | Image loader, resize and writer | 2.16 | https://github.com/nothings/stb | ## Build Flags Arm NN uses the following security related build flags in their code: | Build flags | |---------------------| | -Wall | | -Wextra | | -Wold-style-cast | | -Wno-missing-braces | | -Wconversion | | -Wsign-conversion | | -Werror | armnn-23.08/README.md.license000066400000000000000000000001531446772241200155510ustar00rootroot00000000000000# # Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/SECURITY.md000066400000000000000000000101401446772241200144370ustar00rootroot00000000000000**Reporting vulnerabilities** Arm takes security issues seriously and welcomes feedback from researchers and the security community in order to improve the security of its products and services. We operate a coordinated disclosure policy for disclosing vulnerabilities and other security issues. Security issues can be complex and one single timescale doesn't fit all circumstances. We will make best endeavours to inform you when we expect security notifications and fixes to be available and facilitate coordinated disclosure when notifications and patches/mitigations are available. **Report** For all security issues, contact Arm by email at [arm-security@arm.com](mailto:arm-security@arm.com). **Secure submission using PGP** We support and encourage secure submission of vulnerability reports using PGP, using the key below. If you would like replies to be encrypted, please provide your own public key through a secure mechanism. ~~~ -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFr7/RMBEACjHR5QZL/z1t2aLCRNXLE4KJiQmCo7edU5Be+7MTjIJDzZNu68 lNEUYRoLexeayif8eC4T19bUsSbGpxHiYsFFjV8ewLXDyDJRRuaBGPfQ5rn/mE6X Nvu+9Pputr+mB1R3CXcvrNkhmzPkK7zVM15oeyBMhogqPssuT4OeMduQdip8smfK xTMk91RrJTLb+G3eE1tf+81kXBYvzp2e24Sn0/VeYe0IWnBobjVBZk3TmcYxDvz5 Y47fU9V6cNj3Zq4VYrgxuLoFCA2VtetyiFQm5IYa3Bt3SWcAwihr8nbR2HoNdWyA u8wJYYVzSq3hvT5l/IjTHxEcY+6RBq8poDSsftzvX386u9hmw7sJQFlTw6/pUjdr gbsZ2ZzRBzKtU17ercpn4kU6VgVP3WRB5HiTFFkEpZuqAznOYaHbMq4dfd/g7Quq C0VTbWiJnhku2i+g4BdHHRDtIF6U3aVQAfbrDb1LjVTa65p5ULOeY3HRAWtMNtu/ Cj8cD98JDanzXtcnisds8vMQ8LZ6iMFChEnF8K4V0eLw9Ju6CMNiFYY7SEBndD/H M4KcU4li7mROSbJcshgEbe1SYkxdMuI9eY4DNYxl3VjxoPUGzeqXo/ADFKE9bHsi GTyEoij4ku0HspLVKnYHXn/LqHGwEcwjF8zphS+w5cn/e01akYwz5EVSQwARAQAB tB1Bcm0gU3VwcG9ydCA8c3VwcG9ydEBhcm0uY29tPokCTgQTAQgAOBYhBN9zqDwZ RL/vF0ihcdfNKdz4bBRiBQJa+/0TAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA AAoJENfNKdz4bBRibK0P/jLlJR/QYypcjb+8BnHT9tCDgcV2KFYXS15VpbSNviN9 Xs/UOnSadoGUMGCXDyb1PRNn98yUn7JlNR9rtsqPRmkpbo5cuw46ehgxjVlfcHnk CttaE8Davx6zo0fyrBib2+oVVW8usi9+uRK4vhhPUicO3oXwzldsVFz+RbpubZxc Bg/CZ+dQ2jMKOv1zDtInOG6OBnbQZRAeiWXgGhcIoPZ4zBQOi8nr0+bLcfvMeZi2 uz6uKnylpXwZbl4ijcG8MKV/ei+7du+SzA9NY0WOT2g3FXDREWUhjKs8bmEZgIx4 QgvDNpxAUThF+TqQ7zrsA8nT8POvDD0MhN/Z+A3QdPTdcaZFaXzIdxbDg+0FKmzu OgtQBH4C01RWrkmZlhO5w7/Qjt0vLlhfyQIL9BW/HeEPtjnH2Hnq8xYnZhlVqJEh FJU7F9sMvyiJiKviobFTd6AmpVkhxhcJ3k2L2C03imTsmUwAoejQCXwiYcOhyQ2t Z9Nk8YIZTEw2urGFi4HSQPwPq2j/2j7ABJ4rlzJvO6vs5ppGkumvzIIP9JnpVXbp wcbK6Ev6KdkX4s14Mzd6Hsd8LpL8t5nHhxUey6G0xKe2eSlHVm5Mlfhoete9UmIZ dzIOZkgTgWXlYXRIxwGQ2Pss7pURtofykvLklq4jcobQuHxurl9cteodETfbWk/J uQINBFr7/RMBEADWZG8eqt5D22g3T7ehnH/T3fuTX8LPUBnODMWGAEUY8uv64To8 46odvrXFgWBgCf0sROEyJchc3SGLyR9S4lJsVJRde3QLN3WZkHlB4pSn4IQHFyQd wsLQi+S9uggHMPlQ6MNvc5n0P3k5bT9fLUmtJWJ3QVjW7k963ZXpzf1zbQJqs30w rlqGUZllfRoYQTfcYxFEaUFhwRJ//skNImWH8Vz+PTnqg2zRtFn3usrBV4GpNvsM 6jy+YEsSvUa7IY8k4wpPzEhIfqDjGbZxFSQ1H1G+mLUL+DD7oGffej/ZoC86TIdM p6ew1rGhJdQBLh9nx+1ADOLWjNo2R0h60u7VR5q/K6V4fwWmeGFipPXZCD92I+nR t/cjznwNyD/6J9YrBMF7mbGrS1TyfLaLt4tpdcBnsgqDTodd5OmG65mroXsg/lNO 7YZdecLZ34krfaLrWTtKkqULXbppB+uQvbVj8p8ONRImn6bZ+iAhnNaH9wJ06ico b1F0imJ2SJWnFr6PzPRr0gPStLgu9wrRKheaORwF/H/HxSyPZxNVxFqu81q518A/ plhub9INQLaxHf/TTjXpqZCcfdNTYUAW8rwbQfW9doSIT4lHY8bJXktb6BsVjkFj PzDeYpXeOoTWetQqsEuTdg/F+qg041QBLtNj9Lr3Vy3StgMciRUIP8m0XwARAQAB iQI2BBgBCAAgFiEE33OoPBlEv+8XSKFx180p3PhsFGIFAlr7/RMCGwwACgkQ180p 3PhsFGLWMA//V/XKrnI2YBh/SptUrgg7knPXva45bb7tGSH1fJg8f/wqycOSFFCY ES45boA5jlQ3z8uw6BYCz5KeOucGhxAMw+x5EDdxZ33ksY5zqXB35WaMXzEwGYYb E113/yhOsTbzu4bBKABSXbJO98MdAWvWpyCpp2MHIR3S9+ycM7/FMZ5xi3czZNRg 9+WZP+7W4qWhJptQ0kBh5C3N/tiltju5WQ2Y7XIn+5dMOJdtseFS7CNerxXZGAtH nfRxaD/4ENdbWOwaVJiVW7+ioUJz09OWgy0gLYSDW+hciDnW1QAaJLpdAbniGZ0S JsTmaZla8JnUKqZPgbFfA2OcnH9H+DWc0pHv17c5tJzTMP7rgirgGRX/U2LOzmFZ 1UxjQj5nn3Oa5frXbIAzb8xKiR0VDaquCM/3sti1AesYiS0Gw0Sqnw8qpFypgFXN CKVgYXppIT+TmbDbNJDOB2UycxeI4vbiBwU8fI4qSpW12WsGdAJt/rx3UsyhZ+02 4aSqDHzhJmtDPQ6lnaKe1fUkC90tgp8loVGmriWQx82jAQMqATVjIklTpE4vm00f ocQIWOKEE90mKNEoV6rNbfl5QevmapTVdV/pmrRBzhbsa1uAUS4HZdH0Nf/OXEyv yYCr2gCFPymkkRYhPr2w5EgbWyzLaBIwqjyIbXaveuB3DYi2Lhbf64I= =EaN7 -----END PGP PUBLIC KEY BLOCK----- ~~~ For more information visit https://developer.arm.com/support/arm-security-updates/report-security-vulnerabilities armnn-23.08/SECURITY.md.license000066400000000000000000000001461446772241200160650ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/build-tool/000077500000000000000000000000001446772241200147245ustar00rootroot00000000000000armnn-23.08/build-tool/README.md000066400000000000000000000703271446772241200162140ustar00rootroot00000000000000# Arm NN Build Tool The **_Arm NN Build Tool_** provides a collection of **parameterized bash scripts** accompanied by a **Dockerfile** for building Arm NN and its dependencies, including **[Arm Compute Library (ACL)](https://github.com/ARM-software/ComputeLibrary/)**. This tool replaces/supersedes the majority of the existing Arm NN build guides as a user-friendly way to build Arm NN from scratch. The main benefit of building Arm NN from scratch is the ability to **exactly choose which components to build, targeted for your ML project**.
The Arm NN Build Tool is tested on **x86_64 (Intel) and aarch64 (Arm) build hosts** for the **Ubuntu** platform. Other host platforms such as Windows and Mac **should** work (with Docker installed), but have not been officially tested.
At present, the tool supports **targeting Linux devices (Ubuntu 20.04) on x86_64, aarch64 and android64** architectures.
We recommend using the Arm NN Build Tool through the use of Docker. However, the scripts may be [executed directly on your machine](#build-arm-nn-without-docker) if desired. **If you already have Docker installed** and want to quickly build the Arm NN Dockerfile with some default build arguments, please follow the [Docker Build Steps](#docker-build-steps). * [Overview](#overview) * [System Requirements](#system-requirements) * [Install Docker](#install-docker) * [Ubuntu / Linux](#ubuntu--linux) * [Windows and Mac](#windows-and-mac) * [Docker Build Arguments Reference](#docker-build-arguments-reference) * [SETUP_ARGS](#setup_args) * [BUILD_ARGS](#build_args) * [Docker Build Steps](#docker-build-steps) * [Build Arm NN Without Docker](#build-arm-nn-without-docker) * [Advanced Usage](#advanced-usage) * [Use custom Arm NN and ACL repository versions during build](#use-custom-arm-nn-and-acl-repository-versions-during-build) * [Additional Docker Build Arguments](#additional-docker-build-arguments) * [Inspect the contents of the Docker Image](#inspect-the-contents-of-the-docker-image) * [Bind Mounts](#bind-mounts) ## Overview The Arm NN Build Tool consists of an official Arm NN **Dockerfile** with associated **scripts** for building Arm NN: 1. **```install-packages.sh```:** builds CMake from source and installs system-wide **apt packages** 2. **```setup-armnn.sh```:** downloads and builds Arm NN **dependencies** (e.g. Flatbuffers, TF Lite, Protobuf) 3. **```build-armnn.sh```:** builds Arm NN and ACL 4. **```common.sh```:** common variables and functions used by ```setup-armnn.sh``` and ```build-armnn.sh``` 5. **```validation.sh```:** validation of common command-line arguments to ```setup-armnn.sh``` and ```build-armnn.sh``` 6. **```docker-copy-to-host```:** helpful script to copy contents of a Docker Image to the host machine A **Dockerfile** is a text document which outlines the instructions for building a **Docker Image**. Running ```docker build``` on the Arm NN Dockerfile will result in a Docker Image that contains: 1. The Ubuntu operating system 2. Installed system-wide packages required by Arm NN 3. Source code for Arm NN and its dependencies 4. The build for Arm NN and its dependencies All scripts except ```docker-copy-to-host.sh``` are used during the ```docker build``` process. The ```docker-copy-to-host.sh``` script creates a temporary [**Docker Container**](https://www.docker.com/resources/what-container/) which is required to retrieve files from the Docker Image. A Docker Container is a **runtime** version of a Docker Image. It can be interacted with through a command-line terminal, like a lightweight virtual machine (VM). The ```docker-copy-to-host.sh``` script is designed to run on the host machine after ```docker build``` to copy the Arm NN build to the host. The **diagram below** outlines the operation of the Arm NN **Dockerfile** and the contents of the resulting **Docker Image** after running ```docker build```. During ```docker build```, the provided **```SETUP_ARGS```** determine which of Arm NN's dependencies to download and build. The **```BUILD_ARGS```** Docker argument determines which components of Arm NN to build. The resulting Docker Image contains the Arm NN build (along with everything required to build it) in the home directory ```/home/arm-user```. There are two directories: **```source```** which contains the source code of Arm NN and its dependencies, and **```build```** which contains the Arm NN build and the builds of each dependency of Arm NN. The **```armnn_aarch64_build.tar.gz``` tarball** in the home directory is a compressed archive of the Arm NN build which is located at ```/home/arm-user/build/armnn```. The home directory also contains the **scripts** mentioned above (not pictured in the diagram), which are copied into the Docker Image during the ```docker build``` process.
Arm NN Dockerfile

**Benefits of using Docker:** 1. Run one ```docker build``` command instead of executing multiple scripts, saving developer time 2. Can easily manage multiple different build configurations at once, each in their own Docker Image 3. System packages are installed in the Docker Image only, isolated from the host machine 4. Build in the exact environment the Arm NN Team used during testing, ensuring consistency in builds 5. Allows Arm NN to be built on a wide range of hosts, as long as they support Docker **Disadvantages of using Docker:** 1. Requires the developer to install Docker on their host machine 2. Requires the developer to get familiar with Docker (this guide should help) 3. Possible incompatibilities/limitations if the host machine's Linux Kernel version is too different than that of the base OS in the Docker Image. This is due to the fact that Docker Containers share the Linux Kernel of the host machine (unlike VM's which each have their own Kernel).
## System Requirements This guide will not provide the system requirements for installing Docker - please refer to the Docker documentation during installation. The built Docker Image has disk requirements of **less than 6GB**, depending on the Arm NN components chosen and whether the build included a cross compile (i.e. building aarch64 on x86_64). Repeated builds may cause the total disk usage to increase beyond 6GB. The ```docker images``` command shows the disk usage of each Docker Image. To view total disk space used by all Docker Images and Docker Containers, use the command ```docker system df```. This Dockerfile was built on a **Ubuntu 20.04 host machine with Docker version 20.10.14**. Other Linux distros such as **Debian** should also work as long as the Docker version is similar to **20.10.14**. The build outputs from this Dockerfile have been tested on an **Odroid N2+ target device with Ubuntu 20.04** installed. The build outputs should also work on newer versions of Ubuntu (and Debian) but this has not been exhaustively tested. To view the system packages that are installed during ```docker build```, please refer to the ```install-packages.sh``` script.
## Install Docker Builds of the official Arm NN Dockerfile have been tested on the **Ubuntu 20.04** host platform. Whilst other platforms have not been tested, Docker should be able to build the Arm NN Dockerfile on other platforms such as Windows and Mac. On **Linux**, we recommend using **Docker Engine** which is used through the command-line interface (CLI). For **Windows and Mac** users, **Docker Desktop** is available which allows the use of the CLI plus a graphical interface.
This guide will **only** provide steps on using Docker through the use of the CLI and not Docker Desktop. ### Ubuntu / Linux For Ubuntu users, we recommend installing **Docker Engine** with the following steps from the Docker documentation:
1. [Uninstall any old versions of Docker](https://docs.docker.com/engine/install/ubuntu/#uninstall-old-versions) 2. [Install using the repository](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) 3. [Add user to Docker Unix Group](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) (**recommended**: allows running of Docker commands **without ```sudo```**) Similar steps for installing Docker Engine on other Linux distributions can be found by clicking on your distro under the Server table on [this page](https://docs.docker.com/engine/install/#server). ### Windows and Mac We do not officially test the building of the Arm NN Dockerfile on Windows or Mac. However, it's likely that it will work if your system supports Docker. For **Windows**, use the Docker Desktop download link on [this page](https://docs.docker.com/desktop/install/windows-install/). For **Mac** users, please use the Docker Desktop download link on [this page](https://docs.docker.com/desktop/install/mac-install/).
**Note:** we unfortunately cannot provide support for the installation of Docker and/or the use of the Arm NN Dockerfile on Windows and Mac platforms.
## Docker Build Arguments Reference The following describes the ```docker build``` arguments that can be used to customize the Arm NN build. Docker build arguments such as ```SETUP_ARGS``` and ```BUILD_ARGS``` are provided in the ```docker build``` as a ```--build-arg```. ### SETUP_ARGS These arguments are eventually passed to ```setup-armnn.sh``` which downloads and builds Arm NN dependencies. For ease of use (but longer initial docker build), use ```--all``` to have all Arm NN dependencies available for use during Arm NN builds. Repeated docker builds with the same ```SETUP_ARGS``` will skip the setup process (using [caching](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache) of previous Docker build steps). The ```SETUP_ARGS``` string should start and end with **double quotes** ```"```. | SETUP_ARGS | Description | |----------------------------|:-------------------------------------------------------------------------------------| | --tflite-classic-delegate | **flag:** setup dependencies for the existing Arm NN TF Lite Delegate | | --tflite-opaque-delegate | **flag:** setup dependencies for the new Arm NN Opaque Delegate | | --tflite-parser | **flag:** setup dependencies for the Arm NN TF Lite Parser | | --onnx-parser | **flag:** setup dependencies for the Arm NN ONNX parser | | --all | **flag:** setup dependencies for all Arm NN components listed above | | --target-arch= | **mandatory option:** specify a target architecture ```aarch64, x86_64, android64``` | **At least one component** (e.g. ```--tflite-classic-delegate```) must be provided **or** else provide ```--all``` to setup dependencies for all components. **Examples:**
Setup for aarch64 with all Arm NN dependencies:
```SETUP_ARGS="--target-arch=aarch64 --all"``` Setup for aarch64 with the existing TF Lite Delegate and TF Lite Parser dependencies only:
```SETUP_ARGS="--target-arch=aarch64 --tflite-classic-delegate --tflite-parser"```
### BUILD_ARGS The following arguments are given to ```build-armnn.sh``` and define which components of Arm NN to include in the build. The ```BUILD_ARGS``` string should start and end with **double quotes** ```"```. | BUILD_ARGS | Description | |---------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | --tflite-classic-delegate | **flag:** build the existing Arm NN TF Lite Delegate component | | --tflite-opaque-delegate | **flag:** build the new Arm NN Opaque Delegate | | --tflite-parser | **flag:** build the Arm NN TF Lite Parser component | | --onnx-parser | **flag:** build the Arm NN ONNX parser component | | --all | **flag:** build all Arm NN components listed above | | --target-arch= | **mandatory option:** specify a target architecture ```aarch64, x86_64, android64``` | | --neon-backend | **flag:** build Arm NN with the NEON backend (CPU acceleration from ACL) | | --cl-backend | **flag:** build Arm NN with the OpenCL backend (GPU acceleration from ACL) | | --ref-backend | **flag:** build Arm NN with the reference backend
**Should be used for verification purposes only.
Does not provide any performance acceleration.** | | --debug | **flag:** build Arm NN (and ACL) with debug turned on (optional: defaults to off) | | --armnn-cmake-args= | **option:** provide additional comma-separated CMake arguments string for building Arm NN (optional)
String should start and end with **single quotes** ```'```
Please refer to **armnn/cmake/GlobalConfig.cmake** | | --acl-scons-params= | **option**: provide additional comma-separated scons parameters string for building ACL (optional)
String should start and end with **single quotes** ```'```
ACL provide [documentation](https://arm-software.github.io/ComputeLibrary/latest/how_to_build.xhtml#S1_1_build_options) for their build options | **At least one component** (i.e. ```--tflite-classic-delegate```, ```--tflite-opaque-delegate```, ```--tflite-parser```, ```--onnx-parser```) must be provided or else provide ```--all``` to build all Arm NN components.
**A component given in ```BUILD_ARGS``` must also have been given in ```SETUP_ARGS``` previously**, or else Arm NN will fail to build.
**At least one backend** (i.e. ```--neon-backend```, ```--cl-backend```, ```--ref-backend```) must be chosen.
**Examples:**
Build for aarch64 with all Arm NN components, NEON enabled and OpenCL enabled:
```BUILD_ARGS="--target-arch=aarch64 --all --neon-backend --cl-backend"``` Build for aarch64 with the existing Arm NN TF Lite Delegate, OpenCL enabled and additional ACL scons params:
```BUILD_ARGS="--target-arch=aarch64 --tflite-classic-delegate --cl-backend --acl-scons-params='compress_kernels=1,benchmark_examples=1'"``` Setup for aarch64 with all Arm NN dependencies, OpenCL enabled and additional Arm NN cmake args:
```BUILD_ARGS="--target-arch=aarch64 --all --cl-backend --armnn-cmake-args='-DBUILD_SAMPLE_APP=1,-DBUILD_UNIT_TESTS=0'"``` **Example _valid_ combination of SETUP_ARGS and BUILD_ARGS:**
``` SETUP_ARGS="--target-arch=aarch64 --all" BUILD_ARGS="--target-arch=aarch64 --tflite-classic-delegate --neon-backend --cl-backend" ``` **Example _invalid_ combination of SETUP_ARGS and BUILD_ARGS:**
``` SETUP_ARGS="--target-arch=aarch64 --tflite-classic-delegate" BUILD_ARGS="--target-arch=aarch64 --all --neon-backend --cl-backend" ``` The example above is invalid since it tries to build all Arm NN components after **only** building the dependencies required by the TF Lite Delegate.
## Docker Build Steps First clone the Arm NN repo to obtain the build-tool. This automatically downloads the latest release version of Arm NN. ``` git clone https://github.com/ARM-software/armnn.git armnn ```
Enter into the Arm NN build-tool directory where the Dockerfile and associated scripts are located. ``` cd armnn/build-tool ```
Run the ```docker build```, which downloads and builds Arm NN and its dependencies. This process is isolated from the host machine's filesystem and the result is a Docker Image being created.
Dockerfile arguments are provided using ```--build-arg```, the relative path to the Dockerfile is given with ```--file``` and the current directory is given with ```.```
Provide a descriptive name for the Image with ```--tag``` in the form of ```image_name:tag``` (example given below). The backslashes ```\``` tell Bash to expect a continuation of the command on the next line. This example's choice of **[SETUP_ARGS](#setup_args)** and **[BUILD_ARGS](#build_args)** builds all Arm NN components with NEON and OpenCL accelerated backends for aarch64 target. This process should take **less than an hour** with a modern machine but will vary depending on the arguments chosen and host machine specification. ``` docker build \ --build-arg SETUP_ARGS="--target-arch=aarch64 --all" \ --build-arg BUILD_ARGS="--target-arch=aarch64 --all --neon-backend --cl-backend" \ --tag armnn:aarch64 \ --file docker/Dockerfile . ```
Arm NN and all of its dependencies are now built within a Docker Image. Built Docker images can be listed with ```docker images```. ``` docker images REPOSITORY TAG IMAGE ID CREATED SIZE armnn aarch64 cc623174fd98 7 seconds ago 5.02GB ```
A tarball archive of the Arm NN build is located inside the Docker home directory (```/home/arm-user/```), named ```armnn__build.tar.gz```. If the ```--debug``` build flag is provided in the ```BUILD_ARGS``` above, the tarball will be named ```armnn__build_debug.tar.gz```.
The ```docker-copy-to-host.sh``` script will copy a file from the Docker Image (in arm-user's home directory) to the host machine.
The script copies the tarball into a new directory on the host in ```build-tool/docker_output```. It takes two arguments: ```image_name:tag``` and ```filename```.
The filename is a relative path from the home directory created inside the Docker Image (```/home/arm-user/```). ``` ./scripts/docker-copy-to-host.sh armnn:aarch64 armnn_aarch64_build.tar.gz ```
This tarball can now be used for integration in an ML application. The method of extraction is given below.
If the ```--target-arch``` chosen in the arguments above matches the host machine, the build can be tested locally (else copy the tarball to a remote device). ``` cd docker_output # Extract the tarball into a directory called _build # If --debug is enabled, the extracted build directory will be called _build_debug tar -xzf armnn_aarch64_build.tar.gz cd aarch64_build # Set LD_LIBRARY_PATH to the current aarch64_build directory (.) export LD_LIBRARY_PATH=.; ./UnitTests # If the Arm NN TF Lite Delegate is built, we can also run DelegateUnitTests cd delegate # Set LD_LIBRARY_PATH to the current delegate directory (.) and the aarch64_build directory (..) export LD_LIBRARY_PATH=.:..; ./DelegateUnitTests ```
**Note:** Repeated Docker builds may result in an accumulation of unwanted, dangling images. **To remove dangling images** (good practice), run the following command: ```docker image prune```
## Build Arm NN without Docker For ease of use, we recommend that the official Arm NN Dockerfile is used to build Arm NN. If you'd like to build locally on a Ubuntu host machine without Docker, execute the build-tool scripts directly instead. This involves running ```install-packages.sh``` followed by ```setup-armnn.sh``` and ```build-armnn.sh```. The arguments for ```setup-armnn.sh``` and ```build-armnn.sh``` are very much the same as ```SETUP_ARGS``` and ```BUILD_ARGS```. Please use ```--help``` for more specific information. ``` cd build-tool/scripts sudo ./install-packages.sh ./setup-armnn.sh --target-arch=aarch64 --all ./build-armnn.sh --target-arch=aarch64 --all --neon-backend --cl-backend ./setup-armnn.sh --help ./build-armnn.sh --help ```
## Advanced Usage ### Use custom Arm NN and ACL repository versions during build By default, the docker build process (specifically, during ```build-armnn.sh```) will download the latest release versions of Arm NN and ACL. If you'd like to use different versions during the build, check them out in the ```build-tool``` directory on the host.
When providing custom repositories, the following ```docker build``` argument must be provided ```--build-arg BUILD_TYPE=dev```. This will trigger Docker to copy the custom repos into the Docker Image during build. The ACL repo is only required if supplying the ```--neon-backend``` or ```--cl-backend``` BUILD_ARGS options. **Note:** the Arm NN version used for build-tool (Dockerfile and scripts) is not the same version of Arm NN that is used during the build. This means that separate versions of Arm NN can be used for the build-tool and for building Arm NN itself.
If you repeat the ```docker build``` process multiple times (e.g. with different ```BUILD_ARGS```), the setup process will be skipped as long as ```SETUP_ARGS``` remains the same. ``` cd build-tool git clone https://github.com/ARM-software/armnn.git armnn cd armnn git checkout cd .. # custom ACL repo only required when supplying --neon-backend or --cl-backend BUILD_ARGS options git clone https://github.com/ARM-software/ComputeLibrary.git acl cd acl git checkout cd .. # Example docker build with BUILD_TYPE=dev, ran inside the build-tool directory docker build \ --build-arg BUILD_TYPE=dev \ --build-arg SETUP_ARGS="--target-arch=aarch64 --all" \ --build-arg BUILD_ARGS="--target-arch=aarch64 --all --neon-backend --cl-backend" \ --tag armnn:aarch64 \ --file docker/Dockerfile . ```
### Additional Docker Build Arguments #### UBUNTU_VERSION The default base Image used during ```docker build``` is ```ubuntu:20.04```. Building Arm NN with this default image should be sufficient for a wide range of target devices. To use a different Ubuntu base Image, provide ```UBUNTU_VERSION``` during ```docker build``` e.g. ```--build-arg UBUNTU_VERSION=20.04```. #### BUILD_TYPE By default, ```BUILD_TYPE``` is set to ```production```. This means that the latest release versions of Arm NN and ACL are used during builds. To use custom repositories as explained [above](#Use-custom-Arm-NN-and-ACL-repository-versions-during-build), provide ```--build-arg BUILD_TYPE=dev```. #### Additional SETUP_ARGS and BUILD_ARGS The following are additional ```SETUP_ARGS``` and ```BUILD_ARGS``` that can be provided to the ```docker build```. | SETUP_ARGS / BUILD_ARGS | Description | |-------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------| | --num-threads= | **option:** specify number of threads/cores to build Arm NN and its dependencies with (this defaults to number of online cores on the host)
e.g. --num-threads=4 | | -x | **flag:** enable shell tracing during setup-armnn.sh and build-armnn.sh script execution | #### USER_ID and GROUP_ID By default, the Docker Image creates a user called ```arm-user``` with user/group ID of 1000. This ensures the build outputs can be used by a wide range of users on target devices.
To provide a more specific user and group ID to be associated with the build, provide ```--build-arg USER_ID=XXXX``` and ```--build-arg GROUP_ID=YYYY```.
### Inspect the contents of the Docker Image To inspect the full contents of the Docker Image, the Image must be run as a **Docker Container**. A Container is a runtime version of the Image, like a **lightweight virtual machine** with its own filesystem. The following shows how to run a container with an interactive terminal based on a specified Docker Image ```image_name:tag```. The ID of the generated container in this example is ```4da7c575a95a```. An ```ls``` command shows the contents of the ```/home/arm-user``` directory. ``` docker run --interactive --tty armnn:aarch64 arm-user@4da7c575a95a:~$ ls armnn_aarch64_build.tar.gz build build-armnn.sh common.sh setup-armnn.sh source validation.sh ``` The ```source``` directory contains the downloaded dependencies for building Arm NN.
The ```build``` directory contains the built Arm NN dependencies and the Arm NN build itself.
The ```armnn_aarch64_build.tar.gz``` tarball is an archive of the build located at ```build/armnn/aarch64_build```.
The scripts (e.g. ```build-armnn.sh```) in this directory can be run as you wish, changes will persist within the container but not the Docker Image. To exit the docker container, run ```CTRL-D```. A list of Docker containers can be obtained with the following command: ``` # --all shows both running and non-running containers docker ps --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4da7c575a95a armnn:aarch64 "bash" 7 minutes ago Exited (0) 7 seconds ago pedantic_joliot ``` To restart the same container (and any changes made to it) in a terminal again, use the following commands: ``` # 4da7c575a95a in this case is the CONTAINER ID from above docker start 4da7c575a95a # restart container in background docker attach 4da7c575a95a # re-attach to terminal # After exiting with CTRL-D docker stop 4da7c575a95a ``` To save space over time, stopped Docker containers can be deleted with the following command:
```docker container prune```.
### Bind Mounts **Bind Mounts** may be used to mount directories from the host machine to inside a Docker container. This could be useful when frequently changing the contents of the Arm NN or ACL source repositories (in ```/home/arm-user/source```) between runs of build-armnn.sh inside the container. Note that bind mounts are a feature that apply to runtime versions of Docker images i.e. Docker Containers (```docker run```, not ```docker build```). Please refer to the [Docker documentation for more information about bind mounts](https://docs.docker.com/storage/bind-mounts/).armnn-23.08/build-tool/README.md.license000066400000000000000000000001461446772241200176250ustar00rootroot00000000000000# # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/build-tool/docker/000077500000000000000000000000001446772241200161735ustar00rootroot00000000000000armnn-23.08/build-tool/docker/Dockerfile000066400000000000000000000054251446772241200201730ustar00rootroot00000000000000# # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Default build type is 'production'. Use 'dev' if supplying custom Arm NN / ACL repos from host ARG BUILD_TYPE=production ARG UBUNTU_VERSION=20.04 FROM ubuntu:${UBUNTU_VERSION} AS build-production ENV DEBIAN_FRONTEND noninteractive # Install basic packages for Docker container (not specific to Arm NN) RUN apt-get update && \ apt-get install -y --no-install-recommends \ ca-certificates \ locales \ vim \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* # Set locale for Docker container RUN locale-gen en_GB.UTF-8 && \ update-locale LC_ALL=en_GB.UTF-8 LANG=en_GB.UTF-8 ENV LANG en_GB.UTF-8 ENV LC_ALL en_GB.UTF-8 WORKDIR /root # Install system-wide packages specific to Arm NN COPY ./scripts/install-packages.sh . RUN ./install-packages.sh # Define user for non-root processes (overwriteable during 'docker build' with --build-arg) ARG USER_ID=1000 ARG GROUP_ID=1000 # Create non-root user 'arm-user' based on $USER_ID and $GROUP_ID above RUN addgroup --gid $GROUP_ID arm-user RUN useradd --create-home --shell /bin/bash --uid $USER_ID --gid $GROUP_ID arm-user # Switch to non-root user USER arm-user WORKDIR /home/arm-user # Copy scripts required by Setup into WORKDIR COPY --chown=arm-user:arm-user ./scripts/validation.sh . COPY --chown=arm-user:arm-user ./scripts/common.sh . COPY --chown=arm-user:arm-user ./scripts/setup-armnn.sh . # Run setup-armnn.sh: download and install Arm NN dependencies ARG SETUP_ARGS="" RUN echo "SETUP_ARGS: $SETUP_ARGS" RUN ./setup-armnn.sh $SETUP_ARGS # This build-dev stage (inherits 'build-production' stage) is only used in final image if $BUILD_TYPE is 'dev' FROM build-production as build-dev # Create directory for source repos in WORKDIR RUN mkdir -p source/armnn source/acl # Copy custom armnn/acl source repos from the build-tool directory on the host, if they exist (optional) # The 'acl' repo must be provided if --neon-backend or --cl-backend is given in the BUILD_ARGS, otherwise only custom "armnn" is required # If custom repos not provided, the build-armnn.sh script will automatically download the latest release branches of Arm NN and ACL # Copies Dockerfile to ensure COPY works - at least one file must exist for COPY to work COPY --chown=arm-user:arm-user ./docker/Dockerfile ./armnn* ./source/armnn/ COPY --chown=arm-user:arm-user ./docker/Dockerfile ./acl* ./source/acl/ # Final stage which inherits either 'build-production' or 'build-dev' stage FROM build-${BUILD_TYPE} as final # Copy build script into WORKDIR COPY --chown=arm-user:arm-user ./scripts/build-armnn.sh . # Run build-armnn.sh: build Arm NN and ACL ARG BUILD_ARGS="" RUN echo "BUILD_ARGS: $BUILD_ARGS" RUN ./build-armnn.sh $BUILD_ARGSarmnn-23.08/build-tool/dockerfile_armnn.png000066400000000000000000003376301446772241200207500ustar00rootroot00000000000000PNG  IHDRCw}sRGBgAMA a pHYs+IDATx^Uϲ. ("& !%(!mH7twwҹ},~ }fԝ;Μ=\p!B!BH%K!B!X B!B!$CqB!BP B!Bb9!B!XG+ BCCe̘1rU]Ζ-[:,q?:tH$H %K_~Y֭['+Vmƍ+:u]>~L2EA˖-%G!Bb3oߖCe"V\YVBH3n8Y~ܿ_BBB$N8?~|I4d̘QͫS\Y#((H)F7xdժU:믿o/q|ݻeҫW/-hp I../[L^z%K.իKB uyv6(QD"E ɔ)ϟ_uΝ̙3;Ł޽{_|2ZOʕƍ<>!1k&s1TRI6mC>}zs?ϳ.\|Yr-ne|\$O\O6lGA8x B! 1_ٳˇ~(-Zpz= ?^E89s:tVǃ9!(x|R`A0a<˗;УG}C/nZo߮ƍU!Bȳ:!{Ib䯿2BqD+\8'J۶m%K,w(C7ͥK9B@ (B A! uoŋȑ#QFb`q1QcOðBHc+@iӦe;w_- 0-+ޞ={pKѣy*TuJԩ-Wkի̙38qbGSۉNXzXԫWORLi.9ѓpBuB$ [~57oSA"$P2eHfc͚52yd@TA;c_ݻWmۦ|}}C$a„ݰٳeӦMZdɒIŊ7xd[B!ϰxF ڷoI-cߓ7nx#'VB5kBTܽ{W UT=Gs׈||_n (M4ZRJ6`׮]߫!C{|mp>)_QϞ={VM&7o[^8'b8'^r7\~=h@BQ?\ˬa_x\ رs[L-Z0: 7 9smgi oPu)RO2Eq^080^v~~~xw\ѣ*Tp9Oda{#GF}md C50~\`С֟~\HYfuo޽kntn(/Z-t  óg Bb;#իW`}=E /P۷cOnh˖-0ڱN۳gW9sTݾ6o(Q"iР Uվou{\F]_qƍiӦuQO&\߂ ;zNݶw*e,q=gP=Fp ߻… {:@G~ڻm۶!$yqxIP3g\?zk֬u˗w۷k÷n|饗ܹ J`Z.]:-{y |;i ?t萛pO  4HcG<= XU8o>7!/V|xo޹/+OB<8pmk;wtp1smxmԐgʔIgZW^wz-e#lXz| |%k?|9s\pBg.H!~7$w/2Gk·S]iӦs΅7im=,@=;UZU-6m\k׮K.}bc/Wsb޼y޽{5QCq<8ЩS'xرCfco΁^PhxʱE $} 7qev11mˮc{'Ǭe˖5K]qʕZw/QL! Wٳ/:~ʕ+NXA&B@9#|Cr^[Fv{6,[nu@8to4|e̘)4ryN8߿EVnp :G._lQ7oN kaou{`L8߹L<ko퇶@݋{k@d:xzb528Z!'e$W0G\r>Ƌ\M# TRD07 xi`o/@yw5y@a$Bb;W^D0H@x1^@xkn>x0^iLDŋnupႎ>&ƋS !?9w [xժUsKɓ'5ɝEoMj"'N请dۚ W-8ϰ-%7Y~ e˖O412O<撈a}Kw=y5F{ӵkWׯ 4H<#A Hb+޼yӹJ*W!9dŵnvBi{{ywL̵D#!#> k `.Jdյ^d졙-BvZKs^x?xi{d2Ypa #XƨܥK4;a4KJ,VwlX9B!0,&M{ E w> }=Op<8'F~p q=XAFC`ꫯ̵֙ywarv.VܻwϜsNk'O߱d4x`s+>v{mѸqm?7 #!>f7]ًZn7:EPPK`uf.`\}x9Ϻ4A] ;&;!B̰zN* W;fkف=bγf2\Xx7es>I`0 b:-sДŽA=0uwٗ#!寿GKwzGr?t<, 1۾[j%Y"2uTٴi;.ch? {Ts|x5iB!<ޱroV'=ؖ;z$7 wy7ݼ>PoքPޓ77ОYQmСCe޽:o޽{k >@Y c~k׮s;b+WִgP cav܌YY%zK..@m BBRѼ*-^Gɓ'QlY0aK2f̨ePҡ[\xҦM6R$κ6souG)BB'o. ͚5yLjٷMOZn7-)Sj(ž}975e{v0 :GFD0z?𴿁OOPOo7\ud͚U墳!qΝ {sG)o޼會Gwt1(B:pGҜJ*i XIիg9Dsyb)/'X@@vOUt!Hԯ__V^mqqL#Gt  r%G ٸq_5k4/~v2=_"S !ӣábŊ'`+7$waƌn 6yo%0qDyypОSȎKm<2e[ʕ+BNO-Z2=o 9"İtif?mo`4Yƭ ωc~2eʸ 9ߚh%KD)"81!( ?: ҥKaqla1+V0ɓǹM„ Í?~:r _~4mWl6-?uB ×3gNTas >PfFuԩSQF9;wc޾};: QF^ M0$Nda }X#%|׮]ڎO>uCB!APFw@^ C<0܆Äa` lchB |`BxwxaƪsaLk,~6ol>^oPwu*U04WX,uQpaz|Zjrï]C VPmDLV0u ?h_a-g̘CY˗/Y4nعM48ǎk5!1]~ٲe-AȐ!K/nܸ?<ĉx9pǛ{D- ԩ|lQ`!/^}^jL8W_9=8pl׉*>pښBxљ`9r<;0|Gد"]Ș={>G8~[=\rN.@H.Ԯ], W*DŽM2^/ߗvQfMsU 2s.z`l3mV@y5yz衮eجpWkwK]Ο?V?T|o񆺾!9@x Bf~/:iӦȅйsgsId…2sLGsj.+&֭[Z\)1`KL6HH:8x2\o{B!$IK(!F-[H\̵[x'c?9B 5!9pÆ f_p>No!K."E!s{?wco-@e8#͆|P-ZPww"&y|pV N[pk-rd!c̘1s^/rG*!$VJ wc_~- g !@{ߥ~B`BH)dhAH$+!>vd! t"bi01d=*TRJe86Xg~%}I"7ŠUVU1/e;10hvұo/b [/-Çu '>dEdF˗6=!BDmHPtnEbNFg x#?$.qy+h)S&}y< a|oKI `=r;:tHotA@4rhǶf; 0~G:|Y q<,E?^l6O:|,? q?RNߩ߸hCPdIٺu8X9魽!B!A2C H qvCAjժުOB!B!O^$J.?BTem1p@0>דB!BS="PYj͛!*իW Di(B!B!O-[<׀$|e:8@!B! Q"fϙ3GG2@Bl$Dh$6FzP B!Bb9LHH!B!r(B!B!B!BH,'9n޼!8q⧒9}F!qđɓKܸq͒rՍ RBܡ8@!B.wY$ [A'9 G묏o\Ϛ_ !B!_k% KNOo]u7a%Kx1B! V M&/{Cq@yxA‚|%R'!B!k{|9'|$qLS'<\\:-wRC9ܽ%wOGw 'v"?>xp嬄>o0cA/Q}=QSt^'b{Ƀg4\rﶹ&>mtY9hST/g;'j~;zф޿kAm  /έ>a| y7:$#ǎ]|RB!ĝ/ CdoBAAAҳgOٕO,%Ʈ5:!b}?1sx#rm9@aeI\JtYe6 a߅E?7C._IQd^0K7% Ga)l vAv|hBGOhr}JmkLQdoG;mr08?/yGY49||rxT'WPup=a;iGC9`zW7̗= E޻kC-^w98@!BW)0`]]rH^S;knql ~g.ΜW t()J(st/6^Faعxx6ATGo `xdyQwyc:y`O#'D_R<n  ~̆a!px)KZCpYuiJ@"Ǻ۽=σ絢0Y&{O zdCk6k1cҷmmִ0otD s0zsͼ 7R@΢,U6n+*)ke+&J/Y mE26E ^@0q%l>M}hRRO'B!BȿgܿFK7c ee.?ꉾ/ }OWi2 {!w'X=˞m U<撨o '9q̓8~%i \Syt"\-gΉ$LYVJ_#t;99.6 <$knDo& 36sI:m61"U會\m&b!\NlFX - NNRsD81 W깑'8W1sȵ+9GxISKׅgRFv}!B!_c9ϗ2"C* [Asr[qܣ;9)/,a(bL-_ h&qne߄smLᡡrxdG90ۄȊoqQĹ߿xB05\(򅜟'܁&Sҭ>%Yԭ X ?{A7<^@RM\ i< f 0]\񓹅Qg[(Dd‏-t.Oh#$ ի\Y?O?.Fޒ^8QGW mlMo$i|P B!+eFfܮy$).c3,00q\?t%5"`Fͳ,qpG8dOhu֡~Ŷ{4ݽ_c?3GҪ_ͭy`Loy&wCW'af ?@sEn½ "D主h݃"<\ܧGFukˮt4tb{+`ų= yᓆ!B!H$xI"7Yޫ-IewWlưrߴ<}|nc{}p-mG2&$Ⱦo2ۇnr~}GD#>g/$K&n~v 6y|^c;D{(l緋v| s)3H $gۯ$Yq~J[x1a\^}BIl'B!B3:2Wq`To',Ȍ6qrSg2<0jw]03c= ad {/7송_ W<ϬMKf=#RW"l Mo3BGrWdx}$+Z\ʼx\kx'ajjcM9*[B$n朻7c'8qRD)1lB%j؉)>!F,q'7]&vtټ#d{DU$!B!<2q3"`l0=_%9$aA)WBD$ǵ< fkD%? %X ɞs:Fq) CHXh(L@E;77DόQm%d~sJWWFr{BÛ7KmDo5‚zm`4 QRW|űgu:Z;{ĭ+{K'^D@qB!s+ ܍Wz =in1V,3%%(Y"|a?}!lOY%a ~tzP[-+[]ʝ oivs8r~8sɁ[t=<ŁG#ā pcԌ@ PVϔWv=8EM|(zSUpL5d&kf%dew6?M8@!BykگDaٍ7 1區}i_ȁAm/uH.Ƌ[x{;G2A dO^$ߗ̜QrbgjbJ&gɯ9WAb۰@Grr2mubb_9692Paqeickқ'G٣rxs:ŵKegZ5]=_֐]kQX"F`+Y&G~,9661uy4Ͽ s{dLW947V,E”DX!B!401 oyܓι{.dyĉ/9p7vu^ z9 mr8qGD@H" [șԛ1$*&bl廓iɊT4nqK.I^KKJ]X=,/u=O3 τxzL/骷0< <~xHl%Ocg'y*/>(*G몞 p}IoJt;/q )}3$Q7.?#W'eK`v>A|nۥ@*}@!;ޑc;6H\!?b <$Lf"% ufrgtl{#61x 5 KY8^$a! BBMDc37P7m)͝nǹ)ir a{5!'+\Q4WȽS4'SX@p2`dY6Vs'ɷta;OȨdgeTnZnY2{﮹ 4K}<&B!B!牄F[t 6SG /:0boܸ>Үg:٩hL2d!wnݐ?Oo5B!B!'"ĉky/dSvi1ƍ'餂@? BAoˤ[n6w`V'B!Bg ,k'KJٻe\>FgfΑ'Y5Ξ38z&2׸W\aahIgL n֍ߌilY\N;lmIcInuKF}.wn^$$a"s\zEZ2_%~F{NA8˜۷񼕭q=~ddϕlڴX~`<#Y$ng{iv+$ȸrF*t"W.sՐ5IP6/̑/Ȉ>]ՠ9g5g$KJ˪Ƨ'l'nK{$y x146}Yї}gF͎ JF5$~2saÐtu eqRQss3ǏH͌ޫ s8Q͘Qm344$7LFm;JHx.#Dn_v++>>>>K6dhJݕU% tkD\8W>mD- }FOO6\ ׈s*UNM]ޮo߼RQeedߏ} k^'N"VXa|MsZF` a=?-.t7r< ~$. # Ys͍d!2p@\#<gϞ+G{g!2m/ԕ˛%.] $Hƭ7,2ׇRf=BqV5f".Jw[CčS;Cn* |R/(m>ce܀>T?vSN}`4oWbϖ* `_Y h7Θ53U&ܮmqԛ`=٪\:{Z{G\"SVqK:c`e4I jԧbz2|R|۴r+(Ooj7㸟ܖ^J4ieԹ-zSgOORb>s^ǫogpٲiR=8^z|7w^?DWS/A+wq@4e g%{?˷3K"ĺz6fȐ0PjM%vc'ZWB!B;Ĭ8`&LapM)io0"#;p_{W1KpaaAC߁Rty]4}#]iRGsH;{_kP1]Fgy͏ ú$DXxz+@Ț+nc{_jLBzlRqd˝ϑ맺 SV,R;q/-WI2f! ='#&'B1,n\*c쥂+-~b~Y:UPַ_>iapN& ey%}K~,W3M6zQ?vGVAp k @AReꩀ?fL4p0s(v$IBX e~8Ϸ.RA. uSA uyik`ܫ*k=_R*wzDx !B!$:Ĭ8`G'I;#g5qGO_K]v#62'D0ϑ0Ij,xG?Q}RҠdy͘)fHwK@}G0q6~QOʽXST!շ<5`zs5^.q`Uڣ( @2Bx: Ɲ[75ms|k׸7ϘGȿ`2>xmtl`SG9)ĄsyGH]-;pְZ-W/]ЎV]zG8'!*۾Is!B!BDO&2";7K.&q"+.WpSoq1Js<4==Ċ}w|Ð# Ѩズ^y$87:;%I2x%4 }9%<( ?Ǟs:"ޭ׵W}]uIWoVGj; c eԐ_6 7j!9c14)'x>-O`B:, b`@VSmt{B!Bybs0RϤ7sƙG:xs7LC# ڬXmW/+'Qhdo9 Odm'x@1 f"EĿοѮ\M ˑ愰8>2cÉK7`/ST6:B@nݸhq1u<~fڰVC{xI:mz @YՋoOH08N`.d]7!B!<1fI^Ȁa\a1+L,㑎 &t)8i'8}ung'a7nnv߽+! ‹gOJ@}"mx\V>{b= <?{b8> g?s1:|PypiK@r(ŁGK:dRRQ<;V-1\$ILpPoرEm#AXxvb0d捫B!no^|Û^?c,u..T0+꼅exZ$w{ly g==pp{{c?0=[|T6 86k?dȚ]{s}j?gX{ge'81 F{׉Q[7ʼ>1H֋%uazxm$KQж~Iӊ[^?.}K:ċ +}?\9QZmss>e+\*Fcü^˦UK5@!B!%FŁlyKk5z[W/0E,V!=>Оb =`2+SG)#ʉC}if칤j];wɈ>]d¹ݑ}?_VnYXAIuB]Mjn ޝtؾ]rƬ9$W":?nZC{vy&8 c a@YwUoMܸ$pd.l>$N0֓H'd2fuI0yI5Ȧ߻UC?ڽC"! tiRGVΛhuHn<J_hĤAS/4Cw[EUtB!Bc^Cȱa]pϔ #s^^0KnߌY.:Q[JjRr+$UCIBCBհO6|9qo؁=p@5flX C}oH(7h\"Bh2>O`7_{ݧ9<ߐyy+qԃhJwiR/m>omNA&|_#Gmh$h@rY:a 8PRB"((Hz)rԑ)"~WB!6NMJ1.Xpܷ}?u043~u<$!̐?Ϝ#W'ui/3B uH.gd/SPK2m:gmVɍk-w>'p^laő/d ^0[voKKUYW~SC/^Z2M:3N>(i2dR$:mFB a$Do)$E4*`$5<2`Ûa&ڻ#քVxw b߶M*T=W.=k,~x~h5^%:)F=yx1CFS}O^):Yq/ѫ嵳Q-w#00P6o.W`B!ĝwȱzgBb <$Lf:Mo_!lWΈ_B/Ƚ 8_Y7G?.YIKr](;Gwʍku_T'^|=֝{2 6e㬄޿+m]fO yUHg;vzvɵKZ%6 ƞrcjm\xK.~fͽ(g\8Qw߸"F]}h$ʜQft:Y]5vn8 H:omkV+s~dE*I u< g$J[tx?&)Ֆghy%Iޒ:[q@J_rhkۖGQoEXp_`{ ^=';}ĈI֥rx@y?76wN…%SguD|wOsY$A,}Kb̆qcF"=w7eq'}O5].~rQh<Ǿ3qn-6ݸ"cӓ&Rp^ɜ9Y'wСC2r8iإ11B!޸q,0D(f)!i$={]9R98;g"OeXdn097{9 /{G 2Jkr|R_]'Ð^Y/ja_9~-i*0wf]%i jYg/"lqɭC[_25(_}_W7̗c>QN$)%O@9M94eVꑢL `P ]q_TRrzP1md s@,wO;^6+k,㾥,΃pEyzy,9C*dm]ap?~PCF2OrLVy]! m}9}vPyZ]mV,a\F[.+.GFwޑ?#cɕ?"_.[dAh5Lei[a4\Z5nZđ$sw* z HƽpԻOYuMQEI0TR?B{?o^O߮r>*6NMJt B!5c;t/\|# 9;;Ö\Ixa$O0S8 (wE+; xf𩜜*& 3rog~2|&}zjy`j0{i :yp.?.R @%{O%[^ˊã: `qj)Jא %rƅU{ܷAMU>* 7)JV ;*3JkqX0h%A Qhxb(m{a|־ zOLB1f$ڌӿ 10Ànu9eWC.bY %]fwS̭ }H|ݦD:B35((B!b/<4L,I o\86@`qbEosRm="_̕&HG9-;CVR?u&-Gz`qQI]5)ORDqX[unŹ?A at}\v27Sw%}ͷ$C6zs]cbq^]a+͗N،[JƺmԨؠj#u}ez 7~ <4԰YC؀X!X>E UONL¾[>i8 BI5?<c3aBz9!n9O3 9qd(a߹!~gk;C{p"y9Yۥo1ax|XdkCrLT ~2<B:{='kx@fm- B!r!ſY,%4Nbk: Q4auL'k}b;F)zӾXυūj9@캅JHڪA| /Qݹ(4nNsGjMVɶH1c0j-qu.- rWn |{"D#k1R aj  .zOk$刡O^CF~K+~|*q]5?6jx7VMH[ fPkN]cmkj %D]>X u$˸@NF)1tHH Ba8g=_|֬!=ypcXՎS9K?3YG2n-3!B^c aWds񭂲 7P2|LC$[mY-Hbg0NM%s%"t(q!ٞ=\ø l []ee9p[5 fHxxDGѵljST>6ΰz0 Nت[Z)al[!6ೃi O\+a~0TPyNc-ڋ:>ɑ CPZmlz2 O7նzq6l+ ۳D_AkcK1=)êOl؞[h۽_ y'(QU/_yd{Tc_o%ٽXzqv'8@!B Fzޑp_5[8F[rD\Ɩ'.Cvlǵ:C GskCp0 h$`:@25ͭہ+͕ktߐ[!JiC WH-#k,y9& 0#9 B ƒ] >f[gu$NO -_1:oCޓCt3O y[}ݓBt\[k&VDP3'@ "bwz}8D޷o "!rS 35ww{^;DE" }-=S з4!&BtH/!B1ABBysdNҁP {ndZЈ  @b+bcr%fss{Ñ4q|/qJQ `c|y 8pu7";9\UXC){hDG޹@$meRYXm :^Y7G 7ab#L5=^4Z^mOlF]C|ڎH^Gdoh7K.R$"'73! ۟8W18a$<'xXdJˬsC]k׶sr+^܄'CޓC:hf3Gȅœ3JtYpg#bs.xW+6K #5Hv96/M\9k\F :,-C{PWV"P >7gΣ pK~u>o!B!&AfVS('i*;b })sra9Yt<,$!!`dG?2c(D؉sӼìbA/>eIި_ZGO*)K$@ppOB# QC^MjgK|㒱o|]a -$%LeF44a=h ]d;#G,(׆YuQSZKI!=kH /˃Ƴ">wnJ2 =m6n2}I-$8g*H)"HLy\ IQ }9db?&!EY`MJ`2B!Bb9h' 딣'_Rْn{OxK/K焁GAqB!BHy6&Ň.7Rb2)1|`x& P B!kAN/ij/Y8@!B!rb8pٵq1A\lTC{?criFMF5kݱ~xgt熵|x&~!B!䉊ݕՓޭI/cZ$sͳCo#{w!IX)y}'ɒ+g  2K͞ $$8X/9)|UN> >>>Z7%qcM.i*oB!BDŁU̒;nH)uY-&АI> T+yzso-kW͒Gߤ@ɲxi]X?ABFK]~ٶv|%A__'NF1B!_Y>!At_J)#rp6-{fn;fԁ+7{j8?@8wqŏwvn\ ; N;,W۾ }p]3N_ ʵ$$zչ$HHboRB!BH቉$TQWmSǛ[DNXXoY\E.'G풻n[<&A?ΕS~fj\9 Eý<2^C7:`Cs.wV B!$c&^Cȱa'\;D)_|oW_eֶc?ҝKםʾm4fSFm?&vQ>̚0Zf4ŏ/^o)l'mjS; ( (J4Qv=?xlcddߏf5ǬI<}lo~\c,٥RQ'?|4fXUOǶAKj~I*լ0ߪVJ)wH\䝺a|B;}oǃQpFhv<ָ`3!xQh{W^GZuD:7Adeޮ3˾x ^Ξ8 Miѷ;dpfK3$J$/T>|5wF8Gy &.,wlNj)sTLni#}VKצ/0-mO\,#/|2GT֍kچV-5]&I{Y>RQ?Ǐ hˏu{ˏvCH| IOYxP3&3ǍT!."!<N#igG}Ҿ*`}&/k>7G>'z7\Myh !B!H' C#G/ 7[Y8Wk ~k'NjqnjMXf99u};u\ZW/q]s`eҭ+ZɈbFN𧱾ۙɔ_˄o>St RmE^300R[V)M,\#?u@ΘVC*j,kZsm}zSWT2hyL0c`O% IR#~[xy֡FqQՇok(BeҊƽNM/Cz~c歖 iVGMX2EQ^nT!vn\CVs`;x7fڳCժF:Ml9 ]ֶTdʖ;R=2,0gϓ%Obug~7ud9{$KJ@BY9@!$wF?nov& Ys ⡑ FlѲ/VҲM̝Yh^mt0ҨO/7a$OZʿXK,Ў=15LԀN/݄p~p?3<ڥ}Uqt-tU^~-0,JV#z:p1&g|D;Wvn_xq%9|EKq?u.P@1:5Mbh Mg OaB!$Ł{w3 RJ#%*p| <O:E-S{Dy{@vmq+M.Zt1RLM1 7eqwo٠u6k 1JFo0h3~ h8yQavj+"hWK8wױ}sHLm"2[<Siӭt0Br( eXm #!_8 XlY0sF}6""%B!BQqwFϜ=]2k&ʳd-_5 }M% q53{{dXxm$k2p?8Zfn>4yՎh`N3u=P*l!7iVRך[M+0Pf&0RDN XQo 5~Z>io$Df¿Ii$ y-P& R>3lj3ˌu{>C=ikB!B1q@p^2OtX'}<{pRvT|e]aQ$IB>& |sOhj7jB=x=< RpuGzē#A݈p9玳< c'OQuɐ5^zƻa&o:TZ)fvƳv3x&{JvȮ#*@]a<aƕAǿTޞG8+?(!B!1&ڴNN9 IQلT_nѓ jo jomŭGEFgrC۷s.. i2I!XFzz>De'KZҘǷk߶nNrpvo%b oi`0yGB#_ dhV{_w5jѻ߭e}i\ٵ/] (_(2e%ITchORo\%K. 9 ^nJ7\"y;OHUdQcw cFƹ$wP}EqF8Nhu _L<6/uA6( ,uY@*Y,u Κ!)̘(',{EMk0;) , ~_={`%+\C;ګ1w0x/X=gzMgO'@ĺ@|iӭ?R+}}F'_Qw:uV{dsr^mxܵMz@܅{9$wJQN=,6~ϏȀH%u~엽~\:wZfM-c)e^xI[b XJ*|=2|,!=?UŚ'3P xk끲{_z/>tw}nLB!BH0޼ZcI.sdL0$*-:|ӭ7 lJO%O:ˢ_h(b0Í~DZߨ%voeK0Б=m,Iҹq-M8wiIn`nٷK +%nП`<;ǃ:<N=#=zd͕OC ý[zu#&D$G;{ֻrב L9P&Z+^=om5hI-'ݳUCz 4  g1v,?|QA.$)VӵIGq? h{<~P?)[ 2WA]qOm<#o_#ft$)W!XV]g!qҤ=6URU!<}C 1!!1d!2p@7E8B#xSv#S8%BixԤ/_,qw#00P6o.Wy'{$g" PDdʖS2ܲWc9FR6Ўv$OҠM1{Igiך{:3f!5_oa텆1J>h04}Kί`P$k-5lP{XѲ%Obfm!H0WhOF!fbz&c&"e< fH0_Fz(ob+;<0 gchkt&Qf=)d?`>EW,wv;(C9m *}lZ_  z7ѶH*i~A.s6C&)|5)[%m<-S4tjRɸF)Ҥg"wA3k+^T{ =ly Hݦ4gu{;xj6jn<O-6K!w? @'NSD5ށ/_>)TNYƬ!B&Ͼ8`z-ԑ,e*ɖ'Ylii[۶,!B%~f9sNӦM3xB"vءȑ#5BH?9plsd˝_'1KMvmZB14iR7n\\1?{B.OD Keϖsßri 6F$4$D?".+&쐇 Xſ#lZTKU~R~r ]y=P6\,׭p<8(HΝ<&-es~'BA]_b\ZYLY9oݲA=<{VdۺUmPJ۹v6jH!.:%>ZjIjդE2zh9uꔹU\tI&L o[vm֭ZJc!Ch:LDzիWwI-[9:;ykj姟~͛uҮ];~iӧ_~RF OΕ+Wuƴo>sշ/ `?}5kՓ z_9 ( B7 Ϟ8*#~$;6i,nxRdY0ҿ0䗨`z 8F:U]_>'se5T0˄%WG"  /7vדkW.I e=/nw`VC9o[!%W^aRfwȨe弙$IBl'ou-qlhώ2U GDeZF!2O2!'Ԡ}zAT ޽Fe#_%2ee~A)sϜ93(0 uQCnݺ*hxr1ɑ#aOH~z"I$QcŞ={XbN/ɓ'K˖-u`@} /z>3۷ΣzpBm;ho HrQB?SKH{zyfyJ)^yisiUͿ ѽxKvMe a"yc0d$5^q=.>CLNr/d8OwoW۪@b$'Sه0rhvɚ+6NBr*=zMnݨ[n̟1Q?6k#ݾ#]jSo?켞"e J>Kvt;Heʢwp#n$G$=3wo嚯h*uH"%4’QgM&, I!bxБKyg+"+TRɀtgϚK"~ wyG]Q+W.QL:Uk@$' ,[^bO>yr'xbyFx5^'J,n֬?)>cɘ1C A{^z 3bMϖt*ZB!:1" َ߲^:{(QF&."[#  1[5*d)R<{BH_ ,g:1=$"e"~ݺ8W$M&D ɒk/AF 7e_oXEn Bz-%KnvУמ,#At [Xn^*(C0 3x=p-GXEO>yc#DC8pm@ϼ= D 33? A?4 {ٳkB!:1"ܿOnp$쉷K껂B 7$o^ _Ovc]t?ln+0L'QxVX)R䩌_SxvzFÅ9B"bwIGwk Ul[l;޷}oϞ=[ cϝtُ1`h"='E52MpcvvC>;:b;ƍҳޞcz x!g.U"{7CҿCKܽ;yL˲t|0G$CD7# <OG@BXyHw|Jqiu{L蝛7䒱*K>$5@_B!.0=a 4i9w{ s nDhB ~M-`a.]Hvd̘1XwNHav lٲE+m bK=}ts=]ְ `I2, ,#kaRw2Y?PlE-1[:¨wCW̨eÊZ:= BHl^zο0v}ٹs\xQXDH›oi.lܸQ>3MT"#!ԬiZL2Et wuuN:v1˗wFF!ӦM@5OwҪU+g$] tPa؁ErYy<_N=$[Ȗ'Tˑr7u% _ca:t %Ho4B 2 Io%D?HcǾ-`„ ZjXEO*V(52DFpS?~18,2eʤ V4O0ׯ/[\GC;CG t\r\àAB ;gGɒ%͵ :qq.|:o˜U.IS5 Hӊ*%EbŒnèד~ {9F7V1,ƕQMwWSBMH3gy0ac#Gx$UVQoeGO1Q cիݼ,D+W֞y}TRi0sϞ+ [^n֭SĹq} t~<SĞ>|^K@`{ h٩Sv@[sm=[Gs=& ̛7-_{ *!,cH4r8iإxv/mc?}BzϜ#T}TH?rBp<'2a":As=6,3gΜj@AΝkbAΝ8"{!S%l? &a% p^\;W^]!~!D׌}97}$58u7Ghl ٲe3sD u~@$b \wϞ=eW:r?{!;6NMj'1.B]=;!ryp&~ ݿ'Bޒu>^/˓,]yxOf!>zXwG| [6Aljƞu?UFIǕߺ&N?MId["q'KȽ[ZĹK'B!O P ˥_I})ٚTj nia_vĉP2d|u$9<ҝVkޢ΃-Kаt>M%guwږ(=Mi/A.JB` S? %<G\mlP;7ƶ5y꛵IwI_y³DT?H!B!?OUϚ_ >r%9]cֆaY)֒4H%}9=su=0<yl|4( ?z{6T)6:*H=Whbpp仮ƶpIQdm(=93mno!B!Mڛ#;Jƺ$sR/sDU @ t y?%$E ~΄/'N\[S)(xup1UǽH= `6&yG[rfh]Ї|U$_ױ;R*ۆG%\ 8@!B!o7Q/@$=&Kc$uWu{g:$/E:IQXw`WY_\q!ٻ%`l.8w/W@D5+}Hʯ9 BB.cԛ\߾)<,SSB u߸V(B!Bۤy&pO٭[0 X$̔˜s(K>s uy)N%XC؃%^4߼MD )J$sӲ/81sީs:;g#ÿB!B6 PdE*i~?rVG85c^[أۆ9r/0Oǀ=3p[s/iJsA9QGa\/I ?eI1$ʐSCoHg B#ܹs:͛ =BBBȑ#eٽ{ܽ=;*BCCĉm6ٺuΣBHg+ zLCK$sNZBޔS3| 4\]m}m"F 09](0yAdG}տB=zT}I.dʔIJ(!e˖yJdɤYfg'o& &#G"Dbżn13g-'OYy)qĒ9sfR|6OHڴikiyC(c(L֔$I/|jGڱ]v"E m2eHѢE%UToʙ3g-A $4mT RJIҥuF?!ZA7.S޹j?kHfKu3H\n*aPOsIn~)/ecyܴHhQ +a3rxԺ15Ѳ$yJ/}x9ᵋr߸n¿ BlذAJ,)G˗PSC瞓+VK q& 9m&h<:cNds玜={VV^-}Q7yp˗/vFXX۶fOH"^E=7ncǙ2eTTIΟw$²O?:< #F`pABHXEs90]/ ; AZ u&IcӾxtۇvɊ= Cn]/g玑ɩ;GwjbFK1Ƀ+g%u91sM L gA\:qty`ܿxJCv#u88@!? mʭ[tO6l(C ѩv7ׯ7={H,Y[d̘1D\8/&^xy\.Dܸ+#=QSN5D{z޼y:($[l:NZƸky[7ooDSNIVDSh۴i#ÇZʗ/G֭B!&ZCO;>zIu,;Ւ]K[ [=\JwťSesR}I99kpq)KyΟ9Tvm$[:$celcwO^kۖkFQPK\WS!cM]5ljX-_¿ $K/ǿn^wĠq(YwY1\rY-,!.3D:v(tE?CzazL6\W_}őMk׮`/\0իzy< v7Jh X8yN0-` inܸ!+Wy;wyoШQ#;ӧOoժU͵`(Ghߪg+sNi=DVZ%v2D=,OߤId9Dݺuu=شiE! ?X?$m7$~ M|KR,x|xbd^BX@@^jak(ln gۯthAd+J@b`  alZ)N|H v||}%Oa'(s MĘ+Yv='oWp$e:񎍗4m LvoFeH Qޝ7˛UKhֵJ %1O_6黡f !$&tGl&@NAilyd>lcs :Ǐ^ 0|'w%B=1 ?^ ^0QqFvC=YuO ʕ+D"SƎ؀H#m/x@?/ضpaRԡแ !H&%]eLk5nFqxnN%odͭ\& \ rn[%i򚏠pR4 EW;hDsč'kbJɑkԨ:vK;cuRrhI{Nx&IB$Kn|ar_8}R>`o77Cۙ/CN:XA!$"'}a# G~3uS *p] y+/V[` ;Nv/qqSCCB[zC'Ixʬ7c+fR#Kwj;GB T(Տu+ҠTN 1>>O{>|1:C Å =08p@ *b@?\`_\ywՐ߾}&"`G~P@m+ܹs "Mc*'ēgϞ+G"Y}xG!ҐI%,kgLK&uXĘ8=FȐH窘(<),quOνRB]<XhƝ[I _&MhrBOCS@XAd3]rE gAҥK_hVwVSQ<'"̘1}x@ wB-[ {rM]dװ < 裏zQBT06{b8'4HR[ I.x}y29=w_pp(7rjVWn &ϖb+6~ݕ'Epꄆ$I*Yr_o1-.mtq|7>8/"<# Ǹp\4$e1[,AՋ4 ^4$YǭḲŁp:3>`@nO4>Zd5/B2˛ׯɥs![Nq>O}E NJhh^[G[$q7,8ޛCpCvqg$Rx}-qMҲcA]lTCxE۠dVnu4^uG2Z_Ǎ[7۵Kkդa\2gG﮹ nry5!b&utVJI ej{ݻ2ۯYB乂ҶViX:qUd˚v[֬WeE9Ry3MQNmyneyDvХwהJfu*[551)TjV=@Y`,Ҥ>h71sy; Trd'M+ o,/"\I̚T SG敋n]jUp5׏gyzO|ǨkB3G|޽{=bՑfID`H(l&X> ouB=0 $Ia詷UJrerw@ h b|Tz(#o߾žy.@y]9*='g8qOO dDiK_15 z Fץ[ dURҢcRc/?lfSà\pLNE:~6DU2d.֮,wm.*yU_ܠXJ\R쯥߻X)i;9&Wl۶m۶m۶m]|m۶m{~3d]]g{O=UБLE+YR%=c% ~69w u+Ә"CVurTܮ>3kK߼zA P})}c$gga0f(@ej5iK.:Fku#={A]Vwo_SP ڰOӚtJ&#hٙLWp; ɰhQ6?8EBUU}3Reɮ"wo݂8έ7z5N7. PUmQ\,-:RJjk(<}z +2OzyuhꠞW"51ɘ7hBN^pP+6lߎRc,?-toApᇾyfuCB=`nl`ٳg.P{0ݾzY/i ~?5ҏZ“a~]xu Ti֎?m׃j,(\/FuԾruQh%l~qڳi %n\FZ2+BScuhUoىo[w L7.mi3e P* JsQ<Ӯ:}SqŴ Yˆ먺֩S +w_.чj,]aҚ_ cmfa\fq$./ra6o>A'ϧ%JHtXc{є{Y RbȜ4Hw1Lz,LNncmqXN>ovq`w:^Lp]^sn3v,ΦCUq+QU{ӰyYi}:ya@ׁw,Y+Wo3 ߣ;4~k+"0rev;v,E> (^0KGo`ـԋ V*hN8a΄{Ayɑ@h[x-^8+6hQAw+Lg(tYXCv錑 &:;+߱ q=cnlQ Xhm)2d(1 _N(HPЭxؠ?K 5߾~c@ )C.{%A*|_:}Ct%P/y|_ UFh1(|(tr#V.Ʈ%קZm-]J}Pvf^+#$%TX)PWX==*B OM p׏Zq[Z=~ϯJ8(#< 48ŊܪŖ,aLK0an^G"j:b)<5 A<cBcj=nP*P 55 &\D5@/V"E3^ެ O=dS|ÎJ Aj^,mY0l&[!N//Zc/ӏߥ[(lf˭DL[zFa)gOhTN ' qN'By>Pk ڵgv?~́piF,GVkUV,@mF/A'O)|oΚ5Z '5}G .BÆ Oj`!SF 7paЁ@G/^ШQX2E{  M#:U/U(Q4csԺbaZ2c:g14Mp/k d5ضz Mқj\cjT6n2C`!B (<Ώ@UfXvncp`E hKgNY V$Έ;)xb@3븟e|'x=^1OA~ў3f0̛cݽ, U砄t[7Bjqk_~` x , #L3#e!b`"ҧLU R[Ϝ9ڵkͣ(+f~".#"7mڔػwosm }WpпA/.]:nOŚU»GtЁA?Z@9-gd@Xh Mq Cp,2 įWp ʔBe¸(SBFpT أʏh] !}JE9p!H!$"kuGS -+rl^n_@.#?-̘7jԳaU;nmYz:o';qK!K(~)zxEǽ@U)NSC[-4:+L=RP =6ΘAC{ "[ . }cl*] n^>Y ZU*̂}Xj\n3쀋{w8s/ȕ3 낶zp=Eu/&Z@An:֭cYM:5 8?;BlyP>,(p !-73Vo|/YdX? Ţ3Z0ypE@`u{ V 5@Cvu@I7nU˖-98~OAj@\cǎt(`  7Gsg6G(hଥ4o?c1'L>*q]֕ԽAenDC筦{ҪwhMJ)y:e!Uηa3A^ne&L8R5Ҥջi+=Zڬ0x$zŭ+lqiߧӲ_>sܖwmm,]fh;"A`&7MB&_J4x OlAR>huTW ik^U%Ɣ=<'+ʿ.إ[IAp2@t5޹9k^D:_}y8=x1ӌs2QD,` ߳x bƌ]_k B[n]s[^\ Aӳp@cuqP~6bdv9ط3VVΝ3!Ä3W'ݛԋC s8v&/=x؇8y[XE& hgN_VZM_DMN {7~3R$A>4 AS؇{ )C.s(,8̨{d іbx2 @IT~s CCc2:{}tn]70eUɞ=; <W\iGp)vT)Sgq4ﷂYh}f?~|ɿw Јi&}6;v ^Yyų4ҡ"{b=$H㍬1Vpɓ'm-!o޼^8qⰐle˖톸P8*\ 8@WÇs<Y(Ar㽚E >w”i9 @VG/~q'c3rG 7TY̰JY`v{ư'u)*[@y=͔m6Fn\i6BWXH1XܹE[@z4zصWA4N7.MXC"cD)y3|ׯtjQ.?ESS~mRk8h>Fի7q?y?ȩlƏrÏ^[+͞BH]%LiRa^څ3\6pBJx s@_a̙Z7AAs) Wݡ7q8ؙ+Ab6W(3ϐ̣T9KČV3?>"#ȁ!thPYP dVͳWϟVS!ZA}BIҕ(l(T3OuW0NlwQSm1hm Z 79BdԬt^;)=W12҉3?}d!DhMsq :F'u"Zpo_2O]D鯞+UʜXWb:uh Bc`RT(Ax*(G##(й8%MIoߠsPL~T&Ml٨*B6hce_?yi EQɔ9!ڴu6F&;[ܶHk5*Jiї:qm Z!^ x70s}AA~oTn@RL30m(e[SBƬwlmJYy Ylp]zB*[):ZI9;q#0\'1w2׿U? (\zNM%qQxW,%KH`4mFJ*qUkWY9g*HA* eUBk3V`Ip)z9G<EԪ(.{^+f!B==c|Wm;V,WFQcC#>,4bOf]K`!(o ,5GjR^z6S]Xq׬H1+M˜Xicg!pA(T``c(llMG]XW:& jY- sw>vM_ ~lBBŧρU ~ v=LWizImX#~DG)c-Z4s_TjԚvgn}D3fH"[>D&L*Wm߾)SܜuVs$IgϞjЫW/7{ĈȘbaժUnYlk ,\,k)]tԻworyѣ)Gҥ= ze%.\8vYA[5hЀ9um5kP̙\i%dɒq/ :@TgO XBmd2svw9eIт ^ѳ3/@cƌ12cs {<ÇS=(eʔ4n8ؼy3[`X˰gzy[9[ ߼y&O#3@M)|p;v~Urdȑ,۷ݹ $&A Q [VK ;K0B+je[hp1rW+yAa0c,Y?:tԼG5*Iƶ cЁpNKẸGҤIZBf͚- D/ ݻwh"^ X;I0! fO+|;w'O[ W5k="E ^:ʕ˖jb \tb((+}> \MAOFH4s?I&a}l6sy1 z9ܢE 6o 5mo6;`رct hԱA NVk׮ )G`_TR%sg&L0? |xJ6-ըQM[˃ss? P@1zh 7!AGr5s%Kf~{A=!ZcXSx7y*Ti-L?&?VbǎMwaŴi8`5p7@@I+ JA Q =o޼ar,7ntW=QD槿ˆܯ{z ?2B/L5x\$OB1`eU1ɑ#p}xX"͙3ݻgAQ =ov0o/Pu֍bƌɳ'N4 Š3]ܹ"ؔ.Ee-М;w] 6 # <85mڔgP+d8p\fϞmApnP8,\c f`<~k%Nf! Az† ˮzر#Og?K,_`{nh2g3Xu# *Й3gdɒ#+RN2VBa +Wv@AD9  yqˀ=gΜ3p5~ͬYlOr(H n̮߿DԧOva۷o7"[G @9"hP Xi?/ݻwOD)RpG?ŀ^KG\P 4P,Yd6 , `%I$P v\0pGk w AǂzVt{*r%sVA7^x ܻwoAҥ͵.V_|dEb+NM+VZ B.\870 \|2d@Cf =z{eRhOF9AoB ~ZYYF9yl/o_?26 j>i7%R 5G%}'Ԃ(Yf'ò.7o4Yd.h(pޤI8pdAA s NE1cF^0\V>:=͛ŋ~X+VdЫW/ի=:KV ^BC^Ϻ?~ dO ~C qB,[̦,< 2׌6l0?y<{J*&Mg@N]vm%n({k@OS=7oR[@ 7!ABf}ri7naAPD0 ?}d6@̧-TglX3hzH:uY @}IBP@yPEWzVk(`}pBVhA;v} %*趪U)Q}Ѹqh̘1vZR@ AA A`l1"$g˖V`r\*Ur'Bp:;G#P68;ΣŚes܏B]veիS$(:5͠#(ʡp ިކYG9GcuaӦM^8qБ#GEZ!CRXtرc+{ CQuш#x ׯ_z*kzrxt~L>/V/?ٮ#suz}jKYy0]1PֽIA=8m 4LԽ{@@ꕀk@x}! "ѹ3ծhyx5W4^ţzc?+Zb߳X+2[Ƕ8\ Ȋ4hPV&xg]}.mk;Np"vzm0ͿS)xߏ7ϟАJKiſ8{ŝ cKWh ,$ZISk>׽/Fx=~OtFND7ZV*ƊzGD9  r@pGv# &wAr1 ,ף'IKuG,;W> xݷ_6JlWfuB%Z qȗo_TI_hykhl}#NyjYܻr&5-– x¨.XUhBgvUu ~R)N0s~??U9 6q l<r!J rjV śSRLm˧КtbR;*~.ʊbSj>};e-ߘ?ޱ{v#.(A8p`ڵkٳ燖>}W?{߿rV RK! ZgSs|g_>gnq|޻3`;9:w/{zx:Ǭ}(S&Yxx\!V"ަy9[6GmyRm)H#k% C @`F[IQ}(r\{eC[ӱ_mlXkv|/L [B+Gwkfx+U >dاU ݧ*If7j=b$>F|<fPBlUoìjD)a,l4V(a ݻx2+0 ˜d.L{NQAxP3VDf׎n!Ru3׳G ~t1 S;V҆@P$X(,?~*445 nlo#;haOEja )WOkJw oܡs߅߽ ~k6@4z[%cQG lC py:n>+bϦ?5ݩ V;Limc59#&LI) ˂V/>Q  >Gwx=N<]LY%o [x=q?َL@M'o\[6b^3bןޕӼK#S3x@2E/GϣUZP Xj۩֐i)J_o@zLWJ4u8U?ǦX2BO:.>ITvuƒ=ڹTs5 ܾ۟Jw.7QNP,3qg-"cׂqӇCQlu:s pQh?bX PPn{ LDKfvf5VkFP}%W6FG6)g6erޖDe\&dm5nge/@ zQ}"/ݣOQ6èčle :c54UUlU:rL^/H AAG7]Nu^v*th0`o 3v:^? e*]_Yg*]rTnN„cTb(ʋ&^gaUyt󲹆&1e5Q )\xͺ?Ym3B5m 2o'u6px}x̸݁DS*-l1 e* !)1[ Ys۪K,c6"O^XH_\9:1HȰc{ f-n&fV+7 \7:gN\5xV 8 <1Y6*Ue8ճ^ m1}¦\r@AA@ݵMZzG (1sUlmH1XTp^VOX8[?7MVjA`*'^g`%mNvu&CC uo_넍N i;J RiA)Ns 1cX1׈-Gڔ; _?kWo1icoB_C?P ΄*{pQ5Fün%%ZyJkis7hzCz!gaUbDD9   h>fvZ>{p Ao^#k3jVkmEDpU+<~=zhg6f[ᣘkvlB:.PB4 +oO`5tk̶UC9+:|ax~4i6g]2PݺSe`zP|_6b'w gXX#GDL Ous}7\PNx>f|qE( "zoyGX)2Q:ḵ>7,ir@AA@hP~r? P ^8&l|&)rm,Wb`ޑ+Dc&Q&kx[[ ^ esМ([k1W3ڀk5-խo-9 0ܻ|S]i7ƺjT} aت xzGG*@x%}qRe3,DԵ"M)}\>۹_7׫g#YⶱuP. hh崴S“qTC*1urґ(,SD/x؈C  Sg5?^MxrQH1xiN,!~ƌ-K7t?S:8KAsRdBB;ef 3!rlWB /[X8bWŸ)A!OxVh`UHh?Hq<@5҈iij+0u@u`85G yit\ ש:AEmʔWYiXt@vIKׯI#kfM s_=ϊ۠a$i)L<VHѴei0U7b'Y g@X :=ӲO {C6؎g_r'tz۴U͚1=cr"+ By fa,t8Ɲ{~ǹ6u7ᲫBEيvϪnP6@$dXwqEq߇RJ(SL;nZAAA@7b@ 3a9!#DsRyX4B tn&F{|tT -'!v=kO>ގmCb5G{V@ BEF101>"DȶئTbxf0ϵmn^1P?cH5 n5,Q1'AAAG!AAAAr@A?ӤIܹsAA~Q GzjZj 6N>mnAG  $ϟ?k׮ݻiȑtUs  ߋ(AA#.^HGQFѣGx  /Wyn\@vgGtA~/޽}Cܤf>O>7۷Y}y5|~wQ~1:x <={fAU~rԿe=9ʛC:3PIewZyl+IŸϟw|0 y>w[ ߾}nЍSፋ#N|xZ1u(}i(y}xYId_+ 3jIKϡS)s")oa4}Q߿UKЋO̳o6,KEE;ׯ[峧T2E4ٵk0w*]1VΙJ9 a™G +_w+,J/V|wU_~5L8ڵ8@cǎ?{Ai_1&5+˵ͭ:V5֥i\|?>UhHhvMLnQ~gQjU9д=3KTG ]wрi%`9*\:B4#4lGl0kKrûY@1sz͞G,fNO*&_~)LTI[}D۷o 3gŘ A|J+szoY7]9 7`a"Pt9_^=Q\>Yn\z҇;_,#E+?V,#h} ?B K}oPSjmtx6^w, n]~ݼ|.>Aw_]n^gN8>GKgN< w|qp'񮂱%ãC?,_k`VH.wW/̭>8D]8K^|zT! BDI)F&|DV/ Hbiʹi&Zp!U:k-ݹxṇ21mϯT{"g}o_7.пOїOc|ΰŔF[,6Mڛ_tOk6d!CԾJZQ,9NRܶJ&*AoMbnf jӐ%B5rz3Sɨd4}X>qѩrdTP&PQJpT}xXW)K:2P4ݏᴾv^jQ:y@dKFeT}/[߻޴t>rfnp.<Ɗ(XB=7VR_QOէZ<Ʃ{;rGuk倅ǷX>~}=y۲l|)MFVq[6m\r|߭\Qq2'6@tj_$ʪo7œFUeOGgMr ߙkc1Q~_"E4~.Щ+Kĭ`ZdBkUtA]nwÝ v}7/O!ImcA}Z:+ޭ^=y?c~kXѭtn:u9]9^>B6udp_ۭu7z];Nn[*Yw*W%_> P>7k}/M޼>ғPc{K Fouu@cۅc˷eU!ۥ[95@8u/_:6A>q~F>c LѮJfQuB\m`APi-v<>B:sH<$NF-cn^HTy?}L4꺡Gϩ=YL4L'@@L& F lS`iU=#;7}\Ly Q5[U(3́sSxf|^h̥,D@!`%P!+FP?ğ[+65Ks8h j;hMי͠DQgR"-hi9a40eZo^mQp .=LD"F6ӪMKk7=W)Ș%y=Vks$ϐ$Jwt|.F۷2l^`Et1j 5fs8]ݡPiK\c4G[~ПQUkuBhR]GOm}fEA)]< q,RgA!Ä;/ӡ[Xt ?gNUek=zGJ6WϟQ,9moG?1NܾB8cR(j)zPT(R=ӥ Jɖj@/n(~igc?ݥ8Y=o:ф)[%hyj4 :rsC:G;xʺZ=SvP4spd*ha4h b_͐!CuYJ}+"DSz([lֿ Vԩ]ޅinD?b$H6|?g{3%/es+Q`!)S:r ~7)-ɡU[Qhըa}ۏ_X6ߝuܞljx&4}߳ AajY5AJ~Y:5ߴ/|/ZwS{4fg7~'2G|ǯ?J[*iV/C(( isRs(Ai䬳D P)@;íX PPj9k7 эSݸ#Ǥ⪭bjn%Z7']:uG 6s@ACP6(qV=277)5V]w)~@FMkH5gE[jmg'SB1U}l6e+7Botfd!V"*v8EC~*A;0'7/ʖ e2Th^GLmUJ=(h~Q۸w- D0>D7ZV*F2e26ˁ;߀JP3N?{ =sF/Dk?5f@Xqi,4rgtgl[xFAQ^CYg1=+cATmw0C ^C13YъmZe@x UyN cmQ7{X0cfXu}1wlRmaV0mȊR]q4~6`-+@nDs"GŦHWwF*p눭uwֳJ1PnMAJġ=y0fm=1 7@qFU;Y d>?g`6u:GtiAۏ+ayGB6 B5[uڳY1Pf(~}KmdE#w q4{[5ZOӈ-վOT|549[Mg`p ޓR%Y92*WP8j<`:i0ȊY9B4dJV`{e|Ɨ/cl@N=s(G (PiPQiMT~s޷}2~{NCoU f7)Q˷xX4>_WV ۔flmn {7Jȅ A+xH gmWmT}O%]/@eYe5fÉyد20lcC34uJ1K6!P#]")z|mVkcw.no+h!1`,LXSNǂ@`)RR-nS @+6lE&g^v#c +mrt/a\[]Z+DTe'Vv/L,K" J _sц%sYa"thj}$9$,ݠ>1'bʍpYJ1#ìz}l_LlFDxC;l- L C,χ&I etVJ`#YUc @Ժ(PrD˷q\Ȅu ,V ׯӞ={ht5sӁ~r<Rlk:8ߠްwd)5*.JE6Pɛ)}',u<3H|6j8v-/zv39I/~$  k˂iy)gmXݧPnJ\G X?k5k/06l[J"3o™]kYد7r9E,8n;jSLMXϳUT-+N0&U9!}T4j0f5%bX Nm__MV?yY S)hh#3|w1m 3 [t6qڰM2焉X fRqk6]%Rs*԰'֚뒾X ksX+6CQ5] kGJpckWh5ke.]9o-#HS u6Sx=fh:5Χu kX#Ko9(&`v-ͳǼجO۔7hp9g!`eCN*/P xd*sv'ps+Q 5ϔԪ1_Z rhf^ֵH4)XPM ZЀ@5Q^n-T߾vh.H# +:+Ёs)Op3QƼ-P 'OenŕF ,H;4lZȃRV W2n4EOSepyxGC?z\a=XKxt,Qag`lU@kJ w W6ncxz8#%±n!ZE`qLEݵ%xڗ>o c\y|h (<ˎGh/F`I\(2..+-qkc<JWu;i6_N?~L޹5vŋ4rH&EOP$Hɳ̀c`6"\dJ0`Bv{t^fNWM@ ! %2Mڡ8PqjF*bPͰMed5?'$8oj?{C Ԇo}E@ŒX jA Bf.m=~:CB%@ c^ v`g`NUv(iL6%^fu\(cKk">}^+[(|c"PU^3bU7o-Ʈ >V,/ &/vE@5umEv0QbXj.`\hXQ`L#i.KxpqhSm^Y<{6! n/*7:ε+|X1";Xmr"F~TeQ:U߂,nVOa+%|1vG gpPhEc qϟ?3gɓ'e ǏӴi%{5;]w!6lx~O4^v .]-*x"MaxX/LDi}w Bc& dBtXs~k=1sA|,`mk0`Yt?~vф&Tj xth%Aݎ:1KcŴw ?*}~2lrrpam _wV٭ߘ|D,ASҔ%iˬ!7B[ {3g0ȯC;٦z|ۜHT¿_Y)(@tX.08iX%Y ߌ$9֗_n{@5 fRhb WiإUjԚR>g{"=/a..& svT©=HRy8 \J5O3cx_9[GLZcIq!|"x#k7W%6nW8Ǐ2g6S.]3 L6ۿg[c`\[G8-2n)-@(5  kn5[V$1![n@PX>>><?;Z@9 B,'#afCHGfNaY.+t|)q> oS ^1 zWٷeGq>vS&RCTAKOl:"(aތ|?bLqA$~W ]qհYquvE)3e/ GۺCCM>37;C@0JW_ x)r@+B7h2=*_|Γݳ~9&,O|U4\Xxr+# "㗫۔3Y`Fcx1m}ޭp }G@Sx; b + ->Nʏg0SBԤ bqU1|,ʩ4Ȯ왴. ؿWs[ ܾ}ǝ,3|R(`t#?GOQcL\;a2cGǛSu?-Zh zFcK6gM"*?1\?}>{k~ #! ~bwSOvH NDM`Yr(TX4HAT1#.0&ݥ.fq_ +}Փj\Ym-}V) } Bb\eJqXtbƕR~HuMahXTvGD+А3h(c<1\MmXqRed<~Oy> o{ċx"FGz*h~Pԭ~%5rGBᓫo-f/+x8tJA[ c?1q% 4:ٍK繾2Ma}l .< XDyo7u. X]7̞/iu ũs.=Ǝ}X(?9êhɢClBy7/{ąSɘ%GY})aƎ6ED]f1l"ޔV# +â }7Cl M5wD,'J;K9߃}m fŕ@p-[h…-,L7Nl|hl`ʍw6̯b?)c X`qq3[3,& 2@|t~R m-JZ)1,0U#p0|Xk6IGK%Sx"+j6Ծ߽ 6qY0(t #\Mi$ي<8ʱ]|c&=3iv#7ɜ}ҡ8%mi묡״6U:!Fn亣ݓ*aV Z"JiE={UЮaĞ4J:ֺ4]ؿ&(,:f1'd(^7-Ҋc n w)n0Z˛Ԥ "p\׺W#ۣAez,,ӃڣJ87 jnZXⳳcӻ֭u jK̪K3s*oYvoX]vA9خY4m#Fym^<:<,  RYa`;g ^)|mR`f 3SpD?s+[3Ъ6Eb݁g!,ښܽ fXOXm1VvE;WlY7@?^.)0K5Pq/ )I6#3CEf]E@D:90gDŏ( ߍׁ/(N;Ws P fL6 n;Vф&h񀦜 jP]$l;B7"PGhJR܎EB}F\rk_:NZ-v1I2ρHۣ UHIëgKq+5x m*z!W?v=]-Emű?WOmX=-Kêfq mTO iKX 6[x-*(<X%y,(:jKONM.eE̟}}T`F:!w>_5^ FNq0g{y#2yuh9P1>ưT3oܿu=C:9 &n> p! Ai@ n/+@Ȝ :6cZ^@y6.o3xX !E=@of|n^Z`H(Y9`ukLH SȋT仙|E+U_h,\Եn eҙ̜C3k+n mk ?mpۆQjtV8՚+b*t8rgcw xV"08PYc]>-~~]QeOM-48TQ/u< =_f%{Ŧmr6.5.?&ˎ97Jh`n%z!V.>Eez>]=w>LIRsWZեL6q˷QҴy]3W{Z4Ȏ1wA[W) `;*Mښ[lHhoy3x \p='‘BfSlf.W̓+wp ]Ӝ cچizoϨ< m8e&NF B%S \%MfҁYE'u/jruI^C)o ?3ɫuB-pT)ϟ@6:zx6A-m_qzOO9 r RY,24l[X&Egx޸q۵P1E-2L,:/ qNH#/؍iS= ΋4 {J.ʛq/жs'NP=xf؃;A`bĈAr6mPҤ]l?LhDk@dG%}v ]:^#4194G1u=8xý-΀܏_ǪC3VP.W`1ʇ(88]mǻ sXk5G{]n䋺>ùKY_jdWHc~F LO4;óRNWS0݀Nęry!$JFUe&||򕅽DRզeߑJkV5.x5 Iz6)^gOу7್ VdE!CwnrVwoQѨfT}6/N!]㋣P(#n|*\9@T ! qKX |F<0p \ʚ[݂|!„PlKCT#O=P7jSlA۬޹VQca]ǁР1+K=V!)C|U̔_QR(RWtp?@1r] u%Pe6m 0Yxy7A48y2 3zͻwoë>A;dyǧ0 %ڰPjiۑ0#ua@:\m:Kj3`,S}%U>r? ĤrJ RC'RE8#ZklaB Ge SmUե…αkj-g}yG:xďkʽ=eR*7_QR:X]m+uPu]Њ2%돖Gmd6pv}gU{Ֆ?+p>5mյ1 P\ ܴ#Og+o"eʔ%Kڵ+E{#c9u(MnnLbɼ.Zx-Y$xeւ1.rv Q  X`t!0a}6) ۅnj D9  O8Ν;iOAfD9  >жmhʹxb j) Ոr@AʁիWӵk̭ !AAOx=x3 ߊ(AA<iFO6 ߇(AAD9  qġL2QӦM)hРVAA_|ϟ?qNAYr3=~}Ao%J(-[6jذ!ŏ* 'rwT0~XкX`?cSt\;zә<ɣ-  rEUT4iҘ[AW|>}H?}2|;-+ʟ1C2SnXUX#}VAArMeʔ~xOwo^c3(Jԙs~ݻun_ޞ[w:ݼr޹no_woѫ-vP槏Э.t5ue>Keڿz^VumuMkr;<oW@h^:cU͑eG2&r?QYuL)FT&mҾ[ _0ܵ~%͘ Vܻ\xTMF4qil;HܿuOSǢj9SPiJd| [uu"TJubzp&j\ʤEU%iReѽ|3'iAd2[2g{Կ+EfCq%.2hecTHZh6+-eKyKV`cE*A|Ru{JOg&}AIU6PPٸZW*Lgfe{w)U yjx(9wn NK ga^lReAQѵ gg4OGm+ 9mStzʝ(eZ]u޴l5,ϵ Sỉ\7a{;\W$7޹ͨ!#+1mY0;~ h)p;ݴo o^2EbDbi|Lx|&N?AagjR"W0 ɞ2)DaE'Pǚi򍞩gerkV_ )I:5g$b P@VAAYxr{6!@-{QB킵4g)/!]:skd]8VS]fu9zOGl;FWy%`L>onSuݓV1K7YKiԼp.ؔ]~-갫;OрKӈ)44n6 <$>fkec-8%NN WmF,\O}7/_εQ2T{A,k0˳{*7(Oy:YL4Yf)iֶnixڑۍmx.;.goQ7RQӸ6Paó;upO  ʜ'3h;'aRާY8/[,d(8HPjm g(3?{HmGy?u+؟3]4ˣGգ&Un܆m5oFG A(~TƠ2:Kwm$hٙ]gۧv0l" ?c{|ET;A#HM{)u?kbjl=foWTͲYUehcELO6P΢=W-7^PܧRTBusaU*3p1-W^A~cfW&MPȑͭ 3@͚īSak3O  N)ޯ)[x{?}vp6[ns[ ʔd@1bQXqxݑ =+ Hj PXBn e,[ſkW/@<2C6%GuGT?K/=u#z4+`].W3 '%j,WՍc&|D^x] C;~qߚk΁}EnX2i(O^PhEF\̎>h=wm\[/E,l!σtwNQR9qƔ0& >oy[zq_G F& a׏ x7._`A$&-Z4+e˖"D@…/X`3Aq>2TRc  D% YD<;.\1Pֽ<5o_JYs6n9EGdf=PٺMͭn\,x{̭a\߲.-Yen5;W0q.s[P+Q0!b>XALd.@\cV B=ʺ{RxE@apVCր·[+B "BA=؟A>TI[ަÂ,_x; 'xZw5i\"9ZM%3:loӕ"+;REի72I<15Gl,Oݰf s,&&#@Z,Wn! _PlU*vf%SFEŸha4h x!͟?n߾bOǏȑ#tYsk  ,H*T%K[l>N:щE]h"+QO3R8- =w-[',`n}o*T2edn-DS7^Woޑabɢp{sFk}R|EvR<C?dIf{7=Η;ME*֠C'6G dV5V1 ߰s?Ը5oҰh6Џ09bU41k|)Y#m<=a# ggN99ܴt>#,RbOq/z7N9p|.jQ6? ֞{3 5=T4.364Ucn5*vQب5+Gw3([ Uoщrrv/! SSJs\{73ƛ׆G1iM7v.+}5pÒ) @(O+~鱕Ќ`~U{0=q” +=;{߼U/)nbay>u`@Ƴ)3fk]<ǩi"C =#V 3`v_SGg OFWY0mB/R!vY#FX_R1AJF2dzIAAp)23R^>s;~)еnN>_ Dg='S!a8U6[3d]8(+Y ݴ: PI yJ/#O˂f7|o[,ǘ->zڕ؝ŚGFQ][Y⌤i2_.YgۻcP8)2g6h-kcSAp d͚Sl ߌ)fFtn~ӣ=ϸɖf➭`qi}lJC7jj}H ^x̥@,5Bܤ)8NR\sE+rsJPhUV(\0ˌlXjR1Oeː#o'a2 EsmB1:.G S>} htGzz?CG>{Je3'r=dU0f ñ1 &)ꖻDyN =Wvk?~i@3%3Y8 SJ kL gqQ!Z^M9}JԤd.W(3ȕDā 7I *T:7~C{d_$  5y!UhF jzn)6b$.X=W*jU端غRa*sk}gx䮠p>|f4Ԭt^ݴ5*޾zRfF :sߺiĊi !"TK}Y#5ԭ@U'2ZU,D;57]4|գz6-(jw~Y g;m:3JӄԘqW= PF ٺRܮu^jfBgN j9S8Ӵ&馥5 o݄aC?A~&%M] ڷorlS,VEA /coV`.{YR m<0\$# & gr8VVo8Ui쩔,]&jwysJm*Svh-E_0iUe8kMҩfzwuP̭OܣYpGr`CX7DVMUuHtQSUnj_tY*U)ہCj%ų,"Vg!t`zt $(+Lūեf섥3&ШnZ ΀uÜуi~6BEbV_ ш1kzO\<{9ݺzM1&a heD<{H) `q)*ڱdVXH_00u׀p@gHYXK$SYid$y,CLA9ztd7G\"}V_gcD O 10F0VOOV 2fΜ4!̙ڴiC qzV|r/PC)DD?ds =J/^< <;%?)ae̼{?(?x3X3J,ϙp \ӫ0Lyp~^_~<F0Cw 8qh[ kp?Q/=$_ݗp#S>hқׯ8CO+D9 Wx5*ϟ4iBS)|rB^G~?QAocp,vVwA| +)† ˊurBOW r  F!(o޼TlYv)AuD9  O)wT`A*Qg w"AAhZ]AAAᏄKٳg甅 64 ݈r@A?xQҤI)sԲeKof:A  $ ޽{S׮])hРVAA~Q G8qk  ?(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#AAAAr@AAA|8AAA(AAA#/|kx|.ݺz$  g!᯦rjIBvl6D d5?OާϱrWAp˛W/<^|bn~>~@wn\k҃;O\KAA{S.\1Pֽȷo?VA-M[HY 3zOvq%_ fp_M7-:%J"EiOgUo׏_ 4bKD4YsQ!+8Cn?t`Fzx%IAEJSx =y5m\26,KNq\ %KL9 }m6 DA1 ǏԩS': GA@}Seb)S&s?V9;j\<'ˑvgnr@?}eQwo聴phz.~k} p݈uE~3 vf1` ;a 9*}n\>Oo{u@%W/ DkP>m#^ AB+A6? 뎠<q/e =pA3݁UUnGx́m}>gIVܯ^t nG(TW5'(Y+BhetJ>q/`4cX[bz))!=yp Jk*Qϼ-L},J);/hXǦcr>0P`V|x-L>~xcJTJ7cMs jS(ݾvY}#RD(pР#r$7f4x nA"AU 1+'LGF 0`}{N=Og/Q6WЉj|grJAAY^H߿{˳[r/_^oХ/+ JS) ȗo ^AAl0ymiZΔT3OjUoH~!ӉjOOU'*ْQ\kl#ԴT>7޿u=nUw3eضr4ȣ{wy||̭D{7mTϻ֯%rR)Lp su+PN pHzp& Gu+Iܴ 0s޾չx^Sώ`}| f5=m!{<6ׯ9yE{_UVܴ͝k*/-&όB޼|!5,g)\ϱ`|YzU:chl4M}zXΟ5?gU/?x(=|]kT,I"tXUԮK 6Ń>8ʎ){P&5Y02WE|'j5ݽ NC!xE67#g T T^ D!U`wZVXg= pW/܎e+@7c!%kAX}= @F<̢lϹ++2VXaNn^HNᲖـ2n_ޫ8zСjYY>k2[Dl?deWcX 1u>u(`bf  > oS`fl خ !e|[y&bvoq|y\ݦ 'L,C:4q3pf6 1b)D룸|$m^_ЖcmUy@;*q?Y[Ҡ+a(]SB5ݟ&UG!8dէlip&0MGlgBߩ h<ՎorUySXi NUcl5qYG%SB6Ɇ dLs9U$ &3^Qw4慵 5TPu_ş %W@[@{ K!~T)Z ކt6ݻ,PpB"+A\uC@1^X+N!AAx/Ã{Ƚm9)ަ8ypU G*lfu6Jh@1պftU#27`!CQ}p{7~(o4"#`_|߬>|<6?9Uc>_TZ=6%Q>fEFqPK "#ݝ5]6&nߢ;ׯ:":rl0ZmrtC&NFY2#cQSնnhK?YJ6A砏)[ ?F |㋅q?m#?01e-P6{AxC{M,Zڽ[) 9xej7C`]*Mz fkXTȘ.P gd/\mf7b>i b Q/>X]Ё (qvYP[=p)\&||OhWYqu!TEsܫѻ7u3}Gw=c3v5x! |Nt-I맡 їwcɝ{gu.y㚽z6H\mgvG3֗=WR$%x:[FPELxk0>-~P8#o¾~w‚b=,p8u W/.H5sD т f]%h7KN'yi7s+VL-t,pr)9#a$ذlKptGbMXPL۰r/uݳi ]p-aʧϮpqf>3eG.<ܵ~%֚]?ˡ\,!`B y/|wc^PNPn8)bm[V(pѪy&˄LR̭*~>y`Ybմ[}pZC`94_g;[%a(Rh[;ECgNtL\MC=T2Rإ *(AAF_޾o^p5_{oyQ/ܼM緯_^YˊsEoS`3ahX,=E(_TǬ':C~1 =ZB<g*,)1&jlgf>CqAP?+ݿz>lXpظtq*Ϸևe2ʕ$uzG^mN#];3O<фhoÄD-Vt ;Dp(WSKj|@tmZ0Qi3ԗ $~ 0Y+_:Vj91 ы7Qn)Oa圩,hU NY♰3kMCg3RzT&m\, @3:ɻ8X\UwAc%H– X=9;,.uʱ5 xtP ^hUOJӈ)܇ExvԷuFfbNN5˸Qxj`3x 4*6lIQ2ìBS   _R~y 䫫?m̀53 ֩9UϙJyҌrVklX<#;[b}d]O*XN%Lk8O W(axwKrm/8āſ\ԤDnX4n\䇫rozEpb]ZsyD_1ݞ ۽)mTWC O-1bs=Q,Yj]h|.@: %GRc(fD,BXsy[ BQA >nǟX~& fÊ5d<::NƃF-*s>ǻ+{cW>{3|S_?囃7>l)PĘvUPr38m 6YO۔l;NGNDmP9R5ݜُ?1Ϝ:[X#q;3+VQ 9Pl%#X%"19w9+k G܈^w#Xu`4_rm]m74m&Q,VKBȮ4K+Ns;;ʬ8X!Rj]l ǬYdA:% 7.cHݎYWF?Ta_?kJ]zqR}>武ru9uY`|u^ҖbԺf݄;4P^C,'Ҹ ^EFg]$22[8s vƺl`8cn C{  xw/^ӥ mh‘CK/u+Fxo_Pxn]1ӶJ1%}=Yv8.ҮK¥ayaWE"M/jZ $ʇq}eot;1˖P.3f%gR}^7 X5w:lXiOAA^>>{Dm%q@`|pô VrWO;y*J5d>h(~`Mj4^RnK)3fнnsD6k?gu+H皵@1^G T X^Ahڶz Mԃ #N b3  WԻ_\K'@` 4Z2<|ym]'[yƷ?]=6k9Sɗ_0\TRo7oQ@з3Mڛ}UXL]o-N#`?g>% {5|ϋ( f6ǜq#t8ZmH,5Y0fcKF+6 LjMZKj#G@FYC+:u]8揄[s-8?7"g6-q>rC(T4bPrmnخ V9M~ ׿E?q2[]:|@k!R^l˫j4^˨E(B:lw^'3 ^Zϟ> ԳhP$~L”#Jʑ=;9#W jHy[hKDDDY+R,2~OfK@8=5m<9g$zN$9)ZtCB_Bmq\2w2mҼl>Y6s~c [[7\б Fsȉ{%E_96TsûKˊEcʎbtE+TqྭPHzj ~n-SY g,9w>G@ 5OvOjRt%adVk2k\M[Se"Yu8]MY =:Jͼiu \g4ɟQ&8vŽxik ?n<6|;un#d=3hTT*5h?MJѩ-_HvשЛ0P/3\q&YrXk#H]|QdoE2'\nPF5_HVin|&s~ѬR8ú(o\xfΰ-C"eҨXvPjt ӬL^ڄϏ}Gx9G`V7[^iE^^BF2nقɇI$EZ&rӮ讋_Q;S2drǔ`ˈk5Gt$4_Ƨsچ`eª]:kO?_V&H\:-Mc?/эma{~; Ehlz.SbkԗX资b~"-ڨSHz 580CE^C%]\:}{eu!Kc45aÆ5w @ s @ψ"0ot̹kA(':o:jdiJpu`LW떫H@~Ey讯7kG BZ%)z$'A"1!Gd " p~mG Ieg{Y&۫3| qv|F2 7XC`0i=R3ADDD[xmchg^$1{ ;'^?+% /:ML_~r )ǏQcZ-59}u G$Q}dhyh!c|vu|aF[9CiJtE[$ q Bk?g9ښ+nTa)j4 x޾qD_AtYz{GM|?,@d A-ԣoczx= ˡ{nGw~{ ى^0928W8`|{:;|✸ʼnZð^/0;-=p~?/$̩ =:y~q}uGߋ>~p`ӿ1}v˸}!.fK5j\vAMz{K@Лo':u$fcyPw3 3 $?F@ݸ*+}JBDA\ԩOVVFOb%" S)y~Af}˱ʝ+u9-O_99]$o.?r}^no[Yk킽?7.j\.$<'YmpmT9w7]i.l'mjwwwkw/hM6-K>%Cd)%Iʴ7QӋH>s)ZЍc`(nϱ[-h|!HQ>P&)hk}FDJh1t41VozW@E#PqΉz;7A@t>"JX_)0QTУ~W4fi88fHuoK }_bm%^'K@u;MbרzLb:g\lĵao>3 |6'>'1@DDDk#bc6'0wȩrIoX& : ߙ9u%/S"|tO*t6\yrftٳ Fv]doDDDDD43`!BʣdOo`C-_% !qZ +.|xW]96.VyO^49%L)cýK۴?'L8q~#9praʸelno}: """KPa$x:Z,I0 2<8C[򒴁W1$R_WO%~o$V*ƶ8uގԣ Ҵ%_ܿ!YFI޴AK5d.ji0@_"<GߩOZ7P)`9@i?E>ݞ/_ӫg.^r )O/Һ@>dĨI@}ks.xh3㬱$l*JLM,8<&>w`rW:9{"~S'O]ϝ-`BѧG-H%C%I% !S(:21@DDDD=轰ѧ=B<(/PO[k> `#Rly?x/˅rbwy0DDDD'>^J&賁 ¸%0>XkLїI;21@D`3j}jL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDD]˦cdǢI򅇵>'ޔ}FOsyΕs#SۿzxڸX6!;LYߒ}nܷw,yu}I """"̭:D!'/?2I!Y5;ǷǬG=O}xZc:w`c{/Ɉfdoe޲pHGt| mT@5޻q߼m/DDDDDDaѰN}]Nm^B KʐFȇ x)3JF%J̸=^Q *N_&Zo]<Đ]_0#꺠wly|<{d'9 F6Q ^Mٺ/RR1}?Z۲cI^D lg0s5u_>{ixn`,8@Da<{HN*%JСC[kcyꕬYFGK%/EֺȗJԘ $Lts39}͔#S%D'ׯƹcr%k5 +?PaŠ{o~B6K, q'vC 'aE{kk7(1A=ѷ/'ǣ|t#t~#ʵ3Gkz߃eio\yDXB`=Z]wz6B$vs9uqn[dAux>ه47ܾtZ‘]،+JD)tpOZ/{Wc~A "Dv17 q'/=.bytn*W14ڰPv/.go5P5V|qEc[Wq{%Lq.o[%N[OIĩͫrb:9i0L"DP8/c{{e\$Z7/ڠwAi\2t},!BHQb&ͽWeҷo_K}ҩS'ٟۗʴ褵Ƅ U*? 2"SM!9%G`P:.RTi7yY~8Z%]RHG \{].wپpD6o붠T_|pݠt#<#)JJ4餿jKydݧ̮>r4i2hĦߏo_#Sr!w.Ӡf(XNwSn Y;yvSɖ9eQv6W|~PPл`:O1G$VO' ?Mi1|l3JMס?G6Mtz-=1! kk<"3Tpu)9blj=»9 kr7,8Ce|DҩV mS-.g,\AvI{A$IrxbY07{ORd/$U;bZk>k͐Nn)e|$:N*//A^ypl^X]n#Za]:{R_s֍MtSoW=? عZtsݲA[.یrE |:w򨴪TTZW)&-+feI|SC{,n^l<4/[@Ԩ>~Ӎ+uqΥkKˊ9vYʗ^dO&$9KYMR2c+w9}<zƇu^Oru͚ǺS0ya{gٴb]:{JtO+U6{X;iZ:z@z i+PFCmʩu1'ۍu:vGbܺHl!>Os|' eeHNj_ پ)iK$?i\9y@B4؇ ^TjdYsW2w+M `cq3,o>`GPVm*TߝmxcۯDN\=>mw\=A>ֆO$6֥_Z#]}`|:5U*=#ܾ&{ Z2x\\4Vxx^?1Z7CH:?h@!Dz?Ap},o~]a^a&vk |_dbW3HU@={D&r9qp1⹇>]r.tG#wzg̾KgNʕgrMexY4m 41Ų˴*/]s9o;,h69dcwk?yغz3j^u eG1 0|.Zԑ+qG?H8O& M)6)ޱAAq-3GW.J8%ul4u:OhMwWY$""=w[ ;JR{USl^6 [U47K[}`ۿ>p.|%ɘG؏Β,K>YWm߹/߯K NɃW~40ǸlltvKz+As`Z箖-}y~%]-CgCRnsG0$e#xK5,/YN~=\~:^?̑Xp k3!>^_FH%v-jHIV&?6H&-?S„ 'Ϝ73̟<xR6KNq#"dI6HIJ+n$8EjnF%%i}m\7kݻSwh)/_kʨ\=f,7$!*g-m:y3G9m΄? _U Ix ɣ2{pDDD_6tK==q3~b^19" s $q{\?{Tvi Cte5o Ъ쳱9sZ2=7_PLfw3;逄IYόf1x:4N<^k>AS{;@G'voRt79`v{7.-WZcPmĨnoXIRiM1Cٳ|IE޲K}O-rBZee1otLJ߃~~[kCK.GpIۮkt=1|A+ gX9͔p۪y3Wo*ťezrQ?gc8}Ci\"4(M6m3{A-蛔Hy#CyGWȚݸzY&L+'([!CK&cdž: BHp ڤGM  F2fExC)3Iʴҡ > bR7& 2do1ܤ]audҰ˅ c~U|&Ϛ_ro y*7qt GPo!Bѱ}Ap6Jrbϝ4K^ewu93gT~#q۲/Еy3f}Ms޷a+ƭKgdwؖ$J)s\+vNx+*ad)~c9lȒhe*zK1(sf,_pV4D&c# d=ޕeԮ yir -1̓@SjJi|)ϔ9Gh3ߠ+;_4m]~|1iRs~A֭vFo"qH,E֮ЮxFZ5Ȇ%3zre#.h4L\[1Zx/_p1g _ d!xOBť5u+:: oYc̖Be+ko\kFs )of߰jq'fuH@OIp|_}^X]GDDڷfbƛ>Nֹ;NtrL/ ݫ[HS4f c|ew-;?=,>JtZrD6{[qXkN ^<^ҡ 81ǸyO뻼^3IcװahzoB1qN#"cy؜ [ l7a#FqjQT4[I)׎(H٨li7yZf]LB09`DaQtRȔe`ik=k@,G;V28{dJ3o2Cmu̲2ǥO]5Fv$#|B2d^F5LjPJ?9˖`18{Y0І p({ڸt>_0t!0…SւV6zٻS #&6n W^W]W{̎8I]WSD} 6 $F(xM7DDD -hz8qd|р\NDƆ.ӣ+/˰ƅH߇PFf {8Ψ^W`u|>,Dk:6f|pSk%qXY _9܁m$ f Sc^=5בMK78 !w`fܽvA5ݠI0Π7n 0sLNFk Z}t vA c=L?u-525cΘ$?rh>$wF~ހnX u0Zh‡wWQcSYʅûdǢɲϮk py 1[NKnO5"=NC6LwNٽl,E LuZ_R}۞~z Wv,g>yss)`뼱ws @ۭ}EZQN߫pO;32G#]&7NO&zW%k'Ԡ޼S`.G!ɓx;òиi-SmUΟKZaɈ_e>zlݽ3Yaa:9+ Jr6/#h0v1bq>oS)ܘpޞ3}T<~5_N- 3>P}M!rK%{n[xrxo(@@Ǵ35<ɚu2쥪Y\Tn`ûz,g/-feIӯܥYҺrQּ&=|'}g"=<5\[98|&p̓dr mi}g BZzK4qSftlS~3d/ #HRoO<9k K:VrWI.l+glim!>p_Uw7粺`z3뵌)?~@o\NBpPu AAizx$iIjͥ5SYAeR]#xU]N(@x޻+%рg؜U9O~]ɜ mrUG{|"EiO2]˨5쀺vrOҴcO]€h]-^:biҐ2a@O s*Z M-QF3̺0eX_ɖ KC>BVY߬o|㒹U#V"oMƇC0iڡimVgM#=̘ݺ4ux?۷ 8frٕg#!rb\_H VgbXe?WzGQ-||3{Ik|ߌkyp`~9Q߁Ln\J߾}%t"SN?YYy=5$6A#g@OoO3䢄[iJYk> 6ʋ~1kO(@TtݧE7ކ]ߞ>7΅}O)Rh20[^Wg?ʛN4-1vyUZ k׬F ߁L[m =[+w;CpD7@)[~x\x^ؿ3Yk;2O[|tOc}:y1rylgY2Ys;#߯H0vVoCO  AbOGȘ3ǩ#ٓWibK+4ͯnw! ~yh+@2$rZpm2{ m#ۧl^UmZ?&1Gq5~A$F0@m%M^ie;sU ]B2~ rXϚ?1>wXMuC ʎo#NҼ9(I5W$Re톤B`z-+n] &[3Bc*C -bu `WG󧎙 ܽ[v 0gSy"렸;t]s: Ԑ8A OaNoo=(wx{y܆kE5Χ=}Ǻޭ?] XΝ<&'mQ_2̫I~?})^$:k'[?,'lz7CX @"""""4Oq`k-v\]F7nd01f 91kB/Xymy;7Ɇ ؟o>ѝܸ?!p H`z$N<T+09Z8m.cv8 ,VqJpj˚sWOq5W\a~UgӡuA/0aJMC59=n z>x0ܠacA;G~9s-'CѺOپnDϛxYѧ@W/ZPpОZ/KނʔU-#Ugȱ}_5=`.%b_i3n-}ڈrwyuiMܨa}fwo7!| YJ,0=B@x u-ZԑV ;:zA 3Gc1˛>rt XcK Ye[oy}8.`xi_\>wZ|K$ jϟe@VZ|+p0{d/PTDwe^N}{[zV>ߞ˰ RJ-kcc?4鵏 Z\buHv|iQޏY "9-c?ܼᨑ`ɒ!׼KI[`nDI3tl;^T5灣ن)ˮ"f+bO%.#l#Ds&\x}OV Z1bǕ⛳g  8&#J[ ͍},og+@{O&H^̐Ÿ׿Q'np`ƎAbzBEb_L g.zТ`;%gb:J=_GQBV2qOp"lhEPA%{]#2 XqKzK @y >=[qh)Ω ϙ3nNaJ@̹UKdD2Z$}\>;dlVBҙOfkZ2fʕO[H ذz]Ѥ}Wn|ۥ+YN;@`Odz~Ā^$PC.>7IHt{ԩ }K h!sx Xp8O~[: Fb|Uj߇}En[lûѽ;uѻ]d![&d=n{==г+(ܧt0zr5T:_f2Apaz^QXE4W/);֯++XVgu&}/QGפˢidln2OWY8uq}]π A301@DDDDJ] ZТ h%m;LY.(/a n< b K޾i0T{`h_cևVѾ&Y   @14c_W$þl{!sBq$dS@=5ckـz $N s=}~Е]]R$[19@i19}ZϞq  1hO^ȩ]KI1d-Yݺkݼ\ݤCsg- #~цQK%xw˲aP}^$W*8>;h DDDDD>|\\ ߔH ]9Kv-&@C@=yMdɲg ٵduoxϭB$f\fBv{?gL|e,O~hBGxrﳘxL_û\09@Hvle 2o\(Znn\8!6.pJ{K a19wvQ9u.@6}@o"F)y6[<%k7sQ -o-8.7ADDDDC7R3*]Sd>x;<&>{# Zl]I51JZ=+JXs(Px؅:߰ѧŚ_V́n-+M 6INJ$Og=th"u B h%w_Kk+n4@L^]]w,,F+IjIܱNx[+q*YĈT)%ڈK,VqNW"T(}^{߃z_;6i l%kɽk%BT7}:דwdLI^!gNW~S˩K:-A2I$ɘK#dӬQlOYҸSJe1n?aI$ R6M,ߍ['!Cwn nR[ WO-sh͂DsJ _8o߶Jx)3JbU$z/ %19@i19$.-Ӻ5Y0sU~'w~P' ZJ w$49D[2$[5uC t9 U8T˰v Y7e.d)^E4*(o\u!MknphV\n_~s,-sFkAp>䯖qqR_NX!Q 4@b aG=&hRKDDDDDo?=h1owT0DN/`o 3 /^R(,e[#40SN;32VJ~Y_[at9TpRE¡ d$38EnmymkŘ$_z, A ׆Ƀ[VM||v}O)5n-ڙ#Lf,\Q1&|nzkn#GڒkVŶ$gZ#1%V|ݿ"ujsOw\?{K{cm:",++!Bx=DH|-csnA}ؙ:Wasvylg20xVGw;i8 m'&d# >)R R&0p[y~|c0ej2źxTs> """"#l-NA4 9| aNlibv PC`} ^9ᨗ`1{4i<|?+>y zi[>0Yg.a΃ Lzi {A}oȹG87zR«p#=&>0'=sSmhE[Nѝ?JL9[mnC0myvo;HZ^|if 29Ϫ!'we~[=z]u.>'O~3q]k=k,=+g9kq٣҇|#DH8B9 xtǸV&sV  """" #w63\3qveOkɬcZ9vQgv-GjtRf[ƹ$8,QuS`cZ<@`9kC9ٹdL@t:T&B$+u=KZɓyt~Cz6^.aȎE埞A0Gj\4s^%'w)]鴎W)2z P¶~cd-Nh70CІEyhMB[)NVҹ]9K/Sm U1#-&>0t#sU0Sޭ<^/\(RM#h4+ۃN-/o8{#4Э5YCGKoߏ>BֿˡKdz&k4 _ǁڊodc@O\'3|ᐎr9-̈3_3Db%NS"Er\/8sޗ:wq)wݏnҿA~Sٳbޏ)*ÆߝaNūȒʬ^-5;)^Ɗ=6-n SjyL]‘BEC;ɱ-+wۈ"$JX QB8H`Xޭu QVi?[ z +2|X֮#HDDӽWeҷo_\DyxxHNd4zO;9Km$NG"'s쉜޽Qb75M6ULpsVۗ2wS!#öW1/t/pxܼpRO.i`GtT<&5׆r|*]n=v2]/[7Y}aXfuH_uwxxOH`@Fc6qxb=:WQ}7.1c?<:P/#`@L@ W 8Wvm 10]6Ү3`Coc1t}m4s>P&dɦPLJgxsk_3Onq뤲%H5(p\!N u]FjzV@4v|r'VPtt$H^RdmilS\eX L u\o\pr+M)k#qҦVyqwwxar D_VrDumrs &8>+u'"19@DDDDDA4DDDDDѠ_yQt>5&)ި44WoD19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""}<W/߈>%`!߾Lirvyx~-of|yܻ.OgZT_`kٛǏQcZ< "ލr@۷DZKDtI'+kI!gl誄 ZKDǓr/^&m|$:N*//L{arr|-ߖO[+>`#d&arr """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDD """"""rqL8&\DDDDDDD."""""""cr19@DDDDDDL L<_VV """"rpssgdz'""7ݽqE… 'a„ї@ԨQ%m4uLy򥵖GdϚŒ7o^ 2>kr.䓻""7{JB>(QDx`-֭[ҫW/ ![DGFuyz7ʁ %YҶm[ "u/}lK. ȭ%eX߿ |%/~ǧx,YD>,ϟ?)(T ZKD«Wdʕey왵Ȅ^fœ5jH8q~ZP""rG>/FDD~ gDDDDDDDςDDDDDDD """"""rqL8&\@TCIENDB`armnn-23.08/build-tool/dockerfile_armnn.png.license000066400000000000000000000001461446772241200223560ustar00rootroot00000000000000# # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/build-tool/scripts/000077500000000000000000000000001446772241200164135ustar00rootroot00000000000000armnn-23.08/build-tool/scripts/build-armnn.sh000077500000000000000000000375301446772241200211720ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Script which builds Arm NN and ACL # setup-armnn.sh must be executed in the same directory, before running this script set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. rel_path=$(dirname "$0") # relative path from where script is executed to script location build_acl() { cd "$ACL_SRC" # $acl_scons_params are additional options provided by the user and will overwrite any previously defined args local acl_params="neon=$flag_neon_backend opencl=$flag_cl_backend Werror=0 embed_kernels=1 examples=0 validation_tests=0 benchmark_tests=0 benchmark_examples=0 $acl_scons_params" if [ "$flag_debug" -eq 1 ]; then acl_params="$acl_params debug=1 asserts=1" fi local native_flag="" if [ "$NATIVE_BUILD" ]; then native_flag="build=native" fi # Force -fPIC so that ACL is suitable for inclusion in Arm NN library local extra_cxx_flags="extra_cxx_flags='-fPIC'" local compile_flags="" local acl_arch="" case "$TARGET_ARCH" in "aarch64") compile_flags+="$AARCH64_COMPILER_FLAGS" acl_arch="arch=arm64-v8a" ;; "android64") compile_flags+="$AARCH64_COMPILER_FLAGS" acl_arch="arch=arm64-v8a" ;; "x86_64") acl_arch="arch=x86_64" ;; esac echo -e "\n***** Building ACL for $TARGET_ARCH *****" if [ "$flag_clean" -eq 1 ]; then echo -e "\n***** Clean flag detected: removing existing ACL build *****" rm -rf "$ACL_BUILD_TARGET" fi mkdir -p "$ACL_BUILD_TARGET" if [ "$TARGET_ARCH" == "android64" ]; then eval "$compile_flags" \ scons toolchain_prefix=llvm- \ compiler_prefix=aarch64-linux-android$ANDROID_API_VERSION- \ "$acl_arch" \ "$acl_params" \ "$extra_cxx_flags" \ os=android -j "$NUM_THREADS" else eval "$compile_flags" \ scons "$native_flag" \ "$acl_arch" \ "$acl_params" \ build_dir="$ACL_BUILD_TARGET" \ "$extra_cxx_flags" \ -j "$NUM_THREADS" fi echo -e "\n***** Built ACL for $TARGET_ARCH *****" return 0 } build_armnn() { mkdir -p "$ARMNN_BUILD_TARGET" cd "$ARMNN_BUILD_TARGET" local build_type="Release" if [ "$flag_debug" -eq 1 ]; then build_type="Debug" fi local cmake_flags="" local compile_flags="" local android_cmake_args="" case "$TARGET_ARCH" in "aarch64") compile_flags+="$AARCH64_COMPILER_FLAGS" ;; "android64") compile_flags+="$ANDROID64_COMPILER_FLAGS" cmake_flags+="CXXFLAGS='-fPIE -fPIC'" android_cmake_args+="-DCMAKE_ANDROID_NDK=$NDK_SRC \ -DNDK_VERSION=r$NDK_VERSION \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION=$ANDROID_API_VERSION \ -DCMAKE_ANDROID_ARCH_ABI=$ANDROID_ARM_ARCH \ -DCMAKE_SYSROOT=$ANDROID64_x86_TOOLCHAIN/sysroot \ -DCMAKE_EXE_LINKER_FLAGS='-pie -llog'" ;; esac if [ "$flag_clean" -eq 1 ]; then echo -e "\n***** Clean flag detected: removing existing Arm NN build *****" rm -rf "$ARMNN_BUILD_TARGET" fi echo -e "\n***** Building Arm NN for $TARGET_ARCH *****" eval "$compile_flags" \ cmake "$android_cmake_args" \ -DCMAKE_BUILD_TYPE="$build_type" \ -DBUILD_CLASSIC_DELEGATE="$flag_tflite_classic_delegate" \ -DBUILD_OPAQUE_DELEGATE="$flag_tflite_opaque_delegate" \ -DBUILD_TF_LITE_PARSER="$flag_tflite_parser" \ -DBUILD_DELEGATE_JNI_INTERFACE="$flag_jni" \ -DBUILD_ONNX_PARSER="$flag_onnx_parser" \ -DARMCOMPUTENEON="$flag_neon_backend" \ -DARMCOMPUTECL="$flag_cl_backend" \ -DARMNNREF="$flag_ref_backend" \ -DARMCOMPUTE_ROOT="$ACL_SRC" \ -DARMCOMPUTE_BUILD_DIR="$ACL_BUILD_TARGET" \ -DTENSORFLOW_ROOT="$TENSORFLOW_SRC" \ -DTFLITE_ROOT_DIR="$TFLITE_SRC" \ -DTF_LITE_GENERATED_PATH="$TFLITE_SRC"/schema \ -DTF_LITE_SCHEMA_INCLUDE_PATH="$TFLITE_SRC"/schema \ -DTFLITE_LIB_ROOT="$TFLITE_BUILD_TARGET" \ -DFLATBUFFERS_ROOT="$FLATBUFFERS_BUILD_TARGET" \ -DFLATC_DIR="$FLATBUFFERS_BUILD_HOST" \ -DONNX_GENERATED_SOURCES="$ONNX_BUILD_TARGET" \ -DPROTOBUF_ROOT="$PROTOBUF_BUILD_TARGET" \ "$armnn_cmake_args" \ "$ARMNN_SRC" make -j "$NUM_THREADS" # Copy protobuf library into Arm NN build directory, if ONNX Parser is enabled if [ "$flag_onnx_parser" -eq 1 ]; then cd "$ARMNN_BUILD_TARGET" rm -f libprotobuf.so libprotobuf.so.23 libprotobuf.so.23.0.0 if [ "$TARGET_ARCH" != "android64" ]; then cp "$PROTOBUF_LIBRARY_TARGET" . ln -s libprotobuf.so.23.0.0 ./libprotobuf.so.23 ln -s libprotobuf.so.23.0.0 ./libprotobuf.so else cp "$PROTOBUF_ANDROID_LIB_TARGET" . fi fi # Copy Arm NN include directory into build output cd "$ARMNN_BUILD_TARGET" rm -rf include cp -r "$SOURCE_DIR"/armnn/include . echo -e "\n***** Built Arm NN for $TARGET_ARCH *****" local tarball_path="$ROOT_DIR/armnn_$ARMNN_BUILD_DIR_NAME.tar.gz" echo -e "\n***** Creating tarball of Arm NN build at $tarball_path *****" cd "$ARMNN_BUILD_ROOT" rm -f "$tarball_path" tar -czf "$tarball_path" "$ARMNN_BUILD_DIR_NAME" echo -e "\n***** Created tarball of Arm NN build at $ROOT_DIR/armnn_$ARMNN_BUILD_DIR_NAME.tar.gz *****" echo -e "\n***** To extract tarball, run: tar -xzf armnn_$ARMNN_BUILD_DIR_NAME.tar.gz *****\n" return 0 } download_armnn() { cd "$SOURCE_DIR" echo -e "\n***** Downloading Arm NN *****" rm -rf "$ARMNN_SRC" # Latest release branch of Arm NN is checked out by default git clone https://github.com/ARM-software/armnn.git armnn cd "$ARMNN_SRC" local armnn_branch="$(git rev-parse --abbrev-ref HEAD)" echo -e "\n***** Arm NN Downloaded: $armnn_branch *****" } download_acl() { # First get Arm NN branch so that we can download corresponding ACL tag cd "$ARMNN_SRC" local armnn_branch="$(git rev-parse --abbrev-ref HEAD)" echo -e "\n***** Downloading corresponding ACL version using Arm NN branch: $armnn_branch *****" cd "$SOURCE_DIR" rm -rf "$ACL_SRC" git clone https://github.com/ARM-software/ComputeLibrary.git acl # Get corresponding release tag for ACL by parsing release branch number for Arm NN local acl_tag="" acl_tag="$(echo "$armnn_branch" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /./g')" cd "$ACL_SRC" git checkout v"$acl_tag" echo -e "\n***** ACL Downloaded: $acl_tag *****" } usage() { cat < provide additional comma-separated CMake arguments string for building Arm NN (optional) --acl-scons-params= provide additional comma-separated scons parameters string for building ACL (optional) --num-threads= specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host) -h, --help print brief usage information and exit -x enable shell tracing in this script At least one component (i.e. --tflite-classic-delegate, --tflite-opaque-delegate, --tflite-parser, --onnx-parser) must be provided or else provide --all to build all Arm NN components. At least one backend (i.e. --neon-backend, --cl-backend, --ref-backend) must be chosen. This script must be executed from the same root directory in which setup-armnn.sh was executed from. The first execution of this script will download the latest release branches of Arm NN and ACL, by default. Alternatively, place custom/modified repositories named "armnn" and (optionally) "acl" in /source. Providing custom "acl" repo is optional since it is only required if backend flags --neon-backend or --cl-backend are chosen. By default, a tarball tar.gz archive of the Arm NN build will be created in the directory from which this script is called from. Examples: Build for aarch64 with all Arm NN components, NEON enabled and OpenCL enabled: /build-armnn.sh --target-arch=aarch64 --all --neon-backend --cl-backend Build for aarch64 with TF Lite Delegate, OpenCL enabled and additional ACL scons params: /build-armnn.sh --target-arch=aarch64 --tflite-classic-delegate --cl-backend --acl-scons-params='compress_kernels=1,benchmark_examples=1' Setup for aarch64 with all Arm NN dependencies, OpenCL enabled and additional Arm NN cmake args: /build-armnn.sh --target-arch=aarch64 --all --cl-backend --armnn-cmake-args='-DBUILD_SAMPLE_APP=1,-DBUILD_UNIT_TESTS=0' EOF } # This will catch in validation.sh if not set target_arch="" # Default flag values flag_tflite_classic_delegate=0 flag_tflite_opaque_delegate=0 flag_tflite_parser=0 flag_onnx_parser=0 flag_neon_backend=0 flag_cl_backend=0 flag_ref_backend=0 flag_clean=0 flag_debug=0 flag_jni=0 # Empty strings for optional additional args by default armnn_cmake_args="" acl_scons_params="" # If --num-threads is not set, the default NUM_THREADS value in common.sh will be used num_threads=0 name=$(basename "$0") # If no options provided, show help if [ $# -eq 0 ]; then usage exit 1 fi args=$(getopt -ohx -l tflite-classic-delegate,tflite-opaque-delegate,tflite-parser,onnx-parser,all,target-arch:,neon-backend,cl-backend,ref-backend,clean,debug,armnn-cmake-args:,acl-scons-params:,num-threads:,help -n "$name" -- "$@") eval set -- "$args" while [ $# -gt 0 ]; do if [ -n "${opt_prev:-}" ]; then eval "$opt_prev=\$1" opt_prev= shift 1 continue elif [ -n "${opt_append:-}" ]; then if [ -n "$1" ]; then eval "$opt_append=\"\${$opt_append:-} \$1\"" fi opt_append= shift 1 continue fi case $1 in --tflite-parser) flag_tflite_parser=1 ;; --tflite-classic-delegate) flag_tflite_classic_delegate=1 ;; --tflite-opaque-delegate) flag_tflite_opaque_delegate=1 ;; --onnx-parser) flag_onnx_parser=1 ;; --all) flag_tflite_classic_delegate=1 flag_tflite_opaque_delegate=1 flag_tflite_parser=1 flag_onnx_parser=1 ;; --target-arch) opt_prev=target_arch ;; --neon-backend) flag_neon_backend=1 ;; --cl-backend) flag_cl_backend=1 ;; --ref-backend) flag_ref_backend=1 ;; --clean) flag_clean=1 ;; --debug) flag_debug=1 ;; --armnn-cmake-args) opt_prev=armnn_cmake_args ;; --acl-scons-params) opt_prev=acl_scons_params ;; --num-threads) opt_prev=num_threads ;; -h | --help) usage exit 0 ;; -x) set -x ;; --) shift break 2 ;; esac shift 1 done # shellcheck source=common.sh source "$rel_path"/common.sh # Validation of chosen Arm NN backends if [ "$flag_neon_backend" -eq 0 ] && [ "$flag_cl_backend" -eq 0 ] && [ "$flag_ref_backend" -eq 0 ]; then echo -e "\n$name: at least one of flags --neon-backend, --cl-backend or --ref-backend must be set." exit 1 fi if [ "$target_arch" == "x86_64" ]; then if [ "$flag_neon_backend" -eq 1 ] || [ "$flag_cl_backend" -eq 1 ]; then echo "$name: Accelerated backends --neon-backend and --cl-backend are supported on Arm targets only (x86_64 chosen)." exit 1 fi fi # Verify that root source and build directories are present (post execution of setup-armnn.sh) if [ ! -d "$SOURCE_DIR" ]; then echo -e "\nERROR: Root source directory does not exist at $SOURCE_DIR" echo "Please check that:" echo "1. setup-armnn.sh was executed successfully prior to running this script" echo "2. This script is being executed in the same directory as setup-armnn.sh" exit 1 fi if [ ! -d "$BUILD_DIR" ]; then echo -e "\nERROR: Root build directory does not exist at $BUILD_DIR" echo "Please check that:" echo "1. setup-armnn.sh was executed successfully prior to running this script" echo "2. This script is being executed in the same directory as setup-armnn.sh" exit 1 fi # Download Arm NN if not done already in a previous execution of this script # Check if Arm NN source directory exists AND that it is a repository (not empty) if [ -d "$ARMNN_SRC" ] && check_if_repository "$ARMNN_SRC"; then echo -e "\n***** Arm NN source repository already located at $ARMNN_SRC. Skipping cloning of Arm NN. *****" else # Download latest release branch of Arm NN download_armnn fi # Download ACL if not done already in a previous execution of this script # Only download ACL if backend options --neon-backend and --cl-backend are chosen if [ "$flag_neon_backend" -eq 1 ] || [ "$flag_cl_backend" -eq 1 ]; then # Check if Arm NN source directory exists AND that it is a repository (not empty) if [ -d "$ACL_SRC" ] && check_if_repository "$ACL_SRC"; then echo -e "\n***** ACL source repository already located at $ACL_SRC. Skipping cloning of ACL. *****" else # Download latest release branch of ACL download_acl fi else echo -e "\n***** Backend options --neon-backend and --cl-backend not selected - skipping cloning of ACL *****" fi # Adjust output build directory names for Arm NN and ACL if debug is enabled DEBUG_POSTFIX="" if [ "$flag_debug" -eq 1 ]; then DEBUG_POSTFIX="_debug" fi # Replace commas with spaces in additional Arm NN / ACL build args # shellcheck disable=SC2001 armnn_cmake_args="$(echo "$armnn_cmake_args" | sed 's/,/ /g')" # shellcheck disable=SC2001 acl_scons_params="$(echo "$acl_scons_params" | sed 's/,/ /g')" # Directories for Arm NN and ACL build outputs ARMNN_BUILD_ROOT="$BUILD_DIR"/armnn ARMNN_BUILD_DIR_NAME="$TARGET_ARCH"_build"$DEBUG_POSTFIX" ARMNN_BUILD_TARGET="$ARMNN_BUILD_ROOT"/"$ARMNN_BUILD_DIR_NAME" ACL_BUILD_TARGET="$BUILD_DIR"/acl/"$TARGET_ARCH"_build"$DEBUG_POSTFIX" echo -e "\nINFO: Displaying configuration information before execution of $name" echo " target-arch: $TARGET_ARCH" echo " host-arch: $HOST_ARCH" echo "tflite-classic-delegate: $flag_tflite_classic_delegate" echo "tflite-opaque-delegate : $flag_tflite_opaque_delegate" echo " tflite-parser: $flag_tflite_parser" echo " onnx-parser: $flag_onnx_parser" echo " neon-backend: $flag_neon_backend" echo " cl-backend: $flag_cl_backend" echo " ref-backend: $flag_ref_backend" echo " clean: $flag_clean" echo " debug: $flag_debug" echo " armnn-cmake-args: $armnn_cmake_args" echo " acl-scons-params: $acl_scons_params" echo " num-threads: $NUM_THREADS" echo " root directory: $ROOT_DIR" echo " source directory: $SOURCE_DIR" echo " build directory: $BUILD_DIR" echo " armnn build dir: $ARMNN_BUILD_TARGET" echo -e "\nScript execution will begin in 10 seconds..." sleep 10 if [ "$flag_neon_backend" -eq 1 ] || [ "$flag_cl_backend" -eq 1 ]; then build_acl else echo -e "\n***** Skipping ACL build: --neon-backend and --cl-backend not set in options. *****" fi build_armnn exit 0 armnn-23.08/build-tool/scripts/common.sh000077500000000000000000000063231446772241200202460ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Script which stores common variables and paths used by setup-armnn.sh and build-armnn.sh # shellcheck disable=SC2034 # SC2034: false positives for variables appear unused - variables are used in setup-armnn.sh and build-armnn.sh set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. # ROOT_DIR is the directory in which a script is called from ROOT_DIR=$(pwd) SOURCE_DIR="$ROOT_DIR"/source BUILD_DIR="$ROOT_DIR"/build # Host architecture e.g. x86_64, aarch64 HOST_ARCH=$(uname -m) # Number of online cores on host NUM_THREADS=$(getconf _NPROCESSORS_ONLN) # Validate common user-defined options # shellcheck source=validation.sh source "$rel_path"/validation.sh # target_arch supplied as command line arg TARGET_ARCH="$target_arch" NATIVE_BUILD=0 if [ "$TARGET_ARCH" == "$HOST_ARCH" ]; then NATIVE_BUILD=1 fi AARCH64_COMPILER_FLAGS+="CC=/usr/bin/aarch64-linux-gnu-gcc CXX=/usr/bin/aarch64-linux-gnu-g++ " # NDK NDK_VERSION=25 NDK_SRC="$SOURCE_DIR"/android-ndk-r"$NDK_VERSION" # ANDROID ANDROID_API_VERSION=30 ANDROID_ARM_ARCH="arm64-v8a" ANDROID64_x86_TOOLCHAIN+="$NDK_SRC/toolchains/llvm/prebuilt/linux-x86_64" ANDROID64_COMPILER_FLAGS+="CC="$ANDROID64_x86_TOOLCHAIN"/bin/aarch64-linux-android"$ANDROID_API_VERSION"-clang \ CXX="$ANDROID64_x86_TOOLCHAIN"/bin/aarch64-linux-android"$ANDROID_API_VERSION"-clang++ " # Flatbuffers FLATBUFFERS_VERSION=2.0.6 FLATBUFFERS_SRC="$SOURCE_DIR"/flatbuffers-"$FLATBUFFERS_VERSION" FLATBUFFERS_BUILD_ROOT="$BUILD_DIR"/flatbuffers FLATBUFFERS_BUILD_TARGET="$FLATBUFFERS_BUILD_ROOT"/"$TARGET_ARCH"_build FLATBUFFERS_BUILD_HOST="$FLATBUFFERS_BUILD_ROOT"/"$HOST_ARCH"_build # Location of flatc compiler # Tensorflow TENSORFLOW_VERSION="6f692f73cb2043b4a0b0446539cd8c15b3dd9220" #2.12 RC1 + PR #60015 to fix Cmake build. TENSORFLOW_SRC="$SOURCE_DIR"/tensorflow TFLITE_SRC="$TENSORFLOW_SRC"/tensorflow/lite SCHEMA_SRC="$TFLITE_SRC"/schema/schema.fbs # TF Lite Schema FLATC="$FLATBUFFERS_BUILD_HOST"/bin/flatc TFLITE_BUILD_ROOT="$BUILD_DIR"/tflite # Generated TF Lite Schema location TFLITE_BUILD_TARGET="$TFLITE_BUILD_ROOT"/"$TARGET_ARCH"_build # Protobuf PROTOBUF_VERSION=3.12.0 PROTOBUF_SRC="$SOURCE_DIR"/protobuf-"$PROTOBUF_VERSION" PROTOBUF_BUILD_ROOT="$BUILD_DIR"/protobuf PROTOBUF_BUILD_HOST="$PROTOBUF_BUILD_ROOT"/"$HOST_ARCH"_build PROTOCOL_COMPILER_HOST="$PROTOBUF_BUILD_HOST"/bin/protoc PROTOBUF_BUILD_TARGET="$PROTOBUF_BUILD_ROOT"/"$TARGET_ARCH"_build PROTOBUF_LIBRARY_TARGET="$PROTOBUF_BUILD_TARGET"/lib/libprotobuf.so.23.0.0 PROTOBUF_ANDROID_LIB_TARGET="$PROTOBUF_BUILD_TARGET"/lib/libprotobuf.so # ONNX ONNX_VERSION=1.6.0 ONNX_SRC="$SOURCE_DIR"/onnx-"$ONNX_VERSION" ONNX_BUILD_TARGET="$BUILD_DIR"/onnx/"$TARGET_ARCH"_build # Arm NN / ACL ARMNN_SRC="$SOURCE_DIR"/armnn ACL_SRC="$SOURCE_DIR"/acl # Check if directory at $1 is a repository or not check_if_repository() { pushd "$1" > /dev/null if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" ]; then popd > /dev/null return 0 else popd > /dev/null return 1 fi }armnn-23.08/build-tool/scripts/docker-copy-to-host.sh000077500000000000000000000041561446772241200225720ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Script which copies a file or directory from the /home/arm-user/ directory in Docker to the host machine # This script creates a directory called 'docker_output' in the current directory and places the copied contents there # Takes two arguments: # 1. Name of created Docker image i.e. "--tag " provided at 'docker build' stage (tag is optional in image naming) # 2. Relative path to file or directory to copy from the Docker /home/arm-user/ directory # # Examples: # 1. Copy the tarball of the aarch64 build from the /home/arm-user/ directory # ./scripts/docker-copy-to-host.sh armnn_image armnn_aarch64_build.tar.gz # 2. Copy the unarchived Arm NN build # ./scripts/docker-copy-to-host.sh armnn_image build/armnn # 3. Copy the unarchived ACL build # ./scripts/docker-copy-to-host.sh armnn_image build/acl set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. image_name="$1" file_path="$2" name=$(basename "$0") echo "***** $name: Copying file(s) from path /home/arm-user/$file_path inside Docker image '$image_name' to host *****" echo -e "\n***** Creating directory docker_output on host *****" mkdir -p docker_output # Cleanup old 'armnn_temp' container in case a previous run of this script was not successful docker rm --force armnn_temp 2> /dev/null echo -e "\n***** Creating temporary Docker container named armnn_temp using Docker image '$image_name' *****" docker create --interactive --tty --name armnn_temp "$image_name" bash > /dev/null echo -e "\n***** Running Docker command: docker cp armnn_temp:/home/arm-user/$file_path ./docker_output *****" docker cp armnn_temp:/home/arm-user/"$file_path" ./docker_output > /dev/null echo -e "\n***** Successfully copied file(s) to host in directory docker_output *****" # Remove temporary docker container 'armnn_temp' docker rm --force armnn_temp > /dev/null echo -e "\n***** Deleted temporary Docker container armnn_temp *****"armnn-23.08/build-tool/scripts/install-packages.sh000077500000000000000000000066031446772241200222010ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Script which installs system-wide packages required by setup-armnn.sh and build-armnn.sh # Downloads and builds CMake from source in the current directory from which this script is called # CMake will be installed system-wide once this script has completed execution # Requires sudo privileges set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. # Host architecture e.g. x86_64, aarch64 HOST_ARCH=$(uname -m) # Number of online cores on host NUM_THREADS=$(getconf _NPROCESSORS_ONLN) # CMake is downloaded and built in the current directory from which this script is called ROOT_DIR=$(pwd) # CMake CMAKE_VERSION=3.19 CMAKE_VERSION_FULL=3.19.0 CMAKE_SRC="$ROOT_DIR"/cmake-"$CMAKE_VERSION_FULL" CMAKE_BUILD="$ROOT_DIR"/cmake_build download_cmake() { cd "$ROOT_DIR" echo -e "\n***** Downloading CMake $CMAKE_VERSION *****" wget -O cmake-"$CMAKE_VERSION_FULL".tar.gz https://cmake.org/files/v"$CMAKE_VERSION"/cmake-"$CMAKE_VERSION_FULL".tar.gz echo -e "\n***** Extracting archive *****" tar -xzf cmake-"$CMAKE_VERSION_FULL".tar.gz echo -e "\n***** Removing archive *****" rm cmake-"$CMAKE_VERSION_FULL".tar.gz echo -e "\n***** CMake $CMAKE_VERSION Downloaded *****" } install_cmake() { mkdir -p "$CMAKE_BUILD" cd "$CMAKE_BUILD" apt-get purge -y cmake echo -e "\n***** Building CMake $CMAKE_VERSION ***** " "$CMAKE_SRC"/bootstrap make make install -j "$NUM_THREADS" if [[ "$(cmake --version 2> /dev/null | grep "$CMAKE_VERSION" )" == *"$CMAKE_VERSION"* ]]; then echo -e "\n***** Built and Installed CMake $CMAKE_VERSION *****" else echo -e "\nERROR: CMake $CMAKE_VERSION not installed correctly after building from source" exit 1 fi } install_apt_packages() { apt-get update && apt-get install -y --no-install-recommends \ autoconf \ automake \ build-essential \ curl \ git \ libssl-dev \ libtool \ make \ scons \ unzip \ wget \ xxd # Install cross compile toolchains if host is x86_64 if [ "$HOST_ARCH" == "x86_64" ]; then apt-get update && apt-get install -y --no-install-recommends \ crossbuild-essential-arm64 fi apt-get clean rm -rf /var/lib/apt/lists/* } name=$(basename "$0") if [ ! "$(id -u)" -eq 0 ]; then echo -e "\nERROR: $name must be ran as root (i.e. sudo ./$name)" exit 1 fi echo -e "\n***** $name: Installing system-wide packages required by setup-armnn.sh and build-armnn.sh *****" echo -e "\nINFO: This script downloads and builds CMake from source in the current directory from which this script is called" echo -e "\nINFO: CMake and other apt packages will be installed system-wide once this script has completed execution" echo -e "\nScript execution will begin in 10 seconds..." sleep 10 install_apt_packages # Download, Build and Install CMake if not already present if [[ "$(cmake --version 2> /dev/null | grep "$CMAKE_VERSION" )" == *"$CMAKE_VERSION"* ]]; then echo -e "\n***** CMake $CMAKE_VERSION already installed, skipping CMake install *****" else download_cmake install_cmake fi echo -e "\n***** $name: Successfully installed system-wide packages required by setup-armnn.sh and build-armnn.sh *****\n" exit 0armnn-23.08/build-tool/scripts/setup-armnn.sh000077500000000000000000000307531446772241200212330ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Script which downloads and builds Arm NN dependencies # Perquisite to running build-armnn.sh set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. rel_path=$(dirname "$0") # relative path from where script is executed to script location # Download an archive using wget and extract using tar # Takes three arguments: # 1. Name of dependency being downloaded e.g. Flatbuffers # 2. Link to archive # 3. Filename given to archive upon downloading download_and_extract() { cd "$SOURCE_DIR" echo -e "\n***** Downloading $1 *****\n" wget -O "$3" "$2" echo -e "\n***** Extracting archive *****" tar -xzf "$3" echo -e "\n***** Removing archive *****" rm "$3" echo -e "\n***** $1 downloaded *****" } download_androidndk() { cd "$SOURCE_DIR" echo -e "\n***** Downloading Android NDK *****\n" wget https://dl.google.com/android/repository/android-ndk-r25-linux.zip echo -e "\n***** Extracting archive *****" unzip android-ndk-r25-linux.zip echo -e "\n***** Removing archive *****" rm android-ndk-r25-linux.zip echo -e "\n***** Android NDK downloaded *****" } download_protobuf() { download_and_extract \ "Protobuf" \ "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz" \ "protobuf-all-$PROTOBUF_VERSION.tar.gz" } build_protobuf() { local native_build=$1 local build_dir="$PROTOBUF_BUILD_TARGET" local cmake_flags="" local target_arch="$TARGET_ARCH" local additional_cmds="" if [ "$native_build" -eq 0 ]; then mkdir -p "$PROTOBUF_BUILD_TARGET" additional_cmds+="--with-protoc=$PROTOCOL_COMPILER_HOST " if [ "$TARGET_ARCH" == "aarch64" ]; then cmake_flags+="$AARCH64_COMPILER_FLAGS" additional_cmds+="--host=aarch64-linux " fi if [ "$TARGET_ARCH" == "android64" ]; then additional_cmds+="--host=aarch64-linux-android " cmake_flags+="$ANDROID64_COMPILER_FLAGS" fi else target_arch="$HOST_ARCH" mkdir -p "$PROTOBUF_BUILD_HOST" build_dir="$PROTOBUF_BUILD_HOST" fi echo -e "\n***** Building Protobuf for $target_arch ***** " cd "$PROTOBUF_BUILD_ROOT" # Cleanup any previous cmake files, except actual builds which we keep find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then eval "$cmake_flags" cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \ -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \ -DCMAKE_CXX_FLAGS=--std=c++14 \ -Dprotobuf_BUILD_TESTS=OFF \ -Dprotobuf_BUILD_SHARED_LIBS=ON \ -Dprotobuf_WITH_ZLIB=OFF \ -DCMAKE_BUILD_TYPE=Release \ $PROTOBUF_SRC/cmake/ make libprotobuf -j "$NUM_THREADS" cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=libprotobuf -P cmake_install.cmake cmake -DCMAKE_INSTALL_PREFIX=$PROTOBUF_BUILD_TARGET -DCOMPONENT=protobuf-headers -P cmake_install.cmake else eval "$cmake_flags" \ "$PROTOBUF_SRC"/configure --prefix="$build_dir" "$additional_cmds" make install -j "$NUM_THREADS" fi echo -e "\n***** Protobuf built for $target_arch ***** " } download_flatbuffers() { download_and_extract \ "Flatbuffers" \ "https://github.com/google/flatbuffers/archive/v$FLATBUFFERS_VERSION.tar.gz" \ "flatbuffers-$FLATBUFFERS_VERSION.tar.gz" } build_flatbuffers() { local native_build=$1 local build_dir="$FLATBUFFERS_BUILD_TARGET" local target_arch="$TARGET_ARCH" local cmake_flags="CXXFLAGS=-fPIC " if [ "$native_build" -eq 0 ]; then mkdir -p "$FLATBUFFERS_BUILD_TARGET" if [ "$TARGET_ARCH" == "aarch64" ] || [ "$TARGET_ARCH" == "android64" ]; then cmake_flags+="$AARCH64_COMPILER_FLAGS" fi else target_arch="$HOST_ARCH" mkdir -p "$FLATBUFFERS_BUILD_HOST" build_dir="$FLATBUFFERS_BUILD_HOST" fi echo -e "\n***** Building flatbuffers for $target_arch *****" mkdir -p "$FLATBUFFERS_BUILD_ROOT" cd "$FLATBUFFERS_BUILD_ROOT" # Cleanup any previous cmake files, except actual builds which we keep find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + if [ "$native_build" -eq 0 ] && [ "$TARGET_ARCH" == "android64" ]; then eval "$cmake_flags" \ cmake -DCMAKE_ANDROID_NDK="$NDK_SRC" \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION="$ANDROID_API_VERSION" \ -DCMAKE_ANDROID_ARCH_ABI="$ANDROID_ARM_ARCH" \ -DCMAKE_CXX_FLAGS=--std=c++14 \ -DFLATBUFFERS_BUILD_FLATC=0 \ -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \ -DCMAKE_BUILD_TYPE=Release \ -DFLATBUFFERS_BUILD_TESTS=0 \ "$FLATBUFFERS_SRC" else eval "$cmake_flags" \ cmake -DFLATBUFFERS_BUILD_FLATC="$native_build" \ -DCMAKE_INSTALL_PREFIX:PATH="$build_dir" \ -DFLATBUFFERS_BUILD_TESTS=0 \ "$FLATBUFFERS_SRC" fi make all install -j "$NUM_THREADS" echo -e "\n***** Built flatbuffers for $target_arch *****" } download_tensorflow() { cd "$SOURCE_DIR" echo -e "\n***** Downloading TensorFlow *****" git clone https://github.com/tensorflow/tensorflow.git cd "$TENSORFLOW_SRC" git checkout "$TENSORFLOW_VERSION" echo -e "\n***** TensorFlow downloaded *****" } build_tflite() { mkdir -p "$TFLITE_BUILD_TARGET" cd "$TFLITE_BUILD_TARGET" local target_arch_cmd="" # default is native, no command needed local cmake_flags="" case "$TARGET_ARCH" in "aarch64") cmake_flags+="$AARCH64_COMPILER_FLAGS" target_arch_cmd="-DCMAKE_SYSTEM_PROCESSOR=aarch64 \ -DCMAKE_SYSTEM_NAME=Linux " if [ "$NATIVE_BUILD" -eq 0 ]; then cmake_flags+="ARMCC_FLAGS='-funsafe-math-optimizations' " fi ;; "android64") cmake_flags+="$AARCH64_COMPILER_FLAGS" if [ "$NATIVE_BUILD" -eq 0 ]; then target_arch_cmd="-DCMAKE_TOOLCHAIN_FILE=$NDK_SRC/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=$ANDROID_ARM_ARCH \ -DANDROID_PLATFORM=$ANDROID_API_VERSION" fi ;; esac echo -e "\n***** Building TF Lite for $TARGET_ARCH *****" # Cleanup any previous cmake files, except actual builds which we keep find . -mindepth 1 -name "*_build" -prune -o -exec rm -rf {} + eval "$cmake_flags" \ cmake -DTFLITE_ENABLE_XNNPACK=OFF \ -DFLATBUFFERS_BUILD_FLATC=OFF \ -DBUILD_SHARED_LIBS=OFF \ -DBUILD_TESTING=OFF \ "$target_arch_cmd" \ "$TFLITE_SRC" cmake --build . -j "$NUM_THREADS" echo -e "\n***** Built TF Lite for $TARGET_ARCH *****" } generate_tflite_schema() { echo -e "\n***** Generating TF Lite Schema *****" mkdir -p "$TFLITE_BUILD_ROOT" cd "$TFLITE_BUILD_ROOT" cp "$SCHEMA_SRC" . $FLATC -c --gen-object-api --reflect-types --reflect-names schema.fbs echo -e "\n***** Generated TF Lite Schema *****" } download_onnx() { download_and_extract \ "ONNX" \ "https://github.com/onnx/onnx/releases/download/v$ONNX_VERSION/onnx-$ONNX_VERSION.tar.gz" \ "onnx-$ONNX_VERSION.tar.gz" } generate_onnx_sources() { mkdir -p "$ONNX_BUILD_TARGET" cd "$ONNX_SRC" echo -e "\n***** Generating ONNX sources for $TARGET_ARCH *****" export LD_LIBRARY_PATH="$PROTOBUF_BUILD_HOST"/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} eval "$PROTOCOL_COMPILER_HOST" onnx/onnx.proto \ --proto_path=. \ --proto_path="$ONNX_SRC" \ --proto_path="$PROTOBUF_BUILD_HOST"/include \ --cpp_out "$ONNX_BUILD_TARGET" echo -e "\n***** Generated ONNX sources for $TARGET_ARCH *****" } usage() { cat < specify number of threads/cores to build dependencies with (optional: defaults to number of online CPU cores on host) -h, --help print brief usage information and exit -x enable shell tracing in this script At least one dependency flag (e.g. --tflite-classic-delegate) must be provided or else provide --all to setup all dependencies. Directories called "source" and "build" will be generated in the current directory (ROOT_DIR) from which this script is called. It's recommended to call this script in a directory outside of this Arm NN source repo, to avoid nested repositories. Examples: Setup for aarch64 with all Arm NN dependencies: /setup-armnn.sh --target-arch=aarch64 --all Setup for aarch64 with the existing TF Lite Delegate and TF Lite Parser dependencies only: /setup-armnn.sh --target-arch=aarch64 --tflite-classic-delegate --tflite-parser EOF } # This will catch in validation.sh if not set target_arch="" # Default flag values flag_tflite_classic_delegate=0 flag_tflite_opaque_delegate=0 flag_tflite_parser=0 flag_onnx_parser=0 # If --num-threads is not set, the default NUM_THREADS value in common.sh will be used num_threads=0 name=$(basename "$0") # If no options provided, show help if [ $# -eq 0 ]; then usage exit 1 fi args=$(getopt -ohx -l tflite-classic-delegate,tflite-opaque-delegate,tflite-parser,onnx-parser,all,target-arch:,num-threads:,help -n "$name" -- "$@") eval set -- "$args" while [ $# -gt 0 ]; do if [ -n "${opt_prev:-}" ]; then eval "$opt_prev=\$1" opt_prev= shift 1 continue elif [ -n "${opt_append:-}" ]; then if [ -n "$1" ]; then eval "$opt_append=\"\${$opt_append:-} \$1\"" fi opt_append= shift 1 continue fi case $1 in --tflite-parser) flag_tflite_parser=1 ;; --tflite-classic-delegate) flag_tflite_classic_delegate=1 ;; --tflite-opaque-delegate) flag_tflite_opaque_delegate=1 ;; --onnx-parser) flag_onnx_parser=1 ;; --all) flag_tflite_classic_delegate=1 flag_tflite_opaque_delegate=1 flag_tflite_parser=1 flag_onnx_parser=1 ;; --target-arch) opt_prev=target_arch ;; --num-threads) opt_prev=num_threads ;; -h | --help) usage exit 0 ;; -x) set -x ;; --) shift break 2 ;; esac shift 1 done # shellcheck source=common.sh source "$rel_path"/common.sh echo -e "\nINFO: Displaying configuration information before execution of $name" echo " target-arch: $TARGET_ARCH" echo " host-arch: $HOST_ARCH" echo "tflite-classic-delegate: $flag_tflite_classic_delegate" echo "tflite-opaque-delegate : $flag_tflite_opaque_delegate" echo " tflite-parser: $flag_tflite_parser" echo " onnx-parser: $flag_onnx_parser" echo " num-threads: $NUM_THREADS" echo " root directory: $ROOT_DIR" echo " source directory: $SOURCE_DIR" echo " build directory: $BUILD_DIR" if check_if_repository .; then echo -e "\n***** WARNING: Running script inside a git repository. To avoid nested repos, call this script from outside of this repo. *****" fi echo -e "\nScript execution will begin in 10 seconds..." sleep 10 mkdir -p "$SOURCE_DIR" mkdir -p "$BUILD_DIR" if [ "$TARGET_ARCH" == "android64" ]; then download_androidndk fi if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ] || [ "$flag_tflite_parser" -eq 1 ]; then download_flatbuffers # Host build build_flatbuffers 1 # Target build for cross compile if [ "$NATIVE_BUILD" -eq 0 ]; then build_flatbuffers 0 fi download_tensorflow fi if [ "$flag_tflite_parser" -eq 1 ]; then generate_tflite_schema fi if [ "$flag_tflite_classic_delegate" -eq 1 ] || [ "$flag_tflite_opaque_delegate" -eq 1 ]; then build_tflite fi if [ "$flag_onnx_parser" -eq 1 ]; then download_protobuf # Host build build_protobuf 1 # Target build for cross compile if [ "$NATIVE_BUILD" -eq 0 ]; then build_protobuf 0 fi download_onnx generate_onnx_sources fi echo -e "\n***** Arm NN setup complete. Now build with build-armnn.sh. *****\n" exit 0armnn-23.08/build-tool/scripts/validation.sh000077500000000000000000000036221446772241200211070ustar00rootroot00000000000000#!/bin/bash # # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Common validation of command line arguments provided to setup-armnn.sh and build-armnn.sh # shellcheck disable=SC2034,SC2154 # SC2034: false positives for variables appear unused - variables are used in setup-armnn.sh and build-armnn.sh # SC2154: false positives for variables referenced but not assigned - variables are assigned in setup-armnn.sh and build-armnn.sh set -o nounset # Catch references to undefined variables. set -o pipefail # Catch non zero exit codes within pipelines. set -o errexit # Catch and propagate non zero exit codes. # Host and target architecture validation if [ "$target_arch" == "" ]; then echo "$name: --target-arch is not set. Example usage: --target-arch=aarch64" exit 1 fi if [ "$target_arch" != "aarch64" ] && [ "$target_arch" != "android64" ] && [ "$target_arch" != "x86_64" ]; then echo "$name: --target-arch is not valid. Valid options are: aarch64, android64, x86_64" exit 1 fi if [ "$HOST_ARCH" == "aarch64" ]; then if [ "$target_arch" != "aarch64" ]; then echo "$name: aarch64 is the only supported --target_arch when host is aarch64" exit 1 fi fi if [ "$target_arch" == "android64" ]; then if [ "$HOST_ARCH" != "x86_64" ]; then echo "$name: --target_arch android64 is only supported when host is x86_64" exit 1 fi fi # Validation of chosen Arm NN dependencies if [ "$flag_tflite_classic_delegate" -eq 0 ] && [ "$flag_tflite_opaque_delegate" -eq 0 ] && [ "$flag_tflite_parser" -eq 0 ] && [ "$flag_onnx_parser" -eq 0 ]; then echo "$name: at least one of flags --tflite-classic-delegate, --tflite-opaque-delegate, --tflite-parser or --onnx-parser must be set (or --all)." exit 1 fi # If --num-threads is set, overwrite default NUM_THREADS with user-defined value if [ ! "$num_threads" -eq 0 ]; then NUM_THREADS="$num_threads" fiarmnn-23.08/cmake/000077500000000000000000000000001446772241200137325ustar00rootroot00000000000000armnn-23.08/cmake/AddDllCopyCommands.cmake000066400000000000000000000033141446772241200203760ustar00rootroot00000000000000# # Copyright © 2018-2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # macro (addDllCopyCommand target sourceDebug sourceRelease) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<$:${sourceDebug}>$<$:${sourceRelease}>$<$:${sourceRelease}>$<$:${sourceRelease}>" $) endmacro() # Checks if the given list contains an entry which matches the given regex. function(listContainsRegex result list regex) set(${result} 0 PARENT_SCOPE) foreach(element ${list}) if(${element} MATCHES ${regex}) set(${result} 1 PARENT_SCOPE) return() endif() endforeach() endfunction() macro(addDllCopyCommands target) if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) # Get the list of dependencies for the given target, so we can copy just the DLLs we need. get_target_property(target_deps_str ${target} LINK_LIBRARIES) set(target_deps) list(APPEND target_deps ${target_deps_str}) cmake_policy(SET CMP0057 NEW) # Enable the "IN_LIST" operator # armnn.dll if ("armnn" IN_LIST target_deps) addDllCopyCommand(${target} "$/armnn.dll" "$/armnn.dll") endif() # armnnTfLiteParser.dll if ("armnnTfLiteParser" IN_LIST target_deps) addDllCopyCommand(${target} "$/armnnTfLiteParser.dll" "$/armnnTfLiteParser.dll") endif() endif() endmacro() armnn-23.08/cmake/ArmnnConfig.cmake.in000066400000000000000000000010701446772241200175400ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # get_filename_component(ARMNN_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) set(ARMNN_CONFIG_FILE ${CMAKE_CURRENT_LIST_FILE}) MESSAGE(STATUS "Found Armnn: ${ARMNN_CONFIG_FILE}") include(CMakeFindDependencyMacro) list(APPEND CMAKE_MODULE_PATH ${ARMNN_CMAKE_DIR}) if(NOT TARGET Armnn::Armnn) MESSAGE(STATUS "Armnn Import: ${ARMNN_CMAKE_DIR}/ArmnnTargets.cmake") include("${ARMNN_CMAKE_DIR}/ArmnnTargets.cmake") endif() set(ARMNN_LIBRARIES Armnn::Armnn)armnn-23.08/cmake/ArmnnTestUtilsVersion.cmake000066400000000000000000000015021446772241200212340ustar00rootroot00000000000000# # Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Read the ArmNN armnnTestUtils version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../include/armnnTestUtils/Version.hpp armnnTestUtilsVersion) # Parse the ArmNN armnnTestUtils version components string(REGEX MATCH "#define ARMNN_TEST_UTILS_MAJOR_VERSION ([0-9]*)" _ ${armnnTestUtilsVersion}) set(ARMNN_TEST_UTILS_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define ARMNN_TEST_UTILS_MINOR_VERSION ([0-9]*)" _ ${armnnTestUtilsVersion}) set(ARMNN_TEST_UTILS_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(ARMNN_TEST_UTILS_LIB_VERSION "${ARMNN_TEST_UTILS_MAJOR_VERSION}.${ARMNN_TEST_UTILS_MINOR_VERSION}") # Define LIB soversion set(ARMNN_TEST_UTILS_LIB_SOVERSION "${ARMNN_TEST_UTILS_MAJOR_VERSION}")armnn-23.08/cmake/ArmnnVersion.cmake000066400000000000000000000012221446772241200173520ustar00rootroot00000000000000# # Copyright © 2019 Arm Ltd. All rights reserved. # SPDX-License-Identifier: MIT # # Read the ArmNN version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../include/armnn/Version.hpp armnnVersion) # Parse the ArmNN version components string(REGEX MATCH "#define ARMNN_MAJOR_VERSION ([0-9]*)" _ ${armnnVersion}) set(ARMNN_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define ARMNN_MINOR_VERSION ([0-9]*)" _ ${armnnVersion}) set(ARMNN_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(GENERIC_LIB_VERSION "${ARMNN_MAJOR_VERSION}.${ARMNN_MINOR_VERSION}") # Define LIB soversion set(GENERIC_LIB_SOVERSION "${ARMNN_MAJOR_VERSION}") armnn-23.08/cmake/ClassicDelegateVersion.cmake000066400000000000000000000013701446772241200213170ustar00rootroot00000000000000# # Copyright © 2021,2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Read the ArmNN Delegate version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../delegate/classic/include/Version.hpp ClassicDelegateVersion) # Parse the ArmNN Delegate version components string(REGEX MATCH "#define DELEGATE_MAJOR_VERSION ([0-9]*)" _ ${ClassicDelegateVersion}) set(DELEGATE_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define DELEGATE_MINOR_VERSION ([0-9]*)" _ ${ClassicDelegateVersion}) set(DELEGATE_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(DELEGATE_LIB_VERSION "${DELEGATE_MAJOR_VERSION}.${DELEGATE_MINOR_VERSION}") # Define LIB soversion set(DELEGATE_LIB_SOVERSION "${DELEGATE_MAJOR_VERSION}")armnn-23.08/cmake/GlobalConfig.cmake000066400000000000000000000537551446772241200173010ustar00rootroot00000000000000# # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # Copyright 2020 NXP # SPDX-License-Identifier: MIT # option(BUILD_ONNX_PARSER "Build Onnx parser" OFF) option(BUILD_UNIT_TESTS "Build unit tests" ON) option(BUILD_TESTS "Build test applications" OFF) option(ARMNN_SAMPLE_APPS_ENABLED "Build Sample ArmNN Applications" ON) option(BUILD_FOR_COVERAGE "Use no optimization and output .gcno and .gcda files" OFF) option(ARMCOMPUTENEON "Build with ARM Compute NEON support" OFF) option(ARMCOMPUTECL "Build with ARM Compute OpenCL support" OFF) option(ARMNNREF "Build with ArmNN reference support" ON) option(ARMNNTOSAREF "Build with TOSA reference support" OFF) option(PROFILING_BACKEND_STREAMLINE "Forward the armNN profiling events to DS-5/Streamline as annotations" OFF) # options used for heap profiling and leak checking option(HEAP_PROFILING "Build with heap profiling enabled" OFF) option(LEAK_CHECKING "Build with leak checking enabled" OFF) option(GPERFTOOLS_ROOT "Location where the gperftools 'include' and 'lib' folders to be found" Off) # options used for tensorflow lite support option(BUILD_TF_LITE_PARSER "Build Tensorflow Lite parser" OFF) option(BUILD_ARMNN_SERIALIZER "Build Armnn Serializer" OFF) option(BUILD_ACCURACY_TOOL "Build Accuracy Tool" OFF) option(FLATC_DIR "Path to Flatbuffers compiler" OFF) option(TF_LITE_GENERATED_PATH "Tensorflow lite generated C++ schema location" OFF) option(FLATBUFFERS_ROOT "Location where the flatbuffers 'include' and 'lib' folders to be found" Off) option(TOSA_SERIALIZATION_LIB_ROOT "Location where the TOSA Serialization Library 'include' and 'lib' folders can be found" OFF) option(TOSA_REFERENCE_MODEL_ROOT "Location where the TOSA Reference Model 'include' and 'lib' folders can be found" OFF) option(TOSA_REFERENCE_MODEL_OUTPUT "TOSA Reference Model output is printed during layer support checks" ON) option(DYNAMIC_BACKEND_PATHS "Colon seperated list of paths where to load the dynamic backends from" "") option(SAMPLE_DYNAMIC_BACKEND "Include the sample dynamic backend and its tests in the build" OFF) option(BUILD_GATORD_MOCK "Build the Gatord simulator for external profiling testing." ON) option(BUILD_TIMELINE_DECODER "Build the Timeline Decoder for external profiling." ON) option(BUILD_BASE_PIPE_SERVER "Build the server to handle external profiling pipe traffic" ON) option(BUILD_PYTHON_WHL "Build Python wheel package" OFF) option(BUILD_PYTHON_SRC "Build Python source package" OFF) option(BUILD_STATIC_PIPE_LIBS "Build Static PIPE libraries" OFF) option(BUILD_PIPE_ONLY "Build the PIPE libraries only" OFF) option(BUILD_CLASSIC_DELEGATE "Build the Arm NN TfLite delegate" OFF) option(BUILD_OPAQUE_DELEGATE "Build the Arm NN TfLite Opaque delegate" OFF) option(BUILD_MEMORY_STRATEGY_BENCHMARK "Build the MemoryBenchmark" OFF) option(BUILD_BARE_METAL "Disable features requiring operating system support" OFF) option(BUILD_SHARED_LIBS "Determines if Armnn will be built statically or dynamically. This is an experimental feature and not fully supported. Only the ArmNN core and the Delegate can be built statically." ON) option(EXECUTE_NETWORK_STATIC " This is a limited experimental build that is entirely static. It currently only supports being set by changing the current CMake default options like so: BUILD_TF_LITE_PARSER=1/0 BUILD_ARMNN_SERIALIZER=1/0 ARMCOMPUTENEON=1/0 ARMNNREF=1/0 ARMCOMPUTECL=0 BUILD_ONNX_PARSER=0 BUILD_CLASSIC_DELEGATE=0 BUILD_OPAQUE_DELEGATE=0 BUILD_TIMELINE_DECODER=0 BUILD_BASE_PIPE_SERVER=0 BUILD_UNIT_TESTS=0 ARMNN_SAMPLE_APPS_ENABLED=0 BUILD_SHARED_LIBS=0 BUILD_GATORD_MOCK=0 HEAP_PROFILING=0 LEAK_CHECKING=0" OFF) if(BUILD_ARMNN_TFLITE_DELEGATE) message(BUILD_ARMNN_TFLITE_DELEGATE option is deprecated, it will be removed in 24.02, please use BUILD_CLASSIC_DELEGATE instead) set(BUILD_CLASSIC_DELEGATE 1) endif() include(SelectLibraryConfigurations) set(COMPILER_IS_GNU_LIKE 0) if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU OR ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang OR ${CMAKE_CXX_COMPILER_ID} STREQUAL AppleClang) set(COMPILER_IS_GNU_LIKE 1) endif() # Enable CCache if available and not disabled option(USE_CCACHE "USE_CCACHE" ON) find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND AND USE_CCACHE) get_property(rule_launch_compile DIRECTORY PROPERTY RULE_LAUNCH_COMPILE) set_property(DIRECTORY PROPERTY RULE_LAUNCH_COMPILE "CCACHE_CPP2=yes ${rule_launch_compile} ccache") endif() # Enable distcc if available and not disabled option(USE_DISTCC "USE_DISTCC" OFF) find_program(DISTCC_FOUND distcc) if(DISTCC_FOUND AND USE_DISTCC) get_property(rule_launch_compile DIRECTORY PROPERTY RULE_LAUNCH_COMPILE) set_property(DIRECTORY PROPERTY RULE_LAUNCH_COMPILE "${rule_launch_compile} distcc") endif() # Set to release configuration by default if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() # Compiler flags that are always set set(CMAKE_POSITION_INDEPENDENT_CODE ON) if(COMPILER_IS_GNU_LIKE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -Werror -Wold-style-cast -Wno-missing-braces -Wconversion -Wsign-conversion") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-psabi") endif() elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) # Disable C4996 (use of deprecated identifier) due to # https://developercommunity.visualstudio.com/content/problem/252574/deprecated-compilation-warning-for-virtual-overrid.html set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /wd4996") add_definitions(-DNO_STRICT=1) endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL Android) # -lz is necessary for when building with ACL set with compressed kernels set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -llog -lz") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -llog -lz") endif() # Compiler flags for Release builds set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") if(COMPILER_IS_GNU_LIKE) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2") endif() # Compiler flags for Debug builds if(COMPILER_IS_GNU_LIKE) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0") elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd /ZI /Od") # Disable SAFESEH which is necessary for Edit and Continue to work set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO") set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO") endif() # Modify RelWithDebInfo so that NDEBUG isn't defined. # This enables asserts. if (COMPILER_IS_GNU_LIKE) string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() # Compiler flags for code coverage measurements if(BUILD_FOR_COVERAGE) if(NOT CMAKE_BUILD_TYPE EQUAL "Debug") message(WARNING "BUILD_FOR_COVERAGE set so forcing to Debug build") set(CMAKE_BUILD_TYPE "Debug") endif() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") endif() if(BUILD_FOR_COVERAGE AND NOT BUILD_UNIT_TESTS) message(WARNING "BUILD_FOR_COVERAGE set but not BUILD_UNIT_TESTS, so code coverage will not be able to run") endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) include(CMakeFindDependencyMacro) if(EXECUTE_NETWORK_STATIC) add_definitions(-DARMNN_DISABLE_SOCKETS -DARMNN_STUB_PROFILING -DARMNN_DISABLE_DYNAMIC_BACKENDS) set(ARMNN_SAMPLE_APPS_ENABLED 0) set(DISABLE_DYNAMIC_BACKENDS 1) set(BUILD_SHARED_LIBS 0) endif() if(BUILD_BARE_METAL) add_definitions(-DARMNN_BUILD_BARE_METAL -DARMNN_DISABLE_FILESYSTEM -DARMNN_DISABLE_PROCESSES -DARMNN_DISABLE_THREADS -DARMNN_DISABLE_SOCKETS -DARMNN_STUB_PROFILING -DARMNN_DISABLE_DYNAMIC_BACKENDS) set(DISABLE_DYNAMIC_BACKENDS 1) set(BUILD_SHARED_LIBS 0) endif() if (NOT BUILD_PIPE_ONLY) # cxxopts (Alternative to boost::program_options) find_path(CXXOPTS_INCLUDE cxxopts/cxxopts.hpp PATHS third-party NO_CMAKE_FIND_ROOT_PATH) include_directories(SYSTEM "${CXXOPTS_INCLUDE}") endif() if (NOT BUILD_PIPE_ONLY) # ghc (Alternative to boost::filesystem) find_path(GHC_INCLUDE ghc/filesystem.hpp PATHS third-party NO_CMAKE_FIND_ROOT_PATH) include_directories(SYSTEM "${GHC_INCLUDE}") endif() # JNI_BUILD has DBUILD_SHARED_LIBS set to 0 and not finding libs while building # hence added NOT BUILD_CLASSIC_DELEGATE/BUILD_OPAQUE_DELEGATE condition if(NOT BUILD_SHARED_LIBS AND NOT BUILD_CLASSIC_DELEGATE AND NOT BUILD_OPAQUE_DELEGATE) set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib) endif() # pthread if (NOT BUILD_BARE_METAL) find_package(Threads) endif() if (EXECUTE_NETWORK_STATIC) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static -pthread") endif() # Favour the protobuf passed on command line if(BUILD_ONNX_PARSER) find_library(PROTOBUF_LIBRARY_DEBUG NAMES "protobufd" PATHS ${PROTOBUF_ROOT}/lib NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_library(PROTOBUF_LIBRARY_DEBUG NAMES "protobufd") find_library(PROTOBUF_LIBRARY_RELEASE NAMES "protobuf" PATHS ${PROTOBUF_ROOT}/lib NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_library(PROTOBUF_LIBRARY_RELEASE NAMES "protobuf") select_library_configurations(PROTOBUF) find_path(PROTOBUF_INCLUDE_DIRS "google/protobuf/message.h" PATHS ${PROTOBUF_ROOT}/include NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_path(PROTOBUF_INCLUDE_DIRS "google/protobuf/message.h") include_directories(SYSTEM "${PROTOBUF_INCLUDE_DIRS}") add_definitions(-DPROTOBUF_USE_DLLS) add_definitions(-DARMNN_ONNX_PARSER) find_path(ONNX_GENERATED_SOURCES "onnx/onnx.pb.cc") # C++ headers generated for onnx protobufs include_directories(SYSTEM "${ONNX_GENERATED_SOURCES}") endif() if(BUILD_CLASSIC_DELEGATE) add_definitions(-DARMNN_TFLITE_DELEGATE) endif() if(BUILD_OPAQUE_DELEGATE) add_definitions(-DARMNN_TFLITE_OPAQUE_DELEGATE) endif() # Flatbuffers support for TF Lite, Armnn Serializer or the TOSA backend. if(BUILD_TF_LITE_PARSER OR BUILD_ARMNN_SERIALIZER OR ARMNNTOSAREF) # verify we have a valid flatbuffers include path find_path(FLATBUFFERS_INCLUDE_PATH flatbuffers/flatbuffers.h HINTS ${FLATBUFFERS_ROOT}/include /usr/local/include /usr/include) message(STATUS "Flatbuffers headers are located at: ${FLATBUFFERS_INCLUDE_PATH}") find_library(FLATBUFFERS_LIBRARY NAMES libflatbuffers.a flatbuffers HINTS ${FLATBUFFERS_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "Flatbuffers library located at: ${FLATBUFFERS_LIBRARY}") endif() # Flatbuffers schema support for TF Lite if(BUILD_TF_LITE_PARSER) find_path(TF_LITE_SCHEMA_INCLUDE_PATH schema_generated.h HINTS ${TF_LITE_GENERATED_PATH}) message(STATUS "Tf Lite generated header found at: ${TF_LITE_SCHEMA_INCLUDE_PATH}") add_definitions(-DARMNN_TF_LITE_PARSER) endif() if(BUILD_ARMNN_SERIALIZER) add_definitions(-DARMNN_SERIALIZER) add_definitions(-DARMNN_SERIALIZER_SCHEMA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/src/armnnSerializer/ArmnnSchema.fbs") endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/profiling) # ARM Compute # Note that ARM Compute has a different folder layout depending on the branch but also on # whether it comes from a prepackaged archive (this is why we add several hints below) if(ARMCOMPUTENEON OR ARMCOMPUTECL) find_path(ARMCOMPUTE_INCLUDE arm_compute/core/CL/OpenCL.h PATHS ${ARMCOMPUTE_ROOT}/include PATHS ${ARMCOMPUTE_ROOT}/applications/arm_compute PATHS ${ARMCOMPUTE_ROOT} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_path(ARMCOMPUTE_INCLUDE arm_compute/core/CL/OpenCL.h) include_directories(SYSTEM "${ARMCOMPUTE_INCLUDE}") # Find the Arm Compute libraries if not already specified (the user may have already defined this in advance, # e.g. if building clframework as a dependent cmake project) if (NOT DEFINED ARMCOMPUTE_LIBRARIES) # We link to the static variant so that customers don't need to find and build a compatible version of clframework. # First try the folders specified ARMCOMPUTE_BUILD_DIR (with PATH_SUFFIXES for # Windows builds) if ((NOT DEFINED ARMCOMPUTE_BUILD_DIR) AND (DEFINED ARMCOMPUTE_ROOT)) # Default build directory for ComputeLibrary is under the root set(ARMCOMPUTE_BUILD_DIR ${ARMCOMPUTE_ROOT}/build) endif() find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static PATHS ${ARMCOMPUTE_BUILD_DIR} PATH_SUFFIXES "Debug" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static PATHS ${ARMCOMPUTE_BUILD_DIR} PATH_SUFFIXES "Release" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static PATHS ${ARMCOMPUTE_BUILD_DIR} PATH_SUFFIXES "Debug" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static PATHS ${ARMCOMPUTE_BUILD_DIR} PATH_SUFFIXES "Release" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # In case it wasn't there, try a default search (will work in cases where # the library has been installed into a standard location) find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static) find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static) find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static) find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static) # In case it wasn't there, try the dynamic libraries # This case will get used in a linux setup where the Compute Library # has been installed in a standard system library path as a dynamic library find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute) find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute) find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core) find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core) set(ARMCOMPUTE_LIBRARIES debug ${ARMCOMPUTE_LIBRARY_DEBUG} ${ARMCOMPUTE_CORE_LIBRARY_DEBUG} optimized ${ARMCOMPUTE_LIBRARY_RELEASE} ${ARMCOMPUTE_CORE_LIBRARY_RELEASE} ) endif() endif() # ARM Compute NEON backend if(ARMCOMPUTENEON) # Add preprocessor definition for ARM Compute NEON add_definitions(-DARMCOMPUTENEON_ENABLED) # The ARM Compute headers contain some NEON intrinsics, so we need to build armnn with NEON support on armv7 if(${CMAKE_SYSTEM_PROCESSOR} MATCHES armv7 AND COMPILER_IS_GNU_LIKE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon") endif() endif() # ARM Compute OpenCL backend if(ARMCOMPUTECL) # verify we have a valid flatbuffers include path find_path(FLATBUFFERS_INCLUDE_PATH flatbuffers/flatbuffers.h HINTS ${FLATBUFFERS_ROOT}/include /usr/local/include /usr/include) message(STATUS "Flatbuffers headers are located at: ${FLATBUFFERS_INCLUDE_PATH}") find_library(FLATBUFFERS_LIBRARY NAMES libflatbuffers.a flatbuffers HINTS ${FLATBUFFERS_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "Flatbuffers library located at: ${FLATBUFFERS_LIBRARY}") # Always use Arm compute library OpenCL headers find_path(OPENCL_INCLUDE CL/opencl.hpp PATHS ${ARMCOMPUTE_ROOT}/include NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) # Link against libOpenCL in opencl-1.2-stubs, but don't search there at runtime link_libraries(-L${ARMCOMPUTE_BUILD_DIR}/opencl-1.2-stubs) set(OPENCL_LIBRARIES OpenCL) include_directories(SYSTEM ${OPENCL_INCLUDE}) # Add preprocessor definition for ARM Compute OpenCL add_definitions(-DARMCOMPUTECL_ENABLED) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DARM_COMPUTE_DEBUG_ENABLED") endif() # Used by both Arm Compute backends, but should be added # to the search path after the system directories if necessary if(ARMCOMPUTENEON OR ARMCOMPUTECL) find_path(HALF_INCLUDE half/half.hpp) find_path(HALF_INCLUDE half/half.hpp PATHS ${ARMCOMPUTE_ROOT}/include NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) include_directories(SYSTEM ${HALF_INCLUDE}) endif() # ArmNN reference backend if(ARMNNREF) add_definitions(-DARMNNREF_ENABLED) endif() # If a backend requires TOSA common, add it here. if(ARMNNTOSAREF) set(ARMNNTOSACOMMON ON) endif() if(ARMNNTOSACOMMON) # Locate the includes for the TOSA serialization library as it is needed for TOSA common and TOSA backends. message(STATUS "TOSA serialization library root set to ${TOSA_SERIALIZATION_LIB_ROOT}") find_path(TOSA_SERIALIZATION_LIB_INCLUDE tosa_serialization_handler.h HINTS ${TOSA_SERIALIZATION_LIB_ROOT}/include) message(STATUS "TOSA serialization library include directory located at: ${TOSA_SERIALIZATION_LIB_INCLUDE}") find_library(TOSA_SERIALIZATION_LIB NAMES tosa_serialization_lib.a tosa_serialization_lib HINTS ${TOSA_SERIALIZATION_LIB_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "TOSA serialization library set to ${TOSA_SERIALIZATION_LIB}") # Include required headers for TOSA Serialization Library include_directories(SYSTEM ${FLATBUFFERS_INCLUDE_PATH}) include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/third-party/half) include_directories(SYSTEM ${TOSA_SERIALIZATION_LIB_INCLUDE}) endif() # ArmNN TOSA reference backend if(ARMNNTOSAREF) # Locate the includes for the TOSA Reference Model, which is specific to the TOSA Reference Backend. message(STATUS "TOSA Reference Model root set to ${TOSA_REFERENCE_MODEL_ROOT}") find_path(TOSA_REFERENCE_MODEL_INCLUDE model_runner.h HINTS ${TOSA_REFERENCE_MODEL_ROOT}/include) message(STATUS "TOSA Reference Model include directory located at: ${TOSA_REFERENCE_MODEL_INCLUDE}") include_directories(SYSTEM ${TOSA_REFERENCE_MODEL_INCLUDE}) find_library(TOSA_REFERENCE_MODEL_LIB NAMES tosa_reference_model_lib.a tosa_reference_model_lib HINTS ${TOSA_REFERENCE_MODEL_ROOT}/lib /usr/local/lib /usr/lib) message(STATUS "TOSA Reference Model set to ${TOSA_REFERENCE_MODEL_LIB}") if(TOSA_REFERENCE_MODEL_OUTPUT) add_definitions("-DTOSA_REFERENCE_MODEL_OUTPUT=1") endif() endif() # This is the root for the dynamic backend tests to search for dynamic # backends. By default it will be the project build directory. add_definitions(-DDYNAMIC_BACKEND_BUILD_DIR="${PROJECT_BINARY_DIR}") # ArmNN dynamic backend if(DYNAMIC_BACKEND_PATHS) add_definitions(-DARMNN_DYNAMIC_BACKEND_ENABLED) endif() if(SAMPLE_DYNAMIC_BACKEND) add_definitions(-DSAMPLE_DYNAMIC_BACKEND_ENABLED) endif() # Streamline annotate if(PROFILING_BACKEND_STREAMLINE) include_directories("${GATOR_ROOT}/annotate") add_definitions(-DARMNN_STREAMLINE_ENABLED) endif() if(HEAP_PROFILING OR LEAK_CHECKING) find_path(HEAP_PROFILER_INCLUDE gperftools/heap-profiler.h PATHS ${GPERFTOOLS_ROOT}/include NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) include_directories(SYSTEM "${HEAP_PROFILER_INCLUDE}") find_library(GPERF_TOOLS_LIBRARY NAMES tcmalloc_debug HINTS ${GPERFTOOLS_ROOT}/lib) link_directories(${GPERFTOOLS_ROOT}/lib) link_libraries(${GPERF_TOOLS_LIBRARY}) if (HEAP_PROFILING) add_definitions("-DARMNN_HEAP_PROFILING_ENABLED=1") endif() if (LEAK_CHECKING) add_definitions("-DARMNN_LEAK_CHECKING_ENABLED=1") endif() else() # Valgrind only works with gperftools version number <= 2.4 include(CheckIncludeFiles) CHECK_INCLUDE_FILES("valgrind/memcheck.h" VALGRIND_FOUND) endif() if(NOT BUILD_TF_LITE_PARSER) message(STATUS "Tensorflow Lite parser support is disabled") endif() if(NOT BUILD_ARMNN_SERIALIZER) message(STATUS "Armnn Serializer support is disabled") endif() if(NOT BUILD_PYTHON_WHL) message(STATUS "PyArmNN wheel package is disabled") endif() if(NOT BUILD_PYTHON_SRC) message(STATUS "PyArmNN source package is disabled") endif() if(BUILD_PYTHON_WHL OR BUILD_PYTHON_SRC) find_package(PythonInterp 3 REQUIRED) if(NOT ${PYTHONINTERP_FOUND}) message(FATAL_ERROR "Python 3.x required to build PyArmNN, but not found") endif() find_package(PythonLibs 3 REQUIRED) if(NOT ${PYTHONLIBS_FOUND}) message(FATAL_ERROR "Python 3.x development package required to build PyArmNN, but not found") endif() find_package(SWIG 4 REQUIRED) if(NOT ${SWIG_FOUND}) message(FATAL_ERROR "SWIG 4.x requried to build PyArmNN, but not found") endif() endif() # ArmNN source files required for all build options include_directories(SYSTEM third-party) armnn-23.08/cmake/OpaqueDelegateVersion.cmake000066400000000000000000000014561446772241200211750ustar00rootroot00000000000000# # Copyright © 2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Read the ArmNN Delegate version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../delegate/opaque/include/Version.hpp opaqueDelegateVersion) # Parse the ArmNN Delegate version components string(REGEX MATCH "#define OPAQUE_DELEGATE_MAJOR_VERSION ([0-9]*)" _ ${opaqueDelegateVersion}) set(OPAQUE_DELEGATE_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define OPAQUE_DELEGATE_MINOR_VERSION ([0-9]*)" _ ${opaqueDelegateVersion}) set(OPAQUE_DELEGATE_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(OPAQUE_DELEGATE_LIB_VERSION "${OPAQUE_DELEGATE_MAJOR_VERSION}.${OPAQUE_DELEGATE_MINOR_VERSION}") # Define LIB soversion set(OPAQUE_DELEGATE_LIB_SOVERSION "${OPAQUE_DELEGATE_MINOR_VERSION}")armnn-23.08/cmake/ParserVersion.cmake000066400000000000000000000026041446772241200175400ustar00rootroot00000000000000# # Copyright © 2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Read the OnnxParser version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../include/armnnOnnxParser/Version.hpp onnxVersion) # Parse the OnnxParser version components string(REGEX MATCH "#define ONNX_PARSER_MAJOR_VERSION ([0-9]*)" _ ${onnxVersion}) set(ONNX_PARSER_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define ONNX_PARSER_MINOR_VERSION ([0-9]*)" _ ${onnxVersion}) set(ONNX_PARSER_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(ONNX_PARSER_LIB_VERSION "${ONNX_PARSER_MAJOR_VERSION}.${ONNX_PARSER_MINOR_VERSION}") # Define LIB soversion set(ONNX_PARSER_LIB_SOVERSION "${ONNX_PARSER_MAJOR_VERSION}") # Read the TfLiteParser version components from file file(READ ${CMAKE_CURRENT_LIST_DIR}/../include/armnnTfLiteParser/Version.hpp tfLiteVersion) # Parse the TfLiteParser version components string(REGEX MATCH "#define TFLITE_PARSER_MAJOR_VERSION ([0-9]*)" _ ${tfLiteVersion}) set(TFLITE_PARSER_MAJOR_VERSION ${CMAKE_MATCH_1}) string(REGEX MATCH "#define TFLITE_PARSER_MINOR_VERSION ([0-9]*)" _ ${tfLiteVersion}) set(TFLITE_PARSER_MINOR_VERSION ${CMAKE_MATCH_1}) # Define LIB version set(TFLITE_PARSER_LIB_VERSION "${TFLITE_PARSER_MAJOR_VERSION}.${TFLITE_PARSER_MINOR_VERSION}") # Define LIB soversion set(TFLITE_PARSER_LIB_SOVERSION "${TFLITE_PARSER_MAJOR_VERSION}")armnn-23.08/cmake/Utils.cmake000066400000000000000000000042441446772241200160400ustar00rootroot00000000000000# # Copyright © 2018 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # # Function which creates appropriate "source groups" (filter folders in Visual Studio) for the given list of source files function(createSourceGroups source1) set(sources ${source1} ${ARGN}) foreach(source ${sources}) get_filename_component(source_path ${source} PATH) string(REPLACE "/" "\\" source_path_backslashes "${source_path}") source_group(${source_path_backslashes} FILES ${source}) endforeach() endfunction() # Further processes a target and its list of source files adding extra touches useful for some generators # (filter folders, group targets in folders, etc.). # All optional arguments are treated as additional source files. function(setup_target targetName source1) set(sources ${source1} ${ARGN}) createSourceGroups(${sources}) # Enable USE_FOLDERS. This is required by the set_target_properties(... FOLDER ...) call below. # We prefer to set it here rather than globally at the top of the file so that we only modify # the Cmake environment if/when the functionality is actually required. set_property(GLOBAL PROPERTY USE_FOLDERS ON) file(RELATIVE_PATH projectFolder ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(${targetName} PROPERTIES FOLDER "${projectFolder}") endfunction() # Convenience replacement of add_executable(), which besides adding an executable to the project # further configures the target via setup_target(). # All optional arguments are treated as additional source files. function(add_executable_ex targetName source1) set(sources ${source1} ${ARGN}) add_executable(${targetName} ${sources}) setup_target(${targetName} ${sources}) endfunction() # Convenience replacement of add_library(), which besides adding a library to the project # further configures the target via setup_target(). # All optional arguments are treated as additional source files. function(add_library_ex targetName libraryType source1) set(sources ${source1} ${ARGN}) add_library(${targetName} ${libraryType} ${sources}) setup_target(${targetName} ${sources}) endfunction() armnn-23.08/delegate/000077500000000000000000000000001446772241200144245ustar00rootroot00000000000000armnn-23.08/delegate/BuildGuideNative.md000066400000000000000000000112741446772241200201370ustar00rootroot00000000000000# Delegate Build Guide This guide assumes that Arm NN has been built with the Arm NN TF Lite Delegate with the [Arm NN Build Tool](../build-tool/README.md).
The Arm NN TF Lite Delegate can also be obtained from downloading the [Pre-Built Binaries on the GitHub homepage](../README.md). **Table of Contents:** - [Running DelegateUnitTests](#running-delegateunittests) - [Run the TF Lite Benchmark Tool](#run-the-tflite-model-benchmark-tool) - [Download the TFLite Model Benchmark Tool](#download-the-tflite-model-benchmark-tool) - [Execute the benchmarking tool with the Arm NN TF Lite Delegate](#execute-the-benchmarking-tool-with-the-arm-nn-tf-lite-delegate) - [Integrate the Arm NN TfLite Delegate into your project](#integrate-the-arm-nn-tflite-delegate-into-your-project) ## Running DelegateUnitTests To ensure that the build was successful you can run the unit tests for the delegate that can be found in the build directory for the delegate. [Doctest](https://github.com/onqtam/doctest) was used to create those tests. Using test filters you can filter out tests that your build is not configured for. In this case, we run all test suites that have `CpuAcc` in their name. ```bash cd /delegate/build ./DelegateUnitTests --test-suite=*CpuAcc* ``` If you have built for Gpu acceleration as well you might want to change your test-suite filter: ```bash ./DelegateUnitTests --test-suite=*CpuAcc*,*GpuAcc* ``` ## Run the TFLite Model Benchmark Tool The [TFLite Model Benchmark](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/benchmark) Tool has a useful command line interface to test the TF Lite Delegate. We can use this to demonstrate the use of the Arm NN TF Lite Delegate and its options. Some examples of this can be viewed in this [YouTube demonstration](https://www.youtube.com/watch?v=NResQ1kbm-M&t=920s). ### Download the TFLite Model Benchmark Tool Binary builds of the benchmarking tool for various platforms are available [here](https://www.tensorflow.org/lite/performance/measurement#native_benchmark_binary). In this example I will target an aarch64 Linux environment. I will also download a sample uint8 tflite model from the [Arm ML Model Zoo](https://github.com/ARM-software/ML-zoo). ```bash mkdir $BASEDIR/benchmarking cd $BASEDIR/benchmarking # Get the benchmarking binary. wget https://storage.googleapis.com/tensorflow-nightly-public/prod/tensorflow/release/lite/tools/nightly/latest/linux_aarch64_benchmark_model -O benchmark_model # Make it executable. chmod +x benchmark_model # and a sample model from model zoo. wget https://github.com/ARM-software/ML-zoo/blob/master/models/image_classification/mobilenet_v2_1.0_224/tflite_uint8/mobilenet_v2_1.0_224_quantized_1_default_1.tflite?raw=true -O mobilenet_v2_1.0_224_quantized_1_default_1.tflite ``` ### Execute the benchmarking tool with the Arm NN TF Lite Delegate You are already at $BASEDIR/benchmarking from the previous stage. ```bash LD_LIBRARY_PATH= ./benchmark_model --graph=mobilenet_v2_1.0_224_quantized_1_default_1.tflite --external_delegate_path="/delegate/libarmnnDelegate.so" --external_delegate_options="backends:CpuAcc;logging-severity:info" ``` The "external_delegate_options" here are specific to the Arm NN delegate. They are used to specify a target Arm NN backend or to enable/disable various options in Arm NN. A full description can be found in the parameters of function tflite_plugin_create_delegate. ## Integrate the Arm NN TfLite Delegate into your project The delegate can be integrated into your c++ project by creating a TfLite Interpreter and instructing it to use the Arm NN delegate for the graph execution. This should look similar to the following code snippet. ```objectivec // Create TfLite Interpreter std::unique_ptr armnnDelegateInterpreter; InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver()) (&armnnDelegateInterpreter) // Create the Arm NN Delegate armnnDelegate::DelegateOptions delegateOptions(backends); std::unique_ptr theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), armnnDelegate::TfLiteArmnnDelegateDelete); // Instruct the Interpreter to use the armnnDelegate armnnDelegateInterpreter->ModifyGraphWithDelegate(theArmnnDelegate.get()); ``` For further information on using TfLite Delegates please visit the [TensorFlow website](https://www.tensorflow.org/lite/guide). For more details of the kind of options you can pass to the Arm NN delegate please check the parameters of function tflite_plugin_create_delegate. armnn-23.08/delegate/BuildGuideNative.md.license000066400000000000000000000001531446772241200215520ustar00rootroot00000000000000# # Copyright © 2020-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/CMakeLists.txt000066400000000000000000000345451446772241200171770ustar00rootroot00000000000000# # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # cmake_minimum_required (VERSION 3.7.0) project(armnnDelegate) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -Werror -Wold-style-cast -Wno-missing-braces -Wconversion -Wsign-conversion -Wno-comment") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules/") option(BUILD_UNIT_TESTS "Build unit tests" ON) option(BUILD_CLASSIC_DELEGATE "Build classic delegate" ON) option(BUILD_OPAQUE_DELEGATE "Build opaque delegate" OFF) option(BUILD_SHARED_LIBS "Build share libs" ON) option(BUILD_DELEGATE_JNI_INTERFACE "Builds a library to allow accessing the Arm NN delegate from Java code. This is an experimental feature." ON) set(armnnDelegate_sources) list(APPEND armnnDelegate_sources common/include/DelegateOptions.hpp common/src/DelegateOptions.cpp common/src/DelegateUtils.hpp common/src/MultiLayerFacade.hpp) ## Add Armnn as a Dependency if(NOT ARMNN_SUB_PROJECT) find_package(Armnn REQUIRED CONFIG HINTS ${Armnn_DIR}) endif() if (BUILD_CLASSIC_DELEGATE) add_subdirectory(classic) add_library(armnnDelegate ${armnnDelegate_sources}) target_include_directories(armnnDelegate PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common/src) endif() if (BUILD_OPAQUE_DELEGATE) add_subdirectory(opaque) add_library(armnnOpaqueDelegate ${armnnDelegate_sources}) target_include_directories(armnnOpaqueDelegate PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common/src) endif() include(GNUInstallDirs) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC Armnn::Armnn) ## Add armnnClassicDelegateObject as a Dependency target_link_libraries(armnnDelegate PUBLIC armnnClassicDelegateObject) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC Armnn::Armnn) ## Add armnnOpaqueDelegateObject as a Dependency target_link_libraries(armnnOpaqueDelegate PUBLIC armnnOpaqueDelegateObject) endif() ## Add TfLite dependency find_package(TfLiteSrc REQUIRED MODULE) find_package(TfLite REQUIRED MODULE) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC ${TfLite_LIB}) # lpthread and ldl are not required for Android if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL Android) target_link_libraries(armnnDelegate PUBLIC -lpthread) target_link_libraries(armnnDelegate PUBLIC -ldl) endif() endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC ${TfLite_LIB}) # lpthread and ldl are not required for Android if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL Android) target_link_libraries(armnnOpaqueDelegate PUBLIC -lpthread) target_link_libraries(armnnOpaqueDelegate PUBLIC -ldl) endif() endif() # Add libraries from armnn third-party libraries # Third-party header files are not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(thirdparty_headers INTERFACE) target_include_directories(thirdparty_headers INTERFACE $ $) target_compile_options(thirdparty_headers INTERFACE -Wno-old-style-cast) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC thirdparty_headers) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC thirdparty_headers) endif() add_library(profiling_library_headers INTERFACE) target_include_directories(profiling_library_headers INTERFACE $ $) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC profiling_library_headers) target_link_libraries(armnnDelegate PUBLIC Armnn::armnnUtils) set_target_properties(armnnDelegate PROPERTIES VERSION ${DELEGATE_LIB_VERSION} SOVERSION ${DELEGATE_LIB_SOVERSION}) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC profiling_library_headers) target_link_libraries(armnnOpaqueDelegate PUBLIC Armnn::armnnUtils) set_target_properties(armnnOpaqueDelegate PROPERTIES VERSION ${OPAQUE_DELEGATE_LIB_VERSION} SOVERSION ${OPAQUE_DELEGATE_LIB_SOVERSION}) endif() if(BUILD_UNIT_TESTS) set(commonDelegate_unittest_sources) list(APPEND commonDelegate_unittest_sources common/src/test/DelegateTestInterpreter.hpp common/src/test/DelegateTestInterpreterUtils.hpp test/ActivationTest.cpp test/ActivationTestHelper.hpp test/ArgMinMaxTest.cpp test/ArgMinMaxTestHelper.hpp test/BatchMatMulTest.cpp test/BatchMatMulTestHelper.hpp test/BatchSpaceTest.cpp test/BatchSpaceTestHelper.hpp test/CastTest.cpp test/CastTestHelper.hpp test/ComparisonTest.cpp test/ComparisonTestHelper.hpp test/ControlTest.cpp test/ControlTestHelper.hpp test/Convolution2dTest.cpp test/Convolution3dTest.cpp test/ConvolutionTestHelper.hpp test/DepthwiseConvolution2dTest.cpp test/ElementwiseBinaryTest.cpp test/ElementwiseBinaryTestHelper.hpp test/ElementwiseUnaryTest.cpp test/ElementwiseUnaryTestHelper.hpp test/ExpandDimsTest.cpp test/FillTest.cpp test/FillTestHelper.hpp test/FullyConnectedTest.cpp test/FullyConnectedTestHelper.hpp test/GatherTest.cpp test/GatherTestHelper.hpp test/GatherNdTest.cpp test/GatherNdTestHelper.hpp test/LogicalTest.cpp test/LogicalTestHelper.hpp test/LstmTest.cpp test/LstmTestHelper.hpp test/MirrorPadTest.cpp test/NormalizationTest.cpp test/NormalizationTestHelper.hpp test/PackTest.cpp test/PackTestHelper.hpp test/PadTest.cpp test/PadTestHelper.hpp test/Pooling2dTest.cpp test/Pooling2dTestHelper.hpp test/Pooling3dTest.cpp test/Pooling3dTestHelper.hpp test/PreluTest.cpp test/PreluTestHelper.hpp test/QuantizationTest.cpp test/QuantizationTestHelper.hpp test/RedefineTestHelper.hpp test/ReduceTest.cpp test/ReduceTestHelper.hpp test/ReshapeTest.cpp test/ResizeTest.cpp test/ResizeTestHelper.hpp test/ReverseV2Test.cpp test/ReverseV2TestHelper.hpp test/RoundTest.cpp test/RoundTestHelper.hpp test/SoftmaxTest.cpp test/SoftmaxTestHelper.hpp test/SpaceDepthTest.cpp test/SpaceDepthTestHelper.hpp test/ShapeTest.cpp test/ShapeTestHelper.hpp test/SliceTest.cpp test/SliceTestHelper.hpp test/SqueezeTest.cpp test/StridedSliceTest.cpp test/StridedSliceTestHelper.hpp test/SplitTest.cpp test/SplitTestHelper.hpp test/TestUtils.hpp test/TestUtils.cpp test/TileTest.cpp test/TileTestHelper.hpp test/TransposeConvolution2dTest.cpp test/TransposeTest.cpp test/TransposeTestHelper.hpp test/UnidirectionalSequenceLstmTest.cpp test/UnidirectionalSequenceLstmTestHelper.hpp test/UnpackTest.cpp test/UnpackTestHelper.hpp) # There's a known Android NDK bug which causes a subset of NeonLayerTests to # fail. We'll exclude these tests in NeonLayerTests_NDK_Bug.cpp if we're doing # a debug build and NDK is less than r21. # https://github.com/android/ndk/issues/1135 # Default to always including these tests. set(INCLUDE_NDK_BUG_TESTS "ON") # Reconsider if we in a debug build. string( TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE_LOWERCASE ) if ( NOT BUILD_TYPE_LOWERCASE STREQUAL "release" ) message("CMAKE:: BUILD TYPE IS ${CMAKE_BUILD_TYPE}") # And NDK_VERSION has been set. if ( DEFINED NDK_VERSION ) message("CMAKE:: NDK DEFINED") # And the version is less than r21. if ( ${NDK_VERSION} STRLESS "r21" ) message("CMAKE:: BUG TESTS OFF") set(INCLUDE_NDK_BUG_TESTS "OFF") endif() endif() endif() if ( INCLUDE_NDK_BUG_TESTS STREQUAL "ON" ) list(APPEND commonDelegate_unittest_sources test/NeonDelegateTests_NDK_Issue.cpp) endif() if (BUILD_CLASSIC_DELEGATE) set(classicDelegate_unittest_sources) list(APPEND classicDelegate_unittest_sources classic/src/test/ArmnnClassicDelegateTest.cpp classic/src/test/DelegateTestInterpreter.cpp test/DelegateOptionsTest.cpp test/DelegateOptionsTestHelper.hpp) add_executable(DelegateUnitTests ${commonDelegate_unittest_sources} ${classicDelegate_unittest_sources}) target_include_directories(DelegateUnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}") target_include_directories(DelegateUnitTests SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common/src/test") target_include_directories(DelegateUnitTests PUBLIC ${PROJECT_SOURCE_DIR}) # Add half library from armnn third-party libraries target_link_libraries(DelegateUnitTests PRIVATE thirdparty_headers) target_link_libraries(DelegateUnitTests PRIVATE armnnDelegate) target_link_libraries(DelegateUnitTests PRIVATE Armnn::armnnUtils) target_link_libraries(DelegateUnitTests PRIVATE profiling_library_headers) endif() if (BUILD_OPAQUE_DELEGATE) set(opaqueDelegate_unittest_sources) list(APPEND opaqueDelegate_unittest_sources opaque/src/test/ArmnnOpaqueDelegateTest.cpp opaque/src/test/DelegateTestInterpreter.cpp) # Until all operators are supported, we have to add tests one by one above to opaqueDelegate_unittest_sources. # After we add can add commonDelegate_unittest_sources to the add_executable below. add_executable(OpaqueDelegateUnitTests ${opaqueDelegate_unittest_sources} ${commonDelegate_unittest_sources}) target_include_directories(OpaqueDelegateUnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}") target_include_directories(OpaqueDelegateUnitTests SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common/src/test") target_include_directories(OpaqueDelegateUnitTests PUBLIC ${PROJECT_SOURCE_DIR}) # Add half library from armnn third-party libraries target_link_libraries(OpaqueDelegateUnitTests PRIVATE thirdparty_headers) target_link_libraries(OpaqueDelegateUnitTests PRIVATE armnnOpaqueDelegate) target_link_libraries(OpaqueDelegateUnitTests PRIVATE Armnn::armnnUtils) target_link_libraries(OpaqueDelegateUnitTests PRIVATE profiling_library_headers) endif() endif() if(BUILD_DELEGATE_JNI_INTERFACE AND BUILD_CLASSIC_DELEGATE) add_subdirectory(armnnDelegateJNI) endif() #################################################### ## Export targets if (BUILD_CLASSIC_DELEGATE) set(armnn_delegate_export_targets) list(APPEND armnn_delegate_export_targets armnnClassicDelegateObject armnnDelegate tflite_headers flatbuffer_headers profiling_library_headers thirdparty_headers) install( TARGETS ${armnn_delegate_export_targets} EXPORT armnn-delegate-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ## Set export alias set_target_properties(armnnDelegate PROPERTIES EXPORT_NAME ArmnnDelegate) ## Export target scrips install( EXPORT armnn-delegate-targets FILE ArmnnDelegateTargets.cmake NAMESPACE ArmnnDelegate:: DESTINATION ${CMAKE_INSTALL_LIBDIR}) ## Create ArmnnDelegateConfig.cmake include(CMakePackageConfigHelpers) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}) message(STATUS "CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}" ) message(STATUS "CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}" ) SET(Armnn_DIR "${Armnn_DIR}") configure_package_config_file( ${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/ArmnnDelegateConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateConfig.cmake INSTALL_DESTINATION ${INSTALL_CONFIGDIR} PATH_VARS Armnn_DIR) ## Install ArmNN Delegate config file install( FILES ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateConfig.cmake DESTINATION ${INSTALL_CONFIGDIR}) ## Export from build tree export( EXPORT armnn-delegate-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateTargets.cmake NAMESPACE ArmnnDelegate::) add_library(ArmnnDelegate::ArmnnDelegate ALIAS armnnDelegate) endif() #################################################### ## Export opaque delegate targets if(BUILD_OPAQUE_DELEGATE) set(armnn_opaque_delegate_export_targets) list(APPEND armnn_opaque_delegate_export_targets armnnOpaqueDelegateObject armnnOpaqueDelegate tflite_headers flatbuffer_headers profiling_library_headers thirdparty_headers) install( TARGETS armnnOpaqueDelegate EXPORT armnn-opaque-delegate-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ## Set export alias set_target_properties(armnnOpaqueDelegate PROPERTIES EXPORT_NAME ArmnnOpaqueDelegate) add_library(ArmnnDelegate::ArmnnOpaqueDelegate ALIAS armnnOpaqueDelegate) endif() ####################################################armnn-23.08/delegate/DelegateQuickStartGuide.md000066400000000000000000000126251446772241200214570ustar00rootroot00000000000000# TfLite Delegate Quick Start Guide If you have downloaded the Arm NN Github binaries or built the TfLite delegate yourself, then this tutorial will show you how you can integrate it into TfLite to run models using python. Here is an example python script showing how to do this. In this script we are making use of the [external adaptor](https://www.tensorflow.org/lite/performance/implementing_delegate#option_2_leverage_external_delegate) tool of TfLite that allows you to load delegates at runtime. ```python import numpy as np import tflite_runtime.interpreter as tflite # Load TFLite model and allocate tensors. # (if you are using the complete tensorflow package you can find load_delegate in tf.experimental.load_delegate) armnn_delegate = tflite.load_delegate( library="/libarmnnDelegate.so", options={"backends": "CpuAcc,GpuAcc,CpuRef", "logging-severity":"info"}) # Delegates/Executes all operations supported by Arm NN to/with Arm NN interpreter = tflite.Interpreter(model_path="/delegate/python/test/test_data/mock_model.tflite", experimental_delegates=[armnn_delegate]) interpreter.allocate_tensors() # Get input and output tensors. input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # Test model on random input data. input_shape = input_details[0]['shape'] input_data = np.array(np.random.random_sample(input_shape), dtype=np.uint8) interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() # Print out result output_data = interpreter.get_tensor(output_details[0]['index']) print(output_data) ``` # Prepare the environment Pre-requisites: * Dynamically build Arm NN Delegate library or download the Arm NN binaries (built with a particular SHA of Tensorflow 2.12.0, which is 6f692f73cb2043b4a0b0446539cd8c15b3dd9220) * python3 (Depends on TfLite version) * virtualenv * numpy (Depends on TfLite version) * tflite_runtime (2.12 currently available) If you haven't built the delegate yet then take a look at the [build guide](./BuildGuideNative.md). Otherwise, you can download the binaries [here](https://github.com/ARM-software/armnn/releases/). Set the following environment variable to the location of the .so binary files: ```bash export LD_LIBRARY_PATH= ``` We recommend creating a virtual environment for this tutorial. For the following code to work python3 is needed. Please also check the documentation of the TfLite version you want to use. There might be additional prerequisites for the python version. We will use Tensorflow Lite 2.12.0 for this guide. ```bash # Install python3 (We ended up with python3.5.3) and virtualenv sudo apt-get install python3-pip sudo pip3 install virtualenv # create a virtual environment cd your/tutorial/dir # creates a directory myenv at the current location virtualenv -p python3 myenv # activate the environment source myenv/bin/activate ``` Now that the environment is active we can install additional packages we need for our example script. As you can see in the python script at the start of this page, this tutorial uses the `tflite_runtime` rather than the whole tensorflow package. The `tflite_runtime` is a package that wraps the TfLite Interpreter. Therefore it can only be used to run inferences of TfLite models. But since Arm NN is only an inference engine itself this is a perfect match. The `tflite_runtime` is also much smaller than the whole tensorflow package and better suited to run models on mobile and embedded devices. The TfLite [website](https://www.tensorflow.org/lite/guide/python) shows you two methods to download the `tflite_runtime` package. In our experience, the use of the pip command works for most systems including debian. However, if you're using an older version of Tensorflow, you may need to build the pip package from source. You can find more information [here](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/tools/pip_package/README.md). But in our case, with Tensorflow Lite 2.12.0, we can install through: ``` pip3 install --extra-index-url https://google-coral.github.io/py-repo/ tflite_runtime==2.12.0 ``` Your virtual environment is now all setup. Copy the final python script into a python file e.g. `ExternalDelegatePythonTutorial.py`. Modify the python script above and replace `` and `` with the directories you have set up. If you've been using the [native build guide](./BuildGuideNative.md) this will be `$BASEDIR/armnn/build` and `$BASEDIR/armnn`. Finally, execute the script: ```bash python ExternalDelegatePythonTutorial.py ``` The output should look similar to this: ```bash Info: Arm NN v32.1.0 Info: Initialization time: 0.56 ms INFO: TfLiteArmnnDelegate: Created TfLite Arm NN delegate. [[ 12 123 16 12 11 14 20 16 20 12]] Info: Shutdown time: 0.28 ms ``` For more details of the kind of options you can pass to the Arm NN delegate please check the parameters of function tflite_plugin_create_delegate. You can also test the functionality of the external delegate adaptor by running some unit tests: ```bash pip install pytest cd armnn/delegate/python/test # You can deselect tests that require backends that your hardware doesn't support using markers e.g. -m "not GpuAccTest" pytest --delegate-dir="/libarmnnDelegate.so" -m "not GpuAccTest" ``` armnn-23.08/delegate/DelegateQuickStartGuide.md.license000066400000000000000000000001541446772241200230720ustar00rootroot00000000000000# # Copyright © 2020, 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/README.md000066400000000000000000000006471446772241200157120ustar00rootroot00000000000000# The Arm NN TensorFlow Lite delegate 'armnnDelegate' is a library for accelerating certain TensorFlow Lite operators on Arm hardware by providing the TensorFlow Lite interpreter with an alternative implementation of the operators via its delegation mechanism. For more information, like a list of supported operators, please visit our [doxygen documentation](https://arm-software.github.io/armnn/latest/delegate.xhtml). armnn-23.08/delegate/README.md.license000066400000000000000000000001531446772241200173230ustar00rootroot00000000000000# # Copyright © 2020-2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/armnnDelegateJNI/000077500000000000000000000000001446772241200175335ustar00rootroot00000000000000armnn-23.08/delegate/armnnDelegateJNI/CMakeLists.txt000066400000000000000000000040711446772241200222750ustar00rootroot00000000000000# # Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # cmake_minimum_required(VERSION 3.7.0) project("armnn_delegate_jni") # JNI is needed for jni calls find_package(JNI) list(APPEND jni_delegate_sources src/armnn_delegate_jni.cpp) # the backends under src/backends extend the list of # object libs armnn to include in the build # If armnn is a static library (which it should be to make armnn_delegate_jni a stand alone library) then # the object libraries of the backends need to be linked manually include(${ARMNN_SOURCE_DIR}/src/backends/backends.cmake) foreach(lib ${armnnLibraries}) message(STATUS "Adding object library dependency to armnn_delegate_jni: ${lib}") list(APPEND jni_delegate_sources $) endforeach() if (JNI_FOUND) message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}") message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}") else() message (FATAL_ERROR "JNI library could not be found") endif() include_directories(${JNI_INCLUDE_DIRS}) add_library(armnn_delegate_jni SHARED ${jni_delegate_sources}) target_link_libraries(armnn_delegate_jni PRIVATE Armnn::Armnn ArmnnDelegate::ArmnnDelegate ) # A version script is used to hide all symbols that are not required to use the jni interface # This is mostly required to avoid symbol conflicts between libc++_shared used to compile armnn # and an eventual other version used somewhere else: https://developer.android.com/ndk/guides/cpp-support # This also requires to tell the compiler to link to the static version of libc++_shared. This can be accomplished # by adding -DCMAKE_ANDROID_STL_TYPE=c++_static to the cmake command when building for android set(version_script "${CMAKE_CURRENT_SOURCE_DIR}/version_script") # Generate a map file for debug mode only set_property(TARGET armnn_delegate_jni APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${version_script},-Map=mapfile.map") set_target_properties(armnn_delegate_jni PROPERTIES LINK_DEPENDS ${version_script}) armnn-23.08/delegate/armnnDelegateJNI/README.md000066400000000000000000000017201446772241200210120ustar00rootroot00000000000000# The Arm NN TensorFlow Lite delegate JNI (Experimental) NOTE: This library is an experimental feature. We cannot guarentee full support for this. 'armnnDelegateJNI' is a library for accelerating certain TensorFlow Lite operators on Arm hardware specifically through Android applications. Each release is packaged in an AAR which can be found on Maven Central. The pre-built library contains the ArmNN Core, ArmNN Utils, Neon backend, CL Backend, and the ArmNN Delegate. It is essential to only build these. The backends you choose are optional. It requires a static build which can be switched on through setting BUILD_SHARED_LIBS=OFF. You will also have to set CMAKE_ANDROID_STL_TYPE=c++_static when building ArmNN. BUILD_DELEGATE_JNI_INTERFACE will also have to be set to true. To download the prebuilt ArmNN Delegate JNI AAR from Maven Central, please go to [ArmNN Maven Central Release Page](https://search.maven.org/artifact/io.github.arm-software/armnn.delegate). armnn-23.08/delegate/armnnDelegateJNI/README.md.license000066400000000000000000000001451446772241200224330ustar00rootroot00000000000000# # Copyright © 2022 ARM Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT #armnn-23.08/delegate/armnnDelegateJNI/src/000077500000000000000000000000001446772241200203225ustar00rootroot00000000000000armnn-23.08/delegate/armnnDelegateJNI/src/armnn_delegate_jni.cpp000066400000000000000000000066641446772241200246470ustar00rootroot00000000000000// // Copyright © 2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #if defined(ARMCOMPUTECL_ENABLED) #include #endif #include #include extern "C" { /// Creates an Arm NN Delegate object. /// Options are passed in form of String arrays. For details about what options_keys and option_values /// are supported please see: // armnnDelegate::DelegateOptions::DelegateOptions(char const* const*, char const* const*,size_t,void (*)(const char*)) JNIEXPORT jlong JNICALL Java_com_arm_armnn_delegate_ArmnnDelegate_createDelegate(JNIEnv* env, jclass clazz, jobjectArray optionKeys, jobjectArray optionValues) { int numOptions = env->GetArrayLength(optionKeys); const char* nativeOptionKeys[numOptions]; const char* nativeOptionValues[numOptions]; jstring jKeyStrings[numOptions]; jstring jValueStrings[numOptions]; // Convert java array of string into char so we can make use of it in cpp code for (int i = 0; i < numOptions; i++) { jKeyStrings[i] = static_cast(env->GetObjectArrayElement(optionKeys, i)); jValueStrings[i] = static_cast(env->GetObjectArrayElement(optionValues, i)); nativeOptionKeys[i] = env->GetStringUTFChars(jKeyStrings[i], 0); nativeOptionValues[i] = env->GetStringUTFChars(jValueStrings[i], 0); } armnnDelegate::DelegateOptions delegateOptions(nativeOptionKeys, nativeOptionValues, numOptions, nullptr); // Release jni memory. After the delegate options are created there is no need to hold on to it anymore. for (int i = 0; i < numOptions; i++) { env->ReleaseStringUTFChars(jKeyStrings[i], nativeOptionKeys[i]); env->ReleaseStringUTFChars(jValueStrings[i], nativeOptionValues[i]); } return reinterpret_cast(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions)); } /// Destroys a given Arm NN Delegate object JNIEXPORT void JNICALL Java_com_arm_armnn_delegate_ArmnnDelegate_deleteDelegate(JNIEnv* env, jclass clazz, jlong delegate) { armnnDelegate::TfLiteArmnnDelegateDelete(reinterpret_cast(delegate)); } /// Returns true if a Arm Mali GPU is detected. /// Can be used to ensure that GpuAcc is supported on a device. JNIEXPORT jboolean JNICALL Java_com_arm_armnn_delegate_ArmnnUtils_IsGpuAccSupported(JNIEnv* env, jclass clazz) { #if defined(ARMCOMPUTECL_ENABLED) cl::Device device = cl::Device::getDefault(); char device_name[32]; cl_int err = clGetDeviceInfo(device.get(), CL_DEVICE_NAME, sizeof(device_name), &device_name, NULL); if (err != CL_SUCCESS) { return false; } // search for "Mali" in the devices name if (strstr(device_name, "Mali")) { return true; } #endif return false; } /// Returns true if the current device supports Neon instructions. /// Can be used to ensure the CpuAcc backend is supported. JNIEXPORT jboolean JNICALL Java_com_arm_armnn_delegate_ArmnnUtils_IsNeonDetected(JNIEnv* env, jclass clazz) { return armnn::NeonDetected(); } } armnn-23.08/delegate/armnnDelegateJNI/version_script000066400000000000000000000006151446772241200225310ustar00rootroot00000000000000/* Copyright © 2022 Arm Ltd and Contributors. All rights reserved. SPDX-License-Identifier: MIT */ LIBARMNN_DELEGATE_JNI { global: Java_com_arm_armnn_delegate_ArmnnDelegate_createDelegate; Java_com_arm_armnn_delegate_ArmnnDelegate_deleteDelegate; Java_com_arm_armnn_delegate_ArmnnUtils_IsGpuAccSupported; Java_com_arm_armnn_delegate_ArmnnUtils_IsNeonDetected; local: *; };armnn-23.08/delegate/classic/000077500000000000000000000000001446772241200160455ustar00rootroot00000000000000armnn-23.08/delegate/classic/CMakeLists.txt000066400000000000000000000065261446772241200206160ustar00rootroot00000000000000# # Copyright © 2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # set(armnnClassicDelegateObject_sources) list(APPEND armnnClassicDelegateObject_sources include/armnn_delegate.hpp include/Version.hpp src/armnn_delegate.cpp src/armnn_external_delegate.cpp src/Activation.hpp src/ArgMinMax.hpp src/BatchMatMul.hpp src/BatchSpace.hpp src/ClassicDelegateUtils.hpp src/Comparison.hpp src/Convolution.hpp src/Control.hpp src/ElementwiseBinary.hpp src/ElementwiseUnary.hpp src/Fill.hpp src/FullyConnected.hpp src/Gather.hpp src/GatherNd.hpp src/LogicalBinary.hpp src/Lstm.hpp src/Normalization.hpp src/Pack.hpp src/Pad.hpp src/Pooling.hpp src/Prelu.hpp src/Quantization.hpp src/Redefine.hpp src/Reduce.hpp src/Resize.hpp src/ReverseV2.hpp src/Round.hpp src/Shape.hpp src/SharedFunctions.hpp src/SharedFunctions.cpp src/Slice.hpp src/Softmax.hpp src/SpaceDepth.hpp src/Split.hpp src/Unpack.hpp src/Tile.hpp src/Transpose.hpp) add_library(armnnClassicDelegateObject OBJECT ${armnnClassicDelegateObject_sources}) target_include_directories(armnnClassicDelegateObject PUBLIC $ $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/common/src) ## Add Tflite dependency if(NOT TfLite_INCLUDE_DIR OR NOT TfLite_Schema_INCLUDE_PATH) find_package(TfLiteSrc REQUIRED MODULE) endif() # Various tflite header files are not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(tflite_headers INTERFACE) target_include_directories(tflite_headers INTERFACE $ $) target_compile_options(tflite_headers INTERFACE -Wno-conversion -Wno-sign-conversion -Wno-unused-parameter -Wno-unused-function) target_link_libraries(armnnClassicDelegateObject PUBLIC tflite_headers) ## Add Flatbuffers dependency find_package(Flatbuffers REQUIRED MODULE) target_link_libraries(armnnClassicDelegateObject PRIVATE ${Flatbuffers_LIB}) # include/flatbuffers/flatbuffers.h is not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(flatbuffer_headers INTERFACE) target_include_directories(flatbuffer_headers INTERFACE $ $) target_compile_options(flatbuffer_headers INTERFACE -Wno-sign-conversion) target_link_libraries(armnnClassicDelegateObject PUBLIC flatbuffer_headers) #################################################### ## Export targets install(TARGETS armnnClassicDelegateObject LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})armnn-23.08/delegate/classic/include/000077500000000000000000000000001446772241200174705ustar00rootroot00000000000000armnn-23.08/delegate/classic/include/Version.hpp000066400000000000000000000013541446772241200216310ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once namespace armnnDelegate { /// Macro utils #define STRINGIFY_VALUE(s) STRINGIFY_MACRO(s) #define STRINGIFY_MACRO(s) #s // ArmNN Delegate version components #define DELEGATE_MAJOR_VERSION 29 #define DELEGATE_MINOR_VERSION 0 #define DELEGATE_PATCH_VERSION 0 /// DELEGATE_VERSION: "X.Y.Z" /// where: /// X = Major version number /// Y = Minor version number /// Z = Patch version number #define DELEGATE_VERSION STRINGIFY_VALUE(DELEGATE_MAJOR_VERSION) "." \ STRINGIFY_VALUE(DELEGATE_MINOR_VERSION) "." \ STRINGIFY_VALUE(DELEGATE_PATCH_VERSION) } //namespace armnnDelegatearmnn-23.08/delegate/classic/include/armnn_delegate.hpp000066400000000000000000000112771446772241200231560ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #if TF_MAJOR_VERSION > 2 || (TF_MAJOR_VERSION == 2 && TF_MINOR_VERSION > 3) #define ARMNN_POST_TFLITE_2_3 #endif #if TF_MAJOR_VERSION > 2 || (TF_MAJOR_VERSION == 2 && TF_MINOR_VERSION > 4) #define ARMNN_POST_TFLITE_2_4 #endif #if TF_MAJOR_VERSION > 2 || (TF_MAJOR_VERSION == 2 && TF_MINOR_VERSION > 5) #define ARMNN_POST_TFLITE_2_5 #endif namespace armnnDelegate { struct DelegateData { DelegateData(const std::vector& backends) : m_Backends(backends) , m_Network(nullptr, nullptr) {} const std::vector m_Backends; armnn::INetworkPtr m_Network; std::vector m_OutputSlotForNode; }; // Forward decleration for functions initializing the ArmNN Delegate DelegateOptions TfLiteArmnnDelegateOptionsDefault(); TfLiteDelegate* TfLiteArmnnDelegateCreate(armnnDelegate::DelegateOptions options); void TfLiteArmnnDelegateDelete(TfLiteDelegate* tfLiteDelegate); TfLiteStatus DoPrepare(TfLiteContext* context, TfLiteDelegate* delegate); /// ArmNN Delegate class Delegate { friend class ArmnnSubgraph; public: explicit Delegate(armnnDelegate::DelegateOptions options); TfLiteIntArray* IdentifyOperatorsToDelegate(TfLiteContext* context); TfLiteDelegate* GetDelegate(); /// Retrieve version in X.Y.Z form static const std::string GetVersion(); private: /** * Returns a pointer to the armnn::IRuntime* this will be shared by all armnn_delegates. */ armnn::IRuntime* GetRuntime(const armnn::IRuntime::CreationOptions& options) { static armnn::IRuntimePtr instance = armnn::IRuntime::Create(options); // Instantiated on first use. return instance.get(); } TfLiteDelegate m_Delegate = { reinterpret_cast(this), // .data_ DoPrepare, // .Prepare nullptr, // .CopyFromBufferHandle nullptr, // .CopyToBufferHandle nullptr, // .FreeBufferHandle kTfLiteDelegateFlagsNone, // .flags nullptr, // .opaque_delegate_builder }; /// ArmNN Runtime pointer armnn::IRuntime* m_Runtime; /// ArmNN Delegate Options armnnDelegate::DelegateOptions m_Options; }; /// ArmnnSubgraph class where parsing the nodes to ArmNN format and creating the ArmNN Graph class ArmnnSubgraph { public: static ArmnnSubgraph* Create(TfLiteContext* tfLiteContext, const TfLiteDelegateParams* parameters, const Delegate* delegate); TfLiteStatus Prepare(TfLiteContext* tfLiteContext); TfLiteStatus Invoke(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode); static TfLiteStatus VisitNode(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteRegistration* tfLiteRegistration, TfLiteNode* tfLiteNode, int nodeIndex); private: ArmnnSubgraph(armnn::NetworkId networkId, armnn::IRuntime* runtime, std::vector& inputBindings, std::vector& outputBindings) : m_NetworkId(networkId), m_Runtime(runtime), m_InputBindings(inputBindings), m_OutputBindings(outputBindings) {} static TfLiteStatus AddInputLayer(DelegateData& delegateData, TfLiteContext* tfLiteContext, const TfLiteIntArray* inputs, std::vector& inputBindings); static TfLiteStatus AddOutputLayer(DelegateData& delegateData, TfLiteContext* tfLiteContext, const TfLiteIntArray* outputs, std::vector& outputBindings); /// The Network Id armnn::NetworkId m_NetworkId; /// ArmNN Runtime armnn::IRuntime* m_Runtime; // Binding information for inputs and outputs std::vector m_InputBindings; std::vector m_OutputBindings; }; } // armnnDelegate namespacearmnn-23.08/delegate/classic/src/000077500000000000000000000000001446772241200166345ustar00rootroot00000000000000armnn-23.08/delegate/classic/src/Activation.hpp000066400000000000000000000122471446772241200214540ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateActivationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, armnn::ActivationDescriptor& activationDesc) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, activationDesc); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitActivationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::ActivationDescriptor activationDesc; switch(operatorCode) { case kTfLiteBuiltinRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } case kTfLiteBuiltinRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; break; } case kTfLiteBuiltinLogistic: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteBuiltinTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } case kTfLiteBuiltinElu: { activationDesc.m_Function = armnn::ActivationFunction::Elu; activationDesc.m_A = 1.0f; break; } case kTfLiteBuiltinHardSwish: { activationDesc.m_Function = armnn::ActivationFunction::HardSwish; break; } case kTfLiteBuiltinLeakyRelu: { // Get the alpha param from builtin data auto* leakyReluParameters = reinterpret_cast(tfLiteNode->builtin_data); activationDesc.m_Function = armnn::ActivationFunction::LeakyReLu; activationDesc.m_A = leakyReluParameters->alpha; break; } default: { return kTfLiteError; } } if (!delegateData.m_Network) { return ValidateActivationOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, activationDesc); } auto layerName = GetLayerName(activationDesc.m_Function, nodeIndex); armnn::IConnectableLayer* activationLayer = delegateData.m_Network->AddActivationLayer(activationDesc, layerName.c_str()); ARMNN_ASSERT(activationLayer != nullptr); armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(activationLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(activationLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/ArgMinMax.hpp000066400000000000000000000120021446772241200211630ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitArgMinMaxOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t argMinMaxOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Get const axis value from model and set it to descriptor. const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteAxisTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::ArgMinMaxDescriptor desc; // Get the axis value from the input tensor switch (tfLiteAxisTensor.type) { case kTfLiteInt32: case kTfLiteInt64: desc.m_Axis = tflite::GetTensorData(&tfLiteAxisTensor)[0]; break; default: TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Axis value data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } // If output_type is int32 then set Signed32 else Signed64. Default type is Signed64. if (argMinMaxOperatorCode == kTfLiteBuiltinArgMax) { desc.m_Function = armnn::ArgMinMaxFunction::Max; auto* argMaxParameters = reinterpret_cast(tfLiteNode->builtin_data); if (argMaxParameters->output_type != kTfLiteInt32 && argMaxParameters->output_type != kTfLiteInt64) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: output_type data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } } else { desc.m_Function = armnn::ArgMinMaxFunction::Min; auto* argMinParameters = reinterpret_cast(tfLiteNode->builtin_data); if (argMinParameters->output_type != kTfLiteInt32 && argMinParameters->output_type != kTfLiteInt64) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: output_type data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ARGMINMAX", tfLiteContext, IsArgMinMaxSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add an ArgMinMax layer auto layerName = GetLayerName(desc.m_Function, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddArgMinMaxLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/BatchMatMul.hpp000066400000000000000000000106631446772241200215140ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitBatchMatMulOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& kTfLiteLHSInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; const TfLiteTensor& kTfLiteRHSInputTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, kTfLiteLHSInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } if (!IsValid(tfLiteContext, kTfLiteRHSInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } if (IsDynamicTensor(kTfLiteLHSInputTensor) || IsDynamicTensor(kTfLiteRHSInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& kTfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(kTfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& armnnLHSInputTensorInfo = GetTensorInfoForTfLiteTensor(kTfLiteLHSInputTensor); const armnn::TensorInfo& armnnRHSInputTensorInfo = GetTensorInfoForTfLiteTensor(kTfLiteRHSInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(kTfLiteOutputTensor, true); armnn::BatchMatMulDescriptor descriptor; auto* params = reinterpret_cast(tfLiteNode->builtin_data); // Tensorflow params are called adjoint, however they are actually just transposes behind the scene. They do // not perform ajoint. descriptor.m_TransposeX = params->adj_x; descriptor.m_TransposeY = params->adj_y; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("BATCH_MATMUL", tfLiteContext, IsBatchMatMulSupported, delegateData.m_Backends, isSupported, setBackend, armnnLHSInputTensorInfo, armnnRHSInputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::BatchMatMul, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchMatMulLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/BatchSpace.hpp000066400000000000000000000215321446772241200213450ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitBatchToSpaceNdOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteBlockShapeTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteBlockShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteCropsTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteCropsTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& blockShapeTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBlockShapeTensor); const armnn::TensorInfo& cropsTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteCropsTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); std::vector blockShape(blockShapeTensorInfo.GetNumElements()); ::memcpy(blockShape.data(), tfLiteBlockShapeTensor.data.data, blockShapeTensorInfo.GetNumBytes()); std::vector cropsVector(cropsTensorInfo.GetNumElements()); std::memcpy(cropsVector.data(), tfLiteCropsTensor.data.data, cropsTensorInfo.GetNumBytes()); size_t step = 2; std::vector> crops; for (unsigned int i = 0; i < cropsTensorInfo.GetNumElements() / step; ++i) { crops.emplace_back(cropsVector[i * step], cropsVector[i * step + 1]); } armnn::BatchToSpaceNdDescriptor descriptor; descriptor.m_BlockShape = blockShape; descriptor.m_Crops = crops; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("BATCH_TO_SPACE_ND", tfLiteContext, IsBatchToSpaceNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitBatchToSpaceNdOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a BatchToSpace layer auto layerName = GetLayerName(armnn::LayerType::BatchToSpaceNd, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchToSpaceNdLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitSpaceToBatchNdOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteBlockShapeTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteBlockShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLitePadListTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLitePadListTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& blockShapeTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBlockShapeTensor); const armnn::TensorInfo& padListTensorInfo = GetTensorInfoForTfLiteTensor(tfLitePadListTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); std::vector blockShape(blockShapeTensorInfo.GetNumElements()); std::memcpy(blockShape.data(), tfLiteBlockShapeTensor.data.data, blockShapeTensorInfo.GetNumBytes()); std::vector padListVector(padListTensorInfo.GetNumElements()); std::memcpy(padListVector.data(), tfLitePadListTensor.data.data, padListTensorInfo.GetNumBytes()); size_t step = 2; std::vector> padList; for (unsigned int i = 0; i < padListTensorInfo.GetNumElements() / step; ++i) { padList.emplace_back(padListVector[i * step], padListVector[i * step + 1]); } armnn::SpaceToBatchNdDescriptor descriptor; descriptor.m_BlockShape = blockShape; descriptor.m_PadList = padList; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SPACE_TO_BATCH_ND", tfLiteContext, IsSpaceToBatchNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitSpaceToBatchNdOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a SpaceToBatch layer armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToBatchNdLayer(descriptor); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/ClassicDelegateUtils.hpp000066400000000000000000000503151446772241200234060ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { // Macro to call an IsSupported function and log caller name together with reason for lack of support #define FORWARD_LAYER_SUPPORT_FUNC(opName, tfLiteContext, func, backends, supported, setBackend, ...) \ try \ { \ for (auto&& backendId : backends) \ { \ auto layerSupportObject = armnn::GetILayerSupportByBackendId(backendId); \ if (layerSupportObject.IsBackendRegistered()) \ { \ std::string reasonIfUnsupported; \ supported = \ layerSupportObject.func(__VA_ARGS__, armnn::Optional(reasonIfUnsupported)); \ if (supported) \ { \ setBackend = backendId; \ break; \ } \ else \ { \ if (reasonIfUnsupported.size() > 0) \ { \ TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \ "%s: not supported by armnn: %s", opName, reasonIfUnsupported.c_str()); \ } \ else \ { \ TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \ "%s: not supported by armnn", opName); \ } \ } \ } \ else \ { \ TF_LITE_KERNEL_LOG(tfLiteContext, "%s: backend not registered: %s", opName, backendId.Get().c_str()); \ } \ } \ if (!supported) \ { \ TF_LITE_KERNEL_LOG(tfLiteContext, "%s: not supported by any specified backend", opName); \ } \ } \ catch (const armnn::InvalidArgumentException &e) \ { \ throw armnn::InvalidArgumentException(e, "Failed to check layer support", CHECK_LOCATION()); \ } std::string GetLayerName(armnn::ActivationFunction function, int nodeIndex) { return fmt::format("{}:{}", GetActivationFunctionAsCString(function), nodeIndex); } std::string GetLayerName(armnn::ArgMinMaxFunction function, int nodeIndex) { return fmt::format("{}:{}", GetArgMinMaxFunctionAsCString(function), nodeIndex); } std::string GetLayerName(armnn::BinaryOperation opType, int nodeIndex) { return fmt::format("{}:{}", GetBinaryOperationAsCString(opType), nodeIndex); } std::string GetLayerName(armnn::ComparisonOperation layerType, int nodeIndex) { return fmt::format("{}:{}", GetComparisonOperationAsCString(layerType), nodeIndex); } std::string GetLayerName(armnn::LogicalBinaryOperation operation, int nodeIndex) { return fmt::format("{}:{}", GetLogicalBinaryOperationAsCString(operation), nodeIndex); } std::string GetLayerName(armnn::UnaryOperation opType, int nodeIndex) { return fmt::format("{}:{}", GetUnaryOperationAsCString(opType), nodeIndex); } std::string GetLayerName(armnn::LayerType layerType, int nodeIndex, std::string name = "") { return fmt::format("{}{}:{}", GetLayerTypeAsCString(layerType), name, nodeIndex); } TfLiteStatus ValidateNumInputs(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, const unsigned int expectedSize, int nodeIndex) { auto numInputs = tfLiteNode->inputs->size; if (static_cast(numInputs) != expectedSize) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Unexpected number of inputs (%d != %d) in node #%d", numInputs, expectedSize, nodeIndex); return kTfLiteError; } return kTfLiteOk; } TfLiteStatus ValidateNumOutputs(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, const unsigned int expectedSize, int nodeIndex) { auto numOutputs = tfLiteNode->outputs->size; if (static_cast(numOutputs) != expectedSize) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Unexpected number of outputs (%d != %d) in node #%d", numOutputs, expectedSize, nodeIndex); return kTfLiteError; } return kTfLiteOk; } bool IsDynamicTensor(const TfLiteTensor& tfLiteTensor) { auto tensorAllocationType = tfLiteTensor.allocation_type; if (tensorAllocationType == kTfLiteDynamic) { return true; } return false; } bool IsValid(const TfLiteTensor* tfLiteTensor) { return tfLiteTensor == nullptr ? false : true; } bool IsValid(TfLiteContext* tfLiteContext, const TfLiteTensor& tfLiteTensor, int32_t operatorCode, int32_t nodeIndex) { if(!IsValid(&tfLiteTensor)) { std::cout << "..Is Not Valid" << std::endl; TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid TfLite tensor in operator #%d node #%d: ", operatorCode, nodeIndex); return false; } if (IsDynamicTensor(tfLiteTensor)) { std::cout << "..IsDynamicTensor" << std::endl; TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic tensors are not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return false; } return true; } bool IsAffineQuantization(const TfLiteTensor& tfLiteTensor) { auto quantizationInfo = tfLiteTensor.quantization; if (quantizationInfo.type == kTfLiteAffineQuantization) { return true; } return false; } TfLiteStatus Connect(armnn::IConnectableLayer* layer, TfLiteNode* tfLiteNode, armnnDelegate::DelegateData& data) { if (static_cast(tfLiteNode->outputs->size) != layer->GetNumOutputSlots()) { return kTfLiteError; } // Connect the input slots for (unsigned int inputIndex = 0; inputIndex < layer->GetNumInputSlots(); ++inputIndex) { if (data.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]] != nullptr) { data.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]]->Connect(layer->GetInputSlot(inputIndex)); } } // Prepare output slots for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex) { armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast(tfLiteNode->outputs->data[outputIndex])] = &outputSlot; } return kTfLiteOk; } TfLiteStatus FusedActivation(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, TfLiteFusedActivation activationType, armnn::IConnectableLayer* prevLayer, unsigned int outputSlotIndex, armnnDelegate::DelegateData& data, int nodeIndex) { const armnn::TensorInfo& activationOutputInfo = prevLayer->GetOutputSlot(outputSlotIndex).GetTensorInfo(); armnn::ActivationDescriptor activationDesc; switch (activationType) { case kTfLiteActNone: { // No Activation return kTfLiteOk; } case kTfLiteActRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } // The name of kTfLiteActRelu1 changed after TF Lite v2.3 #if defined(ARMNN_POST_TFLITE_2_3) case kTfLiteActReluN1To1: #else case kTfLiteActRelu1: #endif { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 1.0f; activationDesc.m_B = -1.0f; break; } case kTfLiteActRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; activationDesc.m_B = 0.0f; break; } case kTfLiteActSigmoid: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteActTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } default: return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, data.m_Backends, isSupported, setBackend, activationOutputInfo, activationOutputInfo, activationDesc); if (!isSupported) { return kTfLiteError; } auto layerName = GetLayerName(activationDesc.m_Function, nodeIndex); armnn::IConnectableLayer* activationLayer = data.m_Network->AddActivationLayer(activationDesc, layerName.c_str()); activationLayer->SetBackendId(setBackend); ARMNN_ASSERT(activationLayer != nullptr); activationLayer->GetOutputSlot(0).SetTensorInfo(activationOutputInfo); // Connect and prepare output slots for (unsigned int outputIndex = 0; outputIndex < activationLayer->GetNumOutputSlots(); ++outputIndex) { data.m_OutputSlotForNode[static_cast( tfLiteNode->outputs->data[outputIndex])]->Connect(activationLayer->GetInputSlot(0)); armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast( tfLiteNode->outputs->data[outputIndex])] = &outputSlot; } return kTfLiteOk; } armnn::IConnectableLayer* AddReshapeLayer(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, armnn::IConnectableLayer* prevLayer, armnn::TensorInfo reshapedOutputTensorInfo, armnn::TensorInfo outputTensorInfo, armnnDelegate::DelegateData& data, int nodeIndex) { armnn::ReshapeDescriptor desc; desc.m_TargetShape = outputTensorInfo.GetShape(); bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, data.m_Backends, isSupported, setBackend, reshapedOutputTensorInfo, outputTensorInfo, desc); if (!isSupported) { return nullptr; } auto layerName = GetLayerName(armnn::LayerType::Reshape, nodeIndex); armnn::IConnectableLayer* reshapeLayer = data.m_Network->AddReshapeLayer(desc, layerName.c_str()); reshapeLayer->SetBackendId(setBackend); ARMNN_ASSERT(reshapeLayer != nullptr); prevLayer->GetOutputSlot(0).SetTensorInfo(reshapedOutputTensorInfo); reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); // Connect and prepare output slots for (unsigned int outputIndex = 0; outputIndex < reshapeLayer->GetNumOutputSlots(); ++outputIndex) { data.m_OutputSlotForNode[static_cast( tfLiteNode->outputs->data[outputIndex])]->Connect(reshapeLayer->GetInputSlot(0)); armnn::IOutputSlot& outputSlot = reshapeLayer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast( tfLiteNode->outputs->data[outputIndex])] = &outputSlot; } return reshapeLayer; } armnn::DataType GetDataType(const TfLiteTensor& tfLiteTensor) { switch (tfLiteTensor.type) { case kTfLiteBool: return armnn::DataType::Boolean; case kTfLiteFloat32: return armnn::DataType::Float32; case kTfLiteFloat16: return armnn::DataType::Float16; case kTfLiteUInt8: return armnn::DataType::QAsymmU8; case kTfLiteInt8: { auto quantizationInfo = tfLiteTensor.quantization; if (quantizationInfo.type == kTfLiteAffineQuantization) { auto* quantization = reinterpret_cast(tfLiteTensor.quantization.params); if (quantization->zero_point != nullptr && quantization->zero_point->size == 1) { return armnn::DataType::QAsymmS8; } else { return armnn::DataType::QSymmS8; } } else { return armnn::DataType::QAsymmS8; } } case kTfLiteInt16: return armnn::DataType::QSymmS16; case kTfLiteInt32: return armnn::DataType::Signed32; case kTfLiteInt64: return armnn::DataType::Signed64; default: throw armnn::Exception(&"TfLiteArmnnDelegate: Unsupported data type: " [ tfLiteTensor.type]); } } armnn::TensorInfo GetTensorInfoForTfLiteTensor(const TfLiteTensor& tfLiteTensor, bool isOutput = false) { armnn::DataType type = GetDataType(tfLiteTensor); armnn::TensorInfo ret; auto tensorDimensionSize = tfLiteTensor.dims->size; if (tensorDimensionSize == 0) { // If input tensor does not have a shape // assuming that it has 1D tensor if (!isOutput) { std::vector safeShape = { 1 }; bool dimensionsSpecificity[1] = { true }; armnn::TensorShape tensorShape(safeShape.size(), safeShape.data(), dimensionsSpecificity); ret = armnn::TensorInfo(tensorShape, type); if(tflite::IsConstantTensor(&tfLiteTensor)) { ret.SetConstant(true); } } else { armnn::TensorShape tensorShape(armnn::Dimensionality::NotSpecified); ret = armnn::TensorInfo(tensorShape, type); } } else { std::vector tensorDims(tensorDimensionSize); std::vector dimensionsSpecificity(tensorDimensionSize, true); for (int i = 0; i < tensorDimensionSize; ++i) { auto dim = tfLiteTensor.dims->data[i]; if (dim <= 0) { dimensionsSpecificity[i] = false; } tensorDims[i] = static_cast(dim); } armnn::TensorShape tensorShape(tensorDimensionSize, tensorDims.data(), reinterpret_cast(dimensionsSpecificity.data())); if (tflite::IsConstantTensor(&tfLiteTensor)) { ret = armnn::TensorInfo(tensorShape, type); ret.SetConstant(true); } else { ret = armnn::TensorInfo(tensorShape, type); } } auto quantizationInfo = tfLiteTensor.quantization; if (quantizationInfo.type == kTfLiteAffineQuantization) { // get per-channel quantization parameters const auto* affineQuantization = reinterpret_cast(tfLiteTensor.quantization.params); if (affineQuantization->scale->size > 1) { std::vector quantizationScales; for (unsigned int i = 0; i < static_cast(affineQuantization->scale->size); ++i) { quantizationScales.push_back(affineQuantization->scale->data[i]); } ret.SetQuantizationScales(quantizationScales); ret.SetQuantizationDim(armnn::numeric_cast(affineQuantization->quantized_dimension)); } else { ret.SetQuantizationScale(affineQuantization->scale->data[0]); ret.SetQuantizationOffset(affineQuantization->zero_point->data[0]); } } else { auto quantizationParameters = tfLiteTensor.params; ret.SetQuantizationScale(quantizationParameters.scale); ret.SetQuantizationOffset(quantizationParameters.zero_point); } return ret; } armnn::ConstTensor CreateConstTensor(const TfLiteTensor* tfLiteTensor, const armnn::TensorInfo& tensorInfo) { if (tfLiteTensor->allocation_type != kTfLiteMmapRo) { throw armnn::Exception( "TfLiteArmnnDelegate: Not constant allocation type: " + std::to_string(tfLiteTensor->allocation_type)); } return armnn::ConstTensor(tensorInfo, tfLiteTensor->data.data); } armnn::ConstTensor* GetConstTensorForTfLiteTensor(const TfLiteTensor* tfLiteTensors, TfLiteNode* tfLiteNode, int index) { const TfLiteTensor &tfLiteTensor = tfLiteTensors[tfLiteNode->inputs->data[index]]; armnn::TensorInfo tensorInfo = GetTensorInfoForTfLiteTensor(tfLiteTensor); return new armnn::ConstTensor(tensorInfo, tfLiteTensor.data.data); } bool IsOptionalOperandPresent(TfLiteNode* tfLiteNode, const int operandIndex) { // If the inputs array has fewer than operandIndex entries or if the entry at operandIndex has a value of -1 or // less then the input is not present. if (tfLiteNode->inputs->size > operandIndex && tfLiteNode->inputs->data[operandIndex] >= 0) { return true; } return false; } TfLiteStatus ProcessInputs(armnn::IConnectableLayer* layer, armnnDelegate::DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex) { const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; // Process input tensors // If input tensor is a Constant tensor create a constant layer and connect it to the network for (unsigned int inputIndex = 0; inputIndex < layer->GetNumInputSlots(); ++inputIndex) { const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[inputIndex]]; if (tflite::IsConstantTensor(&tfLiteInputTensor)) { armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_SUPPORT_FUNC("CONSTANT", tfLiteContext, IsConstantSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo); if (!isSupported) { return kTfLiteError; } auto constantInput = CreateConstTensor(&tfLiteInputTensor, inputTensorInfo); auto layerName = GetLayerName(armnn::LayerType::Constant, nodeIndex); armnn::IConnectableLayer* constantLayer = delegateData.m_Network->AddConstantLayer(constantInput, layerName.c_str()); constantLayer->SetBackendId(setBackend); armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(inputTensorInfo); delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]] = &outputSlot; } } return kTfLiteOk; } } // namespace anonymous armnn-23.08/delegate/classic/src/Comparison.hpp000066400000000000000000000124231446772241200214610ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitComparisonOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteComparisonOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor0 = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor0)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLiteComparisonOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor1 = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteInputTensor1)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLiteComparisonOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLiteComparisonOperatorCode, nodeIndex); return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of any of the input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } armnn::ComparisonOperation comparisonOperation = armnn::ComparisonOperation::Equal; switch(tfLiteComparisonOperatorCode) { case kTfLiteBuiltinEqual: comparisonOperation = armnn::ComparisonOperation::Equal; break; case kTfLiteBuiltinGreater: comparisonOperation = armnn::ComparisonOperation::Greater; break; case kTfLiteBuiltinGreaterEqual: comparisonOperation = armnn::ComparisonOperation::GreaterOrEqual; break; case kTfLiteBuiltinLess: comparisonOperation = armnn::ComparisonOperation::Less; break; case kTfLiteBuiltinLessEqual: comparisonOperation = armnn::ComparisonOperation::LessOrEqual; break; case kTfLiteBuiltinNotEqual: comparisonOperation = armnn::ComparisonOperation::NotEqual; break; default: return kTfLiteError; } armnn::ComparisonDescriptor descriptor(comparisonOperation); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("COMPARISON", tfLiteContext, IsComparisonSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(descriptor.m_Operation, nodeIndex); armnn::IConnectableLayer* comparisonLayer = delegateData.m_Network->AddComparisonLayer(descriptor, layerName.c_str()); comparisonLayer->SetBackendId(setBackend); ARMNN_ASSERT(comparisonLayer != nullptr); armnn::IOutputSlot& outputSlot = comparisonLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(comparisonLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(comparisonLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Control.hpp000066400000000000000000000277611446772241200210020ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitConcatenationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteConcatOperatorCode) { unsigned int numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; std::vector inputTensorInfos; for (unsigned int i = 0; i < numInputs; ++i) { const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[i]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteConcatOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); inputTensorInfos.emplace_back(inputTensorInfo); } // Convert input tensors to const armnn::TensorInfo* type for FORWARD_LAYER_SUPPORT_FUNC. std::vector inputConstTensorInfos; std::transform(inputTensorInfos.begin(), inputTensorInfos.end(), std::back_inserter(inputConstTensorInfos), [](armnn::TensorInfo& t)->const armnn::TensorInfo*{ return &t; }); const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteConcatOperatorCode, nodeIndex)) { return kTfLiteError; } // Setup OriginsDescriptor, axis and view origin unsigned int numConcatView = static_cast(numInputs); uint32_t inputRank = tfLiteTensors[tfLiteNode->inputs->data[0]].dims->size; auto* concatenationParameters = reinterpret_cast(tfLiteNode->builtin_data); if(!concatenationParameters) { throw armnn::Exception(&"TfLiteArmnnDelegate: Concat parameters are null in: " [ nodeIndex]); } const unsigned int concatDimInput = static_cast( (static_cast(inputRank) + concatenationParameters->axis) % static_cast(inputRank)); armnn::OriginsDescriptor concatDescriptor(static_cast(numConcatView), inputRank); concatDescriptor.SetConcatAxis(concatDimInput); unsigned int mergeDimOrigin = 0; for (unsigned int viewIndex = 0; viewIndex < numConcatView; ++viewIndex) { armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor( tfLiteTensors[tfLiteNode->inputs->data[viewIndex]]); // Sets up concatDescriptor view origin SetupConcatViewOrigin(inputTensorInfo, concatDescriptor, concatDimInput, viewIndex, mergeDimOrigin); } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Verify we support the fused activation before attempting to create a layer TfLiteFusedActivation activationType = concatenationParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("CONCATENATION", tfLiteContext, IsConcatSupported, delegateData.m_Backends, isSupported, setBackend, inputConstTensorInfos, outputTensorInfo, concatDescriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Setup layer and connect. auto layerName = GetLayerName(armnn::LayerType::Concat, nodeIndex); armnn::IConnectableLayer* concatenationLayer = delegateData.m_Network->AddConcatLayer(concatDescriptor, layerName.c_str()); concatenationLayer->SetBackendId(setBackend); ARMNN_ASSERT(concatenationLayer != nullptr); // Connect the Constant Inputs auto inputsTensorsProcess = ProcessInputs(concatenationLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } armnn::IOutputSlot& outputSlot = concatenationLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(concatenationLayer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (activationType == kTfLiteActNone) { // No Activation return kTfLiteOk; } // Check and Create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, concatenationLayer, 0, delegateData, nodeIndex); } TfLiteStatus VisitMeanOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteMeanOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if(!IsValid(&tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid input tensor in operator #%d node #%d: ", tfLiteMeanOperatorCode, nodeIndex); return kTfLiteError; } if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLiteMeanOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if(!IsValid(&tfLiteAxisTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid axis tensor in operator #%d node #%d: ", tfLiteMeanOperatorCode, nodeIndex); return kTfLiteError; } if (IsDynamicTensor(tfLiteAxisTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic axis tensors are not supported in operator #%d node #%d: ", tfLiteMeanOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if(!IsValid(&tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid output tensor in operator #%d node #%d: ", tfLiteAxisTensor, nodeIndex); return kTfLiteError; } if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLiteMeanOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& axisTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteAxisTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* axisTensorData = tflite::GetTensorData(&tfLiteAxisTensor); std::vector axis; // Add axis data to vector to be converter to unsigned int and assigned to descriptor axis. for (unsigned int i = 0; i < axisTensorInfo.GetNumElements(); ++i) { axis.emplace_back(axisTensorData[i]); } // Convert the axis to unsigned int and remove duplicates. unsigned int rank = inputTensorInfo.GetNumDimensions(); std::set uniqueAxis; std::transform(axis.begin(), axis.end(), std::inserter(uniqueAxis, uniqueAxis.begin()), [rank](int i)->unsigned int{ return (i + rank) % rank; }); // Setup MeanDescriptor and assign axis and keepDims armnn::MeanDescriptor desc; desc.m_Axis.assign(uniqueAxis.begin(), uniqueAxis.end()); desc.m_KeepDims = inputTensorInfo.GetNumDimensions() == outputTensorInfo.GetNumDimensions() ? true : false; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("MEAN", tfLiteContext, IsMeanSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Setup layer and connect. auto layerName = GetLayerName(armnn::LayerType::Mean, nodeIndex); armnn::IConnectableLayer* meanLayer = delegateData.m_Network->AddMeanLayer(desc, layerName.c_str()); meanLayer->SetBackendId(setBackend); ARMNN_ASSERT(meanLayer != nullptr); armnn::IOutputSlot& outputSlot = meanLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(meanLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(meanLayer, tfLiteNode, delegateData); } TfLiteStatus VisitControlOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { switch(operatorCode) { case kTfLiteBuiltinConcatenation: return VisitConcatenationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinMean: return VisitMeanOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); default: return kTfLiteError; } } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Convolution.hpp000066400000000000000000001013361446772241200216700ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitConv2dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); armnn::Convolution2dDescriptor descriptor; const auto params = reinterpret_cast(tfLiteNode->builtin_data); bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); descriptor.m_BiasEnabled = biasEnabled; descriptor.m_StrideX = NonNegative(params->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(params->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_DilationX = NonNegative(params->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(params->dilation_height_factor, nodeIndex); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFilterTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType=kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteFilterTensor); armnn::TensorInfo biasTensorInfo; if(biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::Optional optionalBiasInfo(biasTensorInfo); // TfLite uses NHWC tensors const unsigned int inputHeight = inputTensorInfo.GetShape()[1]; const unsigned int inputWidth = inputTensorInfo.GetShape()[2]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, params->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("CONV2D", tfLiteContext, IsConvolution2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, optionalBiasInfo); return isSupported ? kTfLiteOk : kTfLiteError; } // Set up filter and biases auto layerName = GetLayerName(armnn::LayerType::Convolution2d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution2dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); if (filterTensorInfo.IsConstant()) { auto filter = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[1]], filterTensorInfo); auto filterName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if (biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if(biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(&tfLiteBiasTensor, biasTensorInfo); auto biasName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if (inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[0]], inputTensorInfo); auto inputName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(layer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } // Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. #if defined(ARMNN_POST_TFLITE_2_5) TfLiteStatus VisitConv3dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); armnn::Convolution3dDescriptor descriptor; const auto params = reinterpret_cast(tfLiteNode->builtin_data); bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); descriptor.m_BiasEnabled = biasEnabled; descriptor.m_DataLayout = armnn::DataLayout::NDHWC; descriptor.m_StrideX = NonNegative(params->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(params->stride_height, nodeIndex); descriptor.m_StrideZ = NonNegative(params->stride_depth, nodeIndex); descriptor.m_DilationX = NonNegative(params->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(params->dilation_height_factor, nodeIndex); descriptor.m_DilationZ = NonNegative(params->dilation_depth_factor, nodeIndex); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFilterTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType=kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteFilterTensor); armnn::TensorInfo biasTensorInfo; if(biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::Optional optionalBiasInfo(biasTensorInfo); // TfLite uses NDHWC tensors const unsigned int inputDepth = inputTensorInfo.GetShape()[1]; const unsigned int inputHeight = inputTensorInfo.GetShape()[2]; const unsigned int inputWidth = inputTensorInfo.GetShape()[3]; // Assuming the filter is DHWIO : Depth, Height, Width, OutputChannels, InputChannels const unsigned int filterDepth = filterTensorInfo.GetShape()[0]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputDepth, filterDepth, descriptor.m_StrideZ, descriptor.m_DilationZ, descriptor.m_PadFront, descriptor.m_PadBack, params->padding); CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, params->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitConvolutionOperator will be called again to add the layer to the network as seen below. armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("CONV3D", tfLiteContext, IsConvolution3dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, optionalBiasInfo); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Convolution3d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution3dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant, // which are connected to the Convolution3d layer as inputs. if (filterTensorInfo.IsConstant()) { auto filter = CreateConstTensor(&tfLiteFilterTensor, filterTensorInfo); auto filterName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); ARMNN_ASSERT(weightsLayer != nullptr); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if(biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if(biasTensorInfo.IsConstant()) { auto biases = CreateConstTensor(&tfLiteBiasTensor, biasTensorInfo); auto biasName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biases, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[0]], inputTensorInfo); auto inputName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(layer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } #endif TfLiteStatus VisitDepthwiseConv2dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); armnn::DepthwiseConvolution2dDescriptor descriptor; const auto params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_BiasEnabled = biasEnabled; descriptor.m_StrideX = NonNegative(params->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(params->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_DilationX = NonNegative(params->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(params->dilation_height_factor, nodeIndex); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFilterTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteFilterTensor); // Assuming input is NHWC unsigned int inputHeight = inputTensorInfo.GetShape()[1]; unsigned int inputWidth = inputTensorInfo.GetShape()[2]; // TensorflowLite weights come in the format [1, H, W, I * M] unsigned int filterHeight = filterTensorInfo.GetShape()[1]; unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, params->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); armnn::TensorInfo biasTensorInfo; if(biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("DEPTHWISE_CONV2D", tfLiteContext, IsDepthwiseConvolutionSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, armnn::Optional(biasTensorInfo)); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Convolution3d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthwiseConvolution2dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); if(filterTensorInfo.IsConstant()) { // For depthwise the weights layout is the same as for tflite [1, H, W, I*M]. No permutation required. auto filter = CreateConstTensor(&tfLiteFilterTensor, filterTensorInfo); auto filterName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if (biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if(biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(&tfLiteBiasTensor, biasTensorInfo); auto biasName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[0]], inputTensorInfo); auto inputName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(layer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } TfLiteStatus VisitTransposeConv2dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); armnn::TransposeConvolution2dDescriptor descriptor; auto* parameters = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_BiasEnabled = false; descriptor.m_StrideX = NonNegative(parameters->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(parameters->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteOutputShapeTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFilterTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteFilterTensor); // TfLite uses NHWC tensors const unsigned int inputHeight = inputTensorInfo.GetShape()[1]; const unsigned int inputWidth = inputTensorInfo.GetShape()[2]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // This block determines the output shape of the transpose convolution. // If the output shape tensor is a constant, we can access the data at load time and set the shape of the layer. // If this is not constant, we do not have access to the shape data, so we have to use infer output shape. if (tflite::IsConstantTensor(&tfLiteOutputShapeTensor)) { const armnn::TensorInfo outputShapeTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputShapeTensor); std::vector outputShape(outputShapeTensorInfo.GetNumElements()); if (outputShapeTensorInfo.GetDataType() == armnn::DataType::Signed32) { for(unsigned int i=0; i < outputShapeTensorInfo.GetNumElements(); ++i) { outputShape[i] = ::tflite::GetTensorData(&tfLiteOutputShapeTensor)[i]; } } if (outputShapeTensorInfo.GetDataType() == armnn::DataType::QAsymmU8) { for(unsigned int i=0; i < outputShapeTensorInfo.GetNumElements(); ++i) { outputShape[i] = ::tflite::GetTensorData(&tfLiteOutputShapeTensor)[i]; } } // Change from signed to unsigned int to store in TransposeConvolution2dDescriptor. for (int dimension : outputShape) { descriptor.m_OutputShape.push_back(static_cast(dimension)); } descriptor.m_OutputShapeEnabled = true; // TfLite uses NHWC tensors const unsigned int outputHeight = descriptor.m_OutputShape[1]; const unsigned int outputWidth = descriptor.m_OutputShape[2]; CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, 1, // DilationY descriptor.m_PadTop, descriptor.m_PadBottom, parameters->padding, outputHeight); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, 1, // DilationX descriptor.m_PadLeft, descriptor.m_PadRight, parameters->padding, outputWidth); } else { CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, 1, // DilationY descriptor.m_PadTop, descriptor.m_PadBottom, parameters->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, 1, // DilationX descriptor.m_PadLeft, descriptor.m_PadRight, parameters->padding); } // Set up filter auto filterTensor = CreateConstTensor(&tfLiteFilterTensor, filterTensorInfo); armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("TRANSPOSE_CONV2D", tfLiteContext, IsTransposeConvolution2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, armnn::EmptyOptional()); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::TransposeConvolution2d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddTransposeConvolution2dLayer(descriptor, filterTensor, armnn::EmptyOptional(), layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // The data input can be constant, so we must check that this is allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[2]], inputTensorInfo); auto inputName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect if (delegateData.m_OutputSlotForNode[static_cast(tfLiteNode->inputs->data[2])] != nullptr) { delegateData.m_OutputSlotForNode[static_cast(tfLiteNode->inputs->data[2])]-> Connect(layer->GetInputSlot(0)); } // Prepare output slots for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex) { armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex); delegateData.m_OutputSlotForNode[static_cast(tfLiteNode->outputs->data[outputIndex])] = &outputSlot; } return kTfLiteOk; } TfLiteStatus VisitConvolutionOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { switch(operatorCode) { case kTfLiteBuiltinConv2d: return VisitConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); // Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. #if defined(ARMNN_POST_TFLITE_2_5) case kTfLiteBuiltinConv3d: return VisitConv3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); #endif case kTfLiteBuiltinDepthwiseConv2d: return VisitDepthwiseConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinTransposeConv: return VisitTransposeConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); default: return kTfLiteError; } } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/ElementwiseBinary.hpp000066400000000000000000000527751446772241200230130ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include "MultiLayerFacade.hpp" #include "SharedFunctions.hpp" #include #include #include #include #include "tensorflow/lite/delegates/utils.h" namespace armnnDelegate { TfLiteStatus ValidateAddOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { std::vector infos { inputInfo1, inputInfo2, outputInfo }; FORWARD_LAYER_SUPPORT_FUNC("ADD", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputInfo, armnn::BinaryOperation::Add); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateDivOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("DIV", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Div); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateFloorDivOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { // need first to validate that the div operator is supported // then that the floor operator is supported TfLiteStatus status = ValidateDivOperator(delegateData, tfLiteContext, inputInfo1, inputInfo2, outputInfo); if (status != kTfLiteOk) { return status; } // if the inputs and output of the div are all Signed32 we don't need to add the floor operator afterward. if (AreAllSigned32(inputInfo1, inputInfo2, outputInfo)) { return status; } // in case broadcasting is being done from one of the inputs to the div // choose the full sized input tensor to pass to the floor validation routine armnn::TensorInfo floorInputInfo = inputInfo1; if (inputInfo1.GetNumDimensions() < inputInfo2.GetNumDimensions()) { floorInputInfo = inputInfo2; } status = ValidateFloorOperator(delegateData, tfLiteContext, floorInputInfo, outputInfo); return status; } TfLiteStatus ValidateMaximumOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("MAXIMUM", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Maximum); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateMinimumOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("MINIMUM", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Minimum); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateMulOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("MUL", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Mul); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidatePowerOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("POWER", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Power); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateSquaredDifferenceOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SQUAREDDIFFERENCE", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::SqDiff); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateSubOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SUB", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Sub); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } std::pair AddFloorDivLayer( DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo, int nodeIndex) { auto divName = GetLayerName(armnn::BinaryOperation::Div, nodeIndex); armnn::IConnectableLayer* divisionLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Div, divName.c_str()); // if the output of the div is Signed32 the Floor layer is not required if (armnn::DataType::Signed32 == outputTensorInfo.GetDataType()) { return std::make_pair(divisionLayer, divisionLayer); } armnn::IOutputSlot& outputSlot = divisionLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto floorName = GetLayerName(armnn::LayerType::Floor, nodeIndex); armnn::IConnectableLayer* floorLayer = delegateData.m_Network->AddFloorLayer(floorName.c_str()); outputSlot.Connect(floorLayer->GetInputSlot(0)); return std::make_pair(divisionLayer, floorLayer); } TfLiteStatus VisitElementwiseBinaryOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t elementwiseBinaryOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor0 = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor0)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", elementwiseBinaryOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor1 = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteInputTensor1)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", elementwiseBinaryOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", elementwiseBinaryOperatorCode, nodeIndex); return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of the input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } if (!delegateData.m_Network) { switch(elementwiseBinaryOperatorCode) { case kTfLiteBuiltinAdd: return ValidateAddOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinDiv: return ValidateDivOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinFloorDiv: return ValidateFloorDivOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMaximum: return ValidateMaximumOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMinimum: return ValidateMinimumOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMul: return ValidateMulOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinPow: return ValidatePowerOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinSquaredDifference: return ValidateSquaredDifferenceOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinSub: return ValidateSubOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); default: return kTfLiteError; } } armnn::IConnectableLayer* elementwiseBinaryLayer = nullptr; MultiLayerFacade multiLayer; std::string layerName; switch(elementwiseBinaryOperatorCode) { case kTfLiteBuiltinAdd: layerName = GetLayerName(armnn::BinaryOperation::Add, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Add, layerName.c_str()); break; case kTfLiteBuiltinDiv: layerName = GetLayerName(armnn::BinaryOperation::Div, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Div, layerName.c_str()); break; case kTfLiteBuiltinFloorDiv: { auto layers = AddFloorDivLayer(delegateData, outputTensorInfo, nodeIndex); multiLayer.AssignValues(layers.first, layers.second); elementwiseBinaryLayer = &multiLayer; } break; case kTfLiteBuiltinMaximum: layerName = GetLayerName(armnn::BinaryOperation::Maximum, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Maximum, layerName.c_str()); break; case kTfLiteBuiltinMinimum: layerName = GetLayerName(armnn::BinaryOperation::Minimum, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Minimum, layerName.c_str()); break; case kTfLiteBuiltinMul: layerName = GetLayerName(armnn::BinaryOperation::Mul, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Mul, layerName.c_str()); break; case kTfLiteBuiltinPow: layerName = GetLayerName(armnn::BinaryOperation::Power, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Power, layerName.c_str()); break; case kTfLiteBuiltinSquaredDifference: layerName = GetLayerName(armnn::BinaryOperation::SqDiff, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::SqDiff, layerName.c_str()); break; case kTfLiteBuiltinSub: layerName = GetLayerName(armnn::BinaryOperation::Sub, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Sub, layerName.c_str()); break; default: return kTfLiteError; } ARMNN_ASSERT(elementwiseBinaryLayer != nullptr); armnn::IOutputSlot& outputSlot = elementwiseBinaryLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(elementwiseBinaryLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } if(Connect(elementwiseBinaryLayer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create Activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, elementwiseBinaryLayer, 0, delegateData, nodeIndex); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/ElementwiseUnary.hpp000066400000000000000000000065361446772241200226570ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, armnn::UnaryOperation unaryOperation) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in node #%d: ", nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::ElementwiseUnaryDescriptor descriptor(unaryOperation); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ELEMENTWISE_UNARY", tfLiteContext, IsElementwiseUnarySupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(descriptor.m_Operation, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddElementwiseUnaryLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Fill.hpp000066400000000000000000000100241446772241200202300ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitFillOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteFillOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); switch(tfLiteFillOperatorCode) { case kTfLiteBuiltinFill: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); break; default: return kTfLiteError; } const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteFillTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteFillTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::FillDescriptor descriptor; switch (tfLiteFillTensor.type) { case kTfLiteFloat32: descriptor.m_Value = tflite::GetTensorData(&tfLiteFillTensor)[0]; break; case kTfLiteInt32: descriptor.m_Value = tflite::GetTensorData(&tfLiteFillTensor)[0]; break; default: TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: FILL value data type is not supported in operator #%d node #%d: ", tfLiteFillOperatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("FILL", tfLiteContext, IsFillSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Fill, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFillLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/FullyConnected.hpp000066400000000000000000000265671446772241200223030ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include "armnnUtils/TensorUtils.hpp" #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitFullyConnectedOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteWeightsTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteWeightsTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& weightsTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteWeightsTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Check that we support fused activation before we attempt to create a layer auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType=kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } // Fully Connected Layer accepts two dimensional weights input int32_t weightsDimension = static_cast(weightsTensorInfo.GetNumDimensions()); if (weightsDimension != 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dimension #$d for Fully Connected weights is not supported by Armnn" " in operator #%d node #%d: ", weightsDimension, operatorCode, nodeIndex); return kTfLiteError; } armnn::TensorInfo biasTensorInfo; if (biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::TensorInfo reshapedTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); if (inputTensorInfo.GetNumDimensions() > 2) { // Calculate reshape to flatten to 2D [batch_size, input_size] std::vector reshapedDimensions(2); reshapedDimensions[1] = weightsTensorInfo.GetShape()[1]; reshapedDimensions[0] = inputTensorInfo.GetNumElements() / reshapedDimensions[1]; if (inputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Failed to deduce input tensor shape from filter size #%d #%d node #%d: ", reshapedDimensions[1], operatorCode, nodeIndex); return kTfLiteError; } reshapedTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() }); } armnn::TensorInfo reshapedOutputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); if (outputTensorInfo.GetNumDimensions() > 2) { // Calculate reshape to flatten to 2D [batch_size, input_size] std::vector reshapedDimensions(2); reshapedDimensions[1] = weightsTensorInfo.GetShape()[0]; reshapedDimensions[0] = outputTensorInfo.GetNumElements() / reshapedDimensions[1]; if (outputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Failed to deduce output tensor shape from filter size #%d #%d node #%d: ", reshapedDimensions[1], operatorCode, nodeIndex); return kTfLiteError; } reshapedOutputTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() }); } armnn::FullyConnectedDescriptor descriptor; descriptor.m_TransposeWeightMatrix = true; descriptor.m_BiasEnabled = biasEnabled; descriptor.m_ConstantWeights = weightsTensorInfo.IsConstant(); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("FULLY_CONNECTED", tfLiteContext, IsFullyConnectedSupported, delegateData.m_Backends, isSupported, setBackend, reshapedTensorInfo, outputTensorInfo, weightsTensorInfo, biasTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(reshapedOutputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::FullyConnected, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFullyConnectedLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant. if (weightsTensorInfo.IsConstant()) { auto weightsTensor = CreateConstTensor(&tfLiteWeightsTensor, weightsTensorInfo); auto weightsName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Weights"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(weightsTensor, weightsName.c_str()); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsTensorInfo); } if (biasEnabled) { const TfLiteTensor& tfLiteBiasTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if(biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(&tfLiteBiasTensor, biasTensorInfo); auto biasName = GetLayerName(armnn::LayerType::FullyConnected, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if (inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(&tfLiteContext->tensors[tfLiteNode->inputs->data[0]], inputTensorInfo); auto constantName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer *inputLayer = delegateData.m_Network->AddConstantLayer(input, constantName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); armnn::IConnectableLayer* reshapeLayer = nullptr; if (inputTensorInfo.GetNumDimensions() > 2) { // Add reshape to flatten to 2D [batch_size, input_size] armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = reshapedTensorInfo.GetShape(); auto reshapeName = GetLayerName(armnn::LayerType::Reshape, nodeIndex, "Input"); reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor, reshapeName.c_str()); ARMNN_ASSERT(reshapeLayer != nullptr); reshapeLayer->GetOutputSlot(0).SetTensorInfo(reshapedTensorInfo); // Connect delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[0]]->Connect(reshapeLayer->GetInputSlot(0)); reshapeLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0)); if (!descriptor.m_ConstantWeights) { delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[1]]->Connect(layer->GetInputSlot(1)); } if (biasEnabled && !biasTensorInfo.IsConstant()) { delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[2]]->Connect(layer->GetInputSlot(2)); } delegateData.m_OutputSlotForNode[tfLiteNode->outputs->data[0]] = &outputSlot; } if (reshapeLayer == nullptr) { if(Connect(layer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } } if (outputTensorInfo.GetNumDimensions() > 2) { layer = AddReshapeLayer(tfLiteContext, tfLiteNode, layer, reshapedOutputTensorInfo, outputTensorInfo, delegateData, nodeIndex); if (!layer) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Failed to add reshape for FullyConnected #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create Activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/Gather.hpp000066400000000000000000000104111446772241200205540ustar00rootroot00000000000000// // Copyright © 2020,2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitGatherOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteIndicesTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteIndicesTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } auto* gatherParameters = reinterpret_cast(tfLiteNode->builtin_data); auto axis = gatherParameters->axis; const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& indicesTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteIndicesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::GatherDescriptor gatherDescriptor; gatherDescriptor.m_Axis = axis; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); auto indicesDimensions = indicesTensorInfo.GetNumDimensions(); auto outputDimensions = outputTensorInfo.GetNumDimensions(); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Operation has invalid axis: %d. It is out of bounds [-%d, %d))", axis, inputDimensions, inputDimensions); return kTfLiteError; } if (outputDimensions != static_cast(inputDimensions) + indicesDimensions - 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "Operation has invalid output dimensions: %d. Output must be an (%d + %d - 1)-D tensor", outputDimensions, inputDimensions, indicesDimensions); return kTfLiteError; } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("GATHER", tfLiteContext, IsGatherSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo, gatherDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Gather, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherLayer(gatherDescriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/GatherNd.hpp000066400000000000000000000061411446772241200210430ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitGatherNdOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteIndicesTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteIndicesTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& indicesTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteIndicesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("GATHER_ND", tfLiteContext, IsGatherNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::GatherNd, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherNdLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/LogicalBinary.hpp000066400000000000000000000101601446772241200220620ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitLogicalBinaryOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t logicalOperatorCode, armnn::LogicalBinaryOperation binaryOperation) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor0 = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor0, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor1 = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteInputTensor1, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of any of the input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } // Setup descriptor and assign operation armnn::LogicalBinaryDescriptor desc; desc.m_Operation = binaryOperation; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("LOGICAL_BINARY", tfLiteContext, IsLogicalBinarySupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(desc.m_Operation, nodeIndex); armnn::IConnectableLayer* logicalBinaryLayer = delegateData.m_Network->AddLogicalBinaryLayer(desc, layerName.c_str()); logicalBinaryLayer->SetBackendId(setBackend); ARMNN_ASSERT(logicalBinaryLayer != nullptr); armnn::IOutputSlot& outputSlot = logicalBinaryLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(logicalBinaryLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(logicalBinaryLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Lstm.hpp000066400000000000000000000267311446772241200202750ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitLstmOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } const auto nodeParams = reinterpret_cast(tfLiteNode->builtin_data); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Set the params structure for the AddLstmLayer call armnn::LstmInputParams params; if (IsOptionalOperandPresent(tfLiteNode, 1)) { params.m_InputToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 1); } params.m_InputToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 2); params.m_InputToCellWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 3); params.m_InputToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 4); // Recurrent weight tensors of size {n_cell, n_output} if (IsOptionalOperandPresent(tfLiteNode, 5)) { params.m_RecurrentToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 5); } params.m_RecurrentToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 6); params.m_RecurrentToCellWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 7); params.m_RecurrentToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 8); // Peephole weights tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 9)) { params.m_CellToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 9); } if (IsOptionalOperandPresent(tfLiteNode, 10)) { params.m_CellToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 10); } if (IsOptionalOperandPresent(tfLiteNode, 11)) { params.m_CellToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 11); } // Gates bias tensors of size {n_cell} if (IsOptionalOperandPresent(tfLiteNode, 12)) { params.m_InputGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 12); } params.m_ForgetGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 13); params.m_CellBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 14); params.m_OutputGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 15); // Projection weight tensor of size {n_output, n_cell} if (IsOptionalOperandPresent(tfLiteNode, 16)) { params.m_ProjectionWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 16); } // Projection bias tensor of size {n_output} if (IsOptionalOperandPresent(tfLiteNode, 17)) { params.m_ProjectionBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 17); } // These state tensors are defined as variable tensors, and will be modified by this op. armnn::TensorInfo outputStateInInfo = GetTensorInfoForTfLiteTensor(tfLiteTensors[tfLiteNode->inputs->data[18]]); armnn::TensorInfo cellStateInInfo = GetTensorInfoForTfLiteTensor(tfLiteTensors[tfLiteNode->inputs->data[19]]); // Layer norm coefficient tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 20)) { params.m_InputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 20); } if (IsOptionalOperandPresent(tfLiteNode, 21)) { params.m_ForgetLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 21); } if (IsOptionalOperandPresent(tfLiteNode, 22)) { params.m_CellLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 22); } if (IsOptionalOperandPresent(tfLiteNode, 23)) { params.m_OutputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 23); } // set the layer descriptor armnn::LstmDescriptor desc; desc.m_ActivationFunc = NonNegative(nodeParams->activation, nodeIndex); desc.m_ClippingThresCell = nodeParams->cell_clip; desc.m_ClippingThresProj = nodeParams->proj_clip; desc.m_CifgEnabled = (params.m_InputToInputWeights == nullptr || params.m_RecurrentToInputWeights == nullptr || params.m_InputGateBias == nullptr); desc.m_PeepholeEnabled = (params.m_CellToForgetWeights != nullptr || params.m_CellToOutputWeights != nullptr); desc.m_ProjectionEnabled = (params.m_ProjectionWeights != nullptr); desc.m_LayerNormEnabled = (params.m_InputLayerNormWeights != nullptr || params.m_ForgetLayerNormWeights != nullptr || params.m_CellLayerNormWeights != nullptr || params.m_OutputLayerNormWeights != nullptr); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); unsigned int batchSize = inputTensorInfo.GetShape()[0]; unsigned int outputSize = outputTensorInfo.GetShape()[1]; unsigned int numUnits = cellStateInInfo.GetShape()[1]; armnn::DataType dataType = inputTensorInfo.GetDataType(); float qScale = inputTensorInfo.GetQuantizationScale(); float qOffset = inputTensorInfo.GetQuantizationOffset(); armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 3}, dataType, qScale, qOffset); if (!desc.m_CifgEnabled) { scratchBufferTensorInfo = armnn::TensorInfo({batchSize, numUnits * 4}, dataType, qScale, qOffset); } armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, dataType, qScale, qOffset); armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, dataType, qScale, qOffset); armnn::LstmInputParamsInfo paramsInfo; paramsInfo.m_InputToForgetWeights = &(params.m_InputToForgetWeights->GetInfo()); paramsInfo.m_InputToCellWeights = &(params.m_InputToCellWeights->GetInfo()); paramsInfo.m_InputToOutputWeights = &(params.m_InputToOutputWeights->GetInfo()); paramsInfo.m_RecurrentToForgetWeights = &(params.m_RecurrentToForgetWeights->GetInfo()); paramsInfo.m_RecurrentToCellWeights = &(params.m_RecurrentToCellWeights->GetInfo()); paramsInfo.m_RecurrentToOutputWeights = &(params.m_RecurrentToOutputWeights->GetInfo()); paramsInfo.m_ForgetGateBias = &(params.m_ForgetGateBias->GetInfo()); paramsInfo.m_CellBias = &(params.m_CellBias->GetInfo()); paramsInfo.m_OutputGateBias = &(params.m_OutputGateBias->GetInfo()); if (!desc.m_CifgEnabled) { paramsInfo.m_InputToInputWeights = &(params.m_InputToInputWeights->GetInfo()); paramsInfo.m_RecurrentToInputWeights = &(params.m_RecurrentToInputWeights->GetInfo()); if (params.m_CellToInputWeights != nullptr) { paramsInfo.m_CellToInputWeights = &(params.m_CellToInputWeights->GetInfo()); } paramsInfo.m_InputGateBias = &(params.m_InputGateBias->GetInfo()); } if (desc.m_ProjectionEnabled) { paramsInfo.m_ProjectionWeights = &(params.m_ProjectionWeights->GetInfo()); if (params.m_ProjectionBias != nullptr) { paramsInfo.m_ProjectionBias = &(params.m_ProjectionBias->GetInfo()); } } if (desc.m_PeepholeEnabled) { paramsInfo.m_CellToForgetWeights = &(params.m_CellToForgetWeights->GetInfo()); paramsInfo.m_CellToOutputWeights = &(params.m_CellToOutputWeights->GetInfo()); } if (desc.m_LayerNormEnabled) { if(!desc.m_CifgEnabled) { paramsInfo.m_InputLayerNormWeights = &(params.m_InputLayerNormWeights->GetInfo()); } paramsInfo.m_ForgetLayerNormWeights = &(params.m_ForgetLayerNormWeights->GetInfo()); paramsInfo.m_CellLayerNormWeights = &(params.m_CellLayerNormWeights->GetInfo()); paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo()); } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("LSTM", tfLiteContext, IsLstmSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, scratchBufferTensorInfo, outputStateOutTensorInfo, cellStateOutTensorInfo, outputInfo, desc, paramsInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Lstm, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddLstmLayer(desc, params, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(scratchBufferTensorInfo); layer->GetOutputSlot(1).SetTensorInfo(outputStateOutTensorInfo); layer->GetOutputSlot(2).SetTensorInfo(cellStateOutTensorInfo); layer->GetOutputSlot(3).SetTensorInfo(outputTensorInfo); // Connect the inputs // input_layer delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[0]]->Connect(layer->GetInputSlot(0)); // cellStateIn delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[18]]->Connect(layer->GetInputSlot(1)); //outputStateIn delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[19]]->Connect(layer->GetInputSlot(2)); // In the test_model there is only 1 Output armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(1); delegateData.m_OutputSlotForNode[static_cast(tfLiteNode->outputs->data[0])] = &outputSlot; return kTfLiteOk; } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/Normalization.hpp000066400000000000000000000146051446772241200222010ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitL2NormalizationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::L2NormalizationDescriptor descriptor; descriptor.m_DataLayout = armnn::DataLayout::NHWC; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("L2_NORMALIZATION", tfLiteContext, IsL2NormalizationSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a L2Normalization layer auto layerName = GetLayerName(armnn::LayerType::L2Normalization, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddL2NormalizationLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitLocalResponseNormalizationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t normalizationOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, normalizationOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, normalizationOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::NormalizationDescriptor descriptor; descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_NormChannelType = armnn::NormalizationAlgorithmChannel::Across; descriptor.m_NormMethodType = armnn::NormalizationAlgorithmMethod::LocalBrightness; auto* params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_NormSize = params->radius; descriptor.m_K = params->bias; descriptor.m_Alpha = params->alpha; descriptor.m_Beta = params->beta; // ArmNN expects normSize to be the full size of the normalization window descriptor.m_NormSize = 1 + (2 * descriptor.m_NormSize); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("NORMALIZATION", tfLiteContext, IsNormalizationSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Normalization layer auto layerName = GetLayerName(armnn::LayerType::Normalization, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddNormalizationLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Pack.hpp000066400000000000000000000112561446772241200202300ustar00rootroot00000000000000// // Copyright © 2021,2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitPackOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { unsigned int numInputs = tfLiteNode->inputs->size; if (numInputs < 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Must have at least one input in (%d != %d) in node #%d", 1, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; // Validate all inputs and get TensorInfo std::vector inputTensorInfos; for (unsigned int i = 0; i < numInputs; ++i) { const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[i]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); inputTensorInfos.emplace_back(inputTensorInfo); } // Convert input tensors to const armnn::TensorInfo* type for FORWARD_LAYER_SUPPORT_FUNC. std::vector inputConstTensorInfos; std::transform(inputTensorInfos.begin(), inputTensorInfos.end(), std::back_inserter(inputConstTensorInfos), [](armnn::TensorInfo& t)->const armnn::TensorInfo*{ return &t; }); // Validate output and get TensorInfo const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::StackDescriptor desc; desc.m_NumInputs = static_cast(numInputs); // Get axis from TfLite parameters auto* params = reinterpret_cast(tfLiteNode->builtin_data); desc.m_Axis = static_cast(params->axis); // Use the tensor shape of the first input as the "correct" input shape in the descriptor desc.m_InputShape = inputTensorInfos[0].GetShape(); // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("STACK", tfLiteContext, IsStackSupported, delegateData.m_Backends, isSupported, setBackend, inputConstTensorInfos, outputTensorInfo, desc); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitPackOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // The TfLite Pack operator is equivalent to the ArmNN Stack operator auto layerName = GetLayerName(armnn::LayerType::Stack, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddStackLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Connect the Constant Inputs auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Pad.hpp000066400000000000000000000161311446772241200200530ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitPadOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLitePadOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); switch(tfLitePadOperatorCode) { case kTfLiteBuiltinMirrorPad: case kTfLiteBuiltinPad: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); break; case kTfLiteBuiltinPadv2: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); break; default: return kTfLiteError; } const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; const TfLiteTensor& tfLitepaddingTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& paddingTensorInfo = GetTensorInfoForTfLiteTensor(tfLitepaddingTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Get the padding data from the input tensor auto* paddingData = tflite::GetTensorData(&tfLitepaddingTensor); size_t step = 2; armnn::PadDescriptor descriptor; for (unsigned int i = 0; i < paddingTensorInfo.GetNumElements() / step; ++i) { descriptor.m_PadList.emplace_back(paddingData[i * step], paddingData[i * step + 1]); } if (tfLitePadOperatorCode == kTfLiteBuiltinPad && inputTensorInfo.IsQuantized()) { descriptor.m_PadValue = inputTensorInfo.GetQuantizationOffset(); } else if (tfLitePadOperatorCode == kTfLiteBuiltinPadv2) { const TfLiteTensor& tfLitepaddingValue = tfLiteTensors[tfLiteNode->inputs->data[2]]; armnn::TensorInfo paddingValueTensorInfo = GetTensorInfoForTfLiteTensor(tfLitepaddingValue); if (paddingValueTensorInfo.GetNumElements() != 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Multiple padding value are not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } // Get the padding value from the input tensor switch (tfLitepaddingValue.type) { case kTfLiteFloat32: descriptor.m_PadValue = tflite::GetTensorData(&tfLitepaddingValue)[0]; break; case kTfLiteUInt8: descriptor.m_PadValue = tflite::GetTensorData(&tfLitepaddingValue)[0]; break; case kTfLiteInt8: descriptor.m_PadValue = tflite::GetTensorData(&tfLitepaddingValue)[0]; break; default: TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Padding value datatype is not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } } else if (tfLitePadOperatorCode == kTfLiteBuiltinMirrorPad) { TfLiteMirrorPaddingParams* options = reinterpret_cast(tfLiteNode->builtin_data); if (options->mode == TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingReflect) { descriptor.m_PaddingMode = armnn::PaddingMode::Reflect; } else if (options->mode == TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingSymmetric) { descriptor.m_PaddingMode = armnn::PaddingMode::Symmetric; } else { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: PaddingMode must be either REFLECT or SYMMETRIC in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); } // If padding mode is Reflect then both paddings must be no greater than inputShape(i) - 1. // If padding mode is Symmetric then both paddings must be no greater than inputShape(i). auto inputShape = inputTensorInfo.GetShape(); auto padList = descriptor.m_PadList; const unsigned int isReflect = static_cast(descriptor.m_PaddingMode == armnn::PaddingMode::Reflect); for(unsigned int i = 0; i < padList.size(); ++i) { if(padList.at(i).first > (inputShape[i] - isReflect) || padList.at(i).second > (inputShape[i] - isReflect)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Padding values must be less (Reflect) or " "equal (Symmetric) to the dimension size in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); } } } armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("PAD", tfLiteContext, IsPadSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Pad, nodeIndex); armnn::IConnectableLayer* padLayer = delegateData.m_Network->AddPadLayer(descriptor, layerName.c_str()); padLayer->SetBackendId(setBackend); ARMNN_ASSERT(padLayer != nullptr); armnn::IOutputSlot& outputSlot = padLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); return Connect(padLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Pooling.hpp000066400000000000000000000314061446772241200207600ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitPooling2dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLitePoolingOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLitePoolingOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLitePoolingOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(tfLiteNode->builtin_data); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } armnn::PoolingAlgorithm poolingAlgorithm; switch(tfLitePoolingOperatorCode) { case kTfLiteBuiltinAveragePool2d: poolingAlgorithm = armnn::PoolingAlgorithm::Average; break; case kTfLiteBuiltinL2Pool2d: poolingAlgorithm = armnn::PoolingAlgorithm::L2; break; case kTfLiteBuiltinMaxPool2d: poolingAlgorithm = armnn::PoolingAlgorithm::Max; break; default: return kTfLiteError; } armnn::Pooling2dDescriptor descriptor; descriptor.m_PoolType = poolingAlgorithm; descriptor.m_PoolWidth = tfLiteNodeParameters->filter_width; descriptor.m_PoolHeight = tfLiteNodeParameters->filter_height; descriptor.m_StrideX = tfLiteNodeParameters->stride_width; descriptor.m_StrideY = tfLiteNodeParameters->stride_height; descriptor.m_DataLayout = armnn::DataLayout::NHWC; unsigned int inputHeight = inputTensorInfo.GetShape()[1]; unsigned int inputWidth = inputTensorInfo.GetShape()[2]; CalcPadding(inputHeight, descriptor.m_PoolHeight, descriptor.m_StrideY, 1u, descriptor.m_PadTop, descriptor.m_PadBottom, tfLiteNodeParameters->padding); CalcPadding(inputWidth, descriptor.m_PoolWidth, descriptor.m_StrideX, 1u, descriptor.m_PadLeft, descriptor.m_PadRight, tfLiteNodeParameters->padding); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("POOLING_2D", tfLiteContext, IsPooling2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Pooling2d, nodeIndex); armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling2dLayer(descriptor, layerName.c_str()); poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); armnn::IOutputSlot& outputSlot = poolingLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(poolingLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } if (Connect(poolingLayer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, poolingLayer, 0, delegateData, nodeIndex); } TfLiteStatus VisitPooling3dOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, std::string customOperatorName) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", customOperatorName.c_str(), nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", customOperatorName.c_str(), nodeIndex); return kTfLiteError; } // Set the input and output info const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Custom Operators are defined by the name string associated to the operator. Use this to determine // which pooling algorithm to create the armnn operator with. L2 Pooling3D is unsupported in TfLite. armnn::PoolingAlgorithm poolingAlgorithm; if (customOperatorName == "MaxPool3D") { poolingAlgorithm = armnn::PoolingAlgorithm::Max; } else if (customOperatorName == "AveragePool3D") { poolingAlgorithm = armnn::PoolingAlgorithm::Average; } else { return kTfLiteError; } // Create the armnn pool3d descriptor and set the algorithm parsed above. armnn::Pooling3dDescriptor descriptor; descriptor.m_PoolType = poolingAlgorithm; // custom_initial_data and custom_initial_data_size are void* variables defined in the tflite registration // used to access the custom option buffer for the operator. auto custom_data = tfLiteNode->custom_initial_data; auto custom_data_size = tfLiteNode->custom_initial_data_size; // Reinterpret the void* to a byte buffer to access the options data in the flexbuffers map. const flexbuffers::Map& m = flexbuffers::GetRoot(reinterpret_cast(custom_data), custom_data_size).AsMap(); // poolDims is a vector of [ 1, Depth, Height, Width, 1 ] const auto poolDims = m["ksize"].AsTypedVector(); descriptor.m_PoolWidth = poolDims[3].AsInt32(); descriptor.m_PoolHeight = poolDims[2].AsInt32(); descriptor.m_PoolDepth = poolDims[1].AsInt32(); // strideDimes is a vector of [ 1, Z, Y, X, 1] const auto strideDims = m["strides"].AsTypedVector(); descriptor.m_StrideX = strideDims[3].AsInt32(); descriptor.m_StrideY = strideDims[2].AsInt32(); descriptor.m_StrideZ = strideDims[1].AsInt32(); descriptor.m_DataLayout = armnn::DataLayout::NDHWC; unsigned int inputDepth = inputTensorInfo.GetShape()[1]; unsigned int inputHeight = inputTensorInfo.GetShape()[2]; unsigned int inputWidth = inputTensorInfo.GetShape()[3]; // CalcPadding expects a TfLitePadding type. Parse flexbuffers to extract padding string and create TfLitePadding. std::string paddingStr = m["padding"].AsString().str(); TfLitePadding padding; if (paddingStr == "VALID") { padding = kTfLitePaddingValid; } else if (paddingStr == "SAME") { padding = kTfLitePaddingSame; } else { padding = kTfLitePaddingUnknown; } // Calculates padding for each pooling dimension separately CalcPadding(inputHeight, descriptor.m_PoolHeight, descriptor.m_StrideY, 1u, descriptor.m_PadTop, descriptor.m_PadBottom, padding); CalcPadding(inputWidth, descriptor.m_PoolWidth, descriptor.m_StrideX, 1u, descriptor.m_PadLeft, descriptor.m_PadRight, padding); CalcPadding(inputDepth, descriptor.m_PoolDepth, descriptor.m_StrideZ, 1u, descriptor.m_PadFront, descriptor.m_PadBack, padding); // Check activation by parsing the string from the flexbuffer map std::string activationTypeStr = m["activation"].AsString().str(); TfLiteFusedActivation activationType = kTfLiteActNone; if (activationTypeStr == "kTfLiteActRelu") { activationType = kTfLiteActRelu; } else if (activationTypeStr == "kTfLiteActReluN1To1") { activationType = kTfLiteActReluN1To1; } else if (activationTypeStr == "kTfLiteActRelu6") { activationType = kTfLiteActRelu6; } else if (activationTypeStr == "kTfLiteActTanh") { activationType = kTfLiteActTanh; } else if (activationTypeStr == "kTfLiteActSignBit") { activationType = kTfLiteActSignBit; } else if (activationTypeStr == "kTfLiteActSigmoid") { activationType = kTfLiteActSigmoid; } else { activationType = kTfLiteActNone; } TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } // Validate the output info. bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("POOLING_3D", tfLiteContext, IsPooling3dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Create the Layer auto layerName = GetLayerName(armnn::LayerType::Pooling3d, nodeIndex); armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling3dLayer(descriptor); poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); // Create and set output slots armnn::IOutputSlot& outputSlot = poolingLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(poolingLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } if (Connect(poolingLayer, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } return FusedActivation(tfLiteContext, tfLiteNode, activationType, poolingLayer, 0, delegateData, nodeIndex); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Prelu.hpp000066400000000000000000000103361446772241200204370ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidatePreluOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& alphaInfo, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("PRELU", tfLiteContext, IsPreluSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, alphaInfo, outputInfo); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitPreluOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteAlphaTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteAlphaTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& alphaTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteAlphaTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); if (!delegateData.m_Network) { return ValidatePreluOperator(delegateData, tfLiteContext, inputTensorInfo, alphaTensorInfo, outputTensorInfo); } auto layerName = GetLayerName(armnn::LayerType::Prelu, nodeIndex); armnn::IConnectableLayer* preluLayer = delegateData.m_Network->AddPreluLayer(layerName.c_str()); ARMNN_ASSERT(preluLayer != nullptr); bool isConstantAlpha = tflite::IsConstantTensor(&tfLiteAlphaTensor); // Add constant layer for constant alpha if (isConstantAlpha) { auto constAlphaTensor = armnn::ConstTensor(alphaTensorInfo, tfLiteAlphaTensor.data.data); auto alphaName = GetLayerName(armnn::LayerType::Constant, nodeIndex, "Alpha"); armnn::IConnectableLayer* constLayer = delegateData.m_Network->AddConstantLayer(constAlphaTensor, alphaName.c_str()); ARMNN_ASSERT(constLayer != nullptr); constLayer->GetOutputSlot(0).SetTensorInfo(alphaTensorInfo); constLayer->GetOutputSlot(0).Connect(preluLayer->GetInputSlot(1)); } armnn::IOutputSlot& outputSlot = preluLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(preluLayer, tfLiteNode, delegateData); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/Quantization.hpp000066400000000000000000000154021446772241200220350ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitDequantizeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteDequantizeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLiteDequantizeOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLiteDequantizeOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); armnn::TensorInfo outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); UpdateConstantTensorOutputs(inputTensorInfo, outputTensorInfo); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("DEQUANTIZE", tfLiteContext, IsDequantizeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Dequantize, nodeIndex); armnn::IConnectableLayer* dequantizeLayer = delegateData.m_Network->AddDequantizeLayer(layerName.c_str()); dequantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(dequantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = dequantizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(dequantizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(dequantizeLayer, tfLiteNode, delegateData); } TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteQuantizeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tfLiteQuantizeOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tfLiteQuantizeOperatorCode, nodeIndex); return kTfLiteError; } // Only affine per-layer quantization is supported. if (!IsAffineQuantization(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Only affine per-layer quantization is supported in operator #%d node #%d: ", tfLiteQuantizeOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("QUANTIZE", tfLiteContext, IsQuantizeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Quantize, nodeIndex); armnn::IConnectableLayer* quantizeLayer = delegateData.m_Network->AddQuantizeLayer(layerName.c_str()); quantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(quantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = quantizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(quantizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(quantizeLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Redefine.hpp000066400000000000000000000376121446772241200210770ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitCastOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("CAST", tfLiteContext, IsCastSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitCastOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Cast layer auto layerName = GetLayerName(armnn::LayerType::Cast, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddCastLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitReshapeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs == 2) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); } else { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor0 = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor0, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::ReshapeDescriptor reshapeDesc; std::vector targetShape; TfLiteReshapeParams* reshapeOptions = reinterpret_cast(tfLiteNode->builtin_data); // The new shape can be defined by either a second input tensor or by a builtin option, we need to check for both. // Options might be set without valid data. we need to check the dimensions are in a valid range. if (reshapeOptions && reshapeOptions->num_dimensions > 0 && reshapeOptions->num_dimensions <= 8) { for (int i=0; i < reshapeOptions->num_dimensions; ++i) { targetShape.push_back(reshapeOptions->shape[i]); } } else if (numInputs == 2) { // Get shape from the second input tensor const TfLiteTensor& tfLiteShapeInputTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteShapeInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } if (tfLiteShapeInputTensor.dims->size != 1) { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Target 'shape' input is not a 1D tensor in " "operator #%d node #%d: Falling back to TfLiteOptions.", operatorCode, nodeIndex); } else { // Get the shape data out of the input tensor auto* shapeTensorDataPtr = tflite::GetTensorData(&tfLiteShapeInputTensor); auto shapeTensorNumValues = tfLiteShapeInputTensor.dims->data[0]; for (auto i=0; i < shapeTensorNumValues; ++i) { targetShape.push_back(*(shapeTensorDataPtr+i)); } } } else { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "Target shape not defined in reshape parameters or input tensor. " "At least one method required in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } // Use the data to create the required tensor shape. if (CreateOutputTensorShape(inputTensorInfo0, targetShape, reshapeDesc) != kTfLiteOk) { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: At most one component of shape can be -1 in: " "operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } if (reshapeDesc.m_TargetShape.GetNumElements() != inputTensorInfo0.GetNumElements()) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Reshape, number of elements in output shape does not match input " "operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Reshape, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitSqueezeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } auto* options = reinterpret_cast(tfLiteNode->builtin_data); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); std::vector squeezeDim; // A single negative dim index is interpreted as a negative index in python // Meaning the index will be the shape size plus the negative index value if (options->num_squeeze_dims == 1 && options->squeeze_dims[0] < 0) { int32_t dim = static_cast(inputTensorInfo.GetShape().GetNumDimensions()) + options->squeeze_dims[0]; squeezeDim.push_back(static_cast(dim)); } else { for (int32_t i = 0; i < options->num_squeeze_dims; ++i) { squeezeDim.push_back(static_cast(options->squeeze_dims[i])); } } armnn::TensorInfo outputTensorInfo = OutputShapeOfSqueeze(squeezeDim, inputTensorInfo); armnn::ReshapeDescriptor reshapeDesc; reshapeDesc.m_TargetShape = outputTensorInfo.GetShape(); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SQUEEZE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Reshape, nodeIndex, "Squeeze"); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitExpandDimsOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteAxisTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); armnn::TensorInfo outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); auto* axisTensorData = tflite::GetTensorData(&tfLiteAxisTensor); int32_t axis = axisTensorData[0]; int32_t inputDimSize = static_cast(inputTensorInfo.GetShape().GetNumDimensions()); if (axis > inputDimSize || axis < 0 - (inputDimSize + 1)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Axis must be in range " "[0 - (inputDimSize + 1), inputDimSize] inclusive."); return kTfLiteError; } if(axis < 0) { axis = inputDimSize + axis + 1; } std::vector shape(static_cast(inputDimSize) + 1); unsigned int inputShapeIndex = 0; for (unsigned int i = 0; i < static_cast(inputDimSize + 1); ++i) { if (i == static_cast(axis)) { shape[i] = 1; } else { shape[i] = inputTensorInfo.GetShape()[inputShapeIndex]; ++inputShapeIndex; } } armnn::ReshapeDescriptor reshapeDesc; reshapeDesc.m_TargetShape = armnn::TensorShape(static_cast(inputDimSize + 1), shape.data()); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("EXPAND_DIMS", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Reshape, nodeIndex, "ExpandDims"); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputTensorInfo.SetShape(reshapeDesc.m_TargetShape); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Reduce.hpp000066400000000000000000000122471446772241200205620ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitReduceOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t reduceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // Get const axis value from model and set it to descriptor. const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteAxisTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& axisTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteAxisTensor); auto* axisTensorData = tflite::GetTensorData(&tfLiteAxisTensor); std::vector axis; // Add axis data to vector to be converter to unsigned int and assigned to descriptor axis. if (axisTensorData != nullptr) { for (unsigned int i = 0; i < axisTensorInfo.GetNumElements(); ++i) { axis.emplace_back(axisTensorData[i]); } } else { for (unsigned int i = 0; i < inputTensorInfo.GetNumDimensions(); ++i) { axis.push_back(i); } } // Convert the axis to unsigned int and remove duplicates. unsigned int rank = inputTensorInfo.GetNumDimensions(); std::set uniqueAxis; std::transform(axis.begin(), axis.end(), std::inserter(uniqueAxis, uniqueAxis.begin()), [rank](int i)->unsigned int{ return (i + rank) % rank; }); armnn::ReduceDescriptor desc; desc.m_vAxis.assign(uniqueAxis.begin(), uniqueAxis.end()); auto* reducerParameters = reinterpret_cast(tfLiteNode->builtin_data); desc.m_KeepDims = reducerParameters->keep_dims; if (reduceOperatorCode == kTfLiteBuiltinReduceMax) { desc.m_ReduceOperation = armnn::ReduceOperation::Max; } else if (reduceOperatorCode == kTfLiteBuiltinReduceMin) { desc.m_ReduceOperation = armnn::ReduceOperation::Min; } else if (reduceOperatorCode == kTfLiteBuiltinSum) { desc.m_ReduceOperation = armnn::ReduceOperation::Sum; } else if (reduceOperatorCode == kTfLiteBuiltinReduceProd) { desc.m_ReduceOperation = armnn::ReduceOperation::Prod; } else { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Unsupported Reduction Operator #%d node #%d: ", reduceOperatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("REDUCE", tfLiteContext, IsReduceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Reduce layer auto layerName = GetLayerName(armnn::LayerType::Reduce, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReduceLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Resize.hpp000066400000000000000000000177721446772241200206240ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateResizeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, const armnn::ResizeDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("RESIZE", tfLiteContext, IsResizeSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitResizeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t resizeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; // The first input contains the data of the image that should be resized [batch, height, width, channels] const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // The second input contains a size tensor. The size tensor contains two integer values // that describe the new height and width of the image [new_height, new_width] const TfLiteTensor& tfLiteSizeTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteSizeTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // The output tensor should have the shape [batch, new_height, new_width, channels] const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); std::string layerName("Resize"); // Fill descriptor armnn::ResizeDescriptor desc; switch (resizeOperatorCode) { case kTfLiteBuiltinResizeBilinear: { desc.m_Method = armnn::ResizeMethod::Bilinear; layerName += "Bilinear:" + std::to_string(nodeIndex); TfLiteResizeBilinearParams* biliniarOptions = reinterpret_cast(tfLiteNode->builtin_data); desc.m_AlignCorners = biliniarOptions->align_corners; desc.m_HalfPixelCenters = biliniarOptions->half_pixel_centers; break; } case kTfLiteBuiltinResizeNearestNeighbor: { desc.m_Method = armnn::ResizeMethod::NearestNeighbor; layerName += "NearestNeighbor:" + std::to_string(nodeIndex); TfLiteResizeNearestNeighborParams* nearestNeighborOptions = reinterpret_cast(tfLiteNode->builtin_data); desc.m_AlignCorners = nearestNeighborOptions->align_corners; desc.m_HalfPixelCenters = nearestNeighborOptions->half_pixel_centers; break; } default: { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Unknown TfLite built in operation for Resize. Given operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } } // In armnn the values of the size input tensor [new_hight, new_width] is saved in the operator // descriptor. We have to read it from the input tensor and write it to the descriptor. auto* sizeTensorDataPtr = tflite::GetTensorData(&tfLiteSizeTensor); auto sizeTensorNumDimensions = tfLiteSizeTensor.dims->size; // The size tensor is only a 1D tensor -> [new_hight, new width] if (sizeTensorNumDimensions != 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Size-Input-Tensor of the Resize operation is not allowed to be a " "dynamic tensor. Operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // Get number of values in the size tensor auto sizeTensorNumValues = tfLiteSizeTensor.dims->data[0]; if (sizeTensorNumValues == 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Size-Input-Tensor of the Resize operation is not allowed to be a " "dynamic tensor. Operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } else if (sizeTensorNumValues != 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Size-Input-Tensor of the Resize operation requires to " "have a dimension of 2 [new_hight, new width] but a tensor with a dimension of #%d was given. " "Operator: #%d node #%d: ", sizeTensorNumValues, resizeOperatorCode, nodeIndex); return kTfLiteError; } // get size tensor data std::vector sizeTensorData(sizeTensorDataPtr, sizeTensorDataPtr+sizeTensorNumValues); desc.m_TargetHeight = static_cast (sizeTensorData[0]); desc.m_TargetWidth = static_cast (sizeTensorData[1]); desc.m_DataLayout = armnn::DataLayout::NHWC; // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateResizeOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, desc); } auto resizeName = GetLayerName(armnn::LayerType::Resize, nodeIndex); armnn::IConnectableLayer* resizeLayer = delegateData.m_Network->AddResizeLayer(desc, resizeName.c_str()); armnn::IOutputSlot& outputSlot = resizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(resizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } ARMNN_ASSERT(resizeLayer != nullptr); return Connect(resizeLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/ReverseV2.hpp000066400000000000000000000134501446772241200211730ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateReverseV2Operator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo0, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& outputInfo) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("REVERSEV2", tfLiteContext, IsReverseV2Supported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo0, inputInfo1, outputInfo); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitReverseV2Operator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t reverseV2OperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; // The first input contains the data that should be reversed const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // The second input contains an axis tensor. const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteAxisTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // Get the output tensor const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& inputTensorInfo1 = GetTensorInfoForTfLiteTensor(tfLiteAxisTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); if (inputTensorInfo0.GetNumDimensions() != outputTensorInfo.GetNumDimensions()) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: input tensor dimension and output tensor dimension differ #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } for (unsigned i=0; i < inputTensorInfo0.GetNumDimensions(); i++) { if (inputTensorInfo0.GetShape()[i] != outputTensorInfo.GetShape()[i]) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: input tensor dimension and output tensor differ #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } } const auto maxDimension = 4; const auto axisTensorNumValues = static_cast(tfLiteAxisTensor.dims->size); if (axisTensorNumValues > maxDimension) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Axis-Input-Tensor of the ReverseV2 operation requires a " "dimension of <= %d but a tensor with a dimension of %d was given. " "Operator: #%d node #%d: ", maxDimension, axisTensorNumValues, reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateReverseV2Operator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); } auto layerName = GetLayerName(armnn::LayerType::ReverseV2, nodeIndex); armnn::IConnectableLayer* reverseV2Layer = delegateData.m_Network->AddReverseV2Layer(layerName.c_str()); armnn::IOutputSlot& outputSlot = reverseV2Layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Try to connect the Constant Inputs if there are any if (ProcessInputs(reverseV2Layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } ARMNN_ASSERT(reverseV2Layer != nullptr); return Connect(reverseV2Layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Round.hpp000066400000000000000000000053311446772241200204360ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "SharedFunctions.hpp" #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitFloorOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); // NOTE: looks like the outputTensorInfo is the only thing that is required for the case // where we are adding the floor layer so maybe move the other stuff inside the // if !delegateData block for efficiency. const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitFloorOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { return ValidateFloorOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo); } // Add a Floor layer auto layerName = GetLayerName(armnn::LayerType::Floor, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFloorLayer(layerName.c_str()); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Shape.hpp000066400000000000000000000070111446772241200204040ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitShapeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* shapeParameters = reinterpret_cast(tfLiteNode->builtin_data); if (shapeParameters->out_type != kTfLiteInt32 && shapeParameters->out_type != kTfLiteInt64) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: output_type data type is not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SHAPE", tfLiteContext, IsShapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitShapeOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Shape layer auto layerName = GetLayerName(armnn::LayerType::Shape, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddShapeLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/SharedFunctions.cpp000066400000000000000000000073331446772241200224450ustar00rootroot00000000000000// // Copyright © 2021-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SharedFunctions.hpp" #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateFloorOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& outputTensorInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("FLOOR", tfLiteContext, IsFloorSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputTensorInfo, outInfo); }; validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateFusedActivationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, TfLiteFusedActivation activationType) { armnn::ActivationDescriptor activationDesc; switch (activationType) { case kTfLiteActNone: { // No Activation return kTfLiteOk; } case kTfLiteActRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } // The name of kTfLiteActRelu1 changed after TF Lite v2.3 #if defined(ARMNN_POST_TFLITE_2_3) case kTfLiteActReluN1To1: #else case kTfLiteActRelu1: #endif { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 1.0f; activationDesc.m_B = -1.0f; break; } case kTfLiteActRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; activationDesc.m_B = 0.0f; break; } case kTfLiteActSigmoid: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteActTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } default: return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, activationDesc); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/SharedFunctions.hpp000066400000000000000000000016001446772241200224410ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnDelegate { TfLiteStatus ValidateFloorOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& outputTensorInfo); TfLiteStatus ValidateFusedActivationOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, TfLiteFusedActivation activationType); } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Slice.hpp000066400000000000000000000145131446772241200204100ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitSliceOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t sliceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Read inputs [input, begin, size] int numInputs = tfLiteNode->inputs->size; std::vector tfLiteInputs; tfLiteInputs.reserve(numInputs); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; for (int i = 0; i < numInputs; i++) { const TfLiteTensor* inputTensor = &tfLiteTensors[tfLiteNode->inputs->data[i]]; tfLiteInputs.push_back(inputTensor); if (!IsValid(tfLiteContext, *inputTensor, sliceOperatorCode, nodeIndex)) { return kTfLiteError; } } // We save the begin and size tensors in our descriptor. Therefore we have to read those values from inputs int inputRank = tfLiteInputs[0]->dims->size; auto ReadInt32Input = [&](int inputIndex, std::vector& outputData, const char* name) -> TfLiteStatus { if (tfLiteInputs[inputIndex]->type != kTfLiteInt32) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The %s Tensor of the Slice operation needs to " "be of type int32. Operator: #%d node #%d: ", name, sliceOperatorCode, nodeIndex); return kTfLiteError; } int rank = tfLiteInputs[inputIndex]->dims->size; if (rank != 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The %s Tensor of the Slice operation needs to " "be a 1D-Tensor. Operator: #%d node #%d: ", name, sliceOperatorCode, nodeIndex); return kTfLiteError; } int numValues = tfLiteInputs[inputIndex]->dims->data[0]; if (numValues != inputRank) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The number of values in the %s Tensor of the " "Slice operation needs to be equal to the rank of the Input Tensor. Operator: #%d node #%d: ", name, sliceOperatorCode, nodeIndex); return kTfLiteError; } // return tensor data auto* tensorDataPtr = tflite::GetTensorData(tfLiteInputs[inputIndex]); outputData.assign(tensorDataPtr, tensorDataPtr + numValues); return kTfLiteOk; }; std::vector signedBegin; if (ReadInt32Input(1, signedBegin, "Begin") != kTfLiteOk) { return kTfLiteError; } std::vector signedSize; if (ReadInt32Input(2, signedSize, "Size") != kTfLiteOk) { return kTfLiteError; } std::vector begin({ signedBegin.begin(), signedBegin.end() }); std::vector size(signedSize.size()); for (unsigned int i = 0; i < signedSize.size(); ++i) { int signedValue = signedSize[i]; if (signedValue < -1 || signedValue > tfLiteInputs[0]->dims->data[i] - signedBegin[i]) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid value for Size. Size must be in range [-1, inputDimSize - begin] " "[-1, %d] inclusive but was %d Operator: #%d node #%d: ", tfLiteInputs[0]->dims->data[i] - signedBegin[i], signedValue, sliceOperatorCode, nodeIndex); return kTfLiteError; } if (signedValue == -1) { size[i] = tfLiteInputs[0]->dims->data[i] - signedBegin[i]; } else { size[i] = static_cast(signedValue); } } // Write all data to the descriptor armnn::SliceDescriptor descriptor(begin, size); // Validate output const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, sliceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(*tfLiteInputs[0]); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SLICE", tfLiteContext, IsSliceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Slice layer auto layerName = GetLayerName(armnn::LayerType::Slice, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSliceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Softmax.hpp000066400000000000000000000136621446772241200207760ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateSoftmaxOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputTensorInfo, const armnn::SoftmaxDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("SOFTMAX", tfLiteContext, IsSoftmaxSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateLogSoftmaxOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputTensorInfo, const armnn::LogSoftmaxDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("LOG_SOFTMAX", tfLiteContext, IsLogSoftmaxSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitSoftmaxOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t softmaxOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in node #%d: ", nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); if (!delegateData.m_Network) { switch(softmaxOperatorCode) { case kTfLiteBuiltinSoftmax: { armnn::SoftmaxDescriptor descriptor; auto* params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_Beta = params->beta; return ValidateSoftmaxOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, descriptor); } case kTfLiteBuiltinLogSoftmax: { armnn::LogSoftmaxDescriptor descriptor; return ValidateLogSoftmaxOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, descriptor); } default: return kTfLiteError; } } auto layerName = GetLayerName(armnn::LayerType::Softmax, nodeIndex); armnn::IConnectableLayer* softmaxLayer = nullptr; switch(softmaxOperatorCode) { case kTfLiteBuiltinSoftmax: { armnn::SoftmaxDescriptor descriptor; auto* params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_Beta = params->beta; softmaxLayer = delegateData.m_Network->AddSoftmaxLayer(descriptor, layerName.c_str()); break; } case kTfLiteBuiltinLogSoftmax: { armnn::LogSoftmaxDescriptor descriptor; softmaxLayer = delegateData.m_Network->AddLogSoftmaxLayer(descriptor, layerName.c_str()); break; } default: return kTfLiteError; } ARMNN_ASSERT(softmaxLayer != nullptr); armnn::IOutputSlot& outputSlot = softmaxLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(softmaxLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(softmaxLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/SpaceDepth.hpp000066400000000000000000000135321446772241200213710ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitSpaceToDepthOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::SpaceToDepthDescriptor descriptor; auto* params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_BlockSize = params->block_size; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("SPACE_TO_DEPTH", tfLiteContext, IsSpaceToDepthSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a SpaceToDepth layer auto layerName = GetLayerName(armnn::LayerType::SpaceToDepth, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToDepthLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(layer, tfLiteNode, delegateData); } TfLiteStatus VisitDepthToSpaceOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); armnn::DepthToSpaceDescriptor descriptor; auto* params = reinterpret_cast(tfLiteNode->builtin_data); descriptor.m_BlockSize = params->block_size; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("DEPTH_TO_SPACE", tfLiteContext, IsDepthToSpaceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a DepthToSpace layer auto layerName = GetLayerName(armnn::LayerType::DepthToSpace, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthToSpaceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Split.hpp000066400000000000000000000321321446772241200204410ustar00rootroot00000000000000// // Copyright © 2020,2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { constexpr unsigned int MaxNumOfTensorDimensions = 5U; TfLiteStatus VisitSplitOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteSplitOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); auto* splitParameters = reinterpret_cast(tfLiteNode->builtin_data); const unsigned int numSplits = NonNegative(splitParameters->num_splits, nodeIndex); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, numSplits, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteAxisTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); if (GetTensorInfoForTfLiteTensor(tfLiteAxisTensor).GetNumElements() != 1) { return kTfLiteError; } auto* axisTensorDataPtr = tflite::GetTensorData(&tfLiteAxisTensor); std::vector axisTensorData(axisTensorDataPtr, axisTensorDataPtr + 1); int32_t axis = axisTensorData[0]; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { // Square bracket denotes inclusive n while parenthesis denotes exclusive n // E.g. Rank 4 tensor can have axis in range [-4, 3) // -1 == 3, -2 == 2, -3 == 1, -4 == 0 TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Operation has invalid axis: #%d. Axis must be in range [-n, n) in node #%d:", axis, nodeIndex); } const unsigned int splitDim = ComputeWrappedIndex(axis, inputTensorInfo.GetNumDimensions()); std::vector outputs; for (unsigned int i = 0; i < numSplits; ++i) { const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[i]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); auto inputDimSize = inputTensorInfo.GetNumDimensions(); if (inputDimSize > MaxNumOfTensorDimensions) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The number of dimensions: #%d for input tensors of the split op cannot be greater " "than #%d in node #%d: ", inputDimSize, MaxNumOfTensorDimensions, nodeIndex); return kTfLiteError; } std::vector splitterDimSizes(inputDimSize); // Add current input shape to splitterDimSizes for (unsigned int i = 0; i < inputDimSize; ++i) { splitterDimSizes[i] = inputTensorInfo.GetShape()[i]; } if (splitterDimSizes[splitDim] % numSplits != 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Number of splits #%d must evenly divide the dimension #%d in node #%d: ", numSplits, splitterDimSizes[splitDim], nodeIndex); return kTfLiteError; } splitterDimSizes[splitDim] /= numSplits; armnn::SplitterDescriptor splitDescriptor(numSplits, inputDimSize); for (unsigned int j = 0; j < numSplits; ++j) { // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx) { splitDescriptor.SetViewSize(j, dimIdx, splitterDimSizes[dimIdx]); } splitDescriptor.SetViewOriginCoord(j, splitDim, splitterDimSizes[splitDim] * j); } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("SPLIT", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Splitter, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) { layer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // Connect the input slots delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[1]]->Connect(layer->GetInputSlot(0)); // Prepare output slots for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex) { armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex); delegateData.m_OutputSlotForNode[ static_cast(tfLiteNode->outputs->data[outputIndex])] = &outputSlot; } return kTfLiteOk; } TfLiteStatus VisitSplitVOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfLiteSplitVOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteSplitsTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (!IsValid(tfLiteContext, tfLiteSplitsTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteAxisTensor = tfLiteTensors[tfLiteNode->inputs->data[2]]; if (!IsValid(tfLiteContext, tfLiteAxisTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& splitsTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteSplitsTensor); if (splitsTensorInfo.GetNumDimensions() != 1) { return kTfLiteError; } if (GetTensorInfoForTfLiteTensor(tfLiteAxisTensor).GetNumElements() != 1) { return kTfLiteError; } auto* axisTensorDataPtr = tflite::GetTensorData(&tfLiteAxisTensor); std::vector axisTensorData(axisTensorDataPtr, axisTensorDataPtr + 1); int32_t axis = axisTensorData[0]; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Operation has invalid axis: #%d. Axis must be in range [-n, n) in node #%d:", axis, nodeIndex); } const unsigned int splitDim = ComputeWrappedIndex(axisTensorData[0], inputTensorInfo.GetNumDimensions()); auto* splitVParameters = reinterpret_cast(tfLiteNode->builtin_data); unsigned int numSplits = 0; if (splitVParameters) { numSplits = NonNegative(splitVParameters->num_splits, nodeIndex); } else { numSplits = splitsTensorInfo.GetNumElements(); } if (numSplits <= 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid number of splits %d in node #%d", numSplits, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, numSplits, nodeIndex)); std::vector outputs; for (unsigned int i = 0; i < numSplits; ++i) { const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[i]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); auto inputDimSize = inputTensorInfo.GetNumDimensions(); if (inputDimSize > MaxNumOfTensorDimensions) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The number of dimensions: #%d for input tensors of the split op cannot be greater " "than #%d in node #%d: ", inputDimSize, MaxNumOfTensorDimensions, nodeIndex); return kTfLiteError; } std::vector splitsTensorData(numSplits); std::memcpy(splitsTensorData.data(), tfLiteSplitsTensor.data.data, splitsTensorInfo.GetNumBytes()); unsigned int index = 0; unsigned int inferredIndex = 0; int numberOfInferred = 0; int splitSum = 0; for (auto splitData : splitsTensorData) { if (splitData < 0) { ++numberOfInferred; inferredIndex = index; } else { splitSum += splitData; } ++index; } // Check for inferred axis if (numberOfInferred == 0) { if (splitSum != armnn::numeric_cast(inputTensorInfo.GetShape()[splitDim])) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: SplitV split_sizes does not sum to the dimension of value along" " split_dim in node #%d", nodeIndex); return kTfLiteError; } } else if (numberOfInferred == 1) { splitsTensorData[inferredIndex] = armnn::numeric_cast(inputTensorInfo.GetShape()[splitDim]) - splitSum; } else { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: SplitV cannot infer split size for more than one split in node #%d", nodeIndex); return kTfLiteError; } armnn::SplitterDescriptor splitDescriptor(numSplits, inputDimSize); unsigned int accumSplit = 0; for (unsigned int j = 0; j < numSplits; ++j) { unsigned int splitSize = armnn::numeric_cast(splitsTensorData[j]); // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < inputTensorInfo.GetNumDimensions(); ++dimIdx) { unsigned int dimSize = inputTensorInfo.GetShape()[dimIdx]; if (dimIdx == splitDim) { dimSize = splitSize; } splitDescriptor.SetViewSize(j, dimIdx, dimSize); } splitDescriptor.SetViewOriginCoord(j, splitDim, accumSplit); accumSplit += splitSize; } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("SPLIT", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) { layer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/StridedSlice.hpp000066400000000000000000000142211446772241200217230ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t sliceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 4, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Read inputs [input, begin, end, strides] int numInputs = tfLiteNode->inputs->size; std::vector tfLiteInputs; tfLiteInputs.reserve(numInputs); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; for (int i = 0; i < numInputs; i++) { const TfLiteTensor* inputTensor = &tfLiteTensors[tfLiteNode->inputs->data[i]]; tfLiteInputs.push_back(inputTensor); if (!IsValid(tfLiteContext, *inputTensor, sliceOperatorCode, nodeIndex)) { return kTfLiteError; } } // We save the begin, end and strides tensors in our descriptor. Therefore we have to read those values from inputs int inputRank = tfLiteInputs[0]->dims->size; auto ReadInt32Input = [&](int inputIndex, std::vector& outputData) -> TfLiteStatus { if (tfLiteInputs[inputIndex]->type != kTfLiteInt32) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need to " "be of type int32. Operator: #%d node #%d: ", sliceOperatorCode, nodeIndex); return kTfLiteError; } int rank = tfLiteInputs[inputIndex]->dims->size; if (rank != 1) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need to " "be a 1D-Tensor. Operator: #%d node #%d: ", sliceOperatorCode, nodeIndex); return kTfLiteError; } int numValues = tfLiteInputs[inputIndex]->dims->data[0]; if (numValues != inputRank) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The number of values in the Begin-, End- and Stride-Tensors of the " "StridedSlice operation need to be equal to the rank of the Input-Tensor. Operator: #%d node #%d: ", sliceOperatorCode, nodeIndex); return kTfLiteError; } // return tensor data auto* tensorDataPtr = tflite::GetTensorData(tfLiteInputs[inputIndex]); outputData.assign(tensorDataPtr, tensorDataPtr+numValues); return kTfLiteOk; }; std::vector beginData; if (ReadInt32Input(1, beginData) != kTfLiteOk) return kTfLiteError; std::vector endData; if (ReadInt32Input(2, endData) != kTfLiteOk) return kTfLiteError; std::vector strideData; if (ReadInt32Input(3, strideData) != kTfLiteOk) return kTfLiteError; // parse built in options auto* stridedSliceParams = reinterpret_cast(tfLiteNode->builtin_data); // Write all data to the descriptor armnn::StridedSliceDescriptor descriptor; descriptor.m_Begin = std::move(beginData); descriptor.m_End = std::move(endData); descriptor.m_Stride = std::move(strideData); descriptor.m_BeginMask = stridedSliceParams->begin_mask; descriptor.m_EllipsisMask = stridedSliceParams->ellipsis_mask; descriptor.m_EndMask = stridedSliceParams->end_mask; descriptor.m_NewAxisMask = stridedSliceParams->new_axis_mask; descriptor.m_ShrinkAxisMask = stridedSliceParams->shrink_axis_mask; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Validate output const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, sliceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(*tfLiteInputs[0]); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("STRIDED_SLICE", tfLiteContext, IsStridedSliceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a StridedSlice layer auto layerName = GetLayerName(armnn::LayerType::StridedSlice, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddStridedSliceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/Tile.hpp000066400000000000000000000147611446772241200202530ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus ValidateTileOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, const armnn::TileDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("TILE", tfLiteContext, IsTileSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitTileOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tileOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; // The input contains the data that should be tiled const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // The multiples tensor contains the number of copies for each axis const TfLiteTensor& tfLiteMultiplesTensor = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteMultiplesTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // The output tensor const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& multiplesTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteMultiplesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor); // Multiples length must be the same as the number of dimension in input tensor if (multiplesTensorInfo.GetNumElements() != inputTensorInfo.GetNumDimensions()) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Multiples length must be the same as the number of dimension in input tensor", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // Get the Multiples data: In armnn, the values of the multiples input tensor is saved in the operator descriptor // We have to read it from the input tensor and write it the descriptor auto* multiplesTensorDataPtr = tflite::GetTensorData(&tfLiteMultiplesTensor); auto multiplesTensorNum = tfLiteMultiplesTensor.dims->data[0]; std::vector multiplesIntData(multiplesTensorDataPtr, multiplesTensorDataPtr + multiplesTensorNum); // The multiples must be positive for (auto multiple : multiplesIntData) { if (multiple < 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The Multiples must be positive values", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } } // The original input from TFLite is int32, and we have to make it as uint32 for our descriptor std::vector multiplesUintData; std::transform(multiplesIntData.begin(), multiplesIntData.end(), std::back_inserter(multiplesUintData), [] (const int value) { return static_cast(value); }); armnn::TileDescriptor tileDescriptor; tileDescriptor.m_Multiples = multiplesUintData; // Check output dimensions if (inputTensorInfo.GetNumDimensions() != outputTensorInfo.GetNumDimensions()) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Input tensor dimension and output tensor dimension differ", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateTileOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, tileDescriptor); } auto layerName = GetLayerName(armnn::LayerType::Tile, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddTileLayer(tileDescriptor, layerName.c_str()); if (layer == nullptr) { return kTfLiteError; } layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(layer, tfLiteNode, delegateData); } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/Transpose.hpp000066400000000000000000000112341446772241200213240ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitTransposeOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t tfliteTransposeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor *tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor0 = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (IsDynamicTensor(tfLiteInputTensor0)) { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in " "operator #%d node #%d: ", tfliteTransposeOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteInputTensor1 = tfLiteTensors[tfLiteNode->inputs->data[1]]; if (IsDynamicTensor(tfLiteInputTensor1)) { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Dynamic input tensors are not supported in " "operator #%d node #%d: ", tfliteTransposeOperatorCode, nodeIndex); return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_MAYBE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Dynamic output tensors are not supported in " "operator #%d node #%d: ", tfliteTransposeOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteTensor(tfLiteInputTensor0); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); auto* permTensorDataPtr = tflite::GetTensorData(&tfLiteInputTensor1); unsigned int numEl = tfLiteInputTensor1.dims->data[0]; if (numEl > static_cast(armnn::MaxNumOfTensorDimensions)) { return kTfLiteError; } if (tfLiteInputTensor1.dims->size != 1) { return kTfLiteError; } armnn::TransposeDescriptor descriptor(armnn::PermutationVector( reinterpret_cast (permTensorDataPtr), static_cast(numEl))); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("TRANSPOSE", tfLiteContext, IsTransposeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::Transpose, nodeIndex); armnn::IConnectableLayer* transposeLayer = delegateData.m_Network->AddTransposeLayer(descriptor, layerName.c_str()); transposeLayer->SetBackendId(setBackend); ARMNN_ASSERT(transposeLayer != nullptr); // permutation vector given to descriptor object if (transposeLayer->GetNumInputSlots() != 1) { return kTfLiteError; } armnn::IOutputSlot& outputSlot = transposeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(transposeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(transposeLayer, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/UnidirectionalSequenceLstm.hpp000066400000000000000000000334311446772241200246530ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitUnidirectionalSequenceLstmOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = tfLiteNode->inputs->size; if (numInputs < 2) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } const auto nodeParams = reinterpret_cast(tfLiteNode->builtin_data); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Set the params structure for the AddUnidirectionalSequenceLstmLayer call // Please refer to each operand at // https://www.tensorflow.org/mlir/tfl_ops#tflunidirectional_sequence_lstm_tflunidirectionalsequencelstmop armnn::LstmInputParams params; if (IsOptionalOperandPresent(tfLiteNode, 1)) { params.m_InputToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 1); } params.m_InputToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 2); params.m_InputToCellWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 3); params.m_InputToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 4); // Recurrent weight tensors of size {n_cell, n_output} if (IsOptionalOperandPresent(tfLiteNode, 5)) { params.m_RecurrentToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 5); } params.m_RecurrentToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 6); params.m_RecurrentToCellWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 7); params.m_RecurrentToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 8); // Peephole weights tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 9)) { params.m_CellToInputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 9); } if (IsOptionalOperandPresent(tfLiteNode, 10)) { params.m_CellToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 10); } if (IsOptionalOperandPresent(tfLiteNode, 11)) { params.m_CellToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 11); } // Gates bias tensors of size {n_cell} if (IsOptionalOperandPresent(tfLiteNode, 12)) { params.m_InputGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 12); } params.m_ForgetGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 13); params.m_CellBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 14); params.m_OutputGateBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 15); // Projection weight tensor of size {n_output, n_cell} if (IsOptionalOperandPresent(tfLiteNode, 16)) { params.m_ProjectionWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 16); } // Projection bias tensor of size {n_output} if (IsOptionalOperandPresent(tfLiteNode, 17)) { params.m_ProjectionBias = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 17); } // These state tensors are defined as variable tensors, and will be modified by this op. armnn::TensorInfo outputStateInInfo = GetTensorInfoForTfLiteTensor(tfLiteTensors[tfLiteNode->inputs->data[18]]); armnn::TensorInfo cellStateInInfo = GetTensorInfoForTfLiteTensor(tfLiteTensors[tfLiteNode->inputs->data[19]]); // Layer norm coefficient tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 20)) { params.m_InputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 20); } if (IsOptionalOperandPresent(tfLiteNode, 21)) { params.m_ForgetLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 21); } if (IsOptionalOperandPresent(tfLiteNode, 22)) { params.m_CellLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 22); } if (IsOptionalOperandPresent(tfLiteNode, 23)) { params.m_OutputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteTensors, tfLiteNode, 23); } // set the layer descriptor armnn::UnidirectionalSequenceLstmDescriptor desc; desc.m_ActivationFunc = NonNegative(nodeParams->activation, nodeIndex); desc.m_ClippingThresCell = nodeParams->cell_clip; desc.m_ClippingThresProj = nodeParams->proj_clip; desc.m_CifgEnabled = (params.m_InputToInputWeights == nullptr || params.m_RecurrentToInputWeights == nullptr || params.m_InputGateBias == nullptr); desc.m_PeepholeEnabled = (params.m_CellToForgetWeights != nullptr || params.m_CellToOutputWeights != nullptr); desc.m_ProjectionEnabled = (params.m_ProjectionWeights != nullptr); desc.m_LayerNormEnabled = (params.m_InputLayerNormWeights != nullptr || params.m_ForgetLayerNormWeights != nullptr || params.m_CellLayerNormWeights != nullptr || params.m_OutputLayerNormWeights != nullptr); desc.m_TimeMajor = nodeParams->time_major; if (tfLiteNode->intermediates->size > 3 && desc.m_LayerNormEnabled) { auto inputIntermediateTensorInfo = GetTensorInfoForTfLiteTensor( tfLiteTensors[tfLiteNode->intermediates->data[0]]); auto forgetIntermediateTensorInfo = GetTensorInfoForTfLiteTensor( tfLiteTensors[tfLiteNode->intermediates->data[1]]); auto cellIntermediateTensorInfo = GetTensorInfoForTfLiteTensor( tfLiteTensors[tfLiteNode->intermediates->data[2]]); auto outputIntermediateTensorInfo = GetTensorInfoForTfLiteTensor( tfLiteTensors[tfLiteNode->intermediates->data[3]]); desc.m_InputIntermediateScale = inputIntermediateTensorInfo.GetQuantizationScale(); desc.m_ForgetIntermediateScale = forgetIntermediateTensorInfo.GetQuantizationScale(); desc.m_CellIntermediateScale = cellIntermediateTensorInfo.GetQuantizationScale(); desc.m_OutputIntermediateScale = outputIntermediateTensorInfo.GetQuantizationScale(); } else { float defaultIntermediate = std::pow(2, -12); desc.m_InputIntermediateScale = defaultIntermediate; desc.m_ForgetIntermediateScale = defaultIntermediate; desc.m_CellIntermediateScale = defaultIntermediate; desc.m_OutputIntermediateScale = defaultIntermediate; } if (tfLiteNode->intermediates->size > 4) { auto hiddentensorInfo = GetTensorInfoForTfLiteTensor(tfLiteTensors[tfLiteNode->intermediates->data[4]]); desc.m_HiddenStateScale = hiddentensorInfo.GetQuantizationScale(); desc.m_HiddenStateZeroPoint = hiddentensorInfo.GetQuantizationOffset(); } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true); unsigned int batchSize = inputTensorInfo.GetShape()[0]; unsigned int outputSize = outputTensorInfo.GetShape()[2]; unsigned int numUnits = cellStateInInfo.GetShape()[1]; armnn::DataType dataType = inputTensorInfo.GetDataType(); float qScale = inputTensorInfo.GetQuantizationScale(); float qOffset = inputTensorInfo.GetQuantizationOffset(); armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 3}, dataType, qScale, qOffset); if (!desc.m_CifgEnabled) { scratchBufferTensorInfo = armnn::TensorInfo({batchSize, numUnits * 4}, dataType, qScale, qOffset); } armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, cellStateInInfo.GetDataType(), cellStateInInfo.GetQuantizationScale(), cellStateInInfo.GetQuantizationOffset()); armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, dataType, qScale, qOffset); armnn::LstmInputParamsInfo paramsInfo; paramsInfo.m_InputToForgetWeights = &(params.m_InputToForgetWeights->GetInfo()); paramsInfo.m_InputToCellWeights = &(params.m_InputToCellWeights->GetInfo()); paramsInfo.m_InputToOutputWeights = &(params.m_InputToOutputWeights->GetInfo()); paramsInfo.m_RecurrentToForgetWeights = &(params.m_RecurrentToForgetWeights->GetInfo()); paramsInfo.m_RecurrentToCellWeights = &(params.m_RecurrentToCellWeights->GetInfo()); paramsInfo.m_RecurrentToOutputWeights = &(params.m_RecurrentToOutputWeights->GetInfo()); paramsInfo.m_ForgetGateBias = &(params.m_ForgetGateBias->GetInfo()); paramsInfo.m_CellBias = &(params.m_CellBias->GetInfo()); paramsInfo.m_OutputGateBias = &(params.m_OutputGateBias->GetInfo()); if (!desc.m_CifgEnabled) { paramsInfo.m_InputToInputWeights = &(params.m_InputToInputWeights->GetInfo()); paramsInfo.m_RecurrentToInputWeights = &(params.m_RecurrentToInputWeights->GetInfo()); if (params.m_CellToInputWeights != nullptr) { paramsInfo.m_CellToInputWeights = &(params.m_CellToInputWeights->GetInfo()); } paramsInfo.m_InputGateBias = &(params.m_InputGateBias->GetInfo()); } if (desc.m_ProjectionEnabled) { paramsInfo.m_ProjectionWeights = &(params.m_ProjectionWeights->GetInfo()); if (params.m_ProjectionBias != nullptr) { paramsInfo.m_ProjectionBias = &(params.m_ProjectionBias->GetInfo()); } } if (desc.m_PeepholeEnabled) { paramsInfo.m_CellToForgetWeights = &(params.m_CellToForgetWeights->GetInfo()); paramsInfo.m_CellToOutputWeights = &(params.m_CellToOutputWeights->GetInfo()); } if (desc.m_LayerNormEnabled) { if(!desc.m_CifgEnabled) { paramsInfo.m_InputLayerNormWeights = &(params.m_InputLayerNormWeights->GetInfo()); } paramsInfo.m_ForgetLayerNormWeights = &(params.m_ForgetLayerNormWeights->GetInfo()); paramsInfo.m_CellLayerNormWeights = &(params.m_CellLayerNormWeights->GetInfo()); paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo()); } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_SUPPORT_FUNC("UNIDIRECTIONAL_SEQUENCE_LSTM", tfLiteContext, IsUnidirectionalSequenceLstmSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, outputStateOutTensorInfo, cellStateOutTensorInfo, outputInfo, desc, paramsInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetLayerName(armnn::LayerType::UnidirectionalSequenceLstm, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddUnidirectionalSequenceLstmLayer(desc, params, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo); layer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo); layer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo); // Connect the inputs // input_layer delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[0]]->Connect(layer->GetInputSlot(0)); // cellStateIn delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[18]]->Connect(layer->GetInputSlot(1)); //outputStateIn delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[19]]->Connect(layer->GetInputSlot(2)); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(2); delegateData.m_OutputSlotForNode[static_cast(tfLiteNode->outputs->data[0])] = &outputSlot; return kTfLiteOk; } } // namespace armnnDelegatearmnn-23.08/delegate/classic/src/Unpack.hpp000066400000000000000000000210441446772241200205670ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include namespace armnnDelegate { TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors; const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[0]]; if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Get Unpack Axis const auto params = reinterpret_cast(tfLiteNode->builtin_data); const unsigned int unpackAxis = NonNegative(params->axis, nodeIndex); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor); if (unpackAxis >= inputTensorInfo.GetNumDimensions()) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: The unpack axis #%d cannot be greater than or equal to " "the number of input dimensions #%d in operator #%d node #%d", unpackAxis, inputTensorInfo.GetNumDimensions(), operatorCode, nodeIndex); return kTfLiteError; } // Get Unpack Num unsigned int unpackNum = NonNegative(params->num, nodeIndex); // If num is not defined, automatically infer from the length of the dimension axis. if(unpackNum == 0) { unpackNum = inputTensorInfo.GetShape()[unpackAxis]; } // If unpack number cannot be inferred and is still zero, return kTfLiteError. if(unpackNum == 0) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Number to unpack must greater than zero in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } // Check outputs TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, unpackNum, nodeIndex)); auto inputDimSize = inputTensorInfo.GetNumDimensions(); std::vector unpackDimSizes(inputDimSize); // Add current input shape to unpackDimSizes for (unsigned int i = 0; i < inputDimSize; ++i) { unpackDimSizes[i] = inputTensorInfo.GetShape()[i]; } if (unpackDimSizes[unpackAxis] != unpackNum) { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Number to unpack must be the same as length " "of the dimension to unpack along in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } unpackDimSizes[unpackAxis] /= unpackNum; armnn::SplitterDescriptor splitDesc(unpackNum, static_cast(unpackDimSizes.size())); for (unsigned int j = 0; j < unpackNum; ++j) { // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < unpackDimSizes.size(); ++dimIdx) { splitDesc.SetViewSize(j, dimIdx, unpackDimSizes[dimIdx]); } splitDesc.SetViewOriginCoord(j, unpackAxis, unpackDimSizes[unpackAxis] * j); } std::vector outputs; for (unsigned int i = 0; i < unpackNum; ++i) { const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[i]]; if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); // Determine the shape of the Splitter layer outputs for validation armnn::TensorShape splitOutShape = armnn::TensorShape(static_cast(unpackDimSizes.size()), unpackDimSizes.data()); std::vector splitterOutputs; for (unsigned int outputIndex = 0; outputIndex < outputTensorInfos.size(); ++outputIndex) { splitterOutputs.push_back(armnn::TensorInfo(splitOutShape, outputTensorInfos[outputIndex].get().GetDataType(), outputTensorInfos[outputIndex].get().GetQuantizationScale(), outputTensorInfos[outputIndex].get().GetQuantizationOffset())); } std::vector> splitterOutputTensorInfos(splitterOutputs.begin(), splitterOutputs.end()); armnn::BackendId setBackendSplit; if (!delegateData.m_Network) { // Check if splitter is supported bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("UNPACK", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackendSplit, inputTensorInfo, splitterOutputTensorInfos, splitDesc); return isSupported ? kTfLiteOk : kTfLiteError; } // Create Reshape descriptor from the first outputTensorInfo to validate a single Reshape layer // Use this descriptor later when creating every ReshapeLayer as all Reshape Layers should be the same armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = outputTensorInfos[0].get().GetShape(); armnn::BackendId setBackendReshape; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackendReshape, splitterOutputTensorInfos[0], outputTensorInfos[0], reshapeDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; }; auto layerName = GetLayerName(armnn::LayerType::Splitter, nodeIndex, "Unpack"); armnn::IConnectableLayer* splitterLayer = delegateData.m_Network->AddSplitterLayer(splitDesc, layerName.c_str()); splitterLayer->SetBackendId(setBackendSplit); ARMNN_ASSERT(splitterLayer != nullptr); for (unsigned int k = 0; k < splitterLayer->GetNumOutputSlots(); ++k) { splitterLayer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // Connect the input slots delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[0]]->Connect(splitterLayer->GetInputSlot(0)); // Create reshape to remove the unpacked dimension for unpack operator of each output from Splitter. for (unsigned int outputIndex = 0; outputIndex < splitterLayer->GetNumOutputSlots(); ++outputIndex) { auto reshapeName = GetLayerName(armnn::LayerType::Reshape, nodeIndex, "Unpack"); armnn::IConnectableLayer* reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor, reshapeName.c_str()); reshapeLayer->SetBackendId(setBackendReshape); ARMNN_ASSERT(reshapeLayer != nullptr); splitterLayer->GetOutputSlot(outputIndex).SetTensorInfo(splitterOutputTensorInfos[outputIndex]); splitterLayer->GetOutputSlot(outputIndex).Connect(reshapeLayer->GetInputSlot(0)); armnn::TensorInfo outputTensorInfo = outputTensorInfos[outputIndex]; reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); armnn::IOutputSlot& slot = reshapeLayer->GetOutputSlot(0); delegateData.m_OutputSlotForNode[ static_cast(tfLiteNode->outputs->data[outputIndex])] = &slot; } return kTfLiteOk; } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/armnn_delegate.cpp000066400000000000000000001435441446772241200223200ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include "Version.hpp" #include "Activation.hpp" #include "ArgMinMax.hpp" #include "BatchMatMul.hpp" #include "BatchSpace.hpp" #include "Comparison.hpp" #include "Convolution.hpp" #include "Control.hpp" #include "ElementwiseBinary.hpp" #include "ElementwiseUnary.hpp" #include "Fill.hpp" #include "FullyConnected.hpp" #include "Gather.hpp" #include "GatherNd.hpp" #include "LogicalBinary.hpp" #include "Lstm.hpp" #include "Normalization.hpp" #include "Pack.hpp" #include "Pad.hpp" #include "Pooling.hpp" #include "Prelu.hpp" #include "Quantization.hpp" #include "Redefine.hpp" #include "Reduce.hpp" #include "Resize.hpp" #include "ReverseV2.hpp" #include "Round.hpp" #include "Shape.hpp" #include "Slice.hpp" #include "StridedSlice.hpp" #include "Softmax.hpp" #include "SpaceDepth.hpp" #include "Split.hpp" #include "Tile.hpp" #include "Transpose.hpp" #include "UnidirectionalSequenceLstm.hpp" #include "Unpack.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { DelegateOptions TfLiteArmnnDelegateOptionsDefault() { DelegateOptions options(armnn::Compute::CpuRef); return options; } TfLiteDelegate* TfLiteArmnnDelegateCreate(armnnDelegate::DelegateOptions options) { auto* armnnDelegate = new ::armnnDelegate::Delegate(options); return armnnDelegate->GetDelegate(); } void TfLiteArmnnDelegateDelete(TfLiteDelegate* tfLiteDelegate) { if (tfLiteDelegate != nullptr) { delete static_cast<::armnnDelegate::Delegate*>(tfLiteDelegate->data_); } } TfLiteStatus DoPrepare(TfLiteContext* tfLiteContext, TfLiteDelegate* tfLiteDelegate) { TfLiteIntArray* supportedOperators = static_cast<::armnnDelegate::Delegate*>(tfLiteDelegate->data_)->IdentifyOperatorsToDelegate(tfLiteContext); // ArmNN Delegate Registration static const TfLiteRegistration kArmnnSubgraphRegistration = { // ArmnnSubgraph Init .init = [](TfLiteContext* tfLiteContext, const char* buffer, size_t length) -> void* { armnn::IgnoreUnused(length); const TfLiteDelegateParams* parameters = reinterpret_cast(buffer); return static_cast(ArmnnSubgraph::Create( tfLiteContext, parameters, static_cast<::armnnDelegate::Delegate*>(parameters->delegate->data_))); }, // ArmnnSubgraph Free .free = [](TfLiteContext* tfLiteContext, void* buffer) -> void { armnn::IgnoreUnused(tfLiteContext); if (buffer != nullptr) { delete static_cast(buffer); } }, // ArmnnSubgraph Prepare .prepare = [](TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode) -> TfLiteStatus { if (tfLiteNode->user_data == nullptr) { return kTfLiteError; } return static_cast(tfLiteNode->user_data)->Prepare(tfLiteContext); }, // ArmnnSubgraph Invoke .invoke = [](TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode) -> TfLiteStatus { if (tfLiteNode->user_data == nullptr) { return kTfLiteError; } return static_cast(tfLiteNode->user_data)->Invoke(tfLiteContext, tfLiteNode); }, .profiling_string = nullptr, .builtin_code = kTfLiteBuiltinDelegate, .custom_name = "TfLiteArmNnDelegate", .version = 1, .registration_external = nullptr, }; const TfLiteStatus status = tfLiteContext->ReplaceNodeSubsetsWithDelegateKernels( tfLiteContext, kArmnnSubgraphRegistration, supportedOperators, tfLiteDelegate); TfLiteIntArrayFree(supportedOperators); return status; } Delegate::Delegate(armnnDelegate::DelegateOptions options) : m_Options(std::move(options)) { // Configures logging for ARMNN if (m_Options.IsLoggingEnabled()) { armnn::ConfigureLogging(true, true, m_Options.GetLoggingSeverity()); } // Create/Get the static ArmNN Runtime. Note that the m_Runtime will be shared by all armnn_delegate // instances so the RuntimeOptions cannot be altered for different armnn_delegate instances. m_Runtime = GetRuntime(m_Options.GetRuntimeOptions()); std::vector backends; if (m_Runtime) { const armnn::BackendIdSet supportedDevices = m_Runtime->GetDeviceSpec().GetSupportedBackends(); for (auto& backend : m_Options.GetBackends()) { if (std::find(supportedDevices.cbegin(), supportedDevices.cend(), backend) == supportedDevices.cend()) { TFLITE_LOG_PROD(tflite::TFLITE_LOG_INFO, "TfLiteArmnnDelegate: Requested unknown backend %s", backend.Get().c_str()); } else { backends.push_back(backend); } } } if (backends.empty()) { // No known backend specified throw armnn::InvalidArgumentException("TfLiteArmnnDelegate: No known backend specified."); } m_Options.SetBackends(backends); TFLITE_LOG_PROD_ONCE(tflite::TFLITE_LOG_INFO, "TfLiteArmnnDelegate: Created TfLite ArmNN delegate."); } TfLiteIntArray* Delegate::IdentifyOperatorsToDelegate(TfLiteContext* tfLiteContext) { TfLiteIntArray* executionPlan = nullptr; if (tfLiteContext->GetExecutionPlan(tfLiteContext, &executionPlan) != kTfLiteOk) { TF_LITE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Unable to get graph execution plan."); return nullptr; } // Delegate data with null network DelegateData delegateData(m_Options.GetBackends()); TfLiteIntArray* nodesToDelegate = TfLiteIntArrayCreate(executionPlan->size); nodesToDelegate->size = 0; std::set unsupportedOperators; for (int i = 0; i < executionPlan->size; ++i) { const int nodeIndex = executionPlan->data[i]; // If TfLite nodes can be delegated to ArmNN TfLiteNode* tfLiteNode = nullptr; TfLiteRegistration* tfLiteRegistration = nullptr; if (tfLiteContext->GetNodeAndRegistration( tfLiteContext, nodeIndex, &tfLiteNode, &tfLiteRegistration) != kTfLiteOk) { TF_LITE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnDelegate: Unable to get node and registration for node %d.", nodeIndex); continue; } TfLiteStatus visitStatus; try { visitStatus = ArmnnSubgraph::VisitNode( delegateData, tfLiteContext, tfLiteRegistration, tfLiteNode, nodeIndex); } catch(std::exception& ex) { ARMNN_LOG(error) << "ArmNN Failed to visit node with error: " << ex.what(); visitStatus = kTfLiteError; } if ( visitStatus != kTfLiteOk) { // node is not supported by ArmNN unsupportedOperators.insert(tfLiteRegistration->builtin_code); continue; } nodesToDelegate->data[nodesToDelegate->size++] = nodeIndex; } for (std::set::iterator it=unsupportedOperators.begin(); it!=unsupportedOperators.end(); ++it) { TF_LITE_KERNEL_LOG(tfLiteContext, "Operator %s [%d] is not supported by armnn_delegate.", tflite::EnumNameBuiltinOperator(tflite::BuiltinOperator(*it)), *it); } if (!unsupportedOperators.empty() && m_Options.TfLiteRuntimeFallbackDisabled()) { std::stringstream exMessage; exMessage << "TfLiteArmnnDelegate: There are unsupported operators in the model. "; exMessage << "Not falling back to TfLite Runtime as fallback is disabled. "; exMessage << "This should only be disabled under test conditions."; throw armnn::Exception(exMessage.str()); } if (nodesToDelegate->size == 0) { ARMNN_LOG(info) << "No operators in this model are supported by the Arm NN TfLite delegate." << " The model will be executed entirely by TfLite runtime."; } std::sort(&nodesToDelegate->data[0], &nodesToDelegate->data[nodesToDelegate->size]); return nodesToDelegate; } TfLiteDelegate* Delegate::GetDelegate() { return &m_Delegate; } const std::string Delegate::GetVersion() { return DELEGATE_VERSION; } TfLiteStatus ArmnnSubgraph::AddInputLayer(DelegateData& delegateData, TfLiteContext* tfLiteContext, const TfLiteIntArray* inputs, std::vector& inputBindings) { const size_t numInputs = static_cast(inputs->size); for (unsigned int i = 0; i < numInputs; ++i) { const int32_t tensorId = inputs->data[i]; const TfLiteTensor tensor = tfLiteContext->tensors[tensorId]; // Do not create bindings for constant inputs if (tensor.allocation_type == kTfLiteMmapRo) { continue; } auto bindingId = static_cast((tensorId)); armnn::IConnectableLayer* layer = delegateData.m_Network->AddInputLayer(bindingId); auto tensorInfo = GetTensorInfoForTfLiteTensor(tensor); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(tensorInfo); // Store for creating connections delegateData.m_OutputSlotForNode[static_cast(tensorId)] = &outputSlot; inputBindings.push_back(std::make_pair(bindingId, tensorInfo)); } return kTfLiteOk; } TfLiteStatus ArmnnSubgraph::AddOutputLayer(DelegateData& delegateData, TfLiteContext* tfLiteContext, const TfLiteIntArray* outputs, std::vector& outputBindings) { const size_t numOutputs = static_cast(outputs->size); for (unsigned int i = 0; i < numOutputs; ++i) { const int32_t tensorId = outputs->data[i]; const TfLiteTensor tensor = tfLiteContext->tensors[tensorId]; auto bindingId = static_cast((tensorId)); armnn::IConnectableLayer* layer = delegateData.m_Network->AddOutputLayer(bindingId); auto tensorInfo = GetTensorInfoForTfLiteTensor(tensor); if (delegateData.m_OutputSlotForNode[static_cast(tensorId)] == nullptr) { return kTfLiteError; } delegateData.m_OutputSlotForNode[static_cast(tensorId)]->Connect(layer->GetInputSlot(0)); outputBindings.push_back(std::make_pair(bindingId, tensorInfo)); } return kTfLiteOk; } ArmnnSubgraph* ArmnnSubgraph::Create(TfLiteContext* tfLiteContext, const TfLiteDelegateParams* parameters, const Delegate* delegate) { const auto startTime = armnn::GetTimeNow(); ARMNN_LOG(info) << "ArmnnSubgraph creation"; TfLiteIntArray* executionPlan; if (tfLiteContext->GetExecutionPlan(tfLiteContext, &executionPlan) != kTfLiteOk) { return nullptr; } // Initialize DelegateData holds network and output slots information DelegateData delegateData(delegate->m_Options.GetBackends()); // Build ArmNN Network armnn::NetworkOptions networkOptions = delegate->m_Options.GetOptimizerOptions().GetModelOptions(); armnn::NetworkId networkId; delegateData.m_Network = armnn::INetwork::Create(networkOptions); delegateData.m_OutputSlotForNode = std::vector(tfLiteContext->tensors_size, nullptr); std::vector inputBindings; std::vector outputBindings; // Add input layer auto status = AddInputLayer(delegateData, tfLiteContext, parameters->input_tensors, inputBindings); if (status != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnDelegate: Unable to add Inputs to the network!"); } // Parse TfLite delegate nodes to ArmNN const auto parseStartTime = armnn::GetTimeNow(); for (int i = 0; i < parameters->nodes_to_replace->size; ++i) { const int nodeIndex = parameters->nodes_to_replace->data[i]; TfLiteNode* tfLiteNode = nullptr; TfLiteRegistration* tfLiteRegistration = nullptr; if (tfLiteContext->GetNodeAndRegistration( tfLiteContext, nodeIndex, &tfLiteNode, &tfLiteRegistration) != kTfLiteOk) { throw armnn::Exception(&"TfLiteArmnnDelegate: Unable to get node registration: " [ nodeIndex]); } if (VisitNode(delegateData, tfLiteContext, tfLiteRegistration, tfLiteNode, nodeIndex) != kTfLiteOk) { throw armnn::Exception(&"TfLiteArmnnDelegate: Unable to parse node: " [ nodeIndex]); } } ARMNN_LOG(info) << "Parse nodes to ArmNN time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(parseStartTime).count() << " ms"; // Add Output layer status = AddOutputLayer(delegateData, tfLiteContext, parameters->output_tensors, outputBindings); if (status != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnDelegate: Unable to add Outputs to the network!"); } // Optimize ArmNN network armnn::IOptimizedNetworkPtr optNet(nullptr, nullptr); try { const auto optimizeStartTime = armnn::GetTimeNow(); optNet = armnn::Optimize(*(delegateData.m_Network.get()), delegate->m_Options.GetBackends(), delegate->m_Runtime->GetDeviceSpec(), delegate->m_Options.GetOptimizerOptions()); ARMNN_LOG(info) << "Optimize ArmnnSubgraph time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(optimizeStartTime).count() << " ms"; } catch (std::exception& ex) { std::stringstream exMessage; exMessage << "TfLiteArmnnDelegate: Exception (" << ex.what() << ") caught from optimize."; throw armnn::Exception(exMessage.str()); } if (!optNet) { // Optimize failed throw armnn::Exception("TfLiteArmnnDelegate: Unable to optimize the network!"); } // If set, we will serialize the optimized model into a dot file. const std::string serializeToDotFile = delegate->m_Options.GetSerializeToDot(); if (!serializeToDotFile.empty()) { ARMNN_LOG(info) << "Writing graph to dot file: " << serializeToDotFile; fs::path filename = serializeToDotFile; std::fstream file(filename.c_str(), std::ios_base::out); optNet->SerializeToDot(file); } try { const auto loadStartTime = armnn::GetTimeNow(); // Load graph into runtime std::string errorMessage; armnn::Status loadingStatus; armnn::MemorySource inputSource = armnn::MemorySource::Undefined; armnn::MemorySource outputSource = armnn::MemorySource::Undefined; // There's a bit of an assumption here that the delegate will only support Malloc memory source. if (delegate->m_Options.GetOptimizerOptions().GetImportEnabled()) { inputSource = armnn::MemorySource::Malloc; } if (delegate->m_Options.GetOptimizerOptions().GetExportEnabled()) { outputSource = armnn::MemorySource::Malloc; } armnn::INetworkProperties networkProperties(false, inputSource, outputSource, delegate->m_Options.GetInternalProfilingState(), delegate->m_Options.GetInternalProfilingDetail()); loadingStatus = delegate->m_Runtime->LoadNetwork(networkId, std::move(optNet), errorMessage, networkProperties); if (loadingStatus != armnn::Status::Success) { // Network load failed. throw armnn::Exception("TfLiteArmnnDelegate: Network could not be loaded: " + errorMessage); } ARMNN_LOG(info) << "Load ArmnnSubgraph time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(loadStartTime).count() << " ms"; } catch (std::exception& ex) { std::stringstream exMessage; exMessage << "TfLiteArmnnDelegate: Exception (" << ex.what() << ") caught from LoadNetwork."; throw armnn::Exception(exMessage.str()); } // Register debug callback function if (delegate->m_Options.GetDebugCallbackFunction().has_value()) { delegate->m_Runtime->RegisterDebugCallback(networkId, delegate->m_Options.GetDebugCallbackFunction().value()); } ARMNN_LOG(info) << "Overall ArmnnSubgraph creation time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(startTime).count() << " ms\n"; // Create a new SubGraph with networkId and runtime return new ArmnnSubgraph(networkId, delegate->m_Runtime, inputBindings, outputBindings); } TfLiteStatus ArmnnSubgraph::Prepare(TfLiteContext* tfLiteContext) { armnn::IgnoreUnused(tfLiteContext); return kTfLiteOk; } TfLiteStatus ArmnnSubgraph::Invoke(TfLiteContext* tfLiteContext, TfLiteNode* tfLiteNode) { // Prepare inputs armnn::InputTensors inputTensors; size_t inputIndex = 0; for (auto inputIdx : tflite::TfLiteIntArrayView(tfLiteNode->inputs)) { TfLiteTensor* tensor = &tfLiteContext->tensors[inputIdx]; if (tensor->allocation_type != kTfLiteMmapRo) { const armnn::BindingPointInfo& inputBinding = m_InputBindings[inputIndex]; armnn::TensorInfo inputTensorInfo = inputBinding.second; inputTensorInfo.SetConstant(true); const armnn::ConstTensor inputTensor(inputTensorInfo, tensor->data.data); inputTensors.emplace_back(inputIdx, inputTensor); ++inputIndex; } } // Prepare outputs armnn::OutputTensors outputTensors; size_t outputIndex = 0; for (auto outputIdx : tflite::TfLiteIntArrayView(tfLiteNode->outputs)) { const armnn::BindingPointInfo& outputBinding = m_OutputBindings[outputIndex]; TfLiteTensor* tensor = &tfLiteContext->tensors[outputIdx]; const armnn::Tensor outputTensor(outputBinding.second, tensor->data.data); outputTensors.emplace_back(outputIdx, outputTensor); ++outputIndex; } // Run graph auto status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors); // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data. std::shared_ptr profiler = m_Runtime->GetProfiler(m_NetworkId); if (profiler && profiler->IsProfilingEnabled()) { profiler->Print(std::cout); } return (status == armnn::Status::Success) ? kTfLiteOk : kTfLiteError; } TfLiteStatus ArmnnSubgraph::VisitNode(DelegateData& delegateData, TfLiteContext* tfLiteContext, TfLiteRegistration* tfLiteRegistration, TfLiteNode* tfLiteNode, int nodeIndex) { switch (tfLiteRegistration->builtin_code) { case kTfLiteBuiltinCustom: { #if defined(ARMNN_POST_TFLITE_2_5) // Custom operators are defined by the name rather than the builtin code. // Parse the custom_name param in the registration to point to the correct visitor function. std::string customOperatorName = tfLiteRegistration->custom_name; if ( customOperatorName == "AveragePool3D" ) { return VisitPooling3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, customOperatorName); } else if (customOperatorName == "MaxPool3D") { return VisitPooling3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, customOperatorName); } #endif // Invalid or unsupported custom operator return kTfLiteError; } case kTfLiteBuiltinAbs: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Abs); case kTfLiteBuiltinAdd: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinAdd); case kTfLiteBuiltinArgMax: return VisitArgMinMaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinArgMax); case kTfLiteBuiltinArgMin: return VisitArgMinMaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinArgMin); case kTfLiteBuiltinAveragePool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinAveragePool2d); case kTfLiteBuiltinBatchMatmul: return VisitBatchMatMulOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinBatchMatmul); case kTfLiteBuiltinBatchToSpaceNd: return VisitBatchToSpaceNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinBatchToSpaceNd); case kTfLiteBuiltinCast: return VisitCastOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinCast); case kTfLiteBuiltinCeil: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Ceil); case kTfLiteBuiltinConcatenation: return VisitControlOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConcatenation); case kTfLiteBuiltinConv2d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConv2d); // Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. #if defined(ARMNN_POST_TFLITE_2_5) case kTfLiteBuiltinConv3d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConv3d); #endif case kTfLiteBuiltinDepthToSpace: return VisitDepthToSpaceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDepthToSpace); case kTfLiteBuiltinDepthwiseConv2d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDepthwiseConv2d); case kTfLiteBuiltinDequantize: return VisitDequantizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDequantize); case kTfLiteBuiltinDiv: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDiv); case kTfLiteBuiltinElu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinElu); case kTfLiteBuiltinEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinEqual); case kTfLiteBuiltinExp: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Exp); case kTfLiteBuiltinExpandDims: return VisitExpandDimsOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinExpandDims); case kTfLiteBuiltinFill: return VisitFillOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFill); case kTfLiteBuiltinFloor: return VisitFloorOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFloor); case kTfLiteBuiltinFloorDiv: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFloorDiv); case kTfLiteBuiltinFullyConnected: return VisitFullyConnectedOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFullyConnected); case kTfLiteBuiltinGather: return VisitGatherOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGather); case kTfLiteBuiltinGatherNd: return VisitGatherNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGatherNd); case kTfLiteBuiltinGreater: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGreater); case kTfLiteBuiltinGreaterEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGreaterEqual); case kTfLiteBuiltinHardSwish: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinHardSwish); case kTfLiteBuiltinL2Normalization: return VisitL2NormalizationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinL2Normalization); case kTfLiteBuiltinL2Pool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinL2Pool2d); case kTfLiteBuiltinLeakyRelu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLeakyRelu); case kTfLiteBuiltinLess: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLess); case kTfLiteBuiltinLessEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLessEqual); case kTfLiteBuiltinLocalResponseNormalization: return VisitLocalResponseNormalizationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLocalResponseNormalization); case kTfLiteBuiltinLog: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Log); case kTfLiteBuiltinLogicalAnd: return VisitLogicalBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogicalAnd, armnn::LogicalBinaryOperation::LogicalAnd); case kTfLiteBuiltinLogicalNot: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::LogicalNot); case kTfLiteBuiltinLogicalOr: return VisitLogicalBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogicalOr, armnn::LogicalBinaryOperation::LogicalOr); case kTfLiteBuiltinLogistic: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogistic); case kTfLiteBuiltinLogSoftmax: return VisitSoftmaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogSoftmax); case kTfLiteBuiltinLstm: return VisitLstmOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLstm); case kTfLiteBuiltinMaxPool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMaxPool2d); case kTfLiteBuiltinMaximum: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMaximum); case kTfLiteBuiltinMean: return VisitControlOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMean); case kTfLiteBuiltinMinimum: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMinimum); case kTfLiteBuiltinMirrorPad: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMirrorPad); case kTfLiteBuiltinMul: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMul); case kTfLiteBuiltinNeg: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Neg); case kTfLiteBuiltinNotEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinNotEqual); case kTfLiteBuiltinPack: return VisitPackOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPack); case kTfLiteBuiltinPad: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPad); case kTfLiteBuiltinPadv2: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPadv2); case kTfLiteBuiltinPow: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPow); case kTfLiteBuiltinPrelu: return VisitPreluOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPrelu); case kTfLiteBuiltinQuantize: return VisitQuantizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinQuantize); case kTfLiteBuiltinRank: return VisitControlOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRank); case kTfLiteBuiltinReduceMax: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceMax); case kTfLiteBuiltinReduceMin: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceMin); case kTfLiteBuiltinReduceProd: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceProd); case kTfLiteBuiltinRelu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRelu); case kTfLiteBuiltinReluN1To1: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReluN1To1); case kTfLiteBuiltinRelu6: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRelu6); case kTfLiteBuiltinReshape: return VisitReshapeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReshape); case kTfLiteBuiltinResizeBilinear: return VisitResizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinResizeBilinear); case kTfLiteBuiltinResizeNearestNeighbor: return VisitResizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinResizeNearestNeighbor); case kTfLiteBuiltinReverseV2: return VisitReverseV2Operator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReverseV2); case kTfLiteBuiltinRsqrt: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Rsqrt); case kTfLiteBuiltinShape: return VisitShapeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinShape); case kTfLiteBuiltinSin: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Sin); case kTfLiteBuiltinSplit: return VisitSplitOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSplit); case kTfLiteBuiltinSplitV: return VisitSplitVOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSplitV); case kTfLiteBuiltinSqrt: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, armnn::UnaryOperation::Sqrt); case kTfLiteBuiltinSquaredDifference: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSquaredDifference); case kTfLiteBuiltinSqueeze: return VisitSqueezeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSqueeze); case kTfLiteBuiltinSlice: return VisitSliceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSlice); case kTfLiteBuiltinStridedSlice: return VisitStridedSliceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinStridedSlice); case kTfLiteBuiltinSum: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSum); case kTfLiteBuiltinTranspose: return VisitTransposeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTranspose); case kTfLiteBuiltinTransposeConv: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTransposeConv); case kTfLiteBuiltinSoftmax: return VisitSoftmaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSoftmax); case kTfLiteBuiltinSpaceToBatchNd: return VisitSpaceToBatchNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSpaceToBatchNd); case kTfLiteBuiltinSpaceToDepth: return VisitSpaceToDepthOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSpaceToDepth); case kTfLiteBuiltinSub: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSub); case kTfLiteBuiltinTanh: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTanh); case kTfLiteBuiltinTile: return VisitTileOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTile); case kTfLiteBuiltinUnidirectionalSequenceLstm: return VisitUnidirectionalSequenceLstmOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinUnidirectionalSequenceLstm); case kTfLiteBuiltinUnpack: return VisitUnpackOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinUnpack); default: return kTfLiteError; } } } // armnnDelegate namespacearmnn-23.08/delegate/classic/src/armnn_external_delegate.cpp000066400000000000000000000043061446772241200242120ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "armnn_delegate.hpp" #include #include #include #include namespace tflite { /** * This file defines two symbols that need to be exported to use the TFLite external delegate provider. This is a plugin * that can be used for fast integration of delegates into benchmark tests and other tools. It allows loading of * a dynamic delegate library at runtime. * * The external delegate also has Tensorflow Lite Python bindings. Therefore the dynamic external delegate * can be directly used with Tensorflow Lite Python APIs. * * See tensorflow/lite/delegates/external for details or visit the tensorflow guide * [here](https://www.tensorflow.org/lite/performance/implementing_delegate#option_2_leverage_external_delegate) */ extern "C" { /** * Implementation of the TfLite external delegate plugin * * For details about what options_keys and option_values are supported please see: * armnnDelegate::DelegateOptions::DelegateOptions(char const* const*, char const* const*,size_t,void (*)(const char*)) */ TfLiteDelegate* tflite_plugin_create_delegate(char** options_keys, char** options_values, size_t num_options, void (*report_error)(const char*)) { // Returning null indicates an error during delegate creation, we initialize with that TfLiteDelegate* delegate = nullptr; try { armnnDelegate::DelegateOptions options (options_keys, options_values, num_options, (*report_error)); delegate = TfLiteArmnnDelegateCreate(options); } catch (const std::exception& ex) { if(report_error) { report_error(ex.what()); } } return delegate; } /** Destroy a given delegate plugin * * @param[in] delegate Delegate to destruct */ void tflite_plugin_destroy_delegate(TfLiteDelegate* delegate) { armnnDelegate::TfLiteArmnnDelegateDelete(delegate); } } // extern "C" } // namespace tflitearmnn-23.08/delegate/classic/src/test/000077500000000000000000000000001446772241200176135ustar00rootroot00000000000000armnn-23.08/delegate/classic/src/test/ArmnnClassicDelegateTest.cpp000066400000000000000000000102001446772241200251600ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include #include #include #include #include namespace armnnDelegate { TEST_SUITE("ArmnnDelegate") { TEST_CASE ("ArmnnDelegate Registered") { using namespace tflite; auto tfLiteInterpreter = std::make_unique(); tfLiteInterpreter->AddTensors(3); tfLiteInterpreter->SetInputs({0, 1}); tfLiteInterpreter->SetOutputs({2}); tfLiteInterpreter->SetTensorParametersReadWrite(0, kTfLiteFloat32, "input1", {1,2,2,1}, TfLiteQuantization()); tfLiteInterpreter->SetTensorParametersReadWrite(1, kTfLiteFloat32, "input2", {1,2,2,1}, TfLiteQuantization()); tfLiteInterpreter->SetTensorParametersReadWrite(2, kTfLiteFloat32, "output", {1,2,2,1}, TfLiteQuantization()); tflite::ops::builtin::BuiltinOpResolver opResolver; const TfLiteRegistration* opRegister = opResolver.FindOp(BuiltinOperator_ADD, 1); tfLiteInterpreter->AddNodeWithParameters({0, 1}, {2}, "", 0, nullptr, opRegister); // Create the Armnn Delegate std::vector backends = { armnn::Compute::CpuRef }; std::vector backendOptions; backendOptions.emplace_back( armnn::BackendOptions{ "BackendName", { { "Option1", 42 }, { "Option2", true } }} ); armnnDelegate::DelegateOptions delegateOptions(backends, backendOptions); std::unique_ptr theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), armnnDelegate::TfLiteArmnnDelegateDelete); auto status = tfLiteInterpreter->ModifyGraphWithDelegate(std::move(theArmnnDelegate)); CHECK(status == kTfLiteOk); CHECK(tfLiteInterpreter != nullptr); } TEST_CASE ("ArmnnDelegateOptimizerOptionsRegistered") { using namespace tflite; auto tfLiteInterpreter = std::make_unique(); tfLiteInterpreter->AddTensors(3); tfLiteInterpreter->SetInputs({0, 1}); tfLiteInterpreter->SetOutputs({2}); tfLiteInterpreter->SetTensorParametersReadWrite(0, kTfLiteFloat32, "input1", {1,2,2,1}, TfLiteQuantization()); tfLiteInterpreter->SetTensorParametersReadWrite(1, kTfLiteFloat32, "input2", {1,2,2,1}, TfLiteQuantization()); tfLiteInterpreter->SetTensorParametersReadWrite(2, kTfLiteFloat32, "output", {1,2,2,1}, TfLiteQuantization()); tflite::ops::builtin::BuiltinOpResolver opResolver; const TfLiteRegistration* opRegister = opResolver.FindOp(BuiltinOperator_ADD, 1); tfLiteInterpreter->AddNodeWithParameters({0, 1}, {2}, "", 0, nullptr, opRegister); // Create the Armnn Delegate std::vector backends = { armnn::Compute::CpuRef }; armnn::OptimizerOptionsOpaque optimizerOptions(true, true, false, true); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); std::unique_ptr theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), armnnDelegate::TfLiteArmnnDelegateDelete); auto status = tfLiteInterpreter->ModifyGraphWithDelegate(std::move(theArmnnDelegate)); CHECK(status == kTfLiteOk); CHECK(tfLiteInterpreter != nullptr); } TEST_CASE ("DelegateOptions_ClassicDelegateDefault") { // Check default options can be created auto options = TfLiteArmnnDelegateOptionsDefault(); // Check Classic delegate created auto classicDelegate = armnnDelegate::TfLiteArmnnDelegateCreate(options); CHECK(classicDelegate); // Check Classic Delegate can be deleted CHECK(classicDelegate->data_); armnnDelegate::TfLiteArmnnDelegateDelete(classicDelegate); } } } // namespace armnnDelegate armnn-23.08/delegate/classic/src/test/DelegateTestInterpreter.cpp000066400000000000000000000053161446772241200251220ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include namespace delegateTestInterpreter { DelegateTestInterpreter::DelegateTestInterpreter(std::vector& modelBuffer, const std::vector& backends, const std::string& customOp, bool disableFallback) { TfLiteModel* tfLiteModel = delegateTestInterpreter::CreateTfLiteModel(modelBuffer); TfLiteInterpreterOptions* options = delegateTestInterpreter::CreateTfLiteInterpreterOptions(); if (!customOp.empty()) { options->mutable_op_resolver = delegateTestInterpreter::GenerateCustomOpResolver(customOp); } // Disable fallback by default for unit tests unless specified. armnnDelegate::DelegateOptions delegateOptions(backends); delegateOptions.DisableTfLiteRuntimeFallback(disableFallback); auto armnnDelegate = armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions); TfLiteInterpreterOptionsAddDelegate(options, armnnDelegate); m_TfLiteDelegate = armnnDelegate; m_TfLiteInterpreter = TfLiteInterpreterCreate(tfLiteModel, options); // The options and model can be deleted after the interpreter is created. TfLiteInterpreterOptionsDelete(options); TfLiteModelDelete(tfLiteModel); } DelegateTestInterpreter::DelegateTestInterpreter(std::vector& modelBuffer, const armnnDelegate::DelegateOptions& delegateOptions, const std::string& customOp) { TfLiteModel* tfLiteModel = delegateTestInterpreter::CreateTfLiteModel(modelBuffer); TfLiteInterpreterOptions* options = delegateTestInterpreter::CreateTfLiteInterpreterOptions(); if (!customOp.empty()) { options->mutable_op_resolver = delegateTestInterpreter::GenerateCustomOpResolver(customOp); } auto armnnDelegate = armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions); TfLiteInterpreterOptionsAddDelegate(options, armnnDelegate); m_TfLiteDelegate = armnnDelegate; m_TfLiteInterpreter = TfLiteInterpreterCreate(tfLiteModel, options); // The options and model can be deleted after the interpreter is created. TfLiteInterpreterOptionsDelete(options); TfLiteModelDelete(tfLiteModel); } void DelegateTestInterpreter::Cleanup() { TfLiteInterpreterDelete(m_TfLiteInterpreter); if (m_TfLiteDelegate) { armnnDelegate::TfLiteArmnnDelegateDelete(static_cast(m_TfLiteDelegate)); } } } // anonymous namespacearmnn-23.08/delegate/cmake/000077500000000000000000000000001446772241200155045ustar00rootroot00000000000000armnn-23.08/delegate/cmake/Modules/000077500000000000000000000000001446772241200171145ustar00rootroot00000000000000armnn-23.08/delegate/cmake/Modules/ArmnnDelegateConfig.cmake.in000066400000000000000000000014501446772241200243570ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # get_filename_component(ARMNN_DELEGATE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) set(ARMNN_DELEGATE_CONFIG_FILE ${CMAKE_CURRENT_LIST_FILE}) MESSAGE(STATUS "Found ArmnnDelegate: ${ARMNN_DELEGATE_CONFIG_FILE}") include(CMakeFindDependencyMacro) list(APPEND CMAKE_MODULE_PATH ${ARMNN_DELEGATE_CMAKE_DIR}) @PACKAGE_INIT@ set_and_check(Armnn_DIR "@Armnn_DIR@") find_dependency(Armnn REQUIRED CONFIG HINTS ${Armnn_DIR}) if(NOT TARGET ArmnnDelegate::ArmnnDelegate) MESSAGE(STATUS "ArmnnDelegate Import: ${ARMNN_DELEGATE_CMAKE_DIR}/ArmnnDelegateTargets.cmake") include("${ARMNN_DELEGATE_CMAKE_DIR}/ArmnnDelegateTargets.cmake") endif() set(ARMNN_DELEGATE_LIBRARIES ArmnnDelegate::ArmnnDelegate)armnn-23.08/delegate/cmake/Modules/FindFlatbuffers.cmake000066400000000000000000000015301446772241200231610ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # include(FindPackageHandleStandardArgs) unset(FLATBUFFERS_FOUND) find_path(Flatbuffers_INCLUDE_DIR flatbuffers/flatbuffers.h HINTS ${FLATBUFFERS_ROOT}/include /usr/local/include /usr/include) find_library(Flatbuffers_LIB NAMES libflatbuffers.a flatbuffers HINTS ${FLATBUFFERS_ROOT}/lib /usr/local/lib /usr/lib) ## Set FLATBUFFERS_FOUND find_package_handle_standard_args(Flatbuffers DEFAULT_MSG Flatbuffers_INCLUDE_DIR Flatbuffers_LIB) ## Set external variables for usage in CMakeLists.txt if(FLATBUFFERS_FOUND) set(Flatbuffers_LIB ${Flatbuffers_LIB}) set(Flatbuffers_INCLUDE_DIR ${Flatbuffers_INCLUDE_DIR}) endif()armnn-23.08/delegate/cmake/Modules/FindTfLite.cmake000066400000000000000000000227201446772241200221110ustar00rootroot00000000000000# # Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # include(FindPackageHandleStandardArgs) unset(TFLITE_FOUND) # # NOTE: this module is used to find the tensorflow lite binary libraries only # the FindTfLiteSrc.cmake module is used to find the tensorflow lite include directory. # This is to allow components like the Tensorflow lite parser that have a source dependency # on tensorflow lite headers but no need to link to the binary libraries to use only the sources # and not have an artificial dependency on the libraries. # # First look for the static version of tensorflow lite find_library(TfLite_LIB NAMES "libtensorflow-lite.a" HINTS ${TFLITE_LIB_ROOT} ${TFLITE_LIB_ROOT}/tensorflow/lite) # If not found then, look for the dynamic library of tensorflow lite find_library(TfLite_LIB NAMES "libtensorflow_lite_all.so" "libtensorflowlite.so" HINTS ${TFLITE_LIB_ROOT} ${TFLITE_LIB_ROOT}/tensorflow/lite) # If the static library was found, gather all of its dependencies if (TfLite_LIB MATCHES .a$) message("-- Static tensorflow lite library found, using for ArmNN build") find_library(TfLite_abseilstrings_LIB "libabsl_strings.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/strings) find_library(TfLite_abseil_synchronization_LIB "libabsl_synchronization.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/synchronization) find_library(TfLite_farmhash_LIB "libfarmhash.a" PATH ${TFLITE_LIB_ROOT}/_deps/farmhash-build) find_library(TfLite_fftsg_LIB "libfft2d_fftsg.a" PATH ${TFLITE_LIB_ROOT}/_deps/fft2d-build) find_library(TfLite_fftsg2d_LIB "libfft2d_fftsg2d.a" PATH ${TFLITE_LIB_ROOT}/_deps/fft2d-build) find_library(TfLite_flatbuffers_LIB "libflatbuffers.a" PATH ${TFLITE_LIB_ROOT}/_deps/flatbuffers-build) find_library(TfLite_cpuinfo_LIB "libcpuinfo.a" PATH ${TFLITE_LIB_ROOT}/_deps/cpuinfo-build) # All remaining libraries are part of libruy. find_library(TfLite_ruy_allocator_LIB "libruy_allocator.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_apply_multiplier_LIB "libruy_apply_multiplier.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_blocking_counter_LIB "libruy_blocking_counter.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_block_map_LIB "libruy_block_map.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_context_LIB "libruy_context.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_context_get_ctx_LIB "libruy_context_get_ctx.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_cpuinfo_LIB "libruy_cpuinfo.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_ctx_LIB "libruy_ctx.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_denormal_LIB "libruy_denormal.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_frontend_LIB "libruy_frontend.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_have_built_path_for_avx2_fma_LIB "libruy_have_built_path_for_avx2_fma.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_have_built_path_for_avx512_LIB "libruy_have_built_path_for_avx512.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_have_built_path_for_avx_LIB "libruy_have_built_path_for_avx.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_kernel_arm_LIB "libruy_kernel_arm.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_kernel_avx2_fma_LIB "libruy_kernel_avx2_fma.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_kernel_avx512_LIB "libruy_kernel_avx512.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_kernel_avx_LIB "libruy_kernel_avx.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_pack_arm_LIB "libruy_pack_arm.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_pack_avx2_fma_LIB "libruy_pack_avx2_fma.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_pack_avx512_LIB "libruy_pack_avx512.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_pack_avx_LIB "libruy_pack_avx.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_prepacked_cache_LIB "libruy_prepacked_cache.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_prepare_packed_matrices_LIB "libruy_prepare_packed_matrices.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_system_aligned_alloc_LIB "libruy_system_aligned_alloc.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_threadpool_LIB "libruy_thread_pool.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_trmul_LIB "libruy_trmul.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_tune_LIB "libruy_tune.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_wait_LIB "libruy_wait.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy) find_library(TfLite_ruy_profiler_LIB "libruy_profiler_instrumentation.a" PATH ${TFLITE_LIB_ROOT}/_deps/ruy-build/ruy/profiler) find_library(TfLite_pthread_pool_LIB "libpthreadpool.a" PATH ${TFLITE_LIB_ROOT}/pthreadpool) ## Set TFLITE_FOUND if all libraries are satisfied for static lib find_package_handle_standard_args(TfLite DEFAULT_MSG TfLite_LIB TfLite_abseilstrings_LIB TfLite_farmhash_LIB TfLite_fftsg_LIB TfLite_fftsg2d_LIB TfLite_flatbuffers_LIB TfLite_ruy_allocator_LIB TfLite_ruy_apply_multiplier_LIB TfLite_ruy_blocking_counter_LIB TfLite_ruy_block_map_LIB TfLite_ruy_context_LIB TfLite_ruy_context_get_ctx_LIB TfLite_ruy_cpuinfo_LIB TfLite_ruy_ctx_LIB TfLite_ruy_denormal_LIB TfLite_ruy_frontend_LIB TfLite_ruy_have_built_path_for_avx2_fma_LIB TfLite_ruy_have_built_path_for_avx512_LIB TfLite_ruy_have_built_path_for_avx_LIB TfLite_ruy_kernel_arm_LIB TfLite_ruy_kernel_avx2_fma_LIB TfLite_ruy_kernel_avx512_LIB TfLite_ruy_kernel_avx_LIB TfLite_ruy_pack_arm_LIB TfLite_ruy_pack_avx2_fma_LIB TfLite_ruy_pack_avx512_LIB TfLite_ruy_pack_avx_LIB TfLite_ruy_prepacked_cache_LIB TfLite_ruy_prepare_packed_matrices_LIB TfLite_ruy_system_aligned_alloc_LIB TfLite_ruy_threadpool_LIB TfLite_ruy_trmul_LIB TfLite_ruy_tune_LIB TfLite_ruy_wait_LIB TfLite_ruy_profiler_LIB TfLite_cpuinfo_LIB TfLite_abseil_synchronization_LIB TfLite_pthread_pool_LIB) # Set external variables for usage in CMakeLists.txt if (TFLITE_FOUND) # WARNING! The order of these libraries is critical. Moving them # around will result in linker errors in DelegateUnitTests. set(TfLite_LIB ${TfLite_LIB} ${TfLite_abseilstrings_LIB} ${TfLite_farmhash_LIB} ${TfLite_fftsg_LIB} ${TfLite_fftsg2d_LIB} ${TfLite_flatbuffers_LIB} ${TfLite_ruy_allocator_LIB} ${TfLite_ruy_apply_multiplier_LIB} ${TfLite_ruy_frontend_LIB} ${TfLite_ruy_trmul_LIB} ${TfLite_ruy_threadpool_LIB} ${TfLite_ruy_blocking_counter_LIB} ${TfLite_ruy_block_map_LIB} ${TfLite_ruy_context_LIB} ${TfLite_ruy_context_get_ctx_LIB} ${TfLite_ruy_cpuinfo_LIB} ${TfLite_ruy_ctx_LIB} ${TfLite_ruy_denormal_LIB} ${TfLite_ruy_have_built_path_for_avx2_fma_LIB} ${TfLite_ruy_have_built_path_for_avx512_LIB} ${TfLite_ruy_have_built_path_for_avx_LIB} ${TfLite_ruy_kernel_arm_LIB} ${TfLite_ruy_kernel_avx2_fma_LIB} ${TfLite_ruy_kernel_avx512_LIB} ${TfLite_ruy_kernel_avx_LIB} ${TfLite_ruy_pack_arm_LIB} ${TfLite_ruy_pack_avx2_fma_LIB} ${TfLite_ruy_pack_avx512_LIB} ${TfLite_ruy_pack_avx_LIB} ${TfLite_ruy_prepacked_cache_LIB} ${TfLite_ruy_prepare_packed_matrices_LIB} ${TfLite_ruy_system_aligned_alloc_LIB} ${TfLite_ruy_tune_LIB} ${TfLite_ruy_wait_LIB} ${TfLite_ruy_profiler_LIB} ${TfLite_cpuinfo_LIB} ${TfLite_abseil_synchronization_LIB} ${TfLite_pthread_pool_LIB}) endif () elseif (TfLite_LIB MATCHES .so$) message("-- Dynamic tensorflow lite library found, using for ArmNN build") find_package_handle_standard_args(TfLite DEFAULT_MSG TfLite_LIB) ## Set external variables for usage in CMakeLists.txt if (TFLITE_FOUND) set(TfLite_LIB ${TfLite_LIB}) endif () else() message(FATAL_ERROR "Could not find a tensorflow lite library to use") endif() armnn-23.08/delegate/cmake/Modules/FindTfLiteAbsl.cmake000066400000000000000000000071571446772241200227220ustar00rootroot00000000000000# # Copyright © 2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # include(FindPackageHandleStandardArgs) unset(TFLITEABSL_FOUND) find_path(TfLite_ABSL_SYNC_HEADERS NAMES absl HINTS ${TFLITE_LIB_ROOT}/abseil-cpp) # First look for the static version of tensorflow lite find_library(TfLite_LIB NAMES "libtensorflow-lite.a" HINTS ${TFLITE_LIB_ROOT} ${TFLITE_LIB_ROOT}/tensorflow/lite) # If the static library was found, gather extra absl libraries for opaque delegate if (TfLite_LIB MATCHES .a$) find_library(TfLite_abseil_base_LIB "libabsl_base.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base) find_library(TfLite_abseil_log_severity_LIB "libabsl_log_severity.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base) find_library(TfLite_abseil_spinlock_wait_LIB "libabsl_spinlock_wait.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base) find_library(TfLite_abseil_malloc_internal_LIB "libabsl_malloc_internal.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base) find_library(TfLite_abseil_raw_logging_internal_LIB "libabsl_raw_logging_internal.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/base) find_library(TfLite_abseil_stacktrace_LIB "libabsl_stacktrace.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/debugging) find_library(TfLite_abseil_debugging_internal_LIB "libabsl_debugging_internal.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/debugging) find_library(TfLite_abseil_symbolize_LIB "libabsl_symbolize.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/debugging) find_library(TfLite_abseil_demangle_internal_LIB "libabsl_demangle_internal.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/debugging) find_library(TfLite_abseil_time_LIB "libabsl_time.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/time) find_library(TfLite_abseil_time_zone_LIB "libabsl_time_zone.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/time) find_library(TfLite_abseil_int128_LIB "libabsl_int128.a" PATH ${TFLITE_LIB_ROOT}/_deps/abseil-cpp-build/absl/numeric) ## Set TFLITEABSL_FOUND find_package_handle_standard_args(TfLiteAbsl DEFAULT_MSG TfLite_ABSL_SYNC_HEADERS TfLite_abseil_base_LIB TfLite_abseil_int128_LIB TfLite_abseil_spinlock_wait_LIB TfLite_abseil_raw_logging_internal_LIB TfLite_abseil_malloc_internal_LIB TfLite_abseil_symbolize_LIB TfLite_abseil_stacktrace_LIB TfLite_abseil_demangle_internal_LIB TfLite_abseil_debugging_internal_LIB TfLite_abseil_time_LIB TfLite_abseil_time_zone_LIB) ## Set external variables for usage in CMakeLists.txt if(TFLITEABSL_FOUND) set(TfLite_ABSL_SYNC_HEADERS ${TfLite_ABSL_SYNC_HEADERS}) set(TfLite_Extra_Absl_LIB ${TfLite_abseil_base_LIB} ${TfLite_abseil_int128_LIB} ${TfLite_abseil_spinlock_wait_LIB} ${TfLite_abseil_raw_logging_internal_LIB} ${TfLite_abseil_malloc_internal_LIB} ${TfLite_abseil_symbolize_LIB} ${TfLite_abseil_stacktrace_LIB} ${TfLite_abseil_demangle_internal_LIB} ${TfLite_abseil_debugging_internal_LIB} ${TfLite_abseil_time_LIB} ${TfLite_abseil_time_zone_LIB}) endif() endif() armnn-23.08/delegate/cmake/Modules/FindTfLiteSrc.cmake000066400000000000000000000014021446772241200225530ustar00rootroot00000000000000# # Copyright © 2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # include(FindPackageHandleStandardArgs) unset(TFLITE_SRC_FOUND) find_path(TfLite_INCLUDE_DIR NAMES tensorflow/lite third_party HINTS ${TENSORFLOW_ROOT}) find_path(TfLite_Schema_INCLUDE_PATH schema_generated.h HINTS ${TENSORFLOW_ROOT}/tensorflow/lite/schema) ## Set TFLITE_FOUND find_package_handle_standard_args(TfLiteSrc DEFAULT_MSG TfLite_INCLUDE_DIR TfLite_Schema_INCLUDE_PATH) ## Set external variables for usage in CMakeLists.txt if(TFLITE_SRC_FOUND) set(TfLite_INCLUDE_DIR ${TfLite_INCLUDE_DIR}) set(TfLite_Schema_INCLUDE_PATH ${TfLite_Schema_INCLUDE_PATH}) endif() armnn-23.08/delegate/common/000077500000000000000000000000001446772241200157145ustar00rootroot00000000000000armnn-23.08/delegate/common/include/000077500000000000000000000000001446772241200173375ustar00rootroot00000000000000armnn-23.08/delegate/common/include/DelegateOptions.hpp000066400000000000000000000255301446772241200231430ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include namespace armnnDelegate { struct DelegateOptionsImpl; class DelegateOptions { public: ~DelegateOptions(); DelegateOptions(); DelegateOptions(const DelegateOptions& other); DelegateOptions(armnn::Compute computeDevice, const std::vector& backendOptions = {}, armnn::Optional logSeverityLevel = armnn::EmptyOptional()); DelegateOptions(const std::vector& backends, const std::vector& backendOptions = {}, armnn::Optional logSeverityLevel = armnn::EmptyOptional()); DelegateOptions(armnn::Compute computeDevice, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel = armnn::EmptyOptional(), const armnn::Optional& func = armnn::EmptyOptional()); DelegateOptions(const std::vector& backends, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel = armnn::EmptyOptional(), const armnn::Optional& func = armnn::EmptyOptional()); /** * This constructor processes delegate options in form of command line arguments. * It works in conjunction with the TfLite external delegate plugin. * * Available options: * * Option key: "backends" \n * Possible values: ["EthosNPU"/"GpuAcc"/"CpuAcc"/"CpuRef"] \n * Descriptions: A comma separated list without whitespaces of * backends which should be used for execution. Falls * back to next backend in list if previous doesn't * provide support for operation. e.g. "GpuAcc,CpuAcc" * * Option key: "dynamic-backends-path" \n * Possible values: [filenameString] \n * Descriptions: This is the directory that will be searched for any dynamic backends. * * Option key: "logging-severity" \n * Possible values: ["trace"/"debug"/"info"/"warning"/"error"/"fatal"] \n * Description: Sets the logging severity level for ArmNN. Logging * is turned off if this option is not provided. * * Option key: "gpu-tuning-level" \n * Possible values: ["0"/"1"/"2"/"3"] \n * Description: 0=UseOnly(default), 1=RapidTuning, 2=NormalTuning, * 3=ExhaustiveTuning. Requires option gpu-tuning-file. * 1,2 and 3 will create a tuning-file, 0 will apply the * tunings from an existing file * * Option key: "gpu-mlgo-tuning-file" \n * Possible values: [filenameString] \n * Description: File name for the MLGO tuning file * * Option key: "gpu-tuning-file" \n * Possible values: [filenameString] \n * Description: File name for the tuning file. * * Option key: "gpu-enable-profiling" \n * Possible values: ["true"/"false"] \n * Description: Enables GPU profiling * * Option key: "gpu-kernel-profiling-enabled" \n * Possible values: ["true"/"false"] \n * Description: Enables GPU kernel profiling * * Option key: "save-cached-network" \n * Possible values: ["true"/"false"] \n * Description: Enables saving of the cached network to a file, * specified with the cached-network-filepath option * * Option key: "cached-network-filepath" \n * Possible values: [filenameString] \n * Description: If non-empty, the given file will be used to load/save the cached network. * If save-cached-network is given then the cached network will be saved to the given file. * To save the cached network a file must already exist. * If save-cached-network is not given then the cached network will be loaded from the given file. * This will remove initial compilation time of kernels and speed up the first execution. * * Option key: "enable-fast-math" \n * Possible values: ["true"/"false"] \n * Description: Enables fast_math options in backends that support it * * Option key: "number-of-threads" \n * Possible values: ["1"-"64"] \n * Description: Assign the number of threads used by the CpuAcc backend. * Default is set to 0 (Backend will decide number of threads to use). * * Option key: "reduce-fp32-to-fp16" \n * Possible values: ["true"/"false"] \n * Description: Reduce Fp32 data to Fp16 for faster processing * * Option key: "reduce-fp32-to-bf16" \n * Possible values: ["true"/"false"] \n * Description: This option is currently ignored. Please enable Fast Math in the CpuAcc or GpuAcc backends. * * Option key: "debug-data" \n * Possible values: ["true"/"false"] \n * Description: Add debug data for easier troubleshooting * * Option key: "memory-import" \n * Possible values: ["true"/"false"] \n * Description: Enable memory import * * Option key: "enable-internal-profiling" \n * Possible values: ["true"/"false"] \n * Description: Enable the internal profiling feature. * * Option key: "internal-profiling-detail" \n * Possible values: [1/2] \n * Description: Set the detail on the internal profiling. 1 = DetailsWithEvents, 2 = DetailsOnly. * * Option key: "enable-external-profiling" \n * Possible values: ["true"/"false"] \n * Description: Enable the external profiling feature. * * Option key: "timeline-profiling" \n * Possible values: ["true"/"false"] \n * Description: Indicates whether external timeline profiling is enabled or not. * * Option key: "outgoing-capture-file" \n * Possible values: [filenameString] \n * Description: Path to a file in which outgoing timeline profiling messages will be stored. * * Option key: "incoming-capture-file" \n * Possible values: [filenameString] \n * Description: Path to a file in which incoming timeline profiling messages will be stored. * * Option key: "file-only-external-profiling" \n * Possible values: ["true"/"false"] \n * Description: Enable profiling output to file only. * * Option key: "counter-capture-period" \n * Possible values: Integer, Default is 10000u * Description: Value in microseconds of the profiling capture period. \n * * Option key: "profiling-file-format" \n * Possible values: String of ["binary"] \n * Description: The format of the file used for outputting profiling data. Currently on "binary" is supported. * * Option key: "serialize-to-dot" \n * Possible values: [filenameString] \n * Description: Serialize the optimized network to the file specified in "dot" format. * * Option key: "infer-output-shape" \n * Possible values: ["true"/"false"] \n * Description: Infers output tensor shape from input tensor shape and validate where applicable. * * Option key: "allow-expanded-dims" \n * Possible values: ["true"/"false"] \n * Description: If true will disregard dimensions with a size of 1 when validating tensor shapes but tensor * sizes must still match. \n * This is an Experimental parameter that is incompatible with "infer-output-shape". \n * This parameter may be removed in a later update. * * Option key: "disable-tflite-runtime-fallback" \n * Possible values: ["true"/"false"] \n * Description: Disable TfLite Runtime fallback in the Arm NN TfLite delegate. * An exception will be thrown if unsupported operators are encountered. * This option is only for testing purposes. * * @param[in] option_keys Delegate option names * @param[in] options_values Delegate option values * @param[in] num_options Number of delegate options * @param[in,out] report_error Error callback function * */ DelegateOptions(char const* const* options_keys, char const* const* options_values, size_t num_options, void (*report_error)(const char*)); const std::vector& GetBackends() const; void SetBackends(const std::vector& backends); void SetDynamicBackendsPath(const std::string& dynamicBackendsPath); const std::string& GetDynamicBackendsPath() const; void SetGpuProfilingState(bool gpuProfilingState); bool GetGpuProfilingState(); const std::vector& GetBackendOptions() const; /// Appends a backend option to the list of backend options void AddBackendOption(const armnn::BackendOptions& option); /// Sets the severity level for logging within ArmNN that will be used on creation of the delegate void SetLoggingSeverity(const armnn::LogSeverity& level); void SetLoggingSeverity(const std::string& level); /// Returns the severity level for logging within ArmNN armnn::LogSeverity GetLoggingSeverity(); bool IsLoggingEnabled(); const armnn::OptimizerOptionsOpaque& GetOptimizerOptions() const; void SetOptimizerOptions(const armnn::OptimizerOptionsOpaque& optimizerOptions); const armnn::Optional& GetDebugCallbackFunction() const; void SetInternalProfilingParams(bool internalProfilingState, const armnn::ProfilingDetailsMethod& internalProfilingDetail); bool GetInternalProfilingState() const; const armnn::ProfilingDetailsMethod& GetInternalProfilingDetail() const; void SetSerializeToDot(const std::string& serializeToDotFile); const std::string& GetSerializeToDot() const; /// @Note: This might overwrite options that were set with other setter functions of DelegateOptions void SetRuntimeOptions(const armnn::IRuntime::CreationOptions& runtimeOptions); const armnn::IRuntime::CreationOptions& GetRuntimeOptions(); void DisableTfLiteRuntimeFallback(bool fallbackState); bool TfLiteRuntimeFallbackDisabled(); private: std::unique_ptr p_DelegateOptionsImpl; }; } // namespace armnnDelegate armnn-23.08/delegate/common/src/000077500000000000000000000000001446772241200165035ustar00rootroot00000000000000armnn-23.08/delegate/common/src/DelegateOptions.cpp000066400000000000000000000471211446772241200223020ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include namespace armnnDelegate { struct DelegateOptionsImpl { ~DelegateOptionsImpl() = default; DelegateOptionsImpl() = default; explicit DelegateOptionsImpl(armnn::Compute computeDevice, const std::vector& backendOptions, const armnn::Optional logSeverityLevel) : m_Backends({computeDevice}), m_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel) { m_RuntimeOptions.m_BackendOptions = backendOptions; } explicit DelegateOptionsImpl(const std::vector& backends, const std::vector& backendOptions, const armnn::Optional logSeverityLevel) : m_Backends(backends), m_RuntimeOptions(), m_LoggingSeverity(logSeverityLevel) { m_RuntimeOptions.m_BackendOptions = backendOptions; } explicit DelegateOptionsImpl(armnn::Compute computeDevice, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel, const armnn::Optional& func) : m_Backends({computeDevice}), m_RuntimeOptions(), m_OptimizerOptions(optimizerOptions), m_LoggingSeverity(logSeverityLevel), m_DebugCallbackFunc(func) { } explicit DelegateOptionsImpl(const std::vector& backends, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel, const armnn::Optional& func) : m_Backends(backends), m_RuntimeOptions(), m_OptimizerOptions(optimizerOptions), m_LoggingSeverity(logSeverityLevel), m_DebugCallbackFunc(func) { } /// Which backend to run Delegate on. /// Examples of possible values are: CpuRef, CpuAcc, GpuAcc. /// CpuRef as default. std::vector m_Backends = {armnn::Compute::CpuRef }; /// Creation options for the ArmNN runtime /// Contains options for global settings that are valid for the whole lifetime of ArmNN /// i.e. BackendOptions, DynamicBackendPath, ExternalProfilingOptions and more armnn::IRuntime::CreationOptions m_RuntimeOptions; /// Options for the optimization step for the network armnn::OptimizerOptionsOpaque m_OptimizerOptions; /// Internal profiling options. Written to INetworkProperties during model load. /// Indicates whether internal profiling is enabled or not. bool m_InternalProfilingEnabled = false; /// Sets the level of detail output by the profiling. Options are DetailsWithEvents = 1 and DetailsOnly = 2 armnn::ProfilingDetailsMethod m_InternalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents; /// Severity level for logging within ArmNN that will be used on creation of the delegate armnn::Optional m_LoggingSeverity; /// A callback function to debug layers performing custom computations on intermediate tensors. /// If a function is not registered, and debug is enabled in OptimizerOptions, /// debug will print information of the intermediate tensors. armnn::Optional m_DebugCallbackFunc; /// If not empty then the optimized model will be serialized to a file with this file name in "dot" format. std::string m_SerializeToDot = ""; /// Option to disable TfLite Runtime fallback for unsupported operators. bool m_DisableTfLiteRuntimeFallback = false; }; DelegateOptions::~DelegateOptions() = default; DelegateOptions::DelegateOptions() : p_DelegateOptionsImpl(std::make_unique()) { } DelegateOptions::DelegateOptions(DelegateOptions const &other) : p_DelegateOptionsImpl(std::make_unique(*other.p_DelegateOptionsImpl)) { } DelegateOptions::DelegateOptions(armnn::Compute computeDevice, const std::vector& backendOptions, const armnn::Optional logSeverityLevel) : p_DelegateOptionsImpl(std::make_unique(computeDevice, backendOptions, logSeverityLevel)) { } DelegateOptions::DelegateOptions(const std::vector& backends, const std::vector& backendOptions, const armnn::Optional logSeverityLevel) : p_DelegateOptionsImpl(std::make_unique(backends, backendOptions, logSeverityLevel)) { } DelegateOptions::DelegateOptions(armnn::Compute computeDevice, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel, const armnn::Optional& func) : p_DelegateOptionsImpl(std::make_unique(computeDevice, optimizerOptions, logSeverityLevel, func)) { } DelegateOptions::DelegateOptions(const std::vector& backends, const armnn::OptimizerOptionsOpaque& optimizerOptions, const armnn::Optional& logSeverityLevel, const armnn::Optional& func) : p_DelegateOptionsImpl(std::make_unique(backends, optimizerOptions, logSeverityLevel, func)) { } DelegateOptions::DelegateOptions(char const* const* options_keys, char const* const* options_values, size_t num_options, void (*report_error)(const char*)) : p_DelegateOptionsImpl(std::make_unique()) { armnn::IRuntime::CreationOptions runtimeOptions; armnn::OptimizerOptionsOpaque optimizerOptions; bool internalProfilingState = false; armnn::ProfilingDetailsMethod internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents; for (size_t i = 0; i < num_options; ++i) { // Process backends if (std::string(options_keys[i]) == std::string("backends")) { // The backend option is a comma separated string of backendIDs that needs to be split std::vector backends; char* dup = strdup(options_values[i]); char* pch = std::strtok(dup, ","); while (pch != NULL) { backends.push_back(pch); pch = strtok (NULL, ","); } SetBackends(backends); } // Process dynamic-backends-path else if (std::string(options_keys[i]) == std::string("dynamic-backends-path")) { runtimeOptions.m_DynamicBackendsPath = std::string(options_values[i]); } // Process logging level else if (std::string(options_keys[i]) == std::string("logging-severity")) { SetLoggingSeverity(options_values[i]); } // Process GPU backend options else if (std::string(options_keys[i]) == std::string("gpu-tuning-level")) { armnn::BackendOptions option("GpuAcc", {{"TuningLevel", atoi(options_values[i])}}); runtimeOptions.m_BackendOptions.push_back(option); } else if (std::string(options_keys[i]) == std::string("gpu-mlgo-tuning-file")) { armnn::BackendOptions option("GpuAcc", {{"MLGOTuningFilePath", std::string(options_values[i])}}); optimizerOptions.AddModelOption(option); } else if (std::string(options_keys[i]) == std::string("gpu-tuning-file")) { armnn::BackendOptions option("GpuAcc", {{"TuningFile", std::string(options_values[i])}}); runtimeOptions.m_BackendOptions.push_back(option); } else if (std::string(options_keys[i]) == std::string("gpu-enable-profiling")) { runtimeOptions.m_EnableGpuProfiling = (*options_values[i] != '0'); } else if (std::string(options_keys[i]) == std::string("gpu-kernel-profiling-enabled")) { armnn::BackendOptions option("GpuAcc", {{"KernelProfilingEnabled", armnn::stringUtils::StringToBool(options_values[i])}}); runtimeOptions.m_BackendOptions.push_back(option); } else if (std::string(options_keys[i]) == std::string("save-cached-network")) { armnn::BackendOptions option("GpuAcc", {{"SaveCachedNetwork", armnn::stringUtils::StringToBool(options_values[i])}}); optimizerOptions.AddModelOption(option); } else if (std::string(options_keys[i]) == std::string("cached-network-filepath")) { armnn::BackendOptions option("GpuAcc", {{"CachedNetworkFilePath", std::string(options_values[i])}}); optimizerOptions.AddModelOption(option); } // Process GPU & CPU backend options else if (std::string(options_keys[i]) == std::string("enable-fast-math")) { armnn::BackendOptions modelOptionGpu("GpuAcc", {{"FastMathEnabled", armnn::stringUtils::StringToBool(options_values[i])}}); optimizerOptions.AddModelOption(modelOptionGpu); armnn::BackendOptions modelOptionCpu("CpuAcc", {{"FastMathEnabled", armnn::stringUtils::StringToBool(options_values[i])}}); optimizerOptions.AddModelOption(modelOptionCpu); } // Process CPU backend options else if (std::string(options_keys[i]) == std::string("number-of-threads")) { unsigned int numberOfThreads = armnn::numeric_cast(atoi(options_values[i])); armnn::BackendOptions modelOption("CpuAcc", {{"NumberOfThreads", numberOfThreads}}); optimizerOptions.AddModelOption(modelOption); } // Process reduce-fp32-to-fp16 option else if (std::string(options_keys[i]) == std::string("reduce-fp32-to-fp16")) { optimizerOptions.SetReduceFp32ToFp16(armnn::stringUtils::StringToBool(options_values[i])); } // Process debug-data else if (std::string(options_keys[i]) == std::string("debug-data")) { optimizerOptions.SetDebugEnabled(armnn::stringUtils::StringToBool(options_values[i])); } // Infer output-shape else if (std::string(options_keys[i]) == std::string("infer-output-shape")) { armnn::BackendOptions backendOption("ShapeInferenceMethod", { { "InferAndValidate", armnn::stringUtils::StringToBool(options_values[i]) } }); optimizerOptions.AddModelOption(backendOption); } // Allow expanded dims else if (std::string(options_keys[i]) == std::string("allow-expanded-dims")) { armnn::BackendOptions backendOption("AllowExpandedDims", { { "AllowExpandedDims", armnn::stringUtils::StringToBool(options_values[i]) } }); optimizerOptions.AddModelOption(backendOption); } // Process memory-import else if (std::string(options_keys[i]) == std::string("memory-import")) { optimizerOptions.SetImportEnabled(armnn::stringUtils::StringToBool(options_values[i])); } // Process enable-internal-profiling else if (std::string(options_keys[i]) == std::string("enable-internal-profiling")) { internalProfilingState = *options_values[i] != '0'; optimizerOptions.SetProfilingEnabled(internalProfilingState); } // Process internal-profiling-detail else if (std::string(options_keys[i]) == std::string("internal-profiling-detail")) { uint32_t detailLevel = static_cast(std::stoul(options_values[i])); switch (detailLevel) { case 1: internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsWithEvents; break; case 2: internalProfilingDetail = armnn::ProfilingDetailsMethod::DetailsOnly; break; default: internalProfilingDetail = armnn::ProfilingDetailsMethod::Undefined; break; } } // Process enable-external-profiling else if (std::string(options_keys[i]) == std::string("enable-external-profiling")) { runtimeOptions.m_ProfilingOptions.m_EnableProfiling = armnn::stringUtils::StringToBool(options_values[i]); } // Process timeline-profiling else if (std::string(options_keys[i]) == std::string("timeline-profiling")) { runtimeOptions.m_ProfilingOptions.m_TimelineEnabled = armnn::stringUtils::StringToBool(options_values[i]); } // Process outgoing-capture-file else if (std::string(options_keys[i]) == std::string("outgoing-capture-file")) { runtimeOptions.m_ProfilingOptions.m_OutgoingCaptureFile = options_values[i]; } // Process incoming-capture-file else if (std::string(options_keys[i]) == std::string("incoming-capture-file")) { runtimeOptions.m_ProfilingOptions.m_IncomingCaptureFile = options_values[i]; } // Process file-only-external-profiling else if (std::string(options_keys[i]) == std::string("file-only-external-profiling")) { runtimeOptions.m_ProfilingOptions.m_FileOnly = armnn::stringUtils::StringToBool(options_values[i]); } // Process counter-capture-period else if (std::string(options_keys[i]) == std::string("counter-capture-period")) { runtimeOptions.m_ProfilingOptions.m_CapturePeriod = static_cast(std::stoul(options_values[i])); } // Process profiling-file-format else if (std::string(options_keys[i]) == std::string("profiling-file-format")) { runtimeOptions.m_ProfilingOptions.m_FileFormat = options_values[i]; } // Process serialize-to-dot else if (std::string(options_keys[i]) == std::string("serialize-to-dot")) { SetSerializeToDot(options_values[i]); } // Process disable-tflite-runtime-fallback else if (std::string(options_keys[i]) == std::string("disable-tflite-runtime-fallback")) { this->DisableTfLiteRuntimeFallback(armnn::stringUtils::StringToBool(options_values[i])); } else { throw armnn::Exception("Unknown option for the ArmNN Delegate given: " + std::string(options_keys[i])); } } SetRuntimeOptions(runtimeOptions); SetOptimizerOptions(optimizerOptions); SetInternalProfilingParams(internalProfilingState, internalProfilingDetail); } const std::vector& DelegateOptions::GetBackends() const { return p_DelegateOptionsImpl->m_Backends; } void DelegateOptions::SetBackends(const std::vector& backends) { p_DelegateOptionsImpl->m_Backends = backends; } void DelegateOptions::SetDynamicBackendsPath(const std::string& dynamicBackendsPath) { p_DelegateOptionsImpl->m_RuntimeOptions.m_DynamicBackendsPath = dynamicBackendsPath; } const std::string& DelegateOptions::GetDynamicBackendsPath() const { return p_DelegateOptionsImpl->m_RuntimeOptions.m_DynamicBackendsPath; } void DelegateOptions::SetGpuProfilingState(bool gpuProfilingState) { p_DelegateOptionsImpl->m_RuntimeOptions.m_EnableGpuProfiling = gpuProfilingState; } bool DelegateOptions::GetGpuProfilingState() { return p_DelegateOptionsImpl->m_RuntimeOptions.m_EnableGpuProfiling; } const std::vector& DelegateOptions::GetBackendOptions() const { return p_DelegateOptionsImpl->m_RuntimeOptions.m_BackendOptions; } void DelegateOptions::AddBackendOption(const armnn::BackendOptions& option) { p_DelegateOptionsImpl->m_RuntimeOptions.m_BackendOptions.push_back(option); } void DelegateOptions::SetLoggingSeverity(const armnn::LogSeverity& level) { p_DelegateOptionsImpl->m_LoggingSeverity = level; } void DelegateOptions::SetLoggingSeverity(const std::string& level) { p_DelegateOptionsImpl->m_LoggingSeverity = armnn::StringToLogLevel(level); } armnn::LogSeverity DelegateOptions::GetLoggingSeverity() { return p_DelegateOptionsImpl->m_LoggingSeverity.value(); } bool DelegateOptions::IsLoggingEnabled() { return p_DelegateOptionsImpl->m_LoggingSeverity.has_value(); } const armnn::OptimizerOptionsOpaque& DelegateOptions::GetOptimizerOptions() const { return p_DelegateOptionsImpl->m_OptimizerOptions; } void DelegateOptions::SetOptimizerOptions(const armnn::OptimizerOptionsOpaque& optimizerOptions) { p_DelegateOptionsImpl->m_OptimizerOptions = optimizerOptions; } const armnn::Optional& DelegateOptions::GetDebugCallbackFunction() const { return p_DelegateOptionsImpl->m_DebugCallbackFunc; } void DelegateOptions::SetInternalProfilingParams(bool internalProfilingState, const armnn::ProfilingDetailsMethod& internalProfilingDetail) { p_DelegateOptionsImpl->m_InternalProfilingEnabled = internalProfilingState; p_DelegateOptionsImpl->m_InternalProfilingDetail = internalProfilingDetail; } bool DelegateOptions::GetInternalProfilingState() const { return p_DelegateOptionsImpl->m_InternalProfilingEnabled; } const armnn::ProfilingDetailsMethod& DelegateOptions::GetInternalProfilingDetail() const { return p_DelegateOptionsImpl->m_InternalProfilingDetail; } void DelegateOptions::SetSerializeToDot(const std::string& serializeToDotFile) { p_DelegateOptionsImpl->m_SerializeToDot = serializeToDotFile; } const std::string& DelegateOptions::GetSerializeToDot() const { return p_DelegateOptionsImpl->m_SerializeToDot; } void DelegateOptions::SetRuntimeOptions(const armnn::IRuntime::CreationOptions& runtimeOptions) { p_DelegateOptionsImpl->m_RuntimeOptions = runtimeOptions; } const armnn::IRuntime::CreationOptions& DelegateOptions::GetRuntimeOptions() { return p_DelegateOptionsImpl->m_RuntimeOptions; } void DelegateOptions::DisableTfLiteRuntimeFallback(bool fallbackState) { p_DelegateOptionsImpl->m_DisableTfLiteRuntimeFallback = fallbackState; } bool DelegateOptions::TfLiteRuntimeFallbackDisabled() { return p_DelegateOptionsImpl->m_DisableTfLiteRuntimeFallback; } } // namespace armnnDelegate armnn-23.08/delegate/common/src/DelegateUtils.hpp000066400000000000000000000206721446772241200217560ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { uint32_t NonNegative(int32_t value, int nodeIndex) { if (value < 0) { throw armnn::Exception( "TfLiteArmnnDelegate: Non-negative value in node " + std::to_string(static_cast(nodeIndex))); } else { return static_cast(value); } } void ExpandTensorRankToEqual(armnn::TensorInfo& inputInfo0, armnn::TensorInfo& inputInfo1) { unsigned int inputDimensions0 = inputInfo0.GetNumDimensions(); unsigned int inputDimensions1 = inputInfo1.GetNumDimensions(); if (inputDimensions0 == inputDimensions1) { return; } unsigned int biggerInputDimensions = std::max(inputDimensions0, inputDimensions1); bool input0IsSmaller = inputDimensions0 < inputDimensions1; armnn::TensorInfo& smallInfo = input0IsSmaller ? inputInfo0 : inputInfo1; const armnn::TensorShape& newShape = armnnUtils::ExpandDimsToRank(smallInfo.GetShape(), biggerInputDimensions); smallInfo.SetShape(newShape); } void CalcPadding(uint32_t inputSize, uint32_t filterSize, uint32_t stride, uint32_t dilation, uint32_t& paddingFront, uint32_t& paddingBack, TfLitePadding padding) { paddingFront = 0; paddingBack = 0; if (padding == kTfLitePaddingSame) { uint32_t outputSize = (inputSize + stride - 1) / stride; uint32_t dilatedSize = filterSize + (dilation - 1) * (filterSize - 1); uint32_t temp = (outputSize - 1) * stride + dilatedSize; if (temp > inputSize) { paddingFront = (temp - inputSize) / 2; paddingBack = (temp - inputSize) - paddingFront; } } } // Function that calculates explicit padding when the output shape is known. // At the moment the output is only given as an input parameter in Transpose Convolution, // not in Convolution and Depthwise Convolution void CalcPadding(uint32_t inputSize, uint32_t filterSize, uint32_t stride, uint32_t dilation, uint32_t& paddingFront, uint32_t& paddingBack, TfLitePadding padding, uint32_t outputSize) { armnn::IgnoreUnused(dilation); paddingFront = 0; paddingBack = 0; if (padding == kTfLitePaddingSame) { uint32_t totalPadding = (inputSize - 1) * stride + filterSize - outputSize; paddingFront = totalPadding / 2; paddingBack = totalPadding - paddingFront; } } unsigned int ComputeWrappedIndex(int index, unsigned int numDimensions) { int numDims = armnn::numeric_cast(numDimensions); int wrappedIndex = index < 0 ? numDims + index : index; if (wrappedIndex < 0 || wrappedIndex >= numDims) { throw armnn::ParseException("Unable to compute wrapped index"); } return static_cast(wrappedIndex); }; bool AreAllSigned32(const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { return (armnn::DataType::Signed32 == inputInfo1.GetDataType()) && (armnn::DataType::Signed32 == inputInfo2.GetDataType()) && (armnn::DataType::Signed32 == outputInfo.GetDataType()); } void UpdateConstantTensorOutputs(const armnn::TensorInfo& inputInfo, armnn::TensorInfo& outputInfo) { // If input tensor info is constant and output tensor info shape is not specified // set the output shape from input shape if (inputInfo.IsConstant() && outputInfo.GetShape().GetDimensionality() == armnn::Dimensionality::NotSpecified) { outputInfo.SetShape(inputInfo.GetShape()); } } void SetupConcatViewOrigin(const armnn::TensorInfo& inputTensorInfo, armnn::OriginsDescriptor& concatDescriptor, const unsigned int concatAxis, unsigned int inputIndex, unsigned int& mergeDimOrigin) { const uint32_t inputRank = concatDescriptor.GetNumDimensions(); // double check dimensions of the tensors if (inputTensorInfo.GetNumDimensions() != inputRank) { throw armnn::ParseException("The number of dimensions for input tensors " "of the concatenation operator should be: " + std::to_string(inputRank)); } for (unsigned int j = 0; j < concatAxis; ++j) { concatDescriptor.SetViewOriginCoord(inputIndex, j, 0); } concatDescriptor.SetViewOriginCoord(inputIndex, concatAxis, mergeDimOrigin); mergeDimOrigin += inputTensorInfo.GetShape()[concatAxis]; for (unsigned int j = concatAxis + 1; j < inputRank; ++j) { concatDescriptor.SetViewOriginCoord(inputIndex, j, 0); } } TfLiteStatus CreateOutputTensorShape(const armnn::TensorInfo& inputTensorInfo, const std::vector& targetShape, armnn::ReshapeDescriptor& reshapeDesc) { std::vector outputDims(targetShape.begin(), targetShape.end()); const auto stretchDim = std::find(targetShape.begin(), targetShape.end(), -1); if (stretchDim != targetShape.end()) { if (std::find(std::next(stretchDim), targetShape.end(), -1) != targetShape.end()) { // Return kTfLiteError and log the error after returning return kTfLiteError; } auto targetNumElements = armnn::numeric_cast( std::accumulate(targetShape.begin(), targetShape.end(), -1, std::multiplies())); auto stretchIndex = static_cast(std::distance(targetShape.begin(), stretchDim)); outputDims[stretchIndex] = inputTensorInfo.GetNumElements() / targetNumElements; } armnn::TensorShape outputShape = armnn::TensorShape(static_cast(outputDims.size()), outputDims.data()); reshapeDesc.m_TargetShape = outputShape; return kTfLiteOk; } armnn::TensorInfo OutputShapeOfSqueeze(std::vector squeezeDims, const armnn::TensorInfo& inputTensorInfo) { static const uint32_t dimensionSequence[] = { 0, 1, 2, 3 }; if (inputTensorInfo.GetNumDimensions() > 4) { std::stringstream ss; ss << "Input tensor has unexpected number of dimensions:" << inputTensorInfo.GetNumDimensions() << " shape:" << inputTensorInfo.GetShape() << " " << CHECK_LOCATION().AsString(); throw armnn::ParseException(ss.str()); } if (squeezeDims.empty()) { squeezeDims.assign(dimensionSequence, dimensionSequence + inputTensorInfo.GetNumDimensions()); } std::vector outputDims; for(unsigned int i = 0; i < inputTensorInfo.GetNumDimensions(); i++) { bool skipSqueeze = (std::find(squeezeDims.begin(), squeezeDims.end(), i) == squeezeDims.end()); auto currentDimension = inputTensorInfo.GetShape()[i]; if (skipSqueeze || currentDimension != 1) { outputDims.push_back(currentDimension); } } if (outputDims.size() > 4) { std::stringstream ss; ss << "Output tensor has unexpected number of dimensions:" << inputTensorInfo.GetNumDimensions() << " shape:" << inputTensorInfo.GetShape() << " " << CHECK_LOCATION().AsString(); throw armnn::ParseException(ss.str()); } armnn::TensorShape outShape = armnn::TensorShape(static_cast(outputDims.size()), outputDims.data()); // We need to preserve the tensor type and the quantization data as well armnn::TensorInfo outTensorInfo = inputTensorInfo; outTensorInfo.SetShape(outShape); return outTensorInfo; } } // namespace anonymous armnn-23.08/delegate/common/src/MultiLayerFacade.hpp000066400000000000000000000113601446772241200223700ustar00rootroot00000000000000// // Copyright © 2021-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once // NOTE: the MultiLayerFacade class is a utility class which makes a chain // of operators look like a single IConnectableLayer with the first // layer in the chain supplying the input slots and the last supplying // the output slots. It enables us, for example, to simulate a // Tensorflow Lite FloorDiv operator by chaining a Div layer followed // by a Floor layer and pass them as a single unit to the code that // connects up the graph as the delegate proceeds to build up the // Arm NN subgraphs. // #include #include namespace armnnDelegate { class MultiLayerFacade : public armnn::IConnectableLayer { public: MultiLayerFacade() : m_FirstLayer(nullptr), m_LastLayer(nullptr) {} MultiLayerFacade(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) : m_FirstLayer(firstLayer), m_LastLayer(lastLayer) {} MultiLayerFacade(const MultiLayerFacade& obj) : m_FirstLayer(obj.m_FirstLayer), m_LastLayer(obj.m_LastLayer) {} ~MultiLayerFacade() {} // we don't own the pointers MultiLayerFacade& operator=(const MultiLayerFacade& obj) { m_FirstLayer = obj.m_FirstLayer; m_LastLayer = obj.m_LastLayer; return *this; } void AssignValues(armnn::IConnectableLayer* firstLayer, armnn::IConnectableLayer* lastLayer) { m_FirstLayer = firstLayer; m_LastLayer = lastLayer; } virtual const char* GetName() const override { return m_FirstLayer->GetName(); } virtual unsigned int GetNumInputSlots() const override { return m_FirstLayer->GetNumInputSlots(); } virtual unsigned int GetNumOutputSlots() const override { return m_LastLayer->GetNumOutputSlots(); } virtual const armnn::IInputSlot& GetInputSlot(unsigned int index) const override { return m_FirstLayer->GetInputSlot(index); } virtual armnn::IInputSlot& GetInputSlot(unsigned int index) override { return m_FirstLayer->GetInputSlot(index); } virtual const armnn::IOutputSlot& GetOutputSlot(unsigned int index) const override { return m_LastLayer->GetOutputSlot(index); } virtual armnn::IOutputSlot& GetOutputSlot(unsigned int index) override { return m_LastLayer->GetOutputSlot(index); } virtual std::vector InferOutputShapes( const std::vector& inputShapes) const override { // NOTE: do not expect this function to be used. Likely that if it is it might need to be overridden // for particular sequences of operators. return m_FirstLayer->InferOutputShapes(inputShapes); } virtual LayerGuid GetGuid() const override { return m_FirstLayer->GetGuid(); } virtual void ExecuteStrategy(armnn::IStrategy& strategy) const override { // Do not expect this function to be used so not providing an implementation // if an implementation is required and the chain contains more than two operators // would have to provide a way to record the intermediate layers so they could be // visited... the same applies to the BackendSelectionHint // below. } virtual void BackendSelectionHint(armnn::Optional backend) override { // Do not expect this function to be used so not providing an implementation } virtual armnn::LayerType GetType() const override { return m_FirstLayer->GetType(); } virtual const armnn::BaseDescriptor& GetParameters() const override { return m_NullDescriptor; } void SetBackendId(const armnn::BackendId& id) override {} protected: /// Retrieve the handles to the constant values stored by the layer. /// @return A vector of the constant tensors stored by this layer. ConstantTensors GetConstantTensorsByRef() override { return {}; } ImmutableConstantTensors GetConstantTensorsByRef() const override { return {}; } private: armnn::IConnectableLayer* m_FirstLayer; armnn::IConnectableLayer* m_LastLayer; // to satisfy the GetParameters method need to hand back a NullDescriptor armnn::NullDescriptor m_NullDescriptor; }; } // namespace armnnDelegate armnn-23.08/delegate/common/src/test/000077500000000000000000000000001446772241200174625ustar00rootroot00000000000000armnn-23.08/delegate/common/src/test/DelegateTestInterpreter.hpp000066400000000000000000000145151446772241200247770ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include #include namespace delegateTestInterpreter { class DelegateTestInterpreter { public: /// Create TfLite Interpreter only DelegateTestInterpreter(std::vector& modelBuffer, const std::string& customOp = "") { TfLiteModel* model = delegateTestInterpreter::CreateTfLiteModel(modelBuffer); TfLiteInterpreterOptions* options = delegateTestInterpreter::CreateTfLiteInterpreterOptions(); if (!customOp.empty()) { options->mutable_op_resolver = delegateTestInterpreter::GenerateCustomOpResolver(customOp); } m_TfLiteInterpreter = TfLiteInterpreterCreate(model, options); m_TfLiteDelegate = nullptr; // The options and model can be deleted after the interpreter is created. TfLiteInterpreterOptionsDelete(options); TfLiteModelDelete(model); } /// Create Interpreter with default Arm NN Classic/Opaque Delegate applied DelegateTestInterpreter(std::vector& model, const std::vector& backends, const std::string& customOp = "", bool disableFallback = true); /// Create Interpreter with Arm NN Classic/Opaque Delegate applied and DelegateOptions DelegateTestInterpreter(std::vector& model, const armnnDelegate::DelegateOptions& delegateOptions, const std::string& customOp = ""); /// Allocate the TfLiteTensors within the graph. /// This must be called before FillInputTensor(values, index) and Invoke(). TfLiteStatus AllocateTensors() { return TfLiteInterpreterAllocateTensors(m_TfLiteInterpreter); } /// Copy a buffer of values into an input tensor at a given index. template TfLiteStatus FillInputTensor(std::vector& inputValues, int index) { TfLiteTensor* inputTensor = delegateTestInterpreter::GetInputTensorFromInterpreter(m_TfLiteInterpreter, index); return delegateTestInterpreter::CopyFromBufferToTensor(inputTensor, inputValues); } /// Copy a boolean buffer of values into an input tensor at a given index. /// Boolean types get converted to a bit representation in a vector. /// vector.data() returns a void pointer instead of a pointer to bool, so the tensor needs to be accessed directly. TfLiteStatus FillInputTensor(std::vector& inputValues, int index) { TfLiteTensor* inputTensor = delegateTestInterpreter::GetInputTensorFromInterpreter(m_TfLiteInterpreter, index); if(inputTensor->type != kTfLiteBool) { throw armnn::Exception("Input tensor at the given index is not of bool type: " + std::to_string(index)); } // Make sure there is enough bytes allocated to copy into. if(inputTensor->bytes < inputValues.size() * sizeof(bool)) { throw armnn::Exception("Input tensor has not been allocated to match number of input values."); } for (unsigned int i = 0; i < inputValues.size(); ++i) { inputTensor->data.b[i] = inputValues[i]; } return kTfLiteOk; } /// Run the interpreter either on TFLite Runtime or Arm NN Delegate. /// AllocateTensors() must be called before Invoke(). TfLiteStatus Invoke() { return TfLiteInterpreterInvoke(m_TfLiteInterpreter); } /// Return a buffer of values from the output tensor at a given index. /// This must be called after Invoke(). template std::vector GetOutputResult(int index) { const TfLiteTensor* outputTensor = delegateTestInterpreter::GetOutputTensorFromInterpreter(m_TfLiteInterpreter, index); int64_t n = tflite::NumElements(outputTensor); std::vector output; output.resize(n); TfLiteStatus status = TfLiteTensorCopyToBuffer(outputTensor, output.data(), output.size() * sizeof(T)); if(status != kTfLiteOk) { throw armnn::Exception("An error occurred when copying output buffer."); } return output; } /// Return a buffer of values from the output tensor at a given index. This must be called after Invoke(). /// Boolean types get converted to a bit representation in a vector. /// vector.data() returns a void pointer instead of a pointer to bool, so the tensor needs to be accessed directly. std::vector GetOutputResult(int index) { const TfLiteTensor* outputTensor = delegateTestInterpreter::GetOutputTensorFromInterpreter(m_TfLiteInterpreter, index); if(outputTensor->type != kTfLiteBool) { throw armnn::Exception("Output tensor at the given index is not of bool type: " + std::to_string(index)); } int64_t n = tflite::NumElements(outputTensor); std::vector output(n, false); output.reserve(n); for (unsigned int i = 0; i < output.size(); ++i) { output[i] = outputTensor->data.b[i]; } return output; } /// Return a buffer of dimensions from the output tensor at a given index. std::vector GetOutputShape(int index) { const TfLiteTensor* outputTensor = delegateTestInterpreter::GetOutputTensorFromInterpreter(m_TfLiteInterpreter, index); int32_t numDims = TfLiteTensorNumDims(outputTensor); std::vector dims; dims.reserve(numDims); for (int32_t i = 0; i < numDims; ++i) { dims.push_back(TfLiteTensorDim(outputTensor, i)); } return dims; } /// Delete TfLiteInterpreter and the TfLiteDelegate/TfLiteOpaqueDelegate void Cleanup(); private: TfLiteInterpreter* m_TfLiteInterpreter; /// m_TfLiteDelegate can be TfLiteDelegate or TfLiteOpaqueDelegate void* m_TfLiteDelegate; }; } // anonymous namespacearmnn-23.08/delegate/common/src/test/DelegateTestInterpreterUtils.hpp000066400000000000000000000065141446772241200260200ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace delegateTestInterpreter { inline TfLiteTensor* GetInputTensorFromInterpreter(TfLiteInterpreter* interpreter, int index) { TfLiteTensor* inputTensor = TfLiteInterpreterGetInputTensor(interpreter, index); if(inputTensor == nullptr) { throw armnn::Exception("Input tensor was not found at the given index: " + std::to_string(index)); } return inputTensor; } inline const TfLiteTensor* GetOutputTensorFromInterpreter(TfLiteInterpreter* interpreter, int index) { const TfLiteTensor* outputTensor = TfLiteInterpreterGetOutputTensor(interpreter, index); if(outputTensor == nullptr) { throw armnn::Exception("Output tensor was not found at the given index: " + std::to_string(index)); } return outputTensor; } inline TfLiteModel* CreateTfLiteModel(std::vector& data) { TfLiteModel* tfLiteModel = TfLiteModelCreate(data.data(), data.size()); if(tfLiteModel == nullptr) { throw armnn::Exception("An error has occurred when creating the TfLiteModel."); } return tfLiteModel; } inline TfLiteInterpreterOptions* CreateTfLiteInterpreterOptions() { TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); if(options == nullptr) { throw armnn::Exception("An error has occurred when creating the TfLiteInterpreterOptions."); } return options; } inline tflite::ops::builtin::BuiltinOpResolver GenerateCustomOpResolver(const std::string& opName) { tflite::ops::builtin::BuiltinOpResolver opResolver; if (opName == "MaxPool3D") { opResolver.AddCustom("MaxPool3D", tflite::ops::custom::Register_MAX_POOL_3D()); } else if (opName == "AveragePool3D") { opResolver.AddCustom("AveragePool3D", tflite::ops::custom::Register_AVG_POOL_3D()); } else { throw armnn::Exception("The custom op isn't supported by the DelegateTestInterpreter."); } return opResolver; } template inline TfLiteStatus CopyFromBufferToTensor(TfLiteTensor* tensor, std::vector& values) { // Make sure there is enough bytes allocated to copy into for uint8_t and int16_t case. if(tensor->bytes < values.size() * sizeof(T)) { throw armnn::Exception("Tensor has not been allocated to match number of values."); } // Requires uint8_t and int16_t specific case as the number of bytes is larger than values passed when creating // TFLite tensors of these types. Otherwise, use generic TfLiteTensorCopyFromBuffer function. TfLiteStatus status = kTfLiteOk; if (std::is_same::value) { for (unsigned int i = 0; i < values.size(); ++i) { tensor->data.uint8[i] = values[i]; } } else if (std::is_same::value) { for (unsigned int i = 0; i < values.size(); ++i) { tensor->data.i16[i] = values[i]; } } else { status = TfLiteTensorCopyFromBuffer(tensor, values.data(), values.size() * sizeof(T)); } return status; } } // anonymous namespacearmnn-23.08/delegate/include/000077500000000000000000000000001446772241200160475ustar00rootroot00000000000000armnn-23.08/delegate/include/DelegateOptions.hpp000066400000000000000000000006061446772241200216500ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #pragma message("armnn/delegate/include/DelegateOptions.hpp has been deprecated, it is due for removal in"\ " 24.02 release. Please include armnn/delegate/common/include/DelegateOptions.hpp instead.") armnn-23.08/delegate/include/Version.hpp000066400000000000000000000005601446772241200202060ustar00rootroot00000000000000// // Copyright © 2021-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #pragma message("armnn/delegate/include/Version.hpp has been deprecated, it is due for removal in"\ " 24.02 release. Please include armnn/delegate/classic/include/Version.hpp instead.") armnn-23.08/delegate/include/armnn_delegate.hpp000066400000000000000000000006051446772241200215260ustar00rootroot00000000000000// // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #pragma message("armnn/delegate/include/armnn_delegate.hpp has been deprecated, it is due for removal in"\ " 24.02 release. Please include armnn/delegate/classic/include/armnn_delegate.hpp instead.") armnn-23.08/delegate/opaque/000077500000000000000000000000001446772241200157165ustar00rootroot00000000000000armnn-23.08/delegate/opaque/CMakeLists.txt000066400000000000000000000072101446772241200204560ustar00rootroot00000000000000# # Copyright © 2023 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # set(armnnOpaqueDelegateObject_sources) list(APPEND armnnOpaqueDelegateObject_sources include/armnn_delegate.hpp include/Version.hpp src/Activation.hpp src/ArgMinMax.hpp src/armnn_delegate.cpp src/armnn_external_delegate.cpp src/BatchMatMul.hpp src/BatchSpace.hpp src/Comparison.hpp src/Control.hpp src/Convolution.hpp src/ElementwiseBinary.hpp src/ElementwiseUnary.hpp src/FullyConnected.hpp src/Gather.hpp src/GatherNd.hpp src/LogicalBinary.hpp src/Lstm.hpp src/Normalization.hpp src/Pad.hpp src/Pooling.hpp src/Pack.hpp src/Prelu.hpp src/Redefine.hpp src/Reduce.hpp src/Resize.hpp src/ReverseV2.hpp src/Round.hpp src/Shape.hpp src/SharedFunctions.cpp src/SharedFunctions.hpp src/Slice.hpp src/Softmax.hpp src/SpaceDepth.hpp src/Split.hpp src/StridedSlice.hpp src/Tile.hpp src/Transpose.hpp src/UnidirectionalSequenceLstm.hpp src/Unpack.hpp) add_library(armnnOpaqueDelegateObject OBJECT ${armnnOpaqueDelegateObject_sources}) target_include_directories(armnnOpaqueDelegateObject PUBLIC $ $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/common/src) ## Add Tflite dependency if(NOT TfLite_INCLUDE_DIR OR NOT TfLite_Schema_INCLUDE_PATH) find_package(TfLiteSrc REQUIRED MODULE) endif() # Various tflite header files are not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(tflite_headers_opaque INTERFACE) target_include_directories(tflite_headers_opaque INTERFACE $ $) target_compile_options(tflite_headers_opaque INTERFACE -Wno-conversion -Wno-sign-conversion -Wno-unused-parameter -Wno-unused-function) target_link_libraries(armnnOpaqueDelegateObject PUBLIC tflite_headers_opaque) ## Add Flatbuffers dependency find_package(Flatbuffers REQUIRED MODULE) target_link_libraries(armnnOpaqueDelegateObject PRIVATE ${Flatbuffers_LIB}) # include/flatbuffers/flatbuffers.h is not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(flatbuffer_headers_opaque INTERFACE) target_include_directories(flatbuffer_headers_opaque INTERFACE $ $) target_compile_options(flatbuffer_headers_opaque INTERFACE -Wno-sign-conversion) target_link_libraries(armnnOpaqueDelegateObject PUBLIC flatbuffer_headers_opaque) # Additional Absl Sync for Opaque Delegate find_package(TfLiteAbsl REQUIRED MODULE) target_include_directories(armnnOpaqueDelegateObject PUBLIC ${TfLite_ABSL_SYNC_HEADERS}) target_link_libraries(armnnOpaqueDelegateObject PUBLIC ${TfLite_Extra_Absl_LIB}) #################################################### ## Export targets install(TARGETS armnnOpaqueDelegateObject LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) armnn-23.08/delegate/opaque/include/000077500000000000000000000000001446772241200173415ustar00rootroot00000000000000armnn-23.08/delegate/opaque/include/Version.hpp000066400000000000000000000014601446772241200215000ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once namespace armnnOpaqueDelegate { /// Macro utils #define STRINGIFY_VALUE(s) STRINGIFY_MACRO(s) #define STRINGIFY_MACRO(s) #s // ArmNN Delegate version components #define OPAQUE_DELEGATE_MAJOR_VERSION 1 #define OPAQUE_DELEGATE_MINOR_VERSION 0 #define OPAQUE_DELEGATE_PATCH_VERSION 0 /// DELEGATE_VERSION: "X.Y.Z" /// where: /// X = Major version number /// Y = Minor version number /// Z = Patch version number #define OPAQUE_DELEGATE_VERSION STRINGIFY_VALUE(OPAQUE_DELEGATE_MAJOR_VERSION) "." \ STRINGIFY_VALUE(OPAQUE_DELEGATE_MINOR_VERSION) "." \ STRINGIFY_VALUE(OPAQUE_DELEGATE_PATCH_VERSION) } //namespace armnnDelegatearmnn-23.08/delegate/opaque/include/armnn_delegate.hpp000066400000000000000000000134271446772241200230260ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #if TF_MAJOR_VERSION > 2 || (TF_MAJOR_VERSION == 2 && TF_MINOR_VERSION > 5) #define ARMNN_POST_TFLITE_2_5 #endif namespace armnnOpaqueDelegate { struct DelegateData { DelegateData(const std::vector& backends) : m_Backends(backends) , m_Network(nullptr, nullptr) {} const std::vector m_Backends; armnn::INetworkPtr m_Network; std::vector m_OutputSlotForNode; }; /// Forward declaration for functions initializing the ArmNN Delegate ::armnnDelegate::DelegateOptions TfLiteArmnnDelegateOptionsDefault(); TfLiteOpaqueDelegate* TfLiteArmnnOpaqueDelegateCreate(const void* settings); void TfLiteArmnnOpaqueDelegateDelete(TfLiteOpaqueDelegate* tfLiteDelegate); TfLiteStatus DoPrepare(TfLiteOpaqueContext* context, TfLiteOpaqueDelegate* delegate, void* data); /// ArmNN Opaque Delegate class ArmnnOpaqueDelegate { friend class ArmnnSubgraph; public: explicit ArmnnOpaqueDelegate(armnnDelegate::DelegateOptions options); TfLiteIntArray* IdentifyOperatorsToDelegate(TfLiteOpaqueContext* context); TfLiteOpaqueDelegateBuilder* GetDelegateBuilder() { return &m_Builder; } /// Retrieve version in X.Y.Z form static const std::string GetVersion(); private: /** * Returns a pointer to the armnn::IRuntime* this will be shared by all armnn_delegates. */ armnn::IRuntime* GetRuntime(const armnn::IRuntime::CreationOptions& options) { static armnn::IRuntimePtr instance = armnn::IRuntime::Create(options); /// Instantiated on first use. return instance.get(); } TfLiteOpaqueDelegateBuilder m_Builder = { reinterpret_cast(this), // .data_ DoPrepare, // .Prepare nullptr, // .CopyFromBufferHandle nullptr, // .CopyToBufferHandle nullptr, // .FreeBufferHandle kTfLiteDelegateFlagsNone, // .flags }; /// ArmNN Runtime pointer armnn::IRuntime* m_Runtime; /// ArmNN Delegate Options armnnDelegate::DelegateOptions m_Options; }; static int TfLiteArmnnOpaqueDelegateErrno(TfLiteOpaqueDelegate* delegate) { return 0; } /// In order for the delegate to be loaded by TfLite const TfLiteOpaqueDelegatePlugin* GetArmnnDelegatePluginApi(); using tflite::delegates::DelegatePluginInterface; using TfLiteOpaqueDelegatePtr = tflite::delegates::TfLiteDelegatePtr; class ArmnnDelegatePlugin : public DelegatePluginInterface { public: static std::unique_ptr New(const tflite::TFLiteSettings& tflite_settings) { return std::make_unique(tflite_settings); } tflite::delegates::TfLiteDelegatePtr Create() override { // Use default settings until options have been enabled. return tflite::delegates::TfLiteDelegatePtr( TfLiteArmnnOpaqueDelegateCreate(nullptr), TfLiteArmnnOpaqueDelegateDelete); } int GetDelegateErrno(TfLiteOpaqueDelegate* from_delegate) override { return 0; } explicit ArmnnDelegatePlugin(const tflite::TFLiteSettings& tfliteSettings) { // Use default settings until options have been enabled. } }; /// ArmnnSubgraph class where parsing the nodes to ArmNN format and creating the ArmNN Graph class ArmnnSubgraph { public: static ArmnnSubgraph* Create(TfLiteOpaqueContext* tfLiteContext, const TfLiteOpaqueDelegateParams* parameters, const ArmnnOpaqueDelegate* delegate); TfLiteStatus Prepare(TfLiteOpaqueContext* tfLiteContext); TfLiteStatus Invoke(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode); static TfLiteStatus VisitNode(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteRegistrationExternal* tfLiteRegistration, TfLiteOpaqueNode* tfLiteNode, int nodeIndex); private: ArmnnSubgraph(armnn::NetworkId networkId, armnn::IRuntime* runtime, std::vector& inputBindings, std::vector& outputBindings) : m_NetworkId(networkId) , m_Runtime(runtime) , m_InputBindings(inputBindings) , m_OutputBindings(outputBindings) {} static TfLiteStatus AddInputLayer(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const TfLiteIntArray* inputs, std::vector& inputBindings); static TfLiteStatus AddOutputLayer(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const TfLiteIntArray* outputs, std::vector& outputBindings); /// The Network Id armnn::NetworkId m_NetworkId; /// ArmNN Runtime armnn::IRuntime* m_Runtime; /// Binding information for inputs and outputs std::vector m_InputBindings; std::vector m_OutputBindings; }; } // armnnOpaqueDelegate namespacearmnn-23.08/delegate/opaque/src/000077500000000000000000000000001446772241200165055ustar00rootroot00000000000000armnn-23.08/delegate/opaque/src/Activation.hpp000066400000000000000000000167721446772241200213340ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { std::string GetLayerName(armnn::ActivationFunction activationFunction) { std::string layerName = "ACTIVATION"; switch (activationFunction) { case armnn::ActivationFunction::Abs: layerName += " ABS"; break; case armnn::ActivationFunction::BoundedReLu: layerName += " BOUNDED_RELU"; break; case armnn::ActivationFunction::Elu: layerName += " ELU"; break; case armnn::ActivationFunction::HardSwish: layerName += " HARD_SWISH"; break; case armnn::ActivationFunction::LeakyReLu: layerName += " LEAKY_RELU"; break; case armnn::ActivationFunction::Linear: layerName += " LINEAR"; break; case armnn::ActivationFunction::ReLu: layerName += " RELU"; break; case armnn::ActivationFunction::Sigmoid: layerName += " SIGMOID"; break; case armnn::ActivationFunction::SoftReLu: layerName += " SOFT_RELU"; break; case armnn::ActivationFunction::Square: layerName += " SQUARE"; break; case armnn::ActivationFunction::Sqrt: layerName += " SQRT"; break; case armnn::ActivationFunction::TanH: layerName += " TANH"; break; default: layerName += " UNKNOWN"; } return layerName; } TfLiteStatus ValidateActivationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, armnn::ActivationDescriptor& activationDesc) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported, std::string layerName) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC(layerName.c_str(), tfLiteContext, IsActivationSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, activationDesc); }; validateFunc(outputInfo, isSupported, GetLayerName(activationDesc.m_Function)); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitActivationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::ActivationDescriptor activationDesc; switch(operatorCode) { case kTfLiteBuiltinRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } case kTfLiteBuiltinRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; break; } case kTfLiteBuiltinLogistic: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteBuiltinTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } case kTfLiteBuiltinElu: { activationDesc.m_Function = armnn::ActivationFunction::Elu; activationDesc.m_A = 1.0f; break; } case kTfLiteBuiltinHardSwish: { activationDesc.m_Function = armnn::ActivationFunction::HardSwish; break; } case kTfLiteBuiltinLeakyRelu: { // Get alpha param from builtin data auto* leakyReluParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); activationDesc.m_Function = armnn::ActivationFunction::LeakyReLu; activationDesc.m_A = leakyReluParameters->alpha; break; } default: { return kTfLiteError; } } if (!delegateData.m_Network) { return ValidateActivationOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, activationDesc); } auto layerName = GetName(activationDesc.m_Function, nodeIndex); armnn::IConnectableLayer* activationLayer = delegateData.m_Network->AddActivationLayer(activationDesc, layerName.c_str()); ARMNN_ASSERT(activationLayer != nullptr); armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(activationLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(activationLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/opaque/src/ArgMinMax.hpp000066400000000000000000000146751446772241200210560ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitArgMinMaxOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t argMinMaxOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get filter tensor. const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if(!IsValid(tfLiteAxisTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Invalid filter tensor in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Get const axis value from model and set it to descriptor. if (!IsValid(tfLiteContext, tfLiteAxisTensor, argMinMaxOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::ArgMinMaxDescriptor desc; auto* axisData = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); // Get the axis value from the input tensor switch (TfLiteOpaqueTensorType(tfLiteAxisTensor)) { case kTfLiteInt32: case kTfLiteInt64: desc.m_Axis = axisData[0]; break; default: TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Axis value data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } // If output_type is int32 then set Signed32 else Signed64. Default type is Signed64. if (argMinMaxOperatorCode == kTfLiteBuiltinArgMax) { desc.m_Function = armnn::ArgMinMaxFunction::Max; auto* argMaxParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); if (argMaxParameters->output_type != kTfLiteInt32 && argMaxParameters->output_type != kTfLiteInt64) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: output_type data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } } else { desc.m_Function = armnn::ArgMinMaxFunction::Min; auto* argMinParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); if (argMinParameters->output_type != kTfLiteInt32 && argMinParameters->output_type != kTfLiteInt64) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: output_type data type is not supported in operator #%d node #%d: ", argMinMaxOperatorCode, nodeIndex); return kTfLiteError; } } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("ARGMINMAX", tfLiteContext, IsArgMinMaxSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add an ArgMinMax layer auto layerName = GetName(desc.m_Function, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddArgMinMaxLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } }armnn-23.08/delegate/opaque/src/BatchMatMul.hpp000066400000000000000000000115041446772241200213600ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitBatchMatMulOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* kTfLiteLHSInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); const TfLiteOpaqueTensor* kTfLiteRHSInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, kTfLiteLHSInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } if (!IsValid(tfLiteContext, kTfLiteRHSInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* kTfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (IsDynamicTensor(kTfLiteOutputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& armnnLHSInputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(kTfLiteLHSInputTensor); const armnn::TensorInfo& armnnRHSInputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(kTfLiteRHSInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(kTfLiteOutputTensor, true); armnn::BatchMatMulDescriptor descriptor; auto* params = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); // Tensorflow params are called adjoint, however they are actually just transposes behind the scene. They do // not perform ajoint. descriptor.m_TransposeX = params->adj_x; descriptor.m_TransposeY = params->adj_y; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("BATCH_MATMUL", tfLiteContext, IsBatchMatMulSupported, delegateData.m_Backends, isSupported, setBackend, armnnLHSInputTensorInfo, armnnRHSInputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::BatchMatMul, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchMatMulLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/BatchSpace.hpp000066400000000000000000000265641446772241200212300ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitBatchToSpaceNdOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numInputs = 3; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteBlockShapeTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteBlockShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteCropsTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteCropsTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& blockShapeTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBlockShapeTensor); const armnn::TensorInfo& cropsTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteCropsTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Copy memory into block and crops std::vector blockShape(blockShapeTensorInfo.GetNumElements()); ::memcpy(blockShape.data(), TfLiteOpaqueTensorData(tfLiteBlockShapeTensor), blockShapeTensorInfo.GetNumBytes()); std::vector cropsVector(cropsTensorInfo.GetNumElements()); std::memcpy(cropsVector.data(), TfLiteOpaqueTensorData(tfLiteCropsTensor), cropsTensorInfo.GetNumBytes()); size_t step = 2; std::vector> crops; for (unsigned int i = 0; i < cropsTensorInfo.GetNumElements() / step; ++i) { crops.emplace_back(cropsVector[i * step], cropsVector[i * step + 1]); } // Make a descriptor armnn::BatchToSpaceNdDescriptor descriptor; descriptor.m_BlockShape = blockShape; descriptor.m_Crops = crops; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("BATCH_TO_SPACE_ND", tfLiteContext, IsBatchToSpaceNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitBatchToSpaceNdOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a BatchToSpace layer auto layerName = GetName(armnn::LayerType::BatchToSpaceNd, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddBatchToSpaceNdLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitSpaceToBatchNdOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numInputs = 3; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext,inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteBlockShapeTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteBlockShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLitePadListTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLitePadListTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& blockShapeTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBlockShapeTensor); const armnn::TensorInfo& padListTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLitePadListTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); std::vector blockShape(blockShapeTensorInfo.GetNumElements()); std::memcpy(blockShape.data(), TfLiteOpaqueTensorData(tfLiteBlockShapeTensor), blockShapeTensorInfo.GetNumBytes()); std::vector padListVector(padListTensorInfo.GetNumElements()); std::memcpy(padListVector.data(), TfLiteOpaqueTensorData(tfLitePadListTensor), padListTensorInfo.GetNumBytes()); size_t step = 2; std::vector> padList; for (unsigned int i = 0; i < padListTensorInfo.GetNumElements() / step; ++i) { padList.emplace_back(padListVector[i * step], padListVector[i * step + 1]); } armnn::SpaceToBatchNdDescriptor descriptor; descriptor.m_BlockShape = blockShape; descriptor.m_PadList = padList; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SPACE_TO_BATCH_ND", tfLiteContext, IsSpaceToBatchNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitSpaceToBatchNdOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a SpaceToBatch layer auto layerName = GetName(armnn::LayerType::SpaceToBatchNd, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToBatchNdLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespacearmnn-23.08/delegate/opaque/src/Comparison.hpp000066400000000000000000000133621446772241200213350ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { std::string GetOperationName(armnn::ComparisonOperation comparisonOperation) { std::string layerName = "COMPARISON"; switch (comparisonOperation) { case armnn::ComparisonOperation::NotEqual: layerName += " NOT_EQUAL"; break; case armnn::ComparisonOperation::Equal: layerName += " EQUAL"; break; case armnn::ComparisonOperation::Greater: layerName += " GREATER"; break; case armnn::ComparisonOperation::GreaterOrEqual: layerName += " GREATER_OR_EQUAL"; break; case armnn::ComparisonOperation::Less: layerName += " LESS"; break; case armnn::ComparisonOperation::LessOrEqual: layerName += " LESS_OR_EQUAL"; break; default: layerName += " UNKNOWN"; } return layerName; } TfLiteStatus VisitComparisonOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteComparisonOperatorCode, armnn::ComparisonOperation comparisonOperation) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensors. const TfLiteOpaqueTensor* tfLiteInputTensor0 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor0, tfLiteComparisonOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor1 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteInputTensor1, tfLiteComparisonOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use output indices to get output tensor. const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteComparisonOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of the input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } armnn::ComparisonDescriptor descriptor(comparisonOperation); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported, std::string layerName) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC(layerName.c_str(), tfLiteContext, IsComparisonSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported, GetOperationName(comparisonOperation)); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(descriptor.m_Operation, nodeIndex); armnn::IConnectableLayer* comparisonLayer = delegateData.m_Network->AddComparisonLayer(descriptor, layerName.c_str()); comparisonLayer->SetBackendId(setBackend); ARMNN_ASSERT(comparisonLayer != nullptr); armnn::IOutputSlot& outputSlot = comparisonLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(comparisonLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(comparisonLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Control.hpp000066400000000000000000000310301446772241200206330ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitConcatenationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteConcatOperatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } std::vector inputTensorInfos; for (int i = 0; i < numInputs; ++i) { const TfLiteOpaqueTensor* inputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[i]); if (!IsValid(tfLiteContext, inputTensor, tfLiteConcatOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(inputTensor); inputTensorInfos.emplace_back(inputTensorInfo); } // Convert input tensors to const armnn::TensorInfo* type for FORWARD_LAYER_SUPPORT_FUNC. std::vector inputConstTensorInfos; std::transform(inputTensorInfos.begin(), inputTensorInfos.end(), std::back_inserter(inputConstTensorInfos), [](armnn::TensorInfo& t)->const armnn::TensorInfo*{ return &t; }); // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteConcatOperatorCode, nodeIndex)) { return kTfLiteError; } // Setup OriginsDescriptor, axis and view origin auto numConcatView = static_cast(numInputs); uint32_t inputRank = TfLiteOpaqueTensorNumDims(TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0])); auto* concatenationParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); if(!concatenationParameters) { throw armnn::Exception(&"TfLiteArmnnOpaqueDelegate: Concat parameters are null in: " [ nodeIndex ]); } const auto concatDimInput = static_cast( (static_cast(inputRank) + concatenationParameters->axis) % static_cast(inputRank)); armnn::OriginsDescriptor concatDescriptor(static_cast(numConcatView), inputRank); concatDescriptor.SetConcatAxis(concatDimInput); unsigned int mergeDimOrigin = 0; for (unsigned int viewIndex = 0; viewIndex < numConcatView; ++viewIndex) { armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[viewIndex])); // Sets up concatDescriptor view origin SetupConcatViewOrigin(inputTensorInfo, concatDescriptor, concatDimInput, viewIndex, mergeDimOrigin); } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Verify we support the fused activation before attempting to create a layer TfLiteFusedActivation activationType = concatenationParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("CONCATENATION", tfLiteContext, IsConcatSupported, delegateData.m_Backends, isSupported, setBackend, inputConstTensorInfos, outputTensorInfo, concatDescriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Setup layer and connect. auto layerName = GetName(armnn::LayerType::Concat, nodeIndex); armnn::IConnectableLayer* concatenationLayer = delegateData.m_Network->AddConcatLayer(concatDescriptor, layerName.c_str()); concatenationLayer->SetBackendId(setBackend); ARMNN_ASSERT(concatenationLayer != nullptr); // Connect the Constant Inputs auto inputsTensorsProcess = ProcessInputs(concatenationLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } armnn::IOutputSlot& outputSlot = concatenationLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(concatenationLayer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (activationType == kTfLiteActNone) { // No Activation return kTfLiteOk; } // Check and Create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, concatenationLayer, 0, delegateData, nodeIndex); } TfLiteStatus VisitMeanOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteMeanOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteMeanOperatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get axis tensor. const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteAxisTensor, tfLiteMeanOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteMeanOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& axisTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteAxisTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* axisTensorData = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); std::vector axis; // Add axis data to vector to be converter to unsigned int and assigned to descriptor axis. for (unsigned int i = 0; i < axisTensorInfo.GetNumElements(); ++i) { axis.emplace_back(axisTensorData[i]); } // Convert the axis to unsigned int and remove duplicates. unsigned int rank = inputTensorInfo.GetNumDimensions(); std::set uniqueAxis; std::transform(axis.begin(), axis.end(), std::inserter(uniqueAxis, uniqueAxis.begin()), [rank](int i)->unsigned int{ return (i + rank) % rank; }); // Setup MeanDescriptor and assign axis and keepDims armnn::MeanDescriptor desc; desc.m_Axis.assign(uniqueAxis.begin(), uniqueAxis.end()); desc.m_KeepDims = inputTensorInfo.GetNumDimensions() == outputTensorInfo.GetNumDimensions() ? true : false; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("MEAN", tfLiteContext, IsMeanSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Setup layer and connect. auto layerName = GetName(armnn::LayerType::Mean, nodeIndex); armnn::IConnectableLayer* meanLayer = delegateData.m_Network->AddMeanLayer(desc, layerName.c_str()); meanLayer->SetBackendId(setBackend); ARMNN_ASSERT(meanLayer != nullptr); armnn::IOutputSlot& outputSlot = meanLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(meanLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(meanLayer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitControlOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { switch(operatorCode) { case kTfLiteBuiltinConcatenation: return VisitConcatenationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinMean: return VisitMeanOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); default: return kTfLiteError; } } } // namespace armnnDelegate armnn-23.08/delegate/opaque/src/Convolution.hpp000066400000000000000000001115431446772241200215420ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include #include #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitConv2dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get filter tensor. const TfLiteOpaqueTensor* tfLiteFilterTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteFilterTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } armnn::TensorInfo biasTensorInfo; const TfLiteOpaqueTensor* tfLiteBiasTensor = nullptr; bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); if(biasEnabled) { // Use input indices to get bias tensor. tfLiteBiasTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::Optional optionalBiasInfo(biasTensorInfo); armnn::Convolution2dDescriptor descriptor; descriptor.m_BiasEnabled = biasEnabled; descriptor.m_StrideX = NonNegative(tfLiteNodeParameters->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(tfLiteNodeParameters->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_DilationX = NonNegative(tfLiteNodeParameters->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(tfLiteNodeParameters->dilation_height_factor, nodeIndex); // TfLite uses NHWC tensors const unsigned int inputHeight = inputTensorInfo.GetShape()[1]; const unsigned int inputWidth = inputTensorInfo.GetShape()[2]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, tfLiteNodeParameters->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, tfLiteNodeParameters->padding); armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("CONV2D", tfLiteContext, IsConvolution2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, optionalBiasInfo); return isSupported ? kTfLiteOk : kTfLiteError; } // Set up filter and biases auto layerName = GetName(armnn::LayerType::Convolution2d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution2dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); if(filterTensorInfo.IsConstant()) { auto filter = CreateConstTensor(tfLiteFilterTensor, filterTensorInfo); auto filterName = GetName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if (biasEnabled) { if (biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(tfLiteBiasTensor, biasTensorInfo); auto biasName = GetName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if (inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); auto inputName = GetName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if (Connect(layer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } TfLiteStatus VisitDepthwiseConv2dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get filter tensor. const TfLiteOpaqueTensor* tfLiteFilterTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteFilterTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } armnn::TensorInfo biasTensorInfo; const TfLiteOpaqueTensor* tfLiteBiasTensor = nullptr; bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); if(biasEnabled) { // Use input indices to get bias tensor. tfLiteBiasTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::DepthwiseConvolution2dDescriptor descriptor; descriptor.m_BiasEnabled = biasEnabled; descriptor.m_StrideX = NonNegative(tfLiteNodeParameters->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(tfLiteNodeParameters->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_DilationX = NonNegative(tfLiteNodeParameters->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(tfLiteNodeParameters->dilation_height_factor, nodeIndex); // Assuming input is NHWC unsigned int inputHeight = inputTensorInfo.GetShape()[1]; unsigned int inputWidth = inputTensorInfo.GetShape()[2]; // TensorflowLite weights come in the format [1, H, W, I * M] unsigned int filterHeight = filterTensorInfo.GetShape()[1]; unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, tfLiteNodeParameters->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, tfLiteNodeParameters->padding); armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("DEPTHWISE_CONV2D", tfLiteContext, IsDepthwiseConvolutionSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, armnn::Optional(biasTensorInfo)); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::DepthwiseConvolution2d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthwiseConvolution2dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); if(filterTensorInfo.IsConstant()) { // For depthwise the weights layout is the same as for tflite [1, H, W, I*M]. No permutation required. auto filter = CreateConstTensor(tfLiteFilterTensor, filterTensorInfo); auto filterName = GetName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if (biasEnabled) { if(biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(tfLiteBiasTensor, biasTensorInfo); auto biasName = GetName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); auto inputName = GetName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if(Connect(layer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } TfLiteStatus VisitConv3dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); armnn::Convolution3dDescriptor descriptor; auto* params = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); descriptor.m_BiasEnabled = biasEnabled; descriptor.m_DataLayout = armnn::DataLayout::NDHWC; descriptor.m_StrideX = NonNegative(params->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(params->stride_height, nodeIndex); descriptor.m_StrideZ = NonNegative(params->stride_depth, nodeIndex); descriptor.m_DilationX = NonNegative(params->dilation_width_factor, nodeIndex); descriptor.m_DilationY = NonNegative(params->dilation_height_factor, nodeIndex); descriptor.m_DilationZ = NonNegative(params->dilation_depth_factor, nodeIndex); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get filter tensor. const TfLiteOpaqueTensor* tfLiteFilterTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType=kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteFilterTensor); armnn::TensorInfo biasTensorInfo; const TfLiteOpaqueTensor* tfLiteBiasTensor = nullptr; if (biasEnabled) { // Use input indices to get bias tensor. tfLiteBiasTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::Optional optionalBiasInfo(biasTensorInfo); // TfLite uses NDHWC tensors const unsigned int inputDepth = inputTensorInfo.GetShape()[1]; const unsigned int inputHeight = inputTensorInfo.GetShape()[2]; const unsigned int inputWidth = inputTensorInfo.GetShape()[3]; // Assuming the filter is DHWIO : Depth, Height, Width, OutputChannels, InputChannels const unsigned int filterDepth = filterTensorInfo.GetShape()[0]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // Calculate padding CalcPadding(inputDepth, filterDepth, descriptor.m_StrideZ, descriptor.m_DilationZ, descriptor.m_PadFront, descriptor.m_PadBack, params->padding); CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, descriptor.m_DilationY, descriptor.m_PadTop, descriptor.m_PadBottom, params->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, descriptor.m_DilationX, descriptor.m_PadLeft, descriptor.m_PadRight, params->padding); // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitConvolutionOperator will be called again to add the layer to the network as seen below. armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("CONV3D", tfLiteContext, IsConvolution3dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, optionalBiasInfo); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Convolution3d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddConvolution3dLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant, // which are connected to the Convolution3d layer as inputs. if (filterTensorInfo.IsConstant()) { auto filter = CreateConstTensor(tfLiteFilterTensor, filterTensorInfo); auto filterName = GetName(armnn::LayerType::Constant, nodeIndex, "Filter"); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(filter, filterName.c_str()); ARMNN_ASSERT(weightsLayer != nullptr); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(filterTensorInfo); } if (biasEnabled) { if (biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(tfLiteBiasTensor, biasTensorInfo); auto biasName = GetName(armnn::LayerType::Constant, nodeIndex, "Bias"); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor, biasName.c_str()); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if (inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); auto inputName = GetName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); if (Connect(layer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } TfLiteStatus VisitTransposeConv2dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); armnn::TransposeConvolution2dDescriptor descriptor; auto* parameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_BiasEnabled = false; descriptor.m_StrideX = NonNegative(parameters->stride_width, nodeIndex); descriptor.m_StrideY = NonNegative(parameters->stride_height, nodeIndex); descriptor.m_DataLayout = armnn::DataLayout::NHWC; auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputShapeTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputShapeTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteFilterTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteFilterTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); const armnn::TensorInfo& filterTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteFilterTensor); // TfLite uses NHWC tensors const unsigned int inputHeight = inputTensorInfo.GetShape()[1]; const unsigned int inputWidth = inputTensorInfo.GetShape()[2]; const unsigned int filterHeight = filterTensorInfo.GetShape()[1]; const unsigned int filterWidth = filterTensorInfo.GetShape()[2]; // This block determines the output shape of the transpose convolution. // If the output shape tensor is a constant, we can access the data at load time and set the shape of the layer. // If this is not constant, we do not have access to the shape data, so we have to use infer output shape. if (IsConstantTensor(tfLiteOutputShapeTensor)) { const armnn::TensorInfo outputShapeTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputShapeTensor); std::vector outputShape(outputShapeTensorInfo.GetNumElements()); if (outputShapeTensorInfo.GetDataType() == armnn::DataType::Signed32) { for(unsigned int i=0; i < outputShapeTensorInfo.GetNumElements(); ++i) { outputShape[i] = static_cast(TfLiteOpaqueTensorData(tfLiteOutputShapeTensor))[i]; } } if (outputShapeTensorInfo.GetDataType() == armnn::DataType::QAsymmU8) { for(unsigned int i=0; i < outputShapeTensorInfo.GetNumElements(); ++i) { outputShape[i] = static_cast(TfLiteOpaqueTensorData(tfLiteOutputShapeTensor))[i]; } } // Change from signed to unsigned int to store in TransposeConvolution2dDescriptor. for (int dimension : outputShape) { descriptor.m_OutputShape.push_back(static_cast(dimension)); } descriptor.m_OutputShapeEnabled = true; // TfLite uses NHWC tensors const unsigned int outputHeight = descriptor.m_OutputShape[1]; const unsigned int outputWidth = descriptor.m_OutputShape[2]; CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, 1, // DilationY descriptor.m_PadTop, descriptor.m_PadBottom, parameters->padding, outputHeight); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, 1, // DilationX descriptor.m_PadLeft, descriptor.m_PadRight, parameters->padding, outputWidth); } else { CalcPadding(inputHeight, filterHeight, descriptor.m_StrideY, 1, // DilationY descriptor.m_PadTop, descriptor.m_PadBottom, parameters->padding); CalcPadding(inputWidth, filterWidth, descriptor.m_StrideX, 1, // DilationX descriptor.m_PadLeft, descriptor.m_PadRight, parameters->padding); } // Set up filter auto filterTensor = CreateConstTensor(tfLiteFilterTensor, filterTensorInfo); armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("TRANSPOSE_CONV2D", tfLiteContext, IsTransposeConvolution2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor, filterTensorInfo, armnn::EmptyOptional()); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::TransposeConvolution2d, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddTransposeConvolution2dLayer(descriptor, filterTensor, armnn::EmptyOptional(), layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // The data input can be constant, so we must check that this is allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); auto inputName = GetName(armnn::LayerType::Constant, nodeIndex, "Input"); armnn::IConnectableLayer *inputLayer = delegateData.m_Network->AddConstantLayer(input, inputName.c_str()); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect if (delegateData.m_OutputSlotForNode[static_cast(inputTensors[2])] != nullptr) { delegateData.m_OutputSlotForNode[static_cast(inputTensors[2])]-> Connect(layer->GetInputSlot(0)); } if (Connect(layer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } return kTfLiteOk; } TfLiteStatus VisitConvolutionOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { switch(operatorCode) { case kTfLiteBuiltinConv2d: return VisitConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinConv3d: return VisitConv3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinDepthwiseConv2d: return VisitDepthwiseConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); case kTfLiteBuiltinTransposeConv: return VisitTransposeConv2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, operatorCode); default: return kTfLiteError; } } }armnn-23.08/delegate/opaque/src/ElementwiseBinary.hpp000066400000000000000000000567371446772241200226660ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateAddOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { std::vector infos { inputInfo1, inputInfo2, outputInfo }; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("ADD", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputInfo, armnn::BinaryOperation::Add); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateDivOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("DIV", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Div); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateFloorDivOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { // need first to validate that the div operator is supported // then that the floor operator is supported TfLiteStatus status = ValidateDivOperator(delegateData, tfLiteContext, inputInfo1, inputInfo2, outputInfo); if (status != kTfLiteOk) { return status; } // if the inputs and output of the div are all Signed32 we don't need to add the floor operator afterward. if (AreAllSigned32(inputInfo1, inputInfo2, outputInfo)) { return status; } // in case broadcasting is being done from one of the inputs to the div // choose the full sized input tensor to pass to the floor validation routine armnn::TensorInfo floorInputInfo = inputInfo1; if (inputInfo1.GetNumDimensions() < inputInfo2.GetNumDimensions()) { floorInputInfo = inputInfo2; } status = ValidateFloorOperator(delegateData, tfLiteContext, floorInputInfo, outputInfo); return status; } TfLiteStatus ValidateMaximumOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("MAXIMUM", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Maximum); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateMinimumOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("MINIMUM", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Minimum); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateMulOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("MUL", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Mul); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidatePowerOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("POWER", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Power); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateSquaredDifferenceOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SQUAREDDIFFERENCE", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::SqDiff); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateSubOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& inputInfo2, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SUB", tfLiteContext, IsElementwiseBinarySupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo1, inputInfo2, outputTensorInfo, armnn::BinaryOperation::Sub); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } std::pair AddFloorDivLayer( DelegateData& delegateData, const armnn::TensorInfo& outputTensorInfo, int nodeIndex) { auto layerName = GetName(armnn::BinaryOperation::Div, nodeIndex); armnn::IConnectableLayer* divisionLayer = delegateData.m_Network->AddElementwiseBinaryLayer( armnn::BinaryOperation::Div, layerName.c_str()); // if the output of the div is Signed32 the Floor layer is not required if (armnn::DataType::Signed32 == outputTensorInfo.GetDataType()) { return std::make_pair(divisionLayer, divisionLayer); } armnn::IOutputSlot& outputSlot = divisionLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto floorName = GetName(armnn::LayerType::Floor, nodeIndex); armnn::IConnectableLayer* floorLayer = delegateData.m_Network->AddFloorLayer(floorName.c_str()); outputSlot.Connect(floorLayer->GetInputSlot(0)); return std::make_pair(divisionLayer, floorLayer); } TfLiteStatus VisitElementwiseBinaryOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t elementwiseBinaryOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get Input Tensors auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor0 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor0, elementwiseBinaryOperatorCode, nodeIndex)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Invalid input tensor in operator #%d node #%d: ", elementwiseBinaryOperatorCode, nodeIndex); return kTfLiteError; } // Use input indices to get filter tensor. const TfLiteOpaqueTensor* tfLiteInputTensor1 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if(!IsValid(tfLiteInputTensor1)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Invalid input tensor in operator #%d node #%d: ", elementwiseBinaryOperatorCode, nodeIndex); return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, elementwiseBinaryOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of the input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } if (!delegateData.m_Network) { switch(elementwiseBinaryOperatorCode) { case kTfLiteBuiltinAdd: return ValidateAddOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinDiv: return ValidateDivOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinFloorDiv: return ValidateFloorDivOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMaximum: return ValidateMaximumOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMinimum: return ValidateMinimumOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinMul: return ValidateMulOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinPow: return ValidatePowerOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinSquaredDifference: return ValidateSquaredDifferenceOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); case kTfLiteBuiltinSub: return ValidateSubOperator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); default: return kTfLiteError; } } armnn::IConnectableLayer* elementwiseBinaryLayer = nullptr; armnnDelegate::MultiLayerFacade multiLayer; std::string layerName; switch(elementwiseBinaryOperatorCode) { case kTfLiteBuiltinAdd: layerName = GetName(armnn::BinaryOperation::Add, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Add, layerName.c_str()); break; case kTfLiteBuiltinDiv: layerName = GetName(armnn::BinaryOperation::Div, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Div, layerName.c_str()); break; case kTfLiteBuiltinFloorDiv: { auto layers = AddFloorDivLayer(delegateData, outputTensorInfo, nodeIndex); multiLayer.AssignValues(layers.first, layers.second); elementwiseBinaryLayer = &multiLayer; } break; case kTfLiteBuiltinMaximum: layerName = GetName(armnn::BinaryOperation::Maximum, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Maximum, layerName.c_str()); break; case kTfLiteBuiltinMinimum: layerName = GetName(armnn::BinaryOperation::Minimum, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Minimum, layerName.c_str()); break; case kTfLiteBuiltinMul: layerName = GetName(armnn::BinaryOperation::Mul, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Mul, layerName.c_str()); break; case kTfLiteBuiltinPow: layerName = GetName(armnn::BinaryOperation::Power, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Power, layerName.c_str()); break; case kTfLiteBuiltinSquaredDifference: layerName = GetName(armnn::BinaryOperation::SqDiff, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::SqDiff, layerName.c_str()); break; case kTfLiteBuiltinSub: layerName = GetName(armnn::BinaryOperation::Sub, nodeIndex); elementwiseBinaryLayer = delegateData.m_Network->AddElementwiseBinaryLayer(armnn::BinaryOperation::Sub, layerName.c_str()); break; default: return kTfLiteError; } ARMNN_ASSERT(elementwiseBinaryLayer != nullptr); armnn::IOutputSlot& outputSlot = elementwiseBinaryLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(elementwiseBinaryLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } if(Connect(elementwiseBinaryLayer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create Activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, elementwiseBinaryLayer, 0, delegateData, nodeIndex); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/ElementwiseUnary.hpp000066400000000000000000000122361446772241200225220ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "OpaqueDelegateUtils.hpp" namespace armnnOpaqueDelegate { std::string GetLayerName(armnn::UnaryOperation unaryOperation) { std::string layerName = "ELEMENTWISE_UNARY"; switch (unaryOperation) { case armnn::UnaryOperation::Abs: layerName += " ABS"; break; case armnn::UnaryOperation::Ceil: layerName += " CEIL"; break; case armnn::UnaryOperation::Exp: layerName += " EXP"; break; case armnn::UnaryOperation::Log: layerName += " LOG"; break; case armnn::UnaryOperation::LogicalNot: layerName += " LOGICALNOT"; break; case armnn::UnaryOperation::Neg: layerName += " NEG"; break; case armnn::UnaryOperation::Rsqrt: layerName += " RSQRT"; break; case armnn::UnaryOperation::Sin: layerName += " SIN"; break; case armnn::UnaryOperation::Sqrt: layerName += " SQRT"; break; default: layerName += " UNKNOWN"; } return layerName; } TfLiteStatus VisitElementwiseUnaryOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteElementWiseUnaryOperatorCode, armnn::UnaryOperation unaryOperation) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensor. const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteElementWiseUnaryOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensor. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use output indices to get output tensor. const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteElementWiseUnaryOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::ElementwiseUnaryDescriptor descriptor(unaryOperation); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported, std::string layerName) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC(layerName.c_str(), tfLiteContext, IsElementwiseUnarySupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported, GetLayerName(unaryOperation)); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(descriptor.m_Operation, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddElementwiseUnaryLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Fill.hpp000066400000000000000000000126421446772241200201110ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitFillOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteFillOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); switch(tfLiteFillOperatorCode) { case kTfLiteBuiltinFill: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); break; default: return kTfLiteError; } // Inputs int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteFillTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteFillTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteFillOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::FillDescriptor descriptor; switch (TfLiteOpaqueTensorType(tfLiteFillTensor)) { case kTfLiteFloat32: descriptor.m_Value = *static_cast(TfLiteOpaqueTensorData(tfLiteFillTensor)); break; case kTfLiteInt32: descriptor.m_Value = *static_cast(TfLiteOpaqueTensorData(tfLiteFillTensor)); break; default: TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: FILL value data type is not supported in operator #%d node #%d: ", tfLiteFillOperatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("FILL", tfLiteContext, IsFillSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Fill, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFillLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnDelegate armnn-23.08/delegate/opaque/src/FullyConnected.hpp000066400000000000000000000271711446772241200221440ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitFullyConnectedOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteWeightsTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteWeightsTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& weightsTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteWeightsTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Check that we support fused activation before we attempt to create a layer auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType=kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } // Fully Connected Layer accepts two dimensional weights input int32_t weightsDimension = static_cast(weightsTensorInfo.GetNumDimensions()); if (weightsDimension != 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dimension #$d for Fully Connected weights is not supported by Armnn" " in operator #%d node #%d: ", weightsDimension, operatorCode, nodeIndex); return kTfLiteError; } armnn::TensorInfo biasTensorInfo; const TfLiteOpaqueTensor* tfLiteBiasTensor = nullptr; bool biasEnabled = IsOptionalOperandPresent(tfLiteNode, 2); if (biasEnabled) { // Use input indices to get bias tensor. tfLiteBiasTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteBiasTensor, operatorCode, nodeIndex)) { return kTfLiteError; } biasTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteBiasTensor); } else { biasTensorInfo = armnn::TensorInfo(armnn::TensorShape({1}), GetDataType(tfLiteInputTensor)); } armnn::TensorInfo reshapedTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); if (inputTensorInfo.GetNumDimensions() > 2) { // Calculate reshape to flatten to 2D [batch_size, input_size] std::vector reshapedDimensions(2); reshapedDimensions[1] = weightsTensorInfo.GetShape()[1]; reshapedDimensions[0] = inputTensorInfo.GetNumElements() / reshapedDimensions[1]; if (inputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Failed to deduce input tensor shape from filter size #%d #%d node #%d: ", reshapedDimensions[1], operatorCode, nodeIndex); return kTfLiteError; } reshapedTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() }); } armnn::TensorInfo reshapedOutputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor); if (outputTensorInfo.GetNumDimensions() > 2) { // Calculate reshape to flatten to 2D [batch_size, input_size] std::vector reshapedDimensions(2); reshapedDimensions[1] = weightsTensorInfo.GetShape()[0]; reshapedDimensions[0] = outputTensorInfo.GetNumElements() / reshapedDimensions[1]; if (outputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Failed to deduce output tensor shape from filter size #%d #%d node #%d: ", reshapedDimensions[1], operatorCode, nodeIndex); return kTfLiteError; } reshapedOutputTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() }); } armnn::FullyConnectedDescriptor descriptor; descriptor.m_TransposeWeightMatrix = true; descriptor.m_BiasEnabled = biasEnabled; descriptor.m_ConstantWeights = weightsTensorInfo.IsConstant(); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("FULLY_CONNECTED", tfLiteContext, IsFullyConnectedSupported, delegateData.m_Backends, isSupported, setBackend, reshapedTensorInfo, outputTensorInfo, weightsTensorInfo, biasTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(reshapedOutputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::FullyConnected, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFullyConnectedLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Add a constant layer for weights and biases if inputs are constant. if (weightsTensorInfo.IsConstant()) { auto weightsTensor = CreateConstTensor(tfLiteWeightsTensor, weightsTensorInfo); armnn::IConnectableLayer* weightsLayer = delegateData.m_Network->AddConstantLayer(weightsTensor); weightsLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1u)); weightsLayer->GetOutputSlot(0).SetTensorInfo(weightsTensorInfo); } if (biasEnabled) { if(biasTensorInfo.IsConstant()) { auto biasTensor = CreateConstTensor(tfLiteBiasTensor, biasTensorInfo); armnn::IConnectableLayer* biasLayer = delegateData.m_Network->AddConstantLayer(biasTensor); ARMNN_ASSERT(biasLayer != nullptr); biasLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(2u)); biasLayer->GetOutputSlot(0).SetTensorInfo(biasTensorInfo); } } // The data input can also be constant, so we must check that this is also allocated to an input slot if(inputTensorInfo.IsConstant()) { auto input = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); armnn::IConnectableLayer* inputLayer = delegateData.m_Network->AddConstantLayer(input); inputLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0u)); inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo); } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); armnn::IConnectableLayer* reshapeLayer = nullptr; if (inputTensorInfo.GetNumDimensions() > 2) { // Add reshape to flatten to 2D [batch_size, input_size] armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = reshapedTensorInfo.GetShape(); reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor); ARMNN_ASSERT(reshapeLayer != nullptr); reshapeLayer->GetOutputSlot(0).SetTensorInfo(reshapedTensorInfo); // Connect delegateData.m_OutputSlotForNode[inputTensors[0]]->Connect(reshapeLayer->GetInputSlot(0)); reshapeLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0)); if (!descriptor.m_ConstantWeights) { delegateData.m_OutputSlotForNode[inputTensors[1]]->Connect(layer->GetInputSlot(1)); } if (biasEnabled && !biasTensorInfo.IsConstant()) { delegateData.m_OutputSlotForNode[inputTensors[2]]->Connect(layer->GetInputSlot(2)); } delegateData.m_OutputSlotForNode[outputTensors[0]] = &outputSlot; } if (reshapeLayer == nullptr) { if(Connect(layer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } } if (outputTensorInfo.GetNumDimensions() > 2) { layer = AddReshapeLayer(tfLiteContext, tfLiteNode, layer, reshapedOutputTensorInfo, outputTensorInfo, delegateData, nodeIndex); if (!layer) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Failed to add reshape for FullyConnected #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } } if (!tfLiteNodeParameters) { // No Activation return kTfLiteOk; } // Check and Create Activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, layer, 0, delegateData, nodeIndex); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Gather.hpp000066400000000000000000000127131446772241200204340ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitGatherOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteIndicesTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteIndicesTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); auto axis = tfLiteNodeParameters->axis; const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& indicesTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteIndicesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::GatherDescriptor gatherDescriptor; gatherDescriptor.m_Axis = axis; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); auto indicesDimensions = indicesTensorInfo.GetNumDimensions(); auto outputDimensions = outputTensorInfo.GetNumDimensions(); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Operation has invalid axis: %d. It is out of bounds [-%d, %d))", axis, inputDimensions, inputDimensions); return kTfLiteError; } if (outputDimensions != static_cast(inputDimensions) + indicesDimensions - 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Operation has invalid output dimensions: %d. " "Output must be an (%d + %d - 1)-D tensor", outputDimensions, inputDimensions, indicesDimensions); return kTfLiteError; } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("GATHER", tfLiteContext, IsGatherSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo, gatherDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Gather, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherLayer(gatherDescriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/GatherNd.hpp000066400000000000000000000102351446772241200207130ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitGatherNdOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteIndicesTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteIndicesTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& indicesTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteIndicesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("GATHER_ND", tfLiteContext, IsGatherNdSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, indicesTensorInfo, outputTensorInfo); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::GatherNd, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddGatherNdLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/LogicalBinary.hpp000066400000000000000000000131311446772241200217340ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { std::string GetLayerName(armnn::LogicalBinaryOperation logicalBinaryOperation) { std::string layerName = "LOGICAL_BINARY"; switch (logicalBinaryOperation) { case armnn::LogicalBinaryOperation::LogicalAnd: layerName += " LOGICAL_AND"; break; case armnn::LogicalBinaryOperation::LogicalOr: layerName += " LOGICAL_OR"; break; default: layerName += " UNKNOWN"; } return layerName; } TfLiteStatus VisitLogicalBinaryOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t logicalOperatorCode, armnn::LogicalBinaryOperation binaryOperation) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensors. const TfLiteOpaqueTensor* tfLiteInputTensor0 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor0, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor1 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteInputTensor1, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use output indices to get output tensor. const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, logicalOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor0); armnn::TensorInfo inputTensorInfo1 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor1); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Check if we need to expand the dims of any input tensor infos. // This is required for a few of the backends. if(inputTensorInfo0.GetNumDimensions() != inputTensorInfo1.GetNumDimensions()) { ExpandTensorRankToEqual(inputTensorInfo0, inputTensorInfo1); } // Setup descriptor and assign operation armnn::LogicalBinaryDescriptor desc; desc.m_Operation = binaryOperation; // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported, std::string layerName) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC(layerName.c_str(), tfLiteContext, IsLogicalBinarySupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, inputTensorInfo1, outputTensorInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported, GetLayerName(binaryOperation)); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(desc.m_Operation, nodeIndex); armnn::IConnectableLayer* logicalBinaryLayer = delegateData.m_Network->AddLogicalBinaryLayer(desc, layerName.c_str()); logicalBinaryLayer->SetBackendId(setBackend); ARMNN_ASSERT(logicalBinaryLayer != nullptr); armnn::IOutputSlot& outputSlot = logicalBinaryLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(logicalBinaryLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(logicalBinaryLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Lstm.hpp000066400000000000000000000311251446772241200201370ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitLstmOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Set the params structure for the AddLstmLayer call armnn::LstmInputParams params; if (IsOptionalOperandPresent(tfLiteNode, 1)) { params.m_InputToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 1); } params.m_InputToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 2); params.m_InputToCellWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 3); params.m_InputToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 4); // Recurrent weight tensors of size {n_cell, n_output} if (IsOptionalOperandPresent(tfLiteNode, 5)) { params.m_RecurrentToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 5); } params.m_RecurrentToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 6); params.m_RecurrentToCellWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 7); params.m_RecurrentToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 8); // Peephole weights tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 9)) { params.m_CellToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 9); } if (IsOptionalOperandPresent(tfLiteNode, 10)) { params.m_CellToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 10); } if (IsOptionalOperandPresent(tfLiteNode, 11)) { params.m_CellToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 11); } // Gates bias tensors of size {n_cell} if (IsOptionalOperandPresent(tfLiteNode, 12)) { params.m_InputGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 12); } params.m_ForgetGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 13); params.m_CellBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 14); params.m_OutputGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 15); // Projection weight tensor of size {n_output, n_cell} if (IsOptionalOperandPresent(tfLiteNode, 16)) { params.m_ProjectionWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 16); } // Projection bias tensor of size {n_output} if (IsOptionalOperandPresent(tfLiteNode, 17)) { params.m_ProjectionBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 17); } // These state tensors are defined as variable tensors, and will be modified by this op. const TfLiteOpaqueTensor* tfLiteOutputStateIn = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[18]); if (!IsValid(tfLiteContext, tfLiteOutputStateIn, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* cellStateIn = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[19]); if (!IsValid(tfLiteContext, cellStateIn, operatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo outputStateInInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputStateIn); armnn::TensorInfo cellStateInInfo = GetTensorInfoForTfLiteOpaqueTensor(cellStateIn); // Layer norm coefficient tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 20)) { params.m_InputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 20); } if (IsOptionalOperandPresent(tfLiteNode, 21)) { params.m_ForgetLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 21); } if (IsOptionalOperandPresent(tfLiteNode, 22)) { params.m_CellLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 22); } if (IsOptionalOperandPresent(tfLiteNode, 23)) { params.m_OutputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 23); } const auto nodeParams = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); // set the layer descriptor armnn::LstmDescriptor desc; desc.m_ActivationFunc = NonNegative(nodeParams->activation, nodeIndex); desc.m_ClippingThresCell = nodeParams->cell_clip; desc.m_ClippingThresProj = nodeParams->proj_clip; desc.m_CifgEnabled = (params.m_InputToInputWeights == nullptr || params.m_RecurrentToInputWeights == nullptr || params.m_InputGateBias == nullptr); desc.m_PeepholeEnabled = (params.m_CellToForgetWeights != nullptr || params.m_CellToOutputWeights != nullptr); desc.m_ProjectionEnabled = (params.m_ProjectionWeights != nullptr); desc.m_LayerNormEnabled = (params.m_InputLayerNormWeights != nullptr || params.m_ForgetLayerNormWeights != nullptr || params.m_CellLayerNormWeights != nullptr || params.m_OutputLayerNormWeights != nullptr); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); unsigned int batchSize = inputTensorInfo.GetShape()[0]; unsigned int outputSize = outputTensorInfo.GetShape()[1]; unsigned int numUnits = cellStateInInfo.GetShape()[1]; armnn::DataType dataType = inputTensorInfo.GetDataType(); float qScale = inputTensorInfo.GetQuantizationScale(); float qOffset = inputTensorInfo.GetQuantizationOffset(); armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 3}, dataType, qScale, qOffset); if (!desc.m_CifgEnabled) { scratchBufferTensorInfo = armnn::TensorInfo({batchSize, numUnits * 4}, dataType, qScale, qOffset); } armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, dataType, qScale, qOffset); armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, dataType, qScale, qOffset); armnn::LstmInputParamsInfo paramsInfo; paramsInfo.m_InputToForgetWeights = &(params.m_InputToForgetWeights->GetInfo()); paramsInfo.m_InputToCellWeights = &(params.m_InputToCellWeights->GetInfo()); paramsInfo.m_InputToOutputWeights = &(params.m_InputToOutputWeights->GetInfo()); paramsInfo.m_RecurrentToForgetWeights = &(params.m_RecurrentToForgetWeights->GetInfo()); paramsInfo.m_RecurrentToCellWeights = &(params.m_RecurrentToCellWeights->GetInfo()); paramsInfo.m_RecurrentToOutputWeights = &(params.m_RecurrentToOutputWeights->GetInfo()); paramsInfo.m_ForgetGateBias = &(params.m_ForgetGateBias->GetInfo()); paramsInfo.m_CellBias = &(params.m_CellBias->GetInfo()); paramsInfo.m_OutputGateBias = &(params.m_OutputGateBias->GetInfo()); if (!desc.m_CifgEnabled) { paramsInfo.m_InputToInputWeights = &(params.m_InputToInputWeights->GetInfo()); paramsInfo.m_RecurrentToInputWeights = &(params.m_RecurrentToInputWeights->GetInfo()); if (params.m_CellToInputWeights != nullptr) { paramsInfo.m_CellToInputWeights = &(params.m_CellToInputWeights->GetInfo()); } paramsInfo.m_InputGateBias = &(params.m_InputGateBias->GetInfo()); } if (desc.m_ProjectionEnabled) { paramsInfo.m_ProjectionWeights = &(params.m_ProjectionWeights->GetInfo()); if (params.m_ProjectionBias != nullptr) { paramsInfo.m_ProjectionBias = &(params.m_ProjectionBias->GetInfo()); } } if (desc.m_PeepholeEnabled) { paramsInfo.m_CellToForgetWeights = &(params.m_CellToForgetWeights->GetInfo()); paramsInfo.m_CellToOutputWeights = &(params.m_CellToOutputWeights->GetInfo()); } if (desc.m_LayerNormEnabled) { if(!desc.m_CifgEnabled) { paramsInfo.m_InputLayerNormWeights = &(params.m_InputLayerNormWeights->GetInfo()); } paramsInfo.m_ForgetLayerNormWeights = &(params.m_ForgetLayerNormWeights->GetInfo()); paramsInfo.m_CellLayerNormWeights = &(params.m_CellLayerNormWeights->GetInfo()); paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo()); } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("LSTM", tfLiteContext, IsLstmSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, scratchBufferTensorInfo, outputStateOutTensorInfo, cellStateOutTensorInfo, outputInfo, desc, paramsInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Lstm, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddLstmLayer(desc, params, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(scratchBufferTensorInfo); layer->GetOutputSlot(1).SetTensorInfo(outputStateOutTensorInfo); layer->GetOutputSlot(2).SetTensorInfo(cellStateOutTensorInfo); layer->GetOutputSlot(3).SetTensorInfo(outputTensorInfo); // Connect the inputs // input_layer delegateData.m_OutputSlotForNode[inputTensors[0]]->Connect(layer->GetInputSlot(0)); // cellStateIn delegateData.m_OutputSlotForNode[inputTensors[18]]->Connect(layer->GetInputSlot(1)); //outputStateIn delegateData.m_OutputSlotForNode[inputTensors[19]]->Connect(layer->GetInputSlot(2)); // In the test_model there is only 1 Output armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(1); delegateData.m_OutputSlotForNode[static_cast(outputTensors[0])] = &outputSlot; return kTfLiteOk; } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Normalization.hpp000066400000000000000000000207071446772241200220520ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitL2NormalizationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteL2NormalizationOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensor. const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteL2NormalizationOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensor. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use output indices to get output tensor. const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteL2NormalizationOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::L2NormalizationDescriptor descriptor; descriptor.m_DataLayout = armnn::DataLayout::NHWC; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("L2_NORMALIZATION", tfLiteContext, IsL2NormalizationSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a L2Normalization layer auto layerName = GetName(armnn::LayerType::L2Normalization, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddL2NormalizationLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitLocalResponseNormalizationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteNormalizationOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensor. const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteNormalizationOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensor. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use output indices to get output tensor. const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteNormalizationOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::NormalizationDescriptor descriptor; descriptor.m_DataLayout = armnn::DataLayout::NHWC; descriptor.m_NormChannelType = armnn::NormalizationAlgorithmChannel::Across; descriptor.m_NormMethodType = armnn::NormalizationAlgorithmMethod::LocalBrightness; auto* nodeParams = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_NormSize = nodeParams->radius; descriptor.m_K = nodeParams->bias; descriptor.m_Alpha = nodeParams->alpha; descriptor.m_Beta = nodeParams->beta; // ArmNN expects normSize to be the full size of the normalization window descriptor.m_NormSize = 1 + (2 * descriptor.m_NormSize); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("NORMALIZATION", tfLiteContext, IsNormalizationSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Normalization layer auto layerName = GetName(armnn::LayerType::Normalization, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddNormalizationLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/OpaqueDelegateUtils.hpp000066400000000000000000000614351446772241200231350ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { std::string GetName(armnn::ActivationFunction function, int nodeIndex) { return fmt::format("{}:{}", GetActivationFunctionAsCString(function), nodeIndex); } std::string GetName(armnn::ArgMinMaxFunction function, int nodeIndex) { return fmt::format("{}:{}", GetArgMinMaxFunctionAsCString(function), nodeIndex); } std::string GetName(armnn::BinaryOperation opType, int nodeIndex) { return fmt::format("{}:{}", GetBinaryOperationAsCString(opType), nodeIndex); } std::string GetName(armnn::ComparisonOperation layerType, int nodeIndex) { return fmt::format("{}:{}", GetComparisonOperationAsCString(layerType), nodeIndex); } std::string GetName(armnn::LogicalBinaryOperation operation, int nodeIndex) { return fmt::format("{}:{}", GetLogicalBinaryOperationAsCString(operation), nodeIndex); } std::string GetName(armnn::UnaryOperation opType, int nodeIndex) { return fmt::format("{}:{}", GetUnaryOperationAsCString(opType), nodeIndex); } std::string GetName(armnn::LayerType layerType, int nodeIndex, std::string subname = "") { return fmt::format("{}{}:{}", GetLayerTypeAsCString(layerType), subname, nodeIndex); } // Macro to call an IsSupported function and log caller name together with reason for lack of support #define FORWARD_LAYER_OPAQUE_SUPPORT_FUNC(opName, tfLiteContext, func, backends, supported, setBackend, ...) \ try \ { \ for (auto&& backendId : backends) \ { \ auto layerSupportObject = armnn::GetILayerSupportByBackendId(backendId); \ if (layerSupportObject.IsBackendRegistered()) \ { \ std::string reasonIfUnsupported; \ supported = \ layerSupportObject.func(__VA_ARGS__, armnn::Optional(reasonIfUnsupported)); \ if (supported) \ { \ setBackend = backendId; \ break; \ } \ else \ { \ if (reasonIfUnsupported.size() > 0) \ { \ TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \ "%s: not supported by armnn: %s", opName, reasonIfUnsupported.c_str()); \ } \ else \ { \ TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \ "%s: not supported by armnn", opName); \ } \ } \ } \ else \ { \ TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "%s: backend not registered: %s", \ opName, backendId.Get().c_str()); \ } \ } \ if (!supported) \ { \ TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "%s: not supported by any specified backend", opName); \ } \ } \ catch (const armnn::InvalidArgumentException &e) \ { \ throw armnn::InvalidArgumentException(e, "Failed to check layer support", CHECK_LOCATION()); \ } TfLiteStatus ValidateNumInputs(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, const unsigned int expectedSize, int nodeIndex) { int numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (static_cast(numInputs) != expectedSize) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unexpected number of inputs (%d != %d) in node #%d", numInputs, expectedSize, nodeIndex); return kTfLiteError; } return kTfLiteOk; } TfLiteStatus ValidateNumOutputs(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, const unsigned int expectedSize, int nodeIndex) { auto numOutputs = TfLiteOpaqueNodeNumberOfOutputs(tfLiteNode); if (static_cast(numOutputs) != expectedSize) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unexpected number of outputs (%d != %d) in node #%d", numOutputs, expectedSize, nodeIndex); return kTfLiteError; } return kTfLiteOk; } bool IsConstantTensor(const TfLiteOpaqueTensor* tfLiteTensor) { auto tensorAllocationType = TfLiteOpaqueTensorGetAllocationType(tfLiteTensor); if (tensorAllocationType == kTfLiteMmapRo) { return true; } return false; } bool IsDynamicTensor(const TfLiteOpaqueTensor* tfLiteTensor) { auto tensorAllocationType = TfLiteOpaqueTensorGetAllocationType(tfLiteTensor); if (tensorAllocationType == kTfLiteDynamic) { return true; } return false; } bool IsValid(const TfLiteOpaqueTensor* tfLiteTensor) { return tfLiteTensor == nullptr ? false : true; } bool IsValid(TfLiteOpaqueContext* tfLiteContext, const TfLiteOpaqueTensor* tfLiteTensor, int32_t operatorCode, int32_t nodeIndex) { if(!IsValid(tfLiteTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Invalid TfLite tensor in operator #%d node #%d: ", operatorCode, nodeIndex); return false; } if (IsDynamicTensor(tfLiteTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic tensors are not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return false; } return true; } bool IsAffineQuantization(const TfLiteOpaqueTensor& tfLiteTensor) { auto quantizationInfo = TfLiteOpaqueTensorGetQuantization(&tfLiteTensor); if (quantizationInfo.type == kTfLiteAffineQuantization) { return true; } return false; } // Connects the layer to the graph TfLiteStatus Connect(armnn::IConnectableLayer* layer, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, armnnOpaqueDelegate::DelegateData& data) { // Get array of input indices, inputIndexArray is set from the TfLiteOpaqueNodeInputs function // This function turns inputIndexArray into an int array of indices. These indices point to the index of the // tensors for each input slot in the node. const int* inputIndexArray; int numInputs; if(TfLiteOpaqueNodeInputs(tfLiteNode, &inputIndexArray, &numInputs) != kTfLiteOk) { return kTfLiteError; } // We can't validate the number of inputs vs the layer->GetNumOutputSlots() as some operators differ. // An example is Mean where the number of TFLite inputs is 2, but number of Arm NN inputs is 1, // as we store the axis within the descriptor. // Connect the input slots. // For each input slot, get the index of the opaque tensor that was allocated for it. for (unsigned int inputIndex = 0; inputIndex < layer->GetNumInputSlots(); ++inputIndex) { if (data.m_OutputSlotForNode[inputIndexArray[inputIndex]] != nullptr) { data.m_OutputSlotForNode[inputIndexArray[inputIndex]]->Connect(layer->GetInputSlot(inputIndex)); } } // Get array of output indices, outputIndexArray is set from the TfLiteOpaqueNodeOutputs function // This function turns outputIndexArray into an int array of indices. These indices point to the tensors for // each output slot in the node. const int* outputIndexArray; int numOutputs; if(TfLiteOpaqueNodeOutputs(tfLiteNode, &outputIndexArray, &numOutputs) != kTfLiteOk) { return kTfLiteError; } // numOutputs is set from TfLiteOpaqueNodeOutputs. if(numOutputs != static_cast(layer->GetNumOutputSlots())) { ARMNN_LOG(error) << "Layer: " << layer->GetName() << ": Expected number of output slots does not match actual " "number of output slots."; return kTfLiteError; } // Prepare output slots for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex) { armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast(outputIndexArray[outputIndex])] = &outputSlot; } return kTfLiteOk; } TfLiteStatus FusedActivation(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, TfLiteFusedActivation activationType, armnn::IConnectableLayer* prevLayer, unsigned int outputSlotIndex, armnnOpaqueDelegate::DelegateData& data, int nodeIndex) { const armnn::TensorInfo& activationOutputInfo = prevLayer->GetOutputSlot(outputSlotIndex).GetTensorInfo(); armnn::ActivationDescriptor activationDesc; switch (activationType) { case kTfLiteActNone: { // No Activation return kTfLiteOk; } case kTfLiteActRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } case kTfLiteActReluN1To1: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 1.0f; activationDesc.m_B = -1.0f; break; } case kTfLiteActRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; activationDesc.m_B = 0.0f; break; } case kTfLiteActSigmoid: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteActTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } default: return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, data.m_Backends, isSupported, setBackend, activationOutputInfo, activationOutputInfo, activationDesc); if (!isSupported) { return kTfLiteError; } auto layerName = GetName(activationDesc.m_Function, nodeIndex); armnn::IConnectableLayer* activationLayer = data.m_Network->AddActivationLayer(activationDesc, layerName.c_str()); activationLayer->SetBackendId(setBackend); ARMNN_ASSERT(activationLayer != nullptr); activationLayer->GetOutputSlot(0).SetTensorInfo(activationOutputInfo); // Get array of output indices, outputIndexArray is set from the TfLiteOpaqueNodeOutputs function // This function turns outputIndexArray into an int array of indices. These indices point to the tensors for // each output slot in the node. const int* outputIndexArray; int numOutputs; TfLiteStatus outputStatus = TfLiteOpaqueNodeOutputs(tfLiteNode, &outputIndexArray, &numOutputs); if(outputStatus != kTfLiteOk) { return kTfLiteError; } // Connect and prepare output slots for (unsigned int outputIndex = 0; outputIndex < activationLayer->GetNumOutputSlots(); ++outputIndex) { data.m_OutputSlotForNode[static_cast( outputIndexArray[outputIndex])]->Connect(activationLayer->GetInputSlot(0)); armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast(outputIndexArray[outputIndex])] = &outputSlot; } return kTfLiteOk; } armnn::IConnectableLayer* AddReshapeLayer(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, armnn::IConnectableLayer* prevLayer, armnn::TensorInfo reshapedOutputTensorInfo, armnn::TensorInfo outputTensorInfo, armnnOpaqueDelegate::DelegateData& data, int nodeIndex) { armnn::ReshapeDescriptor desc; desc.m_TargetShape = outputTensorInfo.GetShape(); bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, data.m_Backends, isSupported, setBackend, reshapedOutputTensorInfo, outputTensorInfo, desc); if (!isSupported) { return nullptr; } auto layerName = GetName(armnn::LayerType::Reshape, nodeIndex); armnn::IConnectableLayer* reshapeLayer = data.m_Network->AddReshapeLayer(desc, layerName.c_str()); reshapeLayer->SetBackendId(setBackend); ARMNN_ASSERT(reshapeLayer != nullptr); prevLayer->GetOutputSlot(0).SetTensorInfo(reshapedOutputTensorInfo); reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); // Gather array of indices and it's length, replaces node->outputs->data[i] const int* outputIndices = nullptr; int numOutputs = 0; TfLiteStatus status = TfLiteOpaqueNodeOutputs(tfLiteNode, &outputIndices, &numOutputs); if(status != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to gather output information from node."); } if (static_cast(numOutputs) != reshapeLayer->GetNumOutputSlots()) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unexpected number of outputs (" + std::to_string(numOutputs) + "!= " + std::to_string(reshapeLayer->GetNumOutputSlots()) + ") in node."); } // Connect and prepare output slots for (unsigned int outputIndex = 0; outputIndex < reshapeLayer->GetNumOutputSlots(); ++outputIndex) { data.m_OutputSlotForNode[static_cast( outputIndices[outputIndex])]->Connect(reshapeLayer->GetInputSlot(0)); armnn::IOutputSlot& outputSlot = reshapeLayer->GetOutputSlot(outputIndex); data.m_OutputSlotForNode[static_cast(outputIndices[outputIndex])] = &outputSlot; } return reshapeLayer; } armnn::DataType GetDataType(const TfLiteOpaqueTensor* tfLiteTensor) { switch (TfLiteOpaqueTensorType(tfLiteTensor)) { case kTfLiteBool: return armnn::DataType::Boolean; case kTfLiteFloat32: return armnn::DataType::Float32; case kTfLiteFloat16: return armnn::DataType::Float16; case kTfLiteUInt8: return armnn::DataType::QAsymmU8; case kTfLiteInt8: { auto quantizationInfo = TfLiteOpaqueTensorGetQuantization(tfLiteTensor); if (quantizationInfo.type == kTfLiteAffineQuantization) { auto* quantization = reinterpret_cast(quantizationInfo.params); if (quantization->zero_point != nullptr && quantization->zero_point->size == 1) { return armnn::DataType::QAsymmS8; } else { return armnn::DataType::QSymmS8; } } else { return armnn::DataType::QAsymmS8; } } case kTfLiteInt16: return armnn::DataType::QSymmS16; case kTfLiteInt32: return armnn::DataType::Signed32; case kTfLiteInt64: return armnn::DataType::Signed64; default: throw armnn::Exception( &"TfLiteArmnnOpaqueDelegate: Unsupported data type: " [ TfLiteOpaqueTensorType(tfLiteTensor) ]); } } armnn::TensorInfo GetTensorInfoForTfLiteOpaqueTensor(const TfLiteOpaqueTensor* tfLiteTensor, bool isOutput = false) { armnn::DataType type = GetDataType(tfLiteTensor); armnn::TensorInfo ret; auto tensorDimensionSize = TfLiteOpaqueTensorNumDims(tfLiteTensor); if (tensorDimensionSize == 0) { // If input tensor does not have a shape // assuming that it has 1D tensor if (!isOutput) { std::vector safeShape = { 1 }; bool dimensionsSpecificity[1] = { true }; armnn::TensorShape tensorShape(safeShape.size(), safeShape.data(), dimensionsSpecificity); ret = armnn::TensorInfo(tensorShape, type); if(IsConstantTensor(tfLiteTensor)) { ret.SetConstant(true); } } else { armnn::TensorShape tensorShape(armnn::Dimensionality::NotSpecified); ret = armnn::TensorInfo(tensorShape, type); } } else { std::vector tensorDims(tensorDimensionSize); std::vector dimensionsSpecificity(tensorDimensionSize, true); for (int32_t i = 0; i < tensorDimensionSize; ++i) { int32_t dim = TfLiteOpaqueTensorDim(tfLiteTensor, i); if (dim <= 0) { dimensionsSpecificity[i] = false; } tensorDims[i] = static_cast(dim); } armnn::TensorShape tensorShape(tensorDimensionSize, tensorDims.data(), reinterpret_cast(dimensionsSpecificity.data())); if (IsConstantTensor(tfLiteTensor)) { ret = armnn::TensorInfo(tensorShape, type); ret.SetConstant(true); } else { ret = armnn::TensorInfo(tensorShape, type); } } auto quantizationInfo = TfLiteOpaqueTensorGetQuantization(tfLiteTensor); if (quantizationInfo.type == kTfLiteAffineQuantization) { // get per-channel quantization parameters const auto* affineQuantization = reinterpret_cast(quantizationInfo.params); if (affineQuantization->scale->size > 1) { std::vector quantizationScales; for (unsigned int i = 0; i < static_cast(affineQuantization->scale->size); ++i) { quantizationScales.push_back(affineQuantization->scale->data[i]); } ret.SetQuantizationScales(quantizationScales); ret.SetQuantizationDim(armnn::numeric_cast(affineQuantization->quantized_dimension)); } else { ret.SetQuantizationScale(affineQuantization->scale->data[0]); ret.SetQuantizationOffset(affineQuantization->zero_point->data[0]); } } else { auto quantizationParameters = TfLiteOpaqueTensorGetQuantizationParams(tfLiteTensor); ret.SetQuantizationScale(quantizationParameters.scale); ret.SetQuantizationOffset(quantizationParameters.zero_point); } return ret; } armnn::ConstTensor CreateConstTensor(const TfLiteOpaqueTensor* tfLiteTensor, const armnn::TensorInfo& tensorInfo) { auto allocType = TfLiteOpaqueTensorGetAllocationType(tfLiteTensor); if (allocType != kTfLiteMmapRo) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Not constant allocation type: " + std::to_string(allocType)); } return armnn::ConstTensor(tensorInfo, TfLiteOpaqueTensorData(tfLiteTensor)); } armnn::ConstTensor* GetConstTensorForTfLiteTensor(const TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int index) { const TfLiteOpaqueTensor* tfLiteTensor = TfLiteOpaqueNodeGetInput(tfLiteContext, tfLiteNode, index); armnn::TensorInfo tensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteTensor); return new armnn::ConstTensor(tensorInfo, TfLiteOpaqueTensorData(tfLiteTensor)); } bool IsOptionalOperandPresent(TfLiteOpaqueNode* tfLiteNode, const int operandIndex) { // Get array of input indices, inputIndexArray is set from the TfLiteOpaqueNodeInputs function // This function turns inputIndexArray into an int array of indices. These indices point to the index of the // tensors for each input slot in the node. const int* inputIndexArray; int numInputs = 0; TfLiteStatus status = TfLiteOpaqueNodeInputs(tfLiteNode, &inputIndexArray, &numInputs); if(status != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to gather input information from node."); } // If the inputs array has fewer than operandIndex entries or if the entry at operandIndex has a value of -1 or // less then the input is not present. if (numInputs > operandIndex && inputIndexArray[operandIndex] >= 0) { return true; } return false; } TfLiteStatus ProcessInputs(armnn::IConnectableLayer* layer, armnnOpaqueDelegate::DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex) { // Get array of input indices, inputIndexArray is set from the TfLiteOpaqueNodeInputs function // This function turns inputIndexArray into an int array of indices. These indices point to the index of the // tensors for each input slot in the node. const int* inputIndexArray; int numInputs = 0; TfLiteStatus status = TfLiteOpaqueNodeInputs(tfLiteNode, &inputIndexArray, &numInputs); if(status != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to gather input information from node."); } // Process input tensors // If input tensor is a Constant tensor create a constant layer and connect it to the network for (int32_t inputIndex = 0; inputIndex < static_cast(layer->GetNumInputSlots()); ++inputIndex) { const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueNodeGetInput(tfLiteContext, tfLiteNode, inputIndex); if (IsConstantTensor(tfLiteInputTensor)) { armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); bool isSupported = false; armnn::BackendId setBackend; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("CONSTANT", tfLiteContext, IsConstantSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo); if (!isSupported) { return kTfLiteError; } auto constantInput = CreateConstTensor(tfLiteInputTensor, inputTensorInfo); auto layerName = GetName(armnn::LayerType::Constant, nodeIndex); armnn::IConnectableLayer* constantLayer = delegateData.m_Network->AddConstantLayer(constantInput, layerName.c_str()); constantLayer->SetBackendId(setBackend); armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(inputTensorInfo); delegateData.m_OutputSlotForNode[inputIndexArray[inputIndex]] = &outputSlot; } } return kTfLiteOk; } } // namespace anonymous armnn-23.08/delegate/opaque/src/Pack.hpp000066400000000000000000000132341446772241200200770ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitPackOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLitePackOperatorCode) { // Check Inputs auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Must have at least one input in (%d != %d) in node #%d", 1, numInputs, nodeIndex); return kTfLiteError; } // Gather input indices and use to get input tensors. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Validate all inputs and get TensorInfo std::vector inputTensorInfos; for (int i = 0; i < numInputs; ++i) { const TfLiteOpaqueTensor* inputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[i]); if (!IsValid(tfLiteContext, inputTensor, tfLitePackOperatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(inputTensor); inputTensorInfos.emplace_back(inputTensorInfo); } // Convert inputTensorInfos to const armnn::TensorInfo* type for FORWARD_LAYER_OPAQUE_SUPPORT_FUNC. std::vector inputConstTensorInfos; std::transform(inputTensorInfos.begin(), inputTensorInfos.end(), std::back_inserter(inputConstTensorInfos), [](armnn::TensorInfo& t)->const armnn::TensorInfo*{ return &t; }); // Check outputs TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather output indices and use to get output tensor. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Validate the output and get TensorInfo const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLitePackOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::StackDescriptor desc; desc.m_NumInputs = static_cast(numInputs); // Get axis from TfLite parameters auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); auto axis = tfLiteNodeParameters->axis; desc.m_Axis = NonNegative(axis, nodeIndex); // Use the tensor shape of the first input as the "correct" input shape in the descriptor desc.m_InputShape = inputTensorInfos[0].GetShape(); // Check if supported bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("STACK", tfLiteContext, IsStackSupported, delegateData.m_Backends, isSupported, setBackend, inputConstTensorInfos, outputTensorInfo, desc); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitPackOperator will be called again to add the layer to the network as seen below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // The TfLite Pack operator is equivalent to the ArmNN Stack operator auto layerName = GetName(armnn::LayerType::Stack, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddStackLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // Connect the Constant Inputs auto inputsTensorsProcess = ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Pad.hpp000066400000000000000000000176741446772241200177410ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitPadOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLitePadOperatorCode) { switch(tfLitePadOperatorCode) { case kTfLiteBuiltinMirrorPad: case kTfLiteBuiltinPad: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); break; case kTfLiteBuiltinPadv2: TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); break; default: return kTfLiteError; } // Inputs int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLitePadOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLitePaddingTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLitePaddingTensor, tfLitePadOperatorCode, nodeIndex)) { return kTfLiteError; } // Output TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLitePadOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& paddingTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLitePaddingTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Get the padding data from the input tensor auto* paddingData = static_cast(TfLiteOpaqueTensorData(tfLitePaddingTensor)); size_t step = 2; armnn::PadDescriptor descriptor; for (unsigned int i = 0; i < paddingTensorInfo.GetNumElements() / step; ++i) { descriptor.m_PadList.emplace_back(paddingData[i * step], paddingData[i * step + 1]); } if (tfLitePadOperatorCode == kTfLiteBuiltinPad && inputTensorInfo.IsQuantized()) { descriptor.m_PadValue = inputTensorInfo.GetQuantizationOffset(); } else if (tfLitePadOperatorCode == kTfLiteBuiltinPadv2) { const TfLiteOpaqueTensor* tfLitepaddingValue = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); armnn::TensorInfo paddingValueTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLitepaddingValue); if (paddingValueTensorInfo.GetNumElements() != 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Multiple padding value are not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } // Get the padding value from the input tensor switch (TfLiteOpaqueTensorType(tfLitepaddingValue)) { case kTfLiteFloat32: descriptor.m_PadValue = static_cast(TfLiteOpaqueTensorData(tfLitepaddingValue))[0]; break; case kTfLiteUInt8: descriptor.m_PadValue = static_cast(TfLiteOpaqueTensorData(tfLitepaddingValue))[0]; break; case kTfLiteInt8: descriptor.m_PadValue = static_cast(TfLiteOpaqueTensorData(tfLitepaddingValue))[0]; break; default: TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Padding value datatype is not supported in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); return kTfLiteError; } } else if (tfLitePadOperatorCode == kTfLiteBuiltinMirrorPad) { auto* options = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); if (options->mode == TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingReflect) { descriptor.m_PaddingMode = armnn::PaddingMode::Reflect; } else if (options->mode == TfLiteMirrorPaddingMode::kTfLiteMirrorPaddingSymmetric) { descriptor.m_PaddingMode = armnn::PaddingMode::Symmetric; } else { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: PaddingMode must be either REFLECT or SYMMETRIC " "in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); } // If padding mode is Reflect then both paddings must be no greater than inputShape(i) - 1. // If padding mode is Symmetric then both paddings must be no greater than inputShape(i). auto inputShape = inputTensorInfo.GetShape(); auto padList = descriptor.m_PadList; const auto isReflect = static_cast(descriptor.m_PaddingMode == armnn::PaddingMode::Reflect); for(unsigned int i = 0; i < padList.size(); ++i) { if(padList.at(i).first > (inputShape[i] - isReflect) || padList.at(i).second > (inputShape[i] - isReflect)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Padding values must be less (Reflect) or " "equal (Symmetric) to the dimension size in operator #%d node #%d: ", tfLitePadOperatorCode, nodeIndex); } } } armnn::BackendId setBackend; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("PAD", tfLiteContext, IsPadSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Pad, nodeIndex); armnn::IConnectableLayer* padLayer = delegateData.m_Network->AddPadLayer(descriptor, layerName.c_str()); padLayer->SetBackendId(setBackend); ARMNN_ASSERT(padLayer != nullptr); armnn::IOutputSlot& outputSlot = padLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); return Connect(padLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Pooling.hpp000066400000000000000000000351231446772241200206310ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitPooling2dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLitePoolingOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensors. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLitePoolingOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLitePoolingOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); TfLiteFusedActivation activationType = kTfLiteActNone; if (tfLiteNodeParameters) { activationType = tfLiteNodeParameters->activation; TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } } armnn::PoolingAlgorithm poolingAlgorithm; switch(tfLitePoolingOperatorCode) { case kTfLiteBuiltinAveragePool2d: poolingAlgorithm = armnn::PoolingAlgorithm::Average; break; case kTfLiteBuiltinL2Pool2d: poolingAlgorithm = armnn::PoolingAlgorithm::L2; break; case kTfLiteBuiltinMaxPool2d: poolingAlgorithm = armnn::PoolingAlgorithm::Max; break; default: return kTfLiteError; } armnn::Pooling2dDescriptor descriptor; descriptor.m_PoolType = poolingAlgorithm; descriptor.m_PoolWidth = tfLiteNodeParameters->filter_width; descriptor.m_PoolHeight = tfLiteNodeParameters->filter_height; descriptor.m_StrideX = tfLiteNodeParameters->stride_width; descriptor.m_StrideY = tfLiteNodeParameters->stride_height; descriptor.m_DataLayout = armnn::DataLayout::NHWC; unsigned int inputHeight = inputTensorInfo.GetShape()[1]; unsigned int inputWidth = inputTensorInfo.GetShape()[2]; CalcPadding(inputHeight, descriptor.m_PoolHeight, descriptor.m_StrideY, 1u, descriptor.m_PadTop, descriptor.m_PadBottom, tfLiteNodeParameters->padding); CalcPadding(inputWidth, descriptor.m_PoolWidth, descriptor.m_StrideX, 1u, descriptor.m_PadLeft, descriptor.m_PadRight, tfLiteNodeParameters->padding); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("POOLING_2D", tfLiteContext, IsPooling2dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Pooling2d, nodeIndex); armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling2dLayer(descriptor, layerName.c_str()); poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); armnn::IOutputSlot& outputSlot = poolingLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(poolingLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } if (Connect(poolingLayer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } // Check and create activation return FusedActivation(tfLiteContext, tfLiteNode, activationType, poolingLayer, 0, delegateData, nodeIndex); } TfLiteStatus VisitPooling3dOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, std::string customOperatorName) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensors. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, kTfLiteBuiltinCustom, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, kTfLiteBuiltinCustom, nodeIndex)) { return kTfLiteError; } // Set the input and output info const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Custom Operators are defined by the name string associated to the operator. Use this to determine // which pooling algorithm to create the armnn operator with. L2 Pooling3D is unsupported in TfLite. armnn::PoolingAlgorithm poolingAlgorithm; if (customOperatorName == "MaxPool3D") { poolingAlgorithm = armnn::PoolingAlgorithm::Max; } else if (customOperatorName == "AveragePool3D") { poolingAlgorithm = armnn::PoolingAlgorithm::Average; } else { return kTfLiteError; } // Create the armnn pool3d descriptor and set the algorithm parsed above. armnn::Pooling3dDescriptor descriptor; descriptor.m_PoolType = poolingAlgorithm; // custom_initial_data and custom_initial_data_size are void* variables defined in the tflite registration // used to access the custom option buffer for the operator. const void* customData = nullptr; int customDataSize = 0; if (TfLiteOpaqueNodeGetCustomInitialData(tfLiteNode, &customData, &customDataSize) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to initialise initial custom data from node #%d: ", nodeIndex); return kTfLiteError; } // Reinterpret the void* to a byte buffer to access the options data in the flexbuffers map. const flexbuffers::Map& m = flexbuffers::GetRoot(reinterpret_cast(customData), customDataSize).AsMap(); // poolDims is a vector of [ 1, Depth, Height, Width, 1 ] const auto poolDims = m["ksize"].AsTypedVector(); descriptor.m_PoolWidth = poolDims[3].AsInt32(); descriptor.m_PoolHeight = poolDims[2].AsInt32(); descriptor.m_PoolDepth = poolDims[1].AsInt32(); // strideDimes is a vector of [ 1, Z, Y, X, 1] const auto strideDims = m["strides"].AsTypedVector(); descriptor.m_StrideX = strideDims[3].AsInt32(); descriptor.m_StrideY = strideDims[2].AsInt32(); descriptor.m_StrideZ = strideDims[1].AsInt32(); descriptor.m_DataLayout = armnn::DataLayout::NDHWC; unsigned int inputDepth = inputTensorInfo.GetShape()[1]; unsigned int inputHeight = inputTensorInfo.GetShape()[2]; unsigned int inputWidth = inputTensorInfo.GetShape()[3]; // CalcPadding expects a TfLitePadding type. Parse flexbuffers to extract padding string and create TfLitePadding. std::string paddingStr = m["padding"].AsString().str(); TfLitePadding padding; if (paddingStr == "VALID") { padding = kTfLitePaddingValid; } else if (paddingStr == "SAME") { padding = kTfLitePaddingSame; } else { padding = kTfLitePaddingUnknown; } // Calculates padding for each pooling dimension separately CalcPadding(inputHeight, descriptor.m_PoolHeight, descriptor.m_StrideY, 1u, descriptor.m_PadTop, descriptor.m_PadBottom, padding); CalcPadding(inputWidth, descriptor.m_PoolWidth, descriptor.m_StrideX, 1u, descriptor.m_PadLeft, descriptor.m_PadRight, padding); CalcPadding(inputDepth, descriptor.m_PoolDepth, descriptor.m_StrideZ, 1u, descriptor.m_PadFront, descriptor.m_PadBack, padding); // Check activation by parsing the string from the flexbuffer map std::string activationTypeStr = m["activation"].AsString().str(); TfLiteFusedActivation activationType = kTfLiteActNone; if (activationTypeStr == "kTfLiteActRelu") { activationType = kTfLiteActRelu; } else if (activationTypeStr == "kTfLiteActReluN1To1") { activationType = kTfLiteActReluN1To1; } else if (activationTypeStr == "kTfLiteActRelu6") { activationType = kTfLiteActRelu6; } else if (activationTypeStr == "kTfLiteActTanh") { activationType = kTfLiteActTanh; } else if (activationTypeStr == "kTfLiteActSignBit") { activationType = kTfLiteActSignBit; } else if (activationTypeStr == "kTfLiteActSigmoid") { activationType = kTfLiteActSigmoid; } else { activationType = kTfLiteActNone; } TfLiteStatus activationStatus = ValidateFusedActivationOperator(delegateData, tfLiteContext, outputTensorInfo, outputTensorInfo, activationType); if(activationStatus != kTfLiteOk) { return kTfLiteError; } // Validate the output info. bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("POOLING_3D", tfLiteContext, IsPooling3dSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Create the Layer auto layerName = GetName(armnn::LayerType::Pooling3d, nodeIndex); armnn::IConnectableLayer* poolingLayer = delegateData.m_Network->AddPooling3dLayer(descriptor, layerName.c_str()); poolingLayer->SetBackendId(setBackend); ARMNN_ASSERT(poolingLayer != nullptr); // Create and set output slots armnn::IOutputSlot& outputSlot = poolingLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(poolingLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } if (Connect(poolingLayer, tfLiteContext, tfLiteNode, delegateData) != kTfLiteOk) { return kTfLiteError; } return FusedActivation(tfLiteContext, tfLiteNode, activationType, poolingLayer, 0, delegateData, nodeIndex); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Prelu.hpp000066400000000000000000000120561446772241200203110ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus ValidatePreluOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& alphaInfo, const armnn::TensorInfo& outputInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("PRELU", tfLiteContext, IsPreluSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, alphaInfo, outputInfo); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitPreluOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteAlphaTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteAlphaTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& alphaTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteAlphaTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); if (!delegateData.m_Network) { return ValidatePreluOperator(delegateData, tfLiteContext, inputTensorInfo, alphaTensorInfo, outputTensorInfo); } auto layerName = GetName(armnn::LayerType::Prelu, nodeIndex); armnn::IConnectableLayer* preluLayer = delegateData.m_Network->AddPreluLayer(layerName.c_str()); ARMNN_ASSERT(preluLayer != nullptr); bool isConstantAlpha = IsConstantTensor(tfLiteAlphaTensor); // Add constant layer for constant alpha if (isConstantAlpha) { auto constAlphaTensor = armnn::ConstTensor(alphaTensorInfo, TfLiteOpaqueTensorData(tfLiteAlphaTensor)); auto alphaName = GetName(armnn::LayerType::Constant, nodeIndex, "Alpha"); armnn::IConnectableLayer* constLayer = delegateData.m_Network->AddConstantLayer(constAlphaTensor, alphaName.c_str()); ARMNN_ASSERT(constLayer != nullptr); constLayer->GetOutputSlot(0).SetTensorInfo(alphaTensorInfo); constLayer->GetOutputSlot(0).Connect(preluLayer->GetInputSlot(1)); } armnn::IOutputSlot& outputSlot = preluLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(preluLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Quantization.hpp000066400000000000000000000174631446772241200217170ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitDequantizeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); armnn::TensorInfo outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); UpdateConstantTensorOutputs(inputTensorInfo, outputTensorInfo); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("DEQUANTIZE", tfLiteContext, IsDequantizeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Dequantize, nodeIndex); armnn::IConnectableLayer* dequantizeLayer = delegateData.m_Network->AddDequantizeLayer(layerName.c_str()); dequantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(dequantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = dequantizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); auto inputsTensorsProcess = ProcessInputs(dequantizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex); if (inputsTensorsProcess == kTfLiteError) { return inputsTensorsProcess; } return Connect(dequantizeLayer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitQuantizeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Only affine per-layer quantization is supported. if (!IsAffineQuantization(*tfLiteOutputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Only affine per-layer quantization is supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("QUANTIZE", tfLiteContext, IsQuantizeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Quantize, nodeIndex); armnn::IConnectableLayer* quantizeLayer = delegateData.m_Network->AddQuantizeLayer(layerName.c_str()); quantizeLayer->SetBackendId(setBackend); ARMNN_ASSERT(quantizeLayer != nullptr); armnn::IOutputSlot& outputSlot = quantizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(quantizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(quantizeLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Redefine.hpp000066400000000000000000000466171446772241200207550ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitCastOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { return kTfLiteError; } // This layer only has 1 input, so we can directly assign tensor[0] to a new opaque tensor const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[numInputs-1]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { return kTfLiteError; } // This layer only has 1 output, so we can directly assign tensor[0] to a new opaque tensor const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[numOutputs-1]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("CAST", tfLiteContext, IsCastSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitCastOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Cast layer auto layerName = GetName(armnn::LayerType::Cast, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddCastLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitReshapeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs == 2) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); } else { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::ReshapeDescriptor reshapeDesc; std::vector targetShape; auto* reshapeOptions = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); // The new shape can be defined by either a second input tensor or by a builtin option, we need to check for both. // Options might be set without valid data. we need to check the dimensions are in a valid range. if (reshapeOptions && reshapeOptions->num_dimensions > 0 && reshapeOptions->num_dimensions <= 8) { for (int i = 0; i < reshapeOptions->num_dimensions; ++i) { targetShape.push_back(reshapeOptions->shape[i]); } } else if (numInputs == 2) { // Get shape from the second input tensor const TfLiteOpaqueTensor* tfLiteShapeInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteShapeInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } int32_t numDims = TfLiteOpaqueTensorNumDims(tfLiteShapeInputTensor); if (numDims != 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Target 'shape' input is not a 1D tensor in " "operator #%d node #%d: Falling back to TfLiteOptions.", operatorCode, nodeIndex); } else { // Get the shape data out of the input tensor auto* shapeTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteShapeInputTensor)); int32_t shapeTensorNumValues = TfLiteOpaqueTensorDim(tfLiteShapeInputTensor, 0); for (int32_t i = 0; i < shapeTensorNumValues; ++i) { targetShape.push_back(shapeTensorDataPtr[i]); } } } else { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Target shape not defined in reshape parameters or input tensor. " "At least one method required in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } // Use the data to create the required tensor shape. if (CreateOutputTensorShape(inputTensorInfo0, targetShape, reshapeDesc) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: At most one component of shape can be -1 in: " "operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } if (reshapeDesc.m_TargetShape.GetNumElements() != inputTensorInfo0.GetNumElements()) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Reshape, number of elements in output shape does not match input " "operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Reshape, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitSqueezeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } auto* options = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); std::vector squeezeDim; // A single negative dim index is interpreted as a negative index in python // Meaning the index will be the shape size plus the negative index value if (options->num_squeeze_dims == 1 && options->squeeze_dims[0] < 0) { int32_t dim = static_cast(inputTensorInfo.GetShape().GetNumDimensions()) + options->squeeze_dims[0]; squeezeDim.push_back(static_cast(dim)); } else { for (int32_t i = 0; i < options->num_squeeze_dims; ++i) { squeezeDim.push_back(static_cast(options->squeeze_dims[i])); } } armnn::TensorInfo outputTensorInfo = OutputShapeOfSqueeze(squeezeDim, inputTensorInfo); armnn::ReshapeDescriptor reshapeDesc; reshapeDesc.m_TargetShape = outputTensorInfo.GetShape(); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SQUEEZE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Reshape, nodeIndex, "Squeeze"); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitExpandDimsOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteAxisTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); armnn::TensorInfo outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor); auto* axisTensorData = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); int32_t axis = axisTensorData[0]; int32_t inputDimSize = static_cast(inputTensorInfo.GetShape().GetNumDimensions()); if (axis > inputDimSize || axis < 0 - (inputDimSize + 1)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Axis must be in range " "[0 - (inputDimSize + 1), inputDimSize] inclusive."); return kTfLiteError; } if(axis < 0) { axis = inputDimSize + axis + 1; } std::vector shape(static_cast(inputDimSize) + 1); unsigned int inputShapeIndex = 0; for (unsigned int i = 0; i < static_cast(inputDimSize + 1); ++i) { if (i == static_cast(axis)) { shape[i] = 1; } else { shape[i] = inputTensorInfo.GetShape()[inputShapeIndex]; ++inputShapeIndex; } } armnn::ReshapeDescriptor reshapeDesc; reshapeDesc.m_TargetShape = armnn::TensorShape(static_cast(inputDimSize + 1), shape.data()); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("EXPAND_DIMS", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, reshapeDesc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Reshape, nodeIndex, "ExpandDims"); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputTensorInfo.SetShape(reshapeDesc.m_TargetShape); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } armnn-23.08/delegate/opaque/src/Reduce.hpp000066400000000000000000000141451446772241200204320ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitReduceOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t reduceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteAxisTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, reduceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Get const axis value from model and set it to descriptor. const armnn::TensorInfo& axisTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteAxisTensor); auto* axisTensorData = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); std::vector axis; // Add axis data to vector to be converter to unsigned int and assigned to descriptor axis. if (axisTensorData != nullptr) { for (unsigned int i = 0; i < axisTensorInfo.GetNumElements(); ++i) { axis.emplace_back(axisTensorData[i]); } } else { for (unsigned int i = 0; i < inputTensorInfo.GetNumDimensions(); ++i) { axis.push_back(i); } } // Convert the axis to unsigned int and remove duplicates. unsigned int rank = inputTensorInfo.GetNumDimensions(); std::set uniqueAxis; std::transform(axis.begin(), axis.end(), std::inserter(uniqueAxis, uniqueAxis.begin()), [rank](int i)->unsigned int{ return (i + rank) % rank; }); armnn::ReduceDescriptor desc; desc.m_vAxis.assign(uniqueAxis.begin(), uniqueAxis.end()); auto* reducerParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); desc.m_KeepDims = reducerParameters->keep_dims; if (reduceOperatorCode == kTfLiteBuiltinReduceMax) { desc.m_ReduceOperation = armnn::ReduceOperation::Max; } else if (reduceOperatorCode == kTfLiteBuiltinReduceMin) { desc.m_ReduceOperation = armnn::ReduceOperation::Min; } else if (reduceOperatorCode == kTfLiteBuiltinSum) { desc.m_ReduceOperation = armnn::ReduceOperation::Sum; } else if (reduceOperatorCode == kTfLiteBuiltinReduceProd) { desc.m_ReduceOperation = armnn::ReduceOperation::Prod; } else { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unsupported Reduction Operator #%d node #%d: ", reduceOperatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("REDUCE", tfLiteContext, IsReduceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, desc); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add an Reduce layer auto layerName = GetName(armnn::LayerType::Reduce, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddReduceLayer(desc, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Resize.hpp000066400000000000000000000220231446772241200204560ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateResizeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, const armnn::ResizeDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("RESIZE", tfLiteContext, IsResizeSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitResizeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t resizeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // The first input contains the data of the image that should be resized [batch, height, width, channels] const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // The second input contains a size tensor. The size tensor contains two integer values // that describe the new height and width of the image [new_height, new_width] const TfLiteOpaqueTensor* tfLiteSizeTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (IsDynamicTensor(tfLiteSizeTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // The output tensor should have the shape [batch, new_height, new_width, channels] const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); std::string layerName("Resize"); // Fill descriptor armnn::ResizeDescriptor desc; switch (resizeOperatorCode) { case kTfLiteBuiltinResizeBilinear: { desc.m_Method = armnn::ResizeMethod::Bilinear; layerName += "Bilinear:" + std::to_string(nodeIndex); TfLiteResizeBilinearParams* bilinearOptions = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); desc.m_AlignCorners = bilinearOptions->align_corners; desc.m_HalfPixelCenters = bilinearOptions->half_pixel_centers; break; } case kTfLiteBuiltinResizeNearestNeighbor: { desc.m_Method = armnn::ResizeMethod::NearestNeighbor; layerName += "NearestNeighbor:" + std::to_string(nodeIndex); TfLiteResizeNearestNeighborParams* nearestNeighborOptions = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); desc.m_AlignCorners = nearestNeighborOptions->align_corners; desc.m_HalfPixelCenters = nearestNeighborOptions->half_pixel_centers; break; } default: { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unknown TfLite built in operation for Resize. " "Given operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } } // In Arm NN the values of the size input tensor [new_height, new_width] is saved in the operator // descriptor. We have to read it from the input tensor and write it to the descriptor. auto* sizeTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteSizeTensor)); auto sizeTensorNumDimensions = TfLiteOpaqueTensorNumDims(tfLiteSizeTensor); // The size tensor is only a 1D tensor -> [new_height, new width] if (sizeTensorNumDimensions != 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The Size-Input-Tensor of the Resize operation is not allowed to be a " "dynamic tensor. Operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } // Get number of values in the size tensor auto sizeTensorNumValues = TfLiteOpaqueTensorDim(tfLiteSizeTensor,0); if (sizeTensorNumValues == 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The Size-Input-Tensor of the Resize operation is not allowed to be a " "dynamic tensor. Operator: #%d node #%d: ", resizeOperatorCode, nodeIndex); return kTfLiteError; } else if (sizeTensorNumValues != 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The Size-Input-Tensor of the Resize operation requires to " "have a dimension of 2 [new_height, new width] but a tensor with a dimension of #%d was given. " "Operator: #%d node #%d: ", sizeTensorNumValues, resizeOperatorCode, nodeIndex); return kTfLiteError; } // get size tensor data std::vector sizeTensorData(sizeTensorDataPtr, sizeTensorDataPtr+sizeTensorNumValues); desc.m_TargetHeight = static_cast (sizeTensorData[0]); desc.m_TargetWidth = static_cast (sizeTensorData[1]); desc.m_DataLayout = armnn::DataLayout::NHWC; // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateResizeOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, desc); } armnn::IConnectableLayer* resizeLayer = nullptr; layerName += ":"; layerName += nodeIndex; resizeLayer = delegateData.m_Network->AddResizeLayer(desc, layerName.c_str()); armnn::IOutputSlot& outputSlot = resizeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(resizeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } ARMNN_ASSERT(resizeLayer != nullptr); return Connect(resizeLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/ReverseV2.hpp000066400000000000000000000153451446772241200210510ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateReverseV2Operator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo0, const armnn::TensorInfo& inputInfo1, const armnn::TensorInfo& outputInfo) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("REVERSEV2", tfLiteContext, IsReverseV2Supported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo0, inputInfo1, outputInfo); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitReverseV2Operator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t reverseV2OperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // The first input contains the data to be reversed const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // The second input contains the axis tensor const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (IsDynamicTensor(tfLiteAxisTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Get the output tensor const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& inputTensorInfo1 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteAxisTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); if (inputTensorInfo0.GetNumDimensions() != outputTensorInfo.GetNumDimensions()) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: input tensor dimension and output tensor dimension differ #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } for (unsigned i=0; i < inputTensorInfo0.GetNumDimensions(); i++) { if (inputTensorInfo0.GetShape()[i] != outputTensorInfo.GetShape()[i]) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: input tensor dimension and output tensor differ #%d node #%d: ", reverseV2OperatorCode, nodeIndex); return kTfLiteError; } } // Get axis tensor data auto axisTensorNumValues = static_cast(TfLiteOpaqueTensorDim(tfLiteAxisTensor,0)); const auto maxDimension = 4; if (axisTensorNumValues > maxDimension) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The Axis-Input-Tensor of the ReverseV2 operation requires a " "dimension of <= %d but a tensor with a dimension of %d was given. " "Operator: #%d node #%d: ", maxDimension, axisTensorNumValues, reverseV2OperatorCode, nodeIndex); return kTfLiteError; } // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateReverseV2Operator(delegateData, tfLiteContext, inputTensorInfo0, inputTensorInfo1, outputTensorInfo); } auto layerName = GetName(armnn::LayerType::ReverseV2, nodeIndex); armnn::IConnectableLayer* reverseV2Layer = delegateData.m_Network->AddReverseV2Layer(layerName.c_str()); armnn::IOutputSlot& outputSlot = reverseV2Layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(reverseV2Layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } ARMNN_ASSERT(reverseV2Layer != nullptr); return Connect(reverseV2Layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Round.hpp000066400000000000000000000070231446772241200203070ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include namespace armnnOpaqueDelegate { TfLiteStatus VisitFloorOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. int numInputs = 0; const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Use input indices to get input tensors. const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); // NOTE: looks like the outputTensorInfo is the only thing that is required for the case // where we are adding the floor layer so maybe move the other stuff inside the // if !delegateData block for efficiency. const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitFloorOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { return ValidateFloorOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo); } // Add a Floor layer auto layerName = GetName(armnn::LayerType::Floor, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddFloorLayer(layerName.c_str()); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Shape.hpp000066400000000000000000000105651446772241200202650ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitShapeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* shapeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); if (shapeParameters->out_type != kTfLiteInt32 && shapeParameters->out_type != kTfLiteInt64) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: output_type data type is not supported in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SHAPE", tfLiteContext, IsShapeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo); }; // If the m_Network is a nullptr, this signals that a prerequisite TfLite callback is required to clarify the // support for the operator // If supported, VisitShapeOperator will be called again to add the layer to the network as seen further below if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Shape layer auto layerName = GetName(armnn::LayerType::Shape, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddShapeLayer(layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/SharedFunctions.cpp000066400000000000000000000070451446772241200223160ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SharedFunctions.hpp" #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateFloorOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& outputTensorInfo) { bool isSupported = false; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("FLOOR", tfLiteContext, IsFloorSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputTensorInfo, outInfo); }; validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateFusedActivationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, TfLiteFusedActivation activationType) { armnn::ActivationDescriptor activationDesc; switch (activationType) { case kTfLiteActNone: { // No Activation return kTfLiteOk; } case kTfLiteActRelu: { activationDesc.m_Function = armnn::ActivationFunction::ReLu; break; } case kTfLiteActReluN1To1: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 1.0f; activationDesc.m_B = -1.0f; break; } case kTfLiteActRelu6: { activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; activationDesc.m_A = 6.0f; activationDesc.m_B = 0.0f; break; } case kTfLiteActSigmoid: { activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; break; } case kTfLiteActTanh: { activationDesc.m_Function = armnn::ActivationFunction::TanH; activationDesc.m_A = 1.0f; activationDesc.m_B = 1.0f; break; } default: return kTfLiteError; } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("ACTIVATION", tfLiteContext, IsActivationSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, activationDesc); }; validateFunc(outputInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } } // namespace armnnDelegate armnn-23.08/delegate/opaque/src/SharedFunctions.hpp000066400000000000000000000017021446772241200223150ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateFloorOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputTensorInfo, const armnn::TensorInfo& outputTensorInfo); TfLiteStatus ValidateFusedActivationOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, TfLiteFusedActivation activationType); } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Slice.hpp000066400000000000000000000164631446772241200202670ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitSliceOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteSliceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Read inputs [input, begin, size] // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } std::vector tfLiteInputTensors; tfLiteInputTensors.reserve(numInputs); for (int i = 0; i < numInputs; i++) { const TfLiteOpaqueTensor* inputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[i]); tfLiteInputTensors.push_back(inputTensor); if (!IsValid(tfLiteContext, inputTensor, tfLiteSliceOperatorCode, nodeIndex)) { return kTfLiteError; } } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensors[0]); // We save the begin and size tensors in our descriptor. Therefore we have to read those values from inputs unsigned int inputRank = inputTensorInfo.GetNumDimensions(); auto ReadInt32Input = [&](int inputIndex, std::vector& outputData, const char* name) -> TfLiteStatus { if (TfLiteOpaqueTensorType(tfLiteInputTensors[inputIndex]) != kTfLiteInt32) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The %s Tensor of the Slice operation needs to " "be of type int32. Operator: #%d node #%d: ", name, tfLiteSliceOperatorCode, nodeIndex); return kTfLiteError; } uint32_t rank = TfLiteOpaqueTensorNumDims(tfLiteInputTensors[inputIndex]); if (rank != 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The %s Tensor of the Slice operation needs to " "be a 1D-Tensor. Operator: #%d node #%d: ", name, tfLiteSliceOperatorCode, nodeIndex); return kTfLiteError; } uint32_t numValues = TfLiteOpaqueTensorDim(tfLiteInputTensors[inputIndex], 0); if (numValues != inputRank) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The number of values in the %s Tensor of the " "Slice operation needs to be equal to the rank of the Input Tensor. Operator: #%d node #%d: ", name, tfLiteSliceOperatorCode, nodeIndex); return kTfLiteError; } // return tensor data auto* tensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteInputTensors[inputIndex])); outputData.assign(tensorDataPtr, tensorDataPtr + numValues); return kTfLiteOk; }; std::vector signedBegin; if (ReadInt32Input(1, signedBegin, "Begin") != kTfLiteOk) { return kTfLiteError; } std::vector signedSize; if (ReadInt32Input(2, signedSize, "Size") != kTfLiteOk) { return kTfLiteError; } std::vector begin({ signedBegin.begin(), signedBegin.end() }); std::vector size(signedSize.size()); for (unsigned int i = 0; i < signedSize.size(); ++i) { int signedValue = signedSize[i]; if (signedValue < -1 || signedValue > TfLiteOpaqueTensorDim(tfLiteInputTensors[0], i) - signedBegin[i]) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnDelegate: Invalid value for Size. Size must be in range [-1, inputDimSize - begin] " "[-1, %d] inclusive but was %d Operator: #%d node #%d: ", TfLiteOpaqueTensorDim(tfLiteInputTensors[0], i) - signedBegin[i], signedValue, tfLiteSliceOperatorCode, nodeIndex); return kTfLiteError; } if (signedValue == -1) { size[i] = TfLiteOpaqueTensorDim(tfLiteInputTensors[0], i) - signedBegin[i]; } else { size[i] = static_cast(signedValue); } } // Write all data to the descriptor armnn::SliceDescriptor descriptor(begin, size); // Validate output // Gather output indices and use to get output tensor. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSliceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SLICE", tfLiteContext, IsSliceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a Slice layer auto layerName = GetName(armnn::LayerType::Slice, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSliceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Softmax.hpp000066400000000000000000000151451446772241200206450ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateSoftmaxOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputTensorInfo, const armnn::SoftmaxDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SOFTMAX", tfLiteContext, IsSoftmaxSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus ValidateLogSoftmaxOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputTensorInfo, const armnn::LogSoftmaxDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("LOG_SOFTMAX", tfLiteContext, IsLogSoftmaxSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputTensorInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitSoftmaxOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfliteSoftmaxOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfliteSoftmaxOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensor. const int* outputTensors; int numOutputs = 0; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfliteSoftmaxOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); if (!delegateData.m_Network) { switch(tfliteSoftmaxOperatorCode) { case kTfLiteBuiltinSoftmax: { armnn::SoftmaxDescriptor descriptor; auto* nodeParams = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_Beta = nodeParams->beta; return ValidateSoftmaxOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, descriptor); } case kTfLiteBuiltinLogSoftmax: { armnn::LogSoftmaxDescriptor descriptor; return ValidateLogSoftmaxOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, descriptor); } default: return kTfLiteError; } } armnn::IConnectableLayer* softmaxLayer = nullptr; auto layerName = GetName(armnn::LayerType::Softmax, nodeIndex); switch(tfliteSoftmaxOperatorCode) { case kTfLiteBuiltinSoftmax: { armnn::SoftmaxDescriptor descriptor; auto* nodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_Beta = nodeParameters->beta; softmaxLayer = delegateData.m_Network->AddSoftmaxLayer(descriptor, layerName.c_str()); break; } case kTfLiteBuiltinLogSoftmax: { armnn::LogSoftmaxDescriptor descriptor; softmaxLayer = delegateData.m_Network->AddLogSoftmaxLayer(descriptor, layerName.c_str()); break; } default: return kTfLiteError; } ARMNN_ASSERT(softmaxLayer != nullptr); armnn::IOutputSlot& outputSlot = softmaxLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(softmaxLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(softmaxLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/SpaceDepth.hpp000066400000000000000000000174031446772241200212430ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitSpaceToDepthOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteSpaceDepthOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteSpaceDepthOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSpaceDepthOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::SpaceToDepthDescriptor descriptor; auto* nodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_BlockSize = nodeParameters->block_size; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SPACE_TO_DEPTH", tfLiteContext, IsSpaceToDepthSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a SpaceToDepth layer auto layerName = GetName(armnn::LayerType::SpaceToDepth, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSpaceToDepthLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } TfLiteStatus VisitDepthToSpaceOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteDepthSpaceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteDepthSpaceOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteDepthSpaceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); armnn::DepthToSpaceDescriptor descriptor; auto* nodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); descriptor.m_BlockSize = nodeParameters->block_size; bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("DEPTH_TO_SPACE", tfLiteContext, IsDepthToSpaceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a DepthToSpace layer auto layerName = GetName(armnn::LayerType::DepthToSpace, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddDepthToSpaceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Split.hpp000066400000000000000000000376211446772241200203220ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include #include namespace armnnOpaqueDelegate { constexpr unsigned int MaxNumOfTensorDimensions = 5U; TfLiteStatus VisitSplitOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteSplitOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); auto* splitParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); int numSplits = NonNegative(splitParameters->num_splits, nodeIndex); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, numSplits, nodeIndex)); // Gather input indices and use to get Axis tensor. const int* inputTensors; auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteAxisTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } // Use input indices to get input tensor. const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numSplits) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); if (GetTensorInfoForTfLiteOpaqueTensor(tfLiteAxisTensor).GetNumElements() != 1) { return kTfLiteError; } auto* axisTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); std::vector axisTensorData(axisTensorDataPtr, axisTensorDataPtr + 1); int32_t axis = axisTensorData[0]; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { // Square bracket denotes inclusive n while parenthesis denotes exclusive n // E.g. Rank 4 tensor can have axis in range [-4, 3) // -1 == 3, -2 == 2, -3 == 1, -4 == 0 TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: Operation has invalid axis: #%d. " "Axis must be in range [-n, n) in node #%d:", axis, nodeIndex); } const unsigned int splitDim = ComputeWrappedIndex(axis, inputTensorInfo.GetNumDimensions()); std::vector outputs; for (int i = 0; i < numSplits; ++i) { const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[i]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSplitOperatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); auto inputDimSize = inputTensorInfo.GetNumDimensions(); if (inputDimSize > MaxNumOfTensorDimensions) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: The number of dimensions: #%d for input tensors of the split op cannot be " "greater than #%d in node #%d: ", inputDimSize, MaxNumOfTensorDimensions, nodeIndex); return kTfLiteError; } std::vector splitterDimSizes(inputDimSize); // Add current input shape to splitterDimSizes for (unsigned int i = 0; i < inputDimSize; ++i) { splitterDimSizes[i] = inputTensorInfo.GetShape()[i]; } if (splitterDimSizes[splitDim] % numSplits != 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: Number of splits #%d must evenly divide the dimension #%d in node #%d: ", numSplits, splitterDimSizes[splitDim], nodeIndex); return kTfLiteError; } splitterDimSizes[splitDim] /= numSplits; armnn::SplitterDescriptor splitDescriptor(numSplits, inputDimSize); for (int j = 0; j < numSplits; ++j) { // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx) { splitDescriptor.SetViewSize(j, dimIdx, splitterDimSizes[dimIdx]); } splitDescriptor.SetViewOriginCoord(j, splitDim, splitterDimSizes[splitDim] * j); } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SPLIT", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Splitter, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) { layer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // Connect the input slots delegateData.m_OutputSlotForNode[inputTensors[1]]->Connect(layer->GetInputSlot(0)); if(numSplits != static_cast(layer->GetNumOutputSlots())) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: Expected number of splits #%d does not " "match the number of output slots #%d in node #%d: ", numSplits, layer->GetNumOutputSlots(), nodeIndex); return kTfLiteError; } // Prepare output slots for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex) { armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex); delegateData.m_OutputSlotForNode[ static_cast(outputTensors[outputIndex])] = &outputSlot; } return kTfLiteOk; } TfLiteStatus VisitSplitVOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteSplitVOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); const int* inputTensors; auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteSplitsTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteSplitsTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteAxisTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[2]); if (!IsValid(tfLiteContext, tfLiteAxisTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& splitsTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteSplitsTensor); if (splitsTensorInfo.GetNumDimensions() != 1) { return kTfLiteError; } if (GetTensorInfoForTfLiteOpaqueTensor(tfLiteAxisTensor).GetNumElements() != 1) { return kTfLiteError; } auto* axisTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteAxisTensor)); std::vector axisTensorData(axisTensorDataPtr, axisTensorDataPtr + 1); int32_t axis = axisTensorData[0]; auto inputDimensions = static_cast(inputTensorInfo.GetNumDimensions()); if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0))) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: Operation has invalid axis: #%d. " "Axis must be in range [-n, n) in node #%d:", axis, nodeIndex); } const unsigned int splitDim = ComputeWrappedIndex(axisTensorData[0], inputTensorInfo.GetNumDimensions()); auto* splitVParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); int numSplits = 0; if (splitVParameters) { numSplits = NonNegative(splitVParameters->num_splits, nodeIndex); } else { numSplits = splitsTensorInfo.GetNumElements(); } if (numSplits <= 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: Invalid number of splits %d in node #%d", numSplits, nodeIndex); return kTfLiteError; } TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, numSplits, nodeIndex)); // Gather output indices and use to get output tensors. const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numSplits) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } std::vector outputs; for (int i = 0; i < numSplits; ++i) { const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[i]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteSplitVOperatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); auto inputDimSize = inputTensorInfo.GetNumDimensions(); if (inputDimSize > MaxNumOfTensorDimensions) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: The number of dimensions: #%d for input tensors of the split op cannot be " "greater than #%d in node #%d: ", inputDimSize, MaxNumOfTensorDimensions, nodeIndex); return kTfLiteError; } std::vector splitsTensorData(numSplits); std::memcpy(splitsTensorData.data(), TfLiteOpaqueTensorData(tfLiteSplitsTensor), splitsTensorInfo.GetNumBytes()); unsigned int index = 0; unsigned int inferredIndex = 0; int numberOfInferred = 0; int splitSum = 0; for (auto splitData : splitsTensorData) { if (splitData < 0) { ++numberOfInferred; inferredIndex = index; } else { splitSum += splitData; } ++index; } // Check for inferred axis if (numberOfInferred == 0) { if (splitSum != armnn::numeric_cast(inputTensorInfo.GetShape()[splitDim])) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: SplitV split_sizes does not sum to the dimension " "of value along split_dim in node #%d", nodeIndex); return kTfLiteError; } } else if (numberOfInferred == 1) { splitsTensorData[inferredIndex] = armnn::numeric_cast(inputTensorInfo.GetShape()[splitDim]) - splitSum; } else { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteOpaqueArmnnDelegate: SplitV cannot infer split size for " "more than one split in node #%d", nodeIndex); return kTfLiteError; } armnn::SplitterDescriptor splitDescriptor(numSplits, inputDimSize); unsigned int accumSplit = 0; for (int j = 0; j < numSplits; ++j) { unsigned int splitSize = armnn::numeric_cast(splitsTensorData[j]); // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < inputTensorInfo.GetNumDimensions(); ++dimIdx) { unsigned int dimSize = inputTensorInfo.GetShape()[dimIdx]; if (dimIdx == splitDim) { dimSize = splitSize; } splitDescriptor.SetViewSize(j, dimIdx, dimSize); } splitDescriptor.SetViewOriginCoord(j, splitDim, accumSplit); accumSplit += splitSize; } armnn::BackendId setBackend; if (!delegateData.m_Network) { // Check if supported bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("SPLITV", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputTensorInfos, splitDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Splitter, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddSplitterLayer(splitDescriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k) { layer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/StridedSlice.hpp000066400000000000000000000162411446772241200216000ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitStridedSliceOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfLiteStridedSliceOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 4, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Read inputs [input, begin, end, strides] // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } std::vector tfLiteInputTensors; tfLiteInputTensors.reserve(numInputs); for (int i = 0; i < numInputs; i++) { const TfLiteOpaqueTensor* inputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[i]); tfLiteInputTensors.push_back(inputTensor); if (!IsValid(tfLiteContext, inputTensor, tfLiteStridedSliceOperatorCode, nodeIndex)) { return kTfLiteError; } } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensors[0]); // We save the begin, end and strides tensors in our descriptor. Therefore we have to read those values from inputs unsigned int inputRank = inputTensorInfo.GetNumDimensions(); auto ReadInt32Input = [&](int inputIndex, std::vector& outputData) -> TfLiteStatus { if (TfLiteOpaqueTensorType(tfLiteInputTensors[inputIndex]) != kTfLiteInt32) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLitearmnnOpaqueDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need" " to be of type int32. Operator: #%d node #%d: ", tfLiteStridedSliceOperatorCode, nodeIndex); return kTfLiteError; } uint32_t rank = TfLiteOpaqueTensorNumDims(tfLiteInputTensors[inputIndex]); if (rank != 1) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLitearmnnOpaqueDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need" " to be a 1D-Tensor. Operator: #%d node #%d: ", tfLiteStridedSliceOperatorCode, nodeIndex); return kTfLiteError; } uint32_t numValues = TfLiteOpaqueTensorDim(tfLiteInputTensors[inputIndex], 0); if (numValues != inputRank) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLitearmnnOpaqueDelegate: The number of values in the Begin-, End- and Stride-Tensors of the " "StridedSlice operation need to be equal to the rank of the Input-Tensor. Operator: #%d node #%d: ", tfLiteStridedSliceOperatorCode, nodeIndex); return kTfLiteError; } // return tensor data auto* tensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteInputTensors[inputIndex])); outputData.assign(tensorDataPtr, tensorDataPtr + numValues); return kTfLiteOk; }; std::vector beginData; if (ReadInt32Input(1, beginData) != kTfLiteOk) return kTfLiteError; std::vector endData; if (ReadInt32Input(2, endData) != kTfLiteOk) return kTfLiteError; std::vector strideData; if (ReadInt32Input(3, strideData) != kTfLiteOk) return kTfLiteError; // parse built in options auto* nodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); // Write all data to the descriptor armnn::StridedSliceDescriptor descriptor; descriptor.m_Begin = std::move(beginData); descriptor.m_End = std::move(endData); descriptor.m_Stride = std::move(strideData); descriptor.m_BeginMask = nodeParameters->begin_mask; descriptor.m_EllipsisMask = nodeParameters->ellipsis_mask; descriptor.m_EndMask = nodeParameters->end_mask; descriptor.m_NewAxisMask = nodeParameters->new_axis_mask; descriptor.m_ShrinkAxisMask = nodeParameters->shrink_axis_mask; descriptor.m_DataLayout = armnn::DataLayout::NHWC; // Validate output // Gather output indices and use to get output tensor. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfLiteStridedSliceOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("STRIDED_SLICE", tfLiteContext, IsStridedSliceSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } // Add a StridedSlice layer auto layerName = GetName(armnn::LayerType::StridedSlice, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddStridedSliceLayer(descriptor, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } // Connect return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/Tile.hpp000066400000000000000000000165251446772241200201240ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus ValidateTileOperator(DelegateData& delegateData, TfLiteOpaqueContext *tfLiteContext, const armnn::TensorInfo& inputInfo, const armnn::TensorInfo& outputInfo, const armnn::TileDescriptor& descriptor) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("TILE", tfLiteContext, IsTileSupported, delegateData.m_Backends, isSupported, armnn::BackendId(), inputInfo, outputInfo, descriptor); return isSupported ? kTfLiteOk : kTfLiteError; } TfLiteStatus VisitTileOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tileOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input tensors auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Gather output tensors int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // The input contains the data that should be tiled const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (IsDynamicTensor(tfLiteInputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // The multiples tensor contains the number of copies for each axis const TfLiteOpaqueTensor* tfLiteMultiplesTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]);; if (IsDynamicTensor(tfLiteMultiplesTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic input tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // The output tensor const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (IsDynamicTensor(tfLiteOutputTensor)) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Dynamic output tensors are not supported in operator #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& multiplesTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteMultiplesTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); // Multiples length must be the same as the number of dimension in input tensor if (multiplesTensorInfo.GetNumElements() != inputTensorInfo.GetNumDimensions()) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate:", "The Multiples length must be the same as the number of dimension in input tensor", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // Get the Multiples data: In armnn, the values of the multiples input tensor is saved in the operator descriptor // We have to read it from the input tensor and write it the descriptor auto* multiplesTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteMultiplesTensor)); auto multiplesTensorNum = TfLiteOpaqueTensorDim(tfLiteMultiplesTensor, 0); std::vector multiplesIntData(multiplesTensorDataPtr, multiplesTensorDataPtr + multiplesTensorNum); // The multiples must be positive for (auto multiple : multiplesIntData) { if (multiple < 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The Multiples must be positive values", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } } // The original input from TFLite is int32, and we have to make it as uint32 for our descriptor std::vector multiplesUintData; std::transform(multiplesIntData.begin(), multiplesIntData.end(), std::back_inserter(multiplesUintData), [] (const int value) { return static_cast(value); }); armnn::TileDescriptor tileDescriptor; tileDescriptor.m_Multiples = multiplesUintData; // Check output dimensions if (inputTensorInfo.GetNumDimensions() != outputTensorInfo.GetNumDimensions()) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Input tensor dimension and output tensor dimension differ", "Operator: #%d node #%d: ", tileOperatorCode, nodeIndex); return kTfLiteError; } // No network pointer indicates that only support for this operator should be checked if (!delegateData.m_Network) { return ValidateTileOperator(delegateData, tfLiteContext, inputTensorInfo, outputTensorInfo, tileDescriptor); } auto layerName = GetName(armnn::LayerType::Tile, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddTileLayer(tileDescriptor, layerName.c_str()); if (layer == nullptr) { return kTfLiteError; } layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); if (ProcessInputs(layer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(layer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Transpose.hpp000066400000000000000000000115061446772241200211770ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitTransposeOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t tfliteTransposeOperatorCode) { TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 2, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); // Gather input indices and use to get input tensor. const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor0 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor0, tfliteTransposeOperatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor1 = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[1]); if (!IsValid(tfLiteContext, tfLiteInputTensor1, tfliteTransposeOperatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, tfliteTransposeOperatorCode, nodeIndex)) { return kTfLiteError; } const armnn::TensorInfo& inputTensorInfo0 = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor0); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); auto* permTensorDataPtr = static_cast(TfLiteOpaqueTensorData(tfLiteInputTensor1)); unsigned int numEl = TfLiteOpaqueTensorDim(tfLiteInputTensor1, 0); if ( numEl > static_cast(armnn::MaxNumOfTensorDimensions) ) { return kTfLiteError; } // Ensure only single dimension to the permutation tensor if ( TfLiteOpaqueTensorNumDims(tfLiteInputTensor1) != 1 ) { return kTfLiteError; } armnn::TransposeDescriptor descriptor(armnn::PermutationVector( reinterpret_cast (permTensorDataPtr), static_cast(numEl))); bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputTensorInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("TRANSPOSE", tfLiteContext, IsTransposeSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo0, outputTensorInfo, descriptor); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::Transpose, nodeIndex); armnn::IConnectableLayer* transposeLayer = delegateData.m_Network->AddTransposeLayer(descriptor, layerName.c_str()); transposeLayer->SetBackendId(setBackend); ARMNN_ASSERT(transposeLayer != nullptr); // Permutation vector given to descriptor object if (transposeLayer->GetNumInputSlots() != 1) { return kTfLiteError; } armnn::IOutputSlot& outputSlot = transposeLayer->GetOutputSlot(0); outputSlot.SetTensorInfo(outputTensorInfo); // try to connect the Constant Inputs if there are any if (ProcessInputs(transposeLayer, delegateData, tfLiteContext, tfLiteNode, nodeIndex) != kTfLiteOk) { return kTfLiteError; } return Connect(transposeLayer, tfLiteContext, tfLiteNode, delegateData); } } // namespace armnnOpaqueDelegate armnn-23.08/delegate/opaque/src/UnidirectionalSequenceLstm.hpp000066400000000000000000000375141446772241200245320ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitUnidirectionalSequenceLstmOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { auto numInputs = TfLiteOpaqueNodeNumberOfInputs(tfLiteNode); if (numInputs < 2) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Minimum number of inputs (%d != %d) in node #%d", 2, numInputs, nodeIndex); return kTfLiteError; } // Gather input indices and use to get input tensor. const int* inputTensors; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Gather output indices and use to get output tensors. int numOutputs = 0; const int* outputTensors; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[0]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } // Set the params structure for the AddUnidirectionalSequenceLstmLayer call // Please refer to each operand at // https://www.tensorflow.org/mlir/tfl_ops#tflunidirectional_sequence_lstm_tflunidirectionalsequencelstmop armnn::LstmInputParams params; if (IsOptionalOperandPresent(tfLiteNode, 1)) { params.m_InputToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 1); } params.m_InputToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 2); params.m_InputToCellWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 3); params.m_InputToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 4); // Recurrent weight tensors of size {n_cell, n_output} if (IsOptionalOperandPresent(tfLiteNode, 5)) { params.m_RecurrentToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 5); } params.m_RecurrentToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 6); params.m_RecurrentToCellWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 7); params.m_RecurrentToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 8); // Peephole weights tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 9)) { params.m_CellToInputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 9); } if (IsOptionalOperandPresent(tfLiteNode, 10)) { params.m_CellToForgetWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 10); } if (IsOptionalOperandPresent(tfLiteNode, 11)) { params.m_CellToOutputWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 11); } // Gates bias tensors of size {n_cell} if (IsOptionalOperandPresent(tfLiteNode, 12)) { params.m_InputGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 12); } params.m_ForgetGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 13); params.m_CellBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 14); params.m_OutputGateBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 15); // Projection weight tensor of size {n_output, n_cell} if (IsOptionalOperandPresent(tfLiteNode, 16)) { params.m_ProjectionWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 16); } // Projection bias tensor of size {n_output} if (IsOptionalOperandPresent(tfLiteNode, 17)) { params.m_ProjectionBias = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 17); } // These state tensors are defined as variable tensors, and will be modified by this op. const TfLiteOpaqueTensor* tfLiteOutputStateIn = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[18]); if (!IsValid(tfLiteContext, tfLiteOutputStateIn, operatorCode, nodeIndex)) { return kTfLiteError; } const TfLiteOpaqueTensor* cellStateIn = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[19]); if (!IsValid(tfLiteContext, cellStateIn, operatorCode, nodeIndex)) { return kTfLiteError; } armnn::TensorInfo outputStateInInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputStateIn); armnn::TensorInfo cellStateInInfo = GetTensorInfoForTfLiteOpaqueTensor(cellStateIn); // Layer norm coefficient tensors of size {n_cell}, representing a diagonal matrix. if (IsOptionalOperandPresent(tfLiteNode, 20)) { params.m_InputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 20); } if (IsOptionalOperandPresent(tfLiteNode, 21)) { params.m_ForgetLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 21); } if (IsOptionalOperandPresent(tfLiteNode, 22)) { params.m_CellLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 22); } if (IsOptionalOperandPresent(tfLiteNode, 23)) { params.m_OutputLayerNormWeights = GetConstTensorForTfLiteTensor(tfLiteContext, tfLiteNode, 23); } const auto nodeParams = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); // set the layer descriptor armnn::UnidirectionalSequenceLstmDescriptor desc; desc.m_ActivationFunc = NonNegative(nodeParams->activation, nodeIndex); desc.m_ClippingThresCell = nodeParams->cell_clip; desc.m_ClippingThresProj = nodeParams->proj_clip; desc.m_CifgEnabled = (params.m_InputToInputWeights == nullptr || params.m_RecurrentToInputWeights == nullptr || params.m_InputGateBias == nullptr); desc.m_PeepholeEnabled = (params.m_CellToForgetWeights != nullptr || params.m_CellToOutputWeights != nullptr); desc.m_ProjectionEnabled = (params.m_ProjectionWeights != nullptr); desc.m_LayerNormEnabled = (params.m_InputLayerNormWeights != nullptr || params.m_ForgetLayerNormWeights != nullptr || params.m_CellLayerNormWeights != nullptr || params.m_OutputLayerNormWeights != nullptr); desc.m_TimeMajor = nodeParams->time_major; // Intermediates tensors aren't accessible through the new Opaque Interface yet, so we have to cast it for now. // This should be changed to use the accessor functions once added. auto* classicTfliteNode = reinterpret_cast(tfLiteNode); if (classicTfliteNode->intermediates->size > 3 && desc.m_LayerNormEnabled) { auto inputIntermediateTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, classicTfliteNode->intermediates->data[0])); auto forgetIntermediateTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, classicTfliteNode->intermediates->data[1])); auto cellIntermediateTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, classicTfliteNode->intermediates->data[2])); auto outputIntermediateTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, classicTfliteNode->intermediates->data[3])); desc.m_InputIntermediateScale = inputIntermediateTensorInfo.GetQuantizationScale(); desc.m_ForgetIntermediateScale = forgetIntermediateTensorInfo.GetQuantizationScale(); desc.m_CellIntermediateScale = cellIntermediateTensorInfo.GetQuantizationScale(); desc.m_OutputIntermediateScale = outputIntermediateTensorInfo.GetQuantizationScale(); } else { float defaultIntermediate = std::pow(2, -12); desc.m_InputIntermediateScale = defaultIntermediate; desc.m_ForgetIntermediateScale = defaultIntermediate; desc.m_CellIntermediateScale = defaultIntermediate; desc.m_OutputIntermediateScale = defaultIntermediate; } if (classicTfliteNode->intermediates->size > 4) { auto hiddenTensorInfo = GetTensorInfoForTfLiteOpaqueTensor( TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, classicTfliteNode->intermediates->data[4])); desc.m_HiddenStateScale = hiddenTensorInfo.GetQuantizationScale(); desc.m_HiddenStateZeroPoint = hiddenTensorInfo.GetQuantizationOffset(); } float defaultIntermediate = std::pow(2, -12); desc.m_InputIntermediateScale = defaultIntermediate; desc.m_ForgetIntermediateScale = defaultIntermediate; desc.m_CellIntermediateScale = defaultIntermediate; desc.m_OutputIntermediateScale = defaultIntermediate; const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); const armnn::TensorInfo& outputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true); unsigned int batchSize = inputTensorInfo.GetShape()[0]; unsigned int outputSize = outputTensorInfo.GetShape()[2]; unsigned int numUnits = cellStateInInfo.GetShape()[1]; armnn::DataType dataType = inputTensorInfo.GetDataType(); float qScale = inputTensorInfo.GetQuantizationScale(); float qOffset = inputTensorInfo.GetQuantizationOffset(); armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 3}, dataType, qScale, qOffset); if (!desc.m_CifgEnabled) { scratchBufferTensorInfo = armnn::TensorInfo({batchSize, numUnits * 4}, dataType, qScale, qOffset); } armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits}, cellStateInInfo.GetDataType(), cellStateInInfo.GetQuantizationScale(), cellStateInInfo.GetQuantizationOffset()); armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, dataType, qScale, qOffset); armnn::LstmInputParamsInfo paramsInfo; paramsInfo.m_InputToForgetWeights = &(params.m_InputToForgetWeights->GetInfo()); paramsInfo.m_InputToCellWeights = &(params.m_InputToCellWeights->GetInfo()); paramsInfo.m_InputToOutputWeights = &(params.m_InputToOutputWeights->GetInfo()); paramsInfo.m_RecurrentToForgetWeights = &(params.m_RecurrentToForgetWeights->GetInfo()); paramsInfo.m_RecurrentToCellWeights = &(params.m_RecurrentToCellWeights->GetInfo()); paramsInfo.m_RecurrentToOutputWeights = &(params.m_RecurrentToOutputWeights->GetInfo()); paramsInfo.m_ForgetGateBias = &(params.m_ForgetGateBias->GetInfo()); paramsInfo.m_CellBias = &(params.m_CellBias->GetInfo()); paramsInfo.m_OutputGateBias = &(params.m_OutputGateBias->GetInfo()); if (!desc.m_CifgEnabled) { paramsInfo.m_InputToInputWeights = &(params.m_InputToInputWeights->GetInfo()); paramsInfo.m_RecurrentToInputWeights = &(params.m_RecurrentToInputWeights->GetInfo()); if (params.m_CellToInputWeights != nullptr) { paramsInfo.m_CellToInputWeights = &(params.m_CellToInputWeights->GetInfo()); } paramsInfo.m_InputGateBias = &(params.m_InputGateBias->GetInfo()); } if (desc.m_ProjectionEnabled) { paramsInfo.m_ProjectionWeights = &(params.m_ProjectionWeights->GetInfo()); if (params.m_ProjectionBias != nullptr) { paramsInfo.m_ProjectionBias = &(params.m_ProjectionBias->GetInfo()); } } if (desc.m_PeepholeEnabled) { paramsInfo.m_CellToForgetWeights = &(params.m_CellToForgetWeights->GetInfo()); paramsInfo.m_CellToOutputWeights = &(params.m_CellToOutputWeights->GetInfo()); } if (desc.m_LayerNormEnabled) { if(!desc.m_CifgEnabled) { paramsInfo.m_InputLayerNormWeights = &(params.m_InputLayerNormWeights->GetInfo()); } paramsInfo.m_ForgetLayerNormWeights = &(params.m_ForgetLayerNormWeights->GetInfo()); paramsInfo.m_CellLayerNormWeights = &(params.m_CellLayerNormWeights->GetInfo()); paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo()); } bool isSupported = false; armnn::BackendId setBackend; auto validateFunc = [&](const armnn::TensorInfo& outputInfo, bool& isSupported) { FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("UNIDIRECTIONAL_SEQUENCE_LSTM", tfLiteContext, IsUnidirectionalSequenceLstmSupported, delegateData.m_Backends, isSupported, setBackend, inputTensorInfo, outputStateInInfo, cellStateInInfo, outputStateOutTensorInfo, cellStateOutTensorInfo, outputInfo, desc, paramsInfo); }; if (!delegateData.m_Network) { validateFunc(outputTensorInfo, isSupported); return isSupported ? kTfLiteOk : kTfLiteError; } auto layerName = GetName(armnn::LayerType::UnidirectionalSequenceLstm, nodeIndex); armnn::IConnectableLayer* layer = delegateData.m_Network->AddUnidirectionalSequenceLstmLayer(desc, params, layerName.c_str()); layer->SetBackendId(setBackend); ARMNN_ASSERT(layer != nullptr); layer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo); layer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo); layer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo); // Connect the inputs // input_layer delegateData.m_OutputSlotForNode[inputTensors[0]]->Connect(layer->GetInputSlot(0)); // cellStateIn delegateData.m_OutputSlotForNode[inputTensors[18]]->Connect(layer->GetInputSlot(1)); //outputStateIn delegateData.m_OutputSlotForNode[inputTensors[19]]->Connect(layer->GetInputSlot(2)); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(2); delegateData.m_OutputSlotForNode[static_cast(outputTensors[0])] = &outputSlot; return kTfLiteOk; } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/Unpack.hpp000066400000000000000000000234241446772241200204440ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include namespace armnnOpaqueDelegate { TfLiteStatus VisitUnpackOperator(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode, int nodeIndex, int32_t operatorCode) { // Check inputs TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); const int* inputTensors; int numInputs; if (TfLiteOpaqueNodeInputs(tfLiteNode, &inputTensors, &numInputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather input tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } const TfLiteOpaqueTensor* tfLiteInputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputTensors[0]); if (!IsValid(tfLiteContext, tfLiteInputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } auto* tfLiteNodeParameters = reinterpret_cast(TfLiteOpaqueNodeGetBuiltinData(tfLiteNode)); const armnn::TensorInfo& inputTensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tfLiteInputTensor); // Get Unpack Axis const unsigned int unpackAxis = NonNegative(tfLiteNodeParameters->axis, nodeIndex); if (unpackAxis >= inputTensorInfo.GetNumDimensions()) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: The unpack axis #%d cannot be greater than or equal to " "the number of input dimensions #%d in operator #%d node #%d", unpackAxis, inputTensorInfo.GetNumDimensions(), operatorCode, nodeIndex); return kTfLiteError; } // Get Unpack Num unsigned int unpackNum = NonNegative(tfLiteNodeParameters->num, nodeIndex); // If num is not defined, automatically infer from the length of the dimension axis. if(unpackNum == 0) { unpackNum = inputTensorInfo.GetShape()[unpackAxis]; } // If unpack number cannot be inferred and is still zero, return kTfLiteError. if(unpackNum == 0) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Number to unpack must greater than zero in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } // Check outputs TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, unpackNum, nodeIndex)); auto inputDimSize = inputTensorInfo.GetNumDimensions(); std::vector unpackDimSizes(inputDimSize); // Add current input shape to unpackDimSizes for (unsigned int i = 0; i < inputDimSize; ++i) { unpackDimSizes[i] = inputTensorInfo.GetShape()[i]; } if (unpackDimSizes[unpackAxis] != unpackNum) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Number to unpack must be the same as length " "of the dimension to unpack along in operator #%d node #%d: ", operatorCode, nodeIndex); return kTfLiteError; } unpackDimSizes[unpackAxis] /= unpackNum; armnn::SplitterDescriptor splitDesc(unpackNum, static_cast(unpackDimSizes.size())); for (unsigned int j = 0; j < unpackNum; ++j) { // Set the size of the views. for (unsigned int dimIdx = 0; dimIdx < unpackDimSizes.size(); ++dimIdx) { splitDesc.SetViewSize(j, dimIdx, unpackDimSizes[dimIdx]); } splitDesc.SetViewOriginCoord(j, unpackAxis, unpackDimSizes[unpackAxis] * j); } // Gather output indices and use to get output tensors. const int* outputTensors; int numOutputs; if (TfLiteOpaqueNodeOutputs(tfLiteNode, &outputTensors, &numOutputs) != kTfLiteOk) { TF_LITE_OPAQUE_MAYBE_KERNEL_LOG( tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to gather output tensor indices from node #%d: ", nodeIndex); return kTfLiteError; } // Validate all outputs and get TensorInfo std::vector outputs; for (unsigned int i = 0; i < unpackNum; ++i) { const TfLiteOpaqueTensor* tfLiteOutputTensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputTensors[i]); if (!IsValid(tfLiteContext, tfLiteOutputTensor, operatorCode, nodeIndex)) { return kTfLiteError; } outputs.push_back(GetTensorInfoForTfLiteOpaqueTensor(tfLiteOutputTensor, true)); } const std::vector> outputTensorInfos(outputs.begin(), outputs.end()); // Determine the shape of the Splitter layer outputs for validation armnn::TensorShape splitOutShape = armnn::TensorShape(static_cast(unpackDimSizes.size()), unpackDimSizes.data()); std::vector splitterOutputs; for (unsigned int outputIndex = 0; outputIndex < outputTensorInfos.size(); ++outputIndex) { splitterOutputs.push_back(armnn::TensorInfo(splitOutShape, outputTensorInfos[outputIndex].get().GetDataType(), outputTensorInfos[outputIndex].get().GetQuantizationScale(), outputTensorInfos[outputIndex].get().GetQuantizationOffset())); } std::vector> splitterOutputTensorInfos(splitterOutputs.begin(), splitterOutputs.end()); armnn::BackendId setBackendSplit; if (!delegateData.m_Network) { // Check if splitter is supported bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("UNPACK", tfLiteContext, IsSplitterSupported, delegateData.m_Backends, isSupported, setBackendSplit, inputTensorInfo, splitterOutputTensorInfos, splitDesc); return isSupported ? kTfLiteOk : kTfLiteError; } // Create Reshape descriptor from the first outputTensorInfo to validate a single Reshape layer // Use this descriptor later when creating every ReshapeLayer as all Reshape Layers should be the same armnn::ReshapeDescriptor reshapeDescriptor; reshapeDescriptor.m_TargetShape = outputTensorInfos[0].get().GetShape(); armnn::BackendId setBackendReshape; if (!delegateData.m_Network) { bool isSupported = false; FORWARD_LAYER_OPAQUE_SUPPORT_FUNC("RESHAPE", tfLiteContext, IsReshapeSupported, delegateData.m_Backends, isSupported, setBackendReshape, splitterOutputTensorInfos[0], outputTensorInfos[0], reshapeDescriptor); return isSupported ? kTfLiteOk : kTfLiteError; }; auto layerName = GetName(armnn::LayerType::Splitter, nodeIndex, "Unpack"); armnn::IConnectableLayer* splitterLayer = delegateData.m_Network->AddSplitterLayer(splitDesc, layerName.c_str()); splitterLayer->SetBackendId(setBackendSplit); ARMNN_ASSERT(splitterLayer != nullptr); for (unsigned int k = 0; k < splitterLayer->GetNumOutputSlots(); ++k) { splitterLayer->GetOutputSlot(k).SetTensorInfo(outputs[k]); } // Connect the input slots auto inputIndex = static_cast(inputTensors[0]); delegateData.m_OutputSlotForNode[inputIndex]->Connect(splitterLayer->GetInputSlot(0)); // Create reshape to remove the unpacked dimension for unpack operator of each output from Splitter. for (unsigned int outputIndex = 0; outputIndex < splitterLayer->GetNumOutputSlots(); ++outputIndex) { auto reshapeLayerName = GetName(armnn::LayerType::Reshape, nodeIndex, "Unpack"); armnn::IConnectableLayer* reshapeLayer = delegateData.m_Network->AddReshapeLayer(reshapeDescriptor, reshapeLayerName.c_str()); reshapeLayer->SetBackendId(setBackendReshape); ARMNN_ASSERT(reshapeLayer != nullptr); splitterLayer->GetOutputSlot(outputIndex).SetTensorInfo(splitterOutputTensorInfos[outputIndex]); splitterLayer->GetOutputSlot(outputIndex).Connect(reshapeLayer->GetInputSlot(0)); armnn::TensorInfo outputTensorInfo = outputTensorInfos[outputIndex]; reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo); armnn::IOutputSlot& slot = reshapeLayer->GetOutputSlot(0); delegateData.m_OutputSlotForNode[ static_cast(static_cast(outputTensors[outputIndex]))] = &slot; } return kTfLiteOk; } } // namespace armnnOpaqueDelegatearmnn-23.08/delegate/opaque/src/armnn_delegate.cpp000066400000000000000000001553631446772241200221730ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include "Activation.hpp" #include "ArgMinMax.hpp" #include "BatchMatMul.hpp" #include "BatchSpace.hpp" #include "Comparison.hpp" #include "Convolution.hpp" #include "Control.hpp" #include "ElementwiseBinary.hpp" #include "ElementwiseUnary.hpp" #include "Fill.hpp" #include "FullyConnected.hpp" #include "Gather.hpp" #include "GatherNd.hpp" #include "LogicalBinary.hpp" #include "Lstm.hpp" #include "Normalization.hpp" #include "Pack.hpp" #include "Pad.hpp" #include "Pooling.hpp" #include "Prelu.hpp" #include "Quantization.hpp" #include "Redefine.hpp" #include "Reduce.hpp" #include "Resize.hpp" #include "ReverseV2.hpp" #include "Round.hpp" #include "Shape.hpp" #include "Slice.hpp" #include "StridedSlice.hpp" #include "Softmax.hpp" #include "SpaceDepth.hpp" #include "Split.hpp" #include "Tile.hpp" #include "Transpose.hpp" #include "UnidirectionalSequenceLstm.hpp" #include "Unpack.hpp" #include #include #include #include #include #include #include #include #include #include namespace armnnOpaqueDelegate { static auto* g_delegate_plugin_ArmnnDelegatePlugin_ = new tflite::delegates::DelegatePluginRegistry::Register("armnn_delegate", ArmnnDelegatePlugin::New); ArmnnOpaqueDelegate::ArmnnOpaqueDelegate(armnnDelegate::DelegateOptions options) : m_Options(std::move(options)) { // Configures logging for ARMNN if (m_Options.IsLoggingEnabled()) { armnn::ConfigureLogging(true, true, m_Options.GetLoggingSeverity()); } // Create/Get the static ArmNN Runtime. Note that the m_Runtime will be shared by all armnn_delegate // instances so the RuntimeOptions cannot be altered for different armnn_delegate instances. m_Runtime = GetRuntime(m_Options.GetRuntimeOptions()); std::vector backends; if (m_Runtime) { const armnn::BackendIdSet supportedDevices = m_Runtime->GetDeviceSpec().GetSupportedBackends(); for (auto& backend : m_Options.GetBackends()) { if (std::find(supportedDevices.cbegin(), supportedDevices.cend(), backend) == supportedDevices.cend()) { TFLITE_LOG_PROD(tflite::TFLITE_LOG_INFO, "TfLiteArmnnOpaqueDelegate: Requested unknown backend %s", backend.Get().c_str()); } else { backends.push_back(backend); } } } if (backends.empty()) { // No known backend specified throw armnn::InvalidArgumentException("TfLiteArmnnOpaqueDelegate: No known backend specified."); } m_Options.SetBackends(backends); TFLITE_LOG_PROD_ONCE(tflite::TFLITE_LOG_INFO, "TfLiteArmnnOpaqueDelegate: Created TfLite ArmNN delegate."); } TfLiteStatus DoPrepare(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueDelegate* tfLiteDelegate, void* data) { // We are required to have the void* data parameter in the function signature, but we don't actually use it. armnn::IgnoreUnused(data); TfLiteIntArray* supportedOperators = static_cast<::armnnOpaqueDelegate::ArmnnOpaqueDelegate*> (TfLiteOpaqueDelegateGetData(tfLiteDelegate))->IdentifyOperatorsToDelegate(tfLiteContext); if(supportedOperators == nullptr) { return kTfLiteError; } // ArmNN Opaque Delegate Registration TfLiteRegistrationExternal* kernelRegistration = TfLiteRegistrationExternalCreate(kTfLiteBuiltinDelegate, "armnn_delegate", /*version=*/OPAQUE_DELEGATE_MAJOR_VERSION); if(kernelRegistration == nullptr) { return kTfLiteError; } TfLiteRegistrationExternalSetInit( kernelRegistration, [](TfLiteOpaqueContext* tfLiteContext, const char* buffer, size_t length) -> void* { armnn::IgnoreUnused(length); const TfLiteOpaqueDelegateParams* parameters = reinterpret_cast(buffer); if(parameters == nullptr) { TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to get parameters."); return nullptr; } return static_cast( ArmnnSubgraph::Create(tfLiteContext, parameters, static_cast<::armnnOpaqueDelegate::ArmnnOpaqueDelegate*>( parameters->delegate->opaque_delegate_builder->data))); } ); TfLiteRegistrationExternalSetFree( kernelRegistration, [](TfLiteOpaqueContext* tfLiteContext, void* buffer) -> void { armnn::IgnoreUnused(tfLiteContext); if (buffer != nullptr) { delete static_cast(buffer); } } ); TfLiteRegistrationExternalSetPrepare( kernelRegistration, [](TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode) -> TfLiteStatus { void* userData = TfLiteOpaqueNodeGetUserData(tfLiteNode); if (userData == nullptr) { return kTfLiteError; } return static_cast(userData)->Prepare(tfLiteContext); } ); TfLiteRegistrationExternalSetInvoke( kernelRegistration, [](TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode) -> TfLiteStatus { void* userData = TfLiteOpaqueNodeGetUserData(tfLiteNode); if (userData == nullptr) { return kTfLiteError; } return static_cast(userData)->Invoke(tfLiteContext, tfLiteNode); } ); const TfLiteStatus status = TfLiteOpaqueContextReplaceNodeSubsetsWithDelegateKernels( tfLiteContext, kernelRegistration, supportedOperators, tfLiteDelegate); TfLiteIntArrayFree(supportedOperators); return status; } TfLiteOpaqueDelegate* TfLiteArmnnOpaqueDelegateCreate(const void* settings) { // This method will always create Opaque Delegate with default settings until // we have a DelegateOptions Constructor which can parse the void* settings armnn::IgnoreUnused(settings); auto options = TfLiteArmnnDelegateOptionsDefault(); auto* armnnDelegate = new ::armnnOpaqueDelegate::ArmnnOpaqueDelegate(options); return TfLiteOpaqueDelegateCreate(armnnDelegate->GetDelegateBuilder()); } ::armnnDelegate::DelegateOptions TfLiteArmnnDelegateOptionsDefault() { ::armnnDelegate::DelegateOptions options(armnn::Compute::CpuRef); return options; } void TfLiteArmnnOpaqueDelegateDelete(TfLiteOpaqueDelegate* tfLiteDelegate) { if (tfLiteDelegate != nullptr) { delete static_cast<::armnnOpaqueDelegate::ArmnnOpaqueDelegate*>(TfLiteOpaqueDelegateGetData(tfLiteDelegate)); TfLiteOpaqueDelegateDelete(tfLiteDelegate); } } const std::string ArmnnOpaqueDelegate::GetVersion() { return OPAQUE_DELEGATE_VERSION; } TfLiteIntArray* ArmnnOpaqueDelegate::IdentifyOperatorsToDelegate(TfLiteOpaqueContext* tfLiteContext) { TfLiteIntArray* executionPlan = nullptr; if (TfLiteOpaqueContextGetExecutionPlan(tfLiteContext, &executionPlan) != kTfLiteOk) { TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to get graph execution plan."); return nullptr; } // Delegate data with null network DelegateData delegateData(m_Options.GetBackends()); TfLiteIntArray* nodesToDelegate = TfLiteIntArrayCreate(executionPlan->size); if (nodesToDelegate == nullptr) { TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to create int array from execution plan."); return nullptr; } nodesToDelegate->size = 0; std::set unsupportedOperators; for (int i = 0; i < executionPlan->size; ++i) { const int nodeIndex = executionPlan->data[i]; // If TfLiteOpaqueNodes can be delegated to ArmNN TfLiteOpaqueNode* tfLiteNode = nullptr; TfLiteRegistrationExternal* tfLiteRegistration = nullptr; if (TfLiteOpaqueContextGetNodeAndRegistration( tfLiteContext, nodeIndex, &tfLiteNode, &tfLiteRegistration) != kTfLiteOk) { TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "TfLiteArmnnOpaqueDelegate: Unable to get node and registration for node %d.", nodeIndex); continue; } TfLiteStatus visitStatus; try { visitStatus = ArmnnSubgraph::VisitNode( delegateData, tfLiteContext, tfLiteRegistration, tfLiteNode, nodeIndex); } catch(std::exception& ex) { ARMNN_LOG(error) << "ArmNN Failed to visit node with error: " << ex.what(); visitStatus = kTfLiteError; } if (visitStatus != kTfLiteOk) { // node is not supported by ArmNN unsupportedOperators.insert(TfLiteRegistrationExternalGetBuiltInCode(tfLiteRegistration)); continue; } nodesToDelegate->data[nodesToDelegate->size++] = nodeIndex; } for (std::set::iterator it=unsupportedOperators.begin(); it!=unsupportedOperators.end(); ++it) { TF_LITE_OPAQUE_KERNEL_LOG(tfLiteContext, "Operator %s [%d] is not supported by armnn_opaque_delegate.", tflite::EnumNameBuiltinOperator(tflite::BuiltinOperator(*it)), *it); } if (!unsupportedOperators.empty() && m_Options.TfLiteRuntimeFallbackDisabled()) { std::stringstream exMessage; exMessage << "TfLiteArmnnOpaqueDelegate: There are unsupported operators in the model. "; exMessage << "Not falling back to TfLite Runtime as fallback is disabled. "; exMessage << "This should only be disabled under test conditions."; throw armnn::Exception(exMessage.str()); } if (nodesToDelegate->size == 0) { ARMNN_LOG(info) << "No operators in this model are supported by the Arm NN TfLite delegate." << " The model will be executed entirely by TfLite runtime."; } std::sort(&nodesToDelegate->data[0], &nodesToDelegate->data[nodesToDelegate->size]); return nodesToDelegate; } TfLiteStatus ArmnnSubgraph::AddInputLayer(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const TfLiteIntArray* inputs, std::vector& inputBindings) { const size_t numInputs = static_cast(inputs->size); for (unsigned int i = 0; i < numInputs; ++i) { const int32_t tensorId = inputs->data[i]; const TfLiteOpaqueTensor* tensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, tensorId); if(!tensor) { return kTfLiteError; } // Do not create bindings for constant inputs if (TfLiteOpaqueTensorGetAllocationType(tensor) == kTfLiteMmapRo) { continue; } auto bindingId = static_cast((tensorId)); armnn::IConnectableLayer* layer = delegateData.m_Network->AddInputLayer(bindingId); auto tensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tensor); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); outputSlot.SetTensorInfo(tensorInfo); // Store for creating connections delegateData.m_OutputSlotForNode[static_cast(tensorId)] = &outputSlot; inputBindings.push_back(std::make_pair(bindingId, tensorInfo)); } return kTfLiteOk; } TfLiteStatus ArmnnSubgraph::AddOutputLayer(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, const TfLiteIntArray* outputs, std::vector& outputBindings) { const size_t numOutputs = static_cast(outputs->size); for (unsigned int i = 0; i < numOutputs; ++i) { const int32_t tensorId = outputs->data[i]; const TfLiteOpaqueTensor* tensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, tensorId); if(!IsValid(tensor)) { return kTfLiteError; } auto bindingId = static_cast((tensorId)); armnn::IConnectableLayer* layer = delegateData.m_Network->AddOutputLayer(bindingId); auto tensorInfo = GetTensorInfoForTfLiteOpaqueTensor(tensor); if (delegateData.m_OutputSlotForNode[static_cast(tensorId)] == nullptr) { return kTfLiteError; } delegateData.m_OutputSlotForNode[static_cast(tensorId)]->Connect(layer->GetInputSlot(0)); outputBindings.push_back(std::make_pair(bindingId, tensorInfo)); } return kTfLiteOk; } ArmnnSubgraph* ArmnnSubgraph::Create(TfLiteOpaqueContext* tfLiteContext, const TfLiteOpaqueDelegateParams* parameters, const ArmnnOpaqueDelegate* delegate) { const auto startTime = armnn::GetTimeNow(); ARMNN_LOG(info) << "ArmnnSubgraph creation"; TfLiteIntArray* executionPlan; if (TfLiteOpaqueContextGetExecutionPlan(tfLiteContext, &executionPlan) != kTfLiteOk) { return nullptr; } // Initialize DelegateData holds network and output slots information DelegateData delegateData(delegate->m_Options.GetBackends()); // Build ArmNN Network armnn::NetworkOptions networkOptions = delegate->m_Options.GetOptimizerOptions().GetModelOptions(); armnn::NetworkId networkId; delegateData.m_Network = armnn::INetwork::Create(networkOptions); delegateData.m_OutputSlotForNode = std::vector( TfLiteOpaqueContextGetNumTensors(tfLiteContext), nullptr); std::vector inputBindings; std::vector outputBindings; // Add input layer if (AddInputLayer(delegateData, tfLiteContext, parameters->input_tensors, inputBindings) != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to add Inputs to the network!"); } // Parse TfLite delegate nodes to ArmNN const auto parseStartTime = armnn::GetTimeNow(); for (int i = 0; i < parameters->nodes_to_replace->size; ++i) { const int nodeIndex = parameters->nodes_to_replace->data[i]; TfLiteOpaqueNode* tfLiteNode = nullptr; TfLiteRegistrationExternal* tfLiteRegistration = nullptr; if (TfLiteOpaqueContextGetNodeAndRegistration( tfLiteContext, nodeIndex, &tfLiteNode, &tfLiteRegistration) != kTfLiteOk) { throw armnn::Exception(&"TfLiteArmnnOpaqueDelegate: Unable to get node registration: " [ nodeIndex]); } if (VisitNode(delegateData, tfLiteContext, tfLiteRegistration, tfLiteNode, nodeIndex) != kTfLiteOk) { throw armnn::Exception(&"TfLiteArmnnOpaqueDelegate: Unable to parse node: " [ nodeIndex]); } } ARMNN_LOG(info) << "Parse nodes to ArmNN time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(parseStartTime).count() << " ms"; // Add Output layer if (AddOutputLayer(delegateData, tfLiteContext, parameters->output_tensors, outputBindings) != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to add Outputs to the network!"); } // Optimize ArmNN network armnn::IOptimizedNetworkPtr optNet(nullptr, nullptr); try { const auto optimizeStartTime = armnn::GetTimeNow(); optNet = armnn::Optimize(*(delegateData.m_Network.get()), delegate->m_Options.GetBackends(), delegate->m_Runtime->GetDeviceSpec(), delegate->m_Options.GetOptimizerOptions()); ARMNN_LOG(info) << "Optimize ArmnnSubgraph time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(optimizeStartTime).count() << " ms"; } catch (std::exception& ex) { std::stringstream exMessage; exMessage << "TfLiteArmnnOpaqueDelegate: Exception (" << ex.what() << ") caught from optimize."; throw armnn::Exception(exMessage.str()); } if (!optNet) { // Optimize failed throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to optimize the network!"); } // If set, we will serialize the optimized model into a dot file. const std::string serializeToDotFile = delegate->m_Options.GetSerializeToDot(); if (!serializeToDotFile.empty()) { ARMNN_LOG(info) << "Writing graph to dot file: " << serializeToDotFile; fs::path filename = serializeToDotFile; std::fstream file(filename.c_str(), std::ios_base::out); optNet->SerializeToDot(file); } try { const auto loadStartTime = armnn::GetTimeNow(); // Load graph into runtime std::string errorMessage; armnn::Status loadingStatus; armnn::MemorySource inputSource = armnn::MemorySource::Undefined; armnn::MemorySource outputSource = armnn::MemorySource::Undefined; // There's a bit of an assumption here that the delegate will only support Malloc memory source. if (delegate->m_Options.GetOptimizerOptions().GetImportEnabled()) { inputSource = armnn::MemorySource::Malloc; } if (delegate->m_Options.GetOptimizerOptions().GetExportEnabled()) { outputSource = armnn::MemorySource::Malloc; } armnn::INetworkProperties networkProperties(false, inputSource, outputSource, delegate->m_Options.GetInternalProfilingState(), delegate->m_Options.GetInternalProfilingDetail()); loadingStatus = delegate->m_Runtime->LoadNetwork(networkId, std::move(optNet), errorMessage, networkProperties); if (loadingStatus != armnn::Status::Success) { // Network load failed. throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Network could not be loaded: " + errorMessage); } ARMNN_LOG(info) << "Load ArmnnSubgraph time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(loadStartTime).count() << " ms"; } catch (std::exception& ex) { std::stringstream exMessage; exMessage << "TfLiteArmnnOpaqueDelegate: Exception (" << ex.what() << ") caught from LoadNetwork."; throw armnn::Exception(exMessage.str()); } // Register debug callback function if (delegate->m_Options.GetDebugCallbackFunction().has_value()) { delegate->m_Runtime->RegisterDebugCallback(networkId, delegate->m_Options.GetDebugCallbackFunction().value()); } ARMNN_LOG(info) << "Overall ArmnnSubgraph creation time: " << std::setprecision(2) << std::fixed << armnn::GetTimeDuration(startTime).count() << " ms\n"; // Create a new SubGraph with networkId and runtime return new ArmnnSubgraph(networkId, delegate->m_Runtime, inputBindings, outputBindings); } TfLiteStatus ArmnnSubgraph::Prepare(TfLiteOpaqueContext* tfLiteContext) { armnn::IgnoreUnused(tfLiteContext); return kTfLiteOk; } TfLiteStatus ArmnnSubgraph::Invoke(TfLiteOpaqueContext* tfLiteContext, TfLiteOpaqueNode* tfLiteNode) { // Get array of input indices, inputIndexArray is set from the TfLiteOpaqueNodeInputs function // This function turns inputIndexArray into an int array of indices. These indices point to the tensors for // each input slot in the node. const int* inputIndexArray; int numInputs; if(TfLiteOpaqueNodeInputs(tfLiteNode, &inputIndexArray, &numInputs) != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to load subgraph inputs!"); } // Prepare inputs armnn::InputTensors inputTensors; size_t inputIndex = 0; for (int inputIdx = 0; inputIdx < numInputs; inputIdx++) { TfLiteOpaqueTensor* tensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, inputIndexArray[inputIdx]); if(!IsValid(tensor)) { return kTfLiteError; } // If tensor is not read only if (TfLiteOpaqueTensorGetAllocationType(tensor) != kTfLiteMmapRo) { const armnn::BindingPointInfo& inputBinding = m_InputBindings[inputIndex]; armnn::TensorInfo inputTensorInfo = inputBinding.second; inputTensorInfo.SetConstant(true); const armnn::ConstTensor inputTensor(inputTensorInfo, TfLiteOpaqueTensorData(tensor)); inputTensors.emplace_back(inputIndexArray[inputIdx], inputTensor); ++inputIndex; } } // Get array of output indices, outputIndexArray is set from the TfLiteOpaqueNodeOutputs function // This function turns outputIndexArray into an int array of indices. These indices point to the tensors for // each output slot in the node. const int* outputIndexArray; int numOutputs; if(TfLiteOpaqueNodeOutputs(tfLiteNode, &outputIndexArray, &numOutputs) != kTfLiteOk) { throw armnn::Exception("TfLiteArmnnOpaqueDelegate: Unable to load subgraph outputs!"); } // Assign the tensors from the outputIndexArray to the armnn BindingPointInfo armnn::OutputTensors outputTensors; for (int outputIdx = 0; outputIdx < numOutputs; outputIdx++) { const armnn::BindingPointInfo& outputBinding = m_OutputBindings[outputIdx]; TfLiteOpaqueTensor* tensor = TfLiteOpaqueContextGetOpaqueTensor(tfLiteContext, outputIndexArray[outputIdx]); if(!IsValid(tensor)) { return kTfLiteError; } const armnn::Tensor outputTensor(outputBinding.second, reinterpret_cast(tensor)->data .data); outputTensors.emplace_back(outputIndexArray[outputIdx], outputTensor); } // Run graph auto status = m_Runtime->EnqueueWorkload(m_NetworkId, inputTensors, outputTensors); // The delegate holds its own Arm NN runtime so this is our last chance to print internal profiling data. std::shared_ptr profiler = m_Runtime->GetProfiler(m_NetworkId); if (profiler && profiler->IsProfilingEnabled()) { profiler->Print(std::cout); } return (status == armnn::Status::Success) ? kTfLiteOk : kTfLiteError; } TfLiteStatus ArmnnSubgraph::VisitNode(DelegateData& delegateData, TfLiteOpaqueContext* tfLiteContext, TfLiteRegistrationExternal* tfLiteRegistration, TfLiteOpaqueNode* tfLiteNode, int nodeIndex) { switch (TfLiteRegistrationExternalGetBuiltInCode(tfLiteRegistration)) { case kTfLiteBuiltinAbs: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinAbs, armnn::UnaryOperation::Abs); case kTfLiteBuiltinAdd: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinAdd); case kTfLiteBuiltinArgMax: return VisitArgMinMaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinArgMax); case kTfLiteBuiltinArgMin: return VisitArgMinMaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinArgMin); case kTfLiteBuiltinAveragePool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinAveragePool2d); case kTfLiteBuiltinBatchMatmul: return VisitBatchMatMulOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinBatchMatmul); case kTfLiteBuiltinBatchToSpaceNd: return VisitBatchToSpaceNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinBatchToSpaceNd); case kTfLiteBuiltinCast: return VisitCastOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinCast); case kTfLiteBuiltinCeil: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinCeil, armnn::UnaryOperation::Ceil); case kTfLiteBuiltinConcatenation: return VisitControlOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConcatenation); case kTfLiteBuiltinConv2d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConv2d); case kTfLiteBuiltinConv3d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinConv3d); case kTfLiteBuiltinCustom: { // Custom operators are defined by the name rather than the builtin code. // Parse the custom_name param in the registration to point to the correct visitor function. std::string customOperatorName = TfLiteRegistrationExternalGetCustomName(tfLiteRegistration); if ( customOperatorName == "AveragePool3D" ) { return VisitPooling3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, customOperatorName); } else if (customOperatorName == "MaxPool3D") { return VisitPooling3dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, customOperatorName); } // Invalid or unsupported custom operator return kTfLiteError; } case kTfLiteBuiltinDepthwiseConv2d: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDepthwiseConv2d); case kTfLiteBuiltinDequantize: return VisitDequantizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDequantize); case kTfLiteBuiltinDiv: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDiv); case kTfLiteBuiltinEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinEqual, armnn::ComparisonOperation::Equal); case kTfLiteBuiltinDepthToSpace: return VisitDepthToSpaceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinDepthToSpace); case kTfLiteBuiltinElu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinElu); case kTfLiteBuiltinExp: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinExp, armnn::UnaryOperation::Exp); case kTfLiteBuiltinExpandDims: return VisitExpandDimsOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinExpandDims); case kTfLiteBuiltinFill: return VisitFillOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFill); case kTfLiteBuiltinFloor: return VisitFloorOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFloor); case kTfLiteBuiltinFloorDiv: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFloorDiv); case kTfLiteBuiltinFullyConnected: return VisitFullyConnectedOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinFullyConnected); case kTfLiteBuiltinGather: return VisitGatherOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGather); case kTfLiteBuiltinGatherNd: return VisitGatherNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGatherNd); case kTfLiteBuiltinGreater: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGreater, armnn::ComparisonOperation::Greater); case kTfLiteBuiltinGreaterEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinGreaterEqual, armnn::ComparisonOperation::GreaterOrEqual); case kTfLiteBuiltinHardSwish: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinHardSwish); case kTfLiteBuiltinL2Normalization: return VisitL2NormalizationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinL2Normalization); case kTfLiteBuiltinL2Pool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinL2Pool2d); case kTfLiteBuiltinLeakyRelu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLeakyRelu); case kTfLiteBuiltinLess: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLess, armnn::ComparisonOperation::Less); case kTfLiteBuiltinLessEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLessEqual, armnn::ComparisonOperation::LessOrEqual); case kTfLiteBuiltinLogistic: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogistic); case kTfLiteBuiltinLocalResponseNormalization: return VisitLocalResponseNormalizationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLocalResponseNormalization); case kTfLiteBuiltinLog: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLog, armnn::UnaryOperation::Log); case kTfLiteBuiltinLogicalAnd: return VisitLogicalBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogicalAnd, armnn::LogicalBinaryOperation::LogicalAnd); case kTfLiteBuiltinLogicalNot: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogicalNot, armnn::UnaryOperation::LogicalNot); case kTfLiteBuiltinLogicalOr: return VisitLogicalBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogicalOr, armnn::LogicalBinaryOperation::LogicalOr); case kTfLiteBuiltinLogSoftmax: return VisitSoftmaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLogSoftmax); case kTfLiteBuiltinLstm: return VisitLstmOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinLstm); case kTfLiteBuiltinMaxPool2d: return VisitPooling2dOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMaxPool2d); case kTfLiteBuiltinMaximum: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMaximum); case kTfLiteBuiltinMean: return VisitControlOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMean); case kTfLiteBuiltinMinimum: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMinimum); case kTfLiteBuiltinMirrorPad: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMirrorPad); case kTfLiteBuiltinMul: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinMul); case kTfLiteBuiltinNeg: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinNeg, armnn::UnaryOperation::Neg); case kTfLiteBuiltinNotEqual: return VisitComparisonOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinNotEqual, armnn::ComparisonOperation::NotEqual); case kTfLiteBuiltinPack: return VisitPackOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPack); case kTfLiteBuiltinPad: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPad); case kTfLiteBuiltinPadv2: return VisitPadOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPadv2); case kTfLiteBuiltinPow: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPow); case kTfLiteBuiltinPrelu: return VisitPreluOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinPrelu); case kTfLiteBuiltinQuantize: return VisitQuantizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinQuantize); case kTfLiteBuiltinReduceMax: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceMax); case kTfLiteBuiltinReduceMin: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceMin); case kTfLiteBuiltinReduceProd: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReduceProd); case kTfLiteBuiltinRelu: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRelu); case kTfLiteBuiltinReluN1To1: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReluN1To1); case kTfLiteBuiltinRelu6: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRelu6); case kTfLiteBuiltinReshape: return VisitReshapeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReshape); case kTfLiteBuiltinResizeNearestNeighbor: return VisitResizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinResizeNearestNeighbor); case kTfLiteBuiltinResizeBilinear: return VisitResizeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinResizeBilinear); case kTfLiteBuiltinReverseV2: return VisitReverseV2Operator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinReverseV2); case kTfLiteBuiltinRsqrt: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinRsqrt, armnn::UnaryOperation::Rsqrt); case kTfLiteBuiltinShape: return VisitShapeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinShape); case kTfLiteBuiltinSin: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSin, armnn::UnaryOperation::Sin); case kTfLiteBuiltinSlice: return VisitSliceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSlice); case kTfLiteBuiltinSoftmax: return VisitSoftmaxOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSoftmax); case kTfLiteBuiltinSpaceToBatchNd: return VisitSpaceToBatchNdOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSpaceToBatchNd); case kTfLiteBuiltinSpaceToDepth: return VisitSpaceToDepthOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSpaceToDepth); case kTfLiteBuiltinSplit: return VisitSplitOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSplit); case kTfLiteBuiltinSplitV: return VisitSplitVOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSplitV); case kTfLiteBuiltinSquaredDifference: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSquaredDifference); case kTfLiteBuiltinSub: return VisitElementwiseBinaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSub); case kTfLiteBuiltinSqrt: return VisitElementwiseUnaryOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSqrt, armnn::UnaryOperation::Sqrt); case kTfLiteBuiltinSqueeze: return VisitSqueezeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSqueeze); case kTfLiteBuiltinStridedSlice: return VisitStridedSliceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinStridedSlice); case kTfLiteBuiltinSum: return VisitReduceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinSum); case kTfLiteBuiltinTanh: return VisitActivationOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTanh); case kTfLiteBuiltinTile: return VisitTileOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTile); case kTfLiteBuiltinTranspose: return VisitTransposeOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTranspose); case kTfLiteBuiltinTransposeConv: return VisitConvolutionOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinTransposeConv); case kTfLiteBuiltinUnidirectionalSequenceLstm: return VisitUnidirectionalSequenceLstmOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinUnidirectionalSequenceLstm); case kTfLiteBuiltinUnpack: return VisitUnpackOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, kTfLiteBuiltinUnpack); default: return kTfLiteError; } } } // armnnOpaqueDelegate namespace armnn-23.08/delegate/opaque/src/armnn_external_delegate.cpp000066400000000000000000000023671446772241200240700ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include namespace { TfLiteOpaqueDelegate* ArmNNDelegateCreateFunc(const void* tflite_settings) { auto delegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(tflite_settings); return delegate; } void ArmNNDelegateDestroyFunc(TfLiteOpaqueDelegate* armnnDelegate) { armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateDelete( armnnDelegate); } int ArmNNDelegateErrnoFunc(TfLiteOpaqueDelegate* sample_stable_delegate) { return 0; } const TfLiteOpaqueDelegatePlugin armnn_delegate_plugin = { ArmNNDelegateCreateFunc, ArmNNDelegateDestroyFunc, ArmNNDelegateErrnoFunc}; const TfLiteStableDelegate armnn_delegate = { /*delegate_abi_version=*/ TFL_STABLE_DELEGATE_ABI_VERSION, /*delegate_name=*/ "armnn_delegate", /*delegate_version=*/ OPAQUE_DELEGATE_VERSION, /*delegate_plugin=*/ &armnn_delegate_plugin }; } // namespace /** * The ArmNN delegate to be loaded dynamically */ extern "C" const TfLiteStableDelegate TFL_TheStableDelegate = armnn_delegate;armnn-23.08/delegate/opaque/src/test/000077500000000000000000000000001446772241200174645ustar00rootroot00000000000000armnn-23.08/delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp000066400000000000000000000043661446772241200247220ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include #include #include #include #include namespace armnnOpaqueDelegate { TEST_SUITE("ArmnnOpaqueDelegate") { TEST_CASE ("DelegateOptions_OpaqueDelegateDefault") { // Check default options can be created auto options = armnnOpaqueDelegate::TfLiteArmnnDelegateOptionsDefault(); armnnOpaqueDelegate::ArmnnOpaqueDelegate delegate(options); // Check version returns correctly auto version = delegate.GetVersion(); CHECK_EQ(version, OPAQUE_DELEGATE_VERSION); auto* builder = delegate.GetDelegateBuilder(); CHECK(builder); // Check Opaque delegate created auto opaqueDelegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(&options); CHECK(opaqueDelegate); // Check Opaque Delegate can be deleted CHECK(opaqueDelegate->opaque_delegate_builder->data); armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateDelete(opaqueDelegate); } TEST_CASE ("DelegatePluginTest") { // Use default settings until options have been enabled. flatbuffers::FlatBufferBuilder flatBufferBuilder; tflite::TFLiteSettingsBuilder tfliteSettingsBuilder(flatBufferBuilder); flatbuffers::Offset tfliteSettings = tfliteSettingsBuilder.Finish(); flatBufferBuilder.Finish(tfliteSettings); const tflite::TFLiteSettings* settings = flatbuffers::GetRoot( flatBufferBuilder.GetBufferPointer()); std::unique_ptr delegatePlugin = tflite::delegates::DelegatePluginRegistry::CreateByName("armnn_delegate", *settings); // Plugin is created correctly using armnn_delegate name. CHECK((delegatePlugin != nullptr)); tflite::delegates::TfLiteDelegatePtr armnnDelegate = delegatePlugin->Create(); // Armnn Opaque Delegate is created correctly. CHECK((armnnDelegate != nullptr)); CHECK((armnnDelegate->opaque_delegate_builder != nullptr)); } } } // namespace armnnDelegate armnn-23.08/delegate/opaque/src/test/DelegateTestInterpreter.cpp000066400000000000000000000055001446772241200247660ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include #include #include namespace delegateTestInterpreter { DelegateTestInterpreter::DelegateTestInterpreter(std::vector& modelBuffer, const std::vector& backends, const std::string& customOp, bool disableFallback) { armnn::IgnoreUnused(backends); armnn::IgnoreUnused(disableFallback); TfLiteModel* tfLiteModel = delegateTestInterpreter::CreateTfLiteModel(modelBuffer); TfLiteInterpreterOptions* options = delegateTestInterpreter::CreateTfLiteInterpreterOptions(); if (!customOp.empty()) { options->mutable_op_resolver = delegateTestInterpreter::GenerateCustomOpResolver(customOp); } // Use default settings until options have been enabled. auto armnnDelegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(nullptr); TfLiteInterpreterOptionsAddDelegate(options, armnnDelegate); m_TfLiteDelegate = armnnDelegate; m_TfLiteInterpreter = TfLiteInterpreterCreate(tfLiteModel, options); // The options and model can be deleted after the interpreter is created. TfLiteInterpreterOptionsDelete(options); TfLiteModelDelete(tfLiteModel); } DelegateTestInterpreter::DelegateTestInterpreter(std::vector& modelBuffer, const armnnDelegate::DelegateOptions& delegateOptions, const std::string& customOp) { armnn::IgnoreUnused(delegateOptions); TfLiteModel* tfLiteModel = delegateTestInterpreter::CreateTfLiteModel(modelBuffer); TfLiteInterpreterOptions* options = delegateTestInterpreter::CreateTfLiteInterpreterOptions(); if (!customOp.empty()) { options->mutable_op_resolver = delegateTestInterpreter::GenerateCustomOpResolver(customOp); } // Use default settings until options have been enabled. auto armnnDelegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(nullptr); TfLiteInterpreterOptionsAddDelegate(options, armnnDelegate); m_TfLiteDelegate = armnnDelegate; m_TfLiteInterpreter = TfLiteInterpreterCreate(tfLiteModel, options); // The options and model can be deleted after the interpreter is created. TfLiteInterpreterOptionsDelete(options); TfLiteModelDelete(tfLiteModel); } void DelegateTestInterpreter::Cleanup() { TfLiteInterpreterDelete(m_TfLiteInterpreter); if (m_TfLiteDelegate) { armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateDelete(static_cast(m_TfLiteDelegate)); } } } // anonymous namespacearmnn-23.08/delegate/python/000077500000000000000000000000001446772241200157455ustar00rootroot00000000000000armnn-23.08/delegate/python/test/000077500000000000000000000000001446772241200167245ustar00rootroot00000000000000armnn-23.08/delegate/python/test/conftest.py000066400000000000000000000016211446772241200211230ustar00rootroot00000000000000# Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT import pytest import os @pytest.fixture(scope="module") def test_data_folder(request): """ This fixture returns path to the folder with the shared test resources """ return str(os.path.join(request.fspath.dirname, "test_data")) def pytest_addoption(parser): """ Adds the program option 'delegate-dir' to pytest """ parser.addoption("--delegate-dir", action="append", help="Directory of the armnn tflite delegate library", required=True) def pytest_generate_tests(metafunc): """ Makes the program option 'delegate-dir' available to all tests as a function fixture """ if "delegate_dir" in metafunc.fixturenames: metafunc.parametrize("delegate_dir", metafunc.config.getoption("delegate_dir"))armnn-23.08/delegate/python/test/pytest.ini000066400000000000000000000005041446772241200207540ustar00rootroot00000000000000# Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT [pytest] addopts = --strict-markers markers = CpuRefTest: marks tests that require the CpuRef backend CpuAccTest: marks tests that require the CpuAcc backend GpuAccTest: marks tests that require the GpuAcc backendarmnn-23.08/delegate/python/test/test_data/000077500000000000000000000000001446772241200206745ustar00rootroot00000000000000armnn-23.08/delegate/python/test/test_data/conv2d.tflite000066400000000000000000000013301446772241200232750ustar00rootroot00000000000000TFL3 8$`L8+ArmnnDelegate: Convolution2d Operator Model    ,0,x  (  f outputbias dfilter  tinput ? @   ?@$@@@@@@?armnn-23.08/delegate/python/test/test_data/conv2d.tflite.license000066400000000000000000000001461446772241200247220ustar00rootroot00000000000000# # Copyright © 2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/python/test/test_data/fallback_model.tflite000066400000000000000000000013001446772241200250160ustar00rootroot00000000000000TFL3 8(\l*)ArmnnDelegate: Add and Div Operator Model   $04LT  P   2  outputf add input_2 tinput_1  0input_0   ?armnn-23.08/delegate/python/test/test_data/fallback_model.tflite.license000066400000000000000000000001461446772241200264460ustar00rootroot00000000000000# # Copyright © 2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/python/test/test_data/fp32_model.tflite000066400000000000000000000012601446772241200240360ustar00rootroot00000000000000TFL3 8(\X*)ArmnnDelegate: Add and Div Operator Model   $04@ T  P   B outputr add input_2 pinput_1  0input_0   ?armnn-23.08/delegate/python/test/test_data/fp32_model.tflite.license000066400000000000000000000001461446772241200254610ustar00rootroot00000000000000# # Copyright © 2021 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/python/test/test_data/mock_model.tflite000066400000000000000000001120701446772241200242170ustar00rootroot00000000000000 TFL3 , TOCO Converted.th\TLD<4( nhnnnnnnnnnnno, o0-oQoR"o\n1.5.0 min_runtime_version 8  (+XPD+ddQp4 max_pooling2d_1/MaxPool0$<@Fq( conv2d/Relu , XD;C?q$ dense/BiasAdd|, IW=<AS*r L ,conv2d/weights_quant/FakeQuantWithMinMaxVars0$sC:|>|M Q.WtկݮlD3lw:w9K3ҼqFAVC͆ث!wbm nymil\J6"ղ䆲 +uz)<$AKo[4_= Z<2~vdvÔYL~XglHO_lV#Acѫ#Uķ,Vc?gi!W>ь7bf'hc'hR<! FJCg `Ye´tTs$Z]ębDrbPcRwPv~QkuiPgGmYsczK^`{\c'R^Hf}aoqcds}ev\UVVj^aDc1PFb\~aX_Xt^^\[ŲvrYcWatiTR[W7Z|mrMFXgM\Womp{zf{IlgP?:Fw0}kxFH<IutfeT~թ~vXgkWtx|dwcxwY|HHH7i}]so5ZJp`RRwCne`Cost>q]U0Wm:HxrW@FGM`{Dx_nRv@fgVPdub~gamzy|bXoKx#6oj3t-{@5WZq{V/m]LVb?qyU6zԇ!x_vi?o.B5ٰt8dwoĎWvyXuc=Mf釈]fltgmnXo$~4fhռALSM{uB|2]l`hy[`ǰ?r`8o}qkx@jp;?iy]ȇ4(b}kTIseq\BdFum_`\tbgkrvjpÈckx\UYqs`vCy]waivWPor7geLCZ}g.^hmx\ljkkiY8UT'muGDrvwuwv]EՈx{GZ|ߕOuQ3lIE^/wrr;LM͍S4 OQ[c`qzx\o_P6aVpEw]f*vcR_tPRөzd|"vcU]|!q}rf|u5bɄD>zyh*CHrIAkzV\lSfFEmksLeHIXUOYPw@|qLbYSe`Q;g(MszXYWV*M ^w;O\h)o>s[aeYx;vO^d{PfeTopTL[e9lxmC8nZfxŀwO|w͊pRMKNΉ|XUTݕhm;v]v,nHbzi|rjnT[`PKtUYtpml\|fgQgPZfWjawj\m@vbazb@ZjcrLvj~^yn6RaP8mYqaWupwuYhDcgg‹}Uu3y;cd_YEozxvPaȌYt~H[f~GZ|}vul<^i}S{YqM]9t;pYEyteYm{=A0^P58]nod@vb~EnLUB^HuY~dZ0cyGqL:o}pNF6n=q^spbuXWȐU{DeNaWWxf>El{|=pxwll^,3:eG`_GyLbt#Ceþ=_Qqr'cpfu܃$v[I|fo_suA2oSU`eyLxUgV˳u!=`TnKDZNIzTTlVI?zQkm\qXb8'Utji9uĞgd_}Xj`Pv\hbrrFsao/neKxxNl3fZj_a"zl`eTrzQ Fg-:q~|$`tO~fM+rǃIJE7r!q;o#v>yjbJ+mYA#U{[-%?[3] R|WF}rrzLZbV̻ya_ѧY?a.P;zplyS@n7S@z{F΄]t|Ǩ=Ovrx@>c&}4i`jVqk}wb3nitx>{ՌݢWit[_QwbOcHФ`sD'_fʲg1Uv\=MHS}s[Hj+ybf*Ih3eT&noC">7c9>qdnI.DxaxxVIB e̋QgGrV7nW};:JMɔǜXGSkZJ^nVlfO2tbo]|=>|tNxz@Jn\v{ToDsYt{b^Bm2PPj@qcQ[r:U{yZhRYxTuBWO6;6Gv4\odr-PwseVooCr?~]?|ufH>@uGΎUsгBw֨az@zD-φZkz9)g}C{VhHyzwCpV_sp,nYPBLR{`lRv^tUb=[r+h_Jd__P+W4}cgODO5*w~{ފ_nn<{I~nOX6*KCLFY9>ņoYByZ[pOgTҐ Z|t^Kk>ufhjXq7+}ʓzx5qzSqc]E_U4+o\~dA6~j:NnLN Z;rO]fJrIvx1VkZH@h{zcq/8ZN|s3yfjLэdtJs:,jqChw;ZT_?׊fjPCHY]/CxM 5_i[gOre]^fQlُHTnuejreZs*]žIr$sQo\XF{df͡:_dn_[!POaYj}hf~Lb}~fi{xPxGzn&|dlk|RzkI>6veFRFwzgRP<TxGAuh~LqwiunedMJ[ZaicLuilqOY]uˮJQwjcW¡u%bLvܗЕ:?n/4yfjauwedBkRnӱz46{{xpQMG7wo~r}iKNbKl*]akhD}JdH]w_^UVaQ}_ry8qGZSϟo"bkQ?fUr^lcӂwi|wYĞ_dϦ`yna.szlUxFR9qb]wZIyu]λi'5UŠdn2tH^vjPf6Iќ94bxCK^kbrwȓb@iÏMLW]RGP`Zd3_UPEQZy]z|yau»^avemj[UqWeuzMRvQ~LgoTS`Z]+`\h?`K\~oj{D*lPȇgMcYq[N\zjyn-:aBpr2QGgl[b7RxvBawO3;]xtUB~qnnpJBtyzlr@WrpuTԃ[ZSnp.w[>jyTTiFza7υy>OJYq;eİWxkbjvn^x5\y{^klPh\kKL]lqvdNzZU^{KiDwnS{kDJpf\7[~X6ai\>naxh}]s@zl|yac}]@[z-NWň)/YVǚԶ"jin}}]2̦YxuU_YS4ƀiOCbed}qAyT]vtx,,}^|\UqwU[IPZr\aeI[}omQrG^QzQFUzlaYWeMmQPpQ~ffp\b~O{PwwO}jYK}_N]Ilo{[aJf\GeKXFrHqwNW\_CykPaZxxi\cCXTiO[hXmdPgm[OW^QRXYaTzSHIOeQLKfnVKZNeK_n[U`gDqUeOjrS_I{`tDUmt_h`iuI]hVtJGwqwxEjyMaaN³i~;uf~+Hp|uHzp\(vn{r']cUk`NvuSòϕ_Wfxix6z>Sz)DXKP2Mz`kyi1>p<~[|>;|YhlYxNrH`vkgpŬnUlw|}[C1-~,vaql^&n.J}X4_sb'bR|FA=~Z+z4^S0|tdz2mtsp}ddozQjRN^VHTvfhR_6mlc3M[fJU\%lUDq_lJn@kzrT7CIlJ|~tdZUz~Gkypl}DrwHcs8h}2v(~Hݢr>pHq}HKG!egd}Кy϶ lWo{uymZOXRVcSvrY]BROy[I|IHiSi+/#}p=bH[zxN<JlW;9( conv2d_1/Conv2D_bias<6WAE A W" qd Hq`jL  .conv2d_2/weights_quant/FakeQuantWithMinMaxVars, :%\>7t$o|qmzUMdyfyhRvy5ColHvhfdvzRYVlN}c||`|}Zn`_zBkC~p|~vUrQd`sXSRsP[ouF`e\uFQ`Qʅ|ut{EvYsv\ztPɥjvxeq}{zmnJoYZ]~YyVj^V_xck{Lw|zZwX}8q@oɕ̟d_puXh\gsvfUnée[ophjkasl{D|oHXcj`TVxtZxZVNNnAp`]LnnbRvwnhMjpcqKcđ'a{‹8MhzkJYRp`{yAɏâx\exDSFrfo|k׮EV`fg{xvi]oW\֬W\q¹wE|dUBs_{uPQ`V[Ws_X[{Pts{p`kbm_P~]uWcs֓hxcaizK`0~ieL߯bz9~hT]AfGgiMV2V}z3AQ]S;psZigHB^RtBe~Lllya}ХkxWkeymǘ؉H{xWlDM`osu@^CrTua}|Ng{uIBu[naVR^eʘy}Sv{ɼL@uKЫqyh³unqΆinvambi[fvsk\TvTŤ\Wʃd{q.e@mtqnlLr]0t=kP|VgZVȠfmϯ8Czv2Cc]|zRg8[ugIpDǗvyUWJ2`|3NM0TA_ZZc}!̽ɶ8Kf߽(ddJpdiXduaFbl\oK}{ynUs>hhz[F:z|u]t}nV{]n]Yrhlx?]_}jEtY}˴QizV[\[udtvyiZŔos}zq^x_ouiwhɾ]yŌͲ|Ș^ՠlPRvBrMSg}Yr³яc_jZedrV~ux³pΉ`a~aWYhtiqzssSGZw;lYʽfa_YSbq}Aq͇Nt`FZînpm?x[esʓYl@QrsRUe|rfJpzDuFKdA}|9bOI9k]OO^KnTWP}0bd]rdYyg}ZYRqWRGHSUdAjv_~``l}TFp8BNw^UtMvx~s_|TLwQ=}Hζ}zw}NjjUyetzсzc^ggGeo_QI6}ySXPf0fRxGo`Ŷyiѫ;?L}iRxr?P-yVRnĄghB^]g4N}pW|t|ޅiGraumcSr]σͦdEmd`F2GDMeprJu[[GemqH4X7ZO>WgԔrzAձvlʎXzvWF~Ncc]]t^U`ty;xZVqgtp}un_\ØJSwZqUs`Ty\o^f{hWDptJVjT}Kxbbfb=Obɒ_X?E[Huc9RfXhn`lq`zmnv[DÉKjGR|ĿXUCdstFYVk1ZܱR͜{^Iterԏ=TSWLbKo}JkHrC@[kKPc2C|UÐ_[М_XLs~Kosr|pIitdwkêdxgtGCRT|lcgRimdsnfftum}iVyPhًYqzpXgWbg[ӨiZ©O{s^h~i^zabqf]^j[YqŮx?d`cqsrHebvf[rviStcstyXmnk@ZoZLk`Ijtx]{smGQfyrVLayXpretp`_H;>LStm7gH7Y-~vKHyu|glyciWRekfsdwUtn=ʄţuO\ptMlvaX~NvWjhiWufhmOmrPrhhlXS[wzpwdšX}kigǾWqخcW`ik{RNWnPqfZũQoO{=m~rt}Z~aXxǰfwi^7}Nγq]i{auʩU|nVJR`}ϨΝmnbnXԩ{ɇkQryvq{_Vi}zN[uU^bSlcX]l{hy=WYX<ɼj_Gzeu`ײ7Ƒ@m÷tagazz`Y[dWfiht<\SdwqkuYMf;@{rys[WxzwKgJ=odK@y_xha}}ZvtzKeUVus?vWskdqusOLk[ylQw~~AbAhl'¼[@'T}bqLzi8mSfȷh@mu^t|zkonzk,}O|dIubAp@ruwOh`jnܛhUp˄[zTdL[kY}oneH}ƬxdYhpd;wxhͼ]eJZzZ`tyU[wcI%KNSR^ldZ_$cOOu2 ͚5K^K>aOi2zOFn{9ҝwn`oJبpŕQU`ȄtΝ[Yk|P`ptjH<ˇdȸ{xמzf/FxǐcՌȹ[9[z~{OGi|\UmZݸRx|NgvNGMoPpT;kO)]So]HYd8Rc4j+BBcu'DOqILC}—`DWhUBGqLe9SMrfl>XT4qu{waXQ^ᮍoǧcSØfvFt~m`O^RKkXJcNSnqczWIk~Wr?uZl]}t7uij;WuwooWɇePwCnZjT[a]_~[PbItygCx]IRsxQTclfYX]^+nMowjleuLaCkY[ORwZjcVuw_RUbk=lsxaOtlrnmq1\APso?:<]BoH@tvXŜiQ0[Bwko4~MYGjSeˉuCo:hXC{W.NJI]BE9CMAoğmoerB:Q__fp撉l^YCĻ~KfƜwιw뒚^zSm^hluʏyYḫuq{w^OֹɉOdWgzÿijkr|`jQvАRa9N|eddrJnm|XXr|gez͋yssdsZma_ǨM`S֦̄kJLb]_RHQzwXQ_RL:M_gXdeˁay[Q]ކE`itGurnTIfiOXBYN_2LJuCt.:fxmpo/ZU{acCxENue^BIu̬ŏOe|Dn{͢ybJ~`nfVel]:i`oiCIL;Io:GXVz~s6NxwZki5mj~ݎitqnwzq}Q]leiMhUzd8adToFh;\cPoWHW`0ĬqˢP~hWrzͰRxǼ~Ƈv{[e{[SqN`ǂZndXzkYXwngwrYZolYDmv{;f^vpeiFkmjNjCKhYyzgRV`tQx|Dygk_|hfywo{xSI_nd[??^m7ZHMnY=X~ccMLrHEOTShY|kRvv_zdaJRzhRbĝtp]xUkYw]HB@MdBYO^HZ;Qq>dAu7p7OzaNvsJQJ{z}dP]N]H`aɉGhy`mv@fNƢFa\_TjYhbnޭo;Xgccbq]qToYyjx[dÅiLt`Q{=^kx{vfتՄE=;9ƛfYPytUv͐`KD8u?z_Dcm5٭ Oj;ĞLY!\ғgtjS2EMhvaSgdcbCZ;+Rjh7RFTcrJXPjuoHculnl^xq~qnWϻ\x|^Tr¢~f=VgxiQvgcʫYROvZ.hrN?GX3H>A[@A%OSvZK3=~nz^^X{zfԲa…SuN]_0oXci({cƸ\}wHp`|S'NQ'~"Uui\fvcw^sɎTv׾]y|_mqYhɝʊxH7YRX_̢vMåMD~ȧovuWA=uLoq׵UYP嗗yBMixnUk`bgatO;@nxppV|tmí2gE=xmM[6LO|-]qtz;=r_BqqeqW_U|~DWyXɺ[SUS`gqj`qyKgT|rjSssѫw/aht_s~edeyzZkq\tyzaMvCdJnLM>vtqImU̱;KrlZŠʤǐMNt@ˑ^XYz]d`^RXPum|yFYpPKi`&j-hSiuaiaUhKXkMj_lOumedNdkIcHnjEK٫c8FfEQQR>kA@asgÞBd¼қYxF~$pm6\~^1yqTrg[\y{sBqpeSa&jcӄtoƜ*CxדgE]ht+yeqdζr8bf*;:8ćAqi{\u~8zT{jhg~u}[oPb:)\b-gp/xآb~Q~xbV?a]RUaÞ9[|^WrsS[ZH[g@qxW8g}.r\|*A{jxbɗx}@hʳWůf~^=NmuTkxlbnzgdYk̟}gZfOvUhXRiHf|uc_cIȦViVWzwdfZ/Tyjfbna^[phgv`BrwhdJwf{Vrr`}vuvmIhNuSprR]ȣ~^xcYhf]CvRUa{`5gn̉+m^elkscAb~vcOxȸlJutYH@`]o|mqn>{|@vAT{ZgCQ~WJV^~AZU_ХWȟkwi9kQc]sCvmvwrVKlYsMgc:Orc=K[?ub,QGMi^o]e_8{Y(EHob`Ȅf{TS-@X 5dense/weights_quant/FakeQuantWithMinMaxVars/transpose   , Ȼ:}e&>q{`u;pOLco|r}VbOQzzI{zƍǎ^|{|{UphxqEdrqxn^eœuRP78:oK_n+wk\bokrQmtv|w^dyGjclufSmyM2mwGW,xsr|I{n}5~dsn5dnUyuvKm~boh{ioy{enpZieiXea]YaraYeYdÿt^wwznPgc|opDbeIRij^kUA?^|q^rR[{wx~vW}wtkrdVw}v_u_bkׅ~Yt|wndPapqd\mXxPfhz|WHpkvɏywyEVust~S~hRWNW<{xsgLxwmpXNBFyfc6nvUxeMRl1Fgyz]eâwrxljz{m_ehqw~tuytÛvuyt~~t_cwԓ}Ö~u[lgϗչhstx}DZGso{^~x6{husEf{_}{ǠSusTuΐ>vw|_Sv]yƦoz]zYqЗxgv̦xxIzB~qX^է^Lk΀aijenalwƁB~~QwӘAlj0rJryy/qVq^ėv~U{ΛeIyjsf\o>ki}ʲdlbXžzftskej\kxVkyz`O\kYVcs~llybrlwqznxo{fmmS¤b¦sevAxwxXv?q^x˱zjkJmNZ|Yvf橒y8gtM|u~youbid|lrerFU4xbn~XfIufr~FieiSsXYUY~}yhpkvqs}}^qngim~qouv}|mlcą{m}Ɖl|T]gJo|X\j?~w\'*|g[cnS}{sPWwsRFg /R5hq~gxK5rnYnOo~5aEX=jVMtRnOroh`~y|pDoZfdoԼ̓ku}~3½oB_uWwQtzQIcKLmvwl\ǐŘs\ehHsqtŝayxxmWtyKxpH~qTeTrwo]pcfQ\HmyPnUS5gmbomudfQwc~EwKMϧ@WzVKB޲ʚfb~TsIP{WjƓcoU@|knb]yûW9vYuqSsdzdhnNv\{iɇd`xfwVfs{kdm\hPvq~ntr{rh\iZݎek6^~{OaÖnefklUkTr|Sawsg]}rcʃy~={aqW}Rnُh[dKi~lp^ӏeh]UewlƤ{xgZpnjjђ\x|~wnʼn[ȂŰŰphvayQs`tbswrjzngo~k@pG~xwKo\ov{xvzvtxk]kqOTŅy_\iVo&}cʬbOIߧc[ZŒ^ũᗲvfct9DZ{wZbRtSId_ho{cX`_dtvvYipI+)~b|r=isllyS#emrplBm\H3C~@7{asYR.gwli|opeksxJnjP}KB^|Jfvkhn?p,Yu;Up}nZ|jyQIkdvtnxklWqmd\mH|}o}mkdWz{x}metyq_WtLvxry{Ub2zttnzqWk}XdpuP|lWjj\,j._jjzggs6zn[oHgRF0UN_gczWuI6ZpFPfeZLqcXcs_qtOwoeGvw}_wmћd^5pm4ёUe_|dˎbPyZAԥm|xLys`plQWXc~)|fxtq~|ptRg\ƶq~xeRF|~g8a3v\ko|}~MQ_X\kasSGoqh>wQ|fxT~r}uj{MQʦjrZjtk8yjFxP-V{֍Nkb{Uzy|mUKYKSlXc|AZmyiijgycZvgØ!C\d|7]}S~xoxUp{ué{lepvUol_Xpo|=L:~>jmO{m}RtqoɤʒqoƄkeEŹڿMӭm]e`xpdEsdxfctxUwVZcVywayo_VynYl`~xw_A~.+n'ei_W_}Uyn^Yrep3}wdYUdvHwx_fC B_Wzsn{h?Plxt{|tҞ|fmA_Ѧ~voNDЫ{jNWouuso_k}^tulsvj`érɬiirќ}]r`s?VrxeMvbraVTBZ^fn?g`olP]dKWdpxcxvχva`ÄBɨ಍䯻YD南mguȲή`b|zǨ^j<|ӊq}`pӏc~Sqynwp}}s8OYeztk{{igXcmN`Ustusiehegnr`reWWv}~wofa|akjtrkx]kxwp}rUhuxv~ugegr{tuRdkZN[myTypAeasgɥFrpUHs{TwS?rkI{QvbAhnƎy|qͯxw`TywUdpsqrhgSo_rntWpnwmgOiDVGw]sΜ٩pgwi~WbeVeJ*b9XȰHiͼenRzhguerDXz?_ou̶~+ZPhpϳʧ]RogoØƝ{kÜ`wmyxx^iblgaOiiYXiyȈrxtpflxpkP{BtEț|:NyRYb[pt{BzˏTxFuGXA]N zYemXm[EE(pa_̾3;sewkdLqSbmkmyrza]u|iYzypsJ}oVfg_s~q]N5Ek}Ao}^RLzRJksmpzasfo{[omkutQZog7[qv+qTamqũ¢AHVl}ƁbpxwdmYpnfwvg~rjlZ}Tmpipdvbf^XlpIqwflɬlc[wNwhvFv}ҪWzj^XRWzcuhKy`Ce{<]O[sxwsq|alxh`mrmyy̲mWY~ni|p]mMvbqhwbcmfo̤T\UOewOgNw`a|RjyfQk\w^FӅwUeMw}ȥOly|un{5[iqZ|dsE]qUemt^{bfO@ceeIVayp}mgV_{|wInh}_|rqgulb|?aO{Ivuln`n]tMwm|rwhTtlggOGL\Kkn\kwVqgaDh`dldrwnYQVgomUzVN`oicvgp_YjxWuUwis]ctFnUb}\oL]N_7zc~fy~wfWpuix}Wl]ɷ}a{qwbQx{xxyeytvdkfuQz|zpuu`etud~~rizwUpnpoWrdRRb_}uwdb|}WWM\douUYiyArghkNfa{p[nr{`|W\ksGhFWrbwq|xώlmwvvkncZgxx_wjpxu}}cyxy[9`scCh}o|N\kR{`]}=[y>x8eh{bmz3HW~4zua{wooppqš}jNnQvwsRJbqĨsbnqj|Zr[s~yH|zōίXưпf]bqr~h@lR,>G|8oXbLtdm[Ui\ujjnPNIWSXe]{yu{|~nipDCJRpnlkft\Pgsmq–vsuk\#sx7󟏏ὂ؋ʹmgcbmDX+#huwĚߔݡdP?Zk]Oƛp0n|zŧxu|HܥزP[uwiPiFnMykZ\jcmS|sthjokpH}1]˝{6kszaWjx=ijuebYGWhzkuCovn^oxqbyrplpc;xóp}qͲpwV~~mhrLBkzxlsguxs˫Xo}~jЫNˑT}wdmvuqrvQVajkwkgdnpTjvg|li~w]q|a|cc_cxwtlkx~esygI^yFY[3p~oaWN]awŸru}yhike~CvciuvmbTd|g~RlnRopunsiuvkxltguųsױf|}linmvx[oovɖiv``wɓɄuq~v߹ni{o^h5k|ۤzƨ|҅gߛQmX^ƧpdǵqׅbUl̝vƤcʹoˆlsnVSxzenxbl]tplU~ynbQLtjqyNkpcmdS~`J[vqGiRo–|HykXaqRbHPƳr?}|z{YcuY۹LTKV^hi|M\ynYfhybfԘĐz{tǣz\q~^WdOyntgdw_esis{cwqEZ{SZUYeru~$anEkc:zn{͌\u1_>fpa|[9}\{uLocHzXEZv^c@`=NėnqY@fm~{ertęyf|uĐyv͚|cy=^}rgs\7iz:sUtcDMQhzV|}Ws;~eoiJrJ~cuf }Vϼ&hrcφ_Cĥz8^wqbU[duJ~uvT7phJXWrxSkSgj|zWRhv8`d^rn>rct}0ycV`Tdp}n~O}yYPbn\X[mMq~ynwtqeteThuszs^}yihwgoo~PN`cv5:~yQs@0CIb]f\VGB[QwQLkfbnX1p\tFzpisdLIWY^8yiEg`e`î}dNcu_``/y'[txen^^^grEgzxO=MwjQw|dbfRY`n\u_ZalbkeXm]^XTszbNc_zzg£hqxuoZXl|T|vy\Zp{|Mu^w|j<`RБ?dpFIJ1j]DpH{jcYmdzZoYCq͞eɪv}t}s}ѱ}̦d|tdsrndW_ڠoVZcqMbT\J{ĝmjm]mpoVwElui[ndvoe{~mv{yV|Oa\CcFwVZ~PftPdM~Pbjeay~}qxhmGp[jjmoncyůqssǔrYtaȗt|^vwKa;oBgSgZmceːItzgp{s|ok\kwwzg̑BcAugw|]t}b?WxGs[v{@qZur̿}rxc|m}yqth~tlf|mVgX̼|?Lxjdov{?^rĨss{cv{sljuekusuoup¾wvGejTltXSw{}TxZn{~ya\eyUQ^dyzˮgcgCjsmreUaE\llgvusl]V|]rJnpSreMSp`ptV_L|uilcmtCqyZ|Męĝvā?|t~MZƚ΁UUwkr^daDmIVZ|Nmdh}lrze_Ğwpg]OhdzoaqmWlOKGYq@p^P]oEqHvNb4kTA[rVdmghUiw6vogZKtjp~a7]bUd;qpmgoorxv[TaUxNZp`u`v{qSrXVwyWwvNCAASs]1dexRfYzomx˗pToizÈlӧ[y\zԬoއw¹mfl]co軱ē̖}\nsYsNOiOpfd_lj\{nULa`9~s5oo[eZlNM|gkdui}UpXJujuxmWm{Hynn^yRWTt[yyyyP\Pz}NffXza\yOw}}fzuwLcp[ŇvXrʷPwJ[dufrj²X‘sHdy]ɃhxhlTˁCT]eehOqxivnrQj~m}^lx}ffvSulwitYts}Q^}cqmwpuhnX^plocgotnvȐdh2hs~Znqcksu`sv_nzvSo{bekĘoj`|ƞmdcpy}oj|{v]r_ui~tzrlfvEVZvfTuzimX|1;zbuŗ|x0~{yUW_aienYy]e}ijeubu[oRbi`zU}HYoxvpe~njv|lfTȂ|zei{ptm}{`SkKhz}jyRy]΂_sYBNeqxVˀy30tDwبZhptnozS??ks!zz֊car|>z8_^y{vKYY]R|)zYqmQ¿dΌ[aKxRUyMsZqos]©~wglrtw\|pmnalkpTEtxbraUk!ȟznYe=}nӉOȔzw:[ITV\1mQqilbo~~TSJq\?{yyskbyDXf{jw[_prnvnfr^v|tl}s|mpbFpcjKur;Qq[qnõuz/@resRQxqYUq{j#wnSiksUiOwcvg@fq=nRdypz{fZ8poWY5fYfczwgachvqρWgnmqqtziZu^jhn]o^XfiqxUwb[palw\eOXnYhaf{qh\LZ_m}\r}BorrPi`jt)vuW:xaWejf{)+K7ajqR¡Hw_b]HI]iz}uc>v_xŞMo]Lybzv|P}]mqfrvieU~sR^k]VfVqKkut~oYXumc\PkYKn`wmnsnWVZXtJ4V_M~gQfWOxDlNtccmsfQHxGT/z]YmsykbnRE>gF\V^\OzzxFuHSShiwBbTÅYP_rFwklvELboLvfqezcoE}KVr?[w\eexǿ]jdjl(Wjsua<}nkwUA`>{mT9qX{`]busXu\X[mZdyAqb\cCNl\zbqifd|~_?sgrX[s5~JXc{vha|imN_Z?x\4G<[H@ $  ?(  vh$RH,  0   0    ,H armnn-23.08/delegate/python/test/test_data/mock_model.tflite.license000066400000000000000000000001461446772241200256400ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/delegate/python/test/test_external_delegate.py000066400000000000000000000213151446772241200240130ustar00rootroot00000000000000# Copyright © 2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT import numpy as np import pytest import tflite_runtime.interpreter as tflite import os from utils import run_mock_model, run_inference, compare_outputs def test_external_delegate_unknown_options(delegate_dir): print(delegate_dir) with pytest.raises(ValueError): tflite.load_delegate( delegate_dir, options={"wrong": "wrong"}) def test_external_delegate_options_multiple_backends(delegate_dir): tflite.load_delegate( delegate_dir, options={"backends": "GpuAcc,CpuAcc,CpuRef,Unknown"}) @pytest.mark.GpuAccTest def test_external_delegate_options_gpu_tuning(delegate_dir, test_data_folder, tmp_path): tuning_file = os.path.join(str(tmp_path), "test_gpu.tuning") # cleanup previous test run if necessary if os.path.exists(tuning_file): os.remove(tuning_file) # with tuning level 2 a tuning file should be created armnn_delegate = tflite.load_delegate( delegate_dir, options={ "backends": "GpuAcc", "gpu-tuning-level": "2", "gpu-tuning-file": tuning_file, "logging-severity": "info"}) run_mock_model(armnn_delegate, test_data_folder) # destroy delegate, otherwise tuning file won't be written to file armnn_delegate.__del__() assert (os.path.exists(tuning_file)) # if no tuning level is provided it defaults to 0 which means it will use the tuning parameters from a tuning # file if one is provided armnn_delegate2 = tflite.load_delegate( delegate_dir, options={ "backends": "GpuAcc", "gpu-tuning-file": tuning_file, "logging-severity": "info"}) run_mock_model(armnn_delegate2, test_data_folder) # cleanup os.remove(tuning_file) @pytest.mark.GpuAccTest def test_external_delegate_options_gpu_cached_network(delegate_dir, test_data_folder, tmp_path): binary_file = os.path.join(str(tmp_path), "test_binary.bin") # cleanup previous test run if necessary if os.path.exists(binary_file): os.remove(binary_file) # Create blank binary file to write to. open(binary_file, "a").close() assert (os.path.exists(binary_file)) assert (os.stat(binary_file).st_size == 0) # Run inference to save cached network. armnn_delegate = tflite.load_delegate( delegate_dir, options={ "backends": "GpuAcc", "save-cached-network": "1", "cached-network-filepath": binary_file, "logging-severity": "info"}) run_mock_model(armnn_delegate, test_data_folder) # destroy delegate and check if file has been saved. armnn_delegate.__del__() assert (os.stat(binary_file).st_size != 0) # Create second delegate to load in binary file created. armnn_delegate2 = tflite.load_delegate( delegate_dir, options={ "backends": "GpuAcc", "cached-network-filepath": binary_file, "logging-severity": "info"}) run_mock_model(armnn_delegate2, test_data_folder) # cleanup os.remove(binary_file) @pytest.mark.GpuAccTest def test_external_delegate_gpu_fastmath(delegate_dir, test_data_folder): # create armnn delegate with enable-fast-math # fast-math is only enabled on Conv2d layer, so use conv2d model. armnn_delegate = tflite.load_delegate(delegate_dir, options = {"backends": "GpuAcc", "enable-fast-math": "1", "logging-severity": "info"}) model_file_name = "conv2d.tflite" inputShape = [ 1, 5, 5, 1 ] outputShape = [ 1, 3, 3, 1 ] inputValues = [ 1, 5, 2, 3, 5, 8, 7, 3, 6, 3, 3, 3, 9, 1, 9, 4, 1, 8, 1, 3, 6, 8, 1, 9, 2 ] expectedResult = [ 28, 38, 29, 96, 104, 53, 31, 55, 24 ] input = np.array(inputValues, dtype=np.float32).reshape(inputShape) expected_output = np.array(expectedResult, dtype=np.float32).reshape(outputShape) # run the inference armnn_outputs = run_inference(test_data_folder, model_file_name, [input], [armnn_delegate]) # check results compare_outputs(armnn_outputs, [expected_output]) @pytest.mark.CpuAccTest def test_external_delegate_cpu_options(delegate_dir, test_data_folder): # create armnn delegate with enable-fast-math and number-of-threads options # fast-math is only enabled on Conv2d layer, so use conv2d model. armnn_delegate = tflite.load_delegate(delegate_dir, options = {"backends": "CpuAcc", "enable-fast-math": "1", "number-of-threads": "4", "logging-severity": "info"}) model_file_name = "conv2d.tflite" inputShape = [ 1, 5, 5, 1 ] outputShape = [ 1, 3, 3, 1 ] inputValues = [ 1, 5, 2, 3, 5, 8, 7, 3, 6, 3, 3, 3, 9, 1, 9, 4, 1, 8, 1, 3, 6, 8, 1, 9, 2 ] expectedResult = [ 28, 38, 29, 96, 104, 53, 31, 55, 24 ] input = np.array(inputValues, dtype=np.float32).reshape(inputShape) expected_output = np.array(expectedResult, dtype=np.float32).reshape(outputShape) # run the inference armnn_outputs = run_inference(test_data_folder, model_file_name, [input], [armnn_delegate]) # check results compare_outputs(armnn_outputs, [expected_output]) def test_external_delegate_options_wrong_logging_level(delegate_dir): with pytest.raises(ValueError): tflite.load_delegate( delegate_dir, options={"logging-severity": "wrong"}) def test_external_delegate_options_debug(capfd, delegate_dir, test_data_folder): # create armnn delegate with debug option armnn_delegate = tflite.load_delegate(delegate_dir, options = {"backends": "CpuRef", "debug-data": "1"}) model_file_name = "fp32_model.tflite" tensor_shape = [1, 2, 2, 1] input0 = np.array([1, 2, 3, 4], dtype=np.float32).reshape(tensor_shape) input1 = np.array([2, 2, 3, 4], dtype=np.float32).reshape(tensor_shape) inputs = [input0, input0, input1] expected_output = np.array([1, 2, 2, 2], dtype=np.float32).reshape(tensor_shape) # run the inference armnn_outputs = run_inference(test_data_folder, model_file_name, inputs, [armnn_delegate]) # check results compare_outputs(armnn_outputs, [expected_output]) captured = capfd.readouterr() assert "layerGuid" in captured.out def test_external_delegate_options_fp32_to_fp16(capfd, delegate_dir, test_data_folder): # create armnn delegate with reduce-fp32-to-fp16 option armnn_delegate = tflite.load_delegate(delegate_dir, options = {"backends": "CpuRef", "debug-data": "1", "reduce-fp32-to-fp16": "1"}) model_file_name = "fp32_model.tflite" tensor_shape = [1, 2, 2, 1] input0 = np.array([1, 2, 3, 4], dtype=np.float32).reshape(tensor_shape) input1 = np.array([2, 2, 3, 4], dtype=np.float32).reshape(tensor_shape) inputs = [input0, input0, input1] expected_output = np.array([1, 2, 2, 2], dtype=np.float32).reshape(tensor_shape) # run the inference armnn_outputs = run_inference(test_data_folder, model_file_name, inputs, [armnn_delegate]) # check results compare_outputs(armnn_outputs, [expected_output]) captured = capfd.readouterr() assert "convert_fp32_to_fp16" in captured.out assert "convert_fp16_to_fp32" in captured.out def test_external_delegate_options_memory_import(delegate_dir, test_data_folder): # create armnn delegate with memory-import option armnn_delegate = tflite.load_delegate(delegate_dir, options = {"backends": "CpuAcc,CpuRef", "memory-import": "1"}) model_file_name = "fallback_model.tflite" tensor_shape = [1, 2, 2, 1] input0 = np.array([1, 2, 3, 4], dtype=np.uint8).reshape(tensor_shape) input1 = np.array([2, 2, 3, 4], dtype=np.uint8).reshape(tensor_shape) inputs = [input0, input0, input1] expected_output = np.array([1, 2, 2, 2], dtype=np.uint8).reshape(tensor_shape) # run the inference armnn_outputs = run_inference(test_data_folder, model_file_name, inputs, [armnn_delegate]) # check results compare_outputs(armnn_outputs, [expected_output])armnn-23.08/delegate/python/test/utils.py000066400000000000000000000040731446772241200204420ustar00rootroot00000000000000# Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT import tflite_runtime.interpreter as tflite import numpy as np import os def run_mock_model(delegate, test_data_folder): model_path = os.path.join(test_data_folder, 'mock_model.tflite') interpreter = tflite.Interpreter(model_path=model_path, experimental_delegates=[delegate]) interpreter.allocate_tensors() # Get input and output tensors. input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # Test model on random input data. input_shape = input_details[0]['shape'] input_data = np.array(np.random.random_sample(input_shape), dtype=np.uint8) interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() def run_inference(test_data_folder, model_filename, inputs, delegates=None): model_path = os.path.join(test_data_folder, model_filename) interpreter = tflite.Interpreter(model_path=model_path, experimental_delegates=delegates) interpreter.allocate_tensors() # Get input and output tensors. input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() # Set inputs to tensors. for i in range(len(inputs)): interpreter.set_tensor(input_details[i]['index'], inputs[i]) interpreter.invoke() results = [] for output in output_details: results.append(interpreter.get_tensor(output['index'])) return results def compare_outputs(outputs, expected_outputs): assert len(outputs) == len(expected_outputs), 'Incorrect number of outputs' for i in range(len(expected_outputs)): assert outputs[i].shape == expected_outputs[i].shape, 'Incorrect output shape on output#{}'.format(i) assert outputs[i].dtype == expected_outputs[i].dtype, 'Incorrect output data type on output#{}'.format(i) assert outputs[i].all() == expected_outputs[i].all(), 'Incorrect output value on output#{}'.format(i)armnn-23.08/delegate/test/000077500000000000000000000000001446772241200154035ustar00rootroot00000000000000armnn-23.08/delegate/test/ActivationTest.cpp000066400000000000000000000221421446772241200210510ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ActivationTestHelper.hpp" #include #include #include #include #include namespace armnnDelegate { void ActivationReLuTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; // Calculate output values for input. auto f = [](float value) { return std::fmax(0.0f, value); }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_RELU, backends, inputData, outputExpectedData); } void ActivationBoundedReluTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; const float a = 6.0f; const float b = 0.0f; // Calculate output values for input. auto f = [a, b](float value) { return std::min(a, std::max(b, value)); }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_RELU6, backends, inputData, outputExpectedData); } void ActivationSigmoidTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; // Calculate output values for input. auto f = [](float value) { return 1.0f / (1.0f + std::exp(-value)); }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_LOGISTIC, backends, inputData, outputExpectedData); } void ActivationTanHTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; // Calculate output values for input. auto f = [](float value) { return tanhf(value); }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_TANH, backends, inputData, outputExpectedData); } void ActivationEluTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; // Calculate output values for input. auto f = [](float value) { if (value < 0) { // alpha * (exp(x) - 1) return 1 * (std::exp(value) - 1); } return value; }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_ELU, backends, inputData, outputExpectedData); } void ActivationHardSwishTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; // Calculate output values for input. auto f = [](float x) { // Break down the calculation to help with verification. // hard_swish(x) = x * relu6(x+3) / 6 // relu6(x) = min(max(x,0),6) float reLu6_step1 = std::max((x + 3),0.0f); float reLu6Complete = std::min(reLu6_step1, 6.0f); float hardSwish_step1 = x * reLu6Complete; float result = hardSwish_step1 / 6; return result; }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_HARD_SWISH, backends, inputData, outputExpectedData); } void ActivationLeakyReLuTest(std::vector& backends) { std::vector inputData = { -0.1f, -0.2f, -0.3f, -0.4f, 0.1f, 0.2f, 0.3f, 0.4f, -1.0f, -2.0f, -3.0f, -4.0f, 1.0f, 2.0f, 3.0f, 4.0f }; float alpha = 0.3f; // Calculate output values for input. auto f = [alpha](float value) { return value > 0 ? value : value * alpha; }; std::vector outputExpectedData(inputData.size()); std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); ActivationTest(tflite::BuiltinOperator_LEAKY_RELU, backends, inputData, outputExpectedData, alpha); } TEST_SUITE("Activation_CpuRefTests") { TEST_CASE ("Activation_ReLu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationReLuTest(backends); } TEST_CASE ("Activation_Bounded_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationBoundedReluTest(backends); } TEST_CASE ("Activation_Sigmoid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationSigmoidTest(backends); } TEST_CASE ("Activation_TanH_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationTanHTest(backends); } TEST_CASE ("Activation_Elu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationEluTest(backends); } TEST_CASE ("Activation_HardSwish_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationHardSwishTest(backends); } TEST_CASE ("Activation_LeakyRelu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ActivationLeakyReLuTest(backends); } } TEST_SUITE("Activation_CpuAccTests") { TEST_CASE ("Activation_ReLu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationReLuTest(backends); } TEST_CASE ("Activation_Bounded_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationBoundedReluTest(backends); } TEST_CASE ("Activation_Sigmoid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationSigmoidTest(backends); } TEST_CASE ("Activation_TanH_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationTanHTest(backends); } TEST_CASE ("Activation_Elu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationEluTest(backends); } TEST_CASE ("Activation_HardSwish_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationHardSwishTest(backends); } TEST_CASE ("Activation_LeakyRelu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ActivationLeakyReLuTest(backends); } } TEST_SUITE("Activation_GpuAccTests") { TEST_CASE ("Activation_ReLu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationReLuTest(backends); } TEST_CASE ("Activation_Bounded_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationBoundedReluTest(backends); } TEST_CASE ("Activation_Sigmoid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationSigmoidTest(backends); } TEST_CASE ("Activation_TanH_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationTanHTest(backends); } TEST_CASE ("Activation_Elu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationEluTest(backends); } TEST_CASE ("Activation_HardSwish_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationHardSwishTest(backends); } TEST_CASE ("Activation_LeakyRelu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ActivationLeakyReLuTest(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/ActivationTestHelper.hpp000066400000000000000000000133071446772241200222210ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateActivationTfLiteModel(tflite::BuiltinOperator activationOperatorCode, tflite::TensorType tensorType, const std::vector & tensorShape, float alpha = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 1> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType); // create operator const std::vector operatorInputs{0}; const std::vector operatorOutputs{1}; // builtin options tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOption = 0; if (activationOperatorCode == tflite::BuiltinOperator_LEAKY_RELU) { operatorBuiltinOptionsType = tflite::BuiltinOptions_LeakyReluOptions; operatorBuiltinOption = CreateLeakyReluOptions(flatBufferBuilder, alpha).Union(); } flatbuffers::Offset unaryOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOption); const std::vector subgraphInputs{0}; const std::vector subgraphOutputs{1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&unaryOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Activation Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, activationOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void ActivationTest(tflite::BuiltinOperator activationOperatorCode, std::vector& backends, std::vector& inputValues, std::vector& expectedOutputValues, float alpha = 0) { using namespace delegateTestInterpreter; std::vector inputShape { { 4, 1, 4} }; std::vector modelBuffer = CreateActivationTfLiteModel(activationOperatorCode, ::tflite::TensorType_FLOAT32, inputShape, alpha); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, inputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ArgMinMaxTest.cpp000066400000000000000000000127561446772241200206050ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ArgMinMaxTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void ArgMaxFP32Test(std::vector& backends, int axisValue) { // Set input data std::vector inputShape { 1, 3, 2, 4 }; std::vector outputShape { 1, 3, 4 }; std::vector axisShape { 1 }; std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 100.0f, 200.0f, 300.0f, 400.0f, 500.0f, 600.0f, 700.0f, 800.0f }; std::vector expectedOutputValues = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; ArgMinMaxTest(tflite::BuiltinOperator_ARG_MAX, ::tflite::TensorType_FLOAT32, backends, inputShape, axisShape, outputShape, inputValues, expectedOutputValues, axisValue, ::tflite::TensorType_INT32); } void ArgMinFP32Test(std::vector& backends, int axisValue) { // Set input data std::vector inputShape { 1, 3, 2, 4 }; std::vector outputShape { 1, 3, 2 }; std::vector axisShape { 1 }; std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 100.0f, 200.0f, 300.0f, 400.0f, 500.0f, 600.0f, 700.0f, 800.0f }; std::vector expectedOutputValues = { 0, 0, 0, 0, 0, 0 }; ArgMinMaxTest(tflite::BuiltinOperator_ARG_MIN, ::tflite::TensorType_FLOAT32, backends, inputShape, axisShape, outputShape, inputValues, expectedOutputValues, axisValue, ::tflite::TensorType_INT32); } void ArgMaxUint8Test(std::vector& backends, int axisValue) { // Set input data std::vector inputShape { 1, 1, 1, 5 }; std::vector outputShape { 1, 1, 1 }; std::vector axisShape { 1 }; std::vector inputValues = { 5, 2, 8, 10, 9 }; std::vector expectedOutputValues = { 3 }; ArgMinMaxTest(tflite::BuiltinOperator_ARG_MAX, ::tflite::TensorType_UINT8, backends, inputShape, axisShape, outputShape, inputValues, expectedOutputValues, axisValue, ::tflite::TensorType_INT32); } TEST_SUITE("ArgMinMax_CpuRefTests") { TEST_CASE ("ArgMaxFP32Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ArgMaxFP32Test(backends, 2); } TEST_CASE ("ArgMinFP32Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ArgMinFP32Test(backends, 3); } TEST_CASE ("ArgMaxUint8Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ArgMaxUint8Test(backends, -1); } } // TEST_SUITE("ArgMinMax_CpuRefTests") TEST_SUITE("ArgMinMax_CpuAccTests") { TEST_CASE ("ArgMaxFP32Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ArgMaxFP32Test(backends, 2); } TEST_CASE ("ArgMinFP32Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ArgMinFP32Test(backends, 3); } TEST_CASE ("ArgMaxUint8Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ArgMaxUint8Test(backends, -1); } } // TEST_SUITE("ArgMinMax_CpuAccTests") TEST_SUITE("ArgMinMax_GpuAccTests") { TEST_CASE ("ArgMaxFP32Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ArgMaxFP32Test(backends, 2); } TEST_CASE ("ArgMinFP32Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ArgMinFP32Test(backends, 3); } TEST_CASE ("ArgMaxUint8Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ArgMaxUint8Test(backends, -1); } } // TEST_SUITE("ArgMinMax_GpuAccTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/ArgMinMaxTestHelper.hpp000066400000000000000000000215261446772241200217450ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreateArgMinMaxTfLiteModel(tflite::BuiltinOperator argMinMaxOperatorCode, tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& axisTensorShape, const std::vector& outputTensorShape, const std::vector axisValue, tflite::TensorType outputType, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); auto axisTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(axisTensorShape.data(), axisTensorShape.size()), tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("axis")); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), outputType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); std::vector> tensors = { inputTensor, axisTensor, outputTensor }; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(axisValue.data()), sizeof(OutputT)))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::vector operatorInputs = {{ 0, 1 }}; std::vector subgraphInputs = {{ 0, 1 }}; tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_ArgMaxOptions; flatbuffers::Offset operatorBuiltinOptions = CreateArgMaxOptions(flatBufferBuilder, outputType).Union(); if (argMinMaxOperatorCode == tflite::BuiltinOperator_ARG_MIN) { operatorBuiltinOptionsType = BuiltinOptions_ArgMinOptions; operatorBuiltinOptions = CreateArgMinOptions(flatBufferBuilder, outputType).Union(); } // create operator const std::vector operatorOutputs{ 2 }; flatbuffers::Offset argMinMaxOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&argMinMaxOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: ArgMinMax Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, argMinMaxOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ArgMinMaxTest(tflite::BuiltinOperator argMinMaxOperatorCode, tflite::TensorType tensorType, const std::vector& backends, const std::vector& inputShape, const std::vector& axisShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, OutputT axisValue, tflite::TensorType outputType, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateArgMinMaxTfLiteModel(argMinMaxOperatorCode, tensorType, inputShape, axisShape, outputShape, {axisValue}, outputType, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/BatchMatMulTest.cpp000066400000000000000000000702641446772241200211210ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "BatchMatMulTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void BatchMatMul2DFp32SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2, 2 }; std::vector RHSInputShape { 2, 2 }; std::vector outputShape { 2, 2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul2DInt8SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2, 2 }; std::vector RHSInputShape { 2, 2 }; std::vector outputShape { 2, 2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DFp32SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,2,2 }; std::vector RHSInputShape { 1,2,2 }; std::vector outputShape { 1,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DInt8SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,2,2 }; std::vector RHSInputShape { 1,2,2 }; std::vector outputShape { 1,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul4DFp32SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,1,2,2 }; std::vector RHSInputShape { 1,1,2,2 }; std::vector outputShape { 1,1,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul4DInt8SimpleTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,1,2,2}; std::vector RHSInputShape { 1,1,2,2 }; std::vector outputShape { 1,1,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4 }; std::vector RHSInputValues = { 5, 6, 7, 8 }; std::vector expectedOutputValues = { 19, 22, 43, 50 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DFp32BatchTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 5, 6, 7, 8, 13, 14, 15, 16 }; std::vector expectedOutputValues = { 19, 22, 43, 50, 267, 286, 323, 346 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DInt8BatchTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 5, 6, 7, 8, 1, 2, 3, 4 }; std::vector expectedOutputValues = { 19, 22, 43, 50, 39, 58, 47, 70 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DFp32BroadcastTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 13, 14, 15, 16 }; std::vector expectedOutputValues = { 43, 46, 99, 106, 267, 286, 323, 346 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3DInt8BroadcastTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 7, 10, 15, 22, 39, 58, 47, 70 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3D2DFp32BroadcastTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 13, 14, 15, 16 }; std::vector expectedOutputValues = { 43, 46, 99, 106, 267, 286, 323, 346 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul3D2DInt8BroadcastTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,2,2 }; std::vector RHSInputShape { 2,2 }; std::vector outputShape { 2,2,2 }; std::vector LHSInputValues = { 1, 2, 3, 4, 9, 10, 11, 12 }; std::vector RHSInputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 7, 10, 15, 22, 39, 58, 47, 70 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul2DFp32TinyTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,1 }; std::vector RHSInputShape { 1,1 }; std::vector outputShape { 1,1 }; std::vector LHSInputValues = { 3 }; std::vector RHSInputValues = { 5 }; std::vector expectedOutputValues = { 15 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul2DInt8TinyTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 1,1 }; std::vector RHSInputShape { 1,1 }; std::vector outputShape { 1,1 }; std::vector LHSInputValues = { 3 }; std::vector RHSInputValues = { 5 }; std::vector expectedOutputValues = { 15 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMulNonSquareFp32Test(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,5,3 }; std::vector RHSInputShape { 2,3,4 }; std::vector outputShape { 2,5,4 }; std::vector LHSInputValues = { 8, 8, 4, 6, 1, 3, 8, 8, 3, 8, 9, 8, 5, 4, 4, 1, 8, 5, 7, 1, 1, 8, 7, 9, 3, 2, 7, 8, 5, 3 }; std::vector RHSInputValues = { 6, 2, 3, 2, 6, 2, 2, 8, 3, 7, 8, 1, 7, 2, 9, 5, 2, 3, 1, 3, 2, 7, 7, 5 }; std::vector expectedOutputValues = { 108, 60, 72, 84, 51, 35, 44, 23, 105, 53, 64, 83, 126, 90, 106, 96, 66, 46, 55, 46, 33, 61, 52, 54, 53, 24, 71, 43, 88, 100, 142, 106, 39, 61, 78, 56, 72, 52, 98, 70 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMulNonSquareInt8Test(std::vector& backends) { // Set input data std::vector LHSInputShape { 2,5,3 }; std::vector RHSInputShape { 2,3,4 }; std::vector outputShape { 2,5,4 }; std::vector LHSInputValues = { 8, 8, 4, 6, 1, 3, 8, 8, 3, 8, 9, 8, 5, 4, 4, 1, 8, 5, 7, 1, 1, 8, 7, 9, 3, 2, 7, 8, 5, 3 }; std::vector RHSInputValues = { 6, 2, 3, 2, 6, 2, 2, 8, 3, 7, 8, 1, 7, 2, 3, 5, 2, 3, 1, 3, 2, 7, 7, 5 }; std::vector expectedOutputValues = { 108, 60, 72, 84, 51, 35, 44, 23, 105, 53, 64, 83, 126, 90, 106, 96, 66, 46, 55, 46, 33, 61, 46, 54, 53, 24, 29, 43, 88, 100, 94, 106, 39, 61, 60, 56, 72, 52, 50, 70 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, false, false); } void BatchMatMul2DFp32SimpleAdjointTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 3,3 }; std::vector RHSInputShape { 3,3 }; std::vector outputShape { 3,3 }; std::vector LHSInputValues = { 3, 1, 1, 1, 3, -1, 2, 4, 1 }; std::vector RHSInputValues = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; std::vector expectedOutputValues = { 3, 1, 2, 1, 3, 4, 1, -1, 1 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_FLOAT32, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, true, false); } void BatchMatMul2DInt8SimpleAdjointTest(std::vector& backends) { // Set input data std::vector LHSInputShape { 3,3 }; std::vector RHSInputShape { 3,3 }; std::vector outputShape { 3,3 }; std::vector LHSInputValues = { 3, 1, 1, 1, 3, -1, 2, 4, 1 }; std::vector RHSInputValues = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; std::vector expectedOutputValues = { 3, 1, 2, 1, 3, 4, 1, -1, 1 }; BatchMatMulTest(tflite::BuiltinOperator_BATCH_MATMUL, ::tflite::TensorType_INT8, backends, LHSInputShape, RHSInputShape, outputShape, LHSInputValues, RHSInputValues, expectedOutputValues, true, false); } TEST_SUITE("BATCH_MATMUL_CpuRefTests") { TEST_CASE("BATCH_MATMUL_Fp32_CpuRefTests") { std::vector backends = {armnn::Compute::CpuRef}; BatchMatMul2DFp32SimpleTest (backends); BatchMatMul3DFp32SimpleTest (backends); BatchMatMul4DFp32SimpleTest (backends); BatchMatMul3DFp32BatchTest (backends); BatchMatMul3DFp32BroadcastTest (backends); BatchMatMul3D2DFp32BroadcastTest (backends); BatchMatMul2DFp32TinyTest (backends); BatchMatMulNonSquareFp32Test (backends); BatchMatMul2DFp32SimpleAdjointTest(backends); } TEST_CASE("BATCH_MATMUL_Int8_CpuRefTests") { std::vector backends = {armnn::Compute::CpuRef}; BatchMatMul2DInt8SimpleTest (backends); BatchMatMul3DInt8SimpleTest (backends); BatchMatMul4DInt8SimpleTest (backends); BatchMatMul3DInt8BatchTest (backends); BatchMatMul3DInt8BroadcastTest (backends); BatchMatMul3D2DInt8BroadcastTest (backends); BatchMatMul2DInt8TinyTest (backends); BatchMatMulNonSquareInt8Test (backends); BatchMatMul2DInt8SimpleAdjointTest(backends); } } TEST_SUITE("BATCH_MATMUL_CpuAccTests") { TEST_CASE("BATCH_MATMUL_Fp32_CpuAccTests") { std::vector backends = {armnn::Compute::CpuAcc}; BatchMatMul2DFp32SimpleTest (backends); BatchMatMul3DFp32SimpleTest (backends); BatchMatMul4DFp32SimpleTest (backends); BatchMatMul3DFp32BatchTest (backends); BatchMatMul2DFp32TinyTest (backends); BatchMatMulNonSquareFp32Test (backends); BatchMatMul2DFp32SimpleAdjointTest(backends); } TEST_CASE("BATCH_MATMUL_Int8_CpuAccTests") { std::vector backends = {armnn::Compute::CpuAcc}; BatchMatMul2DInt8SimpleTest (backends); BatchMatMul3DInt8SimpleTest (backends); BatchMatMul4DInt8SimpleTest (backends); BatchMatMul3DInt8BatchTest (backends); BatchMatMul2DInt8TinyTest (backends); BatchMatMulNonSquareInt8Test (backends); BatchMatMul2DInt8SimpleAdjointTest(backends); } } TEST_SUITE("BATCH_MATMUL_GpuAccTests") { TEST_CASE("BATCH_MATMUL_Fp32_GpuAccTests") { std::vector backends = {armnn::Compute::GpuAcc}; BatchMatMul2DFp32SimpleTest (backends); BatchMatMul3DFp32SimpleTest (backends); BatchMatMul4DFp32SimpleTest (backends); BatchMatMul3DFp32BatchTest (backends); BatchMatMul2DFp32TinyTest (backends); BatchMatMulNonSquareFp32Test (backends); BatchMatMul2DFp32SimpleAdjointTest(backends); } TEST_CASE("BATCH_MATMUL_Int8_GpuAccTests") { std::vector backends = {armnn::Compute::GpuAcc}; BatchMatMul2DInt8SimpleTest (backends); BatchMatMul3DInt8SimpleTest (backends); BatchMatMul3DInt8BatchTest (backends); BatchMatMul2DInt8TinyTest (backends); BatchMatMulNonSquareInt8Test (backends); BatchMatMul2DInt8SimpleAdjointTest(backends); } } } armnn-23.08/delegate/test/BatchMatMulTestHelper.hpp000066400000000000000000000204101446772241200222520ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateBatchMatMulTfLiteModel( tflite::BuiltinOperator bmmOperatorCode, tflite::TensorType tensorType, const std::vector & LHSInputTensorShape, const std::vector & RHSInputTensorShape, const std::vector & outputTensorShape, bool adjX = false, bool adjY = false, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(LHSInputTensorShape.data(), LHSInputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("LHSInput"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(RHSInputTensorShape.data(), RHSInputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("RHSInput"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_BatchMatMulOptions; flatbuffers::Offset operatorBuiltinOptions = CreateBatchMatMulOptions(flatBufferBuilder, adjX, adjY).Union(); const std::vector operatorInputs{{0, 1}}; const std::vector operatorOutputs{2}; flatbuffers::Offset bmmOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{{0, 1}}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&bmmOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: BatchMatMul Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, bmmOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void BatchMatMulTest(tflite::BuiltinOperator bmmOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& LHSInputShape, std::vector& RHSInputShape, std::vector& outputShape, std::vector& LHSInputValues, std::vector& RHSInputValues, std::vector& expectedOutputValues, bool adjX = false, bool adjY = false, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateBatchMatMulTfLiteModel(bmmOperatorCode, tensorType, LHSInputShape, RHSInputShape, outputShape, adjX, adjY, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(LHSInputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(RHSInputValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(LHSInputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(RHSInputValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/BatchSpaceTest.cpp000066400000000000000000000222441446772241200207500ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "BatchSpaceTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // BatchToSpaceND Operator void BatchToSpaceNDFp32Test(std::vector& backends) { std::vector inputShape { 4, 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector expectedOutputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector blockShape({2, 2}); std::vector> crops = {{0, 0}, {0, 0}}; BatchSpaceTest(tflite::BuiltinOperator_BATCH_TO_SPACE_ND, ::tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, blockShape, crops, expectedOutputValues); } void BatchToSpaceNDFp32BatchOneTest(std::vector& backends) { std::vector inputShape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector expectedOutputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector blockShape({1, 1}); std::vector> crops = {{0, 0}, {0, 0}}; BatchSpaceTest(tflite::BuiltinOperator_BATCH_TO_SPACE_ND, ::tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, blockShape, crops, expectedOutputValues); } void BatchToSpaceNDUint8Test(std::vector& backends) { std::vector inputShape { 4, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector inputValues { 1, 2, 3, 4, 5, 6, 7 }; std::vector expectedOutputValues { 1, 2, 3, 4, 5, 6, 7 }; std::vector blockShape({2, 2}); std::vector> crops = {{0, 0}, {0, 0}}; BatchSpaceTest(tflite::BuiltinOperator_BATCH_TO_SPACE_ND, ::tflite::TensorType_UINT8, backends, inputShape, expectedOutputShape, inputValues, blockShape, crops, expectedOutputValues); } // SpaceToBatchND Operator void SpaceToBatchNDFp32Test(std::vector& backends) { std::vector inputShape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 4, 1, 1, 1 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector expectedOutputValues { 1.0f, 2.0f, 3.0f, 4.0f }; std::vector blockShape({2, 2}); std::vector> padding = {{0, 0}, {0, 0}}; BatchSpaceTest(tflite::BuiltinOperator_SPACE_TO_BATCH_ND, ::tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, blockShape, padding, expectedOutputValues); } void SpaceToBatchNDFp32PaddingTest(std::vector& backends) { std::vector inputShape { 2, 2, 4, 1 }; std::vector expectedOutputShape { 8, 1, 3, 1 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f }; std::vector expectedOutputValues { 0.0f, 1.0f, 3.0f, 0.0f, 9.0f, 11.0f, 0.0f, 2.0f, 4.0f, 0.0f, 10.0f, 12.0f, 0.0f, 5.0f, 7.0f, 0.0f, 13.0f, 15.0f, 0.0f, 6.0f, 8.0f, 0.0f, 14.0f, 16.0f }; std::vector blockShape({2, 2}); std::vector> padding = {{0, 0}, {2, 0}}; BatchSpaceTest(tflite::BuiltinOperator_SPACE_TO_BATCH_ND, ::tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, blockShape, padding, expectedOutputValues); } void SpaceToBatchNDUint8Test(std::vector& backends) { std::vector inputShape { 1, 2, 2, 3 }; std::vector expectedOutputShape { 4, 1, 1, 3 }; std::vector inputValues { 1, 2, 3, 4, 5, 6, 7 }; std::vector expectedOutputValues { 1, 2, 3, 4, 5, 6, 7 }; std::vector blockShape({2, 2}); std::vector> padding = {{0, 0}, {0, 0}}; BatchSpaceTest(tflite::BuiltinOperator_SPACE_TO_BATCH_ND, ::tflite::TensorType_UINT8, backends, inputShape, expectedOutputShape, inputValues, blockShape, padding, expectedOutputValues); } // BatchToSpaceND Tests TEST_SUITE("BatchToSpaceND_CpuAccTests") { TEST_CASE ("BatchToSpaceND_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; BatchToSpaceNDFp32Test(backends); } TEST_CASE ("BatchToSpaceND_Fp32_BatchOne_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; BatchToSpaceNDFp32BatchOneTest(backends); } TEST_CASE ("BatchToSpaceND_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; BatchToSpaceNDUint8Test(backends); } } TEST_SUITE("BatchToSpaceND_GpuAccTests") { TEST_CASE ("BatchToSpaceND_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; BatchToSpaceNDFp32Test(backends); } TEST_CASE ("BatchToSpaceND_Fp32_BatchOne_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; BatchToSpaceNDFp32BatchOneTest(backends); } TEST_CASE ("BatchToSpaceND_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; BatchToSpaceNDUint8Test(backends); } } TEST_SUITE("BatchToSpaceND_CpuRefTests") { TEST_CASE ("BatchToSpaceND_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; BatchToSpaceNDFp32Test(backends); } TEST_CASE ("BatchToSpaceND_Fp32_BatchOne_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; BatchToSpaceNDFp32BatchOneTest(backends); } TEST_CASE ("BatchToSpaceND_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; BatchToSpaceNDUint8Test(backends); } } // SpaceToBatchND Tests TEST_SUITE("SpaceToBatchND_CpuAccTests") { TEST_CASE ("SpaceToBatchND_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SpaceToBatchNDFp32Test(backends); } TEST_CASE ("SpaceToBatchND_Fp32_Padding_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SpaceToBatchNDFp32PaddingTest(backends); } TEST_CASE ("SpaceToBatchND_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SpaceToBatchNDUint8Test(backends); } } TEST_SUITE("SpaceToBatchND_GpuAccTests") { TEST_CASE ("SpaceToBatchND_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SpaceToBatchNDFp32Test(backends); } TEST_CASE ("SpaceToBatchND_Fp32_Padding_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SpaceToBatchNDFp32PaddingTest(backends); } TEST_CASE ("SpaceToBatchND_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SpaceToBatchNDUint8Test(backends); } } TEST_SUITE("SpaceToBatchND_CpuRefTests") { TEST_CASE ("SpaceToBatchND_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SpaceToBatchNDFp32Test(backends); } TEST_CASE ("SpaceToBatchND_Fp32_Padding_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SpaceToBatchNDFp32PaddingTest(backends); } TEST_CASE ("SpaceToBatchND_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SpaceToBatchNDUint8Test(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/BatchSpaceTestHelper.hpp000066400000000000000000000233521446772241200221160ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateBatchSpaceTfLiteModel(tflite::BuiltinOperator batchSpaceOperatorCode, tflite::TensorType tensorType, std::vector& inputTensorShape, std::vector & outputTensorShape, std::vector& blockData, std::vector>& cropsPadData, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 5> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder); buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(blockData.data()), sizeof(int32_t) * blockData.size())); buffers[3] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cropsPadData.data()), sizeof(int64_t) * cropsPadData.size())); buffers[4] = CreateBuffer(flatBufferBuilder); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::string cropsOrPadding = batchSpaceOperatorCode == tflite::BuiltinOperator_BATCH_TO_SPACE_ND ? "crops" : "padding"; std::vector blockShape { 2 }; std::vector cropsOrPaddingShape { 2, 2 }; std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(blockShape.data(), blockShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("block"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(cropsOrPaddingShape.data(), cropsOrPaddingShape.size()), ::tflite::TensorType_INT32, 3, flatBufferBuilder.CreateString(cropsOrPadding), quantizationParameters); // Create output tensor tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 4, flatBufferBuilder.CreateString("output"), quantizationParameters); // Create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOptions = 0; switch (batchSpaceOperatorCode) { case tflite::BuiltinOperator_BATCH_TO_SPACE_ND: { operatorBuiltinOptionsType = tflite::BuiltinOptions_BatchToSpaceNDOptions; operatorBuiltinOptions = CreateBatchToSpaceNDOptions(flatBufferBuilder).Union(); break; } case tflite::BuiltinOperator_SPACE_TO_BATCH_ND: { operatorBuiltinOptionsType = tflite::BuiltinOptions_SpaceToBatchNDOptions; operatorBuiltinOptions = CreateSpaceToBatchNDOptions(flatBufferBuilder).Union(); break; } default: break; } const std::vector operatorInputs{ {0, 1, 2} }; const std::vector operatorOutputs{ 3 }; flatbuffers::Offset batchSpaceOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1, 2} }; const std::vector subgraphOutputs{ 3 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&batchSpaceOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: BatchSpace Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, batchSpaceOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void BatchSpaceTest(tflite::BuiltinOperator controlOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& expectedOutputShape, std::vector& inputValues, std::vector& blockShapeValues, std::vector>& cropsPaddingValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateBatchSpaceTfLiteModel(controlOperatorCode, tensorType, inputShape, expectedOutputShape, blockShapeValues, cropsPaddingValues, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/CastTest.cpp000066400000000000000000000051031446772241200176400ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "CastTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void CastUint8ToFp32Test(std::vector& backends) { std::vector inputShape {1, 3, 2, 3}; std::vector inputValues { 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 2, 1, 3, 1, 3 }; std::vector expectedOutputValues { 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 2.0f, 1.0f, 3.0f, 1.0f, 3.0f }; CastTest(::tflite::TensorType_UINT8, ::tflite::TensorType_FLOAT32, backends, inputShape, inputValues, expectedOutputValues); } void CastInt32ToFp32Test(std::vector& backends) { std::vector inputShape {1, 3, 2, 3}; std::vector inputValues { -1, -3, -1, -3, -1, -3, -1, -3, 1, 3, 1, 3, 1, 2, 1, 3, 1, 3 }; std::vector expectedOutputValues { -1.0f, -3.0f, -1.0f, -3.0f, -1.0f, -3.0f, -1.0f, -3.0f, 1.0f, 3.0f, 1.0f, 3.0f, 1.0f, 2.0f, 1.0f, 3.0f, 1.0f, 3.0f }; CastTest(::tflite::TensorType_INT32, ::tflite::TensorType_FLOAT32, backends, inputShape, inputValues, expectedOutputValues); } // CAST Test Suite TEST_SUITE("CAST_CpuRefTests") { TEST_CASE ("CAST_UINT8_TO_FP32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; CastUint8ToFp32Test(backends); } TEST_CASE ("CAST_INT32_TO_FP32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; CastInt32ToFp32Test(backends); } } TEST_SUITE("CAST_CpuAccTests") { TEST_CASE ("CAST_INT32_TO_FP32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; CastInt32ToFp32Test(backends); } } TEST_SUITE("CAST_GpuAccTests") { TEST_CASE ("CAST_INT32_TO_FP32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; CastInt32ToFp32Test(backends); } } // End of CAST Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/CastTestHelper.hpp000066400000000000000000000145261446772241200210160ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateCastTfLiteModel(tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, const std::vector & tensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), outputTensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); const std::vector operatorInputs({0}); const std::vector operatorOutputs({1}); flatbuffers::Offset castOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_CastOptions, CreateCastOptions(flatBufferBuilder).Union()); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: CAST Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_CAST); const std::vector subgraphInputs({0}); const std::vector subgraphOutputs({1}); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&castOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void CastTest(tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, std::vector& backends, std::vector& shape, std::vector& inputValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateCastTfLiteModel(inputTensorType, outputTensorType, shape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, shape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/ComparisonTest.cpp000066400000000000000000000617101446772241200210660ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ComparisonTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void EqualFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1.f, 1.f, 1.f, 1.f, 5.f, 5.f, 5.f, 5.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f }; std::vector input1Values = { 1.f, 1.f, 1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 5.f, 5.f, 5.f, 5.f, 4.f, 4.f, 4.f, 4.f }; std::vector expectedOutputValues = { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1 }; ComparisonTest(tflite::BuiltinOperator_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void EqualBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; // Set output data std::vector expectedOutputValues { 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; ComparisonTest(tflite::BuiltinOperator_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void EqualInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 4 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { 1, 0, 0, 1 }; ComparisonTest(tflite::BuiltinOperator_EQUAL, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void NotEqualFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1.f, 1.f, 1.f, 1.f, 5.f, 5.f, 5.f, 5.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f }; std::vector input1Values = { 1.f, 1.f, 1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 5.f, 5.f, 5.f, 5.f, 4.f, 4.f, 4.f, 4.f }; std::vector expectedOutputValues = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }; ComparisonTest(tflite::BuiltinOperator_NOT_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void NotEqualBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; // Set output data std::vector expectedOutputValues { 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; ComparisonTest(tflite::BuiltinOperator_NOT_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void NotEqualInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 4 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { 0, 1, 1, 0 }; ComparisonTest(tflite::BuiltinOperator_NOT_EQUAL, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterFP32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 4 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { 0, 1, 0, 0 }; ComparisonTest(tflite::BuiltinOperator_GREATER, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; std::vector expectedOutputValues { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 }; ComparisonTest(tflite::BuiltinOperator_GREATER, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 4 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { 0, 1, 0, 0 }; ComparisonTest(tflite::BuiltinOperator_GREATER, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterEqualFP32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1.f, 5.f, 6.f, 4.f }; std::vector input1Values = { 1.f, 3.f, 9.f, 4.f }; std::vector expectedOutputValues = { true, true, false, true }; ComparisonTest(tflite::BuiltinOperator_GREATER_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterEqualBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; // Set output data std::vector expectedOutputValues { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; ComparisonTest(tflite::BuiltinOperator_GREATER_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void GreaterEqualInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 3 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { 1, 1, 0, 0 }; ComparisonTest(tflite::BuiltinOperator_GREATER_EQUAL, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessFP32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1.f, 5.f, 6.f, 4.f }; std::vector input1Values = { 1.f, 3.f, 9.f, 4.f }; std::vector expectedOutputValues = { false, false, true, false }; ComparisonTest(tflite::BuiltinOperator_LESS, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; std::vector expectedOutputValues { true, true, true, false, false, false, false, false, false, false, false, false }; ComparisonTest(tflite::BuiltinOperator_LESS, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 3 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { false, false, true, true }; ComparisonTest(tflite::BuiltinOperator_LESS, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessEqualFP32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1.f, 5.f, 6.f, 4.f }; std::vector input1Values = { 1.f, 3.f, 9.f, 4.f }; std::vector expectedOutputValues = { true, false, true, true }; ComparisonTest(tflite::BuiltinOperator_LESS_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessEqualBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f }; std::vector input1Values { 4.f, 5.f, 6.f }; std::vector expectedOutputValues { true, true, true, true, true, true, false, false, false, false, false, false }; ComparisonTest(tflite::BuiltinOperator_LESS_EQUAL, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LessEqualInt32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values = { 1, 5, 6, 3 }; std::vector input1Values = { 1, 3, 9, 4 }; std::vector expectedOutputValues = { true, false, true, true }; ComparisonTest(tflite::BuiltinOperator_LESS_EQUAL, ::tflite::TensorType_INT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } TEST_SUITE("Comparison_CpuRefTests") { TEST_CASE ("EQUAL_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; EqualFP32Test(backends); } TEST_CASE ("EQUAL_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; EqualBroadcastTest(backends); } TEST_CASE ("EQUAL_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; EqualInt32Test(backends); } TEST_CASE ("NOT_EQUAL_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; NotEqualFP32Test(backends); } TEST_CASE ("NOT_EQUAL_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; NotEqualBroadcastTest(backends); } TEST_CASE ("NOT_EQUAL_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; NotEqualInt32Test(backends); } TEST_CASE ("GREATER_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterFP32Test(backends); } TEST_CASE ("GREATER_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterBroadcastTest(backends); } TEST_CASE ("GREATER_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterInt32Test(backends); } TEST_CASE ("GREATER_EQUAL_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterEqualFP32Test(backends); } TEST_CASE ("GREATER_EQUAL_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterEqualBroadcastTest(backends); } TEST_CASE ("GREATER_EQUAL_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; GreaterEqualInt32Test(backends); } TEST_CASE ("LESS_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessFP32Test(backends); } TEST_CASE ("LESS_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessBroadcastTest(backends); } TEST_CASE ("LESS_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessInt32Test(backends); } TEST_CASE ("LESS_EQUAL_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessEqualFP32Test(backends); } TEST_CASE ("LESS_EQUAL_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessEqualBroadcastTest(backends); } TEST_CASE ("LESS_EQUAL_INT32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LessEqualInt32Test(backends); } } // End TEST_SUITE("Comparison_CpuRefTests") TEST_SUITE("Comparison_GpuAccTests") { TEST_CASE ("EQUAL_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; EqualFP32Test(backends); } TEST_CASE ("EQUAL_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; EqualBroadcastTest(backends); } TEST_CASE ("EQUAL_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; EqualInt32Test(backends); } TEST_CASE ("NOT_EQUAL_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; NotEqualFP32Test(backends); } TEST_CASE ("NOT_EQUAL_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; NotEqualBroadcastTest(backends); } TEST_CASE ("NOT_EQUAL_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; NotEqualInt32Test(backends); } TEST_CASE ("GREATER_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc, armnn::Compute::CpuRef }; GreaterFP32Test(backends); } TEST_CASE ("GREATER_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc, armnn::Compute::CpuRef }; GreaterBroadcastTest(backends); } TEST_CASE ("GREATER_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc, armnn::Compute::CpuRef }; GreaterInt32Test(backends); } TEST_CASE ("GREATER_EQUAL_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; GreaterEqualFP32Test(backends); } TEST_CASE ("GREATER_EQUAL_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; GreaterEqualBroadcastTest(backends); } TEST_CASE ("GREATER_EQUAL_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; GreaterEqualInt32Test(backends); } TEST_CASE ("LESS_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessFP32Test(backends); } TEST_CASE ("LESS_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessBroadcastTest(backends); } TEST_CASE ("LESS_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessInt32Test(backends); } TEST_CASE ("LESS_EQUAL_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessEqualFP32Test(backends); } TEST_CASE ("LESS_EQUAL_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessEqualBroadcastTest(backends); } TEST_CASE ("LESS_EQUAL_INT32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LessEqualInt32Test(backends); } } // End TEST_SUITE("Comparison_GpuAccTests") TEST_SUITE("Comparison_CpuAccTests") { TEST_CASE ("EQUAL_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; EqualFP32Test(backends); } TEST_CASE ("EQUAL_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; EqualBroadcastTest(backends); } TEST_CASE ("EQUAL_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; EqualInt32Test(backends); } TEST_CASE ("NOT_EQUAL_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; NotEqualFP32Test(backends); } TEST_CASE ("NOT_EQUAL_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; NotEqualBroadcastTest(backends); } TEST_CASE ("NOT_EQUAL_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; NotEqualInt32Test(backends); } TEST_CASE ("GREATER_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterFP32Test(backends); } TEST_CASE ("GREATER_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterBroadcastTest(backends); } TEST_CASE ("GREATER_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterInt32Test(backends); } TEST_CASE ("GREATER_EQUAL_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterEqualFP32Test(backends); } TEST_CASE ("GREATER_EQUAL_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterEqualBroadcastTest(backends); } TEST_CASE ("GREATER_EQUAL_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; GreaterEqualInt32Test(backends); } TEST_CASE ("LESS_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessFP32Test(backends); } TEST_CASE ("LESS_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessBroadcastTest(backends); } TEST_CASE ("LESS_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessInt32Test(backends); } TEST_CASE ("LESS_EQUAL_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessEqualFP32Test(backends); } TEST_CASE ("LESS_EQUAL_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessEqualBroadcastTest(backends); } TEST_CASE ("LESS_EQUAL_INT32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LessEqualInt32Test(backends); } } // End TEST_SUITE("Comparison_CpuAccTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/ComparisonTestHelper.hpp000066400000000000000000000225641446772241200222370ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateComparisonTfLiteModel(tflite::BuiltinOperator comparisonOperatorCode, tflite::TensorType tensorType, const std::vector & input0TensorShape, const std::vector & input1TensorShape, const std::vector & outputTensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input1TensorShape.data(), input1TensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("input_1"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), ::tflite::TensorType_BOOL, 3); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_EqualOptions;; flatbuffers::Offset operatorBuiltinOptions = CreateEqualOptions(flatBufferBuilder).Union(); switch (comparisonOperatorCode) { case BuiltinOperator_EQUAL: { operatorBuiltinOptionsType = BuiltinOptions_EqualOptions; operatorBuiltinOptions = CreateEqualOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_NOT_EQUAL: { operatorBuiltinOptionsType = BuiltinOptions_NotEqualOptions; operatorBuiltinOptions = CreateNotEqualOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_GREATER: { operatorBuiltinOptionsType = BuiltinOptions_GreaterOptions; operatorBuiltinOptions = CreateGreaterOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_GREATER_EQUAL: { operatorBuiltinOptionsType = BuiltinOptions_GreaterEqualOptions; operatorBuiltinOptions = CreateGreaterEqualOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_LESS: { operatorBuiltinOptionsType = BuiltinOptions_LessOptions; operatorBuiltinOptions = CreateLessOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_LESS_EQUAL: { operatorBuiltinOptionsType = BuiltinOptions_LessEqualOptions; operatorBuiltinOptions = CreateLessEqualOptions(flatBufferBuilder).Union(); break; } default: break; } const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset comparisonOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&comparisonOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Comparison Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, comparisonOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ComparisonTest(tflite::BuiltinOperator comparisonOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& input0Shape, std::vector& input1Shape, std::vector& outputShape, std::vector& input0Values, std::vector& input1Values, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateComparisonTfLiteModel(comparisonOperatorCode, tensorType, input0Shape, input1Shape, outputShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareData(expectedOutputValues, armnnOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(expectedOutputValues, tfLiteOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues.size()); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ControlTest.cpp000066400000000000000000000305401446772241200203710ustar00rootroot00000000000000// // Copyright © 2020,2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ControlTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // CONCATENATION Operator void ConcatUint8TwoInputsTest(std::vector& backends) { std::vector inputShape { 2, 2 }; std::vector expectedOutputShape { 4, 2 }; // Set input and output data std::vector> inputValues; std::vector inputValue1 { 0, 1, 2, 3 }; // Lower bounds std::vector inputValue2 { 252, 253, 254, 255 }; // Upper bounds inputValues.push_back(inputValue1); inputValues.push_back(inputValue2); std::vector expectedOutputValues { 0, 1, 2, 3, 252, 253, 254, 255 }; ConcatenationTest(tflite::BuiltinOperator_CONCATENATION, ::tflite::TensorType_UINT8, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues); } void ConcatInt16TwoInputsTest(std::vector& backends) { std::vector inputShape { 2, 2 }; std::vector expectedOutputShape { 4, 2 }; std::vector> inputValues; std::vector inputValue1 { -32768, -16384, -1, 0 }; std::vector inputValue2 { 1, 2, 16384, 32767 }; inputValues.push_back(inputValue1); inputValues.push_back(inputValue2); std::vector expectedOutputValues { -32768, -16384, -1, 0, 1, 2, 16384, 32767}; ConcatenationTest(tflite::BuiltinOperator_CONCATENATION, ::tflite::TensorType_INT16, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues); } void ConcatFloat32TwoInputsTest(std::vector& backends) { std::vector inputShape { 2, 2 }; std::vector expectedOutputShape { 4, 2 }; std::vector> inputValues; std::vector inputValue1 { -127.f, -126.f, -1.f, 0.f }; std::vector inputValue2 { 1.f, 2.f, 126.f, 127.f }; inputValues.push_back(inputValue1); inputValues.push_back(inputValue2); std::vector expectedOutputValues { -127.f, -126.f, -1.f, 0.f, 1.f, 2.f, 126.f, 127.f }; ConcatenationTest(tflite::BuiltinOperator_CONCATENATION, ::tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues); } void ConcatThreeInputsTest(std::vector& backends) { std::vector inputShape { 2, 2 }; std::vector expectedOutputShape { 6, 2 }; std::vector> inputValues; std::vector inputValue1 { 0, 1, 2, 3 }; std::vector inputValue2 { 125, 126, 127, 128 }; std::vector inputValue3 { 252, 253, 254, 255 }; inputValues.push_back(inputValue1); inputValues.push_back(inputValue2); inputValues.push_back(inputValue3); std::vector expectedOutputValues { 0, 1, 2, 3, 125, 126, 127, 128, 252, 253, 254, 255 }; ConcatenationTest(tflite::BuiltinOperator_CONCATENATION, ::tflite::TensorType_UINT8, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues); } void ConcatAxisTest(std::vector& backends) { std::vector inputShape { 1, 2, 2 }; std::vector expectedOutputShape { 1, 2, 4 }; std::vector> inputValues; std::vector inputValue1 { 0, 1, 2, 3 }; std::vector inputValue3 { 252, 253, 254, 255 }; inputValues.push_back(inputValue1); inputValues.push_back(inputValue3); std::vector expectedOutputValues { 0, 1, 252, 253, 2, 3, 254, 255 }; ConcatenationTest(tflite::BuiltinOperator_CONCATENATION, ::tflite::TensorType_UINT8, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 2); } // MEAN Operator void MeanUint8KeepDimsTest(std::vector& backends) { std::vector input0Shape { 1, 3 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1 }; std::vector input0Values { 5, 10, 15 }; // Inputs std::vector input1Values { 1 }; // Axis std::vector expectedOutputValues { 10 }; MeanTest(tflite::BuiltinOperator_MEAN, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, true); } void MeanUint8Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 2, 2 }; std::vector input0Values { 5, 10, 15, 20 }; // Inputs std::vector input1Values { 0 }; // Axis std::vector expectedOutputValues { 5, 10, 15, 20 }; MeanTest(tflite::BuiltinOperator_MEAN, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, false); } void MeanFp32KeepDimsTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1, 2 }; std::vector input0Values { 1.0f, 1.5f, 2.0f, 2.5f }; // Inputs std::vector input1Values { 1 }; // Axis std::vector expectedOutputValues { 1.5f, 2.0f }; MeanTest(tflite::BuiltinOperator_MEAN, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, true); } void MeanFp32Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 2, 1 }; std::vector input0Values { 1.0f, 1.5f, 2.0f, 2.5f }; // Inputs std::vector input1Values { 2 }; // Axis std::vector expectedOutputValues { 1.25f, 2.25f }; MeanTest(tflite::BuiltinOperator_MEAN, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, false); } // CONCATENATION Tests. TEST_SUITE("Concatenation_CpuAccTests") { TEST_CASE ("Concatenation_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; ConcatUint8TwoInputsTest(backends); } TEST_CASE ("Concatenation_Int16_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; ConcatInt16TwoInputsTest(backends); } TEST_CASE ("Concatenation_Float32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; ConcatFloat32TwoInputsTest(backends); } TEST_CASE ("Concatenation_Three_Inputs_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; ConcatThreeInputsTest(backends); } TEST_CASE ("Concatenation_Axis_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; ConcatAxisTest(backends); } } TEST_SUITE("Concatenation_GpuAccTests") { TEST_CASE ("Concatenation_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; ConcatUint8TwoInputsTest(backends); } TEST_CASE ("Concatenation_Int16_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; ConcatInt16TwoInputsTest(backends); } TEST_CASE ("Concatenation_Float32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; ConcatFloat32TwoInputsTest(backends); } TEST_CASE ("Concatenation_Three_Inputs_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; ConcatThreeInputsTest(backends); } TEST_CASE ("Concatenation_Axis_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; ConcatAxisTest(backends); } } TEST_SUITE("Concatenation_CpuRefTests") { TEST_CASE ("Concatenation_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; ConcatUint8TwoInputsTest(backends); } TEST_CASE ("Concatenation_Int16_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; ConcatInt16TwoInputsTest(backends); } TEST_CASE ("Concatenation_Float32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; ConcatFloat32TwoInputsTest(backends); } TEST_CASE ("Concatenation_Three_Inputs_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; ConcatThreeInputsTest(backends); } TEST_CASE ("Concatenation_Axis_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; ConcatAxisTest(backends); } } // MEAN Tests TEST_SUITE("Mean_CpuAccTests") { TEST_CASE ("Mean_Uint8_KeepDims_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; MeanUint8KeepDimsTest(backends); } TEST_CASE ("Mean_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; MeanUint8Test(backends); } TEST_CASE ("Mean_Fp32_KeepDims_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; MeanFp32KeepDimsTest(backends); } TEST_CASE ("Mean_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; MeanFp32Test(backends); } } TEST_SUITE("Mean_GpuAccTests") { TEST_CASE ("Mean_Uint8_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; MeanUint8KeepDimsTest(backends); } TEST_CASE ("Mean_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; MeanUint8Test(backends); } TEST_CASE ("Mean_Fp32_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; MeanFp32KeepDimsTest(backends); } TEST_CASE ("Mean_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; MeanFp32Test(backends); } } TEST_SUITE("Mean_CpuRefTests") { TEST_CASE ("Mean_Uint8_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; MeanUint8KeepDimsTest(backends); } TEST_CASE ("Mean_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; MeanUint8Test(backends); } TEST_CASE ("Mean_Fp32_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; MeanFp32KeepDimsTest(backends); } TEST_CASE ("Mean_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; MeanFp32Test(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/ControlTestHelper.hpp000066400000000000000000000364761446772241200215540ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateConcatTfLiteModel(tflite::BuiltinOperator controlOperatorCode, tflite::TensorType tensorType, std::vector& inputTensorShape, const std::vector & outputTensorShape, const int32_t inputTensorNum, int32_t axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::vector operatorInputs{}; const std::vector operatorOutputs{inputTensorNum}; std::vector subgraphInputs{}; const std::vector subgraphOutputs{inputTensorNum}; std::vector> tensors(inputTensorNum + 1); for (int i = 0; i < inputTensorNum; ++i) { tensors[i] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input" + std::to_string(i)), quantizationParameters); // Add number of inputs to vector. operatorInputs.push_back(i); subgraphInputs.push_back(i); } // Create output tensor tensors[inputTensorNum] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_ConcatenationOptions; flatbuffers::Offset operatorBuiltinOptions = CreateConcatenationOptions(flatBufferBuilder, axis).Union(); flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Concatenation Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, controlOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } std::vector CreateMeanTfLiteModel(tflite::BuiltinOperator controlOperatorCode, tflite::TensorType tensorType, std::vector& input0TensorShape, std::vector& input1TensorShape, const std::vector & outputTensorShape, std::vector& axisData, const bool keepDims, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 2> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(axisData.data()), sizeof(int32_t) * axisData.size())); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input1TensorShape.data(), input1TensorShape.size()), ::tflite::TensorType_INT32, 1, flatBufferBuilder.CreateString("axis"), quantizationParameters); // Create output tensor tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator. Mean uses ReducerOptions. tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_ReducerOptions; flatbuffers::Offset operatorBuiltinOptions = CreateReducerOptions(flatBufferBuilder, keepDims).Union(); const std::vector operatorInputs{ {0, 1} }; const std::vector operatorOutputs{ 2 }; flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1} }; const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Mean Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, controlOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ConcatenationTest(tflite::BuiltinOperator controlOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShapes, std::vector& expectedOutputShape, std::vector>& inputValues, std::vector& expectedOutputValues, int32_t axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateConcatTfLiteModel(controlOperatorCode, tensorType, inputShapes, expectedOutputShape, inputValues.size(), axis, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); for (unsigned int i = 0; i < inputValues.size(); ++i) { CHECK(tfLiteInterpreter.FillInputTensor(inputValues[i], i) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues[i], i) == kTfLiteOk); } CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } template void MeanTest(tflite::BuiltinOperator controlOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& input0Shape, std::vector& input1Shape, std::vector& expectedOutputShape, std::vector& input0Values, std::vector& input1Values, std::vector& expectedOutputValues, const bool keepDims, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateMeanTfLiteModel(controlOperatorCode, tensorType, input0Shape, input1Shape, expectedOutputShape, input1Values, keepDims, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/Convolution2dTest.cpp000066400000000000000000000323161446772241200215210ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ConvolutionTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void Conv2DWithBiasesFp32Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 5, 5, 1 }; std::vector filterShape { 1, 3, 3, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 3, 3, 1 }; static std::vector inputValues = { 1, 5, 2, 3, 5, 8, 7, 3, 6, 3, 3, 3, 9, 1, 9, 4, 1, 8, 1, 3, 6, 8, 1, 9, 2 }; std::vector filterValues = { 4, 5, 6, 0, 0, 0, 3, 2, 1 }; std::vector biasValues = { 0 }; std::vector expectedOutputValues = { 23, 33, 24, 91, 99, 48, 26, 50, 19 }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_CONV_2D, ::tflite::TensorType_FLOAT32, 2, // strideX 2, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv2DWithBiasesInt8Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector filterShape { 1, 2, 2, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 2, 2, 1 }; static std::vector inputValues = { 1, 2, 3, 4 }; std::vector filterValues = { 2, 1, 0, 6 }; std::vector biasValues = { 10 }; std::vector expectedOutputValues = { (1 * 2 + 2 * 1 + 3 * 0 + 4 * 6 + 10) / 2, // 19 (2 * 2 + 0 * 1 + 4 * 0 + 0 * 6 + 10) / 2, // 7 (3 * 2 + 4 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 10 (4 * 2 + 0 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 9 }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_CONV_2D, ::tflite::TensorType_INT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv2DWithBiasesReluUint8Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector filterShape { 1, 2, 2, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 2, 2, 1 }; static std::vector inputValues = { 1, 2, 4, 8 }; std::vector filterValues = { 2, 1, 0, 6 }; std::vector biasValues = { 16 }; // factors to consider: // - the filter zero point is non zero, hence the (x-fz) // - the output scale is 2 hence the /2 // - output zero point is non zero, hence the +outZero // - RELU cuts negative values and then we add the output zero point uint8_t bias = 16; uint8_t outZero = 20; uint8_t fz = 4; // filter zero point std::vector expectedOutputValues = { std::max(outZero, static_cast((1*(2-fz) + 2*(1-fz) + 4*(0-fz) + 8*(6-fz) + bias)/2 + outZero)), std::max(outZero, static_cast((2*(2-fz) + 0*(1-fz) + 8*(0-fz) + 0*(6-fz) + bias)/2 + outZero)), std::max(outZero, static_cast((4*(2-fz) + 8*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero)), std::max(outZero, static_cast((8*(2-fz) + 0*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero)) }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_CONV_2D, ::tflite::TensorType_UINT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_RELU, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues, {1.0f}, // biasScale {0}, // biasOffset {1.0f}, // filterScale {4}, // filterOffsets 2, // output scale 20); // output offset } void Conv2DWithBiasesRelu6Uint8Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector filterShape { 1, 2, 2, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 2, 2, 1 }; static std::vector inputValues = { 1, 2, 4, 1 }; std::vector filterValues = { 2, 1, 0, 6 }; std::vector biasValues = { 0 }; // factors to consider: // - the output scale is 2 hence the /2 // - RELU6 cuts output values at +6 uint8_t relu6Min = 6 / 2; // divide by output scale std::vector expectedOutputValues = { std::min(relu6Min, static_cast((1 * 2 + 2 * 1 + 4 * 0 + 1 * 6) / 2)), std::min(relu6Min, static_cast((2 * 2 + 0 * 1 + 1 * 0 + 0 * 6) / 2)), std::min(relu6Min, static_cast((4 * 2 + 1 * 1 + 0 * 0 + 0 * 6) / 2)), std::min(relu6Min, static_cast((1 * 2 + 0 * 1 + 0 * 0 + 0 * 6) / 2)) }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_CONV_2D, ::tflite::TensorType_UINT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_RELU6, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv2DPerChannelInt8Test(std::vector& backends) { // Set input data std::vector inputShape { 1,4,4,2 }; std::vector filterShape { 4,2,2,2 }; std::vector biasShape { 4 }; std::vector outputShape { 1,4,4,4 }; static std::vector inputValues = { -11, 40,-26, 11,-28, 8, 0, -8, -10, 34, 47, 0,-33,-14, 28, 35, 6,-28,-26, 8, 13, 33,-31,-41, 31,-20,-31,-16, 8,-18,-44, 0 }; std::vector filterScales = { 1.858268, 2.0, 1.992126, 1.905512 }; int32_t filterQuantizationDim = 0; std::vector filterValues = { 13,-44, 5,-14, 21,-45, 36,-25, -42, -2, 24,-30,-31, 35, 43,-30, -20, -5, 25, 17, 18, 20, 4,-46, -49, 9, -3,-20, 46, 5, 7,-15 }; std::vector biasValues = { 0,0,0,0 }; std::vector biasScales = { 0.721445, 0.7764700055, 0.773414, 0.739787 }; std::vector expectedOutputValues = { -1, 9, 3, 5, 1, -1, 5, 9, 2, 7, -1, 2, 2, 4, 5, 6, 1, 1, 4, 4, 2, 0, -4, -3, 0, 6, 12, 6, 3, 0, -1, -2, 7, -4, 4, 4, 3, 6, 6, 2, 0, -3, -1, 4, 4, 8, 3, 1, 5, 0, 0, 1, 4, 7, 4, 6, 4, 0, 1, 2, 2, 7, 5, 7 }; float outputQuantScale = 401.960785f; int outputQuantOffset = 3; float inputQuantScale = 0.388235f; int inputQuantOffset = 1; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_CONV_2D, ::tflite::TensorType_INT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues, biasScales, {0,0,0,0}, filterScales, {0,0,0,0}, outputQuantScale, outputQuantOffset, inputQuantScale, inputQuantOffset, 1, // depth_multiplier is ignored for conv2d value doesn't matter filterQuantizationDim); } TEST_SUITE("Convolution2dTest_CpuRefTests") { TEST_CASE ("Conv2DWithBiases_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv2DWithBiasesFp32Test(backends); } TEST_CASE ("Conv2DWithBiases_Int8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv2DWithBiasesInt8Test(backends); } TEST_CASE ("Conv2DPerChannel_Int8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv2DPerChannelInt8Test(backends); } } //End of TEST_SUITE("Convolution2dTest_CpuRef") TEST_SUITE("Convolution2dTest_CpuAccTests") { TEST_CASE ("Conv2DWithBiases_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv2DWithBiasesFp32Test(backends); } TEST_CASE ("Conv2DWithBiases_Int8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv2DWithBiasesInt8Test(backends); } TEST_CASE ("Conv2DPerChannel_Int8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv2DPerChannelInt8Test(backends); } } //End of TEST_SUITE("Convolution2dTest_CpuAcc") TEST_SUITE("Convolution2dTest_GpuAccTests") { TEST_CASE ("Conv2DWithBiases_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv2DWithBiasesFp32Test(backends); } TEST_CASE ("Conv2DWithBiases_Int8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv2DWithBiasesInt8Test(backends); } TEST_CASE ("Conv2DPerChannel_Int8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv2DPerChannelInt8Test(backends); } } //End of TEST_SUITE("Convolution2dTest_GpuAcc") } // namespace armnnDelegatearmnn-23.08/delegate/test/Convolution3dTest.cpp000066400000000000000000000240561446772241200215240ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ConvolutionTestHelper.hpp" #include #include #include #include #include #include #include namespace armnnDelegate { // Conv3d is currently only supports Float32 inputs, filter, bias and outputs in TFLite. // Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. #if defined(ARMNN_POST_TFLITE_2_5) // Create a vector from 0 to size divided to create smaller floating point values. template std::vector CreateFloatData(int32_t size, float divisor) { std::vector data; for (int32_t i = 0; i < size; ++i) { float value = static_cast(i); data.push_back(value/divisor); } return data; } void Conv3DWithBiasesSimpleWithPaddingFp32Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 2, 1 }; std::vector filterShape { 2, 2, 2, 1, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 2, 2, 2, 1 }; static std::vector inputValues = { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f }; std::vector filterValues = { 2.f,1.f, 1.f,0.f, 0.f,1.f, 1.f,1.f }; std::vector biasValues = { 5.f }; std::vector expectedOutputValues = { 33.f, 21.f, 23.f, 13.f, 28.f, 25.f, 27.f, 21.f }; Convolution3dTest(tflite::BuiltinOperator_CONV_3D, ::tflite::TensorType_FLOAT32, { 1, 1, 1 }, // strideX, strideY, strideZ { 1, 1, 1 }, // dilationX, dilationY, dilationZ tflite::Padding_SAME, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv3DWithBiasesStridesFp32Test(std::vector& backends) { std::vector inputShape { 1, 3, 10, 10, 1 }; std::vector filterShape { 3, 5, 5, 1, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 1, 3, 3, 1 }; std::vector inputValues = CreateFloatData(300, 1.0f); std::vector filterValues = { 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f, 2.f }; std::vector biasValues = { 10.f }; std::vector expectedOutputValues = { 11660.f, 11810.f, 11960.f, 13160.f, 13310.f, 13460.f, 14660.f, 14810.f, 14960.f }; Convolution3dTest(tflite::BuiltinOperator_CONV_3D, ::tflite::TensorType_FLOAT32, { 2, 2, 2 }, // strideX, strideY, strideZ { 1, 1, 1 }, // dilationX, dilationY, dilationZ tflite::Padding_VALID, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv3DWithBiasesDilationFp32Test(std::vector& backends) { std::vector inputShape { 1, 5, 5, 5, 2 }; std::vector filterShape { 2, 2, 2, 2, 2 }; std::vector biasShape { 2 }; std::vector outputShape { 1, 2, 2, 2, 2 }; std::vector inputValues = CreateFloatData(250, 1.0f); std::vector filterValues = { -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, -1.f, 1.f, 1.f, -1.f, 1.f, -1.f, 1.f, -1.f, 1.f, -1.f, -1.f, -1.f, 1.f, -1.f, 1.f, -1.f, 1.f, }; std::vector biasValues = { 0.f, 2.f }; // Since the dilation rate is 3 this will dilate the kernel to be 4x4, // therefore the output will be 2x2 std::vector expectedOutputValues = { -1124.f, 976.f, -1148.f, 980.f, -1244.f, 996.f, -1268.f, 1000.f, -1724.f, 1076.f, -1748.f, 1080.f, -1844.f, 1096.f, -1868.f, 1100.f }; Convolution3dTest(tflite::BuiltinOperator_CONV_3D, ::tflite::TensorType_FLOAT32, { 1, 1, 1 }, // strideX, strideY, strideZ { 3, 3, 3 }, // dilationX, dilationY, dilationZ tflite::Padding_VALID, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void Conv3DFp32SmallTest(std::vector& backends) { std::vector inputShape { 1, 3, 10, 10, 1 }; std::vector filterShape { 3, 3, 3, 1, 1 }; std::vector biasShape { 1 }; std::vector outputShape { 1, 1, 4, 4, 1 }; std::vector inputValues = CreateFloatData(300, 100.0f); std::vector filterValues = { 0.125977f, 0.150391f, 0.101562f, 0.0585938f, 0.0864258f, 0.043457f, 0.034668f, 0.0322266f, 0.0385742f, 0.125977f, 0.150391f, -0.101562f, -0.0585938f,-0.0864258f,-0.043457f, -0.0104630f, 0.0154114f, 0.0013768f, 0.0344238f, 0.035644f, 0.0495605f, 0.0683594f, 0.099121f, -0.0461426f, -0.0996094f,-0.126953f, -0.043457f, }; std::vector biasValues = { 0 }; std::vector expectedOutputValues = { -0.08156067f, -0.06891209f, -0.05589598f, -0.04310101f, 0.04584253f, 0.05855697f, 0.07129729f, 0.08325434f, 0.17304349f, 0.18521416f, 0.19818866f, 0.21096253f, 0.29965734f, 0.312698f, 0.32547557f, 0.33818722f }; Convolution3dTest(tflite::BuiltinOperator_CONV_3D, ::tflite::TensorType_FLOAT32, { 2, 2, 2 }, // strideX, strideY, strideZ { 1, 1, 1 }, // dilationX, dilationY, dilationZ tflite::Padding_VALID, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } TEST_SUITE("Convolution3dTest_CpuRefTests") { TEST_CASE ("Conv3DWithBiasesSimpleWithPadding_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv3DWithBiasesSimpleWithPaddingFp32Test(backends); } TEST_CASE ("Conv3DWithBiasesStrides_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv3DWithBiasesStridesFp32Test(backends); } TEST_CASE ("Conv3DWithBiasesDilation_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv3DWithBiasesDilationFp32Test(backends); } TEST_CASE ("Conv3DFp32Small_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; Conv3DFp32SmallTest(backends); } } //End of TEST_SUITE("Convolution3dTest_CpuRefTests") TEST_SUITE("Convolution3dTest_CpuAccTests") { TEST_CASE ("Conv3DWithBiasesSimpleWithPadding_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv3DWithBiasesSimpleWithPaddingFp32Test(backends); } TEST_CASE ("Conv3DWithBiasesStrides_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv3DWithBiasesStridesFp32Test(backends); } TEST_CASE ("Conv3DFp32Small_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; Conv3DFp32SmallTest(backends); } } //End of TEST_SUITE("Convolution3dTest_CpuAccTests") TEST_SUITE("Convolution3dTest_GpuAccTests") { TEST_CASE ("Conv3DWithBiasesSimpleWithPadding_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv3DWithBiasesSimpleWithPaddingFp32Test(backends); } TEST_CASE ("Conv3DWithBiasesStrides_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv3DWithBiasesStridesFp32Test(backends); } TEST_CASE ("Conv3DFp32Small_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; Conv3DFp32SmallTest(backends); } } //End of TEST_SUITE("Convolution3dTest_GpuAccTests") #endif } // namespace armnnDelegatearmnn-23.08/delegate/test/ConvolutionTestHelper.hpp000066400000000000000000001144161446772241200224420ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include #include #include namespace { template std::vector CreateConv2dTfLiteModel(tflite::BuiltinOperator convolutionOperatorCode, tflite::TensorType tensorType, uint32_t strideX, uint32_t strideY, uint32_t dilationX, uint32_t dilationY, tflite::Padding padding, tflite::ActivationFunctionType fused_activation_function, const std::vector & inputTensorShape, const std::vector & filterTensorShape, const std::vector & biasTensorShape, const std::vector & outputTensorShape, const std::vector & filterData, const std::vector & biasData, const std::vector biasScales = {1.0f}, const std::vector biasOffsets = {0}, const std::vector filterScales = {1.0f}, const std::vector filterOffsets = {0}, float outputQuantScale = 2.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0, int32_t depth_multiplier = 1, int32_t filterQuantizationDim = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 5> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder); buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(filterData.data()), sizeof(T) * filterData.size())); buffers[3] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(biasData.data()), sizeof(B) * biasData.size())); buffers[4] = CreateBuffer(flatBufferBuilder); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto outputQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ outputQuantScale }), flatBufferBuilder.CreateVector({ outputQuantOffset })); auto filterQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector(filterScales), flatBufferBuilder.CreateVector(filterOffsets), tflite::QuantizationDetails_NONE, 0, filterQuantizationDim); auto biasQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector(biasScales), flatBufferBuilder.CreateVector(biasOffsets)); std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(filterTensorShape.data(), filterTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("filter"), filterQuantizationParameters); auto biasTensorType = ::tflite::TensorType_FLOAT32; if (tensorType == ::tflite::TensorType_INT8 || tensorType == ::tflite::TensorType_UINT8) { biasTensorType = ::tflite::TensorType_INT32; } tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(biasTensorShape.data(), biasTensorShape.size()), biasTensorType, 3, flatBufferBuilder.CreateString("bias"), biasQuantizationParameters); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 4, flatBufferBuilder.CreateString("output"), outputQuantizationParameters); flatbuffers::Offset operatorBuiltinOptions; tflite::BuiltinOptions operatorBuiltinOptionsType; if(convolutionOperatorCode == tflite::BuiltinOperator_DEPTHWISE_CONV_2D) { operatorBuiltinOptionsType = tflite::BuiltinOptions_DepthwiseConv2DOptions; operatorBuiltinOptions = CreateDepthwiseConv2DOptions(flatBufferBuilder, padding, strideX, strideY, depth_multiplier, fused_activation_function, dilationX, dilationY).Union(); } if(convolutionOperatorCode == tflite::BuiltinOperator_CONV_2D) { operatorBuiltinOptionsType = tflite::BuiltinOptions_Conv2DOptions; operatorBuiltinOptions = CreateConv2DOptions(flatBufferBuilder, padding, strideX, strideY, fused_activation_function, dilationX, dilationY).Union(); } // create operator const std::vector operatorInputs{0, 1, 2}; const std::vector operatorOutputs{3}; flatbuffers::Offset convolutionOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1, 2}; const std::vector subgraphOutputs{3}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&convolutionOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Convolution2d Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, convolutionOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ConvolutionTest(tflite::BuiltinOperator convolutionOperatorCode, tflite::TensorType tensorType, uint32_t strideX, uint32_t strideY, uint32_t dilationX, uint32_t dilationY, tflite::Padding padding, tflite::ActivationFunctionType fused_activation_function, std::vector& backends, std::vector& inputShape, std::vector& filterShape, std::vector& outputShape, std::vector& inputValues, std::vector& filterValues, std::vector& expectedOutputValues, const std::vector& biasShape = {}, const std::vector& biasValues = {}, const std::vector biasScales = {1.0f}, const std::vector biasOffsets = {0}, const std::vector filterScales = {1.0f}, const std::vector filterOffsets = {0}, float outputQuantScale = 2.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0, int32_t depth_multiplier = 1, int32_t filterQuantizationDim = 3) { using namespace delegateTestInterpreter; std::vector modelBuffer; modelBuffer = CreateConv2dTfLiteModel(convolutionOperatorCode, tensorType, strideX, strideY, dilationX, dilationY, padding, fused_activation_function, inputShape, filterShape, biasShape, outputShape, filterValues, biasValues, biasScales, biasOffsets, filterScales, filterOffsets, outputQuantScale, outputQuantOffset, quantScale, quantOffset, depth_multiplier, filterQuantizationDim); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // Conv3d is only correctly supported for external delegates from TF Lite v2.6, as there was a breaking bug in v2.5. #if defined(ARMNN_POST_TFLITE_2_5) template std::vector CreateConv3dTfLiteModel(tflite::BuiltinOperator convolutionOperatorCode, tflite::TensorType tensorType, std::vector strides, std::vector dilation, tflite::Padding padding, tflite::ActivationFunctionType fused_activation_function, const std::vector& inputTensorShape, const std::vector& filterTensorShape, const std::vector& biasTensorShape, const std::vector& outputTensorShape, const std::vector& filterData, const std::vector& biasData, const std::vector biasScales = {1.0f}, const std::vector biasOffsets = {0}, const std::vector filterScales = {1.0f}, const std::vector filterOffsets = {0}, float outputQuantScale = 2.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0, int32_t depth_multiplier = 1, int32_t filterQuantizationDim = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 3> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(filterData.data()), sizeof(T) * filterData.size())); buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(biasData.data()), sizeof(B) * biasData.size())); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto outputQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ outputQuantScale }), flatBufferBuilder.CreateVector({ outputQuantOffset })); auto filterQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector(filterScales), flatBufferBuilder.CreateVector(filterOffsets), tflite::QuantizationDetails_NONE, 0, filterQuantizationDim); auto biasQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector(biasScales), flatBufferBuilder.CreateVector(biasOffsets)); std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(filterTensorShape.data(), filterTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("filter"), filterQuantizationParameters); auto biasTensorType = ::tflite::TensorType_FLOAT32; if (tensorType == ::tflite::TensorType_INT8 || tensorType == ::tflite::TensorType_UINT8) { biasTensorType = ::tflite::TensorType_INT32; } tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(biasTensorShape.data(), biasTensorShape.size()), biasTensorType, 2, flatBufferBuilder.CreateString("bias"), biasQuantizationParameters); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), outputQuantizationParameters); tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_Conv3DOptions; flatbuffers::Offset operatorBuiltinOptions = CreateConv3DOptions(flatBufferBuilder, padding, strides[2], // Depth strides[0], // Width strides[1], // Height fused_activation_function, dilation[2], dilation[0], dilation[1]).Union(); // Create operator const std::vector operatorInputs{0, 1, 2}; const std::vector operatorOutputs{3}; flatbuffers::Offset convolutionOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1, 2}; const std::vector subgraphOutputs{3}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&convolutionOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Convolution 3d Operator Model"); // If using an operator with a code greater than 127 then the enum value should be passed as the fifth // parameter rather than the second like in other tests. flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, 0, 0, 1, tflite::BuiltinOperator_CONV_3D); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void Convolution3dTest(tflite::BuiltinOperator convolutionOperatorCode, tflite::TensorType tensorType, std::vector strides, std::vector dilation, tflite::Padding padding, tflite::ActivationFunctionType fused_activation_function, std::vector& backends, std::vector& inputShape, std::vector& filterShape, std::vector& outputShape, std::vector& inputValues, std::vector& filterValues, std::vector& expectedOutputValues, const std::vector& biasShape = {}, const std::vector& biasValues = {}, const std::vector biasScales = {1.0f}, const std::vector biasOffsets = {0}, const std::vector filterScales = {1.0f}, const std::vector filterOffsets = {0}, float outputQuantScale = 2.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0, int32_t depth_multiplier = 1, int32_t filterQuantizationDim = 3) { using namespace delegateTestInterpreter; std::vector modelBuffer; modelBuffer = CreateConv3dTfLiteModel(convolutionOperatorCode, tensorType, strides, dilation, padding, fused_activation_function, inputShape, filterShape, biasShape, outputShape, filterValues, biasValues, biasScales, biasOffsets, filterScales, filterOffsets, outputQuantScale, outputQuantOffset, quantScale, quantOffset, depth_multiplier, filterQuantizationDim); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); armnnDelegate::CompareData(expectedOutputValues.data(), armnnOutputValues.data(), expectedOutputValues.size(), 1); armnnDelegate::CompareData(expectedOutputValues.data(), tfLiteOutputValues.data(), expectedOutputValues.size(), 1); armnnDelegate::CompareData(tfLiteOutputValues.data(), armnnOutputValues.data(), expectedOutputValues.size(), 1); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } #endif template std::vector CreateTransposeConvTfLiteModel(tflite::TensorType tensorType, uint32_t strideX, uint32_t strideY, tflite::Padding padding, const std::vector & transposeTensorShape, const std::vector & filterTensorShape, const std::vector & inputTensorShape, const std::vector & outputTensorShape, const std::vector & transposeData, const std::vector & filterData, float filterScale = 1.0f, int filterOffset = 0, float outputQuantScale = 2.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 3> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(transposeData.data()), sizeof(int32_t) * transposeData.size())); buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(filterData.data()), sizeof(T) * filterData.size())); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto outputQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ outputQuantScale }), flatBufferBuilder.CreateVector({ outputQuantOffset })); auto filterQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ filterScale }), flatBufferBuilder.CreateVector({ filterOffset })); std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(transposeTensorShape.data(), transposeTensorShape.size()), tflite::TensorType_INT32, 1); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(filterTensorShape.data(), filterTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("filter"), filterQuantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), outputQuantizationParameters); tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_TransposeConvOptions; flatbuffers::Offset operatorBuiltinOptions = CreateTransposeConvOptions(flatBufferBuilder, padding, strideX, strideY).Union(); // create operator const std::vector operatorInputs{0, 1, 2}; const std::vector operatorOutputs{3}; flatbuffers::Offset convolutionOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1, 2}; const std::vector subgraphOutputs{3}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&convolutionOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: TransposeConv Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_TRANSPOSE_CONV); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void TransposeConvTest(std::vector& backends, tflite::TensorType tensorType, uint32_t strideX, uint32_t strideY, tflite::Padding padding, const std::vector & transposeTensorShape, const std::vector & filterTensorShape, const std::vector & inputTensorShape, const std::vector & outputTensorShape, const std::vector & transposeData, const std::vector & filterData, std::vector& inputValues, std::vector& expectedOutputValues, float filterScale = 1.0f, int filterOffset = 0, float outputQuantScale = 1.0f, int outputQuantOffset = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer; modelBuffer = CreateTransposeConvTfLiteModel(tensorType, strideX, strideY, padding, transposeTensorShape, filterTensorShape, inputTensorShape, outputTensorShape, transposeData, filterData, filterScale, filterOffset, outputQuantScale, outputQuantOffset, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 2) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 2) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/DelegateOptionsTest.cpp000066400000000000000000000363541446772241200220500ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "DelegateOptionsTestHelper.hpp" #include #include namespace armnnDelegate { TEST_SUITE("DelegateOptions") { TEST_CASE ("ArmnnDelegateOptimizerOptionsReduceFp32ToFp16") { std::stringstream ss; { StreamRedirector redirect(std::cout, ss.rdbuf()); std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; // Enable ReduceFp32ToFp16 armnn::OptimizerOptionsOpaque optimizerOptions(true, true, false, false); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); DelegateOptionTest(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } // ReduceFp32ToFp16 option is enabled CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos); } TEST_CASE ("ArmnnDelegateOptimizerOptionsDebug") { std::stringstream ss; { StreamRedirector redirect(std::cout, ss.rdbuf()); std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; // Enable Debug armnn::OptimizerOptionsOpaque optimizerOptions(false, true, false, false); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); DelegateOptionTest(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } // Debug option triggered. CHECK(ss.str().find("layerGuid") != std::string::npos); CHECK(ss.str().find("layerName") != std::string::npos); CHECK(ss.str().find("outputSlot") != std::string::npos); CHECK(ss.str().find("shape") != std::string::npos); CHECK(ss.str().find("data") != std::string::npos); } TEST_CASE ("ArmnnDelegateOptimizerOptionsDebugFunction") { std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; // Enable debug with debug callback function armnn::OptimizerOptionsOpaque optimizerOptions(false, true, false, false); bool callback = false; auto mockCallback = [&](LayerGuid guid, unsigned int slotIndex, armnn::ITensorHandle* tensor) { armnn::IgnoreUnused(guid); armnn::IgnoreUnused(slotIndex); armnn::IgnoreUnused(tensor); callback = true; }; armnn::INetworkProperties networkProperties(false, armnn::MemorySource::Undefined, armnn::MemorySource::Undefined); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions, armnn::EmptyOptional(), armnn::Optional(mockCallback)); CHECK(!callback); DelegateOptionTest(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); // Check that the debug callback function was called. CHECK(callback); } TEST_CASE ("ArmnnDelegateOptimizerOptionsImport") { std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; armnn::OptimizerOptionsOpaque optimizerOptions(false, false, false, true); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); DelegateOptionTest(::tflite::TensorType_UINT8, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } TEST_CASE ("ArmnnDelegateStringParsingOptionDisableTfLiteRuntimeFallback") { std::stringstream stringStream; std::vector keys { "backends", "debug-data", "disable-tflite-runtime-fallback"}; std::vector values { "CpuRef", "1", "1"}; std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 0.1f, -2.1f, 3.0f, -4.6f }; std::vector expectedResult = { 1.0f, -2.0f, 3.0f, -4.0f }; // Create options_keys and options_values char array size_t num_options = keys.size(); std::unique_ptr options_keys = std::unique_ptr(new const char*[num_options + 1]); std::unique_ptr options_values = std::unique_ptr(new const char*[num_options + 1]); for (size_t i=0; i(::tflite::TensorType_FLOAT32, tensorShape, inputData, expectedResult, delegateOptions); CHECK(stringStream.str().find("TfLiteArmnnDelegate: There are unsupported operators in the model") != std::string::npos); } TEST_CASE ("ArmnnDelegateStringParsingOptionEnableTfLiteRuntimeFallback") { std::stringstream stringStream; std::vector keys { "backends", "debug-data", "disable-tflite-runtime-fallback"}; std::vector values { "CpuRef", "1", "0"}; std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 0.1f, -2.1f, 3.0f, -4.6f }; std::vector expectedResult = { 0.995004177f, -0.504846036f, -0.989992499f, -0.112152621f }; // Create options_keys and options_values char array size_t num_options = keys.size(); std::unique_ptr options_keys = std::unique_ptr(new const char*[num_options + 1]); std::unique_ptr options_values = std::unique_ptr(new const char*[num_options + 1]); for (size_t i=0; i(::tflite::TensorType_FLOAT32, tensorShape, inputData, expectedResult, delegateOptions); CHECK(stringStream.str().find("TfLiteArmnnDelegate: There are unsupported operators in the model") == std::string::npos); } } TEST_SUITE("DelegateOptions_CpuAccTests") { TEST_CASE ("ArmnnDelegateModelOptions_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; unsigned int numberOfThreads = 2; armnn::ModelOptions modelOptions; armnn::BackendOptions cpuAcc("CpuAcc", { { "FastMathEnabled", true }, { "NumberOfThreads", numberOfThreads } }); modelOptions.push_back(cpuAcc); armnn::OptimizerOptionsOpaque optimizerOptions(false, false, false, false, modelOptions, false); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); DelegateOptionTest(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } TEST_CASE ("ArmnnDelegateSerializeToDot") { const fs::path filename(fs::temp_directory_path() / "ArmnnDelegateSerializeToDot.dot"); if ( fs::exists(filename) ) { fs::remove(filename); } std::stringstream ss; { StreamRedirector redirect(std::cout, ss.rdbuf()); std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; armnn::OptimizerOptionsOpaque optimizerOptions(false, false, false, false); armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions); // Enable serialize to dot by specifying the target file name. delegateOptions.SetSerializeToDot(filename); DelegateOptionTest(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } CHECK(fs::exists(filename)); // The file should have a size greater than 0 bytes. CHECK(fs::file_size(filename) > 0); // Clean up. fs::remove(filename); } void CreateFp16StringParsingTestRun(std::vector& keys, std::vector& values, std::stringstream& ss) { StreamRedirector redirect(std::cout, ss.rdbuf()); std::vector backends = { armnn::Compute::CpuRef }; std::vector tensorShape { 1, 2, 2, 1 }; std::vector inputData = { 1, 2, 3, 4 }; std::vector divData = { 2, 2, 3, 4 }; std::vector expectedResult = { 1, 2, 2, 2 }; // Create options_keys and options_values char array size_t num_options = keys.size(); std::unique_ptr options_keys = std::unique_ptr(new const char*[num_options + 1]); std::unique_ptr options_values = std::unique_ptr(new const char*[num_options + 1]); for (size_t i=0; i(::tflite::TensorType_FLOAT32, tensorShape, inputData, inputData, divData, expectedResult, delegateOptions); } TEST_CASE ("ArmnnDelegateStringParsingOptionReduceFp32ToFp16") { SUBCASE("Fp16=1") { std::stringstream ss; std::vector keys { "backends", "debug-data", "reduce-fp32-to-fp16", "logging-severity"}; std::vector values { "CpuRef", "1", "1", "info"}; CreateFp16StringParsingTestRun(keys, values, ss); CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos); } SUBCASE("Fp16=true") { std::stringstream ss; std::vector keys { "backends", "debug-data", "reduce-fp32-to-fp16"}; std::vector values { "CpuRef", "TRUE", "true"}; CreateFp16StringParsingTestRun(keys, values, ss); CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos); } SUBCASE("Fp16=True") { std::stringstream ss; std::vector keys { "backends", "debug-data", "reduce-fp32-to-fp16"}; std::vector values { "CpuRef", "true", "True"}; CreateFp16StringParsingTestRun(keys, values, ss); CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos); } SUBCASE("Fp16=0") { std::stringstream ss; std::vector keys { "backends", "debug-data", "reduce-fp32-to-fp16"}; std::vector values { "CpuRef", "true", "0"}; CreateFp16StringParsingTestRun(keys, values, ss); CHECK(ss.str().find("convert_fp32_to_fp16") == std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") == std::string::npos); } SUBCASE("Fp16=false") { std::stringstream ss; std::vector keys { "backends", "debug-data", "reduce-fp32-to-fp16"}; std::vector values { "CpuRef", "1", "false"}; CreateFp16StringParsingTestRun(keys, values, ss); CHECK(ss.str().find("convert_fp32_to_fp16") == std::string::npos); CHECK(ss.str().find("convert_fp16_to_fp32") == std::string::npos); } } } } // namespace armnnDelegate armnn-23.08/delegate/test/DelegateOptionsTestHelper.hpp000066400000000000000000000364401446772241200232110ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { struct StreamRedirector { public: StreamRedirector(std::ostream &stream, std::streambuf *newStreamBuffer) : m_Stream(stream), m_BackupBuffer(m_Stream.rdbuf(newStreamBuffer)) {} ~StreamRedirector() { m_Stream.rdbuf(m_BackupBuffer); } private: std::ostream &m_Stream; std::streambuf *m_BackupBuffer; }; std::vector CreateAddDivTfLiteModel(tflite::TensorType tensorType, const std::vector& tensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 5> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("input_1"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("input_2"), quantizationParameters); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 4, flatBufferBuilder.CreateString("add"), quantizationParameters); tensors[4] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 5, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions addBuiltinOptionsType = tflite::BuiltinOptions_AddOptions; flatbuffers::Offset addBuiltinOptions = CreateAddOptions(flatBufferBuilder, ActivationFunctionType_NONE).Union(); tflite::BuiltinOptions divBuiltinOptionsType = tflite::BuiltinOptions_DivOptions; flatbuffers::Offset divBuiltinOptions = CreateAddOptions(flatBufferBuilder, ActivationFunctionType_NONE).Union(); std::array, 2> operators; const std::vector addInputs{0, 1}; const std::vector addOutputs{3}; operators[0] = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(addInputs.data(), addInputs.size()), flatBufferBuilder.CreateVector(addOutputs.data(), addOutputs.size()), addBuiltinOptionsType, addBuiltinOptions); const std::vector divInputs{3, 2}; const std::vector divOutputs{4}; operators[1] = CreateOperator(flatBufferBuilder, 1, flatBufferBuilder.CreateVector(divInputs.data(), divInputs.size()), flatBufferBuilder.CreateVector(divOutputs.data(), divOutputs.size()), divBuiltinOptionsType, divBuiltinOptions); const std::vector subgraphInputs{0, 1, 2}; const std::vector subgraphOutputs{4}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(operators.data(), operators.size())); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Add and Div Operator Model"); std::array, 2> codes; codes[0] = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_ADD); codes[1] = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_DIV); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(codes.data(), codes.size()), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } std::vector CreateCosTfLiteModel(tflite::TensorType tensorType, const std::vector & tensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), quantizationParameters); const std::vector operatorInputs({0}); const std::vector operatorOutputs({1}); flatbuffers::Offset ceilOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_NONE); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: CEIL Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_COS); const std::vector subgraphInputs({0}); const std::vector subgraphOutputs({1}); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&ceilOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void DelegateOptionTest(tflite::TensorType tensorType, std::vector& tensorShape, std::vector& input0Values, std::vector& input1Values, std::vector& input2Values, std::vector& expectedOutputValues, const armnnDelegate::DelegateOptions& delegateOptions, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateAddDivTfLiteModel(tensorType, tensorShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input2Values, 2) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, delegateOptions); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input2Values, 2) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, tensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } template void DelegateOptionNoFallbackTest(tflite::TensorType tensorType, std::vector& tensorShape, std::vector& inputValues, std::vector& expectedOutputValues, const armnnDelegate::DelegateOptions& delegateOptions, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateCosTfLiteModel(tensorType, tensorShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); tfLiteInterpreter.Cleanup(); try { auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, delegateOptions); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnInterpreter.Cleanup(); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, tensorShape); } catch (const armnn::Exception& e) { // Forward the exception message to std::cout std::cout << e.what() << std::endl; } } } // anonymous namespacearmnn-23.08/delegate/test/DepthwiseConvolution2dTest.cpp000066400000000000000000000242611446772241200233760ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ConvolutionTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void DepthwiseConv2dValidReluFp32Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 2, 2 }; std::vector filterShape { 1, 2, 2, 4 }; std::vector biasShape { 4 }; std::vector outputShape { 1, 2, 1, 4 }; static std::vector inputValues = { 1, 2, 7, 8, 3, 4, 9, 10, 5, 6, 11, 12 }; std::vector filterValues = { 1, 2, 3, 4, -9, 10, -11, 12, 5, 6, 7, 8, 13, -14, 15, -16 }; std::vector biasValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 71, 0, 99, 0, 91, 0, 127, 0 }; tflite::Padding padding = tflite::Padding_VALID; int32_t depth_multiplier = 2; ConvolutionTest(tflite::BuiltinOperator_DEPTHWISE_CONV_2D, ::tflite::TensorType_FLOAT32, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_RELU, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues, {1.0f}, // biasScale {0}, // biasOffset {1.0f}, // filterScale {0}, // filterOffsets 2.0f, // outputQuantScale 0, // outputQuantOffset 1.0f, // quantScale 0, // quantOffset depth_multiplier); } void DepthwiseConv2dSameUint8Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 3, 1 }; std::vector filterShape { 1, 3, 3, 1 }; std::vector biasShape { 1 } ; std::vector outputShape { 1, 3, 3, 1 }; static std::vector inputValues = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; std::vector filterValues = { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; std::vector biasValues = { 10 }; std::vector expectedOutputValues = { 12, 23, 24, // ( 14+10)/2, ( 35+10)/2, ( 38+10)/2, 34, 65, 61, // ( 57+10)/2, (120+10)/2, (111+10)/2, 60, 104, 84 // (110+10)/2, (197+10)/2, (158+10)/2 }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_DEPTHWISE_CONV_2D, ::tflite::TensorType_UINT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues); } void DepthwiseConv2dSameInt8PerChannelTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 4, 4, 4 }; std::vector filterShape { 1, 2, 2, 16 }; std::vector biasShape {16} ; std::vector outputShape { 1, 4, 4, 16 }; static std::vector inputValues = { 3,3,3,4, 4,4,0,0, 0,3,4,3, 0,2,2,3, 3,0,3,0, 0,3,2,1, 4,1,2,2, 0,0,0,4, 3,2,2,2, 2,1,0,4, 4,3,2,4, 3,2,0,0, 4,1,4,4, 1,0,4,3, 3,2,0,3, 1,1,0,2 }; std::vector filterValues = { 12,20,10, 3, 2,24, 9,10, 5,16,30,12, 3,10, 4,32, 8, 0,30, 3, 0,16,12,15,20,12, 0, 3, 9,20, 8, 8, 12,15,20, 0, 0, 0, 3,15,15, 8,40,12, 9, 5, 2,24, 4, 0, 0, 6, 6, 0, 3, 5,20, 8,20, 3, 6,15, 4, 0 }; std::vector filterScales = { 0.25, 0.2, 0.1, 0.3333333333, 0.5, 0.125, 0.33333333, 0.2, 0.2, 0.25, 0.1, 0.333333333, 0.3333333333, 0.2, 0.5, 0.125 }; int32_t filterQuantizationDim = 3; int32_t depth_multiplier = 4; std::vector biasValues = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; float inputScale = 1.0f; std::vector biasScales {}; std::vector biasOffsets {}; std::vector filterOffsets {}; for (const auto& filterScale: filterScales) { biasScales.push_back(inputScale * filterScale); // filter and bias offset always needs to be zero for per channel. We don't support anything else biasOffsets.push_back(0); filterOffsets.push_back(0); } std::vector expectedOutputValues = { 26,21,21, 7,12,17,28,21,20,22,25,26, 6,11,10,16, 16,16, 4,12, 7,18,28,27,30,20,12,14,16,19,17, 6, 12,12, 8, 0, 3,13,18,15,18,26,20,26,26,32,28,21, 0, 0, 0, 0, 2, 6, 6, 4, 2, 8, 6, 8,15,10,10,24, 20,21, 9, 7, 3, 6,15,16,17,22,17,22,17,18,14, 7, 18, 6,16,12,12,11,17,15,18,18,10,12,27,26,22,18, 27,28,12,10, 7, 3, 8,13, 8,12,14,16,26,24,24,24, 9, 9, 6, 0, 0, 0, 2, 6, 0, 0, 0, 0, 4, 8, 8,16, 26,24,17, 7, 2, 8,11,10,30,24,30,28,32,33,30,24, 20,11,16,12, 7, 9,17,13,20,14,16,18,31,36,33,29, 28,25,19, 9, 6,13,20,19, 2, 8, 6, 8,17,17,15,25, 12,15, 5, 3, 2, 6, 7, 7, 0, 0, 0, 0, 6, 2, 2, 6, 14,16, 7, 5, 1, 3, 3, 2,20,28,12,20,13,20,20,19, 9, 4,10, 4, 0, 4, 8, 6, 4,16,12,16,12,18,18,15, 11,12, 6, 4, 2, 8,10, 7, 0, 0, 0, 0, 9,14,14,14, 3, 4, 1, 1, 1, 3, 3, 2, 0, 0, 0, 0, 2, 4, 4, 8 }; tflite::Padding padding = tflite::Padding_SAME; ConvolutionTest(tflite::BuiltinOperator_DEPTHWISE_CONV_2D, ::tflite::TensorType_INT8, 1, // strideX 1, // strideY 1, // dilationX 1, // dilationY padding, tflite::ActivationFunctionType_NONE, backends, inputShape, filterShape, outputShape, inputValues, filterValues, expectedOutputValues, biasShape, biasValues, biasScales, biasOffsets, filterScales, filterOffsets, 1.0f, 0, inputScale, 0, depth_multiplier, filterQuantizationDim); } TEST_SUITE("DepthwiseConv2d_CpuRef_Tests") { TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; DepthwiseConv2dValidReluFp32Test(backends); } TEST_CASE ("DepthwiseConv2d_Same_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; DepthwiseConv2dSameUint8Test(backends); } TEST_CASE ("DepthwiseConv2d_Same_Int8_PerChannelQuantization_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; DepthwiseConv2dSameInt8PerChannelTest(backends); } }//End of TEST_SUITE("DepthwiseConv2d_CpuRef_Tests") TEST_SUITE("DepthwiseConv2d_CpuAcc_Tests") { TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; DepthwiseConv2dValidReluFp32Test(backends); } TEST_CASE ("DepthwiseConv2d_Same_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; DepthwiseConv2dSameUint8Test(backends); } }//End of TEST_SUITE("DepthwiseConv2d_CpuAcc_Tests") TEST_SUITE("DepthwiseConv2d_GpuAcc_Tests") { TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; DepthwiseConv2dValidReluFp32Test(backends); } TEST_CASE ("DepthwiseConv2d_Same_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; DepthwiseConv2dSameUint8Test(backends); } }//End of TEST_SUITE("DepthwiseConv2d_GpuAcc_Tests") } // namespace armnnDelegatearmnn-23.08/delegate/test/ElementwiseBinaryTest.cpp000066400000000000000000001077431446772241200224110ustar00rootroot00000000000000// // Copyright © 2020-2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ElementwiseBinaryTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void AddFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 3 }; std::vector input1Shape { 2, 2, 2, 3 }; std::vector expectedOutputShape { 2, 2, 2, 3 }; std::vector input0Values = { 0.0f, 2.0f, 1.0f, 0.2f, 1.0f, 2.0f, 1.0f, 2.0f, 1.0f, 0.2f, 1.0f, 2.0f, 0.0f, 2.0f, 1.0f, 4.2f, 1.0f, 2.0f, 0.0f, 0.0f, 1.0f, 0.2f, 1.0f, 2.0f, }; std::vector input1Values = { 1.0f, 2.0f, 1.0f, 0.0f, 1.0f, 2.0f, 1.0f, 2.0f, -2.0f, 0.2f, 1.0f, 2.0f, 0.0f, 2.0f, 1.0f, 4.2f, 0.0f, -3.0f, 0.0f, 0.0f, 1.0f, 0.7f, 1.0f, 5.0f, }; std::vector expectedOutputValues = { 1.0f, 4.0f, 2.0f, 0.2f, 2.0f, 4.0f, 2.0f, 4.0f, -1.0f, 0.4f, 2.0f, 4.0f, 0.0f, 4.0f, 2.0f, 8.4f, 1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.9f, 2.0f, 7.0f, }; ElementwiseBinaryTest(tflite::BuiltinOperator_ADD, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void AddBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 3, 2, 1 }; std::vector input1Shape { 1, 1, 2, 3 }; std::vector expectedOutputShape { 1, 3, 2, 3 }; std::vector input0Values { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, }; std::vector input1Values { 0.5f, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f, }; // Set output data std::vector expectedOutputValues { 0.5f, 1.5f, 2.5f, 4.5f, 5.5f, 6.5f, 2.5f, 3.5f, 4.5f, 6.5f, 7.5f, 8.5f, 4.5f, 5.5f, 6.5f, 8.5f, 9.5f, 10.5f, }; ElementwiseBinaryTest(tflite::BuiltinOperator_ADD, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void AddConstInputTest(std::vector& backends) { std::vector input0Shape { 1, 3, 2, 1 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 3, 2, 1 }; std::vector input0Values { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, }; std::vector input1Values { 0.5f }; // Set output data std::vector expectedOutputValues { 0.5f, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f, }; ElementwiseBinaryTest(tflite::BuiltinOperator_ADD, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 1.0f, 0, true); } void AddActivationTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values { 4.0f, 0.8f, 0.7f, -0.8f }; std::vector input1Values { 0.7f, -1.2f, 0.8f, 0.5f }; std::vector expectedOutputValues { 4.7f, 0.0f, 1.5f, 0.0f }; ElementwiseBinaryTest(tflite::BuiltinOperator_ADD, tflite::ActivationFunctionType_RELU, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void AddUint8Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 2, 2, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values = { 63, 35, 77, 70, 56, 112, 203, 28, 252, 168, 245, 91 }; std::vector input1Values = { 21, 7, 175, 231, 175, 210, 126, 161, 63, 21, 105, 126 }; std::vector expectedOutputValues = { 81, 39, 249, 255, 228, 255, 255, 186, 255, 186, 255, 214, }; ElementwiseBinaryTest(tflite::BuiltinOperator_ADD, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 7.0f, 3); } void DivFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 2.f, 2.f, 2.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f, 5.f, 5.f, 5.f, 5.f }; std::vector input1Values = { 1.f, 1.f, 1.f, 1.f, 2.f, 2.f, 2.f, 2.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f }; std::vector expectedOutputValues = { 2.f, 2.f, 2.f, 2.f, 1.50f, 1.50f, 1.50f, 1.50f, 1.f, 1.f, 1.f, 1.f, 1.25f, 1.25f, 1.25f, 1.25f }; ElementwiseBinaryTest(tflite::BuiltinOperator_DIV, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void DivBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2, 2 }; std::vector input0Values = { 2, 4, 6, 8, 10, 12, 14, 16 }; std::vector input1Values = { 2 }; std::vector expectedOutputValues = { 1, 2, 3, 4, 5, 6, 7, 8 }; ElementwiseBinaryTest(tflite::BuiltinOperator_DIV, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void DivUint8Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; std::vector input1Values = { 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4 }; std::vector expectedOutputValues = { 8, 8, 8, 8, 6, 6, 6, 6, 4, 4, 4, 4, 5, 5, 5, 5 }; ElementwiseBinaryTest(tflite::BuiltinOperator_DIV, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 0.25f, 0); } void FloorDivFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { -37.5f, -15.2f, -8.76f, -2.0f, -2.6f, -1.0f, -0.8f, 0.0f, 4.0f, 1.6f, 2.0f, 5.2f, 6.0f, 35.04f, 60.8f, 150.0f }; std::vector input1Values = { 1.f, 1.f, 1.f, 1.f, 2.f, 2.f, 2.f, 2.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f, 4.f }; std::vector expectedOutputValues = { -38.0f, -16.0f, -9.0f, -2.0f, -2.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 8.0f, 15.0f, 37.0f }; ElementwiseBinaryTest(tflite::BuiltinOperator_FLOOR_DIV, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MaxFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1.f, 1.f, 5.f, 1.f, 2.f, 2.f, 7.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f }; std::vector input1Values = { 2.f, 2.f, 2.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f, 5.f, 5.f, 5.f, 5.f }; std::vector expectedOutputValues = { 2.f, 2.f, 5.f, 2.f, 3.f, 3.f, 7.f, 3.f, 4.f, 4.f, 4.f, 4.f, 5.f, 5.f, 5.f, 5.f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MAXIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MaxBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2, 2 }; std::vector input0Values = { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f }; std::vector input1Values = { 4.f }; std::vector expectedOutputValues = { 4.f, 4.f, 4.f, 4.f, 5.f, 6.f, 7.f, 8.f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MAXIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MaxUint8Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1, 1, 1, 1, 7, 8, 9, 9, 3, 3, 3, 3, 4, 4, 4, 4 }; std::vector input1Values = { 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; std::vector expectedOutputValues = { 2, 2, 2, 2, 7, 8, 9, 9, 4, 4, 4, 4, 5, 5, 5, 5 }; ElementwiseBinaryTest(tflite::BuiltinOperator_MAXIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 1.0f, 0); } void MinFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1.f, 1.f, 5.f, 1.f, 2.f, 2.f, 7.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f }; std::vector input1Values = { 2.f, 2.f, 2.f, 2.f, 3.f, 3.f, 3.f, 3.f, 1.f, 1.f, 1.f, 1.f, 5.f, 5.f, 5.f, 5.f }; std::vector expectedOutputValues = { 1.f, 1.f, 2.f, 1.f, 2.f, 2.f, 3.f, 2.f, 1.f, 1.f, 1.f, 1.f, 4.f, 4.f, 4.f, 4.f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MINIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MinBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2, 2 }; std::vector input0Values = { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f }; std::vector input1Values = { 4.f }; std::vector expectedOutputValues = { 1.f, 2.f, 3.f, 4.f, 4.f, 4.f, 4.f, 4.f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MINIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MinUint8Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1, 1, 1, 1, 7, 8, 9, 9, 3, 3, 3, 3, 4, 4, 4, 4 }; std::vector input1Values = { 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 }; std::vector expectedOutputValues = { 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; ElementwiseBinaryTest(tflite::BuiltinOperator_MINIMUM, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 1.0f, 0); } void MulFP32Test(std::vector& backends) { std::vector input0Shape { 2, 2, 2, 2 }; std::vector input1Shape { 2, 2, 2, 2 }; std::vector expectedOutputShape { 2, 2, 2, 2 }; std::vector input0Values = { 1.f, 1.f, 1.f, 1.f, 2.f, 2.f, 2.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f }; std::vector input1Values = { 2.f, 2.f, 2.f, 2.f, 3.f, 3.f, 3.f, 3.f, 4.f, 4.f, 4.f, 4.f, 5.f, 5.f, 5.f, 5.f }; std::vector expectedOutputValues = { 2.f, 2.f, 2.f, 2.f, 6.f, 6.f, 6.f, 6.f, 12.f, 12.f, 12.f, 12.f, 20.f, 20.f, 20.f, 20.f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MUL, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MulBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2, 2 }; std::vector input0Values = { 2, 4, 6, 8, 10, 12, 14, 16 }; std::vector input1Values = { 2 }; std::vector expectedOutputValues = { 4, 8, 12, 16, 20, 24, 28, 32 }; ElementwiseBinaryTest(tflite::BuiltinOperator_MUL, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void MulUint8Test(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 3 }; std::vector input1Shape { 1, 1, 1, 3 }; std::vector expectedOutputShape { 1, 2, 2, 3 }; std::vector input0Values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; std::vector input1Values = { 1, 2, 3 }; std::vector expectedOutputValues = { 1, 4, 9, 4, 10, 18, 7, 16, 27, 10, 22, 36 }; ElementwiseBinaryTest(tflite::BuiltinOperator_MUL, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 1.0f, 0); } void MulActivationTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2, 1 }; std::vector input1Shape { 1, 2, 2, 1 }; std::vector expectedOutputShape { 1, 2, 2, 1 }; std::vector input0Values { 4.0f, 0.0f, 1.0f, 0.5f }; std::vector input1Values { -2.0f, -1.2f, 2.5f, 2.0f }; std::vector expectedOutputValues { 0.0f, 0.0f, 2.5f, 1.0f }; ElementwiseBinaryTest(tflite::BuiltinOperator_MUL, tflite::ActivationFunctionType_RELU, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void SubFP32Test(std::vector& backends) { std::vector input0Shape { 1, 1, 2, 2 }; std::vector input1Shape { 1, 1, 2, 2 }; std::vector expectedOutputShape { 1, 1, 2, 2 }; std::vector input0Values = { 1, 3, 3, -7 }; std::vector input1Values = { 1, -1, 0, -2 }; std::vector expectedOutputValues = { 0, 4, 3, -5 }; ElementwiseBinaryTest(tflite::BuiltinOperator_SUB, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void PowerFP32Test(std::vector& backends) { std::vector input0Shape { 1, 1, 2, 2 }; std::vector input1Shape { 1, 1, 2, 2 }; std::vector expectedOutputShape { 1, 1, 2, 2 }; std::vector input0Values = { 1, 3, 3, -7 }; std::vector input1Values = { 1, 1, 0, 2 }; std::vector expectedOutputValues = { 1, 3, 1, 49 }; ElementwiseBinaryTest(tflite::BuiltinOperator_POW, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void SqDiffFP32Test(std::vector& backends) { std::vector input0Shape { 1, 1, 2, 2 }; std::vector input1Shape { 1, 1, 2, 2 }; std::vector expectedOutputShape { 1, 1, 2, 2 }; std::vector input0Values = { 1, 3, 3, -7 }; std::vector input1Values = { 1, -1, 0, -2 }; std::vector expectedOutputValues = { 0, 16, 9, 25 }; ElementwiseBinaryTest(tflite::BuiltinOperator_SQUARED_DIFFERENCE, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void SubBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 1, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 1, 2, 2 }; std::vector input0Values = { 2, 3, 4, 5}; std::vector input1Values = { 10 }; std::vector expectedOutputValues = { -8, -7, -6, -5 }; ElementwiseBinaryTest(tflite::BuiltinOperator_SUB, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void SubUint8Test(std::vector& backends) { std::vector input0Shape { 1, 1, 2, 2 }; std::vector input1Shape { 1, 1, 1, 1 }; std::vector expectedOutputShape { 1, 1, 2, 2 }; std::vector input0Values = { 10, 12, 14, 16 }; std::vector input1Values = { 2 }; std::vector expectedOutputValues = { 8, 10, 12, 14 }; ElementwiseBinaryTest(tflite::BuiltinOperator_SUB, tflite::ActivationFunctionType_NONE, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, 1.0f, 0); } TEST_SUITE("ElementwiseBinary_GpuAccTests") { TEST_CASE ("ADD_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AddFP32Test(backends); } TEST_CASE ("ADD_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AddBroadcastTest(backends); } TEST_CASE ("ADD_Activation_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AddActivationTest(backends); } TEST_CASE ("ADD_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AddUint8Test(backends); } TEST_CASE ("DIV_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DivFP32Test(backends); } TEST_CASE ("DIV_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DivBroadcastTest(backends); } TEST_CASE ("FLOORDIV_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; FloorDivFP32Test(backends); } TEST_CASE ("MAX_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxFP32Test(backends); } TEST_CASE ("MAX_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxBroadcastTest(backends); } TEST_CASE ("MAX_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxUint8Test(backends); } TEST_CASE ("MIN_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MinFP32Test(backends); } TEST_CASE ("MIN_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MinBroadcastTest(backends); } TEST_CASE ("MIN_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MinUint8Test(backends); } TEST_CASE ("MUL_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MulFP32Test(backends); } TEST_CASE ("MUL_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MulBroadcastTest(backends); } TEST_CASE ("MUL_Activation_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MulActivationTest(backends); } TEST_CASE ("MUL_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MulUint8Test(backends); } TEST_CASE ("SUB_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SubFP32Test(backends); } TEST_CASE ("SUB_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SubBroadcastTest(backends); } TEST_CASE ("SUB_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SubUint8Test(backends); } } //TEST_SUITE("ElementwiseBinary_GpuAccTests") TEST_SUITE("ElementwiseBinary_CpuAccTests") { TEST_CASE ("ADD_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AddFP32Test(backends); } TEST_CASE ("ADD_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AddBroadcastTest(backends); } TEST_CASE ("ADD_Activation_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AddActivationTest(backends); } TEST_CASE ("ADD_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AddUint8Test(backends); } TEST_CASE ("DIV_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DivFP32Test(backends); } TEST_CASE ("DIV_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DivBroadcastTest(backends); } TEST_CASE ("FLOORDIV_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; FloorDivFP32Test(backends); } TEST_CASE ("MAX_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxFP32Test(backends); } TEST_CASE ("MAX_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxBroadcastTest(backends); } TEST_CASE ("MAX_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxUint8Test(backends); } TEST_CASE ("MIN_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MinFP32Test(backends); } TEST_CASE ("MIN_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MinBroadcastTest(backends); } TEST_CASE ("MIN_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MinUint8Test(backends); } TEST_CASE ("MUL_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MulFP32Test(backends); } TEST_CASE ("MUL_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MulBroadcastTest(backends); } TEST_CASE ("MUL_Actiation_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MulActivationTest(backends); } TEST_CASE ("MUL_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MulUint8Test(backends); } TEST_CASE ("SUB_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SubFP32Test(backends); } TEST_CASE ("SUB_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SubBroadcastTest(backends); } TEST_CASE ("SUB_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SubUint8Test(backends); } } // TEST_SUITE("ElementwiseBinary_CpuAccTests") TEST_SUITE("ElementwiseBinary_CpuRefTests") { TEST_CASE ("ADD_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AddFP32Test(backends); } TEST_CASE ("ADD_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AddBroadcastTest(backends); } TEST_CASE ("ADD_Constant_Input_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AddConstInputTest(backends); } TEST_CASE ("ADD_Activation_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AddActivationTest(backends); } TEST_CASE ("ADD_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AddUint8Test(backends); } TEST_CASE ("DIV_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DivFP32Test(backends); } TEST_CASE ("DIV_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DivBroadcastTest(backends); } TEST_CASE ("FLOORDIV_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FloorDivFP32Test(backends); } TEST_CASE ("DIV_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DivUint8Test(backends); } TEST_CASE ("MAX_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxFP32Test(backends); } TEST_CASE ("MAX_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxBroadcastTest(backends); } TEST_CASE ("MAX_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxUint8Test(backends); } TEST_CASE ("MIN_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MinFP32Test(backends); } TEST_CASE ("MIN_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MinBroadcastTest(backends); } TEST_CASE ("MIN_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MinUint8Test(backends); } TEST_CASE ("MUL_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MulFP32Test(backends); } TEST_CASE ("MUL_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MulBroadcastTest(backends); } TEST_CASE ("MUL_Actiation_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MulActivationTest(backends); } TEST_CASE ("MUL_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MulUint8Test(backends); } TEST_CASE ("SUB_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SubFP32Test(backends); } TEST_CASE ("SUB_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SubBroadcastTest(backends); } TEST_CASE ("SUB_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SubUint8Test(backends); } TEST_CASE ("SqDiffFP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SqDiffFP32Test(backends); } TEST_CASE ("PowerFP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PowerFP32Test(backends); } } // TEST_SUITE("ElementwiseBinary_CpuRefTests") } // namespace armnnDelegate armnn-23.08/delegate/test/ElementwiseBinaryTestHelper.hpp000066400000000000000000000262671446772241200235570ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreateElementwiseBinaryTfLiteModel(tflite::BuiltinOperator binaryOperatorCode, tflite::ActivationFunctionType activationType, tflite::TensorType tensorType, const std::vector & input0TensorShape, const std::vector & input1TensorShape, const std::vector & outputTensorShape, std::vector& input1Values, bool constantInput = false, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); if (constantInput) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(input1Values.data()), sizeof(T) * input1Values.size()))); } else { buffers.push_back(CreateBuffer(flatBufferBuilder)); } buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input1TensorShape.data(), input1TensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("input_1"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOptions = 0; switch (binaryOperatorCode) { case BuiltinOperator_ADD: { operatorBuiltinOptionsType = BuiltinOptions_AddOptions; operatorBuiltinOptions = CreateAddOptions(flatBufferBuilder, activationType).Union(); break; } case BuiltinOperator_DIV: { operatorBuiltinOptionsType = BuiltinOptions_DivOptions; operatorBuiltinOptions = CreateDivOptions(flatBufferBuilder, activationType).Union(); break; } case BuiltinOperator_MAXIMUM: { operatorBuiltinOptionsType = BuiltinOptions_MaximumMinimumOptions; operatorBuiltinOptions = CreateMaximumMinimumOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_MINIMUM: { operatorBuiltinOptionsType = BuiltinOptions_MaximumMinimumOptions; operatorBuiltinOptions = CreateMaximumMinimumOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_MUL: { operatorBuiltinOptionsType = BuiltinOptions_MulOptions; operatorBuiltinOptions = CreateMulOptions(flatBufferBuilder, activationType).Union(); break; } case BuiltinOperator_SUB: { operatorBuiltinOptionsType = BuiltinOptions_SubOptions; operatorBuiltinOptions = CreateSubOptions(flatBufferBuilder, activationType).Union(); break; } case BuiltinOperator_POW: { operatorBuiltinOptionsType = BuiltinOptions_PowOptions; operatorBuiltinOptions = CreatePowOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_SQUARED_DIFFERENCE: { operatorBuiltinOptionsType = BuiltinOptions_SquaredDifferenceOptions; operatorBuiltinOptions = CreateSquaredDifferenceOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_FLOOR_DIV: { operatorBuiltinOptionsType = tflite::BuiltinOptions_FloorDivOptions; operatorBuiltinOptions = CreateSubOptions(flatBufferBuilder, activationType).Union(); break; } default: break; } const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset elementwiseBinaryOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&elementwiseBinaryOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Elementwise Binary Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, binaryOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ElementwiseBinaryTest(tflite::BuiltinOperator binaryOperatorCode, tflite::ActivationFunctionType activationType, tflite::TensorType tensorType, std::vector& backends, std::vector& input0Shape, std::vector& input1Shape, std::vector& outputShape, std::vector& input0Values, std::vector& input1Values, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0, bool constantInput = false) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateElementwiseBinaryTfLiteModel(binaryOperatorCode, activationType, tensorType, input0Shape, input1Shape, outputShape, input1Values, constantInput, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ElementwiseUnaryTest.cpp000066400000000000000000000271511446772241200222550ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ElementwiseUnaryTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { TEST_SUITE("ElementwiseUnary_GpuAccTests") { TEST_CASE ("Abs_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { -0.1f, -0.2f, -0.3f, 0.1f, 0.2f, 0.3f }; // Calculate output data std::vector expectedOutputValues(inputValues.size()); for (unsigned int i = 0; i < inputValues.size(); ++i) { expectedOutputValues[i] = std::abs(inputValues[i]); } ElementwiseUnaryFP32Test(tflite::BuiltinOperator_ABS, backends, inputValues, expectedOutputValues); } TEST_CASE ("Exp_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 1.1f }; // Set output data std::vector expectedOutputValues { 148.413159102577f, 54.598150033144f, 20.085536923188f, 7.389056098931f, 2.718281828459f, 3.004166023946f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_EXP, backends, inputValues, expectedOutputValues); } TEST_CASE ("Log_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { 1.0f, 1.0f, 2.0f, 3.0f, 4.0f, 2.71828f }; // Set output data std::vector expectedOutputValues { 0.f, 0.f, 0.69314718056f, 1.09861228867f, 1.38629436112f, 0.99999932734f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_LOG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Neg_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { 1.f, 0.f, 3.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { -1.f, 0.f, -3.f, -25.f, -64.f, -100.f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_NEG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Rsqrt_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { 1.f, 4.f, 16.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { 1.f, 0.5f, 0.25f, 0.2f, 0.125f, 0.1f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_RSQRT, backends, inputValues, expectedOutputValues); } TEST_CASE ("Sin_Float32_GpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::GpuAcc }; // Set input data std::vector inputValues { 0.0f, 1.0f, 16.0f, 0.5f, 36.0f, -1.f }; // Set output data std::vector expectedOutputValues { 0.0f, 0.8414709848f, -0.28790331666f, 0.4794255386f, -0.99177885344f, -0.8414709848f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_SIN, backends, inputValues, expectedOutputValues); } } // TEST_SUITE("ElementwiseUnary_GpuAccTests") TEST_SUITE("ElementwiseUnary_CpuAccTests") { TEST_CASE ("Abs_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { -0.1f, -0.2f, -0.3f, 0.1f, 0.2f, 0.3f }; // Calculate output data std::vector expectedOutputValues(inputValues.size()); for (unsigned int i = 0; i < inputValues.size(); ++i) { expectedOutputValues[i] = std::abs(inputValues[i]); } ElementwiseUnaryFP32Test(tflite::BuiltinOperator_ABS, backends, inputValues, expectedOutputValues); } TEST_CASE ("Exp_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 1.1f }; // Set output data std::vector expectedOutputValues { 148.413159102577f, 54.598150033144f, 20.085536923188f, 7.389056098931f, 2.718281828459f, 3.004166023946f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_EXP, backends, inputValues, expectedOutputValues); } TEST_CASE ("Log_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { 1.0f, 1.0f, 2.0f, 3.0f, 4.0f, 2.71828f }; // Set output data std::vector expectedOutputValues { 0.f, 0.f, 0.69314718056f, 1.09861228867f, 1.38629436112f, 0.99999932734f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_LOG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Neg_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { 1.f, 0.f, 3.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { -1.f, 0.f, -3.f, -25.f, -64.f, -100.f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_NEG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Rsqrt_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { 1.f, 4.f, 16.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { 1.f, 0.5f, 0.25f, 0.2f, 0.125f, 0.1f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_RSQRT, backends, inputValues, expectedOutputValues); } TEST_CASE ("Sin_Float32_CpuAcc_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuAcc }; // Set input data std::vector inputValues { 0.0f, 1.0f, 16.0f, 0.5f, 36.0f, -1.f }; // Set output data std::vector expectedOutputValues { 0.0f, 0.8414709848f, -0.28790331666f, 0.4794255386f, -0.99177885344f, -0.8414709848f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_SIN, backends, inputValues, expectedOutputValues); } } // TEST_SUITE("ElementwiseUnary_CpuAccTests") TEST_SUITE("ElementwiseUnary_CpuRefTests") { TEST_CASE ("Abs_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { -0.1f, -0.2f, -0.3f, 0.1f, 0.2f, 0.3f }; // Calculate output data std::vector expectedOutputValues(inputValues.size()); for (unsigned int i = 0; i < inputValues.size(); ++i) { expectedOutputValues[i] = std::abs(inputValues[i]); } ElementwiseUnaryFP32Test(tflite::BuiltinOperator_ABS, backends, inputValues, expectedOutputValues); } TEST_CASE ("Ceil_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 0.0f, 1.1f, -16.1f, 0.5f, -0.5f, -1.3f }; // Set output data std::vector expectedOutputValues { 0.0f, 2.0f, -16.0f, 1.0f, 0.0f, -1.0f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_CEIL, backends, inputValues, expectedOutputValues); } TEST_CASE ("Exp_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 1.1f }; // Set output data std::vector expectedOutputValues { 148.413159102577f, 54.598150033144f, 20.085536923188f, 7.389056098931f, 2.718281828459f, 3.004166023946f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_EXP, backends, inputValues, expectedOutputValues); } TEST_CASE ("Log_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 1.0f, 1.0f, 2.0f, 3.0f, 4.0f, 2.71828f }; // Set output data std::vector expectedOutputValues { 0.f, 0.f, 0.69314718056f, 1.09861228867f, 1.38629436112f, 0.99999932734f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_LOG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Neg_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 1.f, 0.f, 3.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { -1.f, 0.f, -3.f, -25.f, -64.f, -100.f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_NEG, backends, inputValues, expectedOutputValues); } TEST_CASE ("Rsqrt_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 1.f, 4.f, 16.f, 25.f, 64.f, 100.f }; // Set output data std::vector expectedOutputValues { 1.f, 0.5f, 0.25f, 0.2f, 0.125f, 0.1f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_RSQRT, backends, inputValues, expectedOutputValues); } TEST_CASE ("Sqrt_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 9.0f, 4.25f, 81.9f, 0.1f, 0.9f, 169.0f }; // Calculate output data std::vector expectedOutputValues(inputValues.size()); for (unsigned int i = 0; i < inputValues.size(); ++i) { expectedOutputValues[i] = std::sqrt(inputValues[i]); } ElementwiseUnaryFP32Test(tflite::BuiltinOperator_SQRT, backends, inputValues, expectedOutputValues); } TEST_CASE ("Sin_Float32_CpuRef_Test") { // Create the ArmNN Delegate std::vector backends = { armnn::Compute::CpuRef }; // Set input data std::vector inputValues { 0.0f, 1.0f, 16.0f, 0.5f, 36.0f, -1.f }; // Set output data std::vector expectedOutputValues { 0.0f, 0.8414709848f, -0.28790331666f, 0.4794255386f, -0.99177885344f, -0.8414709848f }; ElementwiseUnaryFP32Test(tflite::BuiltinOperator_SIN, backends, inputValues, expectedOutputValues); } } // TEST_SUITE("ElementwiseUnary_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/ElementwiseUnaryTestHelper.hpp000066400000000000000000000161701446772241200234210ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateElementwiseUnaryTfLiteModel(tflite::BuiltinOperator unaryOperatorCode, tflite::TensorType tensorType, const std::vector & tensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 1> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType); // create operator const std::vector operatorInputs{0}; const std::vector operatorOutputs{1}; flatbuffers::Offset unaryOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size())); const std::vector subgraphInputs{0}; const std::vector subgraphOutputs{1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&unaryOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Elementwise Unary Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, unaryOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void ElementwiseUnaryFP32Test(tflite::BuiltinOperator unaryOperatorCode, std::vector& backends, std::vector& inputValues, std::vector& expectedOutputValues) { using namespace delegateTestInterpreter; std::vector inputShape { { 3, 1, 2} }; std::vector modelBuffer = CreateElementwiseUnaryTfLiteModel(unaryOperatorCode, ::tflite::TensorType_FLOAT32, inputShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, inputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } void ElementwiseUnaryBoolTest(tflite::BuiltinOperator unaryOperatorCode, std::vector& backends, std::vector& inputShape, std::vector& inputValues, std::vector& expectedOutputValues) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateElementwiseUnaryTfLiteModel(unaryOperatorCode, ::tflite::TensorType_BOOL, inputShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareData(expectedOutputValues, armnnOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(expectedOutputValues, tfLiteOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues.size()); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, inputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/ExpandDimsTest.cpp000066400000000000000000000054351446772241200210120ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "RedefineTestHelper.hpp" namespace armnnDelegate { void ExpandDimsSimpleTest(std::vector& backends) { // Set input data std::vector inputShape { 2, 2, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector axis { 0 }; std::vector inputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 1, 2, 3, 4 }; RedefineTest(tflite::BuiltinOperator_EXPAND_DIMS, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, axis); } void ExpandDimsWithNegativeAxisTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector axis { -1 }; std::vector inputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 1, 2, 3, 4 }; RedefineTest(tflite::BuiltinOperator_EXPAND_DIMS, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, axis); } TEST_SUITE("ExpandDims_GpuAccTests") { TEST_CASE ("ExpandDims_Simple_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ExpandDimsSimpleTest(backends); } TEST_CASE ("ExpandDims_With_Negative_Axis_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ExpandDimsWithNegativeAxisTest(backends); } } // TEST_SUITE("ExpandDims_GpuAccTests") TEST_SUITE("ExpandDims_CpuAccTests") { TEST_CASE ("ExpandDims_Simple_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ExpandDimsSimpleTest(backends); } TEST_CASE ("ExpandDims_With_Negative_Axis_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ExpandDimsWithNegativeAxisTest(backends); } } // TEST_SUITE("ExpandDims_CpuAccTests") TEST_SUITE("ExpandDims_CpuRefTests") { TEST_CASE ("ExpandDims_Simple_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ExpandDimsSimpleTest(backends); } TEST_CASE ("ExpandDims_With_Negative_Axis_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ExpandDimsWithNegativeAxisTest(backends); } } // TEST_SUITE("ExpandDims_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/FillTest.cpp000066400000000000000000000150001446772241200176310ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "FillTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void Fill2dTest(std::vector& backends, tflite::BuiltinOperator fillOperatorCode = tflite::BuiltinOperator_FILL, float fill = 2.0f ) { std::vector inputShape { 2 }; std::vector tensorShape { 2, 2 }; std::vector expectedOutputValues = { fill, fill, fill, fill }; FillTest(fillOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, tensorShape, expectedOutputValues, fill); } void Fill3dTest(std::vector& backends, tflite::BuiltinOperator fillOperatorCode = tflite::BuiltinOperator_FILL, float fill = 5.0f ) { std::vector inputShape { 3 }; std::vector tensorShape { 3, 3, 3 }; std::vector expectedOutputValues = { fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill }; FillTest(fillOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, tensorShape, expectedOutputValues, fill); } void Fill4dTest(std::vector& backends, tflite::BuiltinOperator fillOperatorCode = tflite::BuiltinOperator_FILL, float fill = 3.0f ) { std::vector inputShape { 4 }; std::vector tensorShape { 2, 2, 4, 4 }; std::vector expectedOutputValues = { fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill, fill }; FillTest(fillOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, tensorShape, expectedOutputValues, fill); } void FillInt32Test(std::vector& backends, tflite::BuiltinOperator fillOperatorCode = tflite::BuiltinOperator_FILL, int32_t fill = 2 ) { std::vector inputShape { 2 }; std::vector tensorShape { 2, 2 }; std::vector expectedOutputValues = { fill, fill, fill, fill }; FillTest(fillOperatorCode, ::tflite::TensorType_INT32, backends, inputShape, tensorShape, expectedOutputValues, fill); } TEST_SUITE("Fill_CpuRefTests") { TEST_CASE ("Fill2d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Fill2dTest(backends); } TEST_CASE ("Fill3d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Fill3dTest(backends); } TEST_CASE ("Fill3d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Fill3dTest(backends); } TEST_CASE ("Fill4d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Fill4dTest(backends); } TEST_CASE ("FillInt32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FillInt32Test(backends); } } TEST_SUITE("Fill_CpuAccTests") { TEST_CASE ("Fill2d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Fill2dTest(backends); } TEST_CASE ("Fill3d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Fill3dTest(backends); } TEST_CASE ("Fill3d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Fill3dTest(backends); } TEST_CASE ("Fill4d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Fill4dTest(backends); } TEST_CASE ("FillInt32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; FillInt32Test(backends); } } TEST_SUITE("Fill_GpuAccTests") { TEST_CASE ("Fill2d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Fill2dTest(backends); } TEST_CASE ("Fill3d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Fill3dTest(backends); } TEST_CASE ("Fill3d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Fill3dTest(backends); } TEST_CASE ("Fill4d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Fill4dTest(backends); } TEST_CASE ("FillInt32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; FillInt32Test(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/FillTestHelper.hpp000066400000000000000000000155461446772241200210150ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreateFillTfLiteModel(tflite::BuiltinOperator fillOperatorCode, tflite::TensorType tensorType, const std::vector& inputShape, const std::vector & tensorShape, const std::vector fillValue) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(tensorShape.data()), sizeof(int32_t) * tensorShape.size()))); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(fillValue.data()), sizeof(T) * fillValue.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputShape.data(), inputShape.size()), tflite::TensorType_INT32, 1, flatBufferBuilder.CreateString("dims")); std::vector fillShape = {}; tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(fillShape.data(), fillShape.size()), tensorType, 2, flatBufferBuilder.CreateString("value")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output")); tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_FillOptions; flatbuffers::Offset operatorBuiltinOptions = CreateFillOptions(flatBufferBuilder).Union(); // create operator const std::vector operatorInputs{ {0, 1} }; const std::vector operatorOutputs{ 2 }; flatbuffers::Offset fillOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1} }; const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&fillOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Fill Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, fillOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void FillTest(tflite::BuiltinOperator fillOperatorCode, tflite::TensorType tensorType, const std::vector& backends, std::vector& inputShape, std::vector& tensorShape, std::vector& expectedOutputValues, T fillValue) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateFillTfLiteModel(fillOperatorCode, tensorType, inputShape, tensorShape, {fillValue}); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, tensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/FullyConnectedTest.cpp000066400000000000000000000137221446772241200216720ustar00rootroot00000000000000// // Copyright © 2020-2021,2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "FullyConnectedTestHelper.hpp" namespace { void FullyConnectedFp32Test(std::vector& backends, bool constantWeights = true) { std::vector inputTensorShape { 1, 4, 1, 1 }; std::vector weightsTensorShape { 1, 4 }; std::vector biasTensorShape { 1 }; std::vector outputTensorShape { 1, 1 }; std::vector inputValues = { 10, 20, 30, 40 }; std::vector weightsData = { 2, 3, 4, 5 }; std::vector expectedOutputValues = { (400 + 10) }; // bias is set std::vector biasData = { 10 } in the model FullyConnectedTest(backends, ::tflite::TensorType_FLOAT32, tflite::ActivationFunctionType_NONE, inputTensorShape, weightsTensorShape, biasTensorShape, outputTensorShape, inputValues, expectedOutputValues, weightsData, constantWeights); } void FullyConnectedActivationTest(std::vector& backends, bool constantWeights = true) { std::vector inputTensorShape { 1, 4, 1, 1 }; std::vector weightsTensorShape { 1, 4 }; std::vector biasTensorShape { 1 }; std::vector outputTensorShape { 1, 1 }; std::vector inputValues = { -10, 20, 30, 40 }; std::vector weightsData = { 2, 3, 4, -5 }; std::vector expectedOutputValues = { 0 }; // bias is set std::vector biasData = { 10 } in the model FullyConnectedTest(backends, ::tflite::TensorType_FLOAT32, tflite::ActivationFunctionType_RELU, inputTensorShape, weightsTensorShape, biasTensorShape, outputTensorShape, inputValues, expectedOutputValues, weightsData, constantWeights); } void FullyConnectedInt8Test(std::vector& backends, bool constantWeights = true) { std::vector inputTensorShape { 1, 4, 2, 1 }; std::vector weightsTensorShape { 1, 4 }; std::vector biasTensorShape { 1 }; std::vector outputTensorShape { 2, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 10, 15, 20 }; std::vector weightsData = { 2, 3, 4, 5 }; std::vector expectedOutputValues = { 25, 105 }; // (40 + 10) / 2, (200 + 10) / 2 // bias is set std::vector biasData = { 10 } in the model // input and weights quantization scale 1.0f and offset 0 in the model // output quantization scale 2.0f and offset 0 in the model FullyConnectedTest(backends, ::tflite::TensorType_INT8, tflite::ActivationFunctionType_NONE, inputTensorShape, weightsTensorShape, biasTensorShape, outputTensorShape, inputValues, expectedOutputValues, weightsData, constantWeights); } TEST_SUITE("FullyConnected_GpuAccTests") { TEST_CASE ("FullyConnected_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; FullyConnectedFp32Test(backends); } TEST_CASE ("FullyConnected_Int8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; FullyConnectedInt8Test(backends); } TEST_CASE ("FullyConnected_Activation_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; FullyConnectedActivationTest(backends); } } // End of TEST_SUITE("FullyConnected_GpuAccTests") TEST_SUITE("FullyConnected_CpuAccTests") { TEST_CASE ("FullyConnected_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; FullyConnectedFp32Test(backends); } TEST_CASE ("FullyConnected_Int8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; FullyConnectedInt8Test(backends); } TEST_CASE ("FullyConnected_Activation_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; FullyConnectedActivationTest(backends); } } // End of TEST_SUITE("FullyConnected_CpuAccTests") TEST_SUITE("FullyConnected_CpuRefTests") { TEST_CASE ("FullyConnected_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedFp32Test(backends); } TEST_CASE ("FullyConnected_Int8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedInt8Test(backends); } TEST_CASE ("FullyConnected_Activation_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedActivationTest(backends); } TEST_CASE ("FullyConnected_Weights_As_Inputs_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedFp32Test(backends, false); } TEST_CASE ("FullyConnected_Weights_As_Inputs_Int8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedInt8Test(backends, false); } TEST_CASE ("FullyConnected_Weights_As_Inputs_Activation_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; FullyConnectedActivationTest(backends, false); } } // End of TEST_SUITE("FullyConnected_CpuRefTests") } // anonymous namespacearmnn-23.08/delegate/test/FullyConnectedTestHelper.hpp000066400000000000000000000271731446772241200230440ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreateFullyConnectedTfLiteModel(tflite::TensorType tensorType, tflite::ActivationFunctionType activationType, const std::vector & inputTensorShape, const std::vector & weightsTensorShape, const std::vector & biasTensorShape, std::vector & outputTensorShape, std::vector & weightsData, bool constantWeights = true, float quantScale = 1.0f, int quantOffset = 0, float outputQuantScale = 2.0f, int outputQuantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 5> buffers; buffers[0] = CreateBuffer(flatBufferBuilder); buffers[1] = CreateBuffer(flatBufferBuilder); auto biasTensorType = ::tflite::TensorType_FLOAT32; if (tensorType == ::tflite::TensorType_INT8) { biasTensorType = ::tflite::TensorType_INT32; } if (constantWeights) { buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(weightsData.data()), sizeof(T) * weightsData.size())); if (tensorType == ::tflite::TensorType_INT8) { std::vector biasData = { 10 }; buffers[3] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(biasData.data()), sizeof(int32_t) * biasData.size())); } else { std::vector biasData = { 10 }; buffers[3] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(biasData.data()), sizeof(float) * biasData.size())); } } else { buffers[2] = CreateBuffer(flatBufferBuilder); buffers[3] = CreateBuffer(flatBufferBuilder); } buffers[4] = CreateBuffer(flatBufferBuilder); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto outputQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ outputQuantScale }), flatBufferBuilder.CreateVector({ outputQuantOffset })); std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(weightsTensorShape.data(), weightsTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("weights"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(biasTensorShape.data(), biasTensorShape.size()), biasTensorType, 3, flatBufferBuilder.CreateString("bias"), quantizationParameters); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 4, flatBufferBuilder.CreateString("output"), outputQuantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_FullyConnectedOptions; flatbuffers::Offset operatorBuiltinOptions = CreateFullyConnectedOptions(flatBufferBuilder, activationType, FullyConnectedOptionsWeightsFormat_DEFAULT, false).Union(); const std::vector operatorInputs{0, 1, 2}; const std::vector operatorOutputs{3}; flatbuffers::Offset fullyConnectedOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0, 1, 2}; const std::vector subgraphOutputs{3}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&fullyConnectedOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: FullyConnected Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_FULLY_CONNECTED); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void FullyConnectedTest(std::vector& backends, tflite::TensorType tensorType, tflite::ActivationFunctionType activationType, const std::vector & inputTensorShape, const std::vector & weightsTensorShape, const std::vector & biasTensorShape, std::vector & outputTensorShape, std::vector & inputValues, std::vector & expectedOutputValues, std::vector & weightsData, bool constantWeights = true, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateFullyConnectedTfLiteModel(tensorType, activationType, inputTensorShape, weightsTensorShape, biasTensorShape, outputTensorShape, weightsData, constantWeights, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); if (!constantWeights) { CHECK(tfLiteInterpreter.FillInputTensor(weightsData, 1) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(weightsData, 1) == kTfLiteOk); if (tensorType == ::tflite::TensorType_INT8) { std::vector biasData = {10}; CHECK(tfLiteInterpreter.FillInputTensor(biasData, 2) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(biasData, 2) == kTfLiteOk); } else { std::vector biasData = {10}; CHECK(tfLiteInterpreter.FillInputTensor(biasData, 2) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(biasData, 2) == kTfLiteOk); } } CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/GatherNdTest.cpp000066400000000000000000000056441446772241200204540ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "GatherNdTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // GATHER_ND Operator void GatherNdUint8Test(std::vector& backends) { std::vector paramsShape{ 5, 2 }; std::vector indicesShape{ 3, 1 }; std::vector expectedOutputShape{ 3, 2 }; std::vector paramsValues{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::vector indicesValues{ 1, 0, 4 }; std::vector expectedOutputValues{ 3, 4, 1, 2, 9, 10 }; GatherNdTest(::tflite::TensorType_UINT8, backends, paramsShape, indicesShape, expectedOutputShape, paramsValues, indicesValues, expectedOutputValues); } void GatherNdFp32Test(std::vector& backends) { std::vector paramsShape{ 5, 2 }; std::vector indicesShape{ 3, 1 }; std::vector expectedOutputShape{ 3, 2 }; std::vector paramsValues{ 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 10.10f }; std::vector indicesValues{ 1, 0, 4 }; std::vector expectedOutputValues{ 3.3f, 4.4f, 1.1f, 2.2f, 9.9f, 10.10f }; GatherNdTest(::tflite::TensorType_FLOAT32, backends, paramsShape, indicesShape, expectedOutputShape, paramsValues, indicesValues, expectedOutputValues); } // GATHER_ND Test Suite TEST_SUITE("GATHER_ND_CpuRefTests") { TEST_CASE ("GATHER_ND_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; GatherNdUint8Test(backends); } TEST_CASE ("GATHER_ND_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; GatherNdFp32Test(backends); } } TEST_SUITE("GATHER_ND_CpuAccTests") { TEST_CASE ("GATHER_ND_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; GatherNdUint8Test(backends); } TEST_CASE ("GATHER_ND_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; GatherNdFp32Test(backends); } } TEST_SUITE("GATHER_ND_GpuAccTests") { TEST_CASE ("GATHER_ND_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; GatherNdUint8Test(backends); } TEST_CASE ("GATHER_ND_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; GatherNdFp32Test(backends); } } // End of GATHER_ND Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/GatherNdTestHelper.hpp000066400000000000000000000210541446772241200216120ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateGatherNdTfLiteModel(tflite::TensorType tensorType, std::vector& paramsShape, std::vector& indicesShape, const std::vector& expectedOutputShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(paramsShape.data(), paramsShape.size()), tensorType, 1, flatBufferBuilder.CreateString("params"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(indicesShape.data(), indicesShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("indices"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(expectedOutputShape.data(), expectedOutputShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_GatherNdOptions; flatbuffers::Offset operatorBuiltinOptions = CreateGatherNdOptions(flatBufferBuilder).Union(); const std::vector operatorInputs{{0, 1}}; const std::vector operatorOutputs{2}; flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{{0, 1}}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: GATHER_ND Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_GATHER_ND); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void GatherNdTest(tflite::TensorType tensorType, std::vector& backends, std::vector& paramsShape, std::vector& indicesShape, std::vector& expectedOutputShape, std::vector& paramsValues, std::vector& indicesValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateGatherNdTfLiteModel(tensorType, paramsShape, indicesShape, expectedOutputShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(paramsValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(indicesValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(paramsValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(indicesValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/GatherTest.cpp000066400000000000000000000055621446772241200201710ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "GatherTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // GATHER Operator void GatherUint8Test(std::vector& backends) { std::vector paramsShape{8}; std::vector indicesShape{3}; std::vector expectedOutputShape{3}; int32_t axis = 0; std::vector paramsValues{1, 2, 3, 4, 5, 6, 7, 8}; std::vector indicesValues{7, 6, 5}; std::vector expectedOutputValues{8, 7, 6}; GatherTest(::tflite::TensorType_UINT8, backends, paramsShape, indicesShape, expectedOutputShape, axis, paramsValues, indicesValues, expectedOutputValues); } void GatherFp32Test(std::vector& backends) { std::vector paramsShape{8}; std::vector indicesShape{3}; std::vector expectedOutputShape{3}; int32_t axis = 0; std::vector paramsValues{1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f}; std::vector indicesValues{7, 6, 5}; std::vector expectedOutputValues{8.8f, 7.7f, 6.6f}; GatherTest(::tflite::TensorType_FLOAT32, backends, paramsShape, indicesShape, expectedOutputShape, axis, paramsValues, indicesValues, expectedOutputValues); } // GATHER Test Suite TEST_SUITE("GATHER_CpuRefTests") { TEST_CASE ("GATHER_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; GatherUint8Test(backends); } TEST_CASE ("GATHER_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; GatherFp32Test(backends); } } TEST_SUITE("GATHER_CpuAccTests") { TEST_CASE ("GATHER_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; GatherUint8Test(backends); } TEST_CASE ("GATHER_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; GatherFp32Test(backends); } } TEST_SUITE("GATHER_GpuAccTests") { TEST_CASE ("GATHER_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; GatherUint8Test(backends); } TEST_CASE ("GATHER_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; GatherFp32Test(backends); } } // End of GATHER Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/GatherTestHelper.hpp000066400000000000000000000212711446772241200213310ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateGatherTfLiteModel(tflite::TensorType tensorType, std::vector& paramsShape, std::vector& indicesShape, const std::vector& expectedOutputShape, int32_t axis, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(paramsShape.data(), paramsShape.size()), tensorType, 1, flatBufferBuilder.CreateString("params"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(indicesShape.data(), indicesShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("indices"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(expectedOutputShape.data(), expectedOutputShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_GatherOptions; flatbuffers::Offset operatorBuiltinOptions = CreateGatherOptions(flatBufferBuilder).Union(); const std::vector operatorInputs{{0, 1}}; const std::vector operatorOutputs{2}; flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{{0, 1}}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: GATHER Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_GATHER); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void GatherTest(tflite::TensorType tensorType, std::vector& backends, std::vector& paramsShape, std::vector& indicesShape, std::vector& expectedOutputShape, int32_t axis, std::vector& paramsValues, std::vector& indicesValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateGatherTfLiteModel(tensorType, paramsShape, indicesShape, expectedOutputShape, axis, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(paramsValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(indicesValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(paramsValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(indicesValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/LogicalTest.cpp000066400000000000000000000151001446772241200203160ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ElementwiseUnaryTestHelper.hpp" #include "LogicalTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void LogicalBinaryAndBoolTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1, 2, 2 }; std::vector expectedOutputShape { 1, 2, 2 }; // Set input and output values std::vector input0Values { 0, 0, 1, 1 }; std::vector input1Values { 0, 1, 0, 1 }; std::vector expectedOutputValues { 0, 0, 0, 1 }; LogicalBinaryTest(tflite::BuiltinOperator_LOGICAL_AND, ::tflite::TensorType_BOOL, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LogicalBinaryAndBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2 }; std::vector input0Values { 0, 1, 0, 1 }; std::vector input1Values { 1 }; std::vector expectedOutputValues { 0, 1, 0, 1 }; LogicalBinaryTest(tflite::BuiltinOperator_LOGICAL_AND, ::tflite::TensorType_BOOL, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LogicalBinaryOrBoolTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1, 2, 2 }; std::vector expectedOutputShape { 1, 2, 2 }; std::vector input0Values { 0, 0, 1, 1 }; std::vector input1Values { 0, 1, 0, 1 }; std::vector expectedOutputValues { 0, 1, 1, 1 }; LogicalBinaryTest(tflite::BuiltinOperator_LOGICAL_OR, ::tflite::TensorType_BOOL, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } void LogicalBinaryOrBroadcastTest(std::vector& backends) { std::vector input0Shape { 1, 2, 2 }; std::vector input1Shape { 1, 1, 1 }; std::vector expectedOutputShape { 1, 2, 2 }; std::vector input0Values { 0, 1, 0, 1 }; std::vector input1Values { 1 }; std::vector expectedOutputValues { 1, 1, 1, 1 }; LogicalBinaryTest(tflite::BuiltinOperator_LOGICAL_OR, ::tflite::TensorType_BOOL, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues); } // LogicalNot operator uses ElementwiseUnary unary layer and descriptor but is still classed as logical operator. void LogicalNotBoolTest(std::vector& backends) { std::vector inputShape { 1, 2, 2 }; std::vector inputValues { 0, 1, 0, 1 }; std::vector expectedOutputValues { 1, 0, 1, 0 }; ElementwiseUnaryBoolTest(tflite::BuiltinOperator_LOGICAL_NOT, backends, inputShape, inputValues, expectedOutputValues); } TEST_SUITE("LogicalBinaryTests_GpuAccTests") { TEST_CASE ("LogicalBinary_AND_Bool_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LogicalBinaryAndBoolTest(backends); } TEST_CASE ("LogicalBinary_AND_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LogicalBinaryAndBroadcastTest(backends); } TEST_CASE ("Logical_NOT_Bool_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LogicalNotBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Bool_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LogicalBinaryOrBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Broadcast_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LogicalBinaryOrBroadcastTest(backends); } } TEST_SUITE("LogicalBinaryTests_CpuAccTests") { TEST_CASE ("LogicalBinary_AND_Bool_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LogicalBinaryAndBoolTest(backends); } TEST_CASE ("LogicalBinary_AND_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LogicalBinaryAndBroadcastTest(backends); } TEST_CASE ("Logical_NOT_Bool_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LogicalNotBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Bool_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LogicalBinaryOrBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Broadcast_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LogicalBinaryOrBroadcastTest(backends); } } TEST_SUITE("LogicalBinaryTests_CpuRefTests") { TEST_CASE ("LogicalBinary_AND_Bool_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LogicalBinaryAndBoolTest(backends); } TEST_CASE ("LogicalBinary_AND_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LogicalBinaryAndBroadcastTest(backends); } TEST_CASE ("Logical_NOT_Bool_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LogicalNotBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Bool_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LogicalBinaryOrBoolTest(backends); } TEST_CASE ("LogicalBinary_OR_Broadcast_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LogicalBinaryOrBroadcastTest(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/LogicalTestHelper.hpp000066400000000000000000000211361446772241200214710ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateLogicalBinaryTfLiteModel(tflite::BuiltinOperator logicalOperatorCode, tflite::TensorType tensorType, const std::vector & input0TensorShape, const std::vector & input1TensorShape, const std::vector & outputTensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input1TensorShape.data(), input1TensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("input_1"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOptions = 0; switch (logicalOperatorCode) { case BuiltinOperator_LOGICAL_AND: { operatorBuiltinOptionsType = BuiltinOptions_LogicalAndOptions; operatorBuiltinOptions = CreateLogicalAndOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_LOGICAL_OR: { operatorBuiltinOptionsType = BuiltinOptions_LogicalOrOptions; operatorBuiltinOptions = CreateLogicalOrOptions(flatBufferBuilder).Union(); break; } default: break; } const std::vector operatorInputs{ {0, 1} }; const std::vector operatorOutputs{ 2 }; flatbuffers::Offset logicalBinaryOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1} }; const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&logicalBinaryOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Logical Binary Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, logicalOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void LogicalBinaryTest(tflite::BuiltinOperator logicalOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& input0Shape, std::vector& input1Shape, std::vector& expectedOutputShape, std::vector& input0Values, std::vector& input1Values, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateLogicalBinaryTfLiteModel(logicalOperatorCode, tensorType, input0Shape, input1Shape, expectedOutputShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input1Values, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); armnnDelegate::CompareData(expectedOutputValues, armnnOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(expectedOutputValues, tfLiteOutputValues, expectedOutputValues.size()); armnnDelegate::CompareData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues.size()); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/LstmTest.cpp000066400000000000000000000200321446772241200176630ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "LstmTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void LstmTest(std::vector& backends) { int32_t batchSize = 2; int32_t inputSize = 2; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; std::vector inputShape {batchSize , inputSize}; std::vector cellStateInTensorInfo {batchSize , numUnits}; std::vector outputStateInTensorInfo {batchSize , outputSize}; std::vector scratchBufferTensorInfo {batchSize, numUnits * 4}; std::vector cellStateOutTensorInfo {batchSize, numUnits}; std::vector outputStateOutTensorInfo {batchSize, outputSize}; std::vector outputTensorInfo {batchSize, outputSize}; std::vector tensorInfo4 {numUnits}; std::vector tensorInfo8 {numUnits, 2}; std::vector tensorInfo16 {numUnits, 4}; //tensorInfo8, bool hasInputToInputWeights = true; std::vector inputToInputWeights {-0.45018822f, -0.02338299f, -0.0870589f, -0.34550029f, 0.04266912f, -0.15680569f, -0.34856534f, 0.43890524f}; std::vector inputToForgetWeights {0.09701663f, 0.20334584f, -0.50592935f, -0.31343272f, -0.40032279f, 0.44781327f, 0.01387155f, -0.35593212f}; std::vector inputToCellWeights {-0.50013041f, 0.1370284f, 0.11810488f, 0.2013163f, -0.20583314f, 0.44344562f, 0.22077113f, -0.29909778f}; std::vector inputToOutputWeights {-0.25065863f, -0.28290087f, 0.04613829f, 0.40525138f, 0.44272184f, 0.03897077f, -0.1556896f, 0.19487578f}; //tensorInfo16, bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights {-0.0063535f, -0.2042388f, 0.31454784f, -0.35746509f, 0.28902304f, 0.08183324f, -0.16555229f, 0.02286911f, -0.13566875f, 0.03034258f, 0.48091322f, -0.12528998f, 0.24077177f, -0.51332325f, -0.33502164f, 0.10629296f}; std::vector recurrentToForgetWeights {-0.48684245f, -0.06655136f, 0.42224967f, 0.2112639f, 0.27654213f, 0.20864892f, -0.07646349f, 0.45877004f, 0.00141793f, -0.14609534f, 0.36447752f, 0.09196436f, 0.28053468f, 0.01560611f, -0.20127171f, -0.01140004f}; std::vector recurrentToCellWeights {-0.3407414f, 0.24443203f, -0.2078532f, 0.26320225f, 0.05695659f, -0.00123841f, -0.4744786f, -0.35869038f, -0.06418842f, -0.13502428f, -0.501764f, 0.22830659f, -0.46367589f, 0.26016325f, -0.03894562f, -0.16368064f}; std::vector recurrentToOutputWeights {0.43385774f, -0.17194885f, 0.2718237f, 0.09215671f, 0.24107647f, -0.39835793f, 0.18212086f, 0.01301402f, 0.48572797f, -0.50656658f, 0.20047462f, -0.20607421f, -0.51818722f, -0.15390486f, 0.0468148f, 0.39922136f}; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights {}; bool hasCellToForgetWeights = false; std::vector cellToForgetWeights {}; bool hasCellToOutputWeights = false; std::vector cellToOutputWeights {}; bool hasInputGateBias = true; std::vector inputGateBias {0., 0., 0., 0.}; std::vector forgetGateBias {1., 1., 1., 1.}; std::vector cellBias {0., 0., 0., 0.}; std::vector outputGateBias {0., 0., 0., 0.}; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues {2., 3., 3., 4.}; std::vector expectedOutputValues {-0.02973187f, 0.1229473f, 0.20885126f, -0.15358765f, -0.0185422f, 0.11281417f, 0.24466537f, -0.1826292f}; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 0.f; float clippingThresProj = 0.f; LstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj); } TEST_SUITE("LstmTest_CpuRefTests") { TEST_CASE ("LstmTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; LstmTest(backends); } } //End of TEST_SUITE("Convolution2dTest_CpuRef") TEST_SUITE("LstmTest_CpuAccTests") { TEST_CASE ("LstmTest_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; LstmTest(backends); } } //End of TEST_SUITE("Convolution2dTest_CpuAcc") } // namespace armnnDelegatearmnn-23.08/delegate/test/LstmTestHelper.hpp000066400000000000000000001072621446772241200210430ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreateLstmTfLiteModel(tflite::TensorType tensorType, int32_t batchSize, int32_t inputSize, int32_t outputSize, int32_t numUnits, bool hasInputToInputWeights, const std::vector& inputToInputWeights, const std::vector& inputToForgetWeights, const std::vector& inputToCellWeights, const std::vector& inputToOutputWeights, bool hasRecurrentToInputWeights, const std::vector& recurrentToInputWeights, const std::vector& recurrentToForgetWeights, const std::vector& recurrentToCellWeights, const std::vector& recurrentToOutputWeights, bool hasCellToInputWeights, const std::vector& cellToInputWeights, bool hasCellToForgetWeights, const std::vector& cellToForgetWeights, bool hasCellToOutputWeights, const std::vector& cellToOutputWeights, bool hasInputGateBias, const std::vector& inputGateBias, const std::vector& forgetGateBias, const std::vector& cellBias, const std::vector& outputGateBias, bool hasProjectionWeights, const std::vector& projectionWeights, bool hasProjectionBias, const std::vector& projectionBias, bool hasInputLayerNormWeights, const std::vector& inputLayerNormWeights, bool hasForgetLayerNormWeights, const std::vector& forgetLayerNormWeights, bool hasCellLayerNormWeights, const std::vector& cellLayerNormWeights, bool hasOutputLayerNormWeights, const std::vector& outputLayerNormWeights, tflite::ActivationFunctionType activationFunction, float clippingThresCell, float clippingThresProj, float quantScale = 1.0f, int quantOffset = 0, float outputQuantScale = 2.0f, int outputQuantOffset = 0) { std::vector tensorInfo0 {}; std::vector tensorInfo4 {numUnits}; std::vector tensorInfo8 {numUnits, static_cast(2)}; std::vector tensorInfo16 {numUnits, static_cast(4)}; std::vector inputShape {batchSize , inputSize}; std::vector outputShape {batchSize , outputSize}; std::vector outputStateInDimensions{batchSize, outputSize}; std::vector cellStateInDimensions{batchSize, numUnits}; std::vector operatorInputs; using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; std::vector> tensors; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto outputQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ outputQuantScale }), flatBufferBuilder.CreateVector({ outputQuantOffset })); buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputShape.data(), inputShape.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("input_0"), quantizationParameters)); operatorInputs.push_back(buffers.size() - 1); if (hasInputToInputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputToInputWeights.data()), sizeof(T) * inputToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo8.data(), tensorInfo8.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToInputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputToForgetWeights.data()), sizeof(T) * inputToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo8.data(), tensorInfo8.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToForgetWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputToCellWeights.data()), sizeof(T) * inputToCellWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo8.data(), tensorInfo8.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToCellWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputToOutputWeights.data()), sizeof(T) * inputToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo8.data(), tensorInfo8.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToOutputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); if (hasRecurrentToInputWeights) { buffers.push_back(CreateBuffer( flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(recurrentToInputWeights.data()), sizeof(T) * recurrentToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo16.data(), tensorInfo16.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToInputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(recurrentToForgetWeights.data()), sizeof(T) * recurrentToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo16.data(), tensorInfo16.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToForgetWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(recurrentToCellWeights.data()), sizeof(T) * recurrentToCellWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo16.data(), tensorInfo16.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToCellWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(recurrentToOutputWeights.data()), sizeof(T) * recurrentToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo16.data(), tensorInfo16.size()), tensorType, buffers.size() - 1 , flatBufferBuilder.CreateString("recurrentToOutputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); if (hasCellToInputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellToInputWeights.data()), sizeof(T) * cellToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToInputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellToForgetWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellToForgetWeights.data()), sizeof(T) * cellToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToForgetWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellToOutputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellToOutputWeights.data()), sizeof(T) * cellToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToOutputWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasInputGateBias) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputGateBias.data()), sizeof(T) * inputGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputGateBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(forgetGateBias.data()), sizeof(T) * forgetGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("forgetGateBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellBias.data()), sizeof(T) * cellBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(outputGateBias.data()), sizeof(T) * outputGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("outputGateBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); if (hasProjectionWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(projectionWeights.data()), sizeof(T) * projectionWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("outputGateBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasProjectionBias) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(projectionBias.data()), sizeof(T) * projectionBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("projectionBias"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputStateInDimensions.data(), outputStateInDimensions.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("outputStateInInfo"), outputQuantizationParameters, true)); operatorInputs.push_back(buffers.size() - 1); buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(cellStateInDimensions.data(), cellStateInDimensions.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellStateInInfo"), outputQuantizationParameters, true)); operatorInputs.push_back(buffers.size() - 1); if (hasInputLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputLayerNormWeights.data()), sizeof(T) * inputLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputLayerNormWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasForgetLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(forgetLayerNormWeights.data()), sizeof(T) * forgetLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("forgetLayerNormWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellLayerNormWeights.data()), sizeof(T) * cellLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellLayerNormWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasOutputLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(outputLayerNormWeights.data()), sizeof(T) * outputLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfo4.data(), tensorInfo4.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("outputLayerNormWeights"), outputQuantizationParameters)); operatorInputs.push_back(buffers.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } int outputBufferId = buffers.size(); buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputShape.data(), outputShape.size()), tensorType, outputBufferId, flatBufferBuilder.CreateString("output"), outputQuantizationParameters)); std::vector operatorOutputs; operatorOutputs.push_back(buffers.size() - 1); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_LSTMOptions; flatbuffers::Offset operatorBuiltinOptions = CreateLSTMOptions(flatBufferBuilder, activationFunction, clippingThresCell, clippingThresProj).Union(); flatbuffers::Offset lstmOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), flatBufferBuilder.CreateVector(&lstmOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: LSTM Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_LSTM); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void LstmTestImpl(std::vector& backends, tflite::TensorType tensorType, int32_t batchSize, int32_t inputSize, int32_t outputSize, int32_t numUnits, bool hasInputToInputWeights, const std::vector& inputToInputWeights, const std::vector& inputToForgetWeights, const std::vector& inputToCellWeights, const std::vector& inputToOutputWeights, bool hasRecurrentToInputWeights, const std::vector& recurrentToInputWeights, const std::vector& recurrentToForgetWeights, const std::vector& recurrentToCellWeights, const std::vector& recurrentToOutputWeights, bool hasCellToInputWeights, const std::vector& cellToInputWeights, bool hasCellToForgetWeights, const std::vector& cellToForgetWeights, bool hasCellToOutputWeights, const std::vector& cellToOutputWeights, bool hasInputGateBias, const std::vector& inputGateBias, const std::vector& forgetGateBias, const std::vector& cellBias, const std::vector& outputGateBias, bool hasProjectionWeights, const std::vector& projectionWeights, bool hasProjectionBias, const std::vector& projectionBias, bool hasInputLayerNormWeights, const std::vector& inputLayerNormWeights, bool hasForgetLayerNormWeights, const std::vector& forgetLayerNormWeights, bool hasCellLayerNormWeights, const std::vector& cellLayerNormWeights, bool hasOutputLayerNormWeights, const std::vector& outputLayerNormWeights, std::vector& inputValues, std::vector& expectedOutputValues, tflite::ActivationFunctionType activationFunction, float clippingThresCell, float clippingThresProj) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateLstmTfLiteModel(tensorType, batchSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, activationFunction, clippingThresCell, clippingThresProj); std::vector expectedOutputShape {batchSize , outputSize}; // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/MirrorPadTest.cpp000066400000000000000000000226741446772241200206610ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "PadTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void MirrorPadSymmetric2dTest(std::vector& backends) { // Set input data std::vector inputShape { 3, 3 }; std::vector outputShape { 7, 7 }; std::vector paddingShape { 2, 2 }; std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f }; std::vector expectedOutputValues = { 5.0f, 4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f, 2.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 2.0f, 2.0f, 1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 2.0f, 5.0f, 4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f, 8.0f, 7.0f, 7.0f, 8.0f, 9.0f, 9.0f, 8.0f, 8.0f, 7.0f, 7.0f, 8.0f, 9.0f, 9.0f, 8.0f, 5.0f, 4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f }; std::vector paddingDim = { 2, 2, 2, 2 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 0, // Offset tflite::MirrorPadMode_SYMMETRIC); } void MirrorPadReflect2dTest(std::vector& backends) { // Set input data std::vector inputShape { 3, 3 }; std::vector outputShape { 7, 7 }; std::vector paddingShape { 2, 2 }; std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f }; std::vector expectedOutputValues = { 9.0f, 8.0f, 7.0f, 8.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f, 5.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 3.0f, 2.0f, 1.0f, 6.0f, 5.0f, 4.0f, 5.0f, 6.0f, 5.0f, 4.0f, 9.0f, 8.0f, 7.0f, 8.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f, 5.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 3.0f, 2.0f, 1.0f }; std::vector paddingDim = { 2, 2, 2, 2 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 0, // Offset tflite::MirrorPadMode_REFLECT); } void MirrorPadSymmetric3dTest(std::vector& backends) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 4, 4, 4 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { // Channel 0, Height (2) x Width (2) 1.0f, 2.0f, 3.0f, 4.0f, // Channel 1, Height (2) x Width (2) 5.0f, 6.0f, 7.0f, 8.0f }; std::vector expectedOutputValues = { 1.0f, 1.0f, 2.0f, 2.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 3.0f, 3.0f, 4.0f, 4.0f, 1.0f, 1.0f, 2.0f, 2.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 5.0f, 5.0f, 6.0f, 6.0f, 7.0f, 7.0f, 8.0f, 8.0f, 7.0f, 7.0f, 8.0f, 8.0f, 5.0f, 5.0f, 6.0f, 6.0f, 5.0f, 5.0f, 6.0f, 6.0f, 7.0f, 7.0f, 8.0f, 8.0f, 7.0f, 7.0f, 8.0f, 8.0f }; std::vector paddingDim = { 1, 1, 1, 1, 1, 1 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 0, // Offset tflite::MirrorPadMode_SYMMETRIC); } void MirrorPadReflect3dTest(std::vector& backends) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 4, 4, 4 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { // Channel 0, Height (2) x Width (2) 1.0f, 2.0f, 3.0f, 4.0f, // Channel 1, Height (2) x Width (2) 5.0f, 6.0f, 7.0f, 8.0f }; std::vector expectedOutputValues = { 8.0f, 7.0f, 8.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 8.0f, 7.0f, 8.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 4.0f, 3.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 1.0f, 4.0f, 3.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 1.0f, 8.0f, 7.0f, 8.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 8.0f, 7.0f, 8.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 4.0f, 3.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 1.0f, 4.0f, 3.0f, 4.0f, 3.0f, 2.0f, 1.0f, 2.0f, 1.0f }; std::vector paddingDim = { 1, 1, 1, 1, 1, 1 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 0, // Offset tflite::MirrorPadMode_REFLECT); } void MirrorPadSymmetricUint8Test(std::vector& backends) { // Set input data std::vector inputShape { 3, 3 }; std::vector outputShape { 5, 7 }; std::vector paddingShape { 2, 2 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::vector expectedOutputValues = { 2, 1, 1, 2, 3, 3, 2, 2, 1, 1, 2, 3, 3, 2, 5, 4, 4, 5, 6, 6, 5, 8, 7, 7, 8, 9, 9, 8, 8, 7, 7, 8, 9, 9, 8, }; std::vector paddingDim = { 1, 1, 2, 2 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_UINT8, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 1, // Offset tflite::MirrorPadMode_SYMMETRIC); } void MirrorPadReflectInt8Test(std::vector& backends) { // Set input data std::vector inputShape { 3, 3 }; std::vector outputShape { 7, 5 }; std::vector paddingShape { 2, 2 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; std::vector expectedOutputValues = { 8, 7, 8, 9, 8, 5, 4, 5, 6, 5, 2, 1, 2, 3, 2, 5, 4, 5, 6, 5, 8, 7, 8, 9, 8, 5, 4, 5, 6, 5, 2, 1, 2, 3, 2 }; std::vector paddingDim = { 2, 2, 1, 1 }; PadTest(tflite::BuiltinOperator_MIRROR_PAD, ::tflite::TensorType_INT8, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, 0, // Padding value - Not used in these tests. 1.0f, // Scale 1, // Offset tflite::MirrorPadMode_REFLECT); } TEST_SUITE("MirrorPad_CpuRefTests") { TEST_CASE ("MirrorPadSymmetric2d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadSymmetric2dTest(backends); } TEST_CASE ("MirrorPadReflect2d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadReflect2dTest(backends); } TEST_CASE ("MirrorPadSymmetric3d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadSymmetric3dTest(backends); } TEST_CASE ("MirrorPadReflect3d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadReflect3dTest(backends); } TEST_CASE ("MirrorPadSymmetricUint8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadSymmetricUint8Test(backends); } TEST_CASE ("MirrorPadSymmetricInt8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MirrorPadReflectInt8Test(backends); } } // TEST_SUITE("MirrorPad_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/NeonDelegateTests_NDK_Issue.cpp000066400000000000000000000042031446772241200233270ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "NormalizationTestHelper.hpp" #include "SoftmaxTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // There's a known Android NDK bug which causes this subset of Neon Tests to // fail. We'll exclude these tests in if we're doing // a debug build and NDK is less than r21. // The exclusion takes place in test/CMakeLists.txt // https://github.com/android/ndk/issues/1135 TEST_SUITE ("Softmax_CpuAccTests") { TEST_CASE ("Softmax_Standard_Beta_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; std::vector expectedOutput = {0.00994190481, 0.0445565246, 0.0734612942, 0.329230666, 0.542809606, 0.710742831, 0.158588171, 0.0961885825, 0.0214625746, 0.0130177103}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 1, expectedOutput); } TEST_CASE ("Softmax_Different_Beta_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; std::vector expectedOutput = { 0.0946234912, 0.148399189, 0.172415257, 0.270400971, 0.314161092, 0.352414012, 0.224709094, 0.193408906, 0.123322964, 0.106145054}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 0.3, expectedOutput); } TEST_CASE ("Log_Softmax_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; std::vector expectedOutput = {-4.61099672, -3.11099672, -2.61099672, -1.11099672, -0.610996664, -0.341444582, -1.84144461, -2.34144449, -3.84144449, -4.34144449}; SoftmaxTestCase(tflite::BuiltinOperator_LOG_SOFTMAX, backends, 0, expectedOutput); } } // TEST_SUITE ("Softmax_CpuAccTests") TEST_SUITE("L2Normalization_CpuAccTests") { TEST_CASE ("L2NormalizationFp32Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; L2NormalizationTest(backends); } } // TEST_SUITE("L2NormalizationFp32Test_CpuAcc_Test") }armnn-23.08/delegate/test/NormalizationTest.cpp000066400000000000000000000033411446772241200215760ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "NormalizationTestHelper.hpp" #include #include #include namespace armnnDelegate { TEST_SUITE("L2Normalization_CpuRefTests") { TEST_CASE ("L2NormalizationFp32Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; L2NormalizationTest(backends); } } // TEST_SUITE("L2Normalization_CpuRefTests") TEST_SUITE("L2Normalization_GpuAccTests") { TEST_CASE ("L2NormalizationFp32Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; L2NormalizationTest(backends); } } // TEST_SUITE("L2Normalization_GpuAccTests") TEST_SUITE("LocalResponseNormalization_CpuRefTests") { TEST_CASE ("LocalResponseNormalizationTest_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; LocalResponseNormalizationTest(backends, 3, 1.f, 1.f, 1.f); } } // TEST_SUITE("LocalResponseNormalization_CpuRefTests") TEST_SUITE("LocalResponseNormalization_CpuAccTests") { TEST_CASE ("LocalResponseNormalizationTest_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; LocalResponseNormalizationTest(backends, 3, 1.f, 1.f, 1.f); } } // TEST_SUITE("LocalResponseNormalization_CpuAccTests") TEST_SUITE("LocalResponseNormalization_GpuAccTests") { TEST_CASE ("LocalResponseNormalizationTest_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; LocalResponseNormalizationTest(backends, 3, 1.f, 1.f, 1.f); } } // TEST_SUITE("LocalResponseNormalization_GpuAccTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/NormalizationTestHelper.hpp000066400000000000000000000251741446772241200227530ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateNormalizationTfLiteModel(tflite::BuiltinOperator normalizationOperatorCode, tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& outputTensorShape, int32_t radius, float bias, float alpha, float beta, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); std::vector> tensors = { inputTensor, outputTensor }; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::vector operatorInputs = { 0 }; std::vector subgraphInputs = { 0 }; tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_L2NormOptions; flatbuffers::Offset operatorBuiltinOptions = CreateL2NormOptions(flatBufferBuilder, tflite::ActivationFunctionType_NONE).Union(); if (normalizationOperatorCode == tflite::BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION) { operatorBuiltinOptionsType = BuiltinOptions_LocalResponseNormalizationOptions; operatorBuiltinOptions = CreateLocalResponseNormalizationOptions(flatBufferBuilder, radius, bias, alpha, beta).Union(); } // create operator const std::vector operatorOutputs{ 1 }; flatbuffers::Offset normalizationOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphOutputs{ 1 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&normalizationOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Normalization Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, normalizationOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void NormalizationTest(tflite::BuiltinOperator normalizationOperatorCode, tflite::TensorType tensorType, const std::vector& backends, const std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, int32_t radius = 0, float bias = 0.f, float alpha = 0.f, float beta = 0.f, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateNormalizationTfLiteModel(normalizationOperatorCode, tensorType, inputShape, outputShape, radius, bias, alpha, beta, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } void L2NormalizationTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 1, 1, 10 }; std::vector outputShape { 1, 1, 1, 10 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f }; const float approxInvL2Norm = 0.050964719f; std::vector expectedOutputValues { 1.0f * approxInvL2Norm, 2.0f * approxInvL2Norm, 3.0f * approxInvL2Norm, 4.0f * approxInvL2Norm, 5.0f * approxInvL2Norm, 6.0f * approxInvL2Norm, 7.0f * approxInvL2Norm, 8.0f * approxInvL2Norm, 9.0f * approxInvL2Norm, 10.0f * approxInvL2Norm }; NormalizationTest(tflite::BuiltinOperator_L2_NORMALIZATION, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void LocalResponseNormalizationTest(std::vector& backends, int32_t radius, float bias, float alpha, float beta) { // Set input data std::vector inputShape { 2, 2, 2, 1 }; std::vector outputShape { 2, 2, 2, 1 }; std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; std::vector expectedOutputValues { 0.5f, 0.400000006f, 0.300000012f, 0.235294119f, 0.192307696f, 0.16216217f, 0.140000001f, 0.123076923f }; NormalizationTest(tflite::BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, radius, bias, alpha, beta); } } // anonymous namespacearmnn-23.08/delegate/test/PackTest.cpp000066400000000000000000000257501446772241200176360ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "PackTestHelper.hpp" #include #include #include #include namespace armnnDelegate { template void PackFp32Axis0Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector expectedOutputShape { 2, 3, 2, 3 }; std::vector> inputValues; inputValues.push_back( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }); inputValues.push_back( { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }); std::vector expectedOutputValues = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }; PackTest(tflite::BuiltinOperator_PACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 0); } template void PackFp32Axis1Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector expectedOutputShape { 3, 2, 2, 3 }; std::vector> inputValues; inputValues.push_back( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }); inputValues.push_back( { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }); std::vector expectedOutputValues = { 1, 2, 3, 4, 5, 6, 19, 20, 21, 22, 23, 24, 7, 8, 9, 10, 11, 12, 25, 26, 27, 28, 29, 30, 13, 14, 15, 16, 17, 18, 31, 32, 33, 34, 35, 36 }; PackTest(tflite::BuiltinOperator_PACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 1); } template void PackFp32Axis2Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector expectedOutputShape { 3, 2, 2, 3 }; std::vector> inputValues; inputValues.push_back( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }); inputValues.push_back( { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }); std::vector expectedOutputValues = { 1, 2, 3, 19, 20, 21, 4, 5, 6, 22, 23, 24, 7, 8, 9, 25, 26, 27, 10, 11, 12, 28, 29, 30, 13, 14, 15, 31, 32, 33, 16, 17, 18, 34, 35, 36 }; PackTest(tflite::BuiltinOperator_PACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 2); } template void PackFp32Axis3Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector expectedOutputShape { 3, 2, 3, 2 }; std::vector> inputValues; inputValues.push_back( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }); inputValues.push_back( { 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }); std::vector expectedOutputValues = { 1, 19, 2, 20, 3, 21, 4, 22, 5, 23, 6, 24, 7, 25, 8, 26, 9, 27, 10, 28, 11, 29, 12, 30, 13, 31, 14, 32, 15, 33, 16, 34, 17, 35, 18, 36 }; PackTest(tflite::BuiltinOperator_PACK, tflite::TensorType_FLOAT32, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 3); } template void PackFp32Inputs3Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 3, 3 }; std::vector expectedOutputShape { 3, 3, 3 }; std::vector> inputValues; inputValues.push_back( { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); inputValues.push_back( { 10, 11, 12, 13, 14, 15, 16, 17, 18 }); inputValues.push_back( { 19, 20, 21, 22, 23, 24, 25, 26, 27 }); std::vector expectedOutputValues = { 1, 2, 3, 10, 11, 12, 19, 20, 21, 4, 5, 6, 13, 14, 15, 22, 23, 24, 7, 8, 9, 16, 17, 18, 25, 26, 27 }; PackTest(tflite::BuiltinOperator_PACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 1); } TEST_SUITE("Pack_CpuAccTests") { // Fp32 TEST_CASE ("Pack_Fp32_Axis0_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis0Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis1_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis1Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis2_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis2Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis3_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis3Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Inputs3_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Inputs3Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Pack_Uint8_Axis0_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis0Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Pack_Uint8_Inputs3_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Inputs3Test(tflite::TensorType_UINT8, backends); } // Uint8 TEST_CASE ("Pack_Int8_Axis0_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Axis0Test(tflite::TensorType_INT8, backends); } TEST_CASE ("Pack_Int8_Inputs3_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; PackFp32Inputs3Test(tflite::TensorType_INT8, backends); } } TEST_SUITE("Pack_GpuAccTests") { // Fp32 TEST_CASE ("Pack_Fp32_Axis0_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis0Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis1_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis1Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis2_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis2Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis3_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis3Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Inputs3_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Inputs3Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Pack_Uint8_Axis0_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis0Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Pack_Uint8_Inputs3_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Inputs3Test(tflite::TensorType_UINT8, backends); } // Int8 TEST_CASE ("Pack_Int8_Axis0_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Axis0Test(tflite::TensorType_INT8, backends); } TEST_CASE ("Pack_Int8_Inputs3_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; PackFp32Inputs3Test(tflite::TensorType_INT8, backends); } } TEST_SUITE("Pack_CpuRefTests") { // Fp32 TEST_CASE ("Pack_Fp32_Axis0_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis0Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis1_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis1Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis2_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis2Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Axis3_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis3Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Pack_Fp32_Inputs3_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Inputs3Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Pack_Uint8_Axis0_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis0Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Pack_Uint8_Inputs3_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Inputs3Test(tflite::TensorType_UINT8, backends); } // Int8 TEST_CASE ("Pack_Int8_Axis0_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Axis0Test(tflite::TensorType_INT8, backends); } TEST_CASE ("Pack_Int8_Inputs3_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; PackFp32Inputs3Test(tflite::TensorType_INT8, backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/PackTestHelper.hpp000066400000000000000000000171371446772241200210030ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreatePackTfLiteModel(tflite::BuiltinOperator packOperatorCode, tflite::TensorType tensorType, std::vector& inputTensorShape, const std::vector & outputTensorShape, const int32_t inputTensorNum, unsigned int axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::vector operatorInputs{}; const std::vector operatorOutputs{inputTensorNum}; std::vector subgraphInputs{}; const std::vector subgraphOutputs{inputTensorNum}; std::vector> tensors(inputTensorNum + 1); for (int i = 0; i < inputTensorNum; ++i) { tensors[i] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input" + std::to_string(i)), quantizationParameters); // Add number of inputs to vector. operatorInputs.push_back(i); subgraphInputs.push_back(i); } // Create output tensor tensors[inputTensorNum] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_PackOptions; flatbuffers::Offset operatorBuiltinOptions = CreatePackOptions(flatBufferBuilder, inputTensorNum, axis).Union(); flatbuffers::Offset packOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&packOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Pack Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, packOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void PackTest(tflite::BuiltinOperator packOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& expectedOutputShape, std::vector>& inputValues, std::vector& expectedOutputValues, unsigned int axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreatePackTfLiteModel(packOperatorCode, tensorType, inputShape, expectedOutputShape, inputValues.size(), axis, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); // Set input data for all input tensors. for (unsigned int i = 0; i < inputValues.size(); ++i) { auto inputTensorValues = inputValues[i]; CHECK(tfLiteInterpreter.FillInputTensor(inputTensorValues, i) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputTensorValues, i) == kTfLiteOk); } CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/PadTest.cpp000066400000000000000000000605461446772241200174660ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "PadTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void Pad2dTest(std::vector& backends, tflite::BuiltinOperator padOperatorCode = tflite::BuiltinOperator_PAD, float pad = 0.0f) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 3, 5, 6 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { 0.0f, 4.0f, 2.0f, -5.0f, 6.0f, 1.0f, 5.0f, -2.0f }; std::vector expectedOutputValues = { pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 0.0f, 4.0f, pad, pad, pad, pad, 2.0f, -5.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 6.0f, 1.0f, pad, pad, pad, pad, 5.0f, -2.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad }; std::vector paddingDim = { 0, 1, 2, 1, 2, 2 }; PadTest(padOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, pad); } void Pad3dTest(std::vector& backends, tflite::BuiltinOperator padOperatorCode = tflite::BuiltinOperator_PAD, float pad = 0.0f) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 3, 5, 6 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { 0.0f, 4.0f, 2.0f, 5.0f, 6.0f, 1.0f, 5.0f, 2.0f }; std::vector expectedOutputValues = { pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 0.0f, 4.0f, pad, pad, pad, pad, 2.0f, 5.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 6.0f, 1.0f, pad, pad, pad, pad, 5.0f, 2.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad }; std::vector paddingDim = { 0, 1, 2, 1, 2, 2 }; PadTest(padOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, pad); } void Pad4dTest(std::vector& backends, tflite::BuiltinOperator padOperatorCode = tflite::BuiltinOperator_PAD, float pad = 0.0f) { // Set input data std::vector inputShape { 2, 2, 3, 2 }; std::vector outputShape { 4, 5, 7, 4 }; std::vector paddingShape { 4, 2 }; std::vector inputValues = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f }; std::vector expectedOutputValues = { pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 0.0f, 1.0f, pad, pad, 2.0f, 3.0f, pad, pad, 4.0f, 5.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 6.0f, 7.0f, pad, pad, 8.0f, 9.0f, pad, pad, 10.0f, 11.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 12.0f, 13.0f, pad, pad, 14.0f, 15.0f, pad, pad, 16.0f, 17.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, 18.0f, 19.0f, pad, pad, 20.0f, 21.0f, pad, pad, 22.0f, 23.0f, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad, pad }; std::vector paddingDim = { 1, 1, 2, 1, 3, 1, 1, 1 }; PadTest(padOperatorCode, ::tflite::TensorType_FLOAT32, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, pad); } void PadInt8Test(std::vector& backends, tflite::BuiltinOperator padOperatorCode = tflite::BuiltinOperator_PAD, int8_t paddingValue = 0, int8_t p = 3, float quantizationScale = -2.0f, int32_t quantizationOffset = 3) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 3, 5, 6 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { 0, 4, 2, -5, 6, 1, 5, -2 }; std::vector expectedOutputValues = { p, p, p, p, p, p, p, p, p, p, p, p, p, p, 0, 4, p, p, p, p, 2, -5, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, 6, 1, p, p, p, p, 5, -2, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p }; std::vector paddingDim = { 0, 1, 2, 1, 2, 2 }; PadTest(padOperatorCode, ::tflite::TensorType_INT8, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, paddingValue, quantizationScale, quantizationOffset); } void PadUint8Test(std::vector& backends, tflite::BuiltinOperator padOperatorCode = tflite::BuiltinOperator_PAD, uint8_t paddingValue = 0, uint8_t p = 3, float quantizationScale = -2.0f, int32_t quantizationOffset = 3) { // Set input data std::vector inputShape { 2, 2, 2 }; std::vector outputShape { 3, 5, 6 }; std::vector paddingShape { 3, 2 }; std::vector inputValues = { 0, 4, 2, 5, 6, 1, 5, 2 }; std::vector expectedOutputValues = { p, p, p, p, p, p, p, p, p, p, p, p, p, p, 0, 4, p, p, p, p, 2, 5, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, 6, 1, p, p, p, p, 5, 2, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p, p }; std::vector paddingDim = { 0, 1, 2, 1, 2, 2 }; PadTest(padOperatorCode, ::tflite::TensorType_UINT8, backends, inputShape, paddingShape, outputShape, inputValues, paddingDim, expectedOutputValues, paddingValue, quantizationScale, quantizationOffset); } TEST_SUITE("Pad_CpuRefTests") { TEST_CASE ("Pad2d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad2dTest(backends); } TEST_CASE ("Pad3d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad3dTest(backends); } TEST_CASE ("Pad4d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad4dTest(backends); } TEST_CASE ("Pad_Int8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PadInt8Test(backends); } TEST_CASE ("Pad_Uint8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PadUint8Test(backends); } TEST_CASE ("PadV22d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad2dTest(backends, tflite::BuiltinOperator_PADV2, -2.5); } TEST_CASE ("PadV23d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad3dTest(backends, tflite::BuiltinOperator_PADV2, 2.0); } TEST_CASE ("PadV24d_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; Pad4dTest(backends, tflite::BuiltinOperator_PADV2, -1.33); } TEST_CASE ("PadV2_Int8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PadInt8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } TEST_CASE ("PadV2_Uint8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PadUint8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } } // TEST_SUITE("Pad_CpuRefTests") TEST_SUITE("Pad_CpuAccTests") { TEST_CASE ("Pad2d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad2dTest(backends); } TEST_CASE ("Pad3d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad3dTest(backends); } TEST_CASE ("Pad4d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad4dTest(backends); } TEST_CASE ("Pad_Int8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PadInt8Test(backends); } TEST_CASE ("Pad_Uint8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PadUint8Test(backends); } TEST_CASE ("PadV22d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad2dTest(backends, tflite::BuiltinOperator_PADV2, -2.5); } TEST_CASE ("PadV23d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad3dTest(backends, tflite::BuiltinOperator_PADV2, 2.0); } TEST_CASE ("PadV24d_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; Pad4dTest(backends, tflite::BuiltinOperator_PADV2, -1.33); } TEST_CASE ("PadV2_Int8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PadInt8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } TEST_CASE ("PadV2_Uint8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PadUint8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } } // TEST_SUITE("Pad_CpuAccTests") TEST_SUITE("Pad_GpuAccTests") { TEST_CASE ("Pad2d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad2dTest(backends); } TEST_CASE ("Pad3d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad3dTest(backends); } TEST_CASE ("Pad4d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad4dTest(backends); } TEST_CASE ("Pad_Int8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PadInt8Test(backends); } TEST_CASE ("Pad_Uint8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PadUint8Test(backends); } TEST_CASE ("PadV22d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad2dTest(backends, tflite::BuiltinOperator_PADV2, -2.5); } TEST_CASE ("PadV23d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad3dTest(backends, tflite::BuiltinOperator_PADV2, 2.0); } TEST_CASE ("PadV24d_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; Pad4dTest(backends, tflite::BuiltinOperator_PADV2, -1.33); } TEST_CASE ("PadV2_Int8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PadInt8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } TEST_CASE ("PadV2_Uint8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PadUint8Test(backends, tflite::BuiltinOperator_PADV2, -1, -1); } } // TEST_SUITE("Pad_GpuAccTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/PadTestHelper.hpp000066400000000000000000000233151446772241200206240ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { template std::vector CreatePadTfLiteModel( tflite::BuiltinOperator padOperatorCode, tflite::TensorType tensorType, tflite::MirrorPadMode paddingMode, const std::vector& inputTensorShape, const std::vector& paddingTensorShape, const std::vector& outputTensorShape, const std::vector& paddingDim, const std::vector paddingValue, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); auto paddingTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(paddingTensorShape.data(), paddingTensorShape.size()), tflite::TensorType_INT32, 1, flatBufferBuilder.CreateString("padding")); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); std::vector> tensors = { inputTensor, paddingTensor, outputTensor}; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(paddingDim.data()), sizeof(int32_t) * paddingDim.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::vector operatorInputs; std::vector subgraphInputs; tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_PadOptions; flatbuffers::Offset operatorBuiltinOptions; if (padOperatorCode == tflite::BuiltinOperator_PAD) { operatorInputs = {{ 0, 1 }}; subgraphInputs = {{ 0, 1 }}; operatorBuiltinOptions = CreatePadOptions(flatBufferBuilder).Union(); } else if(padOperatorCode == tflite::BuiltinOperator_MIRROR_PAD) { operatorInputs = {{ 0, 1 }}; subgraphInputs = {{ 0, 1 }}; operatorBuiltinOptionsType = BuiltinOptions_MirrorPadOptions; operatorBuiltinOptions = CreateMirrorPadOptions(flatBufferBuilder, paddingMode).Union(); } else if (padOperatorCode == tflite::BuiltinOperator_PADV2) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(paddingValue.data()), sizeof(T)))); const std::vector shape = { 1 }; auto padValueTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(shape.data(), shape.size()), tensorType, 3, flatBufferBuilder.CreateString("paddingValue"), quantizationParameters); tensors.push_back(padValueTensor); operatorInputs = {{ 0, 1, 3 }}; subgraphInputs = {{ 0, 1, 3 }}; operatorBuiltinOptionsType = BuiltinOptions_PadV2Options; operatorBuiltinOptions = CreatePadV2Options(flatBufferBuilder).Union(); } // create operator const std::vector operatorOutputs{ 2 }; flatbuffers::Offset paddingOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&paddingOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Pad Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, padOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void PadTest(tflite::BuiltinOperator padOperatorCode, tflite::TensorType tensorType, const std::vector& backends, const std::vector& inputShape, const std::vector& paddingShape, std::vector& outputShape, std::vector& inputValues, std::vector& paddingDim, std::vector& expectedOutputValues, T paddingValue, float quantScale = 1.0f, int quantOffset = 0, tflite::MirrorPadMode paddingMode = tflite::MirrorPadMode_SYMMETRIC) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreatePadTfLiteModel(padOperatorCode, tensorType, paddingMode, inputShape, paddingShape, outputShape, paddingDim, {paddingValue}, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/Pooling2dTest.cpp000066400000000000000000001240321446772241200206060ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "Pooling2dTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void MaxPool2dFP32PaddingValidTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 1, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 12.0f, 7.0f }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 2, 2, 2, 2); } void MaxPool2dInt8PaddingValidTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 1, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 12, 7 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void MaxPool2dFP32PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 12.0f, 7.0f, 3.0f, -1.0f }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2); } void MaxPool2dInt8PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 12, 7, 3, -1 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void MaxPool2dFP32ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5.0f, -8.0f, -10.0f, 7.0f, -8.0f, -12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 0.0f, 0.0f, 7.0f, 3.0f, 0.0f, 2.0f }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU); } void MaxPool2dInt8ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5, -8, -10, 7, -8, -12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 1, 1, 7, 3, 1, 2 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.0f, 1); } void MaxPool2dFP32Relu6Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, -8.0f, -10.0f, 7.0f, -8.0f, -12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 0.0f, 0.0f, 3.0f, 0.0f }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 1, 1, ::tflite::ActivationFunctionType_RELU6); } void MaxPool2dInt8Relu6Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, -8, -10, 7, -8, -12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 1, 1, 3, 1 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 1, 1, ::tflite::ActivationFunctionType_RELU6, 2.0f, 1); } void MaxPool2dUint8PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { 5, 8, 10, 7, 8, 12, 15, 2, 3, 4, 1, 11 }; std::vector expectedOutputValues = { 12, 15, 4, 11 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void MaxPool2dUint8ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { 12, 8, 10, 15, 8, 5, 7, 2, 3, 4, 1, 11 }; std::vector expectedOutputValues = { 12, 10, 15, 8, 7, 11 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.0f, 1); } void MaxPool2dInt16PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 12, 7, 3, -1 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 0); } void MaxPool2dInt16ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5, -8, -10, 7, -8, -12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 0, 0, 7, 3, 0, 2 }; Pooling2dTest(tflite::BuiltinOperator_MAX_POOL_2D, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.0f, 0); } void AveragePool2dFP32PaddingValidTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 1, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 5.75f, -4.0f }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 2, 2, 2, 2); } void AveragePool2dInt8PaddingValidTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 1, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 6, -4 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void AveragePool2dFP32PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 5.75f, -4.0f, -0.5f, -6.0f }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2); } void AveragePool2dInt8PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 6, -4, -1, -6 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void AveragePool2dFP32ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, -8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, 11.0f }; std::vector expectedOutputValues = { 1.75f, 0.0f, 0.0f, 0.75f, 0.0f, 0.0f }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU); } void AveragePool2dInt8ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5, 8, -10, 7, -8, 12, -15, 2, 3, -4, -1, 11 }; std::vector expectedOutputValues = { 2, 1, 1, 1, 1, 1 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.5f, 1); } void AveragePool2dFP32Relu6Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, -8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, 11.0f }; std::vector expectedOutputValues = { 0.0f, 0.0f, 3.0f, 0.0f }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 1, 1, ::tflite::ActivationFunctionType_RELU6); } void AveragePool2dInt8Relu6Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, -8, 12, -15, 2, 3, -4, -1, 11 }; std::vector expectedOutputValues = { 1, 1, 3, 1 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 1, 1, ::tflite::ActivationFunctionType_RELU6, 2.5f, 1); } void AveragePool2dUint8PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { 5, 8, 10, 7, 8, 12, 15, 2, 3, 4, 1, 11 }; std::vector expectedOutputValues = { 8, 9, 4, 6 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 1); } void AveragePool2dUint8ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { 12, 8, 10, 15, 8, 5, 7, 2, 3, 4, 1, 11 }; std::vector expectedOutputValues = { 8, 8, 9, 5, 4, 5 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.0f, 1); } void AveragePool2dInt16PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { 6, -4, -1, -6 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2, tflite::ActivationFunctionType_NONE, 2.5f, 0); } void AveragePool2dInt16ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5, 8, -10, 7, -8, 12, -15, 2, 3, -4, -1, 11 }; std::vector expectedOutputValues = { 2, 0, 0, 1, 0, 0 }; Pooling2dTest(tflite::BuiltinOperator_AVERAGE_POOL_2D, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU, 2.5f, 0); } void L2Pool2dFP32PaddingValidTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 1, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 8.616844f, 9.721111f }; Pooling2dTest(tflite::BuiltinOperator_L2_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 2, 2, 2, 2); } void L2Pool2dFP32PaddingSameTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { 8.616844f, 9.721111f, 3.535534f, 7.81025f }; Pooling2dTest(tflite::BuiltinOperator_L2_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 2, 2); } void L2Pool2dFP32ReluTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, -8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, 11.0f }; std::vector expectedOutputValues = { 8.616844f, 11.543396f, 9.721111f, 7.632169f, 9.8234415f, 9.367497f }; Pooling2dTest(tflite::BuiltinOperator_L2_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_VALID, 1, 1, 2, 2, ::tflite::ActivationFunctionType_RELU); } void L2Pool2dFP32Relu6Test(std::vector& backends) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 2, 2, 1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, -8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, 11.0f }; std::vector expectedOutputValues = { 5.0f, 6.0f, 3.0f, 1.0f }; Pooling2dTest(tflite::BuiltinOperator_L2_POOL_2D, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, ::tflite::Padding_SAME, 2, 2, 1, 1, ::tflite::ActivationFunctionType_RELU6); } TEST_SUITE("Pooling2d_GpuAccTests") { TEST_CASE ("MaxPooling2d_FP32_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dInt8PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_FP32_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dInt8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dFP32ReluTest(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dInt8ReluTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dFP32Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dInt8Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Uint8_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dUint8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Uint8_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool2dUint8ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dInt8PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dInt8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dFP32ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dFP32Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dInt8ReluTest(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dInt8Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Uint8_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dUint8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Uint8_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool2dUint8ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; L2Pool2dFP32PaddingValidTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; L2Pool2dFP32PaddingSameTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; L2Pool2dFP32ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu6_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; L2Pool2dFP32Relu6Test(backends); } } // TEST_SUITE("Pooling2d_GpuAccTests") TEST_SUITE("Pooling2d_CpuAccTests") { TEST_CASE ("MaxPooling2d_FP32_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dInt8PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_FP32_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dInt8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dFP32ReluTest(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dInt8ReluTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dFP32Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dInt8Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Uint8_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dUint8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Uint8_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool2dUint8ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dInt8PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dInt8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dFP32ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dFP32Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dInt8ReluTest(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dInt8Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Uint8_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dUint8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Uint8_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool2dUint8ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; L2Pool2dFP32PaddingValidTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; L2Pool2dFP32PaddingSameTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; L2Pool2dFP32ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu6_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; L2Pool2dFP32Relu6Test(backends); } } // TEST_SUITE("Pooling2d_CpuAccTests") TEST_SUITE("Pooling2d_CpuRefTests") { TEST_CASE ("MaxPooling2d_FP32_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt8PaddingValidTest(backends); } TEST_CASE ("MaxPooling2d_FP32_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Int8_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dFP32ReluTest(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt8ReluTest(backends); } TEST_CASE ("MaxPooling2d_FP32_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dFP32Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Int8_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt8Relu6Test(backends); } TEST_CASE ("MaxPooling2d_Uint8_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dUint8PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Uint8_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dUint8ReluTest(backends); } TEST_CASE ("MaxPooling2d_Int16_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt16PaddingSameTest(backends); } TEST_CASE ("MaxPooling2d_Int16_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool2dInt16ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt8PaddingValidTest(backends); } TEST_CASE ("AveragePooling2d_FP32_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Int8_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dFP32ReluTest(backends); } TEST_CASE ("AveragePooling2d_FP32_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dFP32Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt8ReluTest(backends); } TEST_CASE ("AveragePooling2d_Int8_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt8Relu6Test(backends); } TEST_CASE ("AveragePooling2d_Uint8_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dUint8PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Uint8_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dUint8ReluTest(backends); } TEST_CASE ("AveragePooling2d_Int16_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt16PaddingSameTest(backends); } TEST_CASE ("AveragePooling2d_Int16_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool2dInt16ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; L2Pool2dFP32PaddingValidTest(backends); } TEST_CASE ("L2Pooling2d_FP32_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; L2Pool2dFP32PaddingSameTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; L2Pool2dFP32ReluTest(backends); } TEST_CASE ("L2Pooling2d_FP32_Relu6_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; L2Pool2dFP32Relu6Test(backends); } } // TEST_SUITE("Pooling2d_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/Pooling2dTestHelper.hpp000066400000000000000000000176201446772241200217570ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreatePooling2dTfLiteModel( tflite::BuiltinOperator poolingOperatorCode, tflite::TensorType tensorType, const std::vector & inputTensorShape, const std::vector & outputTensorShape, tflite::Padding padding = tflite::Padding_SAME, int32_t strideWidth = 0, int32_t strideHeight = 0, int32_t filterWidth = 0, int32_t filterHeight = 0, tflite::ActivationFunctionType fusedActivation = tflite::ActivationFunctionType_NONE, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; flatbuffers::Offset buffers[3] = {CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder)}; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); flatbuffers::Offset tensors[2] { CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters), CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters) }; // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_Pool2DOptions; flatbuffers::Offset operatorBuiltinOptions = CreatePool2DOptions(flatBufferBuilder, padding, strideWidth, strideHeight, filterWidth, filterHeight, fusedActivation).Union(); const std::vector operatorInputs{0}; const std::vector operatorOutputs{1}; flatbuffers::Offset poolingOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs), flatBufferBuilder.CreateVector(operatorOutputs), operatorBuiltinOptionsType, operatorBuiltinOptions); const int subgraphInputs[1] = {0}; const int subgraphOutputs[1] = {1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors, 2), flatBufferBuilder.CreateVector(subgraphInputs, 1), flatBufferBuilder.CreateVector(subgraphOutputs, 1), flatBufferBuilder.CreateVector(&poolingOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Pooling2d Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, poolingOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers, 3)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void Pooling2dTest(tflite::BuiltinOperator poolingOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, tflite::Padding padding = tflite::Padding_SAME, int32_t strideWidth = 0, int32_t strideHeight = 0, int32_t filterWidth = 0, int32_t filterHeight = 0, tflite::ActivationFunctionType fusedActivation = tflite::ActivationFunctionType_NONE, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreatePooling2dTfLiteModel(poolingOperatorCode, tensorType, inputShape, outputShape, padding, strideWidth, strideHeight, filterWidth, filterHeight, fusedActivation, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/Pooling3dTest.cpp000066400000000000000000000342451446772241200206150ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "Pooling3dTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { // Pool3D custom op was only added in tflite r2.6. #if defined(ARMNN_POST_TFLITE_2_5) void MaxPool3dFP32PaddingValidTest(std::vector& backends) { // Set input and expected output data std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 1, 2, 3, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 6, 6, 4 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kMax"; TfLitePadding padding = kTfLitePaddingValid; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 2, 2); } void MaxPool3dFP32PaddingSameTest(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 2, 3, 4, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 6, 6, 4, 4, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 4, 4 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kMax"; TfLitePadding padding = kTfLitePaddingSame; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 2, 2); } void MaxPool3dFP32H1Test(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 1, 3, 3, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 2, 3 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kMax"; TfLitePadding padding = kTfLitePaddingValid; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 1, 2); } void MaxPool3dFP32Test(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 2, 3, 4, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 6, 6 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kMax"; TfLitePadding padding = kTfLitePaddingUnknown; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 2, 2); } void AveragePool3dFP32PaddingValidTest(std::vector& backends) { // Set input data and expected output data. std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 1, 2, 3, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 3.5, 3, 2.5 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kAverage"; TfLitePadding padding = kTfLitePaddingValid; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 2, 2); } void AveragePool3dFP32PaddingSameTest(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 4, 2, 3, 1, 1 }; std::vector outputShape = { 4, 2, 3, 1, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 3, 4, 4.5, 4.5, 5.5, 6, 3, 4, 4.5, 4.5, 5.5, 6, 3, 4, 4.5, 4.5 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kAverage"; TfLitePadding padding = kTfLitePaddingSame; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 1, 1, 1, 2, 2, 2); } void AveragePool3dFP32H1Test(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 1, 2, 3, 4, 1 }; std::vector outputShape = { 1, 1, 2, 2, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 1.5, 3.5 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kAverage"; TfLitePadding padding = kTfLitePaddingUnknown; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 2, 2, 2, 2, 1, 2); } void AveragePool3dFP32Test(std::vector& backends) { // Set input data and expected output data std::vector inputShape = { 4, 3, 2, 1, 1 }; std::vector outputShape = { 1, 2, 2, 4, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues = { 3.125, 4.25 }; // poolType string required to create the correct pooling operator // Padding type required to create the padding in custom options std::string poolType = "kMax"; TfLitePadding padding = kTfLitePaddingUnknown; Pooling3dTest(poolType, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, padding, 2, 2, 2, 2, 2, 2); } TEST_SUITE("Pooling3d_GpuAccTests") { TEST_CASE ("MaxPooling3d_FP32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool3dFP32Test(backends); } TEST_CASE ("MaxPooling3d_FP32_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool3dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling3d_FP32_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool3dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling3d_FP32_H1_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; MaxPool3dFP32H1Test(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingValid_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool3dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingSame_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool3dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling3d_FP32_H1_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; AveragePool3dFP32H1Test(backends); } } // TEST_SUITE("Pooling3d_GpuAccTests") TEST_SUITE("Pooling3d_CpuAccTests") { TEST_CASE ("MaxPooling3d_FP32_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool3dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling3d_FP32_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool3dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling3d_FP32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool3dFP32Test(backends); } TEST_CASE ("MaxPooling3d_FP32_H1_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; MaxPool3dFP32H1Test(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingValid_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool3dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingSame_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool3dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling3d_FP32_H1_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; AveragePool3dFP32H1Test(backends); } } // TEST_SUITE("Pooling3d_CpuAccTests") TEST_SUITE("Pooling3d_CpuRefTests") { TEST_CASE ("MaxPooling3d_FP32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool3dFP32Test(backends); } TEST_CASE ("MaxPooling3d_FP32_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool3dFP32PaddingValidTest(backends); } TEST_CASE ("MaxPooling3d_FP32_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool3dFP32PaddingSameTest(backends); } TEST_CASE ("MaxPooling3d_FP32_H1_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; MaxPool3dFP32H1Test(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingValid_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool3dFP32PaddingValidTest(backends); } TEST_CASE ("AveragePooling3d_FP32_PaddingSame_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool3dFP32PaddingSameTest(backends); } TEST_CASE ("AveragePooling3d_FP32_H1_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; AveragePool3dFP32H1Test(backends); } } // TEST_SUITE("Pooling3d_CpuRefTests") #endif }armnn-23.08/delegate/test/Pooling3dTestHelper.hpp000066400000000000000000000260271446772241200217610ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include #include #include namespace { #if defined(ARMNN_POST_TFLITE_2_5) std::vector CreateCustomOptions(int, int, int, int, int, int, TfLitePadding); std::vector CreatePooling3dTfLiteModel( std::string poolType, tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& outputTensorShape, TfLitePadding padding = kTfLitePaddingSame, int32_t strideWidth = 0, int32_t strideHeight = 0, int32_t strideDepth = 0, int32_t filterWidth = 0, int32_t filterHeight = 0, int32_t filterDepth = 0, tflite::ActivationFunctionType fusedActivation = tflite::ActivationFunctionType_NONE, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); // Create the input and output tensors std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("output"), quantizationParameters); // Create the custom options from the function below std::vector customOperatorOptions = CreateCustomOptions(strideHeight, strideWidth, strideDepth, filterHeight, filterWidth, filterDepth, padding); // opCodeIndex is created as a uint8_t to avoid map lookup uint8_t opCodeIndex = 0; // Set the operator name based on the PoolType passed in from the test case std::string opName = ""; if (poolType == "kMax") { opName = "MaxPool3D"; } else { opName = "AveragePool3D"; } // To create a custom operator code you pass in the builtin code for custom operators and the name of the custom op flatbuffers::Offset operatorCode = CreateOperatorCodeDirect(flatBufferBuilder, tflite::BuiltinOperator_CUSTOM, opName.c_str()); // Create the Operator using the opCodeIndex and custom options. Also sets builtin options to none. const std::vector operatorInputs{ 0 }; const std::vector operatorOutputs{ 1 }; flatbuffers::Offset poolingOperator = CreateOperator(flatBufferBuilder, opCodeIndex, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), tflite::BuiltinOptions_NONE, 0, flatBufferBuilder.CreateVector(customOperatorOptions), tflite::CustomOptionsFormat_FLEXBUFFERS); // Create the subgraph using the operator created above. const std::vector subgraphInputs{ 0 }; const std::vector subgraphOutputs{ 1 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&poolingOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Pooling3d Operator Model"); // Create the model using operatorCode and the subgraph. flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void Pooling3dTest(std::string poolType, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, TfLitePadding padding = kTfLitePaddingSame, int32_t strideWidth = 0, int32_t strideHeight = 0, int32_t strideDepth = 0, int32_t filterWidth = 0, int32_t filterHeight = 0, int32_t filterDepth = 0, tflite::ActivationFunctionType fusedActivation = tflite::ActivationFunctionType_NONE, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; // Create the single op model buffer std::vector modelBuffer = CreatePooling3dTfLiteModel(poolType, tensorType, inputShape, outputShape, padding, strideWidth, strideHeight, strideDepth, filterWidth, filterHeight, filterDepth, fusedActivation, quantScale, quantOffset); std::string opType = ""; if (poolType == "kMax") { opType = "MaxPool3D"; } else { opType = "AveragePool3D"; } // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer, opType); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends, opType); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // Function to create the flexbuffer custom options for the custom pooling3d operator. std::vector CreateCustomOptions(int strideHeight, int strideWidth, int strideDepth, int filterHeight, int filterWidth, int filterDepth, TfLitePadding padding) { auto flex_builder = std::make_unique(); size_t map_start = flex_builder->StartMap(); flex_builder->String("data_format", "NDHWC"); // Padding is created as a key and padding type. Only VALID and SAME supported if (padding == kTfLitePaddingValid) { flex_builder->String("padding", "VALID"); } else { flex_builder->String("padding", "SAME"); } // Vector of filter dimensions in order ( 1, Depth, Height, Width, 1 ) auto start = flex_builder->StartVector("ksize"); flex_builder->Add(1); flex_builder->Add(filterDepth); flex_builder->Add(filterHeight); flex_builder->Add(filterWidth); flex_builder->Add(1); // EndVector( start, bool typed, bool fixed) flex_builder->EndVector(start, true, false); // Vector of stride dimensions in order ( 1, Depth, Height, Width, 1 ) auto stridesStart = flex_builder->StartVector("strides"); flex_builder->Add(1); flex_builder->Add(strideDepth); flex_builder->Add(strideHeight); flex_builder->Add(strideWidth); flex_builder->Add(1); // EndVector( stridesStart, bool typed, bool fixed) flex_builder->EndVector(stridesStart, true, false); flex_builder->EndMap(map_start); flex_builder->Finish(); return flex_builder->GetBuffer(); } #endif } // anonymous namespace armnn-23.08/delegate/test/PreluTest.cpp000066400000000000000000000070401446772241200200370ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "PreluTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void PreluFloatSimpleTest(std::vector & backends, bool isAlphaConst, bool isDynamicOutput = false) { std::vector inputShape { 1, 2, 3 }; std::vector alphaShape { 1 }; std::vector outputShape { 1, 2, 3 }; if (isDynamicOutput) { outputShape.clear(); } std::vector inputData = { -14.f, 2.f, 0.f, 1.f, -5.f, 14.f }; std::vector alphaData = { 0.5f }; std::vector expectedOutput = { -7.f, 2.f, 0.f, 1.f, -2.5f, 14.f }; PreluTest(tflite::BuiltinOperator_PRELU, ::tflite::TensorType_FLOAT32, backends, inputShape, alphaShape, outputShape, inputData, alphaData, expectedOutput, isAlphaConst); } TEST_SUITE("Prelu_CpuRefTests") { TEST_CASE ("PreluFp32SimpleConstTest_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PreluFloatSimpleTest(backends, true); } TEST_CASE ("PreluFp32SimpleTest_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PreluFloatSimpleTest(backends, false); } TEST_CASE ("PreluFp32SimpleConstDynamicTest_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PreluFloatSimpleTest(backends, true, true); } TEST_CASE ("PreluFp32SimpleDynamicTest_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; PreluFloatSimpleTest(backends, false, true); } } // TEST_SUITE("Prelu_CpuRefTests") TEST_SUITE("Prelu_CpuAccTests") { TEST_CASE ("PreluFp32SimpleConstTest_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PreluFloatSimpleTest(backends, true); } TEST_CASE ("PreluFp32SimpleTest_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PreluFloatSimpleTest(backends, false); } TEST_CASE ("PreluFp32SimpleConstDynamicTest_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PreluFloatSimpleTest(backends, true, true); } TEST_CASE ("PreluFp32SimpleDynamicTest_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; PreluFloatSimpleTest(backends, false, true); } } // TEST_SUITE("Prelu_CpuAccTests") TEST_SUITE("Prelu_GpuAccTests") { TEST_CASE ("PreluFp32SimpleConstTest_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PreluFloatSimpleTest(backends, true); } TEST_CASE ("PreluFp32SimpleTest_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PreluFloatSimpleTest(backends, false); } TEST_CASE ("PreluFp32SimpleConstDynamicTest_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PreluFloatSimpleTest(backends, true, true); } TEST_CASE ("PreluFp32SimpleDynamicTest_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; PreluFloatSimpleTest(backends, false, true); } } // TEST_SUITE("Prelu_GpuAccTests") }armnn-23.08/delegate/test/PreluTestHelper.hpp000066400000000000000000000174621446772241200212150ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreatePreluTfLiteModel(tflite::BuiltinOperator preluOperatorCode, tflite::TensorType tensorType, const std::vector& inputShape, const std::vector& alphaShape, const std::vector& outputShape, std::vector& alphaData, bool alphaIsConstant) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(alphaData.data()), sizeof(float) * alphaData.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ 1.0f }), flatBufferBuilder.CreateVector({ 0 })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputShape.data(), inputShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); auto alphaTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(alphaShape.data(), alphaShape.size()), tensorType, 2, flatBufferBuilder.CreateString("alpha"), quantizationParameters); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputShape.data(), outputShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); std::vector> tensors = { inputTensor, alphaTensor, outputTensor }; const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset preluOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size())); std::vector subgraphInputs{0}; if (!alphaIsConstant) { subgraphInputs.push_back(1); } const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&preluOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Prelu Operator Model"); flatbuffers::Offset opCode = CreateOperatorCode(flatBufferBuilder, preluOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&opCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void PreluTest(tflite::BuiltinOperator preluOperatorCode, tflite::TensorType tensorType, const std::vector& backends, const std::vector& inputShape, const std::vector& alphaShape, std::vector& outputShape, std::vector& inputData, std::vector& alphaData, std::vector& expectedOutput, bool alphaIsConstant) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreatePreluTfLiteModel(preluOperatorCode, tensorType, inputShape, alphaShape, outputShape, alphaData, alphaIsConstant); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputData, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputData, 0) == kTfLiteOk); // Set alpha data if not constant if (!alphaIsConstant) { CHECK(tfLiteInterpreter.FillInputTensor(alphaData, 1) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(alphaData, 1) == kTfLiteOk); } CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutput); // Don't compare shapes on dynamic output tests, as output shape gets cleared. if(!outputShape.empty()) { std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); } tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/QuantizationTest.cpp000066400000000000000000000315451446772241200214450ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "QuantizationTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // Dequantize operator test functions. void DequantizeUint8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; // Set input and output data std::vector inputValues { 0, 1, 2, 3, // Lower bounds 252, 253, 254, 255 // Upper bounds }; std::vector expectedOutputValues { 0.f, 1.f, 2.f, 3.f, 252.f, 253.f, 254.f, 255.f }; QuantizationTest(tflite::BuiltinOperator_DEQUANTIZE, ::tflite::TensorType_UINT8, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void DequantizeInt8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1, 0, 1, 2, -128, -127, 126, 127 }; std::vector expectedOutputValues { -1.f, 0.f, 1.f, 2.f, -128.f, -127.f, 126.f, 127.f }; QuantizationTest(tflite::BuiltinOperator_DEQUANTIZE, ::tflite::TensorType_INT8, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void DequantizeInt16Test(std::vector& backends) { std::vector inputShape { 2, 5 }; std::vector outputShape { 2, 5 }; std::vector inputValues { -1, 0, 1, 2, -32768, -16384, 16384, 32767 }; std::vector expectedOutputValues { -1.f, 0.f, 1.f, 2.f, -32768.f, -16384.f, 16384.f, 32767.f }; QuantizationTest(tflite::BuiltinOperator_DEQUANTIZE, ::tflite::TensorType_INT16, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues); } // Quantize operator test functions. void QuantizeFloat32Uint8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; // Set input and output data std::vector inputValues { -1.f, 0.f, 1.f, 2.f, // Lower bounds 252.f, 253.f, 255.f, 256.f // Upper bounds }; std::vector expectedOutputValues { 0, 0, 1, 2, 252, 253, 255, 255 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_FLOAT32, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeFloat32Int8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1.f, 0.f, 1.f, 2.f, -128.5f, -127.f, 126.f, 127.5f }; std::vector expectedOutputValues { -1, 0, 1, 2, -128, -127, 126, 127 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_FLOAT32, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeFloat32Int16Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1.f, 0.f, 1.f, 2.f, -32768.5f, -16384.f, 16384.f, 32767.5f }; std::vector expectedOutputValues { -1, 0, 1, 2, -32768, -16384, 16384, 32767 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_FLOAT32, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeInt16Int16Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1, 0, 1, 2, -32768, -16384, 16384, 32767 }; std::vector expectedOutputValues { -1, 0, 1, 2, -32768, -16384, 16384, 32767 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_INT16, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeInt16Int8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1, 0, 1, 2, -32768, -16384, 16384, 32767 }; std::vector expectedOutputValues { -1, 0, 1, 2, -128, -128, 127, 127 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_INT16, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeInt8Uint8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { -1, 0, 1, 2, -128, -127, 126, 127 }; std::vector expectedOutputValues { 0, 0, 1, 2, 0, 0, 126, 127 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_INT8, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues); } void QuantizeUint8Int8Test(std::vector& backends) { std::vector inputShape { 2, 4 }; std::vector outputShape { 2, 4 }; std::vector inputValues { 0, 1, 2, 3, 126, 127, 254, 255 }; std::vector expectedOutputValues { 0, 1, 2, 3, 126, 127, 127, 127 }; QuantizationTest(tflite::BuiltinOperator_QUANTIZE, ::tflite::TensorType_UINT8, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues); } TEST_SUITE("CpuRef_QuantizationTests") { TEST_CASE ("DEQUANTIZE_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DequantizeUint8Test(backends); } TEST_CASE ("DEQUANTIZE_INT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DequantizeInt8Test(backends); } TEST_CASE ("DEQUANTIZE_INT16_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DequantizeInt16Test(backends); } TEST_CASE ("QUANTIZE_FLOAT32_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeFloat32Uint8Test(backends); } TEST_CASE ("QUANTIZE_FLOAT32_INT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeFloat32Int8Test(backends); } TEST_CASE ("QUANTIZE_FLOAT32_INT16_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeFloat32Int16Test(backends); } TEST_CASE ("QUANTIZE_INT16_INT16_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeInt16Int16Test(backends); } TEST_CASE ("QUANTIZE_INT16_INT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeInt16Int8Test(backends); } TEST_CASE ("QUANTIZE_INT8_UINT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeInt8Uint8Test(backends); } TEST_CASE ("QUANTIZE_UINT8_INT8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; QuantizeUint8Int8Test(backends); } } TEST_SUITE("CpuAcc_QuantizationTests") { // Dequantize Operator Tests TEST_CASE ("DEQUANTIZE_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DequantizeUint8Test(backends); } TEST_CASE ("DEQUANTIZE_INT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DequantizeInt8Test(backends); } TEST_CASE ("DEQUANTIZE_INT16_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DequantizeInt16Test(backends); } // Quantize Operator Tests TEST_CASE ("QUANTIZE_FLOAT32_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; QuantizeFloat32Uint8Test(backends); } TEST_CASE ("QUANTIZE_FLOAT32_INT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; QuantizeFloat32Int8Test(backends); } TEST_CASE ("QUANTIZE_INT8_UINT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; QuantizeInt8Uint8Test(backends); } TEST_CASE ("QUANTIZE_UINT8_INT8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; QuantizeUint8Int8Test(backends); } } TEST_SUITE("GpuAcc_QuantizationTests") { // Dequantize Operator Tests TEST_CASE ("DEQUANTIZE_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DequantizeUint8Test(backends); } TEST_CASE ("DEQUANTIZE_INT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DequantizeInt8Test(backends); } TEST_CASE ("DEQUANTIZE_INT16_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DequantizeInt16Test(backends); } // Quantize Operator Tests TEST_CASE ("QUANTIZE_FLOAT32_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; QuantizeFloat32Uint8Test(backends); } TEST_CASE ("QUANTIZE_FLOAT32_INT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; QuantizeFloat32Int8Test(backends); } TEST_CASE ("QUANTIZE_INT8_UINT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; QuantizeInt8Uint8Test(backends); } TEST_CASE ("QUANTIZE_UINT8_INT8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; QuantizeUint8Int8Test(backends); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/QuantizationTestHelper.hpp000066400000000000000000000176311446772241200226120ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateQuantizationTfLiteModel(tflite::BuiltinOperator quantizationOperatorCode, tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, const std::vector & inputTensorShape, const std::vector & outputTensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset }), QuantizationDetails_CustomQuantization); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), outputTensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOptions = 0; switch (quantizationOperatorCode) { case BuiltinOperator_QUANTIZE: { operatorBuiltinOptionsType = BuiltinOptions_QuantizeOptions; operatorBuiltinOptions = CreateQuantizeOptions(flatBufferBuilder).Union(); break; } case BuiltinOperator_DEQUANTIZE: { operatorBuiltinOptionsType = BuiltinOptions_DequantizeOptions; operatorBuiltinOptions = CreateDequantizeOptions(flatBufferBuilder).Union(); break; } default: break; } const std::vector operatorInputs{0}; const std::vector operatorOutputs{1}; flatbuffers::Offset quantizationOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{0}; const std::vector subgraphOutputs{1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&quantizationOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Quantization Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, quantizationOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void QuantizationTest(tflite::BuiltinOperator quantizeOperatorCode, tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, std::vector& backends, std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateQuantizationTfLiteModel(quantizeOperatorCode, inputTensorType, outputTensorType, inputShape, outputShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/RedefineTestHelper.hpp000066400000000000000000000406301446772241200216400ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateReshapeTfLiteModel( tflite::BuiltinOperator redefineOperatorCode, tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& outputTensorShape, const std::vector& targetShape, bool useOption = true, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); std::vector> tensors; std::vector operatorInputs; std::vector subgraphInputs; flatbuffers::Offset operatorBuiltinOptions; if (useOption) { buffers.push_back(CreateBuffer(flatBufferBuilder)); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); tensors = { inputTensor, outputTensor}; operatorInputs = {0}; subgraphInputs = {0}; operatorBuiltinOptions = CreateReshapeOptions( flatBufferBuilder, flatBufferBuilder.CreateVector(targetShape.data(), targetShape.size())).Union(); } else { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(targetShape.data()), sizeof(int32_t) * targetShape.size()))); int32_t size = static_cast(targetShape.size()); auto shapeTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector( { size } ), tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("shape")); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); tensors = { inputTensor, outputTensor, shapeTensor }; operatorInputs = {0, 2}; subgraphInputs = {0, 2}; operatorBuiltinOptions = CreateReshapeOptions(flatBufferBuilder).Union(); } // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_ReshapeOptions; const std::vector operatorOutputs{1}; flatbuffers::Offset redefineOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphOutputs{1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&redefineOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Reshape Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, redefineOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } std::vector CreateRedefineTfLiteModel( tflite::BuiltinOperator redefineOperatorCode, tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& outputTensorShape, const std::vector& squeezeOrAxisData, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); auto inputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); std::vector> tensors; std::vector operatorInputs; std::vector subgraphInputs; flatbuffers::Offset operatorBuiltinOptions; tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_SqueezeOptions; if (redefineOperatorCode == tflite::BuiltinOperator_SQUEEZE) { buffers.push_back(CreateBuffer(flatBufferBuilder)); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); tensors = { inputTensor, outputTensor}; operatorInputs = {0}; subgraphInputs = {0}; operatorBuiltinOptions = CreateSqueezeOptions(flatBufferBuilder, flatBufferBuilder.CreateVector(squeezeOrAxisData.data(), squeezeOrAxisData.size())).Union(); operatorBuiltinOptionsType = BuiltinOptions_SqueezeOptions; } else if (redefineOperatorCode == tflite::BuiltinOperator_EXPAND_DIMS) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(squeezeOrAxisData.data()), sizeof(int32_t) * squeezeOrAxisData.size()))); auto shapeTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector( { 1 } ), tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("axis")); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto outputTensor = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); tensors = { inputTensor, outputTensor, shapeTensor }; operatorInputs = {0, 2}; subgraphInputs = {0, 2}; operatorBuiltinOptions = CreateExpandDimsOptions(flatBufferBuilder).Union(); operatorBuiltinOptionsType = BuiltinOptions_ExpandDimsOptions; } const std::vector operatorOutputs{1}; flatbuffers::Offset redefineOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphOutputs{1}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&redefineOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Redefine Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, redefineOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void RedefineTest(tflite::BuiltinOperator redefineOperatorCode, tflite::TensorType tensorType, const std::vector& backends, const std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, std::vector& additionalData, bool useOption = true, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer; if (redefineOperatorCode == tflite::BuiltinOperator_EXPAND_DIMS) { modelBuffer = CreateRedefineTfLiteModel(redefineOperatorCode, tensorType, inputShape, outputShape, additionalData, quantScale, quantOffset); } else if (redefineOperatorCode == tflite::BuiltinOperator_RESHAPE) { modelBuffer = CreateReshapeTfLiteModel(redefineOperatorCode, tensorType, inputShape, outputShape, additionalData, useOption, quantScale, quantOffset); } else if (redefineOperatorCode == tflite::BuiltinOperator_SQUEEZE) { modelBuffer = CreateRedefineTfLiteModel(redefineOperatorCode, tensorType, inputShape, outputShape, additionalData, quantScale, quantOffset); } // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ReduceTest.cpp000066400000000000000000000326461446772241200201710ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ReduceTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void ReduceUint8KeepDimsTest(tflite::BuiltinOperator reduceOperatorCode, std::vector& backends, std::vector& expectedOutputValues) { std::vector input0Shape { 1, 1, 2, 3 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1, 1, 3 }; std::vector input0Values { 1, 2, 3, 4, 3, 1 }; // Inputs std::vector input1Values { 2 }; // Axis ReduceTest(reduceOperatorCode, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, true); } void ReduceUint8Test(tflite::BuiltinOperator reduceOperatorCode, std::vector& backends, std::vector& expectedOutputValues) { std::vector input0Shape { 1, 1, 2, 3 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1, 3 }; std::vector input0Values { 1, 2, 3, 4, 3, 1 }; // Inputs std::vector input1Values { 2 }; // Axis ReduceTest(reduceOperatorCode, ::tflite::TensorType_UINT8, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, false); } void ReduceFp32KeepDimsTest(tflite::BuiltinOperator reduceOperatorCode, std::vector& backends, std::vector& expectedOutputValues) { std::vector input0Shape { 1, 1, 2, 3 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1, 1, 3 }; std::vector input0Values { 1001.0f, 11.0f, 1003.0f, 10.0f, 1002.0f, 12.0f }; // Inputs std::vector input1Values { 2 }; // Axis ReduceTest(reduceOperatorCode, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, true); } void ReduceFp32Test(tflite::BuiltinOperator reduceOperatorCode, std::vector& backends, std::vector& expectedOutputValues) { std::vector input0Shape { 1, 1, 2, 3 }; std::vector input1Shape { 1 }; std::vector expectedOutputShape { 1, 1, 3 }; std::vector input0Values { 1001.0f, 11.0f, 1003.0f, 10.0f, 1002.0f, 12.0f }; // Inputs std::vector input1Values { 2 }; // Axis ReduceTest(reduceOperatorCode, ::tflite::TensorType_FLOAT32, backends, input0Shape, input1Shape, expectedOutputShape, input0Values, input1Values, expectedOutputValues, false); } // REDUCE_MAX Tests TEST_SUITE("ReduceMax_CpuRefTests") { TEST_CASE ("ReduceMax_Uint8_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } } // End of ReduceMax_CpuRefTests TEST_SUITE("ReduceMax_CpuAccTests") { TEST_CASE ("ReduceMax_Uint8_KeepDims_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_KeepDims_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } } // End of ReduceMax_CpuAccTests TEST_SUITE("ReduceMax_GpuAccTests") { TEST_CASE ("ReduceMax_Uint8_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 4, 3, 3 }; ReduceUint8Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32KeepDimsTest(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } TEST_CASE ("ReduceMax_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 1001.0f, 1002.0f, 1003.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MAX, backends, expectedOutputValues); } } // End of ReduceMax_GpuAccTests // REDUCE_MIN Tests TEST_SUITE("ReduceMin_CpuRefTests") { TEST_CASE ("ReduceMin_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 10.0f, 11.0f, 12.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MIN, backends, expectedOutputValues); } } // End of ReduceMin_CpuRefTests TEST_SUITE("ReduceMin_CpuAccTests") { TEST_CASE ("ReduceMin_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 10.0f, 11.0f, 12.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MIN, backends, expectedOutputValues); } } // End of ReduceMin_CpuAccTests TEST_SUITE("ReduceMin_GpuAccTests") { TEST_CASE ("ReduceMin_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 10.0f, 11.0f, 12.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_MIN, backends, expectedOutputValues); } } // End of ReduceMin_GpuAccTests // SUM Tests TEST_SUITE("Sum_CpuRefTests") { TEST_CASE ("Sum_Uint8_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 5, 5, 4 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } TEST_CASE ("Sum_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 1011.0f, 1013.0f, 1015.0f }; ReduceFp32Test(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } } // End of Sum_CpuRefTests TEST_SUITE("Sum_CpuAccTests") { TEST_CASE ("Sum_Uint8_KeepDims_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 5, 5, 4 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } TEST_CASE ("Sum_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 1011.0f, 1013.0f, 1015.0f }; ReduceFp32Test(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } } // End of Sum_CpuAccTests TEST_SUITE("Sum_GpuAccTests") { TEST_CASE ("Sum_Uint8_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 5, 5, 4 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } TEST_CASE ("Sum_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 1011.0f, 1013.0f, 1015.0f }; ReduceFp32Test(tflite::BuiltinOperator_SUM, backends, expectedOutputValues); } } // End of Sum_GpuAccTests // PROD Tests TEST_SUITE("Prod_CpuRefTests") { TEST_CASE ("Prod_Uint8_KeepDims_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 4, 6, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } TEST_CASE ("Prod_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; std::vector expectedOutputValues { 10010.0f, 11022.0f, 12036.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } } // End of Prod_CpuRefTests TEST_SUITE("Prod_CpuAccTests") { TEST_CASE ("Prod_Uint8_KeepDims_CpuAcc_Test" ) { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 4, 6, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } TEST_CASE ("Prod_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; std::vector expectedOutputValues { 10010.0f, 11022.0f, 12036.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } } // End of Prod_CpuAccTests TEST_SUITE("Prod_GpuAccTests") { TEST_CASE ("Prod_Uint8_KeepDims_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 4, 6, 3 }; ReduceUint8KeepDimsTest(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } TEST_CASE ("Prod_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; std::vector expectedOutputValues { 10010.0f, 11022.0f, 12036.0f }; ReduceFp32Test(tflite::BuiltinOperator_REDUCE_PROD, backends, expectedOutputValues); } } // End of Prod_GpuAccTests } // namespace armnnDelegatearmnn-23.08/delegate/test/ReduceTestHelper.hpp000066400000000000000000000241171446772241200213300ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateReduceTfLiteModel(tflite::BuiltinOperator reduceOperatorCode, tflite::TensorType tensorType, std::vector& input0TensorShape, std::vector& input1TensorShape, const std::vector & outputTensorShape, std::vector& axisData, const bool keepDims, float quantScale = 1.0f, int quantOffset = 0, bool kTfLiteNoQuantizationForQuantized = false) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; flatbuffers::Offset buffers[4] = { CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(axisData.data()), sizeof(int32_t) * axisData.size())), CreateBuffer(flatBufferBuilder) }; flatbuffers::Offset quantizationParametersAxis = CreateQuantizationParameters(flatBufferBuilder); flatbuffers::Offset quantizationParameters; if (kTfLiteNoQuantizationForQuantized) { if ((quantScale == 1 || quantScale == 0) && quantOffset == 0) { // Creates quantization parameter with quantization.type = kTfLiteNoQuantization quantizationParameters = CreateQuantizationParameters(flatBufferBuilder); } else { // Creates quantization parameter with quantization.type != kTfLiteNoQuantization quantizationParameters = CreateQuantizationParameters( flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); } } else { quantizationParameters = CreateQuantizationParameters( flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); } std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input1TensorShape.data(), input1TensorShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("axis"), quantizationParametersAxis); // Create output tensor tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 3, flatBufferBuilder.CreateString("output"), quantizationParameters); // Create operator. Reduce operations MIN, MAX, SUM, MEAN, PROD uses ReducerOptions. tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_ReducerOptions; flatbuffers::Offset operatorBuiltinOptions = CreateReducerOptions(flatBufferBuilder, keepDims).Union(); const std::vector operatorInputs{ {0, 1} }; const std::vector operatorOutputs{ 2 }; flatbuffers::Offset reduceOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1} }; const std::vector subgraphOutputs{ 2 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&reduceOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Reduce Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, reduceOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers, 4)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ReduceTest(tflite::BuiltinOperator reduceOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& input0Shape, std::vector& input1Shape, std::vector& expectedOutputShape, std::vector& input0Values, std::vector& input1Values, std::vector& expectedOutputValues, const bool keepDims, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBufferArmNN = CreateReduceTfLiteModel(reduceOperatorCode, tensorType, input0Shape, input1Shape, expectedOutputShape, input1Values, keepDims, quantScale, quantOffset, false); std::vector modelBufferTFLite = CreateReduceTfLiteModel(reduceOperatorCode, tensorType, input0Shape, input1Shape, expectedOutputShape, input1Values, keepDims, quantScale, quantOffset, true); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBufferTFLite); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBufferArmNN, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input0Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ReshapeTest.cpp000066400000000000000000000401501446772241200203360ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "RedefineTestHelper.hpp" #include #include #include #include #include using Half = half_float::half; namespace armnnDelegate { void ReshapeSimpleTest(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 3, 2, 2 }; std::vector targetShape { 1, 3, 2, 2 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption); } using namespace half_float::literal; void ReshapeSimpleFloat16Test(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 3, 2, 2 }; std::vector targetShape { 1, 3, 2, 2 }; std::vector inputValues = { 5._h, -8._h, -10._h, 7._h, 8._h, 12._h, -15._h, 2._h, 3._h, -4._h, -1._h, -11._h }; std::vector expectedOutputValues = { 5._h, -8._h, -10._h, 7._h, 8._h, 12._h, -15._h, 2._h, 3._h, -4._h, -1._h, -11._h }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_FLOAT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption); } void ReshapeReduceDimTest(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 1, 4, 3 }; std::vector targetShape { 1, 4, 3 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption); } void ReshapeFlattenTest(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 6, 2 }; std::vector targetShape { -1, 2 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption); } void ReshapeFlattenAllTest(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 12 }; std::vector targetShape { -1 }; std::vector inputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; std::vector expectedOutputValues = { -5.0f, 8.0f, -10.0f, 7.0f, 8.0f, 12.0f, -15.0f, 2.0f, 3.0f, -4.0f, -1.0f, -11.0f }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption); } void ReshapeInt8Test(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 6, 2 }; std::vector targetShape { -1, 2 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_INT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption, 2.5f, 1); } void ReshapeUint8Test(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 6, 2 }; std::vector targetShape { -1, 2 }; std::vector inputValues = { 5, 8, 10, 7, 8, 12, 15, 2, 3, 4, 1, 11 }; std::vector expectedOutputValues = { 5, 8, 10, 7, 8, 12, 15, 2, 3, 4, 1, 11 }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption, 2.5f, 1); } void ReshapeInt16Test(std::vector& backends, bool useOption = true) { // Set input data std::vector inputShape { 1, 3, 4, 1 }; std::vector outputShape { 6, 2 }; std::vector targetShape { -1, 2 }; std::vector inputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; std::vector expectedOutputValues = { -5, 8, -10, 7, 8, 12, -15, 2, 3, -4, -1, -11 }; RedefineTest(tflite::BuiltinOperator_RESHAPE, ::tflite::TensorType_INT16, backends, inputShape, outputShape, inputValues, expectedOutputValues, targetShape, useOption, 2.5f, 0); } TEST_SUITE("Reshape_GpuAccTests") { TEST_CASE ("Reshape_Simple_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeSimpleTest(backends); } TEST_CASE ("Reshape_ReduceDimension_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeReduceDimTest(backends); } TEST_CASE ("Reshape_Flatten_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeFlattenTest(backends); } TEST_CASE ("Reshape_FlattenAll_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeFlattenAllTest(backends); } TEST_CASE ("Reshape_Int8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeInt8Test(backends); } TEST_CASE ("Reshape_Uint8_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeUint8Test(backends); } TEST_CASE ("Reshape_Float16_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeSimpleFloat16Test(backends); } TEST_CASE ("Reshape_Simple_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeSimpleTest(backends, false); } TEST_CASE ("Reshape_ReduceDimension_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeReduceDimTest(backends, false); } TEST_CASE ("Reshape_Flatten_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeFlattenTest(backends, false); } TEST_CASE ("Reshape_FlattenAll_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeFlattenAllTest(backends, false); } TEST_CASE ("Reshape_Int8_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeInt8Test(backends, false); } TEST_CASE ("Reshape_Uint8_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeUint8Test(backends, false); } TEST_CASE ("Reshape_Float16_ShapeTensor_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReshapeSimpleFloat16Test(backends, false); } } // TEST_SUITE("Reshape_GpuAccTests") TEST_SUITE("Reshape_CpuAccTests") { TEST_CASE ("Reshape_Simple_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeSimpleTest(backends); } TEST_CASE ("Reshape_ReduceDimension_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeReduceDimTest(backends); } TEST_CASE ("Reshape_Flatten_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeFlattenTest(backends); } TEST_CASE ("Reshape_FlattenAll_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeFlattenAllTest(backends); } TEST_CASE ("Reshape_Int8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeInt8Test(backends); } TEST_CASE ("Reshape_Uint8_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeUint8Test(backends); } TEST_CASE ("Reshape_Float16_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeSimpleFloat16Test(backends); } TEST_CASE ("Reshape_Simple_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeSimpleTest(backends, false); } TEST_CASE ("Reshape_ReduceDimension_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeReduceDimTest(backends, false); } TEST_CASE ("Reshape_Flatten_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeFlattenTest(backends, false); } TEST_CASE ("Reshape_FlattenAll_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeFlattenAllTest(backends, false); } TEST_CASE ("Reshape_Int8_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeInt8Test(backends, false); } TEST_CASE ("Reshape_Uint8_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeUint8Test(backends, false); } TEST_CASE ("Reshape_Float16_ShapeTensor_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReshapeSimpleFloat16Test(backends, false); } } // TEST_SUITE("Reshape_CpuAccTests") TEST_SUITE("Reshape_CpuRefTests") { TEST_CASE ("Reshape_Simple_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeSimpleTest(backends); } TEST_CASE ("Reshape_ReduceDimension_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeReduceDimTest(backends); } TEST_CASE ("Reshape_Flatten_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeFlattenTest(backends); } TEST_CASE ("Reshape_FlattenAll_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeFlattenAllTest(backends); } TEST_CASE ("Reshape_Int8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeInt8Test(backends); } TEST_CASE ("Reshape_Uint8_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeUint8Test(backends); } TEST_CASE ("Reshape_Int16_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeInt16Test(backends); } TEST_CASE ("Reshape_Float16_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeSimpleFloat16Test(backends); } TEST_CASE ("Reshape_Simple_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeSimpleTest(backends, false); } TEST_CASE ("Reshape_ReduceDimension_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeReduceDimTest(backends, false); } TEST_CASE ("Reshape_Flatten_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeFlattenTest(backends, false); } TEST_CASE ("Reshape_FlattenAll_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeFlattenAllTest(backends, false); } TEST_CASE ("Reshape_Int8_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeInt8Test(backends, false); } TEST_CASE ("Reshape_Uint8_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeUint8Test(backends, false); } TEST_CASE ("Reshape_Int16_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeInt16Test(backends, false); } TEST_CASE ("Reshape_Float16_ShapeTensor_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReshapeSimpleFloat16Test(backends, false); } } // TEST_SUITE("Reshape_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/ResizeTest.cpp000066400000000000000000000072711446772241200202170ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ResizeTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void ResizeBiliniarFloat32Test(std::vector& backends) { // Set input data std::vector input1Values { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; const std::vector input2NewShape { 5, 5 }; // Calculate output data std::vector expectedOutputValues { 0.0f, 0.6f, 1.2f, 1.8f, 2.0f, 1.8f, 2.4f, 3.0f, 3.6f, 3.8f, 3.6f, 4.2f, 4.8f, 5.4f, 5.6f, 5.4f, 6.0f, 6.6f, 7.2f, 7.4f, 6.0f, 6.6f, 7.2f, 7.8f, 8.0f }; const std::vector input1Shape { 1, 3, 3, 1 }; const std::vector input2Shape { 2 }; const std::vector expectedOutputShape = { 1, 5, 5, 1 }; ResizeFP32TestImpl(tflite::BuiltinOperator_RESIZE_BILINEAR, backends, input1Values, input1Shape, input2NewShape, input2Shape, expectedOutputValues, expectedOutputShape); } void ResizeNearestNeighbourFloat32Test(std::vector& backends) { // Set input data std::vector input1Values { 1.0f, 2.0f, 3.0f, 4.0f } ; const std::vector input2NewShape { 1, 1 }; // Calculate output data std::vector expectedOutputValues { 1.0f }; const std::vector input1Shape { 1, 2, 2, 1 }; const std::vector input2Shape { 2 }; const std::vector expectedOutputShape = { 1, 1, 1, 1 }; ResizeFP32TestImpl(tflite::BuiltinOperator_RESIZE_NEAREST_NEIGHBOR, backends, input1Values, input1Shape, input2NewShape, input2Shape, expectedOutputValues, expectedOutputShape); } TEST_SUITE("ResizeTests_GpuAccTests") { TEST_CASE ("Resize_Biliniar_Float32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ResizeBiliniarFloat32Test(backends); } TEST_CASE ("Resize_NearestNeighbour_Float32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ResizeNearestNeighbourFloat32Test(backends); } } // TEST_SUITE("ResizeTests_GpuAccTests") TEST_SUITE("ResizeTests_CpuAccTests") { TEST_CASE ("Resize_Biliniar_Float32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ResizeBiliniarFloat32Test(backends); } TEST_CASE ("Resize_NearestNeighbour_Float32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ResizeNearestNeighbourFloat32Test(backends); } } // TEST_SUITE("ResizeTests_CpuAccTests") TEST_SUITE("ResizeTests_CpuRefTests") { TEST_CASE ("Resize_Biliniar_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ResizeBiliniarFloat32Test(backends); } TEST_CASE ("Resize_NearestNeighbour_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ResizeNearestNeighbourFloat32Test(backends); } } // TEST_SUITE("ResizeTests_CpuRefTests") } // namespace armnnDelegate armnn-23.08/delegate/test/ResizeTestHelper.hpp000066400000000000000000000175321446772241200213650ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateResizeTfLiteModel(tflite::BuiltinOperator operatorCode, tflite::TensorType inputTensorType, const std::vector & inputTensorShape, const std::vector & sizeTensorData, const std::vector & sizeTensorShape, const std::vector & outputTensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(sizeTensorData.data()), sizeof(int32_t) * sizeTensorData.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input_tensor")); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(sizeTensorShape.data(), sizeTensorShape.size()), TensorType_INT32, 2, flatBufferBuilder.CreateString("size_input_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), inputTensorType, 3, flatBufferBuilder.CreateString("output_tensor")); // Create Operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOption = 0; switch (operatorCode) { case BuiltinOperator_RESIZE_BILINEAR: { operatorBuiltinOption = CreateResizeBilinearOptions(flatBufferBuilder, false, false).Union(); operatorBuiltinOptionsType = tflite::BuiltinOptions_ResizeBilinearOptions; break; } case BuiltinOperator_RESIZE_NEAREST_NEIGHBOR: { operatorBuiltinOption = CreateResizeNearestNeighborOptions(flatBufferBuilder, false, false).Union(); operatorBuiltinOptionsType = tflite::BuiltinOptions_ResizeNearestNeighborOptions; break; } default: break; } const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset resizeOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOption); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&resizeOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Resize Biliniar Operator Model"); flatbuffers::Offset opCode = CreateOperatorCode(flatBufferBuilder, operatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&opCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void ResizeFP32TestImpl(tflite::BuiltinOperator operatorCode, std::vector& backends, std::vector& input1Values, std::vector input1Shape, std::vector input2NewShape, std::vector input2Shape, std::vector& expectedOutputValues, std::vector expectedOutputShape) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateResizeTfLiteModel(operatorCode, ::tflite::TensorType_FLOAT32, input1Shape, input2NewShape, input2Shape, expectedOutputShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input1Values, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(input2NewShape, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input1Values, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(input2NewShape, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/ReverseV2Test.cpp000066400000000000000000000121021446772241200205660ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ReverseV2TestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void ReverseV2Float32Test(std::vector& backends) { // Set input data std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f }; // The output data std::vector expectedOutputValues = { 3.0f, 2.0f, 1.0f, 6.0f, 5.0f, 4.0f, 9.0f, 8.0f, 7.0f, 13.0f, 12.0f, 11.0f, 16.0f, 15.0f, 14.0f, 19.0f, 18.0f, 17.0f, 23.0f, 22.0f, 21.0f, 26.0f, 25.0f, 24.0f, 29.0f, 28.0f, 27.0f }; // The axis to reverse const std::vector axisValues = {2}; // Shapes const std::vector inputShape = {3, 3, 3}; const std::vector axisShapeDims = {1}; const std::vector expectedOutputShape = {3, 3, 3}; ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, backends, inputValues, inputShape, axisValues, axisShapeDims, expectedOutputValues, expectedOutputShape); } void ReverseV2NegativeAxisFloat32Test(std::vector& backends) { // Set input data std::vector inputValues = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f }; // The output data std::vector expectedOutputValues = { 7.0f, 8.0f, 9.0f, 4.0f, 5.0f, 6.0f, 1.0f, 2.0f, 3.0f, 17.0f, 18.0f, 19.0f, 14.0f, 15.0f, 16.0f, 11.0f, 12.0f, 13.0f, 27.0f, 28.0f, 29.0f, 24.0f, 25.0f, 26.0f, 21.0f, 22.0f, 23.0f }; // The axis to reverse const std::vector axisValues = {-2}; // Shapes const std::vector inputShape = {3, 3, 3}; const std::vector axisShapeDims = {1}; const std::vector expectedOutputShape = {3, 3, 3}; ReverseV2FP32TestImpl(tflite::BuiltinOperator_REVERSE_V2, backends, inputValues, inputShape, axisValues, axisShapeDims, expectedOutputValues, expectedOutputShape); } #if defined(REVERSEV2_GPUACC) TEST_SUITE("ReverseV2Tests_GpuAccTests") { TEST_CASE ("ReverseV2_Float32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReverseV2Float32Test(backends); } TEST_CASE ("ReverseV2_NegativeAxis_Float32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; ReverseV2NegativeAxisFloat32Test(backends); } } // TEST_SUITE("ReverseV2Tests_GpuAccTests") #endif #if defined(REVERSEV2_CPUACC) TEST_SUITE("ReverseV2Tests_CpuAccTests") { TEST_CASE ("ReverseV2_Float32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReverseV2Float32Test(backends); } TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; ReverseV2NegativeAxisFloat32Test(backends); } } // TEST_SUITE("ReverseV2Tests_CpuAccTests") #endif TEST_SUITE("ReverseV2Tests_CpuRefTests") { TEST_CASE ("ReverseV2_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReverseV2Float32Test(backends); } TEST_CASE ("ReverseV2_NegativeAxis_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ReverseV2NegativeAxisFloat32Test(backends); } } // TEST_SUITE("ReverseV2Tests_CpuRefTests") } // namespace armnnDelegate armnn-23.08/delegate/test/ReverseV2TestHelper.hpp000066400000000000000000000174551446772241200217530ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateReverseV2TfLiteModel(tflite::BuiltinOperator operatorCode, tflite::TensorType inputTensorType, const std::vector & inputTensorShape, const std::vector & axisTensorData, const std::vector & axisTensorShape, const std::vector & outputTensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(axisTensorData.data()), sizeof(int32_t) * axisTensorData.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input_tensor")); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(axisTensorShape.data(), axisTensorShape.size()), TensorType_INT32, 2, flatBufferBuilder.CreateString("axis_input_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), inputTensorType, 3, flatBufferBuilder.CreateString("output_tensor")); // Create Operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOption = 0; const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset reverseV2Operator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOption); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&reverseV2Operator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: ReverseV2 Operator Model"); flatbuffers::Offset opCode = CreateOperatorCode(flatBufferBuilder, operatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&opCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void ReverseV2FP32TestImpl(tflite::BuiltinOperator operatorCode, std::vector& backends, std::vector& inputValues, std::vector inputShape, std::vector axisValues, std::vector axisShapeDims, std::vector& expectedOutputValues, std::vector expectedOutputShape) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateReverseV2TfLiteModel(operatorCode, ::tflite::TensorType_FLOAT32, inputShape, axisValues, axisShapeDims, expectedOutputShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(axisValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(axisValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/RoundTest.cpp000066400000000000000000000033171446772241200200420ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "RoundTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void FloorFp32Test(std::vector& backends) { std::vector inputShape {1, 3, 2, 3}; std::vector outputShape {1, 3, 2, 3}; std::vector inputValues { -37.5f, -15.2f, -8.76f, -2.0f, -1.5f, -1.3f, -0.5f, -0.4f, 0.0f, 1.0f, 0.4f, 0.5f, 1.3f, 1.5f, 2.0f, 8.76f, 15.2f, 37.5f }; std::vector expectedOutputValues { -38.0f, -16.0f, -9.0f, -2.0f, -2.0f, -2.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 8.0f, 15.0f, 37.0f }; RoundTest(tflite::BuiltinOperator_FLOOR, ::tflite::TensorType_FLOAT32, backends, inputShape, inputValues, expectedOutputValues); } // FLOOR Test Suite TEST_SUITE("FLOOR_CpuRefTests") { TEST_CASE ("FLOOR_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; FloorFp32Test(backends); } } TEST_SUITE("FLOOR_CpuAccTests") { TEST_CASE ("FLOOR_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; FloorFp32Test(backends); } } TEST_SUITE("FLOOR_GpuAccTests") { TEST_CASE ("FLOOR_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; FloorFp32Test(backends); } } // End of FLOOR Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/RoundTestHelper.hpp000066400000000000000000000147001446772241200212050ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateRoundTfLiteModel(tflite::BuiltinOperator roundOperatorCode, tflite::TensorType tensorType, const std::vector & tensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); const std::vector operatorInputs({0}); const std::vector operatorOutputs({1}); flatbuffers::Offset roundOperator; flatbuffers::Offset modelDescription; flatbuffers::Offset operatorCode; switch (roundOperatorCode) { case tflite::BuiltinOperator_FLOOR: default: roundOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size())); modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Floor Operator Model"); operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_FLOOR); break; } const std::vector subgraphInputs({0}); const std::vector subgraphOutputs({1}); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&roundOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void RoundTest(tflite::BuiltinOperator roundOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& shape, std::vector& inputValues, std::vector& expectedOutputValues, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateRoundTfLiteModel(roundOperatorCode, tensorType, shape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, shape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/ShapeTest.cpp000066400000000000000000000022351446772241200200110ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ShapeTestHelper.hpp" #include namespace armnnDelegate { void ShapeSimpleTest(std::vector& backends) { std::vector inputShape{ 1, 3, 2, 3 }; std::vector inputValues{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; std::vector expectedOutputShape{ 4 }; std::vector expectedOutputValues{ 1, 3, 2, 3 }; ShapeTest(::tflite::TensorType_INT32, ::tflite::TensorType_INT32, backends, inputShape, inputValues, expectedOutputValues, expectedOutputShape); } // SHAPE Test Suite TEST_SUITE("SHAPE_CpuRefTests") { TEST_CASE("SHAPE_Simple_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; ShapeSimpleTest(backends); } } // End of SHAPE Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/ShapeTestHelper.hpp000066400000000000000000000160231446772241200211560ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateShapeTfLiteModel(tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, const std::vector& inputTensorShape, const std::vector& outputTensorShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), outputTensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); const std::vector operatorInputs({ 0 }); const std::vector operatorOutputs({ 1 }); flatbuffers::Offset shapeOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_ShapeOptions, CreateShapeOptions(flatBufferBuilder, outputTensorType).Union()); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: SHAPE Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_SHAPE); const std::vector subgraphInputs({ 0 }); const std::vector subgraphOutputs({ 1 }); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&shapeOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void ShapeTest(tflite::TensorType inputTensorType, tflite::TensorType outputTensorType, std::vector& backends, std::vector& inputShape, std::vector& inputValues, std::vector& expectedOutputValues, std::vector& expectedOutputShape, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateShapeTfLiteModel(inputTensorType, outputTensorType, inputShape, expectedOutputShape, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/SliceTest.cpp000066400000000000000000000062371446772241200200160ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SliceTestHelper.hpp" #include #include #include namespace armnnDelegate { void SliceFixtureSimpleTest(std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector outputShape { 2, 1, 3 }; std::vector beginShape { 3 }; std::vector sizeShape { 3 }; std::vector beginData { 1, 0, 0 }; std::vector sizeData { 2, 1, 3 }; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 3.0f, 3.0f, 3.0f, 5.0f, 5.0f, 5.0f }; SliceTestImpl( backends, inputData, outputData, beginData, sizeData, inputShape, beginShape, sizeShape, outputShape); } void SliceFixtureSizeTest(std::vector& backends) { std::vector inputShape { 3, 2, 3 }; std::vector outputShape { 2, 1, 3 }; std::vector beginShape { 3 }; std::vector sizeShape { 3 }; std::vector beginData { 1, 0, 0 }; std::vector sizeData { 2, 1, -1 }; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 3.0f, 3.0f, 3.0f, 5.0f, 5.0f, 5.0f }; SliceTestImpl( backends, inputData, outputData, beginData, sizeData, inputShape, beginShape, sizeShape, outputShape); } TEST_SUITE("Slice_CpuRefTests") { TEST_CASE ("Slice_Simple_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SliceFixtureSimpleTest(backends); } TEST_CASE ("Slice_Size_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SliceFixtureSizeTest(backends); } } // Slice_CpuRefTests TestSuite TEST_SUITE("Slice_CpuAccTests") { TEST_CASE ("Slice_Simple_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SliceFixtureSimpleTest(backends); } TEST_CASE ("Slice_Size_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SliceFixtureSizeTest(backends); } } // Slice_CpuAccTests TestSuite TEST_SUITE("StridedSlice_GpuAccTests") { TEST_CASE ("Slice_Simple_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SliceFixtureSimpleTest(backends); } TEST_CASE ("Slice_Size_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SliceFixtureSizeTest(backends); } } // Slice_GpuAccTests TestSuite } // namespace armnnDelegatearmnn-23.08/delegate/test/SliceTestHelper.hpp000066400000000000000000000171061446772241200211600ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateSliceTfLiteModel(tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& beginTensorData, const std::vector& sizeTensorData, const std::vector& beginTensorShape, const std::vector& sizeTensorShape, const std::vector& outputTensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; flatbuffers::Offset buffers[5] = { CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(beginTensorData.data()), sizeof(int32_t) * beginTensorData.size())), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(sizeTensorData.data()), sizeof(int32_t) * sizeTensorData.size())), CreateBuffer(flatBufferBuilder) }; std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input")); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(beginTensorShape.data(), beginTensorShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("begin_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(sizeTensorShape.data(), sizeTensorShape.size()), ::tflite::TensorType_INT32, 3, flatBufferBuilder.CreateString("size_tensor")); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 4, flatBufferBuilder.CreateString("output")); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_SliceOptions; flatbuffers::Offset operatorBuiltinOptions = CreateSliceOptions(flatBufferBuilder).Union(); const std::vector operatorInputs{ 0, 1, 2 }; const std::vector operatorOutputs{ 3 }; flatbuffers::Offset sliceOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ 0, 1, 2 }; const std::vector subgraphOutputs{ 3 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&sliceOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Slice Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_SLICE); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers, 5)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void SliceTestImpl(std::vector& backends, std::vector& inputValues, std::vector& expectedOutputValues, std::vector& beginTensorData, std::vector& sizeTensorData, std::vector& inputTensorShape, std::vector& beginTensorShape, std::vector& sizeTensorShape, std::vector& outputTensorShape) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateSliceTfLiteModel( ::tflite::TensorType_FLOAT32, inputTensorShape, beginTensorData, sizeTensorData, beginTensorShape, sizeTensorShape, outputTensorShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // End of Slice Test } // anonymous namespacearmnn-23.08/delegate/test/SoftmaxTest.cpp000066400000000000000000000055711446772241200204000ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SoftmaxTestHelper.hpp" #include #include #include #include namespace armnnDelegate { TEST_SUITE ("Softmax_GpuAccTests") { TEST_CASE ("Softmax_Standard_Beta_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; std::vector expectedOutput = {0.00994190481, 0.0445565246, 0.0734612942, 0.329230666, 0.542809606, 0.710742831, 0.158588171, 0.0961885825, 0.0214625746, 0.0130177103}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 1, expectedOutput); } TEST_CASE ("Softmax_Different_Beta_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; std::vector expectedOutput = {0.0946234912, 0.148399189, 0.172415257, 0.270400971, 0.314161092, 0.352414012, 0.224709094, 0.193408906, 0.123322964, 0.106145054}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 0.3, expectedOutput); } TEST_CASE ("Log_Softmax_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; std::vector expectedOutput = {-4.61099672, -3.11099672, -2.61099672, -1.11099672, -0.610996664, -0.341444582, -1.84144461, -2.34144449, -3.84144449, -4.34144449}; SoftmaxTestCase(tflite::BuiltinOperator_LOG_SOFTMAX, backends, 0, expectedOutput); } } // TEST_SUITE ("Softmax_GpuAccTests") TEST_SUITE ("Softmax_CpuRefTests") { TEST_CASE ("Softmax_Standard_Beta_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; std::vector expectedOutput = { 0.00994190481, 0.0445565246, 0.0734612942, 0.329230666, 0.542809606, 0.710742831, 0.158588171, 0.0961885825, 0.0214625746, 0.0130177103}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 1, expectedOutput); } TEST_CASE ("Softmax_Different_Beta_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; std::vector expectedOutput = { 0.0946234912, 0.148399189, 0.172415257, 0.270400971, 0.314161092, 0.352414012, 0.224709094, 0.193408906, 0.123322964, 0.106145054}; SoftmaxTestCase(tflite::BuiltinOperator_SOFTMAX, backends, 0.3, expectedOutput); } TEST_CASE ("Log_Softmax_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; std::vector expectedOutput = {-4.61099672, -3.11099672, -2.61099672, -1.11099672, -0.610996664, -0.341444582, -1.84144461, -2.34144449, -3.84144449, -4.34144449}; SoftmaxTestCase(tflite::BuiltinOperator_LOG_SOFTMAX, backends, 0, expectedOutput); } } // TEST_SUITE ("Softmax_CpuRefTests") } // namespace armnnDelegate armnn-23.08/delegate/test/SoftmaxTestHelper.hpp000066400000000000000000000171241446772241200215420ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include #include namespace { std::vector CreateSoftmaxTfLiteModel(tflite::BuiltinOperator softmaxOperatorCode, tflite::TensorType tensorType, const std::vector & tensorShape, float beta) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 1); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorShape.data(), tensorShape.size()), tensorType, 2); const std::vector operatorInputs({0}); const std::vector operatorOutputs({1}); flatbuffers::Offset softmaxOperator; flatbuffers::Offset modelDescription; flatbuffers::Offset operatorCode; switch (softmaxOperatorCode) { case tflite::BuiltinOperator_SOFTMAX: softmaxOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_SoftmaxOptions, CreateSoftmaxOptions(flatBufferBuilder, beta).Union()); modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Softmax Operator Model"); operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_SOFTMAX); break; case tflite::BuiltinOperator_LOG_SOFTMAX: softmaxOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_LogSoftmaxOptions, CreateLogSoftmaxOptions(flatBufferBuilder).Union()); flatBufferBuilder.CreateString("ArmnnDelegate: Log-Softmax Operator Model"); operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_LOG_SOFTMAX); break; default: break; } const std::vector subgraphInputs({0}); const std::vector subgraphOutputs({1}); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&softmaxOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void SoftmaxTest(tflite::BuiltinOperator softmaxOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& shape, std::vector& inputValues, std::vector& expectedOutputValues, float beta = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateSoftmaxTfLiteModel(softmaxOperatorCode, tensorType, shape, beta); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, shape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } /// Convenience function to run softmax and log-softmax test cases /// \param operatorCode tflite::BuiltinOperator_SOFTMAX or tflite::BuiltinOperator_LOG_SOFTMAX /// \param backends armnn backends to target /// \param beta multiplicative parameter to the softmax function /// \param expectedOutput to be checked against transformed input void SoftmaxTestCase(tflite::BuiltinOperator operatorCode, std::vector backends, float beta, std::vector expectedOutput) { std::vector input = { 1.0, 2.5, 3.0, 4.5, 5.0, -1.0, -2.5, -3.0, -4.5, -5.0}; std::vector shape = {2, 5}; SoftmaxTest(operatorCode, tflite::TensorType_FLOAT32, backends, shape, input, expectedOutput, beta); } } // anonymous namespace armnn-23.08/delegate/test/SpaceDepthTest.cpp000066400000000000000000000142041446772241200207700ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SpaceDepthTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void DepthToSpaceFp32Test(std::vector& backends, int blockSize) { // Set input data std::vector inputShape { 1, 2, 2, 4 }; std::vector outputShape { 1, 4, 4, 1 }; std::vector inputValues = { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f, 10.f, 11.f, 12.f, 13.f, 14.f, 15.f, 16.f }; std::vector expectedOutputValues = { 1.f, 2.f, 5.f, 6.f, 3.f, 4.f, 7.f, 8.f, 9.f, 10.f, 13.f, 14.f, 11.f, 12.f, 15.f, 16.f }; SpaceDepthTest(tflite::BuiltinOperator_DEPTH_TO_SPACE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, blockSize); } void DepthToSpaceUint8Test(std::vector& backends, int blockSize) { // Set input data std::vector inputShape { 2, 1, 1, 4 }; std::vector outputShape { 2, 2, 2, 1 }; std::vector inputValues = { 1, 2, 3, 4, 5, 6, 7, 8 }; std::vector expectedOutputValues = { 1, 2, 3, 4, 5, 6, 7, 8 }; SpaceDepthTest(tflite::BuiltinOperator_DEPTH_TO_SPACE, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, blockSize); } void SpaceToDepthFp32Test(std::vector& backends, int blockSize) { // Set input data std::vector inputShape { 1, 2, 2, 2 }; std::vector outputShape { 1, 1, 1, 8 }; std::vector inputValues = { 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f }; std::vector expectedOutputValues = { 1.4f, 2.3f, 3.2f, 4.1f, 5.4f, 6.3f, 7.2f, 8.1f }; SpaceDepthTest(tflite::BuiltinOperator_SPACE_TO_DEPTH, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, blockSize); } void SpaceToDepthUint8Test(std::vector& backends, int blockSize) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector outputShape { 1, 1, 1, 4 }; std::vector inputValues = { 1, 2, 3, 2 }; std::vector expectedOutputValues = { 1, 2, 3, 2 }; SpaceDepthTest(tflite::BuiltinOperator_SPACE_TO_DEPTH, ::tflite::TensorType_UINT8, backends, inputShape, outputShape, inputValues, expectedOutputValues, blockSize); } TEST_SUITE("DepthToSpace_CpuRefTests") { TEST_CASE ("DepthToSpaceFp32Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DepthToSpaceFp32Test(backends, 2); } TEST_CASE ("DepthToSpaceUint8Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; DepthToSpaceUint8Test(backends, 2); } } // TEST_SUITE("DepthToSpace_CpuRefTests") TEST_SUITE("DepthToSpace_CpuAccTests") { TEST_CASE ("DepthToSpaceFp32Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DepthToSpaceFp32Test(backends, 2); } TEST_CASE ("DepthToSpaceUint8Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; DepthToSpaceUint8Test(backends, 2); } } // TEST_SUITE("DepthToSpace_CpuAccTests") TEST_SUITE("DepthToSpace_GpuAccTests") { TEST_CASE ("DepthToSpaceFp32Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DepthToSpaceFp32Test(backends, 2); } TEST_CASE ("DepthToSpaceUint8Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; DepthToSpaceUint8Test(backends, 2); } } // TEST_SUITE("DepthToSpace_GpuAccTests") TEST_SUITE("SpaceToDepth_CpuRefTests") { TEST_CASE ("SpaceToDepthFp32Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SpaceToDepthFp32Test(backends, 2); } TEST_CASE ("SpaceToDepthUint8Test_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SpaceToDepthUint8Test(backends, 2); } } // TEST_SUITE("SpaceToDepth_CpuRefTests") TEST_SUITE("SpaceToDepth_CpuAccTests") { TEST_CASE ("SpaceToDepthFp32Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SpaceToDepthFp32Test(backends, 2); } TEST_CASE ("SpaceToDepthUint8Test_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SpaceToDepthUint8Test(backends, 2); } } // TEST_SUITE("SpaceToDepth_CpuAccTests") TEST_SUITE("SpaceToDepth_GpuAccTests") { TEST_CASE ("SpaceToDepthFp32Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SpaceToDepthFp32Test(backends, 2); } TEST_CASE ("SpaceToDepthUint8Test_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SpaceToDepthUint8Test(backends, 2); } } // TEST_SUITE("SpaceToDepth_GpuAccTests") } // namespace armnnDelegate armnn-23.08/delegate/test/SpaceDepthTestHelper.hpp000066400000000000000000000172651446772241200221470ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateSpaceDepthTfLiteModel(tflite::BuiltinOperator spaceDepthOperatorCode, tflite::TensorType tensorType, const std::vector & inputTensorShape, const std::vector & outputTensorShape, int32_t blockSize) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ 1.0f }), flatBufferBuilder.CreateVector({ 0 })); std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 2> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 2, flatBufferBuilder.CreateString("output"), quantizationParameters); const std::vector operatorInputs({0}); const std::vector operatorOutputs({1}); flatbuffers::Offset spaceDepthOperator; flatbuffers::Offset modelDescription; flatbuffers::Offset operatorCode; switch (spaceDepthOperatorCode) { case tflite::BuiltinOperator_SPACE_TO_DEPTH: spaceDepthOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_SpaceToDepthOptions, CreateSpaceToDepthOptions(flatBufferBuilder, blockSize).Union()); modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: SPACE_TO_DEPTH Operator Model"); operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_SPACE_TO_DEPTH); break; case tflite::BuiltinOperator_DEPTH_TO_SPACE: spaceDepthOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_DepthToSpaceOptions, CreateDepthToSpaceOptions(flatBufferBuilder, blockSize).Union()); flatBufferBuilder.CreateString("ArmnnDelegate: DEPTH_TO_SPACE Operator Model"); operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_DEPTH_TO_SPACE); break; default: break; } const std::vector subgraphInputs({0}); const std::vector subgraphOutputs({1}); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&spaceDepthOperator, 1)); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void SpaceDepthTest(tflite::BuiltinOperator spaceDepthOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& outputShape, std::vector& inputValues, std::vector& expectedOutputValues, int32_t blockSize = 2) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateSpaceDepthTfLiteModel(spaceDepthOperatorCode, tensorType, inputShape, outputShape, blockSize); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespace armnn-23.08/delegate/test/SplitTest.cpp000066400000000000000000000202361446772241200200450ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "SplitTestHelper.hpp" #include #include #include #include namespace armnnDelegate { // SPLIT Operator void SplitUint8Test(std::vector& backends) { std::vector axisShape { 1 }; std::vector inputShape { 2, 2, 2, 2} ; std::vector outputShape0 { 2, 2, 2, 1 }; std::vector outputShape1 { 2, 2, 2, 1 }; std::vector> outputShapes{ outputShape0, outputShape1 }; std::vector axisData { 3 }; // Axis std::vector inputValues { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // Input std::vector expectedOutputValues0 { 1, 3, 5, 7, 9, 11, 13, 15 }; std::vector expectedOutputValues1 { 2, 4, 6, 8, 10, 12, 14, 16 }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1 }; int32_t numSplits = 2; SplitTest(::tflite::TensorType_UINT8, backends, axisShape, inputShape, outputShapes, axisData, inputValues, expectedOutputValues, numSplits); } void SplitFp32Test(std::vector& backends) { std::vector axisShape { 1 }; std::vector inputShape { 2, 2, 2, 2 }; std::vector outputShape0 { 2, 1, 2, 2 }; std::vector outputShape1 { 2, 1, 2, 2 }; std::vector> outputShapes{ outputShape0, outputShape1 }; std::vector axisData { 1 }; // Axis std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f }; // Input std::vector expectedOutputValues0 { 1.0f, 2.0f, 3.0f, 4.0f, 9.0f, 10.0f, 11.0f, 12.0f }; std::vector expectedOutputValues1 { 5.0f, 6.0f, 7.0f, 8.0f, 13.0f, 14.0f, 15.0f, 16.0f }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1 }; int32_t numSplits = 2; SplitTest(::tflite::TensorType_FLOAT32, backends, axisShape, inputShape, outputShapes, axisData, inputValues, expectedOutputValues, numSplits); } // SPLIT Test Suite TEST_SUITE("SPLIT_CpuRefTests") { TEST_CASE ("SPLIT_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SplitUint8Test(backends); } TEST_CASE ("SPLIT_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SplitFp32Test(backends); } } TEST_SUITE("SPLIT_CpuAccTests") { TEST_CASE ("SPLIT_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SplitUint8Test(backends); } TEST_CASE ("SPLIT_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SplitFp32Test(backends); } } TEST_SUITE("SPLIT_GpuAccTests") { TEST_CASE ("SPLIT_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SplitUint8Test(backends); } TEST_CASE ("SPLIT_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SplitFp32Test(backends); } } // End of SPLIT Test Suite // SPLIT_V Operator void SplitVUint8Test(std::vector& backends) { std::vector axisShape { 1 }; std::vector inputShape { 2, 4, 2, 2 }; std::vector splitsShape { 2 }; std::vector outputShape0 { 2, 3, 2, 2 }; std::vector outputShape1 { 2, 1, 2, 2 }; std::vector> outputShapes{ outputShape0, outputShape1 }; std::vector axisData { 1 }; // Axis std::vector splitsData { 3, 1 }; // Splits std::vector inputValues { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; // Input std::vector expectedOutputValues0 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 }; std::vector expectedOutputValues1 { 13, 14, 15, 16, 29, 30, 31, 32 }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1 }; int32_t numSplits = 2; SplitVTest(::tflite::TensorType_UINT8, backends, inputShape, splitsShape, axisShape, outputShapes, inputValues, splitsData, axisData, expectedOutputValues, numSplits); } void SplitVFp32Test(std::vector& backends) { std::vector axisShape { 1 }; std::vector inputShape { 2, 4, 2, 2 }; std::vector splitsShape { 2 }; std::vector outputShape0 { 2, 3, 2, 2 }; std::vector outputShape1 { 2, 1, 2, 2 }; std::vector> outputShapes{ outputShape0, outputShape1 }; std::vector axisData { 1 }; // Axis std::vector splitsData { 3, 1 }; // Splits std::vector inputValues { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, 30.0f, 31.0f, 32.0f }; // Input std::vector expectedOutputValues0 { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, 24.0f, 25.0f, 26.0f, 27.0f, 28.0f }; std::vector expectedOutputValues1 { 13.0f, 14.0f, 15.0f, 16.0f, 29.0f, 30.0f, 31.0f, 32.0f }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1 }; int32_t numSplits = 2; SplitVTest(::tflite::TensorType_FLOAT32, backends, inputShape, splitsShape, axisShape, outputShapes, inputValues, splitsData, axisData, expectedOutputValues, numSplits); } // SPLIT_V Test Suite TEST_SUITE("SPLIT_V_CpuRefTests") { TEST_CASE ("SPLIT_V_Uint8_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SplitVUint8Test(backends); } TEST_CASE ("SPLIT_V_Fp32_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; SplitVFp32Test(backends); } } TEST_SUITE("SPLIT_V_CpuAccTests") { TEST_CASE ("SPLIT_V_Uint8_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SplitVUint8Test(backends); } TEST_CASE ("SPLIT_V_Fp32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; SplitVFp32Test(backends); } } TEST_SUITE("SPLIT_V_GpuAccTests") { TEST_CASE ("SPLIT_V_Uint8_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SplitVUint8Test(backends); } TEST_CASE ("SPLIT_V_Fp32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; SplitVFp32Test(backends); } } // End of SPLIT_V Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/SplitTestHelper.hpp000066400000000000000000000424701446772241200212160ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateSplitTfLiteModel(tflite::TensorType tensorType, std::vector& axisTensorShape, std::vector& inputTensorShape, const std::vector>& outputTensorShapes, std::vector& axisData, const int32_t numSplits, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(axisData.data()), sizeof(int32_t) * axisData.size()))); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(axisTensorShape.data(), axisTensorShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("axis"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); // Create output tensor for (unsigned int i = 0; i < outputTensorShapes.size(); ++i) { buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors[i + 2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShapes[i].data(), outputTensorShapes[i].size()), tensorType, (i+3), flatBufferBuilder.CreateString("output"), quantizationParameters); } // create operator. Mean uses ReducerOptions. tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_SplitOptions; flatbuffers::Offset operatorBuiltinOptions = CreateSplitOptions(flatBufferBuilder, numSplits).Union(); const std::vector operatorInputs{ {0, 1} }; const std::vector operatorOutputs{ {2, 3} }; flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1} }; const std::vector subgraphOutputs{ {2, 3} }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: SPLIT Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_SPLIT); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void SplitTest(tflite::TensorType tensorType, std::vector& backends, std::vector& axisTensorShape, std::vector& inputTensorShape, std::vector>& outputTensorShapes, std::vector& axisData, std::vector& inputValues, std::vector>& expectedOutputValues, const int32_t numSplits, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateSplitTfLiteModel(tensorType, axisTensorShape, inputTensorShape, outputTensorShapes, axisData, numSplits, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); // Compare output data for (unsigned int i = 0; i < expectedOutputValues.size(); ++i) { std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(i); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(i); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(i); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(i); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues[i]); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShapes[i]); } tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // End of SPLIT Test std::vector CreateSplitVTfLiteModel(tflite::TensorType tensorType, std::vector& inputTensorShape, std::vector& splitsTensorShape, std::vector& axisTensorShape, const std::vector>& outputTensorShapes, std::vector& splitsData, std::vector& axisData, const int32_t numSplits, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::array, 3> buffers; buffers[0] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector({})); buffers[1] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(splitsData.data()), sizeof(int32_t) * splitsData.size())); buffers[2] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(axisData.data()), sizeof(int32_t) * axisData.size())); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); std::array, 5> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 0, flatBufferBuilder.CreateString("input"), quantizationParameters); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(splitsTensorShape.data(), splitsTensorShape.size()), ::tflite::TensorType_INT32, 1, flatBufferBuilder.CreateString("splits"), quantizationParameters); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(axisTensorShape.data(), axisTensorShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("axis"), quantizationParameters); // Create output tensor for (unsigned int i = 0; i < outputTensorShapes.size(); ++i) { tensors[i + 3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShapes[i].data(), outputTensorShapes[i].size()), tensorType, 0, flatBufferBuilder.CreateString("output"), quantizationParameters); } // create operator. Mean uses ReducerOptions. tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_SplitVOptions; flatbuffers::Offset operatorBuiltinOptions = CreateSplitVOptions(flatBufferBuilder, numSplits).Union(); const std::vector operatorInputs{ {0, 1, 2} }; const std::vector operatorOutputs{ {3, 4} }; flatbuffers::Offset controlOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ {0, 1, 2} }; const std::vector subgraphOutputs{ {3, 4} }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&controlOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: SPLIT_V Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_SPLIT_V); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void SplitVTest(tflite::TensorType tensorType, std::vector& backends, std::vector& inputTensorShape, std::vector& splitsTensorShape, std::vector& axisTensorShape, std::vector>& outputTensorShapes, std::vector& inputValues, std::vector& splitsData, std::vector& axisData, std::vector>& expectedOutputValues, const int32_t numSplits, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateSplitVTfLiteModel(tensorType, inputTensorShape, splitsTensorShape, axisTensorShape, outputTensorShapes, splitsData, axisData, numSplits, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); // Compare output data for (unsigned int i = 0; i < expectedOutputValues.size(); ++i) { std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(i); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(i); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(i); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(i); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues[i]); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShapes[i]); } tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // End of SPLIT_V Test } // anonymous namespacearmnn-23.08/delegate/test/SqueezeTest.cpp000066400000000000000000000052651446772241200204000ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "RedefineTestHelper.hpp" namespace armnnDelegate { void SqueezeSimpleTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector outputShape { 2, 2 }; std::vector squeezeDims { }; std::vector inputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 1, 2, 3, 4 }; RedefineTest(tflite::BuiltinOperator_SQUEEZE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, squeezeDims); } void SqueezeWithDimsTest(std::vector& backends) { // Set input data std::vector inputShape { 1, 2, 2, 1 }; std::vector outputShape { 1, 2, 2 }; std::vector squeezeDims { -1 }; std::vector inputValues = { 1, 2, 3, 4 }; std::vector expectedOutputValues = { 1, 2, 3, 4 }; RedefineTest(tflite::BuiltinOperator_SQUEEZE, ::tflite::TensorType_FLOAT32, backends, inputShape, outputShape, inputValues, expectedOutputValues, squeezeDims); } TEST_SUITE("Squeeze_GpuAccTests") { TEST_CASE ("Squeeze_Simple_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SqueezeSimpleTest(backends); } TEST_CASE ("Squeeze_With_Dims_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; SqueezeWithDimsTest(backends); } } // TEST_SUITE("Squeeze_GpuAccTests") TEST_SUITE("Squeeze_CpuAccTests") { TEST_CASE ("Squeeze_Simple_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SqueezeSimpleTest(backends); } TEST_CASE ("Squeeze_With_Dims_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; SqueezeWithDimsTest(backends); } } // TEST_SUITE("Squeeze_CpuAccTests") TEST_SUITE("Squeeze_CpuRefTests") { TEST_CASE ("Squeeze_Simple_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SqueezeSimpleTest(backends); } TEST_CASE ("Squeeze_With_Dims_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; SqueezeWithDimsTest(backends); } } // TEST_SUITE("Squeeze_CpuRefTests") } // namespace armnnDelegatearmnn-23.08/delegate/test/StridedSliceTest.cpp000066400000000000000000000156761446772241200213440ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "StridedSliceTestHelper.hpp" #include #include #include namespace armnnDelegate { void StridedSlice4DTest(std::vector& backends) { std::vector inputShape { 3, 2, 3, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector beginShape { 4 }; std::vector endShape { 4 }; std::vector strideShape { 4 }; std::vector beginData { 1, 0, 0, 0 }; std::vector endData { 2, 2, 3, 1 }; std::vector strideData { 1, 1, 1, 1 }; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f }; StridedSliceTestImpl( backends, inputData, outputData, beginData, endData, strideData, inputShape, beginShape, endShape, strideShape, outputShape ); } void StridedSlice4DReverseTest(std::vector& backends) { std::vector inputShape { 3, 2, 3, 1 }; std::vector outputShape { 1, 2, 3, 1 }; std::vector beginShape { 4 }; std::vector endShape { 4 }; std::vector strideShape { 4 }; std::vector beginData { 1, -1, 0, 0 }; std::vector endData { 2, -3, 3, 1 }; std::vector strideData { 1, -1, 1, 1 }; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 4.0f, 4.0f, 4.0f, 3.0f, 3.0f, 3.0f }; StridedSliceTestImpl( backends, inputData, outputData, beginData, endData, strideData, inputShape, beginShape, endShape, strideShape, outputShape ); } void StridedSliceSimpleStrideTest(std::vector& backends) { std::vector inputShape { 3, 2, 3, 1 }; std::vector outputShape { 2, 1, 2, 1 }; std::vector beginShape { 4 }; std::vector endShape { 4 }; std::vector strideShape { 4 }; std::vector beginData { 0, 0, 0, 0 }; std::vector endData { 3, 2, 3, 1 }; std::vector strideData { 2, 2, 2, 1 }; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 1.0f, 1.0f, 5.0f, 5.0f }; StridedSliceTestImpl( backends, inputData, outputData, beginData, endData, strideData, inputShape, beginShape, endShape, strideShape, outputShape ); } void StridedSliceSimpleRangeMaskTest(std::vector& backends) { std::vector inputShape { 3, 2, 3, 1 }; std::vector outputShape { 3, 2, 3, 1 }; std::vector beginShape { 4 }; std::vector endShape { 4 }; std::vector strideShape { 4 }; std::vector beginData { 1, 1, 1, 1 }; std::vector endData { 1, 1, 1, 1 }; std::vector strideData { 1, 1, 1, 1 }; int beginMask = -1; int endMask = -1; std::vector inputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; std::vector outputData { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 3.0f, 3.0f, 3.0f, 4.0f, 4.0f, 4.0f, 5.0f, 5.0f, 5.0f, 6.0f, 6.0f, 6.0f }; StridedSliceTestImpl( backends, inputData, outputData, beginData, endData, strideData, inputShape, beginShape, endShape, strideShape, outputShape, beginMask, endMask ); } TEST_SUITE("StridedSlice_CpuRefTests") { TEST_CASE ("StridedSlice_4D_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; StridedSlice4DTest(backends); } TEST_CASE ("StridedSlice_4D_Reverse_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; StridedSlice4DReverseTest(backends); } TEST_CASE ("StridedSlice_SimpleStride_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; StridedSliceSimpleStrideTest(backends); } TEST_CASE ("StridedSlice_SimpleRange_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; StridedSliceSimpleRangeMaskTest(backends); } } // StridedSlice_CpuRefTests TestSuite TEST_SUITE("StridedSlice_CpuAccTests") { TEST_CASE ("StridedSlice_4D_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; StridedSlice4DTest(backends); } TEST_CASE ("StridedSlice_4D_Reverse_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; StridedSlice4DReverseTest(backends); } TEST_CASE ("StridedSlice_SimpleStride_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; StridedSliceSimpleStrideTest(backends); } TEST_CASE ("StridedSlice_SimpleRange_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; StridedSliceSimpleRangeMaskTest(backends); } } // StridedSlice_CpuAccTests TestSuite TEST_SUITE("StridedSlice_GpuAccTests") { TEST_CASE ("StridedSlice_4D_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; StridedSlice4DTest(backends); } TEST_CASE ("StridedSlice_4D_Reverse_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; StridedSlice4DReverseTest(backends); } TEST_CASE ("StridedSlice_SimpleStride_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; StridedSliceSimpleStrideTest(backends); } TEST_CASE ("StridedSlice_SimpleRange_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; StridedSliceSimpleRangeMaskTest(backends); } } // StridedSlice_GpuAccTests TestSuite } // namespace armnnDelegatearmnn-23.08/delegate/test/StridedSliceTestHelper.hpp000066400000000000000000000245671446772241200225100ustar00rootroot00000000000000// // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateStridedSliceTfLiteModel(tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& beginTensorData, const std::vector& endTensorData, const std::vector& strideTensorData, const std::vector& beginTensorShape, const std::vector& endTensorShape, const std::vector& strideTensorShape, const std::vector& outputTensorShape, const int32_t beginMask, const int32_t endMask, const int32_t ellipsisMask, const int32_t newAxisMask, const int32_t ShrinkAxisMask, const armnn::DataLayout& dataLayout) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; flatbuffers::Offset buffers[6] = { CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(beginTensorData.data()), sizeof(int32_t) * beginTensorData.size())), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(endTensorData.data()), sizeof(int32_t) * endTensorData.size())), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(strideTensorData.data()), sizeof(int32_t) * strideTensorData.size())), CreateBuffer(flatBufferBuilder) }; std::array, 5> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input")); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(beginTensorShape.data(), beginTensorShape.size()), ::tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("begin_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(endTensorShape.data(), endTensorShape.size()), ::tflite::TensorType_INT32, 3, flatBufferBuilder.CreateString("end_tensor")); tensors[3] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(strideTensorShape.data(), strideTensorShape.size()), ::tflite::TensorType_INT32, 4, flatBufferBuilder.CreateString("stride_tensor")); tensors[4] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, 5, flatBufferBuilder.CreateString("output")); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_StridedSliceOptions; flatbuffers::Offset operatorBuiltinOptions = CreateStridedSliceOptions(flatBufferBuilder, beginMask, endMask, ellipsisMask, newAxisMask, ShrinkAxisMask).Union(); const std::vector operatorInputs{ 0, 1, 2, 3 }; const std::vector operatorOutputs{ 4 }; flatbuffers::Offset sliceOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); const std::vector subgraphInputs{ 0, 1, 2, 3 }; const std::vector subgraphOutputs{ 4 }; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&sliceOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: StridedSlice Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, BuiltinOperator_STRIDED_SLICE); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers, 6)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void StridedSliceTestImpl(std::vector& backends, std::vector& inputValues, std::vector& expectedOutputValues, std::vector& beginTensorData, std::vector& endTensorData, std::vector& strideTensorData, std::vector& inputTensorShape, std::vector& beginTensorShape, std::vector& endTensorShape, std::vector& strideTensorShape, std::vector& outputTensorShape, const int32_t beginMask = 0, const int32_t endMask = 0, const int32_t ellipsisMask = 0, const int32_t newAxisMask = 0, const int32_t ShrinkAxisMask = 0, const armnn::DataLayout& dataLayout = armnn::DataLayout::NHWC) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateStridedSliceTfLiteModel( ::tflite::TensorType_FLOAT32, inputTensorShape, beginTensorData, endTensorData, strideTensorData, beginTensorShape, endTensorShape, strideTensorShape, outputTensorShape, beginMask, endMask, ellipsisMask, newAxisMask, ShrinkAxisMask, dataLayout); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputTensorShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } // End of StridedSlice Test } // anonymous namespacearmnn-23.08/delegate/test/TestUtils.cpp000066400000000000000000000075201446772241200200530ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "TestUtils.hpp" namespace armnnDelegate { void CompareData(bool tensor1[], bool tensor2[], size_t tensorSize) { auto compareBool = [](auto a, auto b) {return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));}; for (size_t i = 0; i < tensorSize; i++) { CHECK(compareBool(tensor1[i], tensor2[i])); } } void CompareData(std::vector& tensor1, std::vector& tensor2, size_t tensorSize) { auto compareBool = [](auto a, auto b) {return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));}; for (size_t i = 0; i < tensorSize; i++) { CHECK(compareBool(tensor1[i], tensor2[i])); } } void CompareData(float tensor1[], float tensor2[], size_t tensorSize) { for (size_t i = 0; i < tensorSize; i++) { CHECK(tensor1[i] == doctest::Approx( tensor2[i] )); } } void CompareData(float tensor1[], float tensor2[], size_t tensorSize, float percentTolerance) { for (size_t i = 0; i < tensorSize; i++) { CHECK(std::max(tensor1[i], tensor2[i]) - std::min(tensor1[i], tensor2[i]) <= std::abs(tensor1[i]*percentTolerance/100)); } } void CompareData(uint8_t tensor1[], uint8_t tensor2[], size_t tensorSize) { uint8_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { CHECK(std::max(tensor1[i], tensor2[i]) - std::min(tensor1[i], tensor2[i]) <= tolerance); } } void CompareData(int16_t tensor1[], int16_t tensor2[], size_t tensorSize) { int16_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { CHECK(std::max(tensor1[i], tensor2[i]) - std::min(tensor1[i], tensor2[i]) <= tolerance); } } void CompareData(int32_t tensor1[], int32_t tensor2[], size_t tensorSize) { int32_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { CHECK(std::max(tensor1[i], tensor2[i]) - std::min(tensor1[i], tensor2[i]) <= tolerance); } } void CompareData(int8_t tensor1[], int8_t tensor2[], size_t tensorSize) { int8_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { CHECK(std::max(tensor1[i], tensor2[i]) - std::min(tensor1[i], tensor2[i]) <= tolerance); } } void CompareData(Half tensor1[], Half tensor2[], size_t tensorSize) { for (size_t i = 0; i < tensorSize; i++) { CHECK(tensor1[i] == doctest::Approx( tensor2[i] )); } } void CompareData(TfLiteFloat16 tensor1[], TfLiteFloat16 tensor2[], size_t tensorSize) { uint16_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { uint16_t tensor1Data = tensor1[i].data; uint16_t tensor2Data = tensor2[i].data; CHECK(std::max(tensor1Data, tensor2Data) - std::min(tensor1Data, tensor2Data) <= tolerance); } } void CompareData(TfLiteFloat16 tensor1[], Half tensor2[], size_t tensorSize) { uint16_t tolerance = 1; for (size_t i = 0; i < tensorSize; i++) { uint16_t tensor1Data = tensor1[i].data; uint16_t tensor2Data = half_float::detail::float2half(tensor2[i]); CHECK(std::max(tensor1Data, tensor2Data) - std::min(tensor1Data, tensor2Data) <= tolerance); } } void CompareOutputShape(const std::vector& tfLiteDelegateShape, const std::vector& armnnDelegateShape, const std::vector& expectedOutputShape) { CHECK(expectedOutputShape.size() == tfLiteDelegateShape.size()); CHECK(expectedOutputShape.size() == armnnDelegateShape.size()); for (size_t i = 0; i < expectedOutputShape.size(); i++) { CHECK(expectedOutputShape[i] == armnnDelegateShape[i]); CHECK(tfLiteDelegateShape[i] == expectedOutputShape[i]); CHECK(tfLiteDelegateShape[i] == armnnDelegateShape[i]); } } } // namespace armnnDelegatearmnn-23.08/delegate/test/TestUtils.hpp000066400000000000000000000065321446772241200200620ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include #include #include #include using Half = half_float::half; namespace armnnDelegate { constexpr const char* FILE_IDENTIFIER = "TFL3"; /// Can be used to compare bool data coming from a tflite interpreter /// Boolean types get converted to a bit representation in a vector. vector.data() returns a void pointer /// instead of a pointer to bool. Therefore a special function to compare to vector of bool is required void CompareData(std::vector& tensor1, std::vector& tensor2, size_t tensorSize); void CompareData(bool tensor1[], bool tensor2[], size_t tensorSize); /// Can be used to compare float data coming from a tflite interpreter with a tolerance of limit_of_float*100 void CompareData(float tensor1[], float tensor2[], size_t tensorSize); /// Can be used to compare float data coming from a tflite interpreter with a given percentage tolerance void CompareData(float tensor1[], float tensor2[], size_t tensorSize, float percentTolerance); /// Can be used to compare int8_t data coming from a tflite interpreter with a tolerance of 1 void CompareData(int8_t tensor1[], int8_t tensor2[], size_t tensorSize); /// Can be used to compare uint8_t data coming from a tflite interpreter with a tolerance of 1 void CompareData(uint8_t tensor1[], uint8_t tensor2[], size_t tensorSize); /// Can be used to compare int16_t data coming from a tflite interpreter with a tolerance of 1 void CompareData(int16_t tensor1[], int16_t tensor2[], size_t tensorSize); /// Can be used to compare int32_t data coming from a tflite interpreter with a tolerance of 1 void CompareData(int32_t tensor1[], int32_t tensor2[], size_t tensorSize); /// Can be used to compare Half (Float16) data with a tolerance of limit_of_float*100 void CompareData(Half tensor1[], Half tensor2[], size_t tensorSize); /// Can be used to compare TfLiteFloat16 data coming from a tflite interpreter void CompareData(TfLiteFloat16 tensor1[], TfLiteFloat16 tensor2[], size_t tensorSize); /// Can be used to compare Half (Float16) data and TfLiteFloat16 data coming from a tflite interpreter void CompareData(TfLiteFloat16 tensor1[], Half tensor2[], size_t tensorSize); /// Can be used to compare the output tensor shape /// Example usage can be found in ControlTestHelper.hpp void CompareOutputShape(const std::vector& tfLiteDelegateShape, const std::vector& armnnDelegateShape, const std::vector& expectedOutputShape); /// Can be used to compare the output tensor values /// Example usage can be found in ControlTestHelper.hpp template void CompareOutputData(std::vector& tfLiteDelegateOutputs, std::vector& armnnDelegateOutputs, std::vector& expectedOutputValues) { armnnDelegate::CompareData(expectedOutputValues.data(), armnnDelegateOutputs.data(), expectedOutputValues.size()); armnnDelegate::CompareData(tfLiteDelegateOutputs.data(), expectedOutputValues.data(), expectedOutputValues.size()); armnnDelegate::CompareData(tfLiteDelegateOutputs.data(), armnnDelegateOutputs.data(), expectedOutputValues.size()); } } // namespace armnnDelegate armnn-23.08/delegate/test/TileTest.cpp000066400000000000000000000042741446772241200176530ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "TileTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void TileFloat32Test(std::vector& backends) { // Set input data std::vector inputValues = { 0.f, 1.f, 2.f, 3.f, 4.f, 5.f }; // Set output data std::vector expectedOutputValues = { 0.f, 1.f, 2.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 3.f, 4.f, 5.f, 0.f, 1.f, 2.f, 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 3.f, 4.f, 5.f }; // The multiples const std::vector multiplesValues = { 2, 2 }; // Set shapes const std::vector inputShape = { 2, 3 }; const std::vector multiplesShape = { 2 }; const std::vector expectedOutputShape = { 4, 6 }; TileFP32TestImpl(tflite::BuiltinOperator_TILE, backends, inputValues, inputShape, multiplesValues, multiplesShape, expectedOutputValues, expectedOutputShape); } TEST_SUITE("TileTests_GpuAccTests") { TEST_CASE ("Tile_Float32_GpuAcc_Test") { std::vector backends = { armnn::Compute::GpuAcc }; TileFloat32Test(backends); } } // TEST_SUITE("Tile_Float32_GpuAcc_Test") TEST_SUITE("TileTests_CpuAccTests") { TEST_CASE ("Tile_Float32_CpuAcc_Test") { std::vector backends = { armnn::Compute::CpuAcc }; TileFloat32Test(backends); } } // TEST_SUITE("Tile_Float32_CpuAcc_Test") TEST_SUITE("TileTests_CpuRefTests") { TEST_CASE ("Tile_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; TileFloat32Test(backends); } } // TEST_SUITE("Tile_Float32_CpuRef_Test") } // namespace armnnDelegatearmnn-23.08/delegate/test/TileTestHelper.hpp000066400000000000000000000165151446772241200210210ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateTileTfLiteModel(tflite::BuiltinOperator operatorCode, tflite::TensorType inputTensorType, const std::vector& inputTensorShape, const std::vector& multiplesTensorData, const std::vector& multiplesTensorShape, const std::vector& outputTensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(multiplesTensorData.data()), sizeof(int32_t) * multiplesTensorData.size()))); buffers.push_back(CreateBuffer(flatBufferBuilder)); std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), inputTensorType, 1, flatBufferBuilder.CreateString("input_tensor")); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(multiplesTensorShape.data(), multiplesTensorShape.size()), TensorType_INT32, 2, flatBufferBuilder.CreateString("axis_input_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), inputTensorType, 3, flatBufferBuilder.CreateString("output_tensor")); // Create Operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_NONE; flatbuffers::Offset operatorBuiltinOption = 0; const std::vector operatorInputs {0, 1}; const std::vector operatorOutputs {2}; flatbuffers::Offset tileOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOption); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&tileOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Tile Operator Model"); flatbuffers::Offset opCode = CreateOperatorCode(flatBufferBuilder, operatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&opCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } void TileFP32TestImpl(tflite::BuiltinOperator operatorCode, std::vector& backends, std::vector& inputValues, std::vector inputShape, std::vector multiplesValues, std::vector multiplesShapes, std::vector& expectedOutputValues, std::vector expectedOutputShape) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateTileTfLiteModel(operatorCode, ::tflite::TensorType::TensorType_FLOAT32, inputShape, multiplesValues, multiplesShapes, expectedOutputShape); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(multiplesValues, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(multiplesValues, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/TransposeConvolution2dTest.cpp000066400000000000000000000101601446772241200234110ustar00rootroot00000000000000// // Copyright © 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "ConvolutionTestHelper.hpp" #include #include #include #include #include #include #include #include namespace armnnDelegate { void TransposeConvInt8Test(std::vector& backends) { // Set input data std::vector transposeTensorShape { 4 }; std::vector filterShape { 1, 2, 2, 1 }; std::vector inputShape { 1, 2, 2, 1 }; std::vector outputShape { 1, 3, 3, 1 }; std::vector transposeData = { 1, 3, 3, 1 }; static std::vector inputValues = { 1, 2, 3, 4 }; std::vector filterValues = { 0, 1, 2, 4 }; std::vector expectedOutputValues = { 0, 1, 2, 2, 11, 12, 6, 20, 16 }; tflite::Padding padding = tflite::Padding_VALID; TransposeConvTest(backends, ::tflite::TensorType_INT8, 1, // strideX 1, // strideY padding, transposeTensorShape, filterShape, inputShape, outputShape, transposeData, filterValues, inputValues, expectedOutputValues); } void TransposeConvFp32Test(std::vector& backends) { std::vector transposeTensorShape { 4 }; std::vector filterShape { 1, 2, 2, 1 }; std::vector inputShape { 1, 2, 2, 1 }; std::vector outputShape { 1, 3, 3, 1 }; std::vector transposeData = { 1, 3, 3, 1 }; static std::vector inputValues = { 1, 2, 3, 4 }; std::vector filterValues = { 0, 1, 2, 4 }; std::vector expectedOutputValues = { 0, 1, 2, 2, 11, 12, 6, 20, 16 }; tflite::Padding padding = tflite::Padding_VALID; TransposeConvTest(backends, ::tflite::TensorType_FLOAT32, 1, // strideX 1, // strideY padding, transposeTensorShape, filterShape, inputShape, outputShape, transposeData, filterValues, inputValues, expectedOutputValues); } TEST_SUITE("TransposeConv_CpuRef_Test") { TEST_CASE ("TransposeConv_CpuRef_Fp32_Test") { std::vector backends = {armnn::Compute::CpuRef}; TransposeConvFp32Test(backends); } TEST_CASE ("TransposeConv_CpuRef_Int8_Test") { std::vector backends = {armnn::Compute::CpuRef}; TransposeConvInt8Test(backends); } } // End of TEST_SUITE(TransposeConv_CpuRef_Test) TEST_SUITE("TransposeConv_CpuAcc_Test") { TEST_CASE ("TransposeConv_CpuAcc_Fp32_Test") { std::vector backends = {armnn::Compute::CpuAcc}; TransposeConvFp32Test(backends); } TEST_CASE ("TransposeConv_CpuAcc_Int8_Test") { std::vector backends = {armnn::Compute::CpuAcc}; TransposeConvInt8Test(backends); } } // End of TEST_SUITE(TransposeConv_CpuAcc_Test) TEST_SUITE("TransposeConv_GpuAcc_Test") { TEST_CASE ("TransposeConv_GpuAcc_Fp32_Test") { std::vector backends = {armnn::Compute::GpuAcc}; TransposeConvFp32Test(backends); } TEST_CASE ("TransposeConv_GpuAcc_Int8_Test") { std::vector backends = {armnn::Compute::GpuAcc}; TransposeConvInt8Test(backends); } } // End of TEST_SUITE(TransposeConv_GpuAcc_Test) } // namespace armnnDelegatearmnn-23.08/delegate/test/TransposeTest.cpp000066400000000000000000000034371446772241200207340ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "TransposeTestHelper.hpp" #include #include #include namespace armnnDelegate { void TransposeFP32Test(std::vector& backends) { // set test input data std::vector input0Shape {4, 2, 3}; std::vector inputPermVecShape {3}; std::vector outputShape {3, 4, 2}; std::vector input0Values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; std::vector inputPermVec = {2, 0, 1}; std::vector expectedOutputValues = {0, 3, 6, 9, 12, 15, 18, 21, 1, 4, 7, 10, 13, 16, 19, 22, 2, 5, 8, 11, 14, 17, 20, 23}; TransposeTest(backends, input0Shape, inputPermVecShape, outputShape, input0Values, inputPermVec, expectedOutputValues); } TEST_SUITE ("Transpose_GpuAccTests") { TEST_CASE ("Transpose_Float32_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; TransposeFP32Test(backends); } } TEST_SUITE ("Transpose_CpuAccTests") { TEST_CASE ("Transpose_Float32_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; TransposeFP32Test(backends); } } TEST_SUITE ("Transpose_CpuRefTests") { TEST_CASE ("Transpose_Float32_CpuRef_Test") { std::vector backends = { armnn::Compute::CpuRef }; TransposeFP32Test(backends); } } } // namespace armnnDelegate armnn-23.08/delegate/test/TransposeTestHelper.hpp000066400000000000000000000153321446772241200220760ustar00rootroot00000000000000// // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateTransposeTfLiteModel(tflite::TensorType tensorType, const std::vector & input0TensorShape, const std::vector & inputPermVecShape, const std::vector & outputTensorShape, const std::vector& inputPermVec) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; flatbuffers::Offset buffers[4]{ CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder), CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputPermVec.data()), sizeof(int32_t) * inputPermVec.size())), CreateBuffer(flatBufferBuilder) }; std::array, 3> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(input0TensorShape.data(), input0TensorShape.size()), tensorType, 1); tensors[1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputPermVecShape.data(), inputPermVecShape.size()), tflite::TensorType_INT32, 2, flatBufferBuilder.CreateString("permutation_vector")); tensors[2] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType,3); const std::vector operatorInputs{0, 1}; const std::vector operatorOutputs{2}; flatbuffers::Offset transposeOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), BuiltinOptions_TransposeOptions, CreateTransposeOptions(flatBufferBuilder).Union()); const std::vector subgraphInputs{0, 1}; const std::vector subgraphOutputs{2}; flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&transposeOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Transpose Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_TRANSPOSE); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers, 4)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void TransposeTest(std::vector& backends, std::vector& inputShape, std::vector& inputPermVecShape, std::vector& outputShape, std::vector& inputValues, std::vector& inputPermVec, std::vector& expectedOutputValues) { using namespace delegateTestInterpreter; // Create model std::vector modelBuffer = CreateTransposeTfLiteModel(::tflite::TensorType_FLOAT32, inputShape, inputPermVecShape, outputShape, inputPermVec); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputPermVec, 1) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputPermVec, 1) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } armnn-23.08/delegate/test/UnidirectionalSequenceLstmTest.cpp000066400000000000000000002503531446772241200242610ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "UnidirectionalSequenceLstmTestHelper.hpp" #include #include #include #include namespace armnnDelegate { void UnidirectionalSequenceLstmTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; //tensorInfo12, bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -0.49536117f, -0.0556083915f, -0.102400711f, -0.117484632f, 0.3298470976f, -0.1179017122f, 0.214305695f, 0.42135173085f, 0.003878414626f, -0.348303917f, -0.1881275477f, 0.0343011027f }; std::vector inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f, -0.3810434485f, 0.268383264f, -0.009807467424f, -0.3522925403f, -0.24275735512f, -0.28344226125f, 0.13512269116f, -0.4932442977f, -0.10039821991f }; std::vector inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f, 0.386399507f, -0.259465157985f, -0.16545993089f, -0.4230232555f, 0.341664791103f, -0.18127849691f, -0.2277662414f, -0.55275535589f, 0.34184026718f }; std::vector inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f, 0.53969591851f, 0.23393625035f, -0.27140527306f, 0.50009280443f, 0.07511717046f, 0.3998299249f, -0.51717478049f, 0.1889653282f, -0.367323637f }; //tensorInfo16, bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -0.128009796112f, 0.1995525098f, -0.07745539397f, 0.1558421701f, -0.265254765766f, -0.38837709614f, -0.05636804124f, 0.4259087456f, 0.17628988623f, 0.3877420127f, 0.53300309181f, -0.0959980934f, 0.00302857416f, 0.3266998827f, -0.142509296562f, -0.04433270756f }; std::vector recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f, -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f, -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f, -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f }; std::vector recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f, -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f, 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f, 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f }; std::vector recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f, -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f, 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f, -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = false; std::vector cellToForgetWeights; bool hasCellToOutputWeights = false; std::vector cellToOutputWeights; bool hasInputGateBias = true; std::vector inputGateBias = {0., 0., 0., 0.}; std::vector forgetGateBias = {1., 1., 1., 1.}; std::vector cellBias = {0., 0., 0., 0.}; std::vector outputGateBias = {0., 0., 0., 0.}; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2. }; std::vector expectedOutputValues = { -0.0714901f, -0.162117f, -0.175168f, -0.0232934f, -0.168107f, -0.414129f, -0.549875f, -0.00803579f, -0.0668735f, 0.204078f, -0.42765f, -0.0312321f, -0.120003f, -0.0941918f, -0.456391f, -0.0287019f, -0.0342921f, 0.20824f, -0.656989f, -0.00415265f, -0.10493f, 0.14211f, -0.583478f, -0.0329754f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor); } void UnidirectionalSequenceLstmTimeMajorTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; std::vector inputShape = {timeSize, batchSize, inputSize}; std::vector cellStateInTensorInfo = {batchSize, numUnits}; std::vector outputStateInTensorInfo = {batchSize, outputSize}; std::vector outputTensorInfo = {timeSize, batchSize, outputSize}; //tensorInfo12 bool hasInputToInputWeights = true; std::vector inputToInputWeights = { 0.27277296781539917f, 0.3813590407371521f, -0.394489049911499f, 0.2782636880874634f, -0.3793870210647583f, -0.018918335437774658f, 0.2724653482437134f, -0.19314253330230713f, -0.2947450876235962f, -0.30253493785858154f, 0.4241350293159485f, -0.22560018301010132f }; std::vector inputToForgetWeights = { -0.2667974531650543f, -0.05505800247192383f, -0.20932340621948242f, -0.14345619082450867f, 0.09666192531585693f, -0.2604355812072754f, -0.2681812047958374f, -0.3314584493637085f, 0.4485899806022644f, -0.23467743396759033f, 0.5072842240333557f, -0.4192768931388855f }; std::vector inputToCellWeights = { -0.15782442688941956f, -0.027530014514923096f, 0.4789854884147644f, 0.23227906227111816f, 0.28259342908859253f, -0.030095696449279785f, 0.10071521997451782f, -0.08535495400428772f, 0.18563997745513916f, -0.3049069046974182f, -0.478048175573349f, 0.025234103202819824f }; std::vector inputToOutputWeights = { -0.04584759473800659f, -0.2716066539287567f, 0.012970447540283203f, -0.4729190170764923f, -0.37422770261764526f, 0.49352723360061646f, 0.3163864016532898f, -0.436781644821167f, -0.33074596524238586f, -0.32885751128196716f, -0.40959352254867554f, -0.2124689817428589f }; //tensorInfo16 bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { 0.23788475990f, -0.24948765337f, 0.50044941902f, 0.14431896805f, -0.115940228137f, -0.717082679f, -0.17208620906f, 0.17850610617f, -0.16702319684f, -0.11384502053f, -0.309785276245f, -0.3316611672f, 0.52380162477f, -0.06839632987f, -0.391478359627f, -0.10756178963f }; std::vector recurrentToForgetWeights = { 0.11383482068f, 0.1676601767f, -0.08550968004f, 0.03399394089f, 0.08042152225f, -0.2133381964f, 0.05182432704f, 0.38161808255f, -0.5018365979f, -0.08043262364f, 0.07894329014f, -0.07547105155f, 0.12047368288f, 0.2986997961f, 0.0485043078f, -0.13372567296f }; std::vector recurrentToCellWeights = { 0.0433832928545f, 0.07587072294f, -0.120520234107f, 0.604576051f, -0.434353142986f, 0.009314475068f, 0.005085289478f, 0.08488202038f, -0.00025437487886f, 0.15245915082f, -0.1936587542f, 0.004754020f, -0.1582719236f, 0.3307867646f, 0.0236605107784f, 0.307716339826f }; std::vector recurrentToOutputWeights = { -0.079031050201f, 0.041414566286f, -0.583727357285f, 0.1025384515f, -0.172372072937f, 0.09214124082f, 0.178184121827f, -0.2439443916f, 0.104485116899f, 0.2600405514f, 0.064414866268f, 0.24141204357f, 0.281875759363f, -0.14234502664f, 0.15126448862f, -0.24421440064f }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = false; std::vector cellToForgetWeights; bool hasCellToOutputWeights = false; std::vector cellToOutputWeights; bool hasInputGateBias = true; std::vector inputGateBias = {0., 0., 0., 0.}; std::vector forgetGateBias = {1., 1., 1., 1.}; std::vector cellBias = {0., 0., 0., 0.}; std::vector outputGateBias = {0., 0., 0., 0.}; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2. }; std::vector expectedOutputValues = { 0.135658f, 0.124673f, 0.021209f, -0.0530204f, 0.106138f, 0.0404792f, 0.0151644f, -0.00675166f, -0.0128514f, 0.0644884f, 0.0709072f, -0.0454045f, 0.162886f, 0.166494f, 0.0277046f, -0.0369807f, 0.111716f, 0.043119f, 0.0762981f, -0.0122854f, 0.104397f, 0.2144f, 0.119192f, -0.0839058f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = true; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor); } void UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionTest(std::vector& backends) { int32_t batchSize = 2; int32_t timeSize = 3; int32_t inputSize = 4; int32_t outputSize = 5; int32_t numUnits = 6; std::vector inputShape = {batchSize, timeSize, inputSize}; std::vector cellStateInTensorInfo = {batchSize, numUnits}; std::vector outputStateInTensorInfo = {batchSize, outputSize}; std::vector outputTensorInfo = {batchSize, timeSize, outputSize}; //tensorInfoInputSize, bool hasInputToInputWeights = true; std::vector inputToInputWeights = { 0.021393683f, 0.06124551f, 0.046905167f, -0.014657677f, -0.03149463f, 0.09171803f, 0.14647801f, 0.10797193f, -0.0057968358f, 0.0019193048f, -0.2726754f, 0.10154029f, -0.018539885f, 0.080349885f, -0.10262385f, -0.022599787f, -0.09121155f, -0.008675967f, -0.045206103f, -0.0821282f, -0.008045952f, 0.015478081f, 0.055217247f, 0.038719587f }; std::vector inputToForgetWeights = { -0.0018401089f, -0.004852237f, 0.03698424f, 0.014181704f, 0.028273236f, -0.016726194f, -0.05249759f, -0.10204261f, 0.00861066f, -0.040979505f, -0.009899187f, 0.01923892f, -0.028177269f, -0.08535103f, -0.14585495f, 0.10662567f, -0.01909731f, -0.017883534f, -0.0047269356f, -0.045103323f, 0.0030784295f, 0.076784775f, 0.07463696f, 0.094531395f}; std::vector inputToCellWeights = { -0.04580283f, -0.09549462f, -0.032418985f, -0.06454633f, -0.043528453f, 0.043018587f, -0.049152344f, -0.12418144f, -0.078985475f, -0.07596889f, 0.019484362f, -0.11434962f, -0.0074034138f, -0.06314844f, -0.092981495f, 0.0062155537f, -0.025034338f, -0.0028890965f, 0.048929527f, 0.06235075f, 0.10665918f, -0.032036792f, -0.08505916f, -0.10843358f }; std::vector inputToOutputWeights = { -0.0998932f, -0.07201956f, -0.052803773f, -0.15629593f, -0.15001918f, -0.07650751f, 0.02359855f, -0.075155355f, -0.08037709f, -0.15093534f, 0.029517552f, -0.04751393f, 0.010350531f, -0.02664851f, -0.016839722f, -0.023121163f, 0.0077019283f, 0.012851257f, -0.05040649f, -0.0129761f, -0.021737747f, -0.038305793f, -0.06870586f, -0.01481247f }; //tensorInfoOutputSize, bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -0.001374326f, -0.078856036f, 0.10672688f, 0.029162422f, -0.11585556f, 0.02557986f, -0.13446963f, -0.035785314f, -0.01244275f, 0.025961924f, -0.02337298f, -0.044228926f, -0.055839065f, -0.046598054f, -0.010546039f, -0.06900766f, 0.027239809f, 0.022582639f, -0.013296484f, -0.05459212f, 0.08981f, -0.045407712f, 0.08682226f, -0.06867011f, -0.14390695f, -0.02916037f, 0.000996957f, 0.091420636f, 0.14283475f, -0.07390571f }; std::vector recurrentToForgetWeights = { -0.057784554f, -0.026057621f, -0.068447545f, -0.022581743f, 0.14811787f, 0.10826372f, 0.09471067f, 0.03987225f, -0.0039523416f, 0.00030638507f, 0.053185795f, 0.10572994f, 0.08414449f, -0.022036452f, -0.00066928595f, -0.09203576f, 0.032950465f, -0.10985798f, -0.023809856f, 0.0021431844f, -0.02196096f, -0.00326074f, 0.00058621005f, -0.074678116f, -0.06193199f, 0.055729095f, 0.03736828f, 0.020123724f, 0.061878487f, -0.04729229f }; std::vector recurrentToCellWeights = { -0.037322544f, 0.018592842f, 0.0056175636f, -0.06253426f, 0.055647098f, -0.05713207f, -0.05626563f, 0.005559383f, 0.03375411f, -0.025757805f, -0.088049285f, 0.06017052f, -0.06570978f, 0.007384076f, 0.035123326f, -0.07920549f, 0.053676967f, 0.044480428f, -0.07663568f, 0.0071805613f, 0.08089997f, 0.05143358f, 0.038261272f, 0.03339287f, -0.027673481f, 0.044746667f, 0.028349208f, 0.020090483f, -0.019443132f, -0.030755889f }; std::vector recurrentToOutputWeights = { 0.025825322f, -0.05813119f, 0.09495884f, -0.045984812f,-0.01255415f, -0.0026479573f, -0.08196161f, -0.054914974f, -0.0046604523f, -0.029587349f, -0.044576716f, -0.07480124f, -0.082868785f, 0.023254942f, 0.027502948f, -0.0039728214f, -0.08683098f, -0.08116779f, -0.014675607f, -0.037924774f, -0.023314456f, -0.007401714f, -0.09255757f, 0.029460307f, -0.08829125f, -0.005139627f, -0.08989442f, -0.0555066f, 0.13596267f, 0.025062224f }; // tensorInfoNumUnits bool hasCellToInputWeights = true; std::vector cellToInputWeights = { 0.040369894f, 0.030746894f, 0.24704495f, 0.018586371f, -0.037586458f, -0.15312155f }; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = { -0.01998659f, -0.15568835f, -0.24248174f, -0.012770197f, 0.041331276f, -0.072311886f }; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = { 0.08286371f, -0.08261836f, -0.51210177f, 0.002913762f, 0.17764764f, -0.5495371f }; bool hasInputGateBias = true; std::vector inputGateBias = { 0.02234832f, 0.14757581f, 0.18176508f, 0.10380666f, 0.053110216f, -0.06928846f }; std::vector forgetGateBias = { 0.035185695f, -0.042891346f, -0.03032477f, 0.23027696f, 0.11098921f, 0.08989442f }; std::vector cellBias = { -0.024379363f, 0.0055531194f, 0.23377132f, 0.033463873f, -0.1483596f, 0.029460307f }; std::vector outputGateBias = { 0.046159424f, -0.0012809046f, 0.03563469f, 0.12648113f, 0.027195795f, 0.35373217f }; bool hasProjectionWeights = true; std::vector projectionWeights = { -0.009802181f, 0.09401916f, 0.0717386f, -0.13895074f, 0.09641832f, 0.060420845f, 0.08539281f, 0.054285463f, 0.061395317f, 0.034448683f, -0.042991187f, 0.019801661f, -0.16840284f, -0.015726732f, -0.23041931f, -0.024478018f, -0.10959692f, -0.013875541f, 0.18600968f, -0.061274476f, 0.0138165f, -0.08160894f, -0.07661644f, 0.032372914f, 0.16169067f, 0.22465782f, -0.03993472f, -0.004017731f, 0.08633481f, -0.28869787f }; bool hasProjectionBias = true; std::vector projectionBias(outputSize, 0.f); bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 1., 2., 3., 4., 5., 4.}; std::vector expectedOutputValues = { -0.0135612f, -0.0263441f, 0.0314008f, -0.00883455f, 0.00763052f, -0.00126877f, -0.0292959f, 0.0449957f, -0.00976195f, -0.00492338f, -0.0175702f, -0.0431753f, 0.0597117f, -0.0169154f, 0.0142087f, 0.00472515f, -0.0196355f, 0.0342524f, -0.00407936f, -0.0253189f, -0.00512944f, -0.0293754f, 0.0512771f, -0.0151874f, -0.0246433f, -0.00744986f, -0.0345103f, 0.0450666f, -0.00944991f, 0.0126895f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor); } void UnidirectionalSequenceLstmWithCifgWithPeepholeNoProjectionTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; //tensorInfo12 bool hasInputToInputWeights = false; std::vector inputToInputWeights{}; std::vector inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f, -0.3810434485f, 0.268383264f, -0.009807467424f, -0.3522925403f, -0.24275735512f, -0.28344226125f, 0.13512269116f, -0.4932442977f, -0.10039821991f }; std::vector inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f, 0.386399507f, -0.259465157985f, -0.16545993089f, -0.4230232555f, 0.341664791103f, -0.18127849691f, -0.2277662414f, -0.55275535589f, 0.34184026718f }; std::vector inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f, 0.53969591851f, 0.23393625035f, -0.27140527306f, 0.50009280443f, 0.07511717046f, 0.3998299249f, -0.51717478049f, 0.1889653282f, -0.367323637f }; //tensorInfo16 bool hasRecurrentToInputWeights = false; std::vector recurrentToInputWeights{}; std::vector recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f, -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f, -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f, -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f }; std::vector recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f, -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f, 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f, 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f }; std::vector recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f, -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f, 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f, -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = {0.47485286f, -0.51955009f, -0.24458408f, 0.31544167f}; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = {-0.17135078f, 0.82760304f, 0.85573703f, -0.77109635f}; bool hasInputGateBias = false; std::vector inputGateBias; std::vector forgetGateBias = {1., 1., 1., 1.}; std::vector cellBias = {0., 0., 0., 0.}; std::vector outputGateBias = {0., 0., 0., 0.}; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2. }; std::vector expectedOutputValues = { -0.0129257f, -0.070531f, -0.153508f, -0.0392391f, -0.0300169f, -0.195717f, -0.528679f, -0.0818106f, -0.0332748f, 0.155429f, -0.353966f, -0.0801505f, -0.032312f, -0.0407911f, -0.435053f, -0.0932317f, -0.0108233f, 0.165584f, -0.640424f, -0.0447535f, -0.031675f, 0.125987f, -0.526695f, -0.110093f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor); } void UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionWithLayerNormTest( std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; int32_t numUnits = 5; //tensorInfo15 bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -0.49536117f, -0.0556083915f, -0.102400711f, -0.117484632f, 0.3298470976f, -0.1179017122f, 0.214305695f, 0.42135173085f, 0.003878414626f, -0.348303917f, -0.1881275477f, 0.0343011027f, -0.38837709614f, -0.05636804124f, 0.4259087456f}; std::vector inputToForgetWeights = { 0.2415594226f, 0.15400093799f, 0.4566498398f, -0.3810434485f, 0.268383264f, -0.009807467424f, -0.3522925403f, -0.24275735512f, -0.28344226125f, 0.13512269116f, -0.4932442977f, -0.10039821991f, 0.2726137042f, 0.09216640889f, -0.06551410215f}; std::vector inputToCellWeights = { -0.2504855627f, 0.184490025045f, -0.2480507493f, 0.386399507f, -0.259465157985f, -0.16545993089f, -0.4230232555f, 0.341664791103f, -0.18127849691f, -0.2277662414f, -0.55275535589f, 0.34184026718f, 0.3954237699f, -0.19407111404f, 0.30412107706f}; std::vector inputToOutputWeights = { 0.2303854227f, 0.5218806862f, -0.4865379333f, 0.53969591851f, 0.23393625035f, -0.27140527306f, 0.50009280443f, 0.07511717046f, 0.3998299249f, -0.51717478049f, 0.1889653282f, -0.367323637f, -0.12584099173f, -0.12319286912f, 0.2407919466f}; //tensorInfo20 bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -0.128009796112f, 0.1995525098f, -0.07745539397f, 0.1558421701f, -0.265254765766f, -0.38837709614f, -0.05636804124f, 0.4259087456f, 0.17628988623f, 0.3877420127f, 0.53300309181f, -0.0959980934f, 0.00302857416f, 0.3266998827f, -0.142509296562f, -0.04433270756f, 0.54066205f, -0.32668582f, -0.43562764f, -0.56094903f }; std::vector recurrentToForgetWeights = { -0.09499983487f, -0.08814888417f, -0.04834804721f, 0.1516668247f, -0.3967529535f, -0.06463699788f, 0.4952811002f, 0.003274492938f, -0.0968840941f, 0.17928104102f, 0.0031281141592f, -0.3387276584f, -0.3587934076f, 0.06705895066f, 0.22463923692f, 0.1961955726f, 0.01841056f, -0.32764608f, -0.33027974f, -0.10826075f }; std::vector recurrentToCellWeights = { -0.21938985582f, -0.3023648226f, -0.1170005202f, -0.3509177422f, -0.4286288613f, 0.2726137042f, 0.09216640889f, -0.06551410215f, 0.20453298098f, 0.2393476665f, 0.11846517771f, 0.2630801796f, 0.3954237699f, -0.19407111404f, 0.30412107706f, -0.27342408554f, 0.19069612f, -0.03026325f, -0.54532051f, 0.33003211f }; std::vector recurrentToOutputWeights = { -0.32921677827f, 0.32624614238f, -0.1388191282f, -0.17879831790f, -0.15185534954f, -0.16918526583f, -0.10087361183f, -0.5436913968f, 0.016758225858f, 0.30454617738f, -0.41493862867f, -0.005565764375f, -0.12584099173f, -0.12319286912f, 0.2407919466f, -0.08879069983f, 0.11178309f, 0.09481031f, -0.26424935f, 0.46261835f }; // tensorInfo5 bool hasCellToInputWeights = true; std::vector cellToInputWeights = { 0.05f, 0.1f, 0.25f, 0.15f, -0.02f }; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = { -0.02f, -0.15f, -0.25f, -0.03f, 0.15f }; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = { 0.1f, -0.1f, -0.5f, 0.05f, 0.01f }; bool hasInputGateBias = true; std::vector inputGateBias = { 0.03f, 0.15f, 0.22f, 0.38f, 0.05f }; std::vector forgetGateBias = { 0.1f, -0.3f, -0.2f, 0.1f, 0.4f }; std::vector cellBias = { -0.05f, 0.72f, 0.25f, 0.08f, 0.1f }; std::vector outputGateBias = { 0.05f, -0.01f, 0.2f, 0.1f, -0.2f }; bool hasProjectionWeights = true; std::vector projectionWeights = { -0.1f, 0.2f, 0.01f, -0.2f, 0.1f, 0.5f, 0.3f, 0.08f, 0.07f, 0.2f, -0.4f, 0.2f, 0.5f, -0.4f, 0.3f, -0.2f, 0.3f, 0.08f, -0.07f, 0.2f}; //{outputSize, numUnits} bool hasProjectionBias = true; std::vector projectionBias(outputSize, 0.f);; bool hasInputLayerNormWeights = true; std::vector inputLayerNormWeights = { 0.1f, 0.2f, 0.3f, 0.5f, 0.8f }; bool hasForgetLayerNormWeights = true; std::vector forgetLayerNormWeights = { 0.1f, 0.2f, 0.3f, 0.5f, 0.2f }; bool hasCellLayerNormWeights = true; std::vector cellLayerNormWeights = { 0.7f, 0.2f, 0.3f, 0.8f, 0.5f }; bool hasOutputLayerNormWeights = true; std::vector outputLayerNormWeights = { 0.6f, 0.2f, 0.2f, 0.5f, 0.1f }; std::vector inputValues = { 1., 2., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2. }; std::vector expectedOutputValues = { 0.0642256f, 0.0343966f, 0.184122f, 0.114717f, 0.11458f, 0.0407109f, 0.300327f, 0.174301f, 0.0864761f, 0.0362912f, 0.178635f, 0.115689f, 0.108008f, 0.0386623f, 0.273471f, 0.167115f, 0.0859545f, 0.0331481f, 0.186051f, 0.11888f, 0.106649f, 0.0276847f, 0.229863f, 0.166958f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_FLOAT32, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor); } void UnidirectionalSequenceLstmInt8Test(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; //tensorInfo12 bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 }; std::vector inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 }; std::vector inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 }; std::vector inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 }; //tensorInfo16 bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 }; std::vector recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 }; std::vector recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 }; std::vector recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = false; std::vector cellToForgetWeights; bool hasCellToOutputWeights = false; std::vector cellToOutputWeights; bool hasInputGateBias = true; std::vector inputGateBias = { 0., 0., 0., 0. }; std::vector forgetGateBias = { 1., 1., 1., 1. }; std::vector cellBias = { 0., 0., 0., 0. }; std::vector outputGateBias = { 0., 0., 0., 0. }; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f }; std::vector expectedOutputValues = { -0.0142517f, -0.0198845f, -0.0120569f, -0.0116868f, -0.0350714f, -0.0343202f, -0.047504f, -0.0569789f, -0.0146346f, 0.0106663f, -0.0247238f, -0.0319502f, -0.0294759f, -0.0129935f, -0.0444175f, -0.0444354f, -0.0280855f, 0.00545101f, -0.051422f, -0.0463838f, -0.0310702f, 0.00915739f, -0.0625207f, -0.0482648f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_INT8, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, 0.1f); } void UnidirectionalSequenceLstmInt8TimeMajorTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; //tensorInfo12 bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 }; std::vector inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 }; std::vector inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 }; std::vector inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 }; //tensorInfo16 bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 }; std::vector recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 }; std::vector recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 }; std::vector recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = false; std::vector cellToForgetWeights; bool hasCellToOutputWeights = false; std::vector cellToOutputWeights; bool hasInputGateBias = true; std::vector inputGateBias = { 0., 0., 0., 0. }; std::vector forgetGateBias = { 1., 1., 1., 1. }; std::vector cellBias = { 0., 0., 0., 0. }; std::vector outputGateBias = { 0., 0., 0., 0. }; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f }; std::vector expectedOutputValues = { -0.0142517f, -0.0198845f, -0.0120122f, -0.0116868f, -0.0261295f, -0.0188487f, -0.0345463f, -0.049733f, -0.0146346f, 0.0106663f, -0.0247238f, -0.0319502f, -0.0291863f, -0.0369402f, -0.0354071f, -0.0296529f, -0.0419539f, -0.00617731f, -0.0814796f, -0.0804005f, -0.0244737f, 0.0119905f, -0.0457527f, -0.0331862f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = true; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_INT8, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, 0.1); } void UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; int32_t numUnits = 4; bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3 }; std::vector inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 }; std::vector inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 }; std::vector inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 }; //tensorInfo16 bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1 }; std::vector recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 }; std::vector recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 }; std::vector recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 }; // tensorInfo4 bool hasCellToInputWeights = true; std::vector cellToInputWeights = { 5, 10, 25, 15 }; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = { -5, 15, 25, 3 }; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = { 10, -10, -5, 50 }; bool hasInputGateBias = true; std::vector inputGateBias = { 0.02234832f, 0.14757581f, 0.18176508f, 0.10380666f}; std::vector forgetGateBias = { 0.035185695f, -0.042891346f, -0.3032477f, 0.23027696f}; std::vector cellBias = { -0.124379363f, 0.55531194f, 0.23377132f, 0.033463873f }; std::vector outputGateBias = { 0.046159424f, -0.12809046f, 0.03563469f, 0.12648113f }; bool hasProjectionWeights = true; std::vector projectionWeights = { -25, 51, 3, -5, 25, 127, 77, 20, 18, 51, -10, 51, -25, 88, 77, -13 }; bool hasProjectionBias = true; std::vector projectionBias(outputSize, 0.f); bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f }; std::vector expectedOutputValues = { 0.612103f, 1.56788f, 0.31966f, 1.42956f, 0.909718f, 3.07916f, -0.560586f, 3.8907f, 0.753671f, 1.77485f, 0.365122f, 1.60077f, 0.812644f, 2.79092f, -0.605396f, 3.61742f, 0.791857f, 1.64353f, 0.316588f, 1.55192f, 0.807265f, 2.47012f, -0.539598f, 3.25654f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_INT8, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, 0.1f); } void UnidirectionalSequenceLstmInt8WithCifgWithPeepholeNoProjectionTest(std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; // cellSize and outputSize have the same size when there is no projection. int32_t numUnits = outputSize; //tensorInfo12, bool hasInputToInputWeights = false; std::vector inputToInputWeights; std::vector inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1 }; std::vector inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3 }; std::vector inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4 }; //tensorInfo16, bool hasRecurrentToInputWeights = false; std::vector recurrentToInputWeights; std::vector recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1 }; std::vector recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3 }; std::vector recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1 }; // tensorInfo4 bool hasCellToInputWeights = false; std::vector cellToInputWeights; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = { 47, -52, -24, 31 }; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = { -17, 82, 85, -77 }; bool hasInputGateBias = false; std::vector inputGateBias; std::vector forgetGateBias = { 1., 1., 1., 1. }; std::vector cellBias = { 0., 0., 0., 0. }; std::vector outputGateBias = { 0., 0., 0., 0. }; bool hasProjectionWeights = false; std::vector projectionWeights; bool hasProjectionBias = false; std::vector projectionBias; bool hasInputLayerNormWeights = false; std::vector inputLayerNormWeights; bool hasForgetLayerNormWeights = false; std::vector forgetLayerNormWeights; bool hasCellLayerNormWeights = false; std::vector cellLayerNormWeights; bool hasOutputLayerNormWeights = false; std::vector outputLayerNormWeights; std::vector inputValues = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.4f, 0.3f, 0.2f, 0.1f, 0.2f }; std::vector expectedOutputValues = { -0.0072104f, -0.00991171f, -0.00650478f, -0.00713055f, -0.0191782f, -0.0161269f, -0.0233683f, -0.054299f, -0.00783725f, 0.00635271f, -0.0126718f, -0.022613f, -0.0161351f, -0.00775868f, -0.021054f, -0.0339778f, -0.0146392f, 0.00330261f, -0.0258733f, -0.0407797f, -0.0174297f, 0.0050105f, -0.0266275f, -0.0362564f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_INT8, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, 0.1); } void UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionWithLayerNormTest( std::vector& backends) { int32_t batchSize = 3; int32_t timeSize = 2; int32_t inputSize = 3; int32_t outputSize = 4; int32_t numUnits = 5; bool hasInputToInputWeights = true; std::vector inputToInputWeights = { -4, -1, -1, -2, 3, -2, 2, 4, 1, -4, -2, 3, 2, 2, -4 }; std::vector inputToForgetWeights = { 2, 1, 4, -4, 3, -1, -3, -2, -3, 1, -4, -1, -3, -2, -4 }; std::vector inputToCellWeights = { -2, 1, -2, 4, -3, -2, -4, 3, -2, -2, -6, 3, 2, 5, -4 }; std::vector inputToOutputWeights = { 2, 5, -4, 5, 2, -3, 5, 7, 3, -5, 1, -4, -4, -1, -1 }; bool hasRecurrentToInputWeights = true; std::vector recurrentToInputWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -1, -1, -1, 4, 2, 3 }; std::vector recurrentToForgetWeights = { -1, 1, -1, 1, -3, -4, -1, 4, 2, 3, 5, -1, 1, 3, -2, -1, -1, 2, 2, 1 }; std::vector recurrentToCellWeights = { -2, -3, -1, -3, -4, 2, 1, -1, 2, 2, 1, 2, 3, -2, 3, -3, -1, -5, 1, 3 }; std::vector recurrentToOutputWeights = { -3, 3, -1, -2, -2, -2, -1, -5, 1, 3, -4, -1, -1, -1, 2, -1, 5, 1, -3, -4 }; // tensorInfo5 bool hasCellToInputWeights = true; std::vector cellToInputWeights = { 5, 3, 8, -5, 2 }; bool hasCellToForgetWeights = true; std::vector cellToForgetWeights = { -2, -7, 5, -3, 4 }; bool hasCellToOutputWeights = true; std::vector cellToOutputWeights = { 9, -10 , -5, 5, 1 }; bool hasInputGateBias = true; std::vector inputGateBias = { 0.03f, 0.15f, 0.22f, 0.38f, 0.05f }; std::vector forgetGateBias = { 0.1f, -0.3f, -0.2f, 0.1f, 0.4f }; std::vector cellBias = { -0.05f, 0.72f, 0.25f, 0.08f, 0.1f }; std::vector outputGateBias = { 0.05f, -0.01f, 0.2f, 0.1f, -0.2f }; bool hasProjectionWeights = true; std::vector projectionWeights = { -1, 2, 1, -2, 1, 5, 3, 8, 7, 2, -4, 2, 5, -4, 3, -2, 3, 8, -7, 2 }; bool hasProjectionBias = true; std::vector projectionBias(outputSize, 0.f); bool hasInputLayerNormWeights = true; std::vector inputLayerNormWeights = { 0.1f, 0.2f, -0.3f, -0.1f, 0.5f }; bool hasForgetLayerNormWeights = true; std::vector forgetLayerNormWeights = { -0.1f, 0.2f, 0.3f, 0.5f, 0.2f }; bool hasCellLayerNormWeights = true; std::vector cellLayerNormWeights = { 0.5f, 0.2f, 0.3f, 0.4f, -0.5f }; bool hasOutputLayerNormWeights = true; std::vector outputLayerNormWeights = { 0.6f, -0.2f, -0.2f, 0.5f, 0.1f }; std::vector inputValues = { 1., 8., 3., 4., 5., 4., 3., 2., 1., 2., 3., 4., 5., 4., 3., 2., 1., 2. }; std::vector expectedOutputValues = { 0.0471276f, 0.0168155f, 0.0789885f, 0.16550f, 0.0643133f, -0.0400722f, 0.100593f, 0.197722f, 0.0465562f, -0.0600682f, 0.0622087f, 0.115053f, 0.056287f, -0.0566218f, 0.0856832f, 0.148484f, 0.0457859f, -0.0588112f, 0.0623636f, 0.114333f, 0.0509271f, -0.0754262f, 0.058600f, 0.0801288f }; tflite::ActivationFunctionType activationFunction = tflite::ActivationFunctionType_TANH; float clippingThresCell = 10.f; float clippingThresProj = 0.f; bool isTimeMajor = false; UnidirectionalSequenceLstmTestImpl(backends, ::tflite::TensorType_INT8, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, inputValues, expectedOutputValues, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, 0.1); } TEST_SUITE("UnidirectionalSequenceLstmTest_CpuRefTests") { TEST_CASE ("UnidirectionalSequenceLstmTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmTimeMajorTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmTimeMajorTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmWithCifgWithPeepholeNoProjectionTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmWithCifgWithPeepholeNoProjectionTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionWithLayerNormTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmNoCifgWithPeepholeWithProjectionWithLayerNormTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmInt8Test_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmInt8Test(backends); } TEST_CASE ("UnidirectionalSequenceLstmTimeInt8TimeMajorTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmInt8TimeMajorTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmInt8WithCifgWithPeepholeNoProjectionTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmInt8WithCifgWithPeepholeNoProjectionTest(backends); } TEST_CASE ("UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionWithLayerNormTest_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnidirectionalSequenceLstmInt8NoCifgWithPeepholeWithProjectionWithLayerNormTest(backends); } } //End of TEST_SUITE("UnidirectionalSequenceLstmTest_CpuRef") } // namespace armnnDelegatearmnn-23.08/delegate/test/UnidirectionalSequenceLstmTestHelper.hpp000066400000000000000000001234101446772241200254170ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace { template std::vector CreateUnidirectionalSequenceLstmTfLiteModel(tflite::TensorType tensorType, int32_t batchSize, int32_t timeSize, int32_t inputSize, int32_t outputSize, int32_t numUnits, bool hasInputToInputWeights, const std::vector& inputToInputWeights, const std::vector& inputToForgetWeights, const std::vector& inputToCellWeights, const std::vector& inputToOutputWeights, bool hasRecurrentToInputWeights, const std::vector& recurrentToInputWeights, const std::vector& recurrentToForgetWeights, const std::vector& recurrentToCellWeights, const std::vector& recurrentToOutputWeights, bool hasCellToInputWeights, const std::vector& cellToInputWeights, bool hasCellToForgetWeights, const std::vector& cellToForgetWeights, bool hasCellToOutputWeights, const std::vector& cellToOutputWeights, bool hasInputGateBias, const std::vector& inputGateBias, const std::vector& forgetGateBias, const std::vector& cellBias, const std::vector& outputGateBias, bool hasProjectionWeights, const std::vector& projectionWeights, bool hasProjectionBias, const std::vector& projectionBias, bool hasInputLayerNormWeights, const std::vector& inputLayerNormWeights, bool hasForgetLayerNormWeights, const std::vector& forgetLayerNormWeights, bool hasCellLayerNormWeights, const std::vector& cellLayerNormWeights, bool hasOutputLayerNormWeights, const std::vector& outputLayerNormWeights, tflite::ActivationFunctionType activationFunction, float clippingThresCell, float clippingThresProj, bool isTimeMajor, float quantScale, int quantOffset = 0) { std::vector tensorInfo0{}; std::vector tensorInfoNumUnits{numUnits}; std::vector tensorInfoInputSize{numUnits, inputSize}; std::vector tensorInfoOutputSize{numUnits, outputSize}; std::vector inputShape; std::vector outputShape; if (isTimeMajor) { inputShape = {timeSize, batchSize, inputSize}; outputShape = {timeSize, batchSize, outputSize}; } else { inputShape = {batchSize, timeSize, inputSize}; outputShape = {batchSize, timeSize, outputSize}; } std::vector outputStateInDimensions{batchSize, outputSize}; std::vector cellStateInDimensions{batchSize, numUnits}; std::vector projectionWeightDimensions{outputSize, numUnits}; std::vector projectionBiasDimensions{outputSize}; std::vector operatorInputs; using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; std::vector> tensors; auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({1.0f}), flatBufferBuilder.CreateVector({0})); auto weightQuantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({quantScale}), flatBufferBuilder.CreateVector({quantOffset})); buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputShape.data(), inputShape.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("input_0"))); operatorInputs.push_back(tensors.size() - 1); if (hasInputToInputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputToInputWeights.data()), sizeof(T) * inputToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoInputSize.data(), tensorInfoInputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToInputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputToForgetWeights.data()), sizeof(T) * inputToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoInputSize.data(), tensorInfoInputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToForgetWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputToCellWeights.data()), sizeof(T) * inputToCellWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoInputSize.data(), tensorInfoInputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToCellWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputToOutputWeights.data()), sizeof(T) * inputToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoInputSize.data(), tensorInfoInputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("inputToOutputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); if (hasRecurrentToInputWeights) { buffers.push_back(CreateBuffer( flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(recurrentToInputWeights.data()), sizeof(T) * recurrentToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoOutputSize.data(), tensorInfoOutputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToInputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( recurrentToForgetWeights.data()), sizeof(T) * recurrentToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoOutputSize.data(), tensorInfoOutputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToForgetWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( recurrentToCellWeights.data()), sizeof(T) * recurrentToCellWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoOutputSize.data(), tensorInfoOutputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToCellWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( recurrentToOutputWeights.data()), sizeof(T) * recurrentToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoOutputSize.data(), tensorInfoOutputSize.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("recurrentToOutputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); if (hasCellToInputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( cellToInputWeights.data()), sizeof(T) * cellToInputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToInputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellToForgetWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( cellToForgetWeights.data()), sizeof(T) * cellToForgetWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToForgetWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellToOutputWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( cellToOutputWeights.data()), sizeof(T) * cellToOutputWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("cellToOutputWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasInputGateBias) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(inputGateBias.data()), sizeof(float) * inputGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("inputGateBias"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(forgetGateBias.data()), sizeof(float) * forgetGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("forgetGateBias"))); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(cellBias.data()), sizeof(float) * cellBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("cellBias"))); operatorInputs.push_back(tensors.size() - 1); buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(outputGateBias.data()), sizeof(float) * outputGateBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("outputGateBias"))); operatorInputs.push_back(tensors.size() - 1); if (hasProjectionWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(projectionWeights.data()), sizeof(T) * projectionWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(projectionWeightDimensions.data(), projectionWeightDimensions.size()), tensorType, buffers.size() - 1, flatBufferBuilder.CreateString("projectionWeights"), weightQuantizationParameters)); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasProjectionBias) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(projectionBias.data()), sizeof(float) * projectionBias.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(projectionBiasDimensions.data(), projectionBiasDimensions.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("projectionBias"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputStateInDimensions.data(), outputStateInDimensions.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("outputStateInInfo"), quantizationParameters, true)); operatorInputs.push_back(tensors.size() - 1); buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(cellStateInDimensions.data(), cellStateInDimensions.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("cellStateInInfo"), quantizationParameters, true)); operatorInputs.push_back(tensors.size() - 1); if (hasInputLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(inputLayerNormWeights.data()), sizeof(float) * inputLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("inputLayerNormWeights"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasForgetLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(forgetLayerNormWeights.data()), sizeof(float) * forgetLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("forgetLayerNormWeights"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasCellLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast( cellLayerNormWeights.data()), sizeof(float) * cellLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("cellLayerNormWeights"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } if (hasOutputLayerNormWeights) { buffers.push_back( CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector( reinterpret_cast(outputLayerNormWeights.data()), sizeof(float) * outputLayerNormWeights.size()))); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(tensorInfoNumUnits.data(), tensorInfoNumUnits.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("outputLayerNormWeights"))); operatorInputs.push_back(tensors.size() - 1); } else { operatorInputs.push_back(kTfLiteOptionalTensor); } buffers.push_back(CreateBuffer(flatBufferBuilder)); tensors.push_back(CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputShape.data(), outputShape.size()), ::tflite::TensorType_FLOAT32, buffers.size() - 1, flatBufferBuilder.CreateString("output"))); std::vector operatorOutputs; operatorOutputs.push_back(tensors.size() - 1); // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = BuiltinOptions_UnidirectionalSequenceLSTMOptions; flatbuffers::Offset operatorBuiltinOptions = CreateUnidirectionalSequenceLSTMOptions(flatBufferBuilder, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor).Union(); flatbuffers::Offset lstmOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), flatBufferBuilder.CreateVector(&lstmOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString( "ArmnnDelegate: UnidirectionalSequenceLSTM Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, tflite::BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void UnidirectionalSequenceLstmTestImpl(std::vector& backends, tflite::TensorType tensorType, int32_t batchSize, int32_t timeSize, int32_t inputSize, int32_t outputSize, int32_t numUnits, bool hasInputToInputWeights, const std::vector& inputToInputWeights, const std::vector& inputToForgetWeights, const std::vector& inputToCellWeights, const std::vector& inputToOutputWeights, bool hasRecurrentToInputWeights, const std::vector& recurrentToInputWeights, const std::vector& recurrentToForgetWeights, const std::vector& recurrentToCellWeights, const std::vector& recurrentToOutputWeights, bool hasCellToInputWeights, const std::vector& cellToInputWeights, bool hasCellToForgetWeights, const std::vector& cellToForgetWeights, bool hasCellToOutputWeights, const std::vector& cellToOutputWeights, bool hasInputGateBias, const std::vector& inputGateBias, const std::vector& forgetGateBias, const std::vector& cellBias, const std::vector& outputGateBias, bool hasProjectionWeights, const std::vector& projectionWeights, bool hasProjectionBias, const std::vector& projectionBias, bool hasInputLayerNormWeights, const std::vector& inputLayerNormWeights, bool hasForgetLayerNormWeights, const std::vector& forgetLayerNormWeights, bool hasCellLayerNormWeights, const std::vector& cellLayerNormWeights, bool hasOutputLayerNormWeights, const std::vector& outputLayerNormWeights, std::vector& inputValues, std::vector& expectedOutputValues, tflite::ActivationFunctionType activationFunction, float clippingThresCell, float clippingThresProj, bool isTimeMajor, float quantScale = 0.1f) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateUnidirectionalSequenceLstmTfLiteModel(tensorType, batchSize, timeSize, inputSize, outputSize, numUnits, hasInputToInputWeights, inputToInputWeights, inputToForgetWeights, inputToCellWeights, inputToOutputWeights, hasRecurrentToInputWeights, recurrentToInputWeights, recurrentToForgetWeights, recurrentToCellWeights, recurrentToOutputWeights, hasCellToInputWeights, cellToInputWeights, hasCellToForgetWeights, cellToForgetWeights, hasCellToOutputWeights, cellToOutputWeights, hasInputGateBias, inputGateBias, forgetGateBias, cellBias, outputGateBias, hasProjectionWeights, projectionWeights, hasProjectionBias, projectionBias, hasInputLayerNormWeights, inputLayerNormWeights, hasForgetLayerNormWeights, forgetLayerNormWeights, hasCellLayerNormWeights, cellLayerNormWeights, hasOutputLayerNormWeights, outputLayerNormWeights, activationFunction, clippingThresCell, clippingThresProj, isTimeMajor, quantScale); std::vector outputShape; if (isTimeMajor) { outputShape = {timeSize, batchSize, outputSize}; } else { outputShape = {batchSize, timeSize, outputSize}; } // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(0); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(0); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(0); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(0); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, outputShape); if (tensorType == ::tflite::TensorType_INT8) { // Allow 2% tolerance for Quantized weights armnnDelegate::CompareData(expectedOutputValues.data(), armnnOutputValues.data(), expectedOutputValues.size(), 2); armnnDelegate::CompareData(expectedOutputValues.data(), tfLiteOutputValues.data(), expectedOutputValues.size(), 2); armnnDelegate::CompareData(tfLiteOutputValues.data(), armnnOutputValues.data(), expectedOutputValues.size(), 2); } else { armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues); } tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/delegate/test/UnpackTest.cpp000066400000000000000000000131131446772241200201670ustar00rootroot00000000000000// // Copyright © 2021,2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #include "UnpackTestHelper.hpp" #include #include #include #include namespace armnnDelegate { template void UnpackAxis0Num4Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 4, 1, 6 }; std::vector expectedOutputShape { 1, 6 }; std::vector inputValues { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; std::vector expectedOutputValues0 { 1, 2, 3, 4, 5, 6 }; std::vector expectedOutputValues1 { 7, 8, 9, 10, 11, 12 }; std::vector expectedOutputValues2 { 13, 14, 15, 16, 17, 18 }; std::vector expectedOutputValues3 { 19, 20, 21, 22, 23, 24 }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1, expectedOutputValues2, expectedOutputValues3 }; UnpackTest(tflite::BuiltinOperator_UNPACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 0); } template void UnpackAxis2Num6Test(tflite::TensorType tensorType, std::vector& backends) { std::vector inputShape { 4, 1, 6 }; std::vector expectedOutputShape { 4, 1 }; std::vector inputValues { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; std::vector expectedOutputValues0 { 1, 7, 13, 19 }; std::vector expectedOutputValues1 { 2, 8, 14, 20 }; std::vector expectedOutputValues2 { 3, 9, 15, 21 }; std::vector expectedOutputValues3 { 4, 10, 16, 22 }; std::vector expectedOutputValues4 { 5, 11, 17, 23 }; std::vector expectedOutputValues5 { 6, 12, 18, 24 }; std::vector> expectedOutputValues{ expectedOutputValues0, expectedOutputValues1, expectedOutputValues2, expectedOutputValues3, expectedOutputValues4, expectedOutputValues5 }; UnpackTest(tflite::BuiltinOperator_UNPACK, tensorType, backends, inputShape, expectedOutputShape, inputValues, expectedOutputValues, 2); } TEST_SUITE("Unpack_CpuRefTests") { // Fp32 TEST_CASE ("Unpack_Fp32_Axis0_Num4_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnpackAxis0Num4Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Unpack_Fp32_Axis2_Num6_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnpackAxis2Num6Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Unpack_Uint8_Axis0_Num4_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnpackAxis0Num4Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Unpack_Uint8_Axis2_Num6_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; UnpackAxis2Num6Test(tflite::TensorType_UINT8, backends); } } // End of Unpack_CpuRefTests TEST_SUITE("Unpack_CpuAccTests") { // Fp32 TEST_CASE ("Unpack_Fp32_Axis0_Num4_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; UnpackAxis0Num4Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Unpack_Fp32_Axis2_Num6_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; UnpackAxis2Num6Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Unpack_Uint8_Axis0_Num4_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; UnpackAxis0Num4Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Unpack_Uint8_Axis2_Num6_CpuAcc_Test") { std::vector backends = {armnn::Compute::CpuAcc}; UnpackAxis2Num6Test(tflite::TensorType_UINT8, backends); } } // End of Unpack_CpuAccTests TEST_SUITE("Unpack_GpuAccTests") { // Fp32 TEST_CASE ("Unpack_Fp32_Axis0_Num4_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; UnpackAxis0Num4Test(tflite::TensorType_FLOAT32, backends); } TEST_CASE ("Unpack_Fp32_Axis2_Num6_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; UnpackAxis2Num6Test(tflite::TensorType_FLOAT32, backends); } // Uint8 TEST_CASE ("Unpack_Uint8_Axis0_Num4_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; UnpackAxis0Num4Test(tflite::TensorType_UINT8, backends); } TEST_CASE ("Unpack_Uint8_Axis2_Num6_GpuAcc_Test") { std::vector backends = {armnn::Compute::GpuAcc}; UnpackAxis2Num6Test(tflite::TensorType_UINT8, backends); } } // End of Unpack_GpuAccTests // End of Unpack Test Suite } // namespace armnnDelegatearmnn-23.08/delegate/test/UnpackTestHelper.hpp000066400000000000000000000172341446772241200213440ustar00rootroot00000000000000// // Copyright © 2021, 2023 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // #pragma once #include "TestUtils.hpp" #include #include #include #include #include #include #include namespace { std::vector CreateUnpackTfLiteModel(tflite::BuiltinOperator unpackOperatorCode, tflite::TensorType tensorType, std::vector& inputTensorShape, const std::vector & outputTensorShape, const int32_t outputTensorNum, unsigned int axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; std::vector> buffers; buffers.push_back(CreateBuffer(flatBufferBuilder)); buffers.push_back(CreateBuffer(flatBufferBuilder)); auto quantizationParameters = CreateQuantizationParameters(flatBufferBuilder, 0, 0, flatBufferBuilder.CreateVector({ quantScale }), flatBufferBuilder.CreateVector({ quantOffset })); const std::vector operatorInputs{ 0 }; std::vector operatorOutputs{}; const std::vector subgraphInputs{ 0 }; std::vector subgraphOutputs{}; std::vector> tensors(outputTensorNum + 1); // Create input tensor tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), tensorType, 1, flatBufferBuilder.CreateString("input"), quantizationParameters); for (int i = 0; i < outputTensorNum; ++i) { tensors[i + 1] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, (i + 2), flatBufferBuilder.CreateString("output" + std::to_string(i)), quantizationParameters); buffers.push_back(CreateBuffer(flatBufferBuilder)); operatorOutputs.push_back(i + 1); subgraphOutputs.push_back(i + 1); } // create operator tflite::BuiltinOptions operatorBuiltinOptionsType = tflite::BuiltinOptions_UnpackOptions; flatbuffers::Offset operatorBuiltinOptions = CreateUnpackOptions(flatBufferBuilder, outputTensorNum, axis).Union(); flatbuffers::Offset unpackOperator = CreateOperator(flatBufferBuilder, 0, flatBufferBuilder.CreateVector(operatorInputs.data(), operatorInputs.size()), flatBufferBuilder.CreateVector(operatorOutputs.data(), operatorOutputs.size()), operatorBuiltinOptionsType, operatorBuiltinOptions); flatbuffers::Offset subgraph = CreateSubGraph(flatBufferBuilder, flatBufferBuilder.CreateVector(tensors.data(), tensors.size()), flatBufferBuilder.CreateVector(subgraphInputs.data(), subgraphInputs.size()), flatBufferBuilder.CreateVector(subgraphOutputs.data(), subgraphOutputs.size()), flatBufferBuilder.CreateVector(&unpackOperator, 1)); flatbuffers::Offset modelDescription = flatBufferBuilder.CreateString("ArmnnDelegate: Unpack Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, unpackOperatorCode); flatbuffers::Offset flatbufferModel = CreateModel(flatBufferBuilder, TFLITE_SCHEMA_VERSION, flatBufferBuilder.CreateVector(&operatorCode, 1), flatBufferBuilder.CreateVector(&subgraph, 1), modelDescription, flatBufferBuilder.CreateVector(buffers)); flatBufferBuilder.Finish(flatbufferModel, armnnDelegate::FILE_IDENTIFIER); return std::vector(flatBufferBuilder.GetBufferPointer(), flatBufferBuilder.GetBufferPointer() + flatBufferBuilder.GetSize()); } template void UnpackTest(tflite::BuiltinOperator unpackOperatorCode, tflite::TensorType tensorType, std::vector& backends, std::vector& inputShape, std::vector& expectedOutputShape, std::vector& inputValues, std::vector>& expectedOutputValues, unsigned int axis = 0, float quantScale = 1.0f, int quantOffset = 0) { using namespace delegateTestInterpreter; std::vector modelBuffer = CreateUnpackTfLiteModel(unpackOperatorCode, tensorType, inputShape, expectedOutputShape, expectedOutputValues.size(), axis, quantScale, quantOffset); // Setup interpreter with just TFLite Runtime. auto tfLiteInterpreter = DelegateTestInterpreter(modelBuffer); CHECK(tfLiteInterpreter.AllocateTensors() == kTfLiteOk); CHECK(tfLiteInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(tfLiteInterpreter.Invoke() == kTfLiteOk); // Setup interpreter with Arm NN Delegate applied. auto armnnInterpreter = DelegateTestInterpreter(modelBuffer, backends); CHECK(armnnInterpreter.AllocateTensors() == kTfLiteOk); CHECK(armnnInterpreter.FillInputTensor(inputValues, 0) == kTfLiteOk); CHECK(armnnInterpreter.Invoke() == kTfLiteOk); // Compare output data for (unsigned int i = 0; i < expectedOutputValues.size(); ++i) { std::vector tfLiteOutputValues = tfLiteInterpreter.GetOutputResult(i); std::vector tfLiteOutputShape = tfLiteInterpreter.GetOutputShape(i); std::vector armnnOutputValues = armnnInterpreter.GetOutputResult(i); std::vector armnnOutputShape = armnnInterpreter.GetOutputShape(i); armnnDelegate::CompareOutputData(tfLiteOutputValues, armnnOutputValues, expectedOutputValues[i]); armnnDelegate::CompareOutputShape(tfLiteOutputShape, armnnOutputShape, expectedOutputShape); } tfLiteInterpreter.Cleanup(); armnnInterpreter.Cleanup(); } } // anonymous namespacearmnn-23.08/docker/000077500000000000000000000000001446772241200141215ustar00rootroot00000000000000armnn-23.08/docker/README.md000066400000000000000000000005631446772241200154040ustar00rootroot00000000000000# ARMNN Docker Files A productized Arm NN Docker solution has been released as part of our new Arm NN Build Tool which can be found at this link on our GitHub website: https://github.com/ARM-software/armnn/tree/HEAD/build-tool The above link automatically points to the latest release version of the Arm NN Build Tool and will be live when Arm NN 22.08 is released. armnn-23.08/docker/README.md.license000066400000000000000000000001531446772241200170200ustar00rootroot00000000000000# # Copyright © 2021-2022 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/docs/000077500000000000000000000000001446772241200136025ustar00rootroot00000000000000armnn-23.08/docs/01_00_quick_start.dox000066400000000000000000000011761446772241200174530ustar00rootroot00000000000000/// Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page quickstart Quick Start Guide On this page you can find guides which allow you to get setup and ready to run models with Arm NN quickly. These guides rely on using the apt packages or prebuilt binaries from our release notes. We only have added a quick start guide that uses TfLite-Delegate. More guides will be added in the future. - @subpage md_delegate_DelegateQuickStartGuide **/ } namespace armnn { /** @page md_delegate_DelegateQuickStartGuide TfLite Delegate Quick Start Guide **/ } armnn-23.08/docs/02_operator_list.dox000066400000000000000000001725451446772241200175230ustar00rootroot00000000000000/// Copyright (c) 2021, 2023 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page operator_list Arm NN Operators @section S5_1_operator_list Arm NN Operators Arm NN supports operators that are listed in below table. Arm NN supports a wide list of data-types. The main data-types that the Machine Learning functions support are the following:
  • BFLOAT16: 16-bit non-standard brain floating point
  • QASYMMU8: 8-bit unsigned asymmetric quantized
  • QASYMMS8: 8-bit signed asymmetric quantized
  • QUANTIZEDSYMM8PERAXIS: 8-bit signed symmetric quantized
  • QSYMMS8: 8-bit signed symmetric quantized
  • QSYMMS16: 16-bit signed symmetric quantized
  • FLOAT32: 32-bit single precision floating point
  • FLOAT16: 16-bit half precision floating point
  • SIGNED32: 32-bit signed integer
  • BOOLEAN: 8-bit unsigned char
  • All: Agnostic to any specific data type
Arm NN supports the following data layouts (fast changing dimension from right to left):
  • NHWC: Layout where channels are in the fastest changing dimension
  • NCHW: Layout where width is in the fastest changing dimension
  • All: Agnostic to any specific data layout
where N = batches, C = channels, H = height, W = width
Operator Description Equivalent Android NNAPI Operator Backends Data Layouts Data Types
AbsLayer Layer to perform absolute operation.
  • ANEURALNETWORKS_ABS
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
FLOAT16
FLOAT32
SIGNED32
GpuAcc
  • All
FLOAT16
FLOAT32
ActivationLayer Layer to simulate an activation layer with the specified activation function.
  • ANEURALNETWORKS_ABS
  • ANEURALNETWORKS_ELU
  • ANEURALNETWORKS_HARD_SWISH
  • ANEURALNETWORKS_LOGISTIC
  • ANEURALNETWORKS_PRELU
  • ANEURALNETWORKS_RELU
  • ANEURALNETWORKS_RELU1
  • ANEURALNETWORKS_RELU6
  • ANEURALNETWORKS_SQRT
  • ANEURALNETWORKS_TANH
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
FLOAT16
FLOAT32
AdditionLayer Layer to add 2 tensors.
  • ANEURALNETWORKS_ADD
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
ArgMinMaxLayer Layer to calculate the index of the minimum or maximum values in a tensor based on an axis.
  • ANEURALNETWORKS_ARGMAX
  • ANEURALNETWORKS_ARGMIN
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
SIGNED64
CpuAcc
  • All
QASYMMU8
QASYMMS8
SIGNED32
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
SIGNED32
FLOAT16
FLOAT32
BatchMatMulLayer Layer to perform batch matrix multiplication.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
FLOAT32
QASYMMS8
GpuAcc
  • All
FLOAT32
QASYMMS8
BatchNormalizationLayer Layer to perform batch normalization.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
FLOAT32
FLOAT16
GpuAcc
  • NHWC
  • NCHW
FLOAT32
FLOAT16
BatchToSpaceNdLayer Layer to perform a batch to space transformation.
  • ANEURALNETWORKS_BATCH_TO_SPACE_ND
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
CastLayer Layer to cast a tensor to a type.
  • ANEURALNETWORKS_CAST
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QSYMMS8
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMS8
QASYMMU8
FLOAT16
SIGNED32
FLOAT32
GpuAcc
  • All
QASYMMS8
QASYMMU8
SIGNED32
FLOAT16
FLOAT32
ChannelShuffleLayer Layer to reorganize the channels of a tensor.
  • ANEURALNETWORKS_CHANNEL_SHUFFLE
CpuRef
  • All
FLOAT16
FLOAT32
QSYMMS8
QASYMMS8
QASYMMU8
CpuAcc
  • All
QASYMMS8
QASYMMU8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMS8
QASYMMU8
FLOAT16
FLOAT32
ComparisonLayer Layer to compare 2 tensors.
  • ANEURALNETWORKS_EQUAL
  • ANEURALNETWORKS_GREATER
  • ANEURALNETWORKS_GREATER_EQUAL
  • ANEURALNETWORKS_LESS
  • ANEURALNETWORKS_LESS_EQUAL
  • ANEURALNETWORKS_NOT_EQUAL
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
BOOLEAN
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
All
GpuAcc
  • All
All
ConcatLayer Layer to concatenate tensors along a given axis.
  • ANEURALNETWORKS_CONCATENATION
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
ConstantLayer Layer to provide a constant tensor.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
SIGNED32
CpuAcc
  • All
All
GpuAcc
  • All
All
ConvertFp16ToFp32Layer Layer to convert Float16 tensor to Float32 tensor.
  • N/A
CpuRef
  • All
FLOAT16
FLOAT32
CpuAcc
  • All
FLOAT16
FLOAT32
GpuAcc
  • All
FLOAT16
FLOAT32
ConvertFp32ToFp16Layer Layer to convert Float32 tensor to Float16 tensor.
  • N/A
CpuRef
  • All
FLOAT16
FLOAT32
CpuAcc
  • All
FLOAT16
FLOAT32
GpuAcc
  • All
FLOAT16
FLOAT32
Convolution2dLayer Layer to compute a convolution operation.
  • ANEURALNETWORKS_CONV_2D
  • ANEURALNETWORKS_GROUPED_CONV_2D
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
GpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
Convolution3dLayer Layer to compute a 3D convolution operation.
  • N/A
CpuRef
  • NDHWC
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • N/A
  • N/A
GpuAcc
  • N/A
  • N/A
DebugLayer Layer to print out inter layer tensor information.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
SIGNED32
DepthToSpaceLayer Layer to perform Depth to Space transformation.
  • ANEURALNETWORKS_DEPTH_TO_SPACE
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
DepthwiseConvolution2dLayer Layer to compute a deconvolution or transpose convolution.
  • ANEURALNETWORKS_DEPTHWISE_CONV_2D
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
SIGNED32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
GpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
SIGNED32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
DequantizeLayer Layer to dequantize the values in a tensor.
  • ANEURALNETWORKS_DEQUANTIZE
CpuRef
  • All
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • All
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
QSYMMS8
QSYMMS16
GpuAcc
  • All
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
QSYMMS8
QSYMMS16
DetectionPostProcessLayer Layer to generate the detection output based on center size encoded boxes, class prediction and anchors by doing non maximum suppression (NMS).
  • ANEURALNETWORKS_DETECTION_POSTPROCESSING
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT32
DivisionLayer Layer to divide 2 tensors.
  • ANEURALNETWORKS_DIV
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
FLOAT16
FLOAT32
GpuAcc
  • All
FLOAT16
FLOAT32
ElementwiseBaseLayer Layer to perform Add - Div - Max - Min - Mul operations.
  • ANEURALNETWORKS_ADD
  • ANEURALNETWORKS_DIV
  • ANEURALNETWORKS_MAXIMUM
  • ANEURALNETWORKS_MINIMUM
  • ANEURALNETWORKS_MUL
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
ElementwiseBinaryLayer Layer to perform Power and Square Difference operations.
  • ANEURALNETWORKS_POW
CpuRef
  • All
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
FLOAT16
FLOAT32
GpuAcc
  • All
FLOAT16
FLOAT32
ElementwiseUnaryLayer Layer to perform Rsqrt - Exp - Neg - Log - Abs - Sin - Sqrt - Ceil operations.
  • ANEURALNETWORKS_ABS
  • ANEURALNETWORKS_EXP
  • ANEURALNETWORKS_LOG
  • ANEURALNETWORKS_NEG
  • ANEURALNETWORKS_RSQRT
  • ANEURALNETWORKS_SIN
  • ANEURALNETWORKS_SQRT
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
FLOAT16
FLOAT32
SIGNED32
GpuAcc
  • All
FLOAT16
FLOAT32
FakeQuantizationLayer Layer to quantize float values and dequantize afterwards. The current implementation does not dequantize the values.
  • N/A
CpuRef
  • All
FLOAT32
FillLayer Layer to set the values of a tensor with a given value.
  • ANEURALNETWORKS_FILL
CpuRef
  • All
FLOAT16
FLOAT32
SIGNED32
CpuAcc
  • All
All
GpuAcc
  • All
All
FloorLayer Layer to round the value to the lowest whole number.
  • ANEURALNETWORKS_FLOOR
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
CpuAcc
  • All
FLOAT32
FLOAT16
GpuAcc
  • All
FLOAT32
FLOAT16
FullyConnectedLayer Layer to perform a fully connected / dense operation.
  • ANEURALNETWORKS_FULLY_CONNECTED
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
GpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
GatherLayer Layer to perform the gather operation along the chosen axis.
  • ANEURALNETWORKS_GATHER
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
All
GpuAcc
  • All
All
GatherNdLayer Layer to perform the gatherNd operation.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
GpuAcc
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
InputLayer Special layer used to provide input data to the computational network.
  • N/A
All
  • All
All
InstanceNormalizationLayer Layer to perform an instance normalization on a given axis.
  • ANEURALNETWORKS_INSTANCE_NORMALIZATION
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
CpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
GpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
L2NormalizationLayer Layer to perform an L2 normalization on a given axis.
  • ANEURALNETWORKS_L2_NORMALIZATION
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
GpuAcc
  • NHWC
  • NCHW
FLOAT16
FLOAT32
LogSoftmaxLayer Layer to perform the log softmax activations given logits.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
LogicalBinaryLayer Layer to perform Logical AND - Logical NOT - Logical OR operations.
  • ANEURALNETWORKS_LOGICAL_AND
  • ANEURALNETWORKS_LOGICAL_NOT
  • ANEURALNETWORKS_LOGICAL_OR
CpuRef
  • All
BOOLEAN
CpuAcc
  • All
BOOLEAN
GpuAcc
  • All
BOOLEAN
LstmLayer Layer to perform a single time step in a Long Short-Term Memory (LSTM) operation.
  • ANEURALNETWORKS_LSTM
CpuRef
  • All
BFLOAT16
FLOAT16
QSYMMS16
CpuAcc
  • All
FLOAT16
FLOAT32
GpuAcc
  • All
FLOAT16
FLOAT32
MapLayer Layer to perform map operation on tensor.
  • N/A
CpuRef
  • All
All
CpuAcc
  • All
All
GpuAcc
  • All
All
MaximumLayer Layer to perform an elementwise maximum of two tensors.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
SIGNED32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
FLOAT16
FLOAT32
SIGNED32
MeanLayer Layer to perform reduce mean operation.
  • ANEURALNETWORKS_MEAN
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
MemCopyLayer Layer to perform memory copy operation.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
BOOLEAN
CpuAcc
  • All
All
GpuAcc
  • All
All
MemImportLayer Layer to perform memory import operation.
  • N/A
CpuRef
  • All
All
CpuAcc
  • All
All
GpuAcc
  • All
All
MergeLayer Layer to concatenate tensors along a given axis.
  • ANEURALNETWORKS_CONCATENATION
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
MinimumLayer Layer to perform an elementwise minimum of two tensors.
  • ANEURALNETWORKS_MINIMUM
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
FLOAT16
FLOAT32
SIGNED32
MultiplicationLayer Layer to perform an elementwise multiplication of two tensors.
  • ANEURALNETWORKS_MUL
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
SIGNED32
NormalizationLayer Layer to compute normalization operation.
  • ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
FLOAT32
FLOAT16
GpuAcc
  • NHWC
  • NCHW
FLOAT32
FLOAT16
OutputLayer A special layer providing access to a user supplied buffer into which the output of a network can be written.
  • N/A
All
  • All
All
PadLayer Layer to pad a tensor.
  • ANEURALNETWORKS_PAD
  • ANEURALNETWORKS_PAD_V2
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
PermuteLayer Layer to transpose an ND tensor.
  • ANEURALNETWORKS_TRANSPOSE
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
Pooling2dLayer Layer to perform 2D pooling with the specified pooling operation.
  • ANEURALNETWORKS_AVERAGE_POOL_2D
  • ANEURALNETWORKS_L2_POOL_2D
  • ANEURALNETWORKS_MAX_POOL_2D
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • NHWC
  • NCHW
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
Pooling3dLayer Layer to perform 3D pooling with the specified pooling operation.
  • ANEURALNETWORKS_AVERAGE_POOL_3D
  • ANEURALNETWORKS_L2_POOL_3D
  • ANEURALNETWORKS_MAX_POOL_3D
CpuRef
  • NDHWC
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NA
GpuAcc
  • NDHWC
PreCompiledLayer Opaque layer provided by a backend which provides an executable representation of a subgraph from the original network.
  • N/A
N/A N/A N/A
PreluLayer Layer to compute the activation layer with the PRELU activation function.
  • ANEURALNETWORKS_PRELU
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
QLstmLayer Layer to perform quantized LSTM (Long Short-Term Memory) operation.
  • ANEURALNETWORKS_QUANTIZED_LSTM
  • ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
CpuRef
  • All
All
CpuAcc
  • All
QASYMMS8
QASYMMU8
SIGNED32
QSYMMS16
GpuAcc
  • All
QASYMMS8
QASYMMU8
SIGNED32
QSYMMS16
QuantizeLayer Layer to perform quantization operation.
  • ANEURALNETWORKS_QUANTIZE
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
QASYMM16
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QASYMM16
FLOAT16
FLOAT32
QuantizedLstmLayer Layer to perform quantized LSTM (Long Short-Term Memory) operation.
  • ANEURALNETWORKS_QUANTIZED_LSTM
  • ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
CpuRef
  • All
All
CpuAcc
  • All
SIGNED32
QASYMMU8
QSYMMS16
GpuAcc
  • All
SIGNED32
QASYMMU8
QSYMMS16
RankLayer Layer to perform a rank operation.
  • ANEURALNETWORKS_RANK
CpuRef
  • All
All
CpuAcc
  • All
All
GpuAcc
  • All
All
ReduceLayer Layer to perform reduce with the following operations - ARG_IDX_MAX: Index of the max value - ARG_IDX_MIN: Index of the min value - MEAN_SUM: Mean of sum - PROD: Product - SUM_SQUARE: Sum of squares - SUM: Sum - MIN: Min - MAX: Max
  • ANEURALNETWORKS_REDUCE_MAX
  • ANEURALNETWORKS_REDUCE_MIN
  • ANEURALNETWORKS_REDUCE_SUM
  • ANEURALNETWORKS_REDUCE_PROD
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
SIGNED32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
SIGNED32
ReshapeLayer Layer to reshape a tensor.
  • ANEURALNETWORKS_RESHAPE
  • ANEURALNETWORKS_SQUEEZE
  • ANEURALNETWORKS_EXPAND_DIMS
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
BOOLEAN
CpuAcc
  • All
All
GpuAcc
  • All
All
ResizeLayer Layer to perform resize of a tensor using one of the interpolation methods: - Bilinear - Nearest Neighbor.
  • ANEURALNETWORKS_RESIZE_BILINEAR
  • ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • NHWC
  • NCHW
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
ReverseV2Layer Layer to perform reverse of a tensor.
  • NA
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
RsqrtLayer Layer to perform Rsqrt operation.
  • ANEURALNETWORKS_RSQRT
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
FLOAT16
FLOAT32
SIGNED32
GpuAcc
  • All
FLOAT16
FLOAT32
ShapeLayer Layer to return the shape of the input tensor.
  • N/A
CpuRef
  • All
All
CpuAcc
  • All
All
GpuAcc
  • All
All
SliceLayer Layer to perform tensor slicing.
  • ANEURALNETWORKS_SLICE
CpuRef
  • All
BFLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
SoftmaxLayer Layer to perform softmax, log-softmax operation over the specified axis.
  • ANEURALNETWORKS_LOG_SOFTMAX
  • ANEURALNETWORKS_SOFTMAX
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
FLOAT16
FLOAT32
SpaceToBatchNdLayer Layer to divide spatial dimensions of the tensor into a grid of blocks and interleaves these blocks with the batch dimension.
  • ANEURALNETWORKS_SPACE_TO_BATCH_ND
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
SpaceToDepthLayer Layer to rearrange blocks of spatial data into depth.
  • ANEURALNETWORKS_SPACE_TO_DEPTH
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
SplitterLayer Layer to split a tensor along a given axis.
  • ANEURALNETWORKS_SPLIT
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
StackLayer Layer to stack tensors along an axis.
  • N/A
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
StandInLayer A layer to represent "unknown" or "unsupported" operations in the input graph. It has a configurable number of input and output slots and an optional name.
  • N/A
N/A N/A N/A
StridedSliceLayer Layer to extract a strided slice of a tensor.
  • ANEURALNETWORKS_STRIDED_SLICE
CpuRef
  • All
BFLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
SubtractionLayer Layer to perform an elementwise subtract of 2 tensors.
  • ANEURALNETWORKS_SUB
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
SIGNED32
CpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
GpuAcc
  • All
QASYMMU8
QASYMMS8
QSYMMS16
SIGNED32
FLOAT16
FLOAT32
TileLayer Layer to construct a tensor by repeating in tiles a given tensor.
  • ANEURALNETWORKS_TILE
CpuRef
  • All
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
SIGNED32
CpuAcc
  • All
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QASYMM8
QSYMMS16
SIGNED32
GpuAcc
  • All
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
SIGNED32
TransposeConvolution2dLayer Layer to perform 2D transpose convolution (deconvolution) operation.
  • ANEURALNETWORKS_TRANSPOSE_CONV_2D
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS8
QSYMMS16
CpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
GpuAcc
  • NHWC
  • NCHW
SIGNED32
FLOAT16
FLOAT32
QASYMMU8
QASYMMS8
QUANTIZEDSYMM8PERAXIS
TransposeLayer Layer to transpose a tensor.
  • ANEURALNETWORKS_TRANSPOSE
CpuRef
  • All
BFLOAT16
FLOAT16
FLOAT32
QASYMMS8
QASYMMU8
QSYMMS16
CpuAcc
  • All
All
GpuAcc
  • All
All
UnidirectionalSquenceLstmLayer Layer to perform unidirectional sequence LSTM operation.
  • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
CpuRef
  • All
Input Types
FLOAT32
Weight Types
FLOAT32
QASYMMS8
CpuAcc
  • All
Input Types
FLOAT32
Weight Types
FLOAT32
GpuAcc
  • All
Input Types
FLOAT32
Weight Types
FLOAT32
UnmapLayer Layer to perform unmap operation on tensor.
  • N/A
CpuRef
  • All
All
CpuAcc
  • NHWC
  • NCHW
All
GpuAcc
  • NHWC
  • NCHW
All
*/ } // namespace armnn-23.08/docs/03_build_guides.dox000066400000000000000000000017211446772241200172600ustar00rootroot00000000000000/// Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page buildguides Build Guides This page links all guides to build and/or install Arm NN tools hosted in our repository. You can find additional tutorials on https://developer.arm.com/solutions/machine-learning-on-arm/developer-material/how-to-guides Arm NN is written using portable C++14 and the build system uses [CMake](https://cmake.org/), therefore it is possible to build for a wide variety of target platforms, from a wide variety of host environments. Arm NN is managed by a single CMake project. That allows you to build multiple tools at once by combining the CMake options from different build guides. ## Installation via APT Repository - @subpage md_InstallationViaAptRepository ## TfLite Delegate build guide - @subpage md_delegate_BuildGuideNative ## Android NDK and Arm NN - @subpage md_BuildGuideAndroidNDK **/ }armnn-23.08/docs/04_contributor.dox000066400000000000000000000020141446772241200171700ustar00rootroot00000000000000/// Copyright (c) 2021 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page contribguides Contribution Guides This is a collection of guides that should help you contribute code to Arm NN. Before you get started, please take a look into our /ref md_Contributor_Guide section. - @subpage md_src_backends_README \n This guide explains how to add your own backend to Arm NN. This might be useful if you would like to accelerate neural networks on hardware that Arm NN currently doesn't support. - @subpage md_src_dynamic_README \n Arm NN allows you to load a backend dynamically on runtime. To find out how that can be done take a look at this guide. **/ } /// Create pages for each tool so they appear nicely in the doxygen tree-view. Subpages are not listed there. /// Also we can overwrite the page name this way. namespace armnn { /** @page md_src_backends_README Backend Developer Guide @page md_src_dynamic_README Dynamically loadable Backend **/ } armnn-23.08/docs/05_00_software_components.dox000066400000000000000000000016351446772241200212250ustar00rootroot00000000000000/// Copyright (c) 2022 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page swtools Software Components On this page you can find all software components contained in the Arm NN repository. You will find links to how-to guides and other helpful information in each section. - @subpage md_src_armnnConverter_README - @subpage deserializer - @subpage supportlibrary - @subpage parsers - @subpage md_python_pyarmnn_README - @subpage runtimeoptions - @subpage serializer - @subpage delegate **/ } /// Create pages for each tool so they appear nicely in the doxygen tree-view. Subpages are not listed there. /// /// Note: The parser, serializer and deserializer pages are created in 01_parsers.dox or 02_deserializer_serializer.dox namespace armnn { /** @page md_python_pyarmnn_README PyArmNN @page md_src_armnnConverter_README Converter **/ } armnn-23.08/docs/05_01_parsers.dox000066400000000000000000000165751446772241200166170ustar00rootroot00000000000000/// Copyright (c) 2022-2023 Arm Ltd and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page parsers Parsers Execute models from different machine learning platforms efficiently with our parsers. Simply choose a parser according to the model you want to run e.g. If you've got a model in onnx format (.onnx) use our onnx-parser. If you would like to run a Tensorflow Lite (TfLite) model you probably also want to take a look at our @ref delegate. All parsers are written in C++ but it is also possible to use them in python. For more information on our python bindings take a look into the @ref md_python_pyarmnn_README section.

@section S5_onnx_parser Arm NN Onnx Parser `armnnOnnxParser` is a library for loading neural networks defined in ONNX protobuf files into the Arm NN runtime. ## ONNX operators that the Arm NN SDK supports This reference guide provides a list of ONNX operators the Arm NN SDK currently supports. The Arm NN SDK ONNX parser currently only supports fp32 operators. ### Fully supported - Add - See the ONNX [Add documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Add) for more information - AveragePool - See the ONNX [AveragePool documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#AveragePool) for more information. - Concat - See the ONNX [Concat documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Concat) for more information. - Constant - See the ONNX [Constant documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Constant) for more information. - Clip - See the ONNX [Clip documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Clip) for more information. - Flatten - See the ONNX [Flatten documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Flatten) for more information. - Gather - See the ONNX [Gather documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Gather) for more information. - GlobalAveragePool - See the ONNX [GlobalAveragePool documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#GlobalAveragePool) for more information. - LeakyRelu - See the ONNX [LeakyRelu documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#LeakyRelu) for more information. - MaxPool - See the ONNX [max_pool documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#MaxPool) for more information. - Relu - See the ONNX [Relu documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Relu) for more information. - Reshape - See the ONNX [Reshape documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Reshape) for more information. - Shape - See the ONNX [Shape documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Shape) for more information. - Sigmoid - See the ONNX [Sigmoid documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Sigmoid) for more information. - Tanh - See the ONNX [Tanh documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Tanh) for more information. - Unsqueeze - See the ONNX [Unsqueeze documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Unsqueeze) for more information. ### Partially supported - Conv - The parser only supports 2D convolutions with a group = 1 or group = #Nb_of_channel (depthwise convolution) - BatchNormalization - The parser does not support training mode. See the ONNX [BatchNormalization documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#BatchNormalization) for more information. - Gemm - The parser only supports constant bias or non-constant bias where bias dimension = 1. See the ONNX [Gemm documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#Gemm) for more information. - MatMul - The parser only supports constant weights in a fully connected layer. See the ONNX [MatMul documentation](https://github.com/onnx/onnx/blob/master/docs/Operators.md#MatMul) for more information. ## Tested networks Arm tested these operators with the following ONNX fp32 neural networks: - Mobilenet_v2. See the ONNX [MobileNet documentation](https://github.com/onnx/models/tree/master/vision/classification/mobilenet) for more information. - Simple MNIST. This is no longer directly documented by ONNX. The model and test data may be downloaded [from the ONNX model zoo](https://onnxzoo.blob.core.windows.net/models/opset_8/mnist/mnist.tar.gz). More machine learning operators will be supported in future releases.



@section S6_tf_lite_parser Arm NN Tf Lite Parser `armnnTfLiteParser` is a library for loading neural networks defined by TensorFlow Lite FlatBuffers files into the Arm NN runtime. ## TensorFlow Lite operators that the Arm NN SDK supports This reference guide provides a list of TensorFlow Lite operators the Arm NN SDK currently supports. ### Fully supported The Arm NN SDK TensorFlow Lite parser currently supports the following operators: - ABS - ADD - ARG_MAX - ARG_MIN - AVERAGE_POOL_2D, Supported Fused Activation: RELU , RELU6 , TANH, NONE - BATCH_TO_SPACE - CAST - CEIL - CONCATENATION, Supported Fused Activation: RELU , RELU6 , TANH, NONE - CONV_2D, Supported Fused Activation: RELU , RELU6 , TANH, NONE - CONV_3D, Supported Fused Activation: RELU , RELU6 , TANH, NONE - DEPTH_TO_SPACE - DEPTHWISE_CONV_2D, Supported Fused Activation: RELU , RELU6 , TANH, NONE - DEQUANTIZE - DIV - ELU - EQUAL - EXP - EXPAND_DIMS - FLOOR_DIV - FULLY_CONNECTED, Supported Fused Activation: RELU , RELU6 , TANH, NONE - GATHER - GATHER_ND - GREATER - GREATER_EQUAL - HARD_SWISH - LEAKY_RELU - LESS - LESS_EQUAL - LOG - LOGICAL_NOT - LOGISTIC - LOG_SOFTMAX - L2_NORMALIZATION - MAX_POOL_2D, Supported Fused Activation: RELU , RELU6 , TANH, NONE - MAXIMUM - MEAN - MINIMUM - MIRROR_PAD - MUL - NEG - NOT_EQUAL - PACK - PAD - PADV2 - POW - PRELU - QUANTIZE - RELU - RELU6 - REDUCE_MAX - REDUCE_MIN - REDUCE_PROD - RESHAPE - RESIZE_BILINEAR - RESIZE_NEAREST_NEIGHBOR - REVERSE_V2 - RSQRT - SHAPE - SIN - SLICE - SOFTMAX - SPACE_TO_BATCH - SPACE_TO_DEPTH - SPLIT - SPLIT_V - SQUEEZE - SQRT - SQUARE - SQUARE_DIFFERENCE - STRIDED_SLICE - SUB - SUM - TANH - TILE - TRANSPOSE - TRANSPOSE_CONV - UNIDIRECTIONAL_SEQUENCE_LSTM - UNPACK ### Custom Operator - TFLite_Detection_PostProcess ## Tested networks Arm tested these operators with the following TensorFlow Lite neural network: - [Quantized MobileNet](http://download.tensorflow.org/models/mobilenet_v1_2018_02_22/mobilenet_v1_1.0_224_quant.tgz) - [Quantized SSD MobileNet](http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_18.tar.gz) - DeepSpeech v1 converted from [TensorFlow model](https://github.com/mozilla/DeepSpeech/releases/tag/v0.4.1) - DeepSpeaker - [DeepLab v3+](https://www.tensorflow.org/lite/models/segmentation/overview) - FSRCNN - EfficientNet-lite - RDN converted from [TensorFlow model](https://github.com/hengchuan/RDN-TensorFlow) - Quantized RDN (CpuRef) - [Quantized Inception v3](http://download.tensorflow.org/models/tflite_11_05_08/inception_v3_quant.tgz) - [Quantized Inception v4](http://download.tensorflow.org/models/inception_v4_299_quant_20181026.tgz) (CpuRef) - Quantized ResNet v2 50 (CpuRef) - Quantized Yolo v3 (CpuRef) More machine learning operators will be supported in future releases. **/ } armnn-23.08/docs/05_02_serializer.dox000066400000000000000000000036571446772241200173070ustar00rootroot00000000000000/// Copyright (c) 2021-2023 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page serializer Serializer The `armnnSerializer` is a library for serializing an Arm NN network to a stream. @section serializersupport Supported Layers This reference guide provides a list of layers which can be serialized by the Arm NN SDK. The Arm NN SDK Serializer currently supports the following layers: - Activation - Addition - ArgMinMax - BatchMatMul - BatchToSpaceNd - BatchNormalization - Cast - ChannelShuffle - Comparison - Concat - Constant - Convolution2d - Convolution3d - DepthToSpace - DepthwiseConvolution2d - Dequantize - DetectionPostProcess - Division - ElementwiseUnary - Fill - Floor - FullyConnected - Gather - GatherNd - Input - InstanceNormalization - L2Normalization - Logical - LogSoftmax - Lstm - Maximum - Mean - Merge - Minimum - Multiplication - Normalization - Output - Pad (Constant, Symmetric, Reflect) - Permute - Pooling2d - Pooling3d - Prelu - QLstm - Quantize - QuantizedLstm - Rank - Reduce - Reshape - Resize - ReverseV2 - Shape - Slice - Softmax - SpaceToBatchNd - SpaceToDepth - Splitter - Stack - StandIn - StridedSlice - Subtraction - Switch - Transpose - TransposeConvolution2d - UnidirectionalSequenceLstm More machine learning layers will be supported in future releases. @section serializersupportdeprecated Deprecated layers Some layers have been deprecated and replaced by others layers. In order to maintain backward compatibility, serializations of these deprecated layers will deserialize to the layers that have replaced them, as follows: - Abs will deserialize as ElementwiseUnary - Equal will deserialize as Comparison - Greater will deserialize as Comparison - Merger will deserialize as Concat - ResizeBilinear will deserialize as Resize - Rsqrt will deserialize as ElementwiseUnary **/ } armnn-23.08/docs/05_03_delegate.dox000066400000000000000000000103551446772241200167020ustar00rootroot00000000000000/// Copyright (c) 2022-2023 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page delegate TfLite Delegate @section delegateintro About the delegate 'armnnDelegate' is a library for accelerating certain TensorFlow Lite (TfLite) operators on Arm hardware. It can be integrated in TfLite using its delegation mechanism. TfLite will then delegate the execution of operators supported by Arm NN to Arm NN. The main difference to our @ref S6_tf_lite_parser is the amount of operators you can run with it. If none of the active backends support an operation in your model you won't be able to execute it with our parser. In contrast to that, TfLite only delegates operations to the armnnDelegate if it does support them and otherwise executes them itself. In other words, every TfLite model can be executed and every operation in your model that we can accelerate will be accelerated. That is the reason why the armnnDelegate is our recommended way to accelerate TfLite models. If you need help building the armnnDelegate, please take a look at our [build guide](delegate/BuildGuideNative.md). @section delegatesupport Supported Operators This reference guide provides a list of TensorFlow Lite operators the Arm NN SDK currently supports. @section delegatefullysupported Fully supported The Arm NN SDK TensorFlow Lite delegate currently supports the following operators: - ABS - ADD - ARG_MAX - ARG_MIN - AVERAGE_POOL_2D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - AVERAGE_POOL_3D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, SIGN_BIT, TANH, NONE - BATCH_MATMUL - BATCH_TO_SPACE_ND - CAST - CEIL - CONCATENATION, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - CONV_2D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - CONV_3D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - DEPTH_TO_SPACE - DEPTHWISE_CONV_2D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - DEQUANTIZE - DIV - EQUAL - ELU - EXP - EXPAND_DIMS - FILL - FLOOR - FLOOR_DIV - FULLY_CONNECTED, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - GATHER - GATHER_ND - GREATER - GREATER_EQUAL - HARD_SWISH - L2_NORMALIZATION - L2_POOL_2D - LESS - LESS_EQUAL - LOCAL_RESPONSE_NORMALIZATION - LOG - LOGICAL_AND - LOGICAL_NOT - LOGICAL_OR - LOGISTIC - LOG_SOFTMAX - LSTM - MAXIMUM - MAX_POOL_2D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, TANH, NONE - MAX_POOL_3D, Supported Fused Activation: RELU, RELU6, RELU_N1_TO_1, SIGMOID, SIGN_BIT, TANH, NONE - MEAN - MINIMUM - MIRROR_PAD - MUL - NEG - NOT_EQUAL - PACK - PAD - PADV2 - POW - PRELU - QUANTIZE - RANK - REDUCE_MAX - REDUCE_MIN - REDUCE_PROD - RELU - RELU6 - RELU_N1_TO_1 - RESHAPE - RESIZE_BILINEAR - RESIZE_NEAREST_NEIGHBOR - REVERSEV2 - RSQRT - SHAPE - SIN - SOFTMAX - SPACE_TO_BATCH_ND - SPACE_TO_DEPTH - SPLIT - SPLIT_V - SQRT - SQUARE_DIFFERENCE - SQUEEZE - SLICE - STRIDED_SLICE - SUB - SUM - TANH - TILE - TRANSPOSE - TRANSPOSE_CONV - UNIDIRECTIONAL_SEQUENCE_LSTM - UNPACK More machine learning operators will be supported in future releases. @section delegateoptions Delegate Options The general list of runtime options are described in @subpage runtimeoptions @subsection opaquedelegateoptions Opaque Delegate Options In Opaque Delegate, delegate options are passed via ArmNNSettings which is a FlatBuffer of tflite::TFLiteSettings. Arm NN Settings | Possible Values | Description :--------------- ------------- | :----- | :---------- backends | ["GpuAcc"/"CpuAcc"] | A comma separated list without whitespaces of backends which should be used for execution. Falls back to next backend in list if previous does not provide support for operation. fastmath | [true/false] | Allows the use of optimisation techniques e.g. Winograd that will reduce execution time with the possibility of a drop in accuracy. additional_parameters | JSON string of additional Arm NN delegate options | JSON string of additional Arm NN delegate options. The general list of runtime options are described in [Runtime options](\ref runtimeoptions). **/ }armnn-23.08/docs/05_04_supportlibrary.dox000066400000000000000000000031451446772241200202310ustar00rootroot00000000000000/// Copyright (c) 2022 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page supportlibrary NNAPI Support Library @section supportlibraryintro About the NNAPI Support Library If you need help building the Arm NN NNAPI Support Library, please take a look at our [build guide](shim/BuildGuideShimSupportLibrary.md). @section sloptions Support Library Options The general list of runtime options are described in @subpage runtimeoptions @section slfullysupported Supported Operators The NNAPI Support Library currently supports the following operators: - ABS - ADD - ARGMAX - ARGMIN - AVERAGE_POOL_2D - BATCH_MATMUL - BATCH_TO_SPACE_ND - CAST - CONCATENATION - CONV_2D - DEPTH_TO_SPACE - DEPTHWISE_CONV_2D - DEQUANTIZE - DIV - ELU - EQUAL - EXP - EXPAND_DIMS - FILL - FLOOR - FULLY_CONNECTED - GATHER - GREATER - GREATER_EQUAL - GROUPED_CONV_2D - HARD_SWISH - INSTANCE_NORMALIZATION - L2_NORMALIZATION - L2_POOL_2D - LESS - LESS_EQUAL - LOCAL_RESPONSE_NORMALIZATION - LOG - LOGICAL_AND - LOGICAL_NOT - LOGICAL_OR - LOGISTIC - LOG_SOFTMAX - LSTM - MAX_POOL_2D - MAXIMUM - MEAN - MINIMUM - MUL - NEG - NOT_EQUAL - PAD - PADV2 - PRELU - POW - QUANTIZE - QUANTIZED_LSTM - QUANTIZED_16BIT_LSTM - RANK - REDUCE_MAX - REDUCE_MIN - REDUCE_PROD - REDUCE_SUM - RELU - RELU1 - RELU6 - RESHAPE - RESIZE_BILINEAR - RESIZE_NEAREST_NEIGHBOR - REVERSE - RSQRT - SIN - SOFTMAX - SPACE_TO_BATCH_ND - SPACE_TO_DEPTH - SQRT - SQUEEZE - STRIDED_SLICE - SUB - TILE - TRANSPOSE - TRANSPOSE_CONV_2D - TANH **/ }armnn-23.08/docs/05_05_runtimeoptions.dox000066400000000000000000000273561446772241200202420ustar00rootroot00000000000000/// Copyright (c) 2022 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page runtimeoptions Runtime options for Arm NN Across all software interfaces to Arm NN there are a set of common configuration parameters. These parameters control how a model is loaded or how the inference is executed. The widest set of options are available at the lowest, Arm NN C++ interface. They reduce as you move outward to the TfLite delegate and NNAPI Support Library. The tables below describe the arguments and in which interface they are available. @subsection deviceselection Compute device selection The compute device selected is required to be specified across all interfaces. The device selection will dictate the availability of some parameters and whether some sub graphs are supported. Interface | Device selection :-------- | :---------- Arm NN | The parameter "const std::vector& backendPreferences" to armnn::Optimize provides a vector of backendId's. If multiple devices are specifed the order of the vector dictates the order in which execution will be attempted. If all or part of the model is not supported by a backend, the next in order will be tried. TfLite delegate | armnnDelegate::DelegateOptions Compute device or backend ids: This tells Arm NN which devices will be used to process the inference. A single device can be specified using the armnn::Compute enum. Multiple devices can be specified using a vector of armnn::BackendId. If multiple devices are specifed the order of the vector dictates the order in which execution will be attempted. If all or part of the model is not supported by a backend the next in order will be tried. Valid backend ids are: [EthosNAcc/GpuAcc/CpuAcc/CpuRef] Support Library | armnn_driver::DriverOptions Compute device or backend ids: This tells Arm NN which devices will be used to process the inference. A single device can be specified using the armnn::Compute enum. Multiple devices can be specified using a vector of armnn::BackendId. If multiple devices are specifed the order of the vector dictates the order in which execution will be attempted. If all or part of the model is not supported by a backend the next in order will be tried. Valid backend ids are: [EthosNAcc/GpuAcc/CpuAcc/CpuRef] @subsection runtimeoptions Runtime options There a several levels at which Arm NN accepts runtime parameters. Some of these are specific to an Arm NN instance, some to a loaded network and some to the backend on which a network inference is to execute. Each of the external interfaces handles these options in different ways. @subsection instanceoptions Arm NN Instance level options In the Arm NN C++ interface these options are set by passing an armnn::CreationOptions struct to IRuntime. Not all available options are described here. Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :----- | :---------- m_DynamicBackendsPath | dynamic-backends-path | (Not Available) | String file path | A path in which Arm NN will search for dynamic backends to load. m_ProtectedMode | (Not Available) | (Not Available) | ["true"/"false"] | Setting this flag will allow the user to create the Runtime in protected mode. It will run all the inferences on protected memory and will make sure that INetworkProperties::m_ImportEnabled set to true with MemorySource::DmaBufProtected option. This requires that the backend supports Protected Memory and has an allocator capable of allocating Protected Memory associated with it. m_CustomAllocatorMap | (Not Available) | (Not Available) | std::map> | A map of Custom Allocator used for allocation of working memory in the backends. Required for Protected Mode in order to correctly allocate Protected Memory m_MemoryOptimizerStrategyMap | (Not Available) | (Not Available) | std::map> | A map to define a custom memory optimizer strategy for specific backend Ids. m_GpuAccTunedParameters | gpu-tuning-level | cl-tuning-level | ["0"/"1"/"2"/"3"] | 0=UseOnly(default), 1=RapidTuning, 2=NormalTuning, 3=ExhaustiveTuning. Requires option gpu-tuning-file. 1,2 and 3 will create a tuning-file, 0 will apply the tunings from an existing file (Not Available) | disable-tflite-runtime-fallback | (Not Available) | ["true"/"false"] | Disable TfLite Runtime fallback in the Arm NN TfLite delegate. An exception will be thrown if unsupported operators are encountered. This option is only for testing purposes. armnn::ConfigureLogging | logging-severity | verbose-logging | [Trace/Debug/Info/Warning/Error/Fatal | Set the level of logging information output by Arm NN. armnn::IOptimizedNetworkPtr->SerializeToDot | serialize-to-dot | (Not Available) | String file path | Serialize the optimized network to the file specified in "dot" format. A specific sub-struct of parameters exists to configure external profiling. This is held as a member, m_ProfilingOptions, of CreationOptions Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :----- | :---------- m_ProfilingOptions.m_EnableProfiling | enable-external-profiling | (Not Available) | ["true"/"false"] | Enable external profiling. m_ProfilingOptions.m_TimelineEnabled | timeline-profiling | (Not Available) | ["true"/"false"] | Enable Arm Development studio Timeline events. m_ProfilingOptions.m_OutgoingCaptureFile | outgoing-capture-file | (Not Available) | String file path | Path to a file in which outgoing timeline profiling messages will be stored. m_ProfilingOptions.m_IncomingCaptureFile | incoming-capture-file | (Not Available) | String file path | Path to a file in which incoming timeline profiling messages will be stored. m_ProfilingOptions.m_FileOnly | file-only-external-profiling | (Not Available) | ["true"/"false"] | Enable profiling output to file only. m_ProfilingOptions.m_CapturePeriod | counter-capture-period | (Not Available) | Integer (default : 10000) | Value in microseconds of the profiling capture period. m_ProfilingOptions.m_FileFormat | profiling-file-format | (Not Available) | String of ["binary"] | The format of the file used for outputting profiling data. Currently on "binary" is supported. @subsection networkoptions NetworkOptions During Network creation you can specify several optional parameters via armnn::NetworkOptions. Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :----- | :---------- ShapeInferenceMethod | infer-output-shape | (Not Available) | ["true"/"false"] | Infers output tensor shape from input tensor shape and validate where applicable. AllowExpandedDims | allow-expanded-dims | (Not Available) | ["true"/"false"] | If true will disregard dimensions with a size of 1 when validating tensor shapes. Tensor sizes must still match. This is an Experimental parameter that is incompatible with infer-output-shape. profilingEnabled | enable-internal-profiling | enable-internal-profiling | ["true"/"false"] | Enable json profiling in CpuAcc and GpuAcc backends. detailsMethod | internal-profiling-detail | (Not Available) | ProfilingDetailsMethod | Set the detail of internale porfiling. Options are DetailsWithEvents and DetailsOnly. @subsection optimizeroptions OptimizerOptions OptimizerOptions are a set of parameters specifically targeting the Arm NN optimizer. This executes when a model is being loaded and these parameters are used to tune its operation. Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :----- | :---------- reduceFp32ToFp16 | reduce-fp32-to-fp16 | (Not available) | ["true"/"false"] | Note This feature works best if all operators of the model are in Fp32. ArmNN will add conversion layers between layers that weren't in Fp32 in the first place or if the operator is not supported in Fp16. The overhead of these conversions can lead to a slower overall performance if too many conversions are required. reduceFp32ToBf16 | reduce-fp32-to-bf16 | (Not available) | ["true"/"false"] | This feature has been replaced by enabling Fast Math in compute library backend options. This is currently a placeholder option debug | debug-data | (Not available) | ["true"/"false"] | If the debug flag is set a DebugLayer is inserted after each layer. The action of each debug layer is backend specific. importEnabled | memory-import | (Not available) | ["true"/"false"] | Instructs the optimizer that this model will be importing it's input tensors. This value must match the MemorySource set for input in INetworkProperties. exportEnabled | (Not available) | (Not available) | ["true"/"false"] | Instructs the optimizer that this model will be exporting it's output tensors. This value must match the MemorySource set for output in INetworkProperties. @subsection modeloptions OptimizerOptions::ModelOptions Model options is a vector of name value pairs contained inside OptimizerOptions. The options specifically target backends. @subsection gpuaccmodeloptions GpuAcc backend model options Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :----- | :---------- FastMathEnabled | enable-fast-math | enable-fast-math | ["true"/"false"] | Enables fast_math options in backends that support it. SaveCachedNetwork| save-cached-network |save-cached-network | ["true"/"false"] | Enables saving the cached network to the file given with cached-network-file option. CachedNetworkFilePath| cached-network-filepath |cached-network-file | String file path | If non-empty, the given file will be used to load/save cached network. If save-cached-network option is given will save the cached network to given file. If save-cached-network option is not given will load the cached network from given file. MLGOTuningFilePath |gpu-mlgo-tuning-file | mlgo-cl-tuned-parameters-file | String file path | If non-empty, the given file will be used to load/save MLGO CL tuned parameters. KernelProfilingEnabled | gpu-kernel-profiling-enabled | (Not available) | ["true"/"false"] | Enables GPU kernel profiling @subsection cpuaccmodeloptions CpuAcc backend model options Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :--- | :---------- FastMathEnabled | enable-fast-math | enable-fast-math | ["true"/"false"] | Enables fast_math options in backends that support it. NumberOfThreads | number-of-threads | number-of-threads | Integer [1-64] | Assign the number of threads used by the CpuAcc backend. Input value must be between 1 and 64. Default is set to 0 (Backend will decide number of threads to use). @subsection ethosnmodeloptions EthosNAcc backend model options Arm NN Parameter | Delegate | Support library | Values | Description :--------------- | :-------- | :-------------- | :--- | :---------- DisableWinograd | (Not available) | (Not available) | ["true"/"false"] | Disables Winograd fast convolution. StrictPrecision | (Not available) | (Not available) | ["true"/"false"] | When enabled the network is more precise as the Re-quantize operations aren't fused, but it is slower to compile as there will be additional operations. This is currently only supported for the Concat operation. SaveCachedNetwork| save-cached-network |save-cached-network | ["true"/"false"] | Enables saving the cached network to the file given with cached-network-file option. CachedNetworkFilePath| cached-network-filepath |cached-network-file | String file path | If non-empty, the given file will be used to load/save cached network. If save-cached-network option is given will save the cached network to given file. If save-cached-network option is not given will load the cached network from given file. **/ }armnn-23.08/docs/05_06_deserializer.dox000066400000000000000000000034301446772241200176110ustar00rootroot00000000000000/// Copyright (c) 2021-2023 ARM Limited and Contributors. All rights reserved. /// /// SPDX-License-Identifier: MIT /// namespace armnn { /** @page deserializer Deserializer The `armnnDeserializer` is a library for loading neural networks defined by Arm NN FlatBuffers files into the Arm NN runtime. @section deserializersupport Supported Layers The Arm NN SDK Deserialize parser currently supports the following layers: - Abs - Activation - Addition - ArgMinMax - BatchMatMul - BatchToSpaceNd - BatchNormalization - Cast - ChannelShuffle - Concat - Comparison - Constant - Convolution2d - DepthToSpace - DepthwiseConvolution2d - Dequantize - DetectionPostProcess - Division - ElementwiseUnary - Fill - Floor - FullyConnected - Gather - GatherNd - Input - InstanceNormalization - L2Normalization - Logical - LogSoftmax - Lstm - Maximum - Mean - Merge - Minimum - Multiplication - Normalization - Output - Pad - Permute - Pooling2d - Pooling3d - Prelu - Quantize - QLstm - QuantizedLstm - Rank - Reduce - Reshape - Resize - ResizeBilinear - ReverseV2 - Slice - Softmax - SpaceToBatchNd - SpaceToDepth - Splitter - Stack - StandIn - StridedSlice - Subtraction - Switch - Transpose - TransposeConvolution2d - UnidirectionalSequenceLstm More machine learning layers will be supported in future releases. @section deserializersupportdeprecated Deprecated layers Some layers have been deprecated and replaced by others layers. In order to maintain backward compatibility, serializations of these deprecated layers will deserialize to the layers that have replaced them, as follows: - Equal will deserialize as Comparison - Merger will deserialize as Concat - Greater will deserialize as Comparison - ResizeBilinear will deserialize as Resize **/ } armnn-23.08/docs/Arm_NN_horizontal_blue.png000066400000000000000000000402341446772241200207050ustar00rootroot00000000000000PNG  IHDRwTd+ pHYsgRYiTXtXML:com.adobe.xmp v*9IDATxg!B1%mZQ_C =Zh C 5PL ^ Qbzz `lm~82^ֻ+)=ϝ{Gw==6050L^u$,xk5X y9\gj+R} Q50p4I`,pUe;"s \SJ)TzFrG$tlj`4qB̎$uG%x2pXTJ)T y|`f LIitykV\ |J)j@&w? 8Єٞun\iksORJ)TZ/ـ+-GW -[:7ļO\ļǧHw#+#-ɢZxPRJ)Ո|=QLnDNҪl`ш|XΏ!(<"468T`fJ)jP~;Y{ X8G=p 8Y25 $Z۵ǁ]qW 沁ˈy [qJ)2n;Hs.[f82u F^ r+ags*Ray>Ps1g:GJ\gH6v0b\gȽr]kiRٟl:f(RJ>;ϟXp=@j4.&Qi1Ǒ-1O5SJ)RN6kbE] ;,܍3=:-]G9OʵǺJ)JI^ ?1]Ed$il/p Y>`Ҹ[ o#J)Tnykcu]qtmi?++Z68RJ)&wK\,~Jq֏3;~Z)ܨRC)R@;Tf11g:tuz' "_*R)crz+ Z3ڴ[mkRJ:yLf۽8M+kK-5IoSB)RLLʏ?q|JtuZ,(AӟRJ) /V& ifx}ҵ+KC FĭRJ)CK׮K)M -(5X/80RJ)53z=<N>x]{@i84nRJkr&!Iwpw;^_M[ճ7?O$RJ)krVQC>`Q%2w^>6sIH|?k\DWJ)TܹǘLm {n_g8sWyc G5RJ)gr'0h<H3z㘗W^J)2:%!6<o7<=ޭqWUFS6_qMͯRJ)Z%BfF; U<췛t):f0RJ)iN;MArX 9יĹRJ)Յ~YPo "͟ ڄjF\&̩RJ)y[ %N]p5Ł9k> i_;Q%O1jrHo݅AH: iIQ\dVJ)T g8s`q\g|1Mw-b8/RJ,wϝ/l7udN[p3)ĢRJ7Ӏ $>pz'sD7*_ ajVRJ)|&wvFVeqo8fD+}r x(jBt@Xʪ`}K)K%N=d8\gbpd`i\Db.45 |BDy0`C5s;u%\ l=%ledHFfvWWpϛfd0ҹgA` L<<|؄xK 0<0i%ru LK=r-'sP,4BXZ)y,z`h`ωQM\XX9Un_ {mLjxς<9_uLi9P,MVGfH  E: Y{dOi?U >>Bbpu1ΞeiuJxq-4׮io?OBWA Œiɵ60m[cD$#v.uM4_:'(M79X`͸;)K?83.KZ<,J5btfE)4@_]I$&un|QQ L~1F)|bѲde\wH `i^<un< ip ?QhObHly7QpUX$@Z+ RO;mr0/&֮mHOAtTsX7PX?sZM/d<7^+K3?Vy#?h41뼄yG3kGeMS)JlԳ!PA7bƽѾJt@Bjց=_>wKd_>Fa }9u1j 'b^Qq"#mWOh6Z@\(V:BtlAĕF6Cj͂xxי~Z?ܘP\K<$2q9q1oMs֮ xRSLC΅fG0~|xꭿFjʩKP]Z _y @4I֩VѻJYUNM$^K)^[6dvI1SG?Vߘ##ZFK@>gz&.: 6,B>Z=ުN/KV+ $hɝ/00)(3u |qr)x@pɞaֆlq }}?ςZ8 |JcId*ҭ if :oWm* 7/4^A܈t/TVG&q"3ҷk ʪB]R9@L4IwNYTr>_v@ryYʷ Jl s!#BJuxI :!<adu &:ow{lѩFͣ.^:?W %z6K9ӳq)ub{ϿdV[1)cڐ"ǛW+廳Q#YH|PuP-kA<%v-T¿=np>ppM\=\ dkQ7:M\k\矸ΊHw!bnO`]{3YMs$3>\GLwi # _J,I1իiS25O<dB5rq<(^ʯ hn~? ¼F ;IX6~ljƓ̇:[F :7:IJX`H_]g*3?/i%\H~ 1Oqo޼k5ee$3;y՝b)m1C 9hfS#nOZ{#p3A͡$`c\Ǵfc}3  lA \e&ta;3-\["aؽ]r@,&pU+2zZb?CZߥR<'w.=x\ۗ/rjF`ŬC:N័GY?Y:sgsvcs97]뜕u)> |}{4{%q*yDHERr[M9=t\:ٯhRfN<( / UVKyr R/7g/a)ۑu%ۦQ9akeЦ̕/zg=}ΣI^ȽđVf LZ)_ *K{<߃77G@_@]As7b#oY3880: ܄Zf9Nw":C'pVdt&y6ω-S~̘`By-{M?Ij|u.P,m1ij:Cӏ\D*N:#⼖Y<meakl .0HNgvY,M²7vI$x0O&&|$ܒt9~DHYRgWZwn⪕k&[BلNHqQR~P,mC'Hrվ;|٨VC LuF ̞a>NY9h(:g7 u^u@GϳUfwA2m':$v3lTZ=8Dlsa|HJ!_j{So$ \gb"Rܸr`>zN)KLU+N =/5)t`}\=3h Zx⑽O;Dy> cHuVɝϗ(EXVWdmcw?;khݚJ=h<1wzA riJV\q&$uJy.?P,rHVA+)c桤n'q?[:񾹺9HiS&aK̗߯Fm):Wğ>C [pŠmk*NÑC y,WnJ"9_:}~x7(fViJT" |n^\(K9\VʷXVeiCVLܟP !mL$QfׇrWhNQ{bsk=$]wb, Θ Y6JʐwSY]W"}SWDV=5i./Ky횉ZFZn\e׆I<7IW[FQm8o~hX`fs3}ĶLWۺf[_""MLqqI%q3|dqO} j޿Huҏ*4Vww;`LV5ېr&F'Ԓfy 9)j"Fs`v"e>h{{CwLKiº Ҩa")đ]ܲ:ix!*RlK3JY~)'R'!ឭsiBdYߣT+3i@& Ӑ}difu386B 5gp}{} z<lk pᨼ;zMvnYl:~^7Yj%<6~ݿ݅biʯj| \)Չj4{,4poXߗ&xΥӬo>CO&5$(¸ޟh3c'&BϷY>V]8(PJVʏ"IKR9+ lGOJy"҂^MYGf=ۤRD3kxbxSB`i[?ap/E.8%ӟoD+M$d+rZ)?୊$-U>j44@qv!ڀ' xCz_Dc1[Z OcPMqgif@ŭS\A$̤еR*G_ nmB4 V3Dc5Mf`~Iy( U+sF~r8VeKBB¸l+0r ?abA؏ 9mDlqlD x,ȿTRkC ӎ'ϪSӔFjf`SVxC"M--jAGU%=R25}p#. \@s/C2qlRȡ;2 H|n`Ok%VR#p7{ߊdypd{ƝR=~lHѝ j|v!SR Ҧg{w.W.K׊#:/)P,rHVGLsQJt|Dx>(0d]Gu]x$-"+ny7UA4DhcFyyRMWPm9mH @f^ \1/3ows&6y`MV9wqlGrbTasjAzƵ%߼DKY݀lPJoc~lCVO?V4pvE <:X(4_\g!}dۗO8N=n鱭 h|ڞLkfuܪx_Wݝ>י_#^ieGa#O:x0ComMAV@"z? #!O_u&n6oo"l%q ¥h0cGb[%ŐH"-B. yBy?i駔R-Z)W R Izzbi#iIÒۀ/-^3H_SS|ZSN=>(ItF7/pP20Ykqxۺvs'dRJVO֒Y'Ϫj@qi=$u1t1o>A9}lA ᨩ_o>IamE)LU+Gܫ =kLFa ۊ~׶Kfgo6wV= ٯZ~ )ʝj|A; kr%i۪~G!{MD} ,j8f#Z}# y'Jv\=iW${E+:VʗdG+V#?:MzmEyI` 9 9jUrV7dJ'uzJTªhJMdo{ #w&[R#w%WH4Dy`M,3u8*)VʧHYER)57MQ[zmt8=Hg}UZRaީߵJ\R} X9%RQ$Y=HR~Igu/jRe)c)8dbQӹ۸Uio:O6q^Tq pqAjJ$Wĸ pT>j[a^4lk ? t(1uePE:#oyi|)srPwMշI84}'%H'ޣa}Bׯg?U+ibiov [j`XZ-^Gik{b[Qn 970o| u|qaπű)Sxjfno* \>?ϟ;?:/QJϟ iaV@YHy:\513uR)KRJirW_XD^RsAxXp5֟n55*}?\R(KU+mabi&we_ G ,m5`<a1?#ƶM+RJ)Dz.܏ԣ+TpXǥ"&0ۚ#pykTĶ>@V+XQTJ)Tca20{`gl+[eNJݸ u%QkY_)Rkra[o'ñHب hel롄cOiԬj ǠRJvܙ:/K<-ox9G _.4\q(RgyMF\eQ^ow\&%b&"5p|RJ^']4DJti0P*Qtnakƶ&mbRJ)e(nx}zM\ȷ#H+NNilN?_RJcrgG6ӟ]AE13$)?\RJ)δIɂI]jQ$a3MMikRJ:yL1>=\A8;0`iq<.MZADPJ)T>1[Z)@"TG׮Th \f0$nRJ_r'L6BΛR4^Z*QtUk&^H)u܉qvI<  `8$^4~# G78RJ)&w^Ah7s\!F1taL.p cM'фcPJ)T;=% 87كp)HQ$6cG_dkׂpn_󧱭K(RZ>;zxpvၱy[#= zՀc G^{nRJu+ɝ"˜3 C" #ݕN^y/lÑN)J]O"; hTn< ,aN2-m=<5'#FFN9>0N)Rҩ}Y;-e+] R@`|2)* ydql.IżtSV=nRJ^/ݬHybd$ GYb{l''jZ{ uYXga[żRJ) KYх'ձ2B>OD5 Kb[vL)j<U7'v*atb*&vJ)T?OdD;?;c[oelBJmibRZ#ŶbHӮYQsuzA(RMk$w%P¼j¶8I9kBcPJ)z(<_Mלt6ُ`^RJъPp"phf jKF4a/{0RJ)КtA0JWFLFǷ \'V\<49RJ)ՀN`*_+NnDλ[ l , c S)R1~r7$y; mE˻X_V`t I:NA9ҲrlSJ)TzNr^FC , ]0K*v!l륦ǚi*6,ҎmX$}55RJ)Հ·mH vIENDB`armnn-23.08/docs/Arm_NN_horizontal_blue.png.license000066400000000000000000000001461446772241200223240ustar00rootroot00000000000000# # Copyright © 2020 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # armnn-23.08/docs/Doxyfile000066400000000000000000003277131446772241200153250ustar00rootroot00000000000000# Doxyfile 1.8.17 # Copyright (c) 2018, 2020-2023 ARM Ltd and Contributors. All rights reserved. # # SPDX-License-Identifier: MIT # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "Arm NN" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = 23.08 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = ./docs/Arm_NN_horizontal_blue.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = docs/ # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = Yes # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 0. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = YES # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. #HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. #SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = YES # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line:[DOXY_WARN] $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = ./docs/01_00_quick_start.dox \ ./docs/02_operator_list.dox \ ./docs/03_build_guides.dox \ ./docs/04_contributor.dox \ ./docs/05_00_software_components.dox \ ./docs/05_01_parsers.dox \ ./docs/05_02_serializer.dox \ ./docs/05_03_delegate.dox \ ./docs/05_04_supportlibrary.dox \ ./docs/05_05_runtimeoptions.dox \ ./docs/05_06_deserializer.dox \ ./docs/FAQ.md \ ./tests/ImageCSVFileGenerator/README.md \ ./tests/ImageTensorGenerator/README.md \ ./tests/ModelAccuracyTool-Armnn/README.md \ ./python/pyarmnn/README.md \ ./include/ \ ./src/ \ ./src/armnnConverter/README.md \ ./src/backends/README.md \ ./src/dynamic/README.md \ ./delegate/classic/include \ ./delegate/opaque/include \ ./delegate/classic/src/armnn_external_delegate.cpp \ ./delegate/opaque/src/armnn_external_delegate.cpp \ ./delegate/BuildGuideNative.md \ ./delegate/DelegateQuickStartGuide.md \ ./shim/ \ ./shim/BuildGuideShimSupportLibrary.md \ ./shim/sl/ \ ./shim/sl/canonical/ \ ./README.md \ ./InstallationViaAptRepository.md \ ./CONTRIBUTING.md \ ./BuildGuideAndroidNDK.md \ ./samples/examples.dox # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, # *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. FILE_PATTERNS = *.cpp \ *.inl \ *.h \ *.hpp \ *.md \ *.dox \ *.py # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = ./include/armnnTestUtils \ ./tests/ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = *.md EXCLUDE_PATTERNS += */test/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = caffe tensorflow cl armcomputetensorutils # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = ./samples/ # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = ./docs/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = ./README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse-libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = -std=c++11 #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = ./docs/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = ./docs/customdoxygen.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /