diff options
author | Teresa Charlin <teresa.charlinreyes@arm.com> | 2023-10-04 11:17:03 +0100 |
---|---|---|
committer | TeresaARM <teresa.charlinreyes@arm.com> | 2023-10-05 18:18:29 +0000 |
commit | 19ad816539037a095749cdd41852292a3d87dd2b (patch) | |
tree | 409697e5f10ac6a4e1b86cd86bfba5e0663f16ba /delegate/opaque/src | |
parent | 727d017aa3559cb33c97a8d77b5a32fbb98b9e35 (diff) | |
download | armnn-19ad816539037a095749cdd41852292a3d87dd2b.tar.gz |
IVGCVSW-8060 Add ArmNNSettings parser function for Opaque Delegate
* Add Unit Tests
* Update DelegateOptions constructor
Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com>
Change-Id: I0e88403ac280e4cf8710ae7ee38b3b56dba42adc
Diffstat (limited to 'delegate/opaque/src')
-rw-r--r-- | delegate/opaque/src/armnn_delegate.cpp | 64 | ||||
-rw-r--r-- | delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp | 255 |
2 files changed, 319 insertions, 0 deletions
diff --git a/delegate/opaque/src/armnn_delegate.cpp b/delegate/opaque/src/armnn_delegate.cpp index 83e90a0026..8e3597d1d3 100644 --- a/delegate/opaque/src/armnn_delegate.cpp +++ b/delegate/opaque/src/armnn_delegate.cpp @@ -55,6 +55,7 @@ #include <algorithm> #include <iostream> #include <sstream> +#include <regex> namespace armnnOpaqueDelegate { @@ -63,6 +64,69 @@ static auto* g_delegate_plugin_ArmnnDelegatePlugin_ = new tflite::delegates::DelegatePluginRegistry::Register("armnn_delegate", ArmnnDelegatePlugin::New); +armnnDelegate::DelegateOptions ParseArmNNSettings(const tflite::TFLiteSettings* tfLiteSettings) +{ + const tflite::ArmNNSettings* settings = tfLiteSettings->armnn_settings(); + ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(settings, + "The passed TFLiteSettings did not contain a valid ArmNNSettings"); + + // Extract settings fields + bool fastmath = settings->fastmath(); + std::string backends_str = (settings->backends()) ? settings->backends()->str() : ""; + const ::flatbuffers::String* additional_parameters = settings->additional_parameters(); + + // Build additional parameters string + std::string additional_parameters_str; + if (additional_parameters) + { + additional_parameters_str = additional_parameters->str(); + + // Apply a regex to remove spaces around the = and , signs + std::regex regex_equals_str("[ ]*=[ ]*"); + std::regex regex_comma_str("[ ]*,[ ]*"); + additional_parameters_str = std::regex_replace(additional_parameters_str, regex_equals_str, "="); + additional_parameters_str = std::regex_replace(additional_parameters_str, regex_comma_str, ","); + } + + // Build a std::pair list of option names and values + std::vector<std::pair<std::string, std::string>> options; + options.emplace_back(std::pair<std::string, std::string>("backends", backends_str)); + options.emplace_back(std::pair<std::string, std::string>("enable-fast-math", (fastmath) ? "true" : "false")); + + std::stringstream additional_parameters_ss(additional_parameters_str); + while (additional_parameters_ss.good()) + { + std::string option_str; + getline( additional_parameters_ss, option_str, ',' ); + size_t n = option_str.find("="); + if (n != std::string::npos) + { + std::string name = option_str.substr(0, n); + std::string value = option_str.substr(n + 1, std::string::npos); + options.emplace_back(std::pair<std::string, std::string>(name, value)); + } + } + + // Build the key and value lists to pass into the constructor of the DelegateOptions + size_t num_options = options.size(); + std::unique_ptr<const char*> options_keys = std::unique_ptr<const char*>(new const char*[num_options + 1]); + std::unique_ptr<const char*> options_values = std::unique_ptr<const char*>(new const char*[num_options + 1]); + + for (size_t i=0; i<num_options; ++i) + { + options_keys.get()[i] = options[i].first.c_str(); + options_values.get()[i] = options[i].second.c_str(); + } + + // Finally call the constructor + armnnDelegate::DelegateOptions delegateOptions = armnnDelegate::DelegateOptions(options_keys.get(), + options_values.get(), + num_options, + nullptr); + + return delegateOptions; +} + ArmnnOpaqueDelegate::ArmnnOpaqueDelegate(armnnDelegate::DelegateOptions options) : m_Options(std::move(options)) { diff --git a/delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp b/delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp index 9d255b1126..091dcefe8b 100644 --- a/delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp +++ b/delegate/opaque/src/test/ArmnnOpaqueDelegateTest.cpp @@ -59,5 +59,260 @@ TEST_CASE ("DelegatePluginTest") CHECK((armnnDelegate->opaque_delegate_builder != nullptr)); } +armnnDelegate::DelegateOptions BuildDelegateOptions(const char* backends, + bool fastmath, + const char* additional_parameters) +{ + flatbuffers::FlatBufferBuilder flatbuffer_builder; + + flatbuffers::Offset<tflite::ArmNNSettings> + armnn_settings_offset = tflite::CreateArmNNSettingsDirect(flatbuffer_builder, + backends, + fastmath, + additional_parameters); + + tflite::TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder); + tflite_settings_builder.add_armnn_settings(armnn_settings_offset); + flatbuffers::Offset<tflite::TFLiteSettings> tflite_settings_offset = tflite_settings_builder.Finish(); + flatbuffer_builder.Finish(tflite_settings_offset); + + const tflite::TFLiteSettings* tflite_settings = flatbuffers::GetRoot<tflite::TFLiteSettings>( + flatbuffer_builder.GetBufferPointer()); + + armnnDelegate::DelegateOptions delegateOptions = ParseArmNNSettings(tflite_settings); + + return delegateOptions; +} + +unsigned int CountBackendOptions(armnn::BackendId backendId, + armnnDelegate::DelegateOptions& delegateOptions, + bool runtime = false) +{ + unsigned int count = 0; + + std::vector<armnn::BackendOptions> modelOptions = runtime ? delegateOptions.GetRuntimeOptions().m_BackendOptions + : delegateOptions.GetOptimizerOptions().GetModelOptions(); + for (const auto& backendOptions : modelOptions) + { + if (backendOptions.GetBackendId() == backendId) + { + count = backendOptions.GetOptionCount(); + } + } + + return count; +} + +bool GetBackendOption(armnn::BackendId backendId, + armnnDelegate::DelegateOptions& delegateOptions, + std::string& optionName, + armnn::BackendOptions::BackendOption& backendOption, + bool runtime = false) +{ + bool result = false; + + std::vector<armnn::BackendOptions> modelOptions = runtime ? delegateOptions.GetRuntimeOptions().m_BackendOptions + : delegateOptions.GetOptimizerOptions().GetModelOptions(); + + for (const auto& backendOptions : modelOptions) + { + if (backendOptions.GetBackendId() == backendId) + { + for (size_t i = 0; i < backendOptions.GetOptionCount(); ++i) + { + const armnn::BackendOptions::BackendOption& option = backendOptions.GetOption(i); + if (option.GetName() == optionName) + { + backendOption = option; + result = true; + break; + } + } + } + } + + return result; +} + +TEST_CASE ("ParseArmNNSettings_backend") +{ + { + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuRef,GpuAcc", false, nullptr); + + std::vector<armnn::BackendId> expectedBackends = {"CpuRef", "GpuAcc"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + } + { + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, nullptr); + + std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + } +} + +TEST_CASE ("ParseArmNNSettings_fastmath") +{ + // Test fastmath true in both backends + { + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,GpuAcc", true, nullptr); + + std::vector<armnn::BackendId> expectedBackends = {"CpuAcc", "GpuAcc"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1); + CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1); + + armnn::BackendOptions::BackendOption backendOption("", false); + std::string optionName = "FastMathEnabled"; + CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsBool(), true); + CHECK_EQ(backendOption.GetName(), optionName); + CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsBool(), true); + CHECK_EQ(backendOption.GetName(), optionName); + } + + // Test fastmath true in one backend + { + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,CpuRef", true, nullptr); + + std::vector<armnn::BackendId> expectedBackends = {"CpuAcc", "CpuRef"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1); + CHECK_EQ(CountBackendOptions(armnn::Compute::CpuRef, delegateOptions), 0); + + armnn::BackendOptions::BackendOption backendOption("", false); + std::string optionName = "FastMathEnabled"; + CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsBool(), true); + CHECK_EQ(backendOption.GetName(), optionName); + CHECK_EQ(GetBackendOption(armnn::Compute::CpuRef, delegateOptions, optionName, backendOption), false); + } + + // Test fastmath false + { + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, nullptr); + + std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions), 1); + + armnn::BackendOptions::BackendOption backendOption("", false); + std::string optionName = "FastMathEnabled"; + CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsBool(), false); + CHECK_EQ(backendOption.GetName(), optionName); + } +} + +TEST_CASE ("ParseArmNNSettings_additional_options_raw") +{ + const char* backends = "GpuAcc"; + bool fastmath = false; + const char* additional_parameters = "allow-expanded-dims=true"; + + flatbuffers::FlatBufferBuilder flatbuffer_builder; + flatbuffers::Offset<tflite::ArmNNSettings> + armnn_settings_offset = tflite::CreateArmNNSettingsDirect(flatbuffer_builder, + backends, + fastmath, + additional_parameters); + + tflite::TFLiteSettingsBuilder tflite_settings_builder(flatbuffer_builder); + tflite_settings_builder.add_armnn_settings(armnn_settings_offset); + flatbuffers::Offset<tflite::TFLiteSettings> tflite_settings_offset = tflite_settings_builder.Finish(); + flatbuffer_builder.Finish(tflite_settings_offset); + + const tflite::TFLiteSettings* tflite_settings = flatbuffers::GetRoot<tflite::TFLiteSettings>( + flatbuffer_builder.GetBufferPointer()); + CHECK((tflite_settings->armnn_settings()->additional_parameters() != nullptr)); + CHECK_EQ(tflite_settings->armnn_settings()->additional_parameters()->str(), additional_parameters); + + armnnDelegate::DelegateOptions delegateOptions = ParseArmNNSettings(tflite_settings); + CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true); +} + +TEST_CASE ("ParseArmNNSettings_additional_options") +{ + std::string options = "number-of-threads=29," // optimizer-backend option only Cpu + "gpu-kernel-profiling-enabled=true," // runtime-backend option only GPU + "allow-expanded-dims=true," // optimizer option + "logging-severity=debug," // option + "counter-capture-period=100u"; // runtime-profiling option + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("CpuAcc,GpuAcc", false, options.c_str()); + + // Variables to be used in all checks + armnn::BackendOptions::BackendOption backendOption("", false); + std::string optionName; + + // number-of-threads + CHECK_EQ(CountBackendOptions(armnn::Compute::CpuAcc, delegateOptions), 1); + optionName = "NumberOfThreads"; + CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsUnsignedInt(), 29); + CHECK_EQ(backendOption.GetName(), optionName); + + // gpu-kernel-profiling-enabled + CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions, true), 1); + optionName = "KernelProfilingEnabled"; + CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption, true), true); + CHECK_EQ(backendOption.GetValue().AsBool(), true); + CHECK_EQ(backendOption.GetName(), optionName); + + // allow-expanded-dims + CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true); + + // logging-severity + CHECK_EQ(delegateOptions.GetLoggingSeverity(), armnn::LogSeverity::Debug); + + // counter-capture-period + CHECK_EQ(delegateOptions.GetRuntimeOptions().m_ProfilingOptions.m_CapturePeriod, 100); +} + +TEST_CASE ("ParseArmNNSettings_additional_options_regex") +{ + std::string options = "allow-expanded-dims= true, " // optimizer option + "number-of-threads =29 ," // optimizer-backend option only Cpu + "logging-severity = trace , " // option + "counter-capture-period = 100u"; // runtime-profiling option + armnnDelegate::DelegateOptions delegateOptions = BuildDelegateOptions("GpuAcc", false, options.c_str()); + + // Variables to be used in all checks + armnn::BackendOptions::BackendOption backendOption("", false); + std::string optionName; + + std::vector<armnn::BackendId> expectedBackends = {"GpuAcc"}; + CHECK_EQ(expectedBackends, delegateOptions.GetBackends()); + + // enable-fast-math + CHECK_EQ(CountBackendOptions(armnn::Compute::GpuAcc, delegateOptions), 1); + optionName = "FastMathEnabled"; + CHECK_EQ(GetBackendOption(armnn::Compute::CpuRef, delegateOptions, optionName, backendOption), false); + CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), false); + CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), true); + CHECK_EQ(backendOption.GetValue().AsBool(), false); + CHECK_EQ(backendOption.GetName(), optionName); + + // allow-expanded-dims + CHECK_EQ(delegateOptions.GetOptimizerOptions().GetAllowExpandedDims(), true); + + // number-of-threads not saved anywhere, as it is a parameter only valid for CpuAcc + optionName="number-of-threads"; + CHECK_EQ(GetBackendOption(armnn::Compute::CpuAcc, delegateOptions, optionName, backendOption), false); + CHECK_EQ(GetBackendOption(armnn::Compute::GpuAcc, delegateOptions, optionName, backendOption), false); + + // logging-severity + CHECK_EQ(delegateOptions.GetLoggingSeverity(), armnn::LogSeverity::Trace); + + // counter-capture-period + CHECK_EQ(delegateOptions.GetRuntimeOptions().m_ProfilingOptions.m_CapturePeriod, 100); +} + +TEST_CASE ("ParseArmNNSettings_additional_options_incorrect") +{ + std::string options = "number-of-thread=29"; // The correct one would be "number-of-threads" in plural + + CHECK_THROWS(BuildDelegateOptions("CpuAcc,GpuAcc", false, options.c_str())); +} + } } // namespace armnnDelegate |