17 #include <boost/test/unit_test.hpp> 24 using namespace armnn;
27 bool ConstantUsageTest(
const std::vector<BackendId>& computeDevice,
29 const std::vector<T>& inputData,
30 const std::vector<T>& constantData,
31 const std::vector<T>& expectedOutputData)
59 runtime->LoadNetwork(netId, std::move(optNet));
62 std::vector<T> outputData(inputData.size());
66 {0,
ConstTensor(runtime->GetInputTensorInfo(netId, 0), inputData.data())}
70 {0,
Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
74 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
77 return outputData == expectedOutputData;
80 inline bool ConstantUsageFloat32Test(
const std::vector<BackendId>& backends)
84 return ConstantUsageTest(backends,
86 std::vector<float>{ 1.f, 2.f, 3.f, 4.f, 5.f, 6.f },
87 std::vector<float>{ 6.f, 5.f, 4.f, 3.f, 2.f, 1.f },
88 std::vector<float>{ 7.f, 7.f, 7.f, 7.f, 7.f, 7.f }
92 inline bool ConstantUsageUint8Test(
const std::vector<BackendId>& backends)
96 const float scale = 0.023529f;
97 const int8_t offset = -43;
102 return ConstantUsageTest(backends,
104 armnnUtils::QuantizedVector<uint8_t>({ 1.f, 2.f, 3.f, 4.f, 5.f, 6.f }, scale, offset),
105 armnnUtils::QuantizedVector<uint8_t>({ 6.f, 5.f, 4.f, 3.f, 2.f, 1.f }, scale, offset),
106 armnnUtils::QuantizedVector<uint8_t>({ 7.f, 7.f, 7.f, 7.f, 7.f, 7.f }, scale, offset)
111 int SubStringCounter(std::string&
string, std::string&& substring)
113 std::size_t found = 0;
116 while((found =
string.find(substring, found)) != std::string::npos)
120 found += substring.length();
128 const std::map<
int, std::vector<TInput>>& inputTensorData,
129 const std::map<
int, std::vector<TOutput>>& expectedOutputData,
130 std::vector<BackendId> backends,
131 float tolerance = 0.000001f)
142 runtime->LoadNetwork(netId, std::move(optNet));
145 inputTensors.reserve(inputTensorData.size());
146 for (
auto&& it : inputTensorData)
148 inputTensors.push_back({it.first,
149 ConstTensor(runtime->GetInputTensorInfo(netId, it.first), it.second.data())});
152 outputTensors.reserve(expectedOutputData.size());
153 std::map<int, std::vector<TOutput>> outputStorage;
154 for (
auto&& it : expectedOutputData)
156 std::vector<TOutput> out(it.second.size());
157 outputStorage.emplace(it.first, out);
158 outputTensors.push_back({it.first,
159 Tensor(runtime->GetOutputTensorInfo(netId, it.first),
160 outputStorage.at(it.first).data())});
164 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
167 for (
auto&& it : expectedOutputData)
169 std::vector<TOutput> out = outputStorage.at(it.first);
170 for (
unsigned int i = 0; i < out.size(); ++i)
172 BOOST_CHECK_MESSAGE(Compare<ArmnnOType>(it.second[i], out[i], tolerance) ==
true,
173 "Actual output: " << out[i] <<
". Expected output:" << it.second[i]);
179 inline void ImportNonAlignedInputPointerTest(std::vector<BackendId> backends)
181 using namespace armnn;
210 std::string ignoredErrorMessage;
213 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
216 std::vector<float> inputData
218 1.0f, 2.0f, 3.0f, 4.0f
222 float* misalignedInputData =
reinterpret_cast<float*
>(
reinterpret_cast<char*
>(inputData.data()) + 1);
224 std::vector<float> outputData(4);
227 float* alignedOutputData = outputData.data();
235 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), alignedOutputData)}
238 runtime->GetProfiler(netId)->EnableProfiling(
true);
241 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryImportException);
244 inline void ExportNonAlignedOutputPointerTest(std::vector<BackendId> backends)
246 using namespace armnn;
275 std::string ignoredErrorMessage;
278 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
281 std::vector<float> inputData
283 1.0f, 2.0f, 3.0f, 4.0f, 5.0f
287 float* alignedInputData = inputData.data();
289 std::vector<float> outputData(5);
292 float* misalignedOutputData =
reinterpret_cast<float*
>(
reinterpret_cast<char*
>(outputData.data()) + 1);
300 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), misalignedOutputData)}
307 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryImportException);
311 BOOST_CHECK_THROW(runtime->EnqueueWorkload(netId, inputTensors, outputTensors),
MemoryExportException);
315 inline void ImportAlignedPointerTest(std::vector<BackendId> backends)
317 using namespace armnn;
346 std::string ignoredErrorMessage;
349 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
352 std::vector<float> inputData
354 1.0f, 2.0f, 3.0f, 4.0f
357 std::vector<float> outputData(4);
359 std::vector<float> expectedOutput
361 1.0f, 4.0f, 9.0f, 16.0f
370 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
373 runtime->GetProfiler(netId)->EnableProfiling(
true);
376 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
380 std::stringstream ss;
382 std::string dump = ss.str();
385 std::size_t found = dump.find(
"ActivationWorkload");
386 BOOST_TEST(found != std::string::npos);
389 found = dump.find(
"SyncMemGeneric");
390 BOOST_TEST(found != std::string::npos);
393 found = dump.find(
"CopyMemGeneric");
394 BOOST_TEST(found == std::string::npos);
397 BOOST_TEST(outputData == expectedOutput);
400 inline void ImportOnlyWorkload(std::vector<BackendId> backends)
402 using namespace armnn;
427 BOOST_TEST_CHECKPOINT(
"Load Network");
430 std::string ignoredErrorMessage;
434 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
437 BOOST_TEST_CHECKPOINT(
"Generate Data");
439 std::vector<float> inputData
441 1.0f, 2.0f, 3.0f, 4.0f
444 std::vector<float> outputData(4);
446 std::vector<float> expectedOutput
448 1.0f, 4.0f, 9.0f, 16.0f
451 BOOST_TEST_CHECKPOINT(
"Create Network");
458 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
461 BOOST_TEST_CHECKPOINT(
"Get Profiler");
463 runtime->GetProfiler(netId)->EnableProfiling(
true);
465 BOOST_TEST_CHECKPOINT(
"Run Inference");
467 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
469 BOOST_TEST_CHECKPOINT(
"Print Profiler");
472 std::stringstream ss;
474 std::string dump = ss.str();
477 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
478 int count = SubStringCounter(dump,
"SyncMemGeneric");
479 BOOST_TEST(count == 0);
482 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
483 count = SubStringCounter(dump,
"CopyMemGeneric");
484 BOOST_TEST(count == 1);
487 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
490 inline void ExportOnlyWorkload(std::vector<BackendId> backends)
492 using namespace armnn;
517 BOOST_TEST_CHECKPOINT(
"Load Network");
520 std::string ignoredErrorMessage;
522 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
525 BOOST_TEST_CHECKPOINT(
"Generate Data");
527 std::vector<float> inputData
529 1.0f, 2.0f, 3.0f, 4.0f
532 std::vector<float> outputData(4);
534 std::vector<float> expectedOutput
536 1.0f, 4.0f, 9.0f, 16.0f
539 BOOST_TEST_CHECKPOINT(
"Create Network");
546 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
549 BOOST_TEST_CHECKPOINT(
"Get Profiler");
551 runtime->GetProfiler(netId)->EnableProfiling(
true);
553 BOOST_TEST_CHECKPOINT(
"Run Inference");
555 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
557 BOOST_TEST_CHECKPOINT(
"Print Profiler");
560 std::stringstream ss;
562 std::string dump = ss.str();
565 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
566 int count = SubStringCounter(dump,
"SyncMemGeneric");
567 BOOST_TEST(count == 1);
570 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
571 count = SubStringCounter(dump,
"CopyMemGeneric");
572 BOOST_TEST(count == 1);
575 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
578 inline void ImportAndExportWorkload(std::vector<BackendId> backends)
580 using namespace armnn;
604 BOOST_TEST_CHECKPOINT(
"Load Network");
607 std::string ignoredErrorMessage;
611 BOOST_TEST(runtime->LoadNetwork(netId, std::move(optNet),ignoredErrorMessage, networkProperties)
614 BOOST_TEST_CHECKPOINT(
"Generate Data");
616 std::vector<float> inputData
618 1.0f, 2.0f, 3.0f, 4.0f
621 std::vector<float> outputData(4);
623 std::vector<float> expectedOutput
625 1.0f, 4.0f, 9.0f, 16.0f
628 BOOST_TEST_CHECKPOINT(
"Create Network");
635 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData.data())}
638 BOOST_TEST_CHECKPOINT(
"Get Profiler");
640 runtime->GetProfiler(netId)->EnableProfiling(
true);
642 BOOST_TEST_CHECKPOINT(
"Run Inference");
644 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
646 BOOST_TEST_CHECKPOINT(
"Print Profiler");
649 std::stringstream ss;
651 std::string dump = ss.str();
654 BOOST_TEST_CHECKPOINT(
"Find SyncMemGeneric");
655 int count = SubStringCounter(dump,
"SyncMemGeneric");
656 BOOST_TEST(count == 1);
659 BOOST_TEST_CHECKPOINT(
"Find CopyMemGeneric");
660 count = SubStringCounter(dump,
"CopyMemGeneric");
661 BOOST_TEST(count == 0);
664 BOOST_CHECK_EQUAL_COLLECTIONS(outputData.begin(), outputData.end(), expectedOutput.begin(), expectedOutput.end());
667 inline void ExportOutputWithSeveralOutputSlotConnectionsTest(std::vector<BackendId> backends)
669 using namespace armnn;
699 std::string ignoredErrorMessage;
702 runtime->LoadNetwork(netId, std::move(optNet), ignoredErrorMessage, networkProperties);
705 std::vector<float> inputData
707 1.0f, 2.0f, 3.0f, 4.0f
710 std::vector<float> outputData0(4);
711 std::vector<float> outputData1(4);
713 std::vector<float> expectedOutput
715 1.0f, 4.0f, 9.0f, 16.0f
724 {0,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 0), outputData0.data())},
725 {1,
armnn::Tensor(runtime->GetOutputTensorInfo(netId, 1), outputData1.data())}
730 runtime->GetProfiler(netId)->EnableProfiling(
true);
733 runtime->EnqueueWorkload(netId, inputTensors, outputTensors);
737 std::stringstream ss;
739 std::string dump = ss.str();
741 std::size_t found = std::string::npos;
745 found = dump.find(
"RefActivationWorkload");
749 found = dump.find(
"NeonActivationWorkload");
753 found = dump.find(
"ClActivationWorkload");
756 BOOST_TEST(found != std::string::npos);
758 found = dump.find(
"SyncMemGeneric");
759 BOOST_TEST(found == std::string::npos);
761 found = dump.find(
"CopyMemGeneric");
762 BOOST_TEST(found != std::string::npos);
765 BOOST_CHECK_EQUAL_COLLECTIONS(outputData0.begin(), outputData0.end(),
766 expectedOutput.begin(), expectedOutput.end());
767 BOOST_CHECK_EQUAL_COLLECTIONS(outputData1.begin(), outputData1.end(),
768 expectedOutput.begin(), expectedOutput.end());
771 inline void StridedSliceInvalidSliceEndToEndTest(std::vector<BackendId> backends)
773 using namespace armnn;
788 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
void Print(std::ostream &outStream) const
Print stats for events in JSON Format to the given output stream.
typename ResolveTypeImpl< DT >::Type ResolveType
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Copyright (c) 2021 ARM Limited and Contributors.
int32_t m_BeginMask
Begin mask value.
int32_t m_EndMask
End mask value.
virtual void SetTensorInfo(const TensorInfo &tensorInfo)=0
IProfiler * GetProfiler()
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
static INetworkPtr Create(NetworkOptions networkOptions={})
ActivationFunction m_Function
The activation function to use (Sigmoid, TanH, Linear, ReLu, BoundedReLu, SoftReLu, LeakyReLu, Abs, Sqrt, Square, Elu).