From 839b9329611ecc148d6547920cec7b105fc5660f Mon Sep 17 00:00:00 2001 From: Cathal Corbett Date: Fri, 18 Nov 2022 08:52:18 +0000 Subject: IVGCVSW-6980 Delegate support for slice operator Signed-off-by: Cathal Corbett Change-Id: I90d800160b070e25d999b5102a7ce6d3e0ed6a81 --- delegate/CMakeLists.txt | 2 + delegate/src/Slice.hpp | 49 ++---- delegate/src/StridedSlice.hpp | 146 ++++++++++++++++ delegate/src/armnn_delegate.cpp | 11 +- delegate/src/test/SliceTest.cpp | 230 ++++--------------------- delegate/src/test/SliceTestHelper.hpp | 179 +++++++------------- delegate/src/test/StridedSliceTest.cpp | 241 +++++++++++++++++++++++++++ delegate/src/test/StridedSliceTestHelper.hpp | 218 ++++++++++++++++++++++++ src/armnnTfLiteParser/test/Slice.cpp | 6 +- 9 files changed, 729 insertions(+), 353 deletions(-) create mode 100644 delegate/src/StridedSlice.hpp create mode 100644 delegate/src/test/StridedSliceTest.cpp create mode 100644 delegate/src/test/StridedSliceTestHelper.hpp diff --git a/delegate/CMakeLists.txt b/delegate/CMakeLists.txt index 847a8a0be5..fe5c962321 100644 --- a/delegate/CMakeLists.txt +++ b/delegate/CMakeLists.txt @@ -202,6 +202,8 @@ if(BUILD_UNIT_TESTS) src/test/ShapeTestHelper.hpp src/test/SliceTest.cpp src/test/SliceTestHelper.hpp + src/test/StridedSliceTest.cpp + src/test/StridedSliceTestHelper.hpp src/test/SplitTest.cpp src/test/SplitTestHelper.hpp src/test/TestUtils.hpp diff --git a/delegate/src/Slice.hpp b/delegate/src/Slice.hpp index 6e355ae741..cbcb45ec65 100644 --- a/delegate/src/Slice.hpp +++ b/delegate/src/Slice.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2020 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -21,10 +21,10 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, int nodeIndex, int32_t sliceOperatorCode) { - TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 4, nodeIndex)); + TF_LITE_ENSURE_STATUS(ValidateNumInputs(tfLiteContext, tfLiteNode, 3, nodeIndex)); TF_LITE_ENSURE_STATUS(ValidateNumOutputs(tfLiteContext, tfLiteNode, 1, nodeIndex)); - // Read inputs [input, begin, end, strides] + // Read inputs [input, begin, size] int numInputs = tfLiteNode->inputs->size; std::vector tfLiteInputs; tfLiteInputs.reserve(numInputs); @@ -39,15 +39,15 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, } } - // We save the begin, end and strides tensors in our descriptor. Therefore we have to read those values from inputs + // 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) -> TfLiteStatus + 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 " + "TfLiteArmnnDelegate: The Begin- and Size-Tensors of the Slice operation need to " "be of type int32. Operator: #%d node #%d: ", sliceOperatorCode, nodeIndex); return kTfLiteError; @@ -57,7 +57,7 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, { TF_LITE_MAYBE_KERNEL_LOG( tfLiteContext, - "TfLiteArmnnDelegate: The Begin-, End- and Stride-Tensors of the StridedSlice operation need to " + "TfLiteArmnnDelegate: The Begin- and Size-Tensors of the Slice operation need to " "be a 1D-Tensor. Operator: #%d node #%d: ", sliceOperatorCode, nodeIndex); return kTfLiteError; @@ -67,41 +67,26 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, { 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: ", + "TfLiteArmnnDelegate: The number of values in the Begin- and Size-Tensors of the " + "Slice 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]); + auto* tensorDataPtr = tflite::GetTensorData(tfLiteInputs[inputIndex]); outputData.assign(tensorDataPtr, tensorDataPtr+numValues); return kTfLiteOk; }; - std::vector beginData; - if (ReadInt32Input(1, beginData) != kTfLiteOk) + std::vector begin; + if (ReadInt32Input(1, begin) != kTfLiteOk) return kTfLiteError; - std::vector endData; - if (ReadInt32Input(2, endData) != kTfLiteOk) + std::vector size; + if (ReadInt32Input(2, size) != 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; + armnn::SliceDescriptor descriptor(begin, size); // Validate output const TfLiteTensor& tfLiteOutputTensor = tfLiteTensors[tfLiteNode->outputs->data[0]]; @@ -118,7 +103,7 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, { FORWARD_LAYER_SUPPORT_FUNC("SLICE", tfLiteContext, - IsStridedSliceSupported, + IsSliceSupported, delegateData.m_Backends, isSupported, inputTensorInfo, @@ -133,7 +118,7 @@ TfLiteStatus VisitSliceOperator(DelegateData& delegateData, } // Add a StridedSlice layer - armnn::IConnectableLayer* layer = delegateData.m_Network->AddStridedSliceLayer(descriptor); + armnn::IConnectableLayer* layer = delegateData.m_Network->AddSliceLayer(descriptor); ARMNN_ASSERT(layer != nullptr); armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); diff --git a/delegate/src/StridedSlice.hpp b/delegate/src/StridedSlice.hpp new file mode 100644 index 0000000000..515c819ffe --- /dev/null +++ b/delegate/src/StridedSlice.hpp @@ -0,0 +1,146 @@ +// +// Copyright © 2022 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; + auto validateFunc = [&](const armnn::TensorInfo& outInfo, bool& isSupported) + { + FORWARD_LAYER_SUPPORT_FUNC("STRIDED_SLICE", + tfLiteContext, + IsStridedSliceSupported, + delegateData.m_Backends, + isSupported, + inputTensorInfo, + outInfo, + descriptor); + }; + + if (!delegateData.m_Network) + { + validateFunc(outputTensorInfo, isSupported); + return isSupported ? kTfLiteOk : kTfLiteError; + } + + // Add a StridedSlice layer + armnn::IConnectableLayer* layer = delegateData.m_Network->AddStridedSliceLayer(descriptor); + ARMNN_ASSERT(layer != nullptr); + + armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(0); + outputSlot.SetTensorInfo(outputTensorInfo); + + // Connect + return Connect(layer, tfLiteNode, delegateData); +} + +} // namespace armnnDelegate diff --git a/delegate/src/armnn_delegate.cpp b/delegate/src/armnn_delegate.cpp index b2ad16051f..4d95522dbd 100644 --- a/delegate/src/armnn_delegate.cpp +++ b/delegate/src/armnn_delegate.cpp @@ -34,6 +34,7 @@ #include "Round.hpp" #include "Shape.hpp" #include "Slice.hpp" +#include "StridedSlice.hpp" #include "Softmax.hpp" #include "SpaceDepth.hpp" #include "Split.hpp" @@ -963,12 +964,18 @@ TfLiteStatus ArmnnSubgraph::VisitNode(DelegateData& delegateData, tfLiteNode, nodeIndex, kTfLiteBuiltinSqueeze); - case kTfLiteBuiltinStridedSlice: + case kTfLiteBuiltinSlice: return VisitSliceOperator(delegateData, tfLiteContext, tfLiteNode, nodeIndex, - kTfLiteBuiltinStridedSlice); + kTfLiteBuiltinSlice); + case kTfLiteBuiltinStridedSlice: + return VisitStridedSliceOperator(delegateData, + tfLiteContext, + tfLiteNode, + nodeIndex, + kTfLiteBuiltinStridedSlice); case kTfLiteBuiltinSum: return VisitReduceOperator(delegateData, tfLiteContext, diff --git a/delegate/src/test/SliceTest.cpp b/delegate/src/test/SliceTest.cpp index bd0584936e..1d7133f1fd 100644 --- a/delegate/src/test/SliceTest.cpp +++ b/delegate/src/test/SliceTest.cpp @@ -1,5 +1,5 @@ // -// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -8,236 +8,74 @@ #include #include -#include #include namespace armnnDelegate { -void StridedSlice4DTest(std::vector& backends) +void SliceFixtureSimpleTest(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 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, 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 - ); -} + std::vector outputData { 3.0f, 3.0f, 3.0f, + 5.0f, 5.0f, 5.0f }; -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 - ); + SliceTestImpl( + backends, + inputData, + outputData, + beginData, + sizeData, + inputShape, + beginShape, + sizeShape, + outputShape); } -void StridedSliceSimpleRangeMaskTest(std::vector& backends) +TEST_SUITE("Slice_CpuRefTests") { - 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") +TEST_CASE ("Slice_Simple_CpuRef_Test") { std::vector backends = {armnn::Compute::CpuRef}; - StridedSliceSimpleRangeMaskTest(backends); + SliceFixtureSimpleTest(backends); } -} // StridedSlice_CpuRefTests TestSuite - +} // Slice_CpuRefTests TestSuite -TEST_SUITE("StridedSlice_CpuAccTests") -{ -TEST_CASE ("StridedSlice_4D_CpuAcc_Test") +TEST_SUITE("Slice_CpuAccTests") { - std::vector backends = {armnn::Compute::CpuAcc}; - StridedSlice4DTest(backends); -} -TEST_CASE ("StridedSlice_4D_Reverse_CpuAcc_Test") +TEST_CASE ("Slice_Simple_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); + std::vector backends = {armnn::Compute::CpuRef}; + SliceFixtureSimpleTest(backends); } -} // StridedSlice_CpuAccTests TestSuite +} // Slice_CpuAccTests TestSuite TEST_SUITE("StridedSlice_GpuAccTests") { -TEST_CASE ("StridedSlice_4D_GpuAcc_Test") +TEST_CASE ("Slice_Simple_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); + std::vector backends = {armnn::Compute::CpuRef}; + SliceFixtureSimpleTest(backends); } -} // StridedSlice_GpuAccTests TestSuite +} // Slice_GpuAccTests TestSuite } // namespace armnnDelegate \ No newline at end of file diff --git a/delegate/src/test/SliceTestHelper.hpp b/delegate/src/test/SliceTestHelper.hpp index abaa807aed..4a2537feec 100644 --- a/delegate/src/test/SliceTestHelper.hpp +++ b/delegate/src/test/SliceTestHelper.hpp @@ -1,5 +1,5 @@ // -// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// Copyright © 2022 Arm Ltd and Contributors. All rights reserved. // SPDX-License-Identifier: MIT // @@ -24,61 +24,27 @@ namespace { -struct StridedSliceParams -{ - StridedSliceParams(std::vector& inputTensorShape, - std::vector& beginTensorData, - std::vector& endTensorData, - std::vector& strideTensorData, - std::vector& outputTensorShape, - armnn::StridedSliceDescriptor& descriptor) - : m_InputTensorShape(inputTensorShape), - m_BeginTensorData(beginTensorData), - m_EndTensorData(endTensorData), - m_StrideTensorData(strideTensorData), - m_OutputTensorShape(outputTensorShape), - m_Descriptor (descriptor) {} - - std::vector m_InputTensorShape; - std::vector m_BeginTensorData; - std::vector m_EndTensorData; - std::vector m_StrideTensorData; - std::vector m_OutputTensorShape; - armnn::StridedSliceDescriptor m_Descriptor; -}; - std::vector CreateSliceTfLiteModel(tflite::TensorType tensorType, const std::vector& inputTensorShape, const std::vector& beginTensorData, - const std::vector& endTensorData, - const std::vector& strideTensorData, + const std::vector& sizeTensorData, 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) + const std::vector& sizeTensorShape, + const std::vector& outputTensorShape) { using namespace tflite; flatbuffers::FlatBufferBuilder flatBufferBuilder; - std::array, 4> buffers; + std::array, 3> buffers; buffers[0] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector({})); buffers[1] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector(reinterpret_cast(beginTensorData.data()), sizeof(int32_t) * beginTensorData.size())); buffers[2] = CreateBuffer(flatBufferBuilder, - flatBufferBuilder.CreateVector(reinterpret_cast(endTensorData.data()), - sizeof(int32_t) * endTensorData.size())); - buffers[3] = CreateBuffer(flatBufferBuilder, - flatBufferBuilder.CreateVector(reinterpret_cast(strideTensorData.data()), - sizeof(int32_t) * strideTensorData.size())); + flatBufferBuilder.CreateVector(reinterpret_cast(sizeTensorData.data()), + sizeof(int32_t) * sizeTensorData.size())); - std::array, 5> tensors; + std::array, 4> tensors; tensors[0] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(inputTensorShape.data(), inputTensorShape.size()), @@ -92,18 +58,12 @@ std::vector CreateSliceTfLiteModel(tflite::TensorType tensorType, 1, flatBufferBuilder.CreateString("begin_tensor")); tensors[2] = CreateTensor(flatBufferBuilder, - flatBufferBuilder.CreateVector(endTensorShape.data(), - endTensorShape.size()), + flatBufferBuilder.CreateVector(sizeTensorShape.data(), + sizeTensorShape.size()), ::tflite::TensorType_INT32, 2, - flatBufferBuilder.CreateString("end_tensor")); + flatBufferBuilder.CreateString("size_tensor")); tensors[3] = CreateTensor(flatBufferBuilder, - flatBufferBuilder.CreateVector(strideTensorShape.data(), - strideTensorShape.size()), - ::tflite::TensorType_INT32, - 3, - flatBufferBuilder.CreateString("stride_tensor")); - tensors[4] = CreateTensor(flatBufferBuilder, flatBufferBuilder.CreateVector(outputTensorShape.data(), outputTensorShape.size()), tensorType, @@ -112,45 +72,40 @@ std::vector CreateSliceTfLiteModel(tflite::TensorType tensorType, // 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 }; + 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, 3 }; - const std::vector subgraphOutputs{ 4 }; + 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)); + 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"); + flatBufferBuilder.CreateString("ArmnnDelegate: Slice Operator Model"); flatbuffers::Offset operatorCode = CreateOperatorCode(flatBufferBuilder, - BuiltinOperator_STRIDED_SLICE); + BuiltinOperator_SLICE); flatbuffers::Offset flatbufferModel = - CreateModel(flatBufferBuilder, - TFLITE_SCHEMA_VERSION, - flatBufferBuilder.CreateVector(&operatorCode, 1), - flatBufferBuilder.CreateVector(&subgraph, 1), - modelDescription, - flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); + CreateModel(flatBufferBuilder, + TFLITE_SCHEMA_VERSION, + flatBufferBuilder.CreateVector(&operatorCode, 1), + flatBufferBuilder.CreateVector(&subgraph, 1), + modelDescription, + flatBufferBuilder.CreateVector(buffers.data(), buffers.size())); flatBufferBuilder.Finish(flatbufferModel); @@ -159,62 +114,46 @@ std::vector CreateSliceTfLiteModel(tflite::TensorType tensorType, } 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) +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 tflite; std::vector modelBuffer = CreateSliceTfLiteModel( - ::tflite::TensorType_FLOAT32, - inputTensorShape, - beginTensorData, - endTensorData, - strideTensorData, - beginTensorShape, - endTensorShape, - strideTensorShape, - outputTensorShape, - beginMask, - endMask, - ellipsisMask, - newAxisMask, - ShrinkAxisMask, - dataLayout); + ::tflite::TensorType_FLOAT32, + inputTensorShape, + beginTensorData, + sizeTensorData, + beginTensorShape, + sizeTensorShape, + outputTensorShape); auto tfLiteModel = GetModel(modelBuffer.data()); // Create TfLite Interpreters std::unique_ptr armnnDelegate; CHECK(InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver()) - (&armnnDelegate) == kTfLiteOk); + (&armnnDelegate) == kTfLiteOk); CHECK(armnnDelegate != nullptr); CHECK(armnnDelegate->AllocateTensors() == kTfLiteOk); std::unique_ptr tfLiteDelegate; CHECK(InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver()) - (&tfLiteDelegate) == kTfLiteOk); + (&tfLiteDelegate) == kTfLiteOk); CHECK(tfLiteDelegate != nullptr); CHECK(tfLiteDelegate->AllocateTensors() == kTfLiteOk); // Create the ArmNN Delegate armnnDelegate::DelegateOptions delegateOptions(backends); std::unique_ptr - theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), - armnnDelegate::TfLiteArmnnDelegateDelete); + theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), + armnnDelegate::TfLiteArmnnDelegateDelete); CHECK(theArmnnDelegate != nullptr); // Modify armnnDelegateInterpreter to use armnnDelegate @@ -236,6 +175,6 @@ void StridedSliceTestImpl(std::vector& backends, tfLiteDelegate.reset(nullptr); armnnDelegate.reset(nullptr); -} // End of StridedSlice Test +} // End of Slice Test } // anonymous namespace \ No newline at end of file diff --git a/delegate/src/test/StridedSliceTest.cpp b/delegate/src/test/StridedSliceTest.cpp new file mode 100644 index 0000000000..43aea8a449 --- /dev/null +++ b/delegate/src/test/StridedSliceTest.cpp @@ -0,0 +1,241 @@ +// +// Copyright © 2022 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 armnnDelegate \ No newline at end of file diff --git a/delegate/src/test/StridedSliceTestHelper.hpp b/delegate/src/test/StridedSliceTestHelper.hpp new file mode 100644 index 0000000000..2bca4fdc35 --- /dev/null +++ b/delegate/src/test/StridedSliceTestHelper.hpp @@ -0,0 +1,218 @@ +// +// Copyright © 2022 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 + +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; + + std::array, 4> buffers; + buffers[0] = CreateBuffer(flatBufferBuilder, flatBufferBuilder.CreateVector({})); + buffers[1] = CreateBuffer(flatBufferBuilder, + flatBufferBuilder.CreateVector(reinterpret_cast(beginTensorData.data()), + sizeof(int32_t) * beginTensorData.size())); + buffers[2] = CreateBuffer(flatBufferBuilder, + flatBufferBuilder.CreateVector(reinterpret_cast(endTensorData.data()), + sizeof(int32_t) * endTensorData.size())); + buffers[3] = CreateBuffer(flatBufferBuilder, + flatBufferBuilder.CreateVector(reinterpret_cast(strideTensorData.data()), + sizeof(int32_t) * strideTensorData.size())); + + std::array, 5> tensors; + tensors[0] = CreateTensor(flatBufferBuilder, + flatBufferBuilder.CreateVector(inputTensorShape.data(), + inputTensorShape.size()), + tensorType, + 0, + flatBufferBuilder.CreateString("input")); + tensors[1] = CreateTensor(flatBufferBuilder, + flatBufferBuilder.CreateVector(beginTensorShape.data(), + beginTensorShape.size()), + ::tflite::TensorType_INT32, + 1, + flatBufferBuilder.CreateString("begin_tensor")); + tensors[2] = CreateTensor(flatBufferBuilder, + flatBufferBuilder.CreateVector(endTensorShape.data(), + endTensorShape.size()), + ::tflite::TensorType_INT32, + 2, + flatBufferBuilder.CreateString("end_tensor")); + tensors[3] = CreateTensor(flatBufferBuilder, + flatBufferBuilder.CreateVector(strideTensorShape.data(), + strideTensorShape.size()), + ::tflite::TensorType_INT32, + 3, + flatBufferBuilder.CreateString("stride_tensor")); + tensors[4] = CreateTensor(flatBufferBuilder, + flatBufferBuilder.CreateVector(outputTensorShape.data(), + outputTensorShape.size()), + tensorType, + 0, + 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.data(), buffers.size())); + + flatBufferBuilder.Finish(flatbufferModel); + + 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 tflite; + std::vector modelBuffer = CreateStridedSliceTfLiteModel( + ::tflite::TensorType_FLOAT32, + inputTensorShape, + beginTensorData, + endTensorData, + strideTensorData, + beginTensorShape, + endTensorShape, + strideTensorShape, + outputTensorShape, + beginMask, + endMask, + ellipsisMask, + newAxisMask, + ShrinkAxisMask, + dataLayout); + + auto tfLiteModel = GetModel(modelBuffer.data()); + + // Create TfLite Interpreters + std::unique_ptr armnnDelegate; + CHECK(InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver()) + (&armnnDelegate) == kTfLiteOk); + CHECK(armnnDelegate != nullptr); + CHECK(armnnDelegate->AllocateTensors() == kTfLiteOk); + + std::unique_ptr tfLiteDelegate; + CHECK(InterpreterBuilder(tfLiteModel, ::tflite::ops::builtin::BuiltinOpResolver()) + (&tfLiteDelegate) == kTfLiteOk); + CHECK(tfLiteDelegate != nullptr); + CHECK(tfLiteDelegate->AllocateTensors() == kTfLiteOk); + + // Create the ArmNN Delegate + armnnDelegate::DelegateOptions delegateOptions(backends); + std::unique_ptr + theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), + armnnDelegate::TfLiteArmnnDelegateDelete); + CHECK(theArmnnDelegate != nullptr); + + // Modify armnnDelegateInterpreter to use armnnDelegate + CHECK(armnnDelegate->ModifyGraphWithDelegate(theArmnnDelegate.get()) == kTfLiteOk); + + // Set input data + armnnDelegate::FillInput(tfLiteDelegate, 0, inputValues); + armnnDelegate::FillInput(armnnDelegate, 0, inputValues); + + // Run EnqueWorkload + CHECK(tfLiteDelegate->Invoke() == kTfLiteOk); + CHECK(armnnDelegate->Invoke() == kTfLiteOk); + + // Compare output data + armnnDelegate::CompareOutputData(tfLiteDelegate, + armnnDelegate, + outputTensorShape, + expectedOutputValues); + + tfLiteDelegate.reset(nullptr); + armnnDelegate.reset(nullptr); +} // End of StridedSlice Test + +} // anonymous namespace \ No newline at end of file diff --git a/src/armnnTfLiteParser/test/Slice.cpp b/src/armnnTfLiteParser/test/Slice.cpp index a2a791feef..83c0b73d2f 100644 --- a/src/armnnTfLiteParser/test/Slice.cpp +++ b/src/armnnTfLiteParser/test/Slice.cpp @@ -174,9 +174,9 @@ TEST_CASE_FIXTURE(SliceFixtureD213, "SliceD213") struct DynamicSliceFixtureD213 : SliceFixture { DynamicSliceFixtureD213() : SliceFixture("[ 3, 2, 3 ]", - "[ ]", - "[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]", - "[ 255, 255, 255, 255, 1, 0, 0, 0, 255, 255, 255, 255 ]") {} + "[ ]", + "[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]", + "[ 255, 255, 255, 255, 1, 0, 0, 0, 255, 255, 255, 255 ]") {} }; TEST_CASE_FIXTURE(DynamicSliceFixtureD213, "DynamicSliceD213") -- cgit v1.2.1