blob: 091dcefe8b0f0112f6f6872aace6df9d8f7ab6e7 [file] [log] [blame]
//
// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>
#include <opaque/include/armnn_delegate.hpp>
namespace armnnOpaqueDelegate
{
TEST_SUITE("ArmnnOpaqueDelegate")
{
TEST_CASE ("DelegateOptions_OpaqueDelegateDefault")
{
// Check default options can be created
auto options = armnnOpaqueDelegate::TfLiteArmnnDelegateOptionsDefault();
armnnOpaqueDelegate::ArmnnOpaqueDelegate delegate(options);
// Check version returns correctly
auto version = delegate.GetVersion();
CHECK_EQ(version, OPAQUE_DELEGATE_VERSION);
auto* builder = delegate.GetDelegateBuilder();
CHECK(builder);
// Check Opaque delegate created
auto opaqueDelegate = armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateCreate(&options);
CHECK(opaqueDelegate);
// Check Opaque Delegate can be deleted
CHECK(opaqueDelegate->opaque_delegate_builder->data);
armnnOpaqueDelegate::TfLiteArmnnOpaqueDelegateDelete(opaqueDelegate);
}
TEST_CASE ("DelegatePluginTest")
{
// Use default settings until options have been enabled.
flatbuffers::FlatBufferBuilder flatBufferBuilder;
tflite::TFLiteSettingsBuilder tfliteSettingsBuilder(flatBufferBuilder);
flatbuffers::Offset<tflite::TFLiteSettings> tfliteSettings = tfliteSettingsBuilder.Finish();
flatBufferBuilder.Finish(tfliteSettings);
const tflite::TFLiteSettings* settings = flatbuffers::GetRoot<tflite::TFLiteSettings>(
flatBufferBuilder.GetBufferPointer());
std::unique_ptr<tflite::delegates::DelegatePluginInterface> delegatePlugin =
tflite::delegates::DelegatePluginRegistry::CreateByName("armnn_delegate", *settings);
// Plugin is created correctly using armnn_delegate name.
CHECK((delegatePlugin != nullptr));
tflite::delegates::TfLiteDelegatePtr armnnDelegate = delegatePlugin->Create();
// Armnn Opaque Delegate is created correctly.
CHECK((armnnDelegate != nullptr));
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