1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2019 Arm Ltd. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include "QuantizedLstmEndToEndTestImpl.hpp"
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include <CommonTestUtils.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include "EndToEndTestImpl.hpp"
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker #include <ResolveType.hpp>
12*89c4ff92SAndroid Build Coastguard Worker
13*89c4ff92SAndroid Build Coastguard Worker #include <armnn/INetwork.hpp>
14*89c4ff92SAndroid Build Coastguard Worker #include <armnn/QuantizedLstmParams.hpp>
15*89c4ff92SAndroid Build Coastguard Worker
16*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/NumericCast.hpp>
17*89c4ff92SAndroid Build Coastguard Worker
18*89c4ff92SAndroid Build Coastguard Worker #include <armnnTestUtils/TensorHelpers.hpp>
19*89c4ff92SAndroid Build Coastguard Worker
20*89c4ff92SAndroid Build Coastguard Worker #include <doctest/doctest.h>
21*89c4ff92SAndroid Build Coastguard Worker
22*89c4ff92SAndroid Build Coastguard Worker #include <type_traits>
23*89c4ff92SAndroid Build Coastguard Worker
24*89c4ff92SAndroid Build Coastguard Worker namespace
25*89c4ff92SAndroid Build Coastguard Worker {
26*89c4ff92SAndroid Build Coastguard Worker
CreateQuantizedLstmNetwork(armnn::TensorShape & inputShape,armnn::TensorShape & outputExpectedShape)27*89c4ff92SAndroid Build Coastguard Worker armnn::INetworkPtr CreateQuantizedLstmNetwork(armnn::TensorShape& inputShape,
28*89c4ff92SAndroid Build Coastguard Worker armnn::TensorShape& outputExpectedShape)
29*89c4ff92SAndroid Build Coastguard Worker {
30*89c4ff92SAndroid Build Coastguard Worker auto batchSize = armnn::numeric_cast<unsigned int>(inputShape[0]);
31*89c4ff92SAndroid Build Coastguard Worker auto inputSize = armnn::numeric_cast<unsigned int>(inputShape[1]);
32*89c4ff92SAndroid Build Coastguard Worker auto outputSize = armnn::numeric_cast<unsigned int>(outputExpectedShape[1]);
33*89c4ff92SAndroid Build Coastguard Worker
34*89c4ff92SAndroid Build Coastguard Worker float inputOutputScale = 0.0078125f;
35*89c4ff92SAndroid Build Coastguard Worker int32_t inputOutputOffset = 128;
36*89c4ff92SAndroid Build Coastguard Worker
37*89c4ff92SAndroid Build Coastguard Worker float weightsScale = 0.00408021f;
38*89c4ff92SAndroid Build Coastguard Worker int32_t weightsOffset = 100;
39*89c4ff92SAndroid Build Coastguard Worker
40*89c4ff92SAndroid Build Coastguard Worker float biasScale = 3.1876640625e-05f;
41*89c4ff92SAndroid Build Coastguard Worker int32_t biasOffset = 0;
42*89c4ff92SAndroid Build Coastguard Worker
43*89c4ff92SAndroid Build Coastguard Worker float cellStateScale = 0.00048828125f;
44*89c4ff92SAndroid Build Coastguard Worker int32_t cellStateOffset = 0;
45*89c4ff92SAndroid Build Coastguard Worker
46*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo inputWeightsInfo({outputSize, inputSize},
47*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QAsymmU8,
48*89c4ff92SAndroid Build Coastguard Worker weightsScale,
49*89c4ff92SAndroid Build Coastguard Worker weightsOffset,
50*89c4ff92SAndroid Build Coastguard Worker true);
51*89c4ff92SAndroid Build Coastguard Worker
52*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo recurrentWeightsInfo({outputSize, outputSize},
53*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QAsymmU8,
54*89c4ff92SAndroid Build Coastguard Worker weightsScale,
55*89c4ff92SAndroid Build Coastguard Worker weightsOffset,
56*89c4ff92SAndroid Build Coastguard Worker true);
57*89c4ff92SAndroid Build Coastguard Worker
58*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo biasInfo({outputSize}, armnn::DataType::Signed32, biasScale, biasOffset, true);
59*89c4ff92SAndroid Build Coastguard Worker
60*89c4ff92SAndroid Build Coastguard Worker armnn::QuantizedLstmInputParams data;
61*89c4ff92SAndroid Build Coastguard Worker
62*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> inputToInputWeightsVector = {146, 250, 235, 171, 10, 218, 171, 108};
63*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor inputToInputWeightsTensor(inputWeightsInfo, inputToInputWeightsVector.data());
64*89c4ff92SAndroid Build Coastguard Worker
65*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> inputToForgetWeightsVector = {24, 50, 132, 179, 158, 110, 3, 169};
66*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor inputToForgetWeightsTensor(inputWeightsInfo, inputToForgetWeightsVector.data());
67*89c4ff92SAndroid Build Coastguard Worker
68*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> inputToCellWeightsTensorVector = {133, 34, 29, 49, 206, 109, 54, 183};
69*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor inputToCellWeightsTensor(inputWeightsInfo, inputToCellWeightsTensorVector.data());
70*89c4ff92SAndroid Build Coastguard Worker
71*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> inputToOutputWeightsTensorVector = {195, 187, 11, 99, 109, 10, 218, 48};
72*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor inputToOutputWeightsTensor(inputWeightsInfo, inputToOutputWeightsTensorVector.data());
73*89c4ff92SAndroid Build Coastguard Worker
74*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> recurrentToInputWeightsTensorVector =
75*89c4ff92SAndroid Build Coastguard Worker {254, 206, 77, 168, 71, 20, 215, 6, 223, 7, 118, 225, 59, 130, 174, 26};
76*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor recurrentToInputWeightsTensor(recurrentWeightsInfo, recurrentToInputWeightsTensorVector.data());
77*89c4ff92SAndroid Build Coastguard Worker
78*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> recurrentToForgetWeightsTensorVector =
79*89c4ff92SAndroid Build Coastguard Worker {137, 240, 103, 52, 68, 51, 237, 112, 0, 220, 89, 23, 69, 4, 207, 253};
80*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor recurrentToForgetWeightsTensor(recurrentWeightsInfo,
81*89c4ff92SAndroid Build Coastguard Worker recurrentToForgetWeightsTensorVector.data());
82*89c4ff92SAndroid Build Coastguard Worker
83*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> recurrentToCellWeightsTensorVector =
84*89c4ff92SAndroid Build Coastguard Worker {172, 60, 205, 65, 14, 0, 140, 168, 240, 223, 133, 56, 142, 64, 246, 216};
85*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor recurrentToCellWeightsTensor(recurrentWeightsInfo, recurrentToCellWeightsTensorVector.data());
86*89c4ff92SAndroid Build Coastguard Worker
87*89c4ff92SAndroid Build Coastguard Worker const std::vector<uint8_t> recurrentToOutputWeightsTensorVector =
88*89c4ff92SAndroid Build Coastguard Worker {106, 214, 67, 23, 59, 158, 45, 3, 119, 132, 49, 205, 129, 218, 11, 98};
89*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor recurrentToOutputWeightsTensor(recurrentWeightsInfo,
90*89c4ff92SAndroid Build Coastguard Worker recurrentToOutputWeightsTensorVector.data());
91*89c4ff92SAndroid Build Coastguard Worker
92*89c4ff92SAndroid Build Coastguard Worker const std::vector<int32_t> inputGateBiasTensorVector = {-7876, 13488, -726, 32839};
93*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor inputGateBiasTensor(biasInfo, inputGateBiasTensorVector.data());
94*89c4ff92SAndroid Build Coastguard Worker
95*89c4ff92SAndroid Build Coastguard Worker const std::vector<int32_t> forgetGateBiasTensorVector = {9206, -46884, -11693, -38724};
96*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor forgetGateBiasTensor(biasInfo, forgetGateBiasTensorVector.data());
97*89c4ff92SAndroid Build Coastguard Worker
98*89c4ff92SAndroid Build Coastguard Worker const std::vector<int32_t> cellBiasTensorVector = {39481, 48624, 48976, -21419};
99*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor cellBiasTensor(biasInfo, cellBiasTensorVector.data());
100*89c4ff92SAndroid Build Coastguard Worker
101*89c4ff92SAndroid Build Coastguard Worker const std::vector<int32_t> outputGateBiasTensorVector = {-58999, -17050, -41852, -40538};
102*89c4ff92SAndroid Build Coastguard Worker armnn::ConstTensor outputGateBiasTensor(biasInfo, outputGateBiasTensorVector.data());
103*89c4ff92SAndroid Build Coastguard Worker
104*89c4ff92SAndroid Build Coastguard Worker data.m_InputToInputWeights = &inputToInputWeightsTensor;
105*89c4ff92SAndroid Build Coastguard Worker data.m_InputToForgetWeights = &inputToForgetWeightsTensor;
106*89c4ff92SAndroid Build Coastguard Worker data.m_InputToCellWeights = &inputToCellWeightsTensor;
107*89c4ff92SAndroid Build Coastguard Worker data.m_InputToOutputWeights = &inputToOutputWeightsTensor;
108*89c4ff92SAndroid Build Coastguard Worker data.m_RecurrentToInputWeights = &recurrentToInputWeightsTensor;
109*89c4ff92SAndroid Build Coastguard Worker data.m_RecurrentToForgetWeights = &recurrentToForgetWeightsTensor;
110*89c4ff92SAndroid Build Coastguard Worker data.m_RecurrentToCellWeights = &recurrentToCellWeightsTensor;
111*89c4ff92SAndroid Build Coastguard Worker data.m_RecurrentToOutputWeights = &recurrentToOutputWeightsTensor;
112*89c4ff92SAndroid Build Coastguard Worker data.m_InputGateBias = &inputGateBiasTensor;
113*89c4ff92SAndroid Build Coastguard Worker data.m_ForgetGateBias = &forgetGateBiasTensor;
114*89c4ff92SAndroid Build Coastguard Worker data.m_CellBias = &cellBiasTensor;
115*89c4ff92SAndroid Build Coastguard Worker data.m_OutputGateBias = &outputGateBiasTensor;
116*89c4ff92SAndroid Build Coastguard Worker
117*89c4ff92SAndroid Build Coastguard Worker armnn::INetworkPtr net(armnn::INetwork::Create());
118*89c4ff92SAndroid Build Coastguard Worker
119*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const inputLayer = net->AddInputLayer(0);
120*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const cellStateIn = net->AddInputLayer(1);
121*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const outputStateIn = net->AddInputLayer(2);
122*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const quantizedLstmLayer = net->AddQuantizedLstmLayer(data, "quantizedLstm");
123*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const cellStateOut = net->AddOutputLayer(0);
124*89c4ff92SAndroid Build Coastguard Worker armnn::IConnectableLayer* const outputStateOut = net->AddOutputLayer(1);
125*89c4ff92SAndroid Build Coastguard Worker
126*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo inputTensorInfo({batchSize , inputSize},
127*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QAsymmU8,
128*89c4ff92SAndroid Build Coastguard Worker inputOutputScale,
129*89c4ff92SAndroid Build Coastguard Worker inputOutputOffset);
130*89c4ff92SAndroid Build Coastguard Worker
131*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo cellStateInTensorInfo({batchSize , outputSize},
132*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QSymmS16,
133*89c4ff92SAndroid Build Coastguard Worker cellStateScale,
134*89c4ff92SAndroid Build Coastguard Worker cellStateOffset);
135*89c4ff92SAndroid Build Coastguard Worker
136*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo outputStateInTensorInfo({batchSize , outputSize},
137*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QAsymmU8,
138*89c4ff92SAndroid Build Coastguard Worker inputOutputScale,
139*89c4ff92SAndroid Build Coastguard Worker inputOutputOffset);
140*89c4ff92SAndroid Build Coastguard Worker
141*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo cellStateOutTensorInfo({batchSize, outputSize},
142*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QSymmS16,
143*89c4ff92SAndroid Build Coastguard Worker cellStateScale,
144*89c4ff92SAndroid Build Coastguard Worker cellStateOffset);
145*89c4ff92SAndroid Build Coastguard Worker
146*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo outputTensorInfo({batchSize, outputSize},
147*89c4ff92SAndroid Build Coastguard Worker armnn::DataType::QAsymmU8,
148*89c4ff92SAndroid Build Coastguard Worker inputOutputScale,
149*89c4ff92SAndroid Build Coastguard Worker inputOutputOffset);
150*89c4ff92SAndroid Build Coastguard Worker
151*89c4ff92SAndroid Build Coastguard Worker // connect up
152*89c4ff92SAndroid Build Coastguard Worker // inputs
153*89c4ff92SAndroid Build Coastguard Worker Connect(inputLayer, quantizedLstmLayer, inputTensorInfo, 0, 0);
154*89c4ff92SAndroid Build Coastguard Worker Connect(cellStateIn, quantizedLstmLayer, cellStateInTensorInfo, 0, 1);
155*89c4ff92SAndroid Build Coastguard Worker Connect(outputStateIn, quantizedLstmLayer, outputStateInTensorInfo, 0, 2);
156*89c4ff92SAndroid Build Coastguard Worker
157*89c4ff92SAndroid Build Coastguard Worker // outputs
158*89c4ff92SAndroid Build Coastguard Worker Connect(quantizedLstmLayer, cellStateOut, cellStateOutTensorInfo, 0, 0);
159*89c4ff92SAndroid Build Coastguard Worker Connect(quantizedLstmLayer, outputStateOut, outputTensorInfo, 1, 0);
160*89c4ff92SAndroid Build Coastguard Worker
161*89c4ff92SAndroid Build Coastguard Worker return net;
162*89c4ff92SAndroid Build Coastguard Worker }
163*89c4ff92SAndroid Build Coastguard Worker
164*89c4ff92SAndroid Build Coastguard Worker // Checks if two values of an arithmetic type are close enough to each other
165*89c4ff92SAndroid Build Coastguard Worker // with regard to a given tolerance value.
166*89c4ff92SAndroid Build Coastguard Worker template<typename T>
167*89c4ff92SAndroid Build Coastguard Worker typename std::enable_if<std::is_arithmetic<T>::value, bool>::type
IsCloseEnough(T value1,T value2,T tolerance)168*89c4ff92SAndroid Build Coastguard Worker IsCloseEnough(T value1, T value2, T tolerance)
169*89c4ff92SAndroid Build Coastguard Worker {
170*89c4ff92SAndroid Build Coastguard Worker if (tolerance < 0)
171*89c4ff92SAndroid Build Coastguard Worker {
172*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("Tolerance cannot be < 0");
173*89c4ff92SAndroid Build Coastguard Worker }
174*89c4ff92SAndroid Build Coastguard Worker
175*89c4ff92SAndroid Build Coastguard Worker T diff = value1 >= value2 ? static_cast<T>(value1 - value2) : static_cast<T>(value2 - value1);
176*89c4ff92SAndroid Build Coastguard Worker return diff <= tolerance;
177*89c4ff92SAndroid Build Coastguard Worker }
178*89c4ff92SAndroid Build Coastguard Worker
179*89c4ff92SAndroid Build Coastguard Worker } // anonymous namespace
180*89c4ff92SAndroid Build Coastguard Worker
QuantizedLstmEndToEnd(const std::vector<armnn::BackendId> & backends)181*89c4ff92SAndroid Build Coastguard Worker void QuantizedLstmEndToEnd(const std::vector<armnn::BackendId>& backends)
182*89c4ff92SAndroid Build Coastguard Worker {
183*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t> inputVector = {166, 179, 50, 150};
184*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo inputDesc({2, 2}, armnn::DataType::QAsymmU8);
185*89c4ff92SAndroid Build Coastguard Worker
186*89c4ff92SAndroid Build Coastguard Worker std::vector<int16_t> cellStateInVector = {876, 1034, 955, -909, 761, 1029, 796, -1036};
187*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo cellStateInDesc({2, 4}, armnn::DataType::QSymmS16);
188*89c4ff92SAndroid Build Coastguard Worker
189*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t> outputStateInVector = {136, 150, 140, 115, 135, 152, 138, 112};
190*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo outputStateInDesc({2, 4}, armnn::DataType::QAsymmU8);
191*89c4ff92SAndroid Build Coastguard Worker
192*89c4ff92SAndroid Build Coastguard Worker std::vector<int16_t> cellStateOutVector = {1485, 1177, 1373, -1023, 1019, 1355, 1097, -1235};
193*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo cellStateOutVectorDesc({2, 4}, armnn::DataType::QSymmS16);
194*89c4ff92SAndroid Build Coastguard Worker
195*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t> outputStateOutVector = {140, 151, 146, 112, 136, 156, 142, 112};
196*89c4ff92SAndroid Build Coastguard Worker armnn::TensorInfo outputDesc({2, 4}, armnn::DataType::QAsymmU8);
197*89c4ff92SAndroid Build Coastguard Worker
198*89c4ff92SAndroid Build Coastguard Worker // Builds up the structure of the network
199*89c4ff92SAndroid Build Coastguard Worker armnn::INetworkPtr net = CreateQuantizedLstmNetwork(inputDesc.GetShape(), outputDesc.GetShape());
200*89c4ff92SAndroid Build Coastguard Worker
201*89c4ff92SAndroid Build Coastguard Worker IRuntime::CreationOptions options;
202*89c4ff92SAndroid Build Coastguard Worker IRuntimePtr runtime(IRuntime::Create(options));
203*89c4ff92SAndroid Build Coastguard Worker
204*89c4ff92SAndroid Build Coastguard Worker // optimize the network
205*89c4ff92SAndroid Build Coastguard Worker IOptimizedNetworkPtr optNet = Optimize(*net, backends, runtime->GetDeviceSpec());
206*89c4ff92SAndroid Build Coastguard Worker
207*89c4ff92SAndroid Build Coastguard Worker // Loads it into the runtime.
208*89c4ff92SAndroid Build Coastguard Worker NetworkId netId;
209*89c4ff92SAndroid Build Coastguard Worker runtime->LoadNetwork(netId, std::move(optNet));
210*89c4ff92SAndroid Build Coastguard Worker
211*89c4ff92SAndroid Build Coastguard Worker InputTensors inputTensors;
212*89c4ff92SAndroid Build Coastguard Worker inputTensors.reserve(3);
213*89c4ff92SAndroid Build Coastguard Worker
214*89c4ff92SAndroid Build Coastguard Worker // input
215*89c4ff92SAndroid Build Coastguard Worker TensorInfo inputTensorInfo0 = runtime->GetInputTensorInfo(netId, 0);
216*89c4ff92SAndroid Build Coastguard Worker TensorInfo inputTensorInfo1 = runtime->GetInputTensorInfo(netId, 1);
217*89c4ff92SAndroid Build Coastguard Worker TensorInfo inputTensorInfo2 = runtime->GetInputTensorInfo(netId, 2);
218*89c4ff92SAndroid Build Coastguard Worker inputTensorInfo0.SetConstant(true);
219*89c4ff92SAndroid Build Coastguard Worker inputTensorInfo1.SetConstant(true);
220*89c4ff92SAndroid Build Coastguard Worker inputTensorInfo2.SetConstant(true);
221*89c4ff92SAndroid Build Coastguard Worker
222*89c4ff92SAndroid Build Coastguard Worker inputTensors.push_back({0, ConstTensor(inputTensorInfo0, inputVector.data())});
223*89c4ff92SAndroid Build Coastguard Worker inputTensors.push_back({1, ConstTensor(inputTensorInfo1, cellStateInVector.data())});
224*89c4ff92SAndroid Build Coastguard Worker inputTensors.push_back({2, ConstTensor(inputTensorInfo2, outputStateInVector.data())});
225*89c4ff92SAndroid Build Coastguard Worker
226*89c4ff92SAndroid Build Coastguard Worker OutputTensors outputTensors;
227*89c4ff92SAndroid Build Coastguard Worker outputTensors.reserve(2);
228*89c4ff92SAndroid Build Coastguard Worker
229*89c4ff92SAndroid Build Coastguard Worker //output
230*89c4ff92SAndroid Build Coastguard Worker std::vector<int16_t> cellStateOutResult(cellStateOutVector.size());
231*89c4ff92SAndroid Build Coastguard Worker std::vector<uint8_t> outputStateOutResult(outputStateOutVector.size());
232*89c4ff92SAndroid Build Coastguard Worker outputTensors.push_back({0, Tensor(runtime->GetOutputTensorInfo(netId, 0), cellStateOutResult.data())});
233*89c4ff92SAndroid Build Coastguard Worker outputTensors.push_back({1, Tensor(runtime->GetOutputTensorInfo(netId, 1), outputStateOutResult.data())});
234*89c4ff92SAndroid Build Coastguard Worker
235*89c4ff92SAndroid Build Coastguard Worker // Does the inference.
236*89c4ff92SAndroid Build Coastguard Worker runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
237*89c4ff92SAndroid Build Coastguard Worker
238*89c4ff92SAndroid Build Coastguard Worker // Checks the results
239*89c4ff92SAndroid Build Coastguard Worker constexpr int16_t toleranceInt16 = 2;
240*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0u; i < cellStateOutResult.size(); ++i)
241*89c4ff92SAndroid Build Coastguard Worker {
242*89c4ff92SAndroid Build Coastguard Worker CHECK(IsCloseEnough(cellStateOutVector[i], cellStateOutResult[i], toleranceInt16));
243*89c4ff92SAndroid Build Coastguard Worker }
244*89c4ff92SAndroid Build Coastguard Worker
245*89c4ff92SAndroid Build Coastguard Worker constexpr uint8_t toleranceUint8 = 1;
246*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0u; i < outputStateOutResult.size(); ++i)
247*89c4ff92SAndroid Build Coastguard Worker {
248*89c4ff92SAndroid Build Coastguard Worker CHECK(IsCloseEnough(outputStateOutVector[i], outputStateOutResult[i], toleranceUint8));
249*89c4ff92SAndroid Build Coastguard Worker }
250*89c4ff92SAndroid Build Coastguard Worker }
251