15 #include <boost/test/unit_test.hpp> 22 using namespace armnn;
25 bool ConstantUsageTest(
const std::vector<BackendId>& computeDevice,
27 const std::vector<T>& inputData,
28 const std::vector<T>& constantData,
29 const std::vector<T>& expectedOutputData)
57 runtime->LoadNetwork(netId, std::move(optNet));
60 std::vector<T> outputData(inputData.size());
64 {0,
ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData.data())}
68 {0,
Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
72 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
75 return outputData == expectedOutputData;
78 inline bool ConstantUsageFloat32Test(
const std::vector<BackendId>& backends)
82 return ConstantUsageTest(backends,
84 std::vector<float>{ 1.f, 2.f, 3.f, 4.f, 5.f, 6.f },
85 std::vector<float>{ 6.f, 5.f, 4.f, 3.f, 2.f, 1.f },
86 std::vector<float>{ 7.f, 7.f, 7.f, 7.f, 7.f, 7.f }
90 inline bool ConstantUsageUint8Test(
const std::vector<BackendId>& backends)
94 const float scale = 0.023529f;
95 const int8_t offset = -43;
100 return ConstantUsageTest(backends,
102 armnnUtils::QuantizedVector<uint8_t>({ 1.f, 2.f, 3.f, 4.f, 5.f, 6.f }, scale, offset),
103 armnnUtils::QuantizedVector<uint8_t>({ 6.f, 5.f, 4.f, 3.f, 2.f, 1.f }, scale, offset),
104 armnnUtils::QuantizedVector<uint8_t>({ 7.f, 7.f, 7.f, 7.f, 7.f, 7.f }, scale, offset)
109 template<DataType ArmnnType,
typename T = ResolveType<ArmnnType>>
110 bool Compare(T a, T b,
float tolerance = 0.000001f)
117 return static_cast<bool>(a) == static_cast<bool>(b);
122 return std::fabs(static_cast<float>(a) - static_cast<float>(b)) <= tolerance;
126 int SubStringCounter(std::string&
string, std::string&& substring)
128 std::size_t found = 0;
131 while((found =
string.find(substring, found)) != std::string::npos)
135 found += substring.length();
143 const std::map<
int, std::vector<TInput>>& inputTensorData,
144 const std::map<
int, std::vector<TOutput>>& expectedOutputData,
145 std::vector<BackendId> backends,
146 float tolerance = 0.000001f)
157 runtime->LoadNetwork(netId, std::move(optNet));
160 inputTensors.reserve(inputTensorData.size());
161 for (
auto&& it : inputTensorData)
163 inputTensors.push_back({it.first,
164 ConstTensor(runtime->GetInputTensorInfo(netId, it.first), it.second.data())});
167 outputTensors.reserve(expectedOutputData.size());
168 std::map<int, std::vector<TOutput>> outputStorage;
169 for (
auto&& it : expectedOutputData)
171 std::vector<TOutput> out(it.second.size());
172 outputStorage.emplace(it.first, out);
173 outputTensors.push_back({it.first,
174 Tensor(runtime->GetOutputTensorInfo(netId, it.first),
175 outputStorage.at(it.first).data())});
179 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
182 for (
auto&& it : expectedOutputData)
184 std::vector<TOutput> out = outputStorage.at(it.first);
185 for (
unsigned int i = 0; i < out.size(); ++i)
187 BOOST_CHECK_MESSAGE(Compare<ArmnnOType>(it.second[i], out[i], tolerance) ==
true,
188 "Actual output: " << out[i] <<
". Expected output:" << it.second[i]);
194 inline void ImportNonAlignedInputPointerTest(std::vector<BackendId> backends)
196 using namespace armnn;
225 std::string ignoredErrorMessage;
228 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
231 std::vector<float> inputData
233 1.0f, 2.0f, 3.0f, 4.0f
237 float* misalignedInputData =
reinterpret_cast<float*
>(
reinterpret_cast<char*
>(inputData.data()) + 1);
239 std::vector<float> outputData(4);
242 float* alignedOutputData = outputData.data();
250 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), alignedOutputData)}
253 runtime->GetProfiler(netId)->EnableProfiling(
true);
256 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryImportException);
259 inline void ExportNonAlignedOutputPointerTest(std::vector<BackendId> backends)
261 using namespace armnn;
290 std::string ignoredErrorMessage;
293 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
296 std::vector<float> inputData
298 1.0f, 2.0f, 3.0f, 4.0f, 5.0f
302 float* alignedInputData = inputData.data();
304 std::vector<float> outputData(5);
307 float* misalignedOutputData =
reinterpret_cast<float*
>(
reinterpret_cast<char*
>(outputData.data()) + 1);
315 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), misalignedOutputData)}
322 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryImportException);
326 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryExportException);
330 inline void ImportAlignedPointerTest(std::vector<BackendId> backends)
332 using namespace armnn;
361 std::string ignoredErrorMessage;
364 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
367 std::vector<float> inputData
369 1.0f, 2.0f, 3.0f, 4.0f
372 std::vector<float> outputData(4);
374 std::vector<float> expectedOutput
376 1.0f, 4.0f, 9.0f, 16.0f
385 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
388 runtime->GetProfiler(netId)->EnableProfiling(
true);
391 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
395 std::stringstream ss;
397 std::string dump = ss.str();
400 std::size_t found = dump.find(
"ActivationWorkload");
401 BOOST_TEST(found != std::string::npos);
404 found = dump.find(
"SyncMemGeneric");
405 BOOST_TEST(found != std::string::npos);
408 found = dump.find(
"CopyMemGeneric");
409 BOOST_TEST(found == std::string::npos);
412 BOOST_TEST(outputData == expectedOutput);
415 inline void ImportOnlyWorkload(std::vector<BackendId> backends)
417 using namespace armnn;
442 BOOST_TEST_CHECKPOINT(
"Load Network");
445 std::string ignoredErrorMessage;
447 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
450 BOOST_TEST_CHECKPOINT(
"Generate Data");
452 std::vector<float> inputData
454 1.0f, 2.0f, 3.0f, 4.0f
457 std::vector<float> outputData(4);
459 std::vector<float> expectedOutput
461 1.0f, 4.0f, 9.0f, 16.0f
464 BOOST_TEST_CHECKPOINT(
"Create Network");
471 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
474 BOOST_TEST_CHECKPOINT(
"Get Profiler");
476 runtime->GetProfiler(netId)->EnableProfiling(
true);
478 BOOST_TEST_CHECKPOINT(
"Run Inference");
480 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
482 BOOST_TEST_CHECKPOINT(
"Print Profiler");
485 std::stringstream ss;
487 std::string dump = ss.str();
490 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
491 int count = SubStringCounter(dump,
"SyncMemGeneric");
492 BOOST_TEST(count == 0);
495 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
496 count = SubStringCounter(dump,
"CopyMemGeneric");
497 BOOST_TEST(count == 1);
500 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
503 inline void ExportOnlyWorkload(std::vector<BackendId> backends)
505 using namespace armnn;
530 BOOST_TEST_CHECKPOINT(
"Load Network");
533 std::string ignoredErrorMessage;
535 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
538 BOOST_TEST_CHECKPOINT(
"Generate Data");
540 std::vector<float> inputData
542 1.0f, 2.0f, 3.0f, 4.0f
545 std::vector<float> outputData(4);
547 std::vector<float> expectedOutput
549 1.0f, 4.0f, 9.0f, 16.0f
552 BOOST_TEST_CHECKPOINT(
"Create Network");
559 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
562 BOOST_TEST_CHECKPOINT(
"Get Profiler");
564 runtime->GetProfiler(netId)->EnableProfiling(
true);
566 BOOST_TEST_CHECKPOINT(
"Run Inference");
568 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
570 BOOST_TEST_CHECKPOINT(
"Print Profiler");
573 std::stringstream ss;
575 std::string dump = ss.str();
578 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
579 int count = SubStringCounter(dump,
"SyncMemGeneric");
580 BOOST_TEST(count == 1);
583 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
584 count = SubStringCounter(dump,
"CopyMemGeneric");
585 BOOST_TEST(count == 1);
588 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
591 inline void ImportAndExportWorkload(std::vector<BackendId> backends)
593 using namespace armnn;
617 BOOST_TEST_CHECKPOINT(
"Load Network");
620 std::string ignoredErrorMessage;
622 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
625 BOOST_TEST_CHECKPOINT(
"Generate Data");
627 std::vector<float> inputData
629 1.0f, 2.0f, 3.0f, 4.0f
632 std::vector<float> outputData(4);
634 std::vector<float> expectedOutput
636 1.0f, 4.0f, 9.0f, 16.0f
639 BOOST_TEST_CHECKPOINT(
"Create Network");
646 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
649 BOOST_TEST_CHECKPOINT(
"Get Profiler");
651 runtime->GetProfiler(netId)->EnableProfiling(
true);
653 BOOST_TEST_CHECKPOINT(
"Run Inference");
655 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
657 BOOST_TEST_CHECKPOINT(
"Print Profiler");
660 std::stringstream ss;
662 std::string dump = ss.str();
665 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
666 int count = SubStringCounter(dump,
"SyncMemGeneric");
667 BOOST_TEST(count == 1);
670 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
671 count = SubStringCounter(dump,
"CopyMemGeneric");
672 BOOST_TEST(count == 0);
675 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
678 inline void ExportOutputWithSeveralOutputSlotConnectionsTest(std::vector<BackendId> backends)
680 using namespace armnn;
710 std::string ignoredErrorMessage;
713 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
716 std::vector<float> inputData
718 1.0f, 2.0f, 3.0f, 4.0f
721 std::vector<float> outputData0(4);
722 std::vector<float> outputData1(4);
724 std::vector<float> expectedOutput
726 1.0f, 4.0f, 9.0f, 16.0f
735 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData0.data())},
736 {1,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 1), outputData1.data())}
741 runtime->GetProfiler(netId)->EnableProfiling(
true);
744 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
748 std::stringstream ss;
750 std::string dump = ss.str();
752 std::size_t found = std::string::npos;
756 found = dump.find(
"RefActivationWorkload");
760 found = dump.find(
"NeonActivationWorkload");
764 found = dump.find(
"ClActivationWorkload");
767 BOOST_TEST(found != std::string::npos);
769 found = dump.find(
"SyncMemGeneric");
770 BOOST_TEST(found == std::string::npos);
772 found = dump.find(
"CopyMemGeneric");
773 BOOST_TEST(found != std::string::npos);
776 BOOST_CHECK_EQUAL_COLLECTIONS(outputData0.begin(), outputData0.end(),
777 expectedOutput.begin(), expectedOutput.end());
778 BOOST_CHECK_EQUAL_COLLECTIONS(outputData1.begin(), outputData1.end(),
779 expectedOutput.begin(), expectedOutput.end());
782 inline void StridedSliceInvalidSliceEndToEndTest(std::vector<BackendId> backends)
784 using namespace armnn;
799 descriptor.
m_End = {2, 3};
static IRuntimePtr Create(const CreationOptions &options)
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
CPU Execution: Reference C++ kernels.
int32_t m_ShrinkAxisMask
Shrink axis mask value. If set, the nth specification shrinks the dimensionality by 1...
static ProfilerManager & GetInstance()
std::vector< int > m_Begin
Begin values for the input that will be sliced.
std::unique_ptr< IRuntime, void(*)(IRuntime *runtime)> IRuntimePtr
typename ResolveTypeImpl< DT >::Type ResolveType
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Copyright (c) 2020 ARM Limited.
int32_t m_BeginMask
Begin mask value.
int32_t m_EndMask
End mask value.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
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.
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
void SetQuantizationScale(float scale)
GPU Execution: OpenCL: ArmCompute.
std::vector< int > m_Stride
Stride values for the input that will be sliced.
An ActivationDescriptor for the ActivationLayer.
std::vector< int > m_End
End values for the input that will be sliced.
CPU Execution: NEON: ArmCompute.
virtual const IInputSlot & GetInputSlot(unsigned int index) const =0
Get a const input slot handle by slot index.
A StridedSliceDescriptor for the StridedSliceLayer.
virtual const IOutputSlot & GetOutputSlot(unsigned int index) const =0
Get the const output slot handle by slot index.
void SetQuantizationOffset(int32_t offset)
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
virtual int Connect(IInputSlot &destination)=0
void Print(std::ostream &outStream) const override
Print stats for events in JSON Format to the given output stream.
static INetworkPtr Create(NetworkOptions networkOptions={})
ActivationFunction m_Function
The activation function to use (Sigmoid, TanH, Linear, ReLu, BoundedReLu, SoftReLu, LeakyReLu, Abs, Sqrt, Square, Elu).
bool Compare(T a, T b, float tolerance=0.000001f)