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