blob: 69744f45cfc23dc9c152e287b8a4ed8cbeac4da1 [file] [log] [blame]
Aron Virginas-Tarc975f922019-10-23 17:38:17 +01001//
2// Copyright © 2019 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "ParserFlatbuffersFixture.hpp"
7#include "../TfLiteParser.hpp"
8
9#include <armnn/LayerVisitorBase.hpp>
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010010#include <armnn/utility/Assert.hpp>
Matthew Sloyan589e3e82020-09-11 16:17:48 +010011#include <armnn/utility/NumericCast.hpp>
Jan Eilersbb446e52020-04-02 13:56:54 +010012#include <armnn/utility/PolymorphicDowncast.hpp>
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010013
14#include <layers/StandInLayer.hpp>
15
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010016#include <sstream>
17#include <string>
18#include <vector>
19
Sadik Armagan1625efc2021-06-10 18:24:34 +010020TEST_SUITE("TensorflowLiteParser_Unsupported")
21{
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010022using namespace armnn;
23
24class StandInLayerVerifier : public LayerVisitorBase<VisitorThrowingPolicy>
25{
26public:
27 StandInLayerVerifier(const std::vector<TensorInfo>& inputInfos,
28 const std::vector<TensorInfo>& outputInfos)
29 : LayerVisitorBase<VisitorThrowingPolicy>()
30 , m_InputInfos(inputInfos)
31 , m_OutputInfos(outputInfos) {}
32
33 void VisitInputLayer(const IConnectableLayer*, LayerBindingId, const char*) override {}
34
Derek Lambertibaa177f2019-12-10 22:00:43 +000035 void VisitOutputLayer(const IConnectableLayer*, LayerBindingId, const char*) override {}
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010036
37 void VisitStandInLayer(const IConnectableLayer* layer,
38 const StandInDescriptor& descriptor,
39 const char*) override
40 {
Matthew Sloyan589e3e82020-09-11 16:17:48 +010041 unsigned int numInputs = armnn::numeric_cast<unsigned int>(m_InputInfos.size());
Sadik Armagan1625efc2021-06-10 18:24:34 +010042 CHECK(descriptor.m_NumInputs == numInputs);
43 CHECK(layer->GetNumInputSlots() == numInputs);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010044
Matthew Sloyan589e3e82020-09-11 16:17:48 +010045 unsigned int numOutputs = armnn::numeric_cast<unsigned int>(m_OutputInfos.size());
Sadik Armagan1625efc2021-06-10 18:24:34 +010046 CHECK(descriptor.m_NumOutputs == numOutputs);
47 CHECK(layer->GetNumOutputSlots() == numOutputs);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010048
Jan Eilersbb446e52020-04-02 13:56:54 +010049 const StandInLayer* standInLayer = PolymorphicDowncast<const StandInLayer*>(layer);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010050 for (unsigned int i = 0u; i < numInputs; ++i)
51 {
52 const OutputSlot* connectedSlot = standInLayer->GetInputSlot(i).GetConnectedOutputSlot();
Sadik Armagan1625efc2021-06-10 18:24:34 +010053 CHECK(connectedSlot != nullptr);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010054
55 const TensorInfo& inputInfo = connectedSlot->GetTensorInfo();
Sadik Armagan1625efc2021-06-10 18:24:34 +010056 CHECK(inputInfo == m_InputInfos[i]);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010057 }
58
59 for (unsigned int i = 0u; i < numOutputs; ++i)
60 {
61 const TensorInfo& outputInfo = layer->GetOutputSlot(i).GetTensorInfo();
Sadik Armagan1625efc2021-06-10 18:24:34 +010062 CHECK(outputInfo == m_OutputInfos[i]);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010063 }
64 }
65
66private:
67 std::vector<TensorInfo> m_InputInfos;
68 std::vector<TensorInfo> m_OutputInfos;
69};
70
71class DummyCustomFixture : public ParserFlatbuffersFixture
72{
73public:
74 explicit DummyCustomFixture(const std::vector<TensorInfo>& inputInfos,
75 const std::vector<TensorInfo>& outputInfos)
76 : ParserFlatbuffersFixture()
77 , m_StandInLayerVerifier(inputInfos, outputInfos)
78 {
Matthew Sloyan589e3e82020-09-11 16:17:48 +010079 const unsigned int numInputs = armnn::numeric_cast<unsigned int>(inputInfos.size());
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010080 ARMNN_ASSERT(numInputs > 0);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010081
Matthew Sloyan589e3e82020-09-11 16:17:48 +010082 const unsigned int numOutputs = armnn::numeric_cast<unsigned int>(outputInfos.size());
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010083 ARMNN_ASSERT(numOutputs > 0);
Aron Virginas-Tarc975f922019-10-23 17:38:17 +010084
85 m_JsonString = R"(
86 {
87 "version": 3,
88 "operator_codes": [{
89 "builtin_code": "CUSTOM",
90 "custom_code": "DummyCustomOperator"
91 }],
92 "subgraphs": [ {
93 "tensors": [)";
94
95 // Add input tensors
96 for (unsigned int i = 0u; i < numInputs; ++i)
97 {
98 const TensorInfo& inputInfo = inputInfos[i];
99 m_JsonString += R"(
100 {
101 "shape": )" + GetTensorShapeAsString(inputInfo.GetShape()) + R"(,
102 "type": )" + GetDataTypeAsString(inputInfo.GetDataType()) + R"(,
103 "buffer": 0,
104 "name": "inputTensor)" + std::to_string(i) + R"(",
105 "quantization": {
106 "min": [ 0.0 ],
107 "max": [ 255.0 ],
108 "scale": [ )" + std::to_string(inputInfo.GetQuantizationScale()) + R"( ],
109 "zero_point": [ )" + std::to_string(inputInfo.GetQuantizationOffset()) + R"( ],
110 }
111 },)";
112 }
113
114 // Add output tensors
115 for (unsigned int i = 0u; i < numOutputs; ++i)
116 {
117 const TensorInfo& outputInfo = outputInfos[i];
118 m_JsonString += R"(
119 {
120 "shape": )" + GetTensorShapeAsString(outputInfo.GetShape()) + R"(,
121 "type": )" + GetDataTypeAsString(outputInfo.GetDataType()) + R"(,
122 "buffer": 0,
123 "name": "outputTensor)" + std::to_string(i) + R"(",
124 "quantization": {
125 "min": [ 0.0 ],
126 "max": [ 255.0 ],
127 "scale": [ )" + std::to_string(outputInfo.GetQuantizationScale()) + R"( ],
128 "zero_point": [ )" + std::to_string(outputInfo.GetQuantizationOffset()) + R"( ],
129 }
130 })";
131
132 if (i + 1 < numOutputs)
133 {
134 m_JsonString += ",";
135 }
136 }
137
138 const std::string inputIndices = GetIndicesAsString(0u, numInputs - 1u);
139 const std::string outputIndices = GetIndicesAsString(numInputs, numInputs + numOutputs - 1u);
140
141 // Add dummy custom operator
142 m_JsonString += R"(],
143 "inputs": )" + inputIndices + R"(,
144 "outputs": )" + outputIndices + R"(,
145 "operators": [
146 {
147 "opcode_index": 0,
148 "inputs": )" + inputIndices + R"(,
149 "outputs": )" + outputIndices + R"(,
150 "builtin_options_type": 0,
151 "custom_options": [ ],
152 "custom_options_format": "FLEXBUFFERS"
153 }
154 ],
155 } ],
156 "buffers" : [
157 { },
158 { }
159 ]
160 }
161 )";
162
163 ReadStringToBinary();
164 }
165
166 void RunTest()
167 {
168 INetworkPtr network = m_Parser->CreateNetworkFromBinary(m_GraphBinary);
169 network->Accept(m_StandInLayerVerifier);
170 }
171
172private:
173 static std::string GetTensorShapeAsString(const TensorShape& tensorShape)
174 {
175 std::stringstream stream;
176 stream << "[ ";
177 for (unsigned int i = 0u; i < tensorShape.GetNumDimensions(); ++i)
178 {
179 stream << tensorShape[i];
180 if (i + 1 < tensorShape.GetNumDimensions())
181 {
182 stream << ",";
183 }
184 stream << " ";
185 }
186 stream << "]";
187
188 return stream.str();
189 }
190
191 static std::string GetDataTypeAsString(DataType dataType)
192 {
193 switch (dataType)
194 {
195 case DataType::Float32: return "FLOAT32";
Derek Lambertif90c56d2020-01-10 17:14:08 +0000196 case DataType::QAsymmU8: return "UINT8";
Aron Virginas-Tarc975f922019-10-23 17:38:17 +0100197 default: return "UNKNOWN";
198 }
199 }
200
201 static std::string GetIndicesAsString(unsigned int first, unsigned int last)
202 {
203 std::stringstream stream;
204 stream << "[ ";
205 for (unsigned int i = first; i <= last ; ++i)
206 {
207 stream << i;
208 if (i + 1 <= last)
209 {
210 stream << ",";
211 }
212 stream << " ";
213 }
214 stream << "]";
215
216 return stream.str();
217 }
218
219 StandInLayerVerifier m_StandInLayerVerifier;
220};
221
222class DummyCustom1Input1OutputFixture : public DummyCustomFixture
223{
224public:
225 DummyCustom1Input1OutputFixture()
226 : DummyCustomFixture({ TensorInfo({ 1, 1 }, DataType::Float32) },
227 { TensorInfo({ 2, 2 }, DataType::Float32) }) {}
228};
229
230class DummyCustom2Inputs1OutputFixture : public DummyCustomFixture
231{
232public:
233 DummyCustom2Inputs1OutputFixture()
234 : DummyCustomFixture({ TensorInfo({ 1, 1 }, DataType::Float32), TensorInfo({ 2, 2 }, DataType::Float32) },
235 { TensorInfo({ 3, 3 }, DataType::Float32) }) {}
236};
237
Sadik Armagan1625efc2021-06-10 18:24:34 +0100238TEST_CASE_FIXTURE(DummyCustom1Input1OutputFixture, "UnsupportedCustomOperator1Input1Output")
Aron Virginas-Tarc975f922019-10-23 17:38:17 +0100239{
240 RunTest();
241}
242
Sadik Armagan1625efc2021-06-10 18:24:34 +0100243TEST_CASE_FIXTURE(DummyCustom2Inputs1OutputFixture, "UnsupportedCustomOperator2Inputs1Output")
Aron Virginas-Tarc975f922019-10-23 17:38:17 +0100244{
245 RunTest();
246}
247
Sadik Armagan1625efc2021-06-10 18:24:34 +0100248}