ArmNN
 21.08
ClCustomAllocatorTests.cpp File Reference
#include <armnn/backends/ICustomAllocator.hpp>
#include <armnn/Descriptors.hpp>
#include <armnn/Exceptions.hpp>
#include <armnn/INetwork.hpp>
#include <armnn/IRuntime.hpp>
#include <armnn/Utils.hpp>
#include <armnn/BackendRegistry.hpp>
#include <cl/ClBackend.hpp>
#include <neon/NeonBackend.hpp>
#include <doctest/doctest.h>
#include <arm_compute/core/CL/CLKernelLibrary.h>
#include <CL/cl_ext.h>
#include <arm_compute/runtime/CL/CLScheduler.h>

Go to the source code of this file.

Functions

armnn::INetworkPtr CreateTestNetwork (armnn::TensorInfo &inputTensorInfo)
 
 TEST_SUITE ("ClCustomAllocatorTests")
 

Function Documentation

◆ CreateTestNetwork()

armnn::INetworkPtr CreateTestNetwork ( armnn::TensorInfo inputTensorInfo)

Definition at line 63 of file ClCustomAllocatorTests.cpp.

References ARMNN_NO_DEPRECATE_WARN_BEGIN, ARMNN_NO_DEPRECATE_WARN_END, OutputSlot::Connect(), IConnectableLayer::GetInputSlot(), Layer::GetOutputSlot(), and TensorInfo::SetConstant().

Referenced by TEST_SUITE().

64 {
65  using namespace armnn;
66  INetworkPtr myNetwork = INetwork::Create();
67 
68  armnn::FullyConnectedDescriptor fullyConnectedDesc;
69  float weightsData[] = {1.0f}; // Identity
70  TensorInfo weightsInfo(TensorShape({1, 1}), DataType::Float32);
71  weightsInfo.SetConstant(true);
72  armnn::ConstTensor weights(weightsInfo, weightsData);
73 
75  IConnectableLayer* fullyConnected = myNetwork->AddFullyConnectedLayer(fullyConnectedDesc,
76  weights,
77  EmptyOptional(),
78  "fully connected");
80  IConnectableLayer* InputLayer = myNetwork->AddInputLayer(0);
81  IConnectableLayer* OutputLayer = myNetwork->AddOutputLayer(0);
82  InputLayer->GetOutputSlot(0).Connect(fullyConnected->GetInputSlot(0));
83  fullyConnected->GetOutputSlot(0).Connect(OutputLayer->GetInputSlot(0));
84 
85  //Set the tensors in the network.
86 
87  InputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
88 
89  TensorInfo outputTensorInfo(TensorShape({1, 1}), DataType::Float32);
90  fullyConnected->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
91 
92  return myNetwork;
93 }
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
Definition: INetwork.hpp:61
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
Definition: Deprecated.hpp:33
int Connect(InputSlot &destination)
Definition: Layer.cpp:83
Copyright (c) 2021 ARM Limited and Contributors.
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: OutputLayer.hpp:13
#define ARMNN_NO_DEPRECATE_WARN_END
Definition: Deprecated.hpp:34
A FullyConnectedDescriptor for the FullyConnectedLayer.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:327
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition: Optional.hpp:32
A layer user-provided data can be bound to (e.g. inputs, outputs).
Definition: InputLayer.hpp:13
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
const OutputSlot & GetOutputSlot(unsigned int index=0) const override
Get the const output slot handle by slot index.
Definition: Layer.hpp:318
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:172
static INetworkPtr Create(NetworkOptions networkOptions={})
Definition: Network.cpp:530

◆ TEST_SUITE()

TEST_SUITE ( "ClCustomAllocatorTests"  )

Definition at line 95 of file ClCustomAllocatorTests.cpp.

References CreateTestNetwork(), and IRuntime::CreationOptions::m_CustomAllocatorMap.

96 {
97 
98 // This is a copy of the SimpleSample app modified to use a custom
99 // allocator for the clbackend. It creates a FullyConnected network with a single layer
100 // taking a single number as an input
101 TEST_CASE("ClCustomAllocatorTest")
102 {
103  using namespace armnn;
104 
105  float number = 3;
106 
107  // Construct ArmNN network
108  armnn::NetworkId networkIdentifier;
109 
110  TensorInfo inputTensorInfo(TensorShape({1, 1}), DataType::Float32);
111 
112  INetworkPtr myNetwork = CreateTestNetwork(inputTensorInfo);
113 
114  // Create ArmNN runtime
115  IRuntime::CreationOptions options; // default options
116  auto customAllocator = std::make_shared<SampleClBackendCustomAllocator>();
117  options.m_CustomAllocatorMap = {{"GpuAcc", std::move(customAllocator)}};
118  IRuntimePtr run = IRuntime::Create(options);
119 
120  // Optimise ArmNN network
121  OptimizerOptions optOptions;
122  optOptions.m_ImportEnabled = true;
123  armnn::IOptimizedNetworkPtr optNet = Optimize(*myNetwork, {"GpuAcc"}, run->GetDeviceSpec(), optOptions);
124  CHECK(optNet);
125 
126  // Load graph into runtime
127  std::string ignoredErrorMessage;
129  run->LoadNetwork(networkIdentifier, std::move(optNet), ignoredErrorMessage, networkProperties);
130 
131  // Creates structures for input & output
132  unsigned int numElements = inputTensorInfo.GetNumElements();
133  size_t totalBytes = numElements * sizeof(float);
134 
135  const size_t alignment =
136  arm_compute::CLKernelLibrary::get().get_device().getInfo<CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE>();
137 
138  void* alignedInputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, alignment);
139 
140  // Input with negative values
141  auto* inputPtr = reinterpret_cast<float*>(alignedInputPtr);
142  std::fill_n(inputPtr, numElements, number);
143 
144  void* alignedOutputPtr = options.m_CustomAllocatorMap["GpuAcc"]->allocate(totalBytes, alignment);
145  auto* outputPtr = reinterpret_cast<float*>(alignedOutputPtr);
146  std::fill_n(outputPtr, numElements, -10.0f);
147 
148  armnn::InputTensors inputTensors
149  {
150  {0, armnn::ConstTensor(run->GetInputTensorInfo(networkIdentifier, 0), alignedInputPtr)},
151  };
152  armnn::OutputTensors outputTensors
153  {
154  {0, armnn::Tensor(run->GetOutputTensorInfo(networkIdentifier, 0), alignedOutputPtr)}
155  };
156 
157  // Execute network
158  run->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
159  run->UnloadNetwork(networkIdentifier);
160 
161 
162  // Tell the CLBackend to sync memory so we can read the output.
163  arm_compute::CLScheduler::get().sync();
164  auto* outputResult = reinterpret_cast<float*>(alignedOutputPtr);
165 
166  run->UnloadNetwork(networkIdentifier);
167  CHECK(outputResult[0] == number);
168  auto& backendRegistry = armnn::BackendRegistryInstance();
169  backendRegistry.DeregisterAllocator(ClBackend::GetIdStatic());
170 }
171 
172 // Only run this test if NEON is enabled
173 #if defined(ARMCOMPUTENEON_ENABLED)
174 
175 TEST_CASE("ClCustomAllocatorCpuAccNegativeTest")
176 {
177  using namespace armnn;
178 
179  // Create ArmNN runtime
180  IRuntime::CreationOptions options; // default options
181  auto customAllocator = std::make_shared<SampleClBackendCustomAllocator>();
182  options.m_CustomAllocatorMap = {{"CpuAcc", std::move(customAllocator)}};
183  IRuntimePtr run = IRuntime::Create(options);
184  TensorInfo inputTensorInfo(TensorShape({1, 1}), DataType::Float32);
185  INetworkPtr myNetwork = CreateTestNetwork(inputTensorInfo);
186 
187  // Optimise ArmNN network
188  OptimizerOptions optOptions;
189  optOptions.m_ImportEnabled = true;
190  IOptimizedNetworkPtr optNet(nullptr, nullptr);
191  std::vector<std::string> errMessages;
192 
193  CHECK_THROWS_AS_MESSAGE(Optimize(*myNetwork, {"CpuAcc"}, run->GetDeviceSpec(), optOptions, errMessages),
195  "Expected an exception as GetAvailablePreferredBackends() should be empty in Optimize().");
196 
197  auto& backendRegistry = armnn::BackendRegistryInstance();
198  backendRegistry.DeregisterAllocator(NeonBackend::GetIdStatic());
199 }
200 
201 #endif
202 
203 TEST_CASE("ClCustomAllocatorGpuAccNullptrTest")
204 {
205  using namespace armnn;
206 
207  // Create ArmNN runtime
208  IRuntime::CreationOptions options; // default options
209  auto customAllocator = std::make_shared<SampleClBackendCustomAllocator>();
210  options.m_CustomAllocatorMap = {{"GpuAcc", nullptr}};
211 
212  CHECK_THROWS_AS_MESSAGE(IRuntimePtr run = IRuntime::Create(options),
214  "Expected exception in RuntimeImpl::RuntimeImpl() as allocator was nullptr.");
215 }
216 
217 }
static IRuntimePtr Create(const CreationOptions &options)
Definition: Runtime.cpp:39
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
Definition: IRuntime.hpp:30
BackendRegistry & BackendRegistryInstance()
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Definition: Tensor.hpp:360
Copyright (c) 2021 ARM Limited and Contributors.
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Definition: Tensor.hpp:319
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
Definition: Network.cpp:1613
int NetworkId
Definition: IRuntime.hpp:24
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:327
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
Definition: Tensor.hpp:361
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
Definition: INetwork.hpp:173
std::map< BackendId, std::shared_ptr< ICustomAllocator > > m_CustomAllocatorMap
A map to define a custom memory allocator for specific backend Ids.
Definition: IRuntime.hpp:136
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
static const BackendId & GetIdStatic()
Definition: NeonBackend.cpp:43
armnn::INetworkPtr CreateTestNetwork(armnn::TensorInfo &inputTensorInfo)
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
Definition: INetwork.hpp:172
static const BackendId & GetIdStatic()
Definition: ClBackend.cpp:44