aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadik Armagan <sadik.armagan@arm.com>2021-10-04 15:13:11 +0100
committerTeresaARM <teresa.charlinreyes@arm.com>2021-10-06 13:27:57 +0000
commitb8a26d8f497f92643288a4c519af4d230ede1d7e (patch)
tree89b1ad2303b8a18d4491eb47ab16f37e53e33c37
parentbc3bb62c2d5b881ca7f0b3973a533134196fc802 (diff)
downloadarmnn-b8a26d8f497f92643288a4c519af4d230ede1d7e.tar.gz
IVGCVSW-6300 'IMemoryOptimizerStrategy Add strategy library and add support in BackendRegistry'
* Updated IRuntime interface for providing custom memory optimizer strategy. * Enabled selecting existing memory optimizer strategy by using BackendOptions * Added MemoryOptimizerStrategyLibrary that sets one of the existing memory optimizer strategies selected by user Signed-off-by: Sadik Armagan <sadik.armagan@arm.com> Change-Id: I037f8ac8efa79c0f71bd63e379101e3ad92d80c9
-rw-r--r--include/armnn/BackendOptions.hpp18
-rw-r--r--include/armnn/BackendRegistry.hpp7
-rw-r--r--include/armnn/IRuntime.hpp14
-rw-r--r--include/armnn/TypesUtils.hpp10
-rw-r--r--src/armnn/BackendRegistry.cpp22
-rw-r--r--src/armnn/Runtime.cpp40
-rw-r--r--src/backends/backendsCommon/CMakeLists.txt3
-rw-r--r--src/backends/backendsCommon/MemoryOptimizerStrategyFactory.hpp28
-rw-r--r--src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.cpp68
-rw-r--r--src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.hpp21
-rw-r--r--src/backends/backendsCommon/common.mk2
-rw-r--r--src/backends/backendsCommon/test/BackendRegistryTests.cpp21
-rw-r--r--src/backends/backendsCommon/test/CMakeLists.txt1
-rw-r--r--src/backends/backendsCommon/test/CustomMemoryOptimizerStrategyTests.cpp125
-rw-r--r--src/backends/cl/ClBackend.hpp3
-rw-r--r--src/backends/neon/NeonBackend.hpp3
-rw-r--r--src/backends/reference/RefBackend.hpp3
17 files changed, 386 insertions, 3 deletions
diff --git a/include/armnn/BackendOptions.hpp b/include/armnn/BackendOptions.hpp
index b8bf8f51f2..33cecf6614 100644
--- a/include/armnn/BackendOptions.hpp
+++ b/include/armnn/BackendOptions.hpp
@@ -296,4 +296,22 @@ void ParseOptions(const std::vector<BackendOptions>& options, BackendId backend,
}
}
+inline bool ParseBooleanBackendOption(const armnn::BackendOptions::Var& value, bool defaultValue)
+{
+ if (value.IsBool())
+ {
+ return value.AsBool();
+ }
+ return defaultValue;
+}
+
+inline std::string ParseStringBackendOption(const armnn::BackendOptions::Var& value, std::string defaultValue)
+{
+ if (value.IsString())
+ {
+ return value.AsString();
+ }
+ return defaultValue;
+}
+
} //namespace armnn
diff --git a/include/armnn/BackendRegistry.hpp b/include/armnn/BackendRegistry.hpp
index c13aa9f8b6..0d09607de2 100644
--- a/include/armnn/BackendRegistry.hpp
+++ b/include/armnn/BackendRegistry.hpp
@@ -8,7 +8,9 @@
#include <armnn/BackendId.hpp>
#include <armnn/Optional.hpp>
#include <armnn/backends/ICustomAllocator.hpp>
+#include <armnn/backends/IMemoryOptimizerStrategy.hpp>
+#include <algorithm>
#include <memory>
#include <unordered_map>
#include <functional>
@@ -22,6 +24,7 @@ namespace profiling
}
class IBackendInternal;
using IBackendInternalUniquePtr = std::unique_ptr<IBackendInternal>;
+using MemoryOptimizerStrategiesMapRef = std::unordered_map<BackendId, std::shared_ptr<IMemoryOptimizerStrategy>>;
class BackendRegistry
{
@@ -38,6 +41,8 @@ public:
void SetProfilingService(armnn::Optional<profiling::ProfilingService&> profilingService);
void RegisterAllocator(const BackendId& id, std::shared_ptr<ICustomAllocator> alloc);
std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> GetAllocators();
+ void RegisterMemoryOptimizerStrategy(const BackendId& id, std::shared_ptr<IMemoryOptimizerStrategy> strategy);
+ MemoryOptimizerStrategiesMapRef GetMemoryOptimizerStrategies();
BackendRegistry() {}
virtual ~BackendRegistry() {}
@@ -54,6 +59,7 @@ public:
void Deregister(const BackendId& id);
void DeregisterAllocator(const BackendId &id);
+ void DeregisterMemoryOptimizerStrategy(const BackendId &id);
protected:
using FactoryStorage = std::unordered_map<BackendId, FactoryFunction>;
@@ -68,6 +74,7 @@ private:
FactoryStorage m_Factories;
armnn::Optional<profiling::ProfilingService&> m_ProfilingService;
std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> m_CustomMemoryAllocatorMap;
+ std::unordered_map<BackendId, std::shared_ptr<IMemoryOptimizerStrategy>> m_MemoryOptimizerStrategyMap;
};
BackendRegistry& BackendRegistryInstance();
diff --git a/include/armnn/IRuntime.hpp b/include/armnn/IRuntime.hpp
index a46830c95a..ca9a0ceec2 100644
--- a/include/armnn/IRuntime.hpp
+++ b/include/armnn/IRuntime.hpp
@@ -15,6 +15,7 @@
#include "profiling/ILocalPacketHandler.hpp"
#include <armnn/backends/ICustomAllocator.hpp>
+#include <armnn/backends/IMemoryOptimizerStrategy.hpp>
#include <memory>
#include <map>
@@ -106,6 +107,7 @@ public:
, m_DynamicBackendsPath("")
, m_ProtectedMode(false)
, m_CustomAllocatorMap()
+ , m_MemoryOptimizerStrategyMap()
{}
/// If set, uses the GpuAcc tuned parameters from the given object when executing GPU workloads.
@@ -135,6 +137,14 @@ public:
/// @note Only supported for GpuAcc
std::map<BackendId, std::shared_ptr<ICustomAllocator>> m_CustomAllocatorMap;
+ /// @brief A map to define a custom memory optimizer strategy for specific backend Ids.
+ ///
+ /// @details A Memory Optimizer Strategy provides a solution to an abstract representation of
+ /// a network's memory requirements. This can also be used to return a pre-computed solution
+ /// for a specific network. Set this if you want to implement a Custom Memory Optimizer Strategy
+ /// for a given backend.
+ std::map<BackendId, std::shared_ptr<IMemoryOptimizerStrategy>> m_MemoryOptimizerStrategyMap;
+
struct ExternalProfilingOptions
{
ExternalProfilingOptions()
@@ -168,6 +178,7 @@ public:
/// {
/// {"TuningLevel", 2},
/// {"TuningFile", filename}
+ /// {"MemoryOptimizerStrategy", strategyname}
/// }
/// });
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -185,6 +196,9 @@ public:
/// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// The following backend options are available:
+ /// AllBackends:
+ /// "MemoryOptimizerStrategy" : string [stategynameString]
+ /// (Existing Memory Optimizer Strategies: ConstLayerMemoryOptimizerStrategy)
/// GpuAcc:
/// "TuningLevel" : int [0..3] (0=UseOnly(default) | 1=RapidTuning | 2=NormalTuning | 3=ExhaustiveTuning)
/// "TuningFile" : string [filenameString]
diff --git a/include/armnn/TypesUtils.hpp b/include/armnn/TypesUtils.hpp
index 9bd9c8148f..d08f592d86 100644
--- a/include/armnn/TypesUtils.hpp
+++ b/include/armnn/TypesUtils.hpp
@@ -249,6 +249,16 @@ constexpr const char* GetResizeMethodAsCString(ResizeMethod method)
}
}
+constexpr const char* GetMemBlockStrategyTypeName(MemBlockStrategyType memBlockStrategyType)
+{
+ switch (memBlockStrategyType)
+ {
+ case MemBlockStrategyType::SingleAxisPacking: return "SingleAxisPacking";
+ case MemBlockStrategyType::MultiAxisPacking: return "MultiAxisPacking";
+ default: return "Unknown";
+ }
+}
+
template<typename T>
struct IsHalfType
: std::integral_constant<bool, std::is_floating_point<T>::value && sizeof(T) == 2>
diff --git a/src/armnn/BackendRegistry.cpp b/src/armnn/BackendRegistry.cpp
index 80daed9896..ade844fc39 100644
--- a/src/armnn/BackendRegistry.cpp
+++ b/src/armnn/BackendRegistry.cpp
@@ -128,4 +128,26 @@ std::unordered_map<BackendId, std::shared_ptr<ICustomAllocator>> BackendRegistry
return m_CustomMemoryAllocatorMap;
}
+void BackendRegistry::RegisterMemoryOptimizerStrategy(const BackendId& id,
+ std::shared_ptr<IMemoryOptimizerStrategy> strategy)
+{
+ if (m_MemoryOptimizerStrategyMap.find(id) != m_MemoryOptimizerStrategyMap.end())
+ {
+ throw InvalidArgumentException(
+ std::string(id) + " already has an memory optimizer strategy associated with it",
+ CHECK_LOCATION());
+ }
+ m_MemoryOptimizerStrategyMap[id] = strategy;
+}
+
+void BackendRegistry::DeregisterMemoryOptimizerStrategy(const BackendId &id)
+{
+ m_MemoryOptimizerStrategyMap.erase(id);
+}
+
+MemoryOptimizerStrategiesMapRef BackendRegistry::GetMemoryOptimizerStrategies()
+{
+ return m_MemoryOptimizerStrategyMap;
+}
+
} // namespace armnn
diff --git a/src/armnn/Runtime.cpp b/src/armnn/Runtime.cpp
index 085cf2cee8..50068ebe36 100644
--- a/src/armnn/Runtime.cpp
+++ b/src/armnn/Runtime.cpp
@@ -12,6 +12,7 @@
#include <armnn/backends/IBackendContext.hpp>
#include <backendsCommon/DynamicBackendUtils.hpp>
+#include <backendsCommon/MemoryOptimizerStrategyLibrary.hpp>
#include <armnn/utility/PolymorphicDowncast.hpp>
#include <common/include/LabelsAndEventClasses.hpp>
@@ -373,6 +374,45 @@ RuntimeImpl::RuntimeImpl(const IRuntime::CreationOptions& options)
BackendRegistryInstance().RegisterAllocator(id, customAllocatorMapIterator->second);
}
}
+
+ // check if custom memory optimizer strategy map is set
+ if (!options.m_MemoryOptimizerStrategyMap.empty())
+ {
+ auto customMemoryOptimizerStrategyMapIterator = options.m_MemoryOptimizerStrategyMap.find(id);
+ // if a memory optimizer strategy is provided make the backend use that instead of the default
+ if (customMemoryOptimizerStrategyMapIterator != options.m_MemoryOptimizerStrategyMap.end())
+ {
+ // no errors.. register the memory optimizer strategy with the BackendRegistry
+ BackendRegistryInstance().RegisterMemoryOptimizerStrategy(
+ id, customMemoryOptimizerStrategyMapIterator->second);
+
+ ARMNN_LOG(info) << "MemoryOptimizerStrategy "
+ << customMemoryOptimizerStrategyMapIterator->second->GetName()
+ << " set for the backend " << id << ".";
+ }
+ }
+ else
+ {
+ // check if to use one of the existing memory optimizer strategies is set
+ std::string memoryOptimizerStrategyName = "";
+ ParseOptions(options.m_BackendOptions, id, [&](std::string name, const BackendOptions::Var& value)
+ {
+ if (name == "MemoryOptimizerStrategy")
+ {
+ memoryOptimizerStrategyName = ParseStringBackendOption(value, "");
+ }
+ });
+ if (memoryOptimizerStrategyName != "")
+ {
+ MemoryOptimizerStrategyLibrary memoryOptimizerStrategyLibrary;
+ if (memoryOptimizerStrategyLibrary.SetMemoryOptimizerStrategy(id, memoryOptimizerStrategyName))
+ {
+ ARMNN_LOG(info) << "MemoryOptimizerStrategy "
+ << memoryOptimizerStrategyName << " set for the backend " << id << ".";
+ }
+ }
+ }
+
auto context = backend->CreateBackendContext(options);
// backends are allowed to return nullptrs if they
diff --git a/src/backends/backendsCommon/CMakeLists.txt b/src/backends/backendsCommon/CMakeLists.txt
index c894f986c9..a18ee330d4 100644
--- a/src/backends/backendsCommon/CMakeLists.txt
+++ b/src/backends/backendsCommon/CMakeLists.txt
@@ -26,6 +26,9 @@ list(APPEND armnnBackendsCommon_sources
MemCopyWorkload.hpp
MemImportWorkload.cpp
MemImportWorkload.hpp
+ MemoryOptimizerStrategyFactory.hpp
+ MemoryOptimizerStrategyLibrary.cpp
+ MemoryOptimizerStrategyLibrary.hpp
MemSyncWorkload.cpp
MemSyncWorkload.hpp
OptimizationViews.cpp
diff --git a/src/backends/backendsCommon/MemoryOptimizerStrategyFactory.hpp b/src/backends/backendsCommon/MemoryOptimizerStrategyFactory.hpp
new file mode 100644
index 0000000000..62a2182a6e
--- /dev/null
+++ b/src/backends/backendsCommon/MemoryOptimizerStrategyFactory.hpp
@@ -0,0 +1,28 @@
+//
+// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <armnn/backends/IMemoryOptimizerStrategy.hpp>
+
+#include <algorithm>
+
+namespace armnn
+{
+
+class MemoryOptimizerStrategyFactory
+{
+public:
+ MemoryOptimizerStrategyFactory() {}
+
+ template <typename T>
+ std::shared_ptr<IMemoryOptimizerStrategy> CreateMemoryOptimizerStrategy()
+ {
+ return std::make_shared<T>();
+ }
+
+};
+
+} // namespace armnn \ No newline at end of file
diff --git a/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.cpp b/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.cpp
new file mode 100644
index 0000000000..0b48cbd176
--- /dev/null
+++ b/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.cpp
@@ -0,0 +1,68 @@
+//
+// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "MemoryOptimizerStrategyLibrary.hpp"
+#include "MemoryOptimizerStrategyFactory.hpp"
+
+#include <armnn/BackendHelper.hpp>
+#include <armnn/Logging.hpp>
+#include <armnn/TypesUtils.hpp>
+
+#include <armnn/backends/IMemoryOptimizerStrategy.hpp>
+
+#include <backendsCommon/memoryOptimizationStrategies/ConstLayerMemoryOptimizerStrategy.hpp>
+
+#include <algorithm>
+
+namespace
+{
+// Default Memory Optimizer Strategies
+static const std::vector<std::string> memoryOptimizationStrategies({
+ "ConstLayerMemoryOptimizerStrategy",
+ });
+
+#define CREATE_MEMORY_OPTIMIZER_STRATEGY(strategyName, memoryOptimizerStrategy) \
+{ \
+ MemoryOptimizerStrategyFactory memoryOptimizerStrategyFactory; \
+ memoryOptimizerStrategy = memoryOptimizerStrategyFactory.CreateMemoryOptimizerStrategy<strategyName>(); \
+} \
+
+} // anonymous namespace
+
+namespace armnn
+{
+
+bool MemoryOptimizerStrategyLibrary::SetMemoryOptimizerStrategy(const BackendId& id, const std::string& strategyName)
+{
+ auto isStrategyExist = std::find(memoryOptimizationStrategies.begin(),
+ memoryOptimizationStrategies.end(),
+ strategyName) != memoryOptimizationStrategies.end();
+ if (isStrategyExist)
+ {
+ std::shared_ptr<IMemoryOptimizerStrategy> memoryOptimizerStrategy = nullptr;
+ CREATE_MEMORY_OPTIMIZER_STRATEGY(armnn::ConstLayerMemoryOptimizerStrategy,
+ memoryOptimizerStrategy);
+ if (memoryOptimizerStrategy)
+ {
+ using BackendCapability = BackendOptions::BackendOption;
+ auto strategyType = GetMemBlockStrategyTypeName(memoryOptimizerStrategy->GetMemBlockStrategyType());
+ BackendCapability memOptimizeStrategyCapability {strategyType, true};
+ if (HasCapability(memOptimizeStrategyCapability, id))
+ {
+ BackendRegistryInstance().RegisterMemoryOptimizerStrategy(id, memoryOptimizerStrategy);
+ return true;
+ }
+ // reset shared_ptr memoryOptimizerStrategy
+ memoryOptimizerStrategy.reset();
+ }
+ }
+ ARMNN_LOG(warning) << "Backend "
+ << id
+ << " is not registered as does not support memory optimizer strategy "
+ << strategyName << " \n";
+ return false;
+}
+
+} // namespace armnn \ No newline at end of file
diff --git a/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.hpp b/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.hpp
new file mode 100644
index 0000000000..795fc640b9
--- /dev/null
+++ b/src/backends/backendsCommon/MemoryOptimizerStrategyLibrary.hpp
@@ -0,0 +1,21 @@
+//
+// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include <armnn/BackendRegistry.hpp>
+
+namespace armnn
+{
+
+class MemoryOptimizerStrategyLibrary
+{
+public:
+ MemoryOptimizerStrategyLibrary() = default;
+
+ bool SetMemoryOptimizerStrategy(const BackendId& id, const std::string& strategyName);
+
+};
+
+} // namespace armnn \ No newline at end of file
diff --git a/src/backends/backendsCommon/common.mk b/src/backends/backendsCommon/common.mk
index 8c1037ad19..2795c9cc2f 100644
--- a/src/backends/backendsCommon/common.mk
+++ b/src/backends/backendsCommon/common.mk
@@ -17,6 +17,7 @@ COMMON_SOURCES := \
MapWorkload.cpp \
MemCopyWorkload.cpp \
MemImportWorkload.cpp \
+ MemoryOptimizerStrategyLibrary.cpp \
MemSyncWorkload.cpp \
OptimizationViews.cpp \
TensorHandleFactoryRegistry.cpp \
@@ -32,6 +33,7 @@ COMMON_SOURCES := \
COMMON_TEST_SOURCES := \
test/CommonTestUtils.cpp \
+ test/CustomMemoryOptimizerStrategyTests.cpp \
test/InstanceNormalizationEndToEndTestImpl.cpp \
test/JsonPrinterTestImpl.cpp \
test/LogSoftmaxEndToEndTestImpl.cpp \
diff --git a/src/backends/backendsCommon/test/BackendRegistryTests.cpp b/src/backends/backendsCommon/test/BackendRegistryTests.cpp
index ba21b332e1..5acc61fe2c 100644
--- a/src/backends/backendsCommon/test/BackendRegistryTests.cpp
+++ b/src/backends/backendsCommon/test/BackendRegistryTests.cpp
@@ -7,6 +7,7 @@
#include <armnn/BackendRegistry.hpp>
#include <armnn/backends/IBackendInternal.hpp>
+#include <backendsCommon/memoryOptimizationStrategies/ConstLayerMemoryOptimizerStrategy.hpp>
#include <reference/RefBackend.hpp>
#include <doctest/doctest.h>
@@ -145,4 +146,24 @@ TEST_CASE("ThrowBackendUnavailableException")
BackendRegistryInstance().Deregister(mockBackendId);
}
+#if defined(ARMNNREF_ENABLED)
+TEST_CASE("RegisterMemoryOptimizerStrategy")
+{
+ using namespace armnn;
+
+ const BackendId cpuRefBackendId(armnn::Compute::CpuRef);
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+
+ // Register the memory optimizer
+ std::shared_ptr<IMemoryOptimizerStrategy> memoryOptimizerStrategy =
+ std::make_shared<ConstLayerMemoryOptimizerStrategy>();
+ BackendRegistryInstance().RegisterMemoryOptimizerStrategy(cpuRefBackendId, memoryOptimizerStrategy);
+ CHECK(!BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().size() == 1);
+ // De-register the memory optimizer
+ BackendRegistryInstance().DeregisterMemoryOptimizerStrategy(cpuRefBackendId);
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+}
+#endif
+
}
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt
index ea33513097..e3221c5ae4 100644
--- a/src/backends/backendsCommon/test/CMakeLists.txt
+++ b/src/backends/backendsCommon/test/CMakeLists.txt
@@ -13,6 +13,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources
ChannelShuffleEndToEndTestImpl.hpp
ComparisonEndToEndTestImpl.hpp
CompatibilityTests.cpp
+ CustomMemoryOptimizerStrategyTests.cpp
DefaultAsyncExecuteTest.cpp
DepthToSpaceEndToEndTestImpl.hpp
DequantizeEndToEndTestImpl.hpp
diff --git a/src/backends/backendsCommon/test/CustomMemoryOptimizerStrategyTests.cpp b/src/backends/backendsCommon/test/CustomMemoryOptimizerStrategyTests.cpp
new file mode 100644
index 0000000000..a5bf17c8b1
--- /dev/null
+++ b/src/backends/backendsCommon/test/CustomMemoryOptimizerStrategyTests.cpp
@@ -0,0 +1,125 @@
+//
+// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include <armnn/IRuntime.hpp>
+#include <armnn/Utils.hpp>
+#include <armnn/BackendRegistry.hpp>
+
+#include <armnn/backends/IMemoryOptimizerStrategy.hpp>
+
+#if defined(ARMNNREF_ENABLED)
+#include <reference/RefBackend.hpp>
+#endif
+
+#if defined(ARMCOMPUTENEON_ENABLED)
+#include <neon/NeonBackend.hpp>
+#endif
+
+#include <doctest/doctest.h>
+
+
+// Sample implementation of IMemoryOptimizerStrategy..
+class SampleMemoryOptimizerStrategy : public armnn::IMemoryOptimizerStrategy
+{
+public:
+ SampleMemoryOptimizerStrategy() = default;
+
+ std::string GetName() const
+ {
+ return std::string("SampleMemoryOptimizerStrategy");
+ }
+
+ armnn::MemBlockStrategyType GetMemBlockStrategyType() const
+ {
+ return armnn::MemBlockStrategyType::SingleAxisPacking;
+ }
+
+ std::vector<armnn::MemBin> Optimize(std::vector<armnn::MemBlock>& memBlocks)
+ {
+ std::vector<armnn::MemBin> memBins;
+ memBins.reserve(memBlocks.size());
+ return memBins;
+ }
+};
+
+TEST_SUITE("CustomMemoryOptimizerStrategyTests")
+{
+
+// Only run this test if CpuRef is enabled
+#if defined(ARMNNREF_ENABLED)
+TEST_CASE("RefCustomMemoryOptimizerStrategyTest")
+{
+ using namespace armnn;
+
+ // Create ArmNN runtime
+ IRuntime::CreationOptions options; // default options
+ auto customMemoryOptimizerStrategy = std::make_shared<SampleMemoryOptimizerStrategy>();
+ options.m_MemoryOptimizerStrategyMap = {{"CpuRef", std::move(customMemoryOptimizerStrategy)}};
+ IRuntimePtr run = IRuntime::Create(options);
+
+ CHECK(!BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().size() == 1);
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().at(RefBackend::GetIdStatic()));
+ auto optimizerStrategy = BackendRegistryInstance().GetMemoryOptimizerStrategies().at(RefBackend::GetIdStatic());
+ CHECK(optimizerStrategy->GetName() == std::string("SampleMemoryOptimizerStrategy"));
+
+ // De-register the memory optimizer
+ BackendRegistryInstance().DeregisterMemoryOptimizerStrategy(RefBackend::GetIdStatic());
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+
+}
+
+TEST_CASE("CpuRefSetMemoryOptimizerStrategyTest")
+{
+ using namespace armnn;
+
+ // Create ArmNN runtime
+ IRuntime::CreationOptions options; // default options
+ options.m_BackendOptions.emplace_back(
+ BackendOptions{"CpuRef",
+ {
+ {"MemoryOptimizerStrategy", "ConstLayerMemoryOptimizerStrategy"}
+ }
+ });
+
+ IRuntimePtr run = IRuntime::Create(options);
+
+ // ConstLayerMemoryOptimizerStrategy should be registered for CpuRef
+ CHECK(!BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().size() == 1);
+ CHECK(BackendRegistryInstance().GetMemoryOptimizerStrategies().at(RefBackend::GetIdStatic()));
+ auto optimizerStrategy = BackendRegistryInstance().GetMemoryOptimizerStrategies().at(RefBackend::GetIdStatic());
+ CHECK(optimizerStrategy->GetName() == std::string("ConstLayerMemoryOptimizerStrategy"));
+ armnn::BackendRegistryInstance().DeregisterMemoryOptimizerStrategy(RefBackend::GetIdStatic());
+}
+
+#endif
+
+// Only run this test if CpuAcc is enabled
+#if defined(ARMCOMPUTENEON_ENABLED)
+
+TEST_CASE("CpuAccSetMemoryOptimizerStrategyTest")
+{
+ using namespace armnn;
+
+ // Create ArmNN runtime
+ IRuntime::CreationOptions options; // default options
+ options.m_BackendOptions.emplace_back(
+ BackendOptions{"CpuAcc",
+ {
+ {"MemoryOptimizerStrategy", "NotExistMemoryOptimizerStrategy"}
+ }
+ });
+
+ IRuntimePtr run = IRuntime::Create(options);
+
+ // No MemoryOptimizerStrategy should be registered..
+ CHECK(armnn::BackendRegistryInstance().GetMemoryOptimizerStrategies().empty());
+ armnn::BackendRegistryInstance().DeregisterMemoryOptimizerStrategy(NeonBackend::GetIdStatic());
+}
+
+#endif
+
+} // test suite CustomMemoryOptimizerStrategyTests \ No newline at end of file
diff --git a/src/backends/cl/ClBackend.hpp b/src/backends/cl/ClBackend.hpp
index 80e4b97ff4..e0708d18e2 100644
--- a/src/backends/cl/ClBackend.hpp
+++ b/src/backends/cl/ClBackend.hpp
@@ -30,7 +30,8 @@ const BackendCapabilities gpuAccCapabilities("GpuAcc",
{"ConstantTensorsAsInputs", false},
{"PreImportIOTensors", false},
{"ExternallyManagedMemory", false},
- {"MultiAxisPacking", false}
+ {"MultiAxisPacking", false},
+ {"SingleAxisPacking", true}
});
class ClBackend : public IBackendInternal
diff --git a/src/backends/neon/NeonBackend.hpp b/src/backends/neon/NeonBackend.hpp
index d28ac3bfcd..37e1722984 100644
--- a/src/backends/neon/NeonBackend.hpp
+++ b/src/backends/neon/NeonBackend.hpp
@@ -18,7 +18,8 @@ const BackendCapabilities cpuAccCapabilities("GpuAcc",
{"ConstantTensorsAsInputs", false},
{"PreImportIOTensors", false},
{"ExternallyManagedMemory", false},
- {"MultiAxisPacking", false}
+ {"MultiAxisPacking", false},
+ {"SingleAxisPacking", true}
});
diff --git a/src/backends/reference/RefBackend.hpp b/src/backends/reference/RefBackend.hpp
index c04bf43db3..93a1cf4844 100644
--- a/src/backends/reference/RefBackend.hpp
+++ b/src/backends/reference/RefBackend.hpp
@@ -17,7 +17,8 @@ const BackendCapabilities cpuRefCapabilities("CpuRef",
{"ConstantTensorsAsInputs", true},
{"PreImportIOTensors", false},
{"ExternallyManagedMemory", false},
- {"MultiAxisPacking", false}
+ {"MultiAxisPacking", false},
+ {"SingleAxisPacking", true}
});
const std::set<armnn::BackendCapability> oldCpuRefCapabilities {