xref: /aosp_15_r20/external/armnn/delegate/test/DelegateOptionsTest.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2021, 2023 Arm Ltd and Contributors. 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 "DelegateOptionsTestHelper.hpp"
7*89c4ff92SAndroid Build Coastguard Worker #include <common/include/ProfilingGuid.hpp>
8*89c4ff92SAndroid Build Coastguard Worker #include <armnnUtils/Filesystem.hpp>
9*89c4ff92SAndroid Build Coastguard Worker 
10*89c4ff92SAndroid Build Coastguard Worker namespace armnnDelegate
11*89c4ff92SAndroid Build Coastguard Worker {
12*89c4ff92SAndroid Build Coastguard Worker 
13*89c4ff92SAndroid Build Coastguard Worker TEST_SUITE("DelegateOptions")
14*89c4ff92SAndroid Build Coastguard Worker {
15*89c4ff92SAndroid Build Coastguard Worker 
16*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateOptimizerOptionsReduceFp32ToFp16")
17*89c4ff92SAndroid Build Coastguard Worker {
18*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
19*89c4ff92SAndroid Build Coastguard Worker     {
20*89c4ff92SAndroid Build Coastguard Worker         StreamRedirector redirect(std::cout, ss.rdbuf());
21*89c4ff92SAndroid Build Coastguard Worker 
22*89c4ff92SAndroid Build Coastguard Worker         std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
23*89c4ff92SAndroid Build Coastguard Worker         std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
24*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> inputData = { 1, 2, 3, 4 };
25*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> divData = { 2, 2, 3, 4 };
26*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> expectedResult = { 1, 2, 2, 2 };
27*89c4ff92SAndroid Build Coastguard Worker 
28*89c4ff92SAndroid Build Coastguard Worker         // Enable ReduceFp32ToFp16
29*89c4ff92SAndroid Build Coastguard Worker         armnn::OptimizerOptionsOpaque optimizerOptions(true, true, false, false);
30*89c4ff92SAndroid Build Coastguard Worker         armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions);
31*89c4ff92SAndroid Build Coastguard Worker 
32*89c4ff92SAndroid Build Coastguard Worker         DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
33*89c4ff92SAndroid Build Coastguard Worker                                   tensorShape,
34*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
35*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
36*89c4ff92SAndroid Build Coastguard Worker                                   divData,
37*89c4ff92SAndroid Build Coastguard Worker                                   expectedResult,
38*89c4ff92SAndroid Build Coastguard Worker                                   delegateOptions);
39*89c4ff92SAndroid Build Coastguard Worker     }
40*89c4ff92SAndroid Build Coastguard Worker     // ReduceFp32ToFp16 option is enabled
41*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos);
42*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos);
43*89c4ff92SAndroid Build Coastguard Worker }
44*89c4ff92SAndroid Build Coastguard Worker 
45*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateOptimizerOptionsDebug")
46*89c4ff92SAndroid Build Coastguard Worker {
47*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
48*89c4ff92SAndroid Build Coastguard Worker     {
49*89c4ff92SAndroid Build Coastguard Worker         StreamRedirector redirect(std::cout, ss.rdbuf());
50*89c4ff92SAndroid Build Coastguard Worker 
51*89c4ff92SAndroid Build Coastguard Worker         std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
52*89c4ff92SAndroid Build Coastguard Worker         std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
53*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> inputData = { 1, 2, 3, 4 };
54*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> divData = { 2, 2, 3, 4 };
55*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> expectedResult = { 1, 2, 2, 2 };
56*89c4ff92SAndroid Build Coastguard Worker 
57*89c4ff92SAndroid Build Coastguard Worker         // Enable Debug
58*89c4ff92SAndroid Build Coastguard Worker         armnn::OptimizerOptionsOpaque optimizerOptions(false, true, false, false);
59*89c4ff92SAndroid Build Coastguard Worker         armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions);
60*89c4ff92SAndroid Build Coastguard Worker 
61*89c4ff92SAndroid Build Coastguard Worker         DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
62*89c4ff92SAndroid Build Coastguard Worker                                   tensorShape,
63*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
64*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
65*89c4ff92SAndroid Build Coastguard Worker                                   divData,
66*89c4ff92SAndroid Build Coastguard Worker                                   expectedResult,
67*89c4ff92SAndroid Build Coastguard Worker                                   delegateOptions);
68*89c4ff92SAndroid Build Coastguard Worker     }
69*89c4ff92SAndroid Build Coastguard Worker     // Debug option triggered.
70*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("layerGuid") != std::string::npos);
71*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("layerName") != std::string::npos);
72*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("outputSlot") != std::string::npos);
73*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("shape") != std::string::npos);
74*89c4ff92SAndroid Build Coastguard Worker     CHECK(ss.str().find("data") != std::string::npos);
75*89c4ff92SAndroid Build Coastguard Worker }
76*89c4ff92SAndroid Build Coastguard Worker 
77*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateOptimizerOptionsDebugFunction")
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
80*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
81*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> inputData = { 1, 2, 3, 4 };
82*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> divData = { 2, 2, 3, 4 };
83*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedResult = { 1, 2, 2, 2 };
84*89c4ff92SAndroid Build Coastguard Worker 
85*89c4ff92SAndroid Build Coastguard Worker     // Enable debug with debug callback function
86*89c4ff92SAndroid Build Coastguard Worker     armnn::OptimizerOptionsOpaque optimizerOptions(false, true, false, false);
87*89c4ff92SAndroid Build Coastguard Worker     bool callback = false;
88*89c4ff92SAndroid Build Coastguard Worker     auto mockCallback = [&](LayerGuid guid, unsigned int slotIndex, armnn::ITensorHandle* tensor)
__anond0a399830102(LayerGuid guid, unsigned int slotIndex, armnn::ITensorHandle* tensor) 89*89c4ff92SAndroid Build Coastguard Worker     {
90*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(guid);
91*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(slotIndex);
92*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(tensor);
93*89c4ff92SAndroid Build Coastguard Worker         callback = true;
94*89c4ff92SAndroid Build Coastguard Worker     };
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker     armnn::INetworkProperties networkProperties(false, armnn::MemorySource::Undefined, armnn::MemorySource::Undefined);
97*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(backends,
98*89c4ff92SAndroid Build Coastguard Worker                                                    optimizerOptions,
99*89c4ff92SAndroid Build Coastguard Worker                                                    armnn::EmptyOptional(),
100*89c4ff92SAndroid Build Coastguard Worker                                                    armnn::Optional<armnn::DebugCallbackFunction>(mockCallback));
101*89c4ff92SAndroid Build Coastguard Worker 
102*89c4ff92SAndroid Build Coastguard Worker     CHECK(!callback);
103*89c4ff92SAndroid Build Coastguard Worker 
104*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
105*89c4ff92SAndroid Build Coastguard Worker                               tensorShape,
106*89c4ff92SAndroid Build Coastguard Worker                               inputData,
107*89c4ff92SAndroid Build Coastguard Worker                               inputData,
108*89c4ff92SAndroid Build Coastguard Worker                               divData,
109*89c4ff92SAndroid Build Coastguard Worker                               expectedResult,
110*89c4ff92SAndroid Build Coastguard Worker                               delegateOptions);
111*89c4ff92SAndroid Build Coastguard Worker 
112*89c4ff92SAndroid Build Coastguard Worker     // Check that the debug callback function was called.
113*89c4ff92SAndroid Build Coastguard Worker     CHECK(callback);
114*89c4ff92SAndroid Build Coastguard Worker }
115*89c4ff92SAndroid Build Coastguard Worker 
116*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateOptimizerOptionsImport")
117*89c4ff92SAndroid Build Coastguard Worker {
118*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
119*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
120*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint8_t> inputData = { 1, 2, 3, 4 };
121*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint8_t> divData = { 2, 2, 3, 4 };
122*89c4ff92SAndroid Build Coastguard Worker     std::vector<uint8_t> expectedResult = { 1, 2, 2, 2 };
123*89c4ff92SAndroid Build Coastguard Worker 
124*89c4ff92SAndroid Build Coastguard Worker     armnn::OptimizerOptionsOpaque optimizerOptions(false, false, false, true);
125*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions);
126*89c4ff92SAndroid Build Coastguard Worker 
127*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionTest<uint8_t>(::tflite::TensorType_UINT8,
128*89c4ff92SAndroid Build Coastguard Worker                                 tensorShape,
129*89c4ff92SAndroid Build Coastguard Worker                                 inputData,
130*89c4ff92SAndroid Build Coastguard Worker                                 inputData,
131*89c4ff92SAndroid Build Coastguard Worker                                 divData,
132*89c4ff92SAndroid Build Coastguard Worker                                 expectedResult,
133*89c4ff92SAndroid Build Coastguard Worker                                 delegateOptions);
134*89c4ff92SAndroid Build Coastguard Worker }
135*89c4ff92SAndroid Build Coastguard Worker 
136*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateStringParsingOptionDisableTfLiteRuntimeFallback")
137*89c4ff92SAndroid Build Coastguard Worker {
138*89c4ff92SAndroid Build Coastguard Worker     std::stringstream stringStream;
139*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> keys   {  "backends", "debug-data", "disable-tflite-runtime-fallback"};
140*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> values {    "CpuRef",          "1",                               "1"};
141*89c4ff92SAndroid Build Coastguard Worker 
142*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
143*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
144*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> inputData = { 0.1f, -2.1f, 3.0f, -4.6f };
145*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedResult = { 1.0f, -2.0f, 3.0f, -4.0f };
146*89c4ff92SAndroid Build Coastguard Worker 
147*89c4ff92SAndroid Build Coastguard Worker     // Create options_keys and options_values char array
148*89c4ff92SAndroid Build Coastguard Worker     size_t num_options = keys.size();
149*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_keys =
150*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
151*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_values =
152*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
153*89c4ff92SAndroid Build Coastguard Worker     for (size_t i=0; i<num_options; ++i)
154*89c4ff92SAndroid Build Coastguard Worker     {
155*89c4ff92SAndroid Build Coastguard Worker         options_keys.get()[i]   = keys[i].c_str();
156*89c4ff92SAndroid Build Coastguard Worker         options_values.get()[i] = values[i].c_str();
157*89c4ff92SAndroid Build Coastguard Worker     }
158*89c4ff92SAndroid Build Coastguard Worker 
159*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector redirect(std::cout, stringStream.rdbuf());
160*89c4ff92SAndroid Build Coastguard Worker 
161*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(options_keys.get(), options_values.get(), num_options, nullptr);
162*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionNoFallbackTest<float>(::tflite::TensorType_FLOAT32,
163*89c4ff92SAndroid Build Coastguard Worker                                         tensorShape,
164*89c4ff92SAndroid Build Coastguard Worker                                         inputData,
165*89c4ff92SAndroid Build Coastguard Worker                                         expectedResult,
166*89c4ff92SAndroid Build Coastguard Worker                                         delegateOptions);
167*89c4ff92SAndroid Build Coastguard Worker     CHECK(stringStream.str().find("TfLiteArmnnDelegate: There are unsupported operators in the model")
168*89c4ff92SAndroid Build Coastguard Worker                                                                                                  != std::string::npos);
169*89c4ff92SAndroid Build Coastguard Worker }
170*89c4ff92SAndroid Build Coastguard Worker 
171*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateStringParsingOptionEnableTfLiteRuntimeFallback")
172*89c4ff92SAndroid Build Coastguard Worker {
173*89c4ff92SAndroid Build Coastguard Worker     std::stringstream stringStream;
174*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> keys   {  "backends", "debug-data", "disable-tflite-runtime-fallback"};
175*89c4ff92SAndroid Build Coastguard Worker     std::vector<std::string> values {    "CpuRef",          "1",                               "0"};
176*89c4ff92SAndroid Build Coastguard Worker 
177*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
178*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
179*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> inputData = { 0.1f, -2.1f, 3.0f, -4.6f };
180*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedResult = { 0.995004177f, -0.504846036f, -0.989992499f, -0.112152621f };
181*89c4ff92SAndroid Build Coastguard Worker 
182*89c4ff92SAndroid Build Coastguard Worker     // Create options_keys and options_values char array
183*89c4ff92SAndroid Build Coastguard Worker     size_t num_options = keys.size();
184*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_keys =
185*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
186*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_values =
187*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
188*89c4ff92SAndroid Build Coastguard Worker     for (size_t i=0; i<num_options; ++i)
189*89c4ff92SAndroid Build Coastguard Worker     {
190*89c4ff92SAndroid Build Coastguard Worker         options_keys.get()[i]   = keys[i].c_str();
191*89c4ff92SAndroid Build Coastguard Worker         options_values.get()[i] = values[i].c_str();
192*89c4ff92SAndroid Build Coastguard Worker     }
193*89c4ff92SAndroid Build Coastguard Worker 
194*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector redirect(std::cout, stringStream.rdbuf());
195*89c4ff92SAndroid Build Coastguard Worker 
196*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(options_keys.get(), options_values.get(), num_options, nullptr);
197*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionNoFallbackTest<float>(::tflite::TensorType_FLOAT32,
198*89c4ff92SAndroid Build Coastguard Worker                                         tensorShape,
199*89c4ff92SAndroid Build Coastguard Worker                                         inputData,
200*89c4ff92SAndroid Build Coastguard Worker                                         expectedResult,
201*89c4ff92SAndroid Build Coastguard Worker                                         delegateOptions);
202*89c4ff92SAndroid Build Coastguard Worker 
203*89c4ff92SAndroid Build Coastguard Worker     CHECK(stringStream.str().find("TfLiteArmnnDelegate: There are unsupported operators in the model")
204*89c4ff92SAndroid Build Coastguard Worker                                                                                                  == std::string::npos);
205*89c4ff92SAndroid Build Coastguard Worker }
206*89c4ff92SAndroid Build Coastguard Worker 
207*89c4ff92SAndroid Build Coastguard Worker }
208*89c4ff92SAndroid Build Coastguard Worker 
209*89c4ff92SAndroid Build Coastguard Worker TEST_SUITE("DelegateOptions_CpuAccTests")
210*89c4ff92SAndroid Build Coastguard Worker {
211*89c4ff92SAndroid Build Coastguard Worker 
212*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateModelOptions_CpuAcc_Test")
213*89c4ff92SAndroid Build Coastguard Worker {
214*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
215*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
216*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> inputData = { 1, 2, 3, 4 };
217*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> divData = { 2, 2, 3, 4 };
218*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedResult = { 1, 2, 2, 2 };
219*89c4ff92SAndroid Build Coastguard Worker 
220*89c4ff92SAndroid Build Coastguard Worker     unsigned int numberOfThreads = 2;
221*89c4ff92SAndroid Build Coastguard Worker 
222*89c4ff92SAndroid Build Coastguard Worker     armnn::ModelOptions modelOptions;
223*89c4ff92SAndroid Build Coastguard Worker     armnn::BackendOptions cpuAcc("CpuAcc",
224*89c4ff92SAndroid Build Coastguard Worker                                  {
225*89c4ff92SAndroid Build Coastguard Worker                                          { "FastMathEnabled", true },
226*89c4ff92SAndroid Build Coastguard Worker                                          { "NumberOfThreads", numberOfThreads }
227*89c4ff92SAndroid Build Coastguard Worker                                  });
228*89c4ff92SAndroid Build Coastguard Worker     modelOptions.push_back(cpuAcc);
229*89c4ff92SAndroid Build Coastguard Worker 
230*89c4ff92SAndroid Build Coastguard Worker     armnn::OptimizerOptionsOpaque optimizerOptions(false, false, false,
231*89c4ff92SAndroid Build Coastguard Worker                                                    false, modelOptions, false);
232*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions);
233*89c4ff92SAndroid Build Coastguard Worker 
234*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
235*89c4ff92SAndroid Build Coastguard Worker                               tensorShape,
236*89c4ff92SAndroid Build Coastguard Worker                               inputData,
237*89c4ff92SAndroid Build Coastguard Worker                               inputData,
238*89c4ff92SAndroid Build Coastguard Worker                               divData,
239*89c4ff92SAndroid Build Coastguard Worker                               expectedResult,
240*89c4ff92SAndroid Build Coastguard Worker                               delegateOptions);
241*89c4ff92SAndroid Build Coastguard Worker }
242*89c4ff92SAndroid Build Coastguard Worker 
243*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateSerializeToDot")
244*89c4ff92SAndroid Build Coastguard Worker {
245*89c4ff92SAndroid Build Coastguard Worker     const fs::path filename(fs::temp_directory_path() / "ArmnnDelegateSerializeToDot.dot");
246*89c4ff92SAndroid Build Coastguard Worker     if ( fs::exists(filename) )
247*89c4ff92SAndroid Build Coastguard Worker     {
248*89c4ff92SAndroid Build Coastguard Worker         fs::remove(filename);
249*89c4ff92SAndroid Build Coastguard Worker     }
250*89c4ff92SAndroid Build Coastguard Worker     std::stringstream ss;
251*89c4ff92SAndroid Build Coastguard Worker     {
252*89c4ff92SAndroid Build Coastguard Worker         StreamRedirector redirect(std::cout, ss.rdbuf());
253*89c4ff92SAndroid Build Coastguard Worker 
254*89c4ff92SAndroid Build Coastguard Worker         std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
255*89c4ff92SAndroid Build Coastguard Worker         std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
256*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> inputData = { 1, 2, 3, 4 };
257*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> divData = { 2, 2, 3, 4 };
258*89c4ff92SAndroid Build Coastguard Worker         std::vector<float> expectedResult = { 1, 2, 2, 2 };
259*89c4ff92SAndroid Build Coastguard Worker 
260*89c4ff92SAndroid Build Coastguard Worker         armnn::OptimizerOptionsOpaque optimizerOptions(false, false,
261*89c4ff92SAndroid Build Coastguard Worker                                                        false, false);
262*89c4ff92SAndroid Build Coastguard Worker         armnnDelegate::DelegateOptions delegateOptions(backends, optimizerOptions);
263*89c4ff92SAndroid Build Coastguard Worker         // Enable serialize to dot by specifying the target file name.
264*89c4ff92SAndroid Build Coastguard Worker         delegateOptions.SetSerializeToDot(filename);
265*89c4ff92SAndroid Build Coastguard Worker         DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
266*89c4ff92SAndroid Build Coastguard Worker                                   tensorShape,
267*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
268*89c4ff92SAndroid Build Coastguard Worker                                   inputData,
269*89c4ff92SAndroid Build Coastguard Worker                                   divData,
270*89c4ff92SAndroid Build Coastguard Worker                                   expectedResult,
271*89c4ff92SAndroid Build Coastguard Worker                                   delegateOptions);
272*89c4ff92SAndroid Build Coastguard Worker     }
273*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::exists(filename));
274*89c4ff92SAndroid Build Coastguard Worker     // The file should have a size greater than 0 bytes.
275*89c4ff92SAndroid Build Coastguard Worker     CHECK(fs::file_size(filename) > 0);
276*89c4ff92SAndroid Build Coastguard Worker     // Clean up.
277*89c4ff92SAndroid Build Coastguard Worker     fs::remove(filename);
278*89c4ff92SAndroid Build Coastguard Worker }
279*89c4ff92SAndroid Build Coastguard Worker 
CreateFp16StringParsingTestRun(std::vector<std::string> & keys,std::vector<std::string> & values,std::stringstream & ss)280*89c4ff92SAndroid Build Coastguard Worker void CreateFp16StringParsingTestRun(std::vector<std::string>& keys,
281*89c4ff92SAndroid Build Coastguard Worker                                     std::vector<std::string>& values,
282*89c4ff92SAndroid Build Coastguard Worker                                     std::stringstream& ss)
283*89c4ff92SAndroid Build Coastguard Worker {
284*89c4ff92SAndroid Build Coastguard Worker     StreamRedirector redirect(std::cout, ss.rdbuf());
285*89c4ff92SAndroid Build Coastguard Worker 
286*89c4ff92SAndroid Build Coastguard Worker     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
287*89c4ff92SAndroid Build Coastguard Worker     std::vector<int32_t> tensorShape { 1, 2, 2, 1 };
288*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> inputData = { 1, 2, 3, 4 };
289*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> divData = { 2, 2, 3, 4 };
290*89c4ff92SAndroid Build Coastguard Worker     std::vector<float> expectedResult = { 1, 2, 2, 2 };
291*89c4ff92SAndroid Build Coastguard Worker 
292*89c4ff92SAndroid Build Coastguard Worker     // Create options_keys and options_values char array
293*89c4ff92SAndroid Build Coastguard Worker     size_t num_options = keys.size();
294*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_keys =
295*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
296*89c4ff92SAndroid Build Coastguard Worker     std::unique_ptr<const char*> options_values =
297*89c4ff92SAndroid Build Coastguard Worker             std::unique_ptr<const char*>(new const char*[num_options + 1]);
298*89c4ff92SAndroid Build Coastguard Worker     for (size_t i=0; i<num_options; ++i)
299*89c4ff92SAndroid Build Coastguard Worker     {
300*89c4ff92SAndroid Build Coastguard Worker         options_keys.get()[i]   = keys[i].c_str();
301*89c4ff92SAndroid Build Coastguard Worker         options_values.get()[i] = values[i].c_str();
302*89c4ff92SAndroid Build Coastguard Worker     }
303*89c4ff92SAndroid Build Coastguard Worker 
304*89c4ff92SAndroid Build Coastguard Worker     armnnDelegate::DelegateOptions delegateOptions(options_keys.get(), options_values.get(),
305*89c4ff92SAndroid Build Coastguard Worker                                                    num_options, nullptr);
306*89c4ff92SAndroid Build Coastguard Worker     DelegateOptionTest<float>(::tflite::TensorType_FLOAT32,
307*89c4ff92SAndroid Build Coastguard Worker                               tensorShape,
308*89c4ff92SAndroid Build Coastguard Worker                               inputData,
309*89c4ff92SAndroid Build Coastguard Worker                               inputData,
310*89c4ff92SAndroid Build Coastguard Worker                               divData,
311*89c4ff92SAndroid Build Coastguard Worker                               expectedResult,
312*89c4ff92SAndroid Build Coastguard Worker                               delegateOptions);
313*89c4ff92SAndroid Build Coastguard Worker }
314*89c4ff92SAndroid Build Coastguard Worker 
315*89c4ff92SAndroid Build Coastguard Worker TEST_CASE ("ArmnnDelegateStringParsingOptionReduceFp32ToFp16")
316*89c4ff92SAndroid Build Coastguard Worker {
317*89c4ff92SAndroid Build Coastguard Worker     SUBCASE("Fp16=1")
318*89c4ff92SAndroid Build Coastguard Worker     {
319*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
320*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> keys   {  "backends", "debug-data", "reduce-fp32-to-fp16", "logging-severity"};
321*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> values {    "CpuRef",          "1",                   "1",             "info"};
322*89c4ff92SAndroid Build Coastguard Worker         CreateFp16StringParsingTestRun(keys, values, ss);
323*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos);
324*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos);
325*89c4ff92SAndroid Build Coastguard Worker     }
326*89c4ff92SAndroid Build Coastguard Worker     SUBCASE("Fp16=true")
327*89c4ff92SAndroid Build Coastguard Worker     {
328*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
329*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> keys   {  "backends", "debug-data", "reduce-fp32-to-fp16"};
330*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> values {    "CpuRef",       "TRUE",                "true"};
331*89c4ff92SAndroid Build Coastguard Worker         CreateFp16StringParsingTestRun(keys, values, ss);
332*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos);
333*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos);
334*89c4ff92SAndroid Build Coastguard Worker     }
335*89c4ff92SAndroid Build Coastguard Worker     SUBCASE("Fp16=True")
336*89c4ff92SAndroid Build Coastguard Worker     {
337*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
338*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> keys   {  "backends", "debug-data", "reduce-fp32-to-fp16"};
339*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> values {    "CpuRef",       "true",                "True"};
340*89c4ff92SAndroid Build Coastguard Worker         CreateFp16StringParsingTestRun(keys, values, ss);
341*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp32_to_fp16") != std::string::npos);
342*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp16_to_fp32") != std::string::npos);
343*89c4ff92SAndroid Build Coastguard Worker     }
344*89c4ff92SAndroid Build Coastguard Worker     SUBCASE("Fp16=0")
345*89c4ff92SAndroid Build Coastguard Worker     {
346*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
347*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> keys   {  "backends", "debug-data", "reduce-fp32-to-fp16"};
348*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> values {    "CpuRef",       "true",                   "0"};
349*89c4ff92SAndroid Build Coastguard Worker         CreateFp16StringParsingTestRun(keys, values, ss);
350*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp32_to_fp16") == std::string::npos);
351*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp16_to_fp32") == std::string::npos);
352*89c4ff92SAndroid Build Coastguard Worker     }
353*89c4ff92SAndroid Build Coastguard Worker     SUBCASE("Fp16=false")
354*89c4ff92SAndroid Build Coastguard Worker     {
355*89c4ff92SAndroid Build Coastguard Worker         std::stringstream ss;
356*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> keys   {  "backends", "debug-data", "reduce-fp32-to-fp16"};
357*89c4ff92SAndroid Build Coastguard Worker         std::vector<std::string> values {    "CpuRef",     "1",               "false"};
358*89c4ff92SAndroid Build Coastguard Worker         CreateFp16StringParsingTestRun(keys, values, ss);
359*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp32_to_fp16") == std::string::npos);
360*89c4ff92SAndroid Build Coastguard Worker         CHECK(ss.str().find("convert_fp16_to_fp32") == std::string::npos);
361*89c4ff92SAndroid Build Coastguard Worker     }
362*89c4ff92SAndroid Build Coastguard Worker }
363*89c4ff92SAndroid Build Coastguard Worker 
364*89c4ff92SAndroid Build Coastguard Worker }
365*89c4ff92SAndroid Build Coastguard Worker 
366*89c4ff92SAndroid Build Coastguard Worker } // namespace armnnDelegate
367