blob: 091dcefe8b0f0112f6f6872aace6df9d8f7ab6e7 [file] [log] [blame]
Matthew Sloyan65c21a12023-04-04 12:06:14 +01001//
2// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
7#include <doctest/doctest.h>
8
9#include <opaque/include/armnn_delegate.hpp>
Narumol Prangnawarat26654cb2023-05-03 16:08:11 +010010
Matthew Sloyan65c21a12023-04-04 12:06:14 +010011namespace armnnOpaqueDelegate
12{
13
14TEST_SUITE("ArmnnOpaqueDelegate")
15{
16
17TEST_CASE ("DelegateOptions_OpaqueDelegateDefault")
18{
19 // Check default options can be created
20 auto options = armnnOpaqueDelegate::TfLiteArmnnDelegateOptionsDefault();
21 armnnOpaqueDelegate::ArmnnOpaqueDelegate delegate(options);
22
23 // Check version returns correctly
24 auto version = delegate.GetVersion();
25 CHECK_EQ(version, OPAQUE_DELEGATE_VERSION);
26
27 auto* builder = delegate.GetDelegateBuilder();
28 CHECK(builder);
29
30 // Check Opaque delegate created
31 auto opaqueDelegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(&options);
32 CHECK(opaqueDelegate);
33
34 // Check Opaque Delegate can be deleted
35 CHECK(opaqueDelegate->opaque_delegate_builder->data);
36 armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateDelete(opaqueDelegate);
37}
38
Narumol Prangnawarat26654cb2023-05-03 16:08:11 +010039TEST_CASE ("DelegatePluginTest")
40{
41 // Use default settings until options have been enabled.
42 flatbuffers::FlatBufferBuilder flatBufferBuilder;
Narumol Prangnawarat46e574e2023-05-05 16:39:05 +010043 tflite::TFLiteSettingsBuilder tfliteSettingsBuilder(flatBufferBuilder);
44 flatbuffers::Offset<tflite::TFLiteSettings> tfliteSettings = tfliteSettingsBuilder.Finish();
Narumol Prangnawarat26654cb2023-05-03 16:08:11 +010045 flatBufferBuilder.Finish(tfliteSettings);
46 const tflite::TFLiteSettings* settings = flatbuffers::GetRoot<tflite::TFLiteSettings>(
47 flatBufferBuilder.GetBufferPointer());
48
49 std::unique_ptr<tflite::delegates::DelegatePluginInterface> delegatePlugin =
50 tflite::delegates::DelegatePluginRegistry::CreateByName("armnn_delegate", *settings);
51
52 // Plugin is created correctly using armnn_delegate name.
53 CHECK((delegatePlugin != nullptr));
54
55 tflite::delegates::TfLiteDelegatePtr armnnDelegate = delegatePlugin->Create();
56
57 // Armnn Opaque Delegate is created correctly.
58 CHECK((armnnDelegate != nullptr));
59 CHECK((armnnDelegate->opaque_delegate_builder != nullptr));
Matthew Sloyan65c21a12023-04-04 12:06:14 +010060}
61
Teresa Charlin19ad8162023-10-04 11:17:03 +010062armnnDelegate::DelegateOptions BuildDelegateOptions(const char* backends,
63 bool fastmath,
64 const char* additional_parameters)
65{
66 flatbuffers::FlatBufferBuilder flatbuffer_builder;
67
68 flatbuffers::Offset<tflite::ArmNNSettings>
69 armnn_settings_offset = tflite::CreateArmNNSettingsDirect(flatbuffer_builder,
70 backends,
71 fastmath,
72 additional_parameters);
73
74 tflite::TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder);
75 tflite_settings_builder.add_armnn_settings(armnn_settings_offset);
76 flatbuffers::Offset<tflite::TFLiteSettings> tflite_settings_offset = tflite_settings_builder.Finish();
77 flatbuffer_builder.Finish(tflite_settings_offset);
78
79 const tflite::TFLiteSettings* tflite_settings = flatbuffers::GetRoot<tflite::TFLiteSettings>(
80 flatbuffer_builder.GetBufferPointer());
81
82 armnnDelegate::DelegateOptions delegateOptions = ParseArmNNSettings(tflite_settings);
83
84 return delegateOptions;
85}
86
87unsigned int CountBackendOptions(armnn::BackendId backendId,
88 armnnDelegate::DelegateOptions& delegateOptions,
89 bool runtime = false)
90{
91 unsigned int count = 0;
92
93 std::vector<armnn::BackendOptions> modelOptions = runtime ? delegateOptions.GetRuntimeOptions().m_BackendOptions
94 : delegateOptions.GetOptimizerOptions().GetModelOptions();
95 for (const auto& backendOptions : modelOptions)
96 {
97 if (backendOptions.GetBackendId() == backendId)
98 {
99 count = backendOptions.GetOptionCount();
100 }
101 }
102
103 return count;
104}
105
106bool GetBackendOption(armnn::BackendId backendId,
107 armnnDelegate::DelegateOptions& delegateOptions,
108 std::string& optionName,
109 armnn::BackendOptions::BackendOption& backendOption,
110 bool runtime = false)
111{
112 bool result = false;
113
114 std::vector<armnn::BackendOptions> modelOptions = runtime ? delegateOptions.GetRuntimeOptions().m_BackendOptions
115 : delegateOptions.GetOptimizerOptions().GetModelOptions();
116
117 for (const auto& backendOptions : modelOptions)
118 {
119 if (backendOptions.GetBackendId() == backendId)
120 {
121 for (size_t i = 0; i < backendOptions.GetOptionCount(); ++i)
122 {
123 const armnn::BackendOptions::BackendOption& option = backendOptions.GetOption(i);
124 if (option.GetName() == optionName)
125 {
126 backendOption = option;
127 result = true;
128 break;
129 }
130 }
131 }
132 }
133
134 return result;
135}
136
137TEST_CASE ("ParseArmNNSettings_backend")
138{
139 {
140 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuRef,GpuAcc", false, nullptr);
141
142 std::vector<armnn::BackendId> expectedBackends = {"CpuRef", "GpuAcc"};
143 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
144 }
145 {
146 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, nullptr);
147
148 std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"};
149 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
150 }
151}
152
153TEST_CASE ("ParseArmNNSettings_fastmath")
154{
155 // Test fastmath true in both backends
156 {
157 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,GpuAcc", true, nullptr);
158
159 std::vector<armnn::BackendId> expectedBackends = {"CpuAcc", "GpuAcc"};
160 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
161 CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1);
162 CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1);
163
164 armnn::BackendOptions::BackendOption backendOption("", false);
165 std::string optionName = "FastMathEnabled";
166 CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true);
167 CHECK_EQ(backendOption.GetValue().AsBool(), true);
168 CHECK_EQ(backendOption.GetName(), optionName);
169 CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true);
170 CHECK_EQ(backendOption.GetValue().AsBool(), true);
171 CHECK_EQ(backendOption.GetName(), optionName);
172 }
173
174 // Test fastmath true in one backend
175 {
176 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,CpuRef", true, nullptr);
177
178 std::vector<armnn::BackendId> expectedBackends = {"CpuAcc", "CpuRef"};
179 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
180 CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1);
181 CHECK_EQ(CountBackendOptions(armnn::Compute::CpuRef, delegateOptions), 0);
182
183 armnn::BackendOptions::BackendOption backendOption("", false);
184 std::string optionName = "FastMathEnabled";
185 CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true);
186 CHECK_EQ(backendOption.GetValue().AsBool(), true);
187 CHECK_EQ(backendOption.GetName(), optionName);
188 CHECK_EQ(GetBackendOption(armnn::Compute::CpuRef, delegateOptions, optionName, backendOption), false);
189 }
190
191 // Test fastmath false
192 {
193 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, nullptr);
194
195 std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"};
196 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
197 CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions), 1);
198
199 armnn::BackendOptions::BackendOption backendOption("", false);
200 std::string optionName = "FastMathEnabled";
201 CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true);
202 CHECK_EQ(backendOption.GetValue().AsBool(), false);
203 CHECK_EQ(backendOption.GetName(), optionName);
204 }
205}
206
207TEST_CASE ("ParseArmNNSettings_additional_options_raw")
208{
209 const char* backends = "GpuAcc";
210 bool fastmath = false;
211 const char* additional_parameters = "allow-expanded-dims=true";
212
213 flatbuffers::FlatBufferBuilder flatbuffer_builder;
214 flatbuffers::Offset<tflite::ArmNNSettings>
215 armnn_settings_offset = tflite::CreateArmNNSettingsDirect(flatbuffer_builder,
216 backends,
217 fastmath,
218 additional_parameters);
219
220 tflite::TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder);
221 tflite_settings_builder.add_armnn_settings(armnn_settings_offset);
222 flatbuffers::Offset<tflite::TFLiteSettings> tflite_settings_offset = tflite_settings_builder.Finish();
223 flatbuffer_builder.Finish(tflite_settings_offset);
224
225 const tflite::TFLiteSettings* tflite_settings = flatbuffers::GetRoot<tflite::TFLiteSettings>(
226 flatbuffer_builder.GetBufferPointer());
227 CHECK((tflite_settings->armnn_settings()->additional_parameters() != nullptr));
228 CHECK_EQ(tflite_settings->armnn_settings()->additional_parameters()->str(), additional_parameters);
229
230 armnnDelegate::DelegateOptions delegateOptions = ParseArmNNSettings(tflite_settings);
231 CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true);
232}
233
234TEST_CASE ("ParseArmNNSettings_additional_options")
235{
236 std::string options = "number-of-threads=29," // optimizer-backend option only Cpu
237 "gpu-kernel-profiling-enabled=true," // runtime-backend option only GPU
238 "allow-expanded-dims=true," // optimizer option
239 "logging-severity=debug," // option
240 "counter-capture-period=100u"; // runtime-profiling option
241 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,GpuAcc", false, options.c_str());
242
243 // Variables to be used in all checks
244 armnn::BackendOptions::BackendOption backendOption("", false);
245 std::string optionName;
246
247 // number-of-threads
248 CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1);
249 optionName = "NumberOfThreads";
250 CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true);
251 CHECK_EQ(backendOption.GetValue().AsUnsignedInt(), 29);
252 CHECK_EQ(backendOption.GetName(), optionName);
253
254 // gpu-kernel-profiling-enabled
255 CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions, true), 1);
256 optionName = "KernelProfilingEnabled";
257 CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption, true), true);
258 CHECK_EQ(backendOption.GetValue().AsBool(), true);
259 CHECK_EQ(backendOption.GetName(), optionName);
260
261 // allow-expanded-dims
262 CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true);
263
264 // logging-severity
265 CHECK_EQ(delegateOptions.GetLoggingSeverity(), armnn::LogSeverity::Debug);
266
267 // counter-capture-period
268 CHECK_EQ(delegateOptions.GetRuntimeOptions().m_ProfilingOptions.m_CapturePeriod, 100);
269}
270
271TEST_CASE ("ParseArmNNSettings_additional_options_regex")
272{
273 std::string options = "allow-expanded-dims= true, " // optimizer option
274 "number-of-threads =29 ," // optimizer-backend option only Cpu
275 "logging-severity = trace , " // option
276 "counter-capture-period = 100u"; // runtime-profiling option
277 armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, options.c_str());
278
279 // Variables to be used in all checks
280 armnn::BackendOptions::BackendOption backendOption("", false);
281 std::string optionName;
282
283 std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"};
284 CHECK_EQ(expectedBackends, delegateOptions.GetBackends());
285
286 // enable-fast-math
287 CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions), 1);
288 optionName = "FastMathEnabled";
289 CHECK_EQ(GetBackendOption(armnn::Compute::CpuRef, delegateOptions, optionName, backendOption), false);
290 CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), false);
291 CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true);
292 CHECK_EQ(backendOption.GetValue().AsBool(), false);
293 CHECK_EQ(backendOption.GetName(), optionName);
294
295 // allow-expanded-dims
296 CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true);
297
298 // number-of-threads not saved anywhere, as it is a parameter only valid for CpuAcc
299 optionName="number-of-threads";
300 CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), false);
301 CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), false);
302
303 // logging-severity
304 CHECK_EQ(delegateOptions.GetLoggingSeverity(), armnn::LogSeverity::Trace);
305
306 // counter-capture-period
307 CHECK_EQ(delegateOptions.GetRuntimeOptions().m_ProfilingOptions.m_CapturePeriod, 100);
308}
309
310TEST_CASE ("ParseArmNNSettings_additional_options_incorrect")
311{
312 std::string options = "number-of-thread=29"; // The correct one would be "number-of-threads" in plural
313
314 CHECK_THROWS(BuildDelegateOptions("CpuAcc,GpuAcc", false, options.c_str()));
315}
316
Narumol Prangnawarat26654cb2023-05-03 16:08:11 +0100317}
Matthew Sloyan65c21a12023-04-04 12:06:14 +0100318} // namespace armnnDelegate