15 #include <arm_compute/runtime/Allocator.h> 18 #include <boost/test/unit_test.hpp> 22 using namespace armnn;
26 std::shared_ptr<NeonMemoryManager> memoryManager = std::make_shared<NeonMemoryManager>();
43 std::vector<Capability> capabilities = handleFactory.GetCapabilities(input,
46 BOOST_TEST(capabilities.empty());
50 BOOST_TEST(capabilities.empty());
54 BOOST_TEST(capabilities.empty());
59 std::shared_ptr<NeonMemoryManager> memoryManager = std::make_shared<NeonMemoryManager>();
75 std::vector<Capability> capabilities = handleFactory.GetCapabilities(input,
78 BOOST_TEST(capabilities.empty());
82 BOOST_TEST(capabilities.empty());
86 BOOST_TEST(capabilities.size() == 1);
88 BOOST_TEST(capabilities[0].m_Value);
115 std::array<armnn::TensorShape, 2> concatInputShapes = { intermediateInfo.GetShape(), intermediateInfo.GetShape() };
117 concatInputShapes.begin(), concatInputShapes.end(), 2),
"concatenation");
135 runtime->LoadNetwork(networkIdentifier, std::move(optimizedNet));
140 if (subTensorHandle && subTensorHandle->GetParent())
147 for (
auto&& layer : theGraph)
151 unsigned int numberOfSubTensors = 0;
152 for (
unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
157 ++numberOfSubTensors;
177 descriptor.m_PoolWidth = descriptor.m_PoolHeight = 3;
178 descriptor.m_StrideX = descriptor.m_StrideY = 1;
179 descriptor.m_PadLeft = 1;
180 descriptor.m_PadRight = 1;
181 descriptor.m_PadTop = 1;
182 descriptor.m_PadBottom = 1;
198 std::array<armnn::TensorShape, 2> concatInputShapes = { intermediateInfo.GetShape(), intermediateInfo.GetShape() };
200 concatInputShapes.begin(), concatInputShapes.end(), 2),
"concatenation");
218 runtime->LoadNetwork(networkIdentifier, std::move(optimizedNet));
223 if (subTensorHandle && subTensorHandle->GetParent())
230 unsigned int numberOfSubTensors = 0;
231 for (
auto&& layer : theGraph)
235 for (
unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
240 ++numberOfSubTensors;
251 using namespace armnn;
253 unsigned int splitAxis = 2;
254 unsigned int numSplit = 2;
258 const std::vector<TensorShape> outputShapes{{ 2, 3, 2, 2 },
260 const float qScale = 1.0f;
261 const int32_t qOffset = 0;
264 std::vector<float> inputData{
291 std::vector<float> expectedOutput0{
306 std::vector<float> expectedOutput1{
334 splitterDimSizes[i] = inputTensorInfo.
GetShape()[i];
337 if (splitterDimSizes[splitAxis] % numSplit != 0)
339 throw ParseException(
"Number of splits must evenly divide the dimension");
342 splitterDimSizes[splitAxis] /= numSplit;
346 for (
unsigned int g = 0; g < numSplit; ++g)
349 for (
unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx)
351 splitDesc.
SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]);
353 splitDesc.SetViewOriginCoord(g, splitAxis, splitterDimSizes[splitAxis] * g);
356 IConnectableLayer* elementWiseUnary0 = net->AddElementwiseUnaryLayer(descriptor,
"elementwiseunary_0");
357 IConnectableLayer* elementWiseUnary1 = net->AddElementwiseUnaryLayer(descriptor,
"elementwiseunary_0");
361 Connect(input, splitter, inputTensorInfo, 0, 0);
362 Connect(splitter, elementWiseUnary0, intermediateInfo, 0, 0);
363 Connect(splitter, elementWiseUnary1, intermediateInfo, 1, 0);
365 std::vector<IConnectableLayer*> pooling2dLayers{elementWiseUnary0, elementWiseUnary1};
367 for (
unsigned int i = 0; i < outputShapes.size(); ++i)
370 IConnectableLayer* output = net->AddOutputLayer(armnn::numeric_cast<LayerBindingId>(i));
371 Connect(pooling2dLayers[i], output, outputTensorInfo, 0, 0);
374 std::map<int, std::vector<float>> inputTensorData = {{ 0,inputData }};
375 std::map<int, std::vector<float>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
387 runtime->LoadNetwork(networkIdentifier, std::move(optimizedNet));
392 if (subTensorHandle && subTensorHandle->GetParent())
399 for (
auto&& layer : theGraph)
403 unsigned int numberOfSubTensors = 0;
404 for (
unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
409 ++numberOfSubTensors;
418 inputTensors.reserve(inputTensorData.size());
419 for (
auto&& it : inputTensorData)
421 inputTensors.push_back({it.first,
422 ConstTensor(runtime->GetInputTensorInfo(networkIdentifier, it.first), it.second.data())});
425 outputTensors.reserve(expectedOutputData.size());
426 std::map<int, std::vector<float>> outputStorage;
427 for (
auto&& it : expectedOutputData)
429 std::vector<float> out(it.second.size());
430 outputStorage.emplace(it.first, out);
431 outputTensors.push_back({it.first,
432 Tensor(runtime->GetOutputTensorInfo(networkIdentifier, it.first),
433 outputStorage.at(it.first).data())});
437 runtime->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
440 float tolerance = 0.000001f;
441 for (
auto&& it : expectedOutputData)
443 std::vector<float> out = outputStorage.at(it.first);
444 for (
unsigned int i = 0; i < out.size(); ++i)
446 BOOST_CHECK_MESSAGE(Compare<armnn::DataType::Float32>(it.second[i], out[i], tolerance) ==
true,
447 "Actual output: " << out[i] <<
". Expected output:" << it.second[i]);
455 using namespace armnn;
457 unsigned int splitAxis = 2;
458 unsigned int numSplit = 2;
462 const std::vector<TensorShape> outputShapes{{ 1, 1, 2, 4 },
465 const float qScale = 1.0f;
466 const int32_t qOffset = 0;
469 std::vector<float> inputData{
470 9.0f, 27.0f, 18.0f, 36.0f,
471 18.0f, 9.0f, 18.0f, 9.0f,
472 27.0f, 18.0f, 9.0f, 27.0f,
473 9.0f, 27.0f, 9.0f, 18.0f,
476 std::vector<float> expectedOutput0{
477 7.0f, 11.0f, 13.0f, 9.0f,
478 7.0f, 11.0f, 13.0f, 9.0f
481 std::vector<float> expectedOutput1{
482 9.0f, 11.0f, 12.0f, 7.0f,
483 9.0f, 11.0f, 12.0f, 7.0f
508 splitterDimSizes[i] = inputTensorInfo.
GetShape()[i];
511 if (splitterDimSizes[splitAxis] % numSplit != 0)
513 throw ParseException(
"Number of splits must evenly divide the dimension");
516 splitterDimSizes[splitAxis] /= numSplit;
520 for (
unsigned int g = 0; g < numSplit; ++g)
523 for (
unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx)
525 splitDesc.
SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]);
527 splitDesc.SetViewOriginCoord(g, splitAxis, splitterDimSizes[splitAxis] * g);
531 IConnectableLayer* pooling2d0 = net->AddPooling2dLayer(descriptor,
"pooling2d_0");
532 IConnectableLayer* pooling2d1 = net->AddPooling2dLayer(descriptor,
"pooling2d_1");
536 Connect(input, splitter, inputTensorInfo, 0, 0);
537 Connect(splitter, pooling2d0, intermediateInfo, 0, 0);
538 Connect(splitter, pooling2d1, intermediateInfo, 1, 0);
540 std::vector<IConnectableLayer*> pooling2dLayers{pooling2d0, pooling2d1};
542 for (
unsigned int i = 0; i < outputShapes.size(); ++i)
545 IConnectableLayer* output = net->AddOutputLayer(armnn::numeric_cast<LayerBindingId>(i));
546 Connect(pooling2dLayers[i], output, outputTensorInfo, 0, 0);
549 std::map<int, std::vector<float>> inputTensorData = {{ 0,inputData }};
550 std::map<int, std::vector<float>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
562 runtime->LoadNetwork(networkIdentifier, std::move(optimizedNet));
567 if (subTensorHandle && subTensorHandle->GetParent())
574 for (
auto&& layer : theGraph)
578 unsigned int numberOfSubTensors = 0;
579 for (
unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
584 ++numberOfSubTensors;
593 inputTensors.reserve(inputTensorData.size());
594 for (
auto&& it : inputTensorData)
596 inputTensors.push_back({it.first,
597 ConstTensor(runtime->GetInputTensorInfo(networkIdentifier, it.first), it.second.data())});
600 outputTensors.reserve(expectedOutputData.size());
601 std::map<int, std::vector<float>> outputStorage;
602 for (
auto&& it : expectedOutputData)
604 std::vector<float> out(it.second.size());
605 outputStorage.emplace(it.first, out);
606 outputTensors.push_back({it.first,
607 Tensor(runtime->GetOutputTensorInfo(networkIdentifier, it.first),
608 outputStorage.at(it.first).data())});
612 runtime->EnqueueWorkload(networkIdentifier, inputTensors, outputTensors);
615 float tolerance = 0.000001f;
616 for (
auto&& it : expectedOutputData)
618 std::vector<float> out = outputStorage.at(it.first);
619 for (
unsigned int i = 0; i < out.size(); ++i)
621 BOOST_CHECK_MESSAGE(Compare<armnn::DataType::Float32>(it.second[i], out[i], tolerance) ==
true,
622 "Actual output: " << out[i] <<
". Expected output:" << it.second[i]);
630 std::shared_ptr<NeonMemoryManager> memoryManager = std::make_shared<NeonMemoryManager>(
631 std::make_unique<arm_compute::Allocator>(),
641 memoryManager->Acquire();
643 float* buffer =
reinterpret_cast<float*
>(handle->Map());
644 BOOST_CHECK(buffer !=
nullptr);
647 BOOST_CHECK(buffer[0] == 1.5f);
648 BOOST_CHECK(buffer[1] == 2.5f);
650 memoryManager->Release();
652 memoryManager->Acquire();
654 float* buffer =
reinterpret_cast<float*
>(handle->Map());
655 BOOST_CHECK(buffer !=
nullptr);
658 BOOST_CHECK(buffer[0] == 3.5f);
659 BOOST_CHECK(buffer[1] == 4.5f);
661 memoryManager->Release();
663 float testPtr[2] = { 2.5f, 5.5f };
670 std::shared_ptr<NeonMemoryManager> memoryManager = std::make_shared<NeonMemoryManager>(
671 std::make_unique<arm_compute::Allocator>(),
680 memoryManager->Acquire();
683 BOOST_CHECK((PolymorphicDowncast<NeonTensorHandle*>(handle.get()))->GetTensor().buffer() ==
nullptr);
685 float testPtr[2] = { 2.5f, 5.5f };
688 float* buffer =
reinterpret_cast<float*
>(handle->Map());
689 BOOST_CHECK(buffer !=
nullptr);
690 BOOST_CHECK(buffer == testPtr);
692 BOOST_CHECK(buffer[0] == 2.5f);
693 BOOST_CHECK(buffer[1] == 5.5f);
696 BOOST_CHECK(buffer[0] == 3.5f);
697 BOOST_CHECK(buffer[1] == 10.0f);
698 memoryManager->Release();
703 std::shared_ptr<NeonMemoryManager> memoryManager = std::make_shared<NeonMemoryManager>();
707 ARMNN_ASSERT(handleFactory.SupportsInPlaceComputation());
BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
static IRuntimePtr Create(const CreationOptions &options)
A ViewsDescriptor for the SplitterLayer.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
uint32_t m_PadBottom
Padding bottom value in the height dimension.
const TensorShape & GetShape() const
uint32_t m_PadLeft
Padding left value in the width dimension.
std::unique_ptr< ITensorHandle > CreateTensorHandle(const TensorInfo &tensorInfo) const override
uint32_t m_PoolWidth
Pooling width value.
float m_Beta
Exponentiation value.
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
PaddingMethod m_PaddingMethod
The padding method to be used. (Exclude, IgnoreValue).
uint32_t m_PadTop
Padding top value in the height dimension.
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Copyright (c) 2020 ARM Limited.
uint32_t m_StrideX
Stride value when proceeding through input for the width dimension.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
uint32_t m_PoolHeight
Pooling height value.
uint32_t m_PadRight
Padding right value in the width dimension.
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.
Status SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
Set the size of the views.
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
std::unique_ptr< IOptimizedNetwork, void(*)(IOptimizedNetwork *network)> IOptimizedNetworkPtr
#define ARMNN_ASSERT(COND)
BOOST_AUTO_TEST_CASE(CheckConvolution2dLayer)
ITensorHandle * GetData() const
Gets the allocated tensor memory.
BOOST_AUTO_TEST_SUITE_END()
A ElementwiseUnaryDescriptor for the ElementwiseUnaryLayer.
PoolingAlgorithm m_PoolType
The pooling algorithm to use (Max. Average, L2).
The padding fields count, but are ignored.
CPU Execution: NEON: ArmCompute.
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
const OutputHandler & GetOutputHandler() const
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
OriginsDescriptor CreateDescriptorForConcatenation(TensorShapeIt first, TensorShapeIt last, unsigned int concatenationDimension)
Convenience template to create an OriginsDescriptor to use when creating a ConcatLayer for performing...
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
A Pooling2dDescriptor for the Pooling2dLayer.
static INetworkPtr Create(NetworkOptions networkOptions={})
A SoftmaxDescriptor for the SoftmaxLayer.
uint32_t m_StrideY
Stride value when proceeding through input for the height dimension.