9 #include <armnnTestUtils/TensorHelpers.hpp>
14 #include <doctest/doctest.h>
15 #include <fmt/format.h>
23 template<
typename TParser>
39 const std::string& inputName,
40 const std::string& outputName);
43 const std::string& inputName,
44 const std::string& outputName);
45 void Setup(
const std::map<std::string, armnn::TensorShape>& inputShapes,
46 const std::vector<std::string>& requestedOutputs);
47 void Setup(
const std::map<std::string, armnn::TensorShape>& inputShapes);
50 const std::map<std::string,armnn::TensorShape>& inputShapes,
51 const std::vector<std::string>& requestedOutputs);
56 template <std::
size_t NumOutputDimensions>
57 void RunTest(
const std::vector<float>& inputData,
const std::vector<float>& expectedOutputData);
61 template <std::
size_t NumOutputDimensions>
62 void RunComparisonTest(
const std::map<std::string, std::vector<float>>& inputData,
63 const std::map<std::string, std::vector<uint8_t>>& expectedOutputData);
67 template <std::
size_t NumOutputDimensions,
typename T =
float>
68 void RunTest(
const std::map<std::string, std::vector<float>>& inputData,
69 const std::map<std::string, std::vector<T>>& expectedOutputData);
72 std::unique_ptr<TParser, void(*)(TParser* parser)>
m_Parser;
88 template<
typename TParser>
90 const std::string& outputName)
93 m_SingleInputName = inputName;
94 m_SingleOutputName = outputName;
95 Setup({ }, { outputName });
98 template<
typename TParser>
100 const std::string& inputName,
101 const std::string& outputName)
104 m_SingleInputName = inputName;
105 m_SingleOutputName = outputName;
106 Setup({ { inputName, inputTensorShape } }, { outputName });
109 template<
typename TParser>
112 const std::string& inputName,
113 const std::string& outputName)
117 m_SingleInputName = inputName;
118 m_SingleOutputName = outputName;
119 m_SingleOutputShape = outputTensorShape;
120 Setup({ { inputName, inputTensorShape } }, { outputName });
123 template<
typename TParser>
125 const std::vector<std::string>& requestedOutputs)
127 std::string errorMessage;
130 m_Parser->CreateNetworkFromString(m_Prototext.c_str(), inputShapes, requestedOutputs);
132 armnn::Status ret = m_Runtime->LoadNetwork(m_NetworkIdentifier, std::move(optimized), errorMessage);
135 throw armnn::Exception(fmt::format(
"LoadNetwork failed with error: '{0}' {1}",
141 template<
typename TParser>
144 std::string errorMessage;
147 m_Parser->CreateNetworkFromString(m_Prototext.c_str(), inputShapes);
149 armnn::Status ret = m_Runtime->LoadNetwork(m_NetworkIdentifier, std::move(optimized), errorMessage);
152 throw armnn::Exception(fmt::format(
"LoadNetwork failed with error: '{0}' {1}",
159 template<
typename TParser>
162 std::string errorMessage;
165 m_Parser->CreateNetworkFromString(m_Prototext.c_str());
167 armnn::Status ret = m_Runtime->LoadNetwork(m_NetworkIdentifier, std::move(optimized), errorMessage);
170 throw armnn::Exception(fmt::format(
"LoadNetwork failed with error: '{0}' {1}",
177 template<
typename TParser>
179 const std::map<std::string,armnn::TensorShape>& inputShapes,
180 const std::vector<std::string>& requestedOutputs)
183 m_Parser->CreateNetworkFromString(m_Prototext.c_str(), inputShapes, requestedOutputs);
188 template<
typename TParser>
189 template <std::
size_t NumOutputDimensions>
191 const std::vector<float>& expectedOutputData)
193 RunTest<NumOutputDimensions>({ { m_SingleInputName, inputData } }, { { m_SingleOutputName, expectedOutputData } });
196 template<
typename TParser>
197 template <std::
size_t NumOutputDimensions>
199 const std::map<std::string, std::vector<uint8_t>>&
202 RunTest<NumOutputDimensions, uint8_t>(inputData, expectedOutputData);
205 template<
typename TParser>
206 template <std::
size_t NumOutputDimensions,
typename T>
208 const std::map<std::string, std::vector<T>>& expectedOutputData)
212 for (
auto&& it : inputData)
215 bindingInfo.second.SetConstant(
true);
216 inputTensors.push_back({ bindingInfo.first,
armnn::ConstTensor(bindingInfo.second, it.second.data()) });
217 if (bindingInfo.second.GetNumElements() != it.second.size())
219 throw armnn::Exception(fmt::format(
"Input tensor {0} is expected to have {1} elements. "
220 "{2} elements supplied. {3}",
222 bindingInfo.second.GetNumElements(),
229 std::map<std::string, std::vector<T>> outputStorage;
231 for (
auto&& it : expectedOutputData)
234 outputStorage.emplace(it.first, std::vector<T>(bindingInfo.second.GetNumElements()));
235 outputTensors.push_back(
236 { bindingInfo.first,
armnn::Tensor(bindingInfo.second, outputStorage.at(it.first).data()) });
239 m_Runtime->EnqueueWorkload(m_NetworkIdentifier, inputTensors, outputTensors);
242 for (
auto&& it : expectedOutputData)
245 if (bindingInfo.second.GetNumElements() != it.second.size())
247 throw armnn::Exception(fmt::format(
"Output tensor {0} is expected to have {1} elements. "
248 "{2} elements supplied. {3}",
250 bindingInfo.second.GetNumElements(),
256 if (m_SingleOutputShape.GetNumDimensions() != 0)
259 if (bindingInfo.second.GetShape().GetNumDimensions() == NumOutputDimensions &&
260 bindingInfo.second.GetShape().GetNumDimensions() == m_SingleOutputShape.GetNumDimensions())
262 for (
unsigned int i = 0; i < m_SingleOutputShape.GetNumDimensions(); ++i)
264 if (m_SingleOutputShape[i] != bindingInfo.second.GetShape()[i])
268 std::stringstream message;
269 message <<
"Output tensor " << it.first <<
" is expected to have "
270 << bindingInfo.second.GetShape() <<
"shape. "
271 << m_SingleOutputShape <<
" shape supplied. "
279 throw armnn::Exception(fmt::format(
"Output tensor {0} is expected to have {1} dimensions. "
280 "{2} dimensions supplied. {3}",
282 bindingInfo.second.GetShape().GetNumDimensions(),
288 auto outputExpected = it.second;
289 auto shape = bindingInfo.second.GetShape();
290 if (std::is_same<T, uint8_t>::value)
292 auto result = CompareTensors(outputExpected, outputStorage[it.first], shape, shape,
true);
293 CHECK_MESSAGE(result.m_Result, result.m_Message.str());
297 auto result = CompareTensors(outputExpected, outputStorage[it.first], shape, shape);
298 CHECK_MESSAGE(result.m_Result, result.m_Message.str());
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
#define ARMNN_NO_DEPRECATE_WARN_END
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Base class for all ArmNN exceptions so that users can filter to just those.
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Copyright (c) 2021 ARM Limited and Contributors.
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
std::pair< armnn::LayerBindingId, armnn::TensorInfo > BindingPointInfo
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptionsOpaque &options=OptimizerOptionsOpaque(), Optional< std::vector< std::string > & > messages=EmptyOptional())
Create an optimized version of the network.
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
@ CpuRef
CPU Execution: Reference C++ kernels.
armnn::NetworkId m_NetworkIdentifier
ARMNN_NO_DEPRECATE_WARN_END void SetupSingleInputSingleOutput(const std::string &inputName, const std::string &outputName)
Parses and loads the network defined by the m_Prototext string.
armnn::TensorShape m_SingleOutputShape
This will store the output shape so it don't need to be passed to the single-input-single-output over...
void RunComparisonTest(const std::map< std::string, std::vector< float >> &inputData, const std::map< std::string, std::vector< uint8_t >> &expectedOutputData)
Executes the network with the given input tensor and checks the result against the given output tenso...
std::string m_SingleInputName
If the single-input-single-output overload of Setup() is called, these will store the input and outpu...
armnn::IOptimizedNetworkPtr SetupOptimizedNetwork(const std::map< std::string, armnn::TensorShape > &inputShapes, const std::vector< std::string > &requestedOutputs)
std::unique_ptr< TParser, void(*)(TParser *parser)> m_Parser
ARMNN_NO_DEPRECATE_WARN_BEGIN ParserPrototxtFixture()
void RunTest(const std::vector< float > &inputData, const std::vector< float > &expectedOutputData)
Executes the network with the given input tensor and checks the result against the given output tenso...
std::string m_SingleOutputName
armnn::IRuntimePtr m_Runtime