11 #include <doctest/doctest.h> 15 using namespace armnn;
24 struct Workload0 :
BaseWorkload<ElementwiseUnaryQueueDescriptor>
37 int* inVals =
static_cast<int*
>(m_Data.m_Inputs[0][0].Map());
38 int* outVals =
static_cast<int*
>(m_Data.m_Outputs[0][0].Map());
40 for (
unsigned int i = 0;
41 i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
44 outVals[i] = inVals[i] * outVals[i];
45 inVals[i] = outVals[i];
51 int* inVals =
static_cast<int*
>(desc.
m_Inputs[0][0].Map());
52 int* outVals =
static_cast<int*
>(desc.
m_Outputs[0][0].Map());
54 for (
unsigned int i = 0;
55 i < desc.
m_Inputs[0][0].GetShape().GetNumElements();
58 outVals[i] = inVals[i] + outVals[i];
59 inVals[i] = outVals[i];
69 struct Workload1 :
BaseWorkload<ElementwiseUnaryQueueDescriptor>
78 int* inVals =
static_cast<int*
>(m_Data.m_Inputs[0][0].Map());
79 int* outVals =
static_cast<int*
>(m_Data.m_Outputs[0][0].Map());
81 for (
unsigned int i = 0;
82 i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
85 outVals[i] = inVals[i] * outVals[i];
86 inVals[i] = outVals[i];
91 void ValidateTensor(
ITensorHandle* tensorHandle,
int expectedValue)
93 int* actualOutput =
static_cast<int*
>(tensorHandle->
Map());
95 bool allValuesCorrect =
true;
96 for (
unsigned int i = 0;
100 if (actualOutput[i] != expectedValue)
102 allValuesCorrect =
false;
106 CHECK(allValuesCorrect);
109 template<
typename Workload>
117 elementwiseUnaryQueueDescriptor.
m_Inputs = std::vector<ITensorHandle*>{inputTensor};
118 elementwiseUnaryQueueDescriptor.
m_Outputs = std::vector<ITensorHandle*>{outputTensor};
120 return std::make_unique<Workload>(elementwiseUnaryQueueDescriptor, workloadInfo);
123 TEST_CASE(
"TestAsyncExecute")
127 int inVals[5]{2, 2, 2, 2, 2};
128 int outVals[5]{1, 1, 1, 1, 1};
130 int expectedExecuteval = 2;
131 int expectedExecuteAsyncval = 3;
139 std::unique_ptr<Workload0> workload0 = CreateWorkload<Workload0>(
info, &syncInput0, &syncOutput0);
141 workload0.get()->Execute();
147 workingMemDescriptor0.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput0};
148 workingMemDescriptor0.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput0};
150 workload0.get()->ExecuteAsync(workingMemDescriptor0);
153 ValidateTensor(workingMemDescriptor0.
m_Outputs[0], expectedExecuteAsyncval);
154 ValidateTensor(workingMemDescriptor0.
m_Inputs[0], expectedExecuteAsyncval);
156 ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Outputs[0][0], expectedExecuteval);
157 ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Inputs[0][0], expectedExecuteval);
160 TEST_CASE(
"TestDefaultAsyncExecute")
164 std::vector<int> inVals{2, 2, 2, 2, 2};
165 std::vector<int> outVals{1, 1, 1, 1, 1};
166 std::vector<int> defaultVals{0, 0, 0, 0, 0};
168 int expectedExecuteval = 2;
177 std::unique_ptr<Workload1> workload1 = CreateWorkload<Workload1>(
info, &defaultInput, &defaultOutput);
183 workingMemDescriptor.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput};
184 workingMemDescriptor.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput};
186 workload1.get()->ExecuteAsync(workingMemDescriptor);
190 ValidateTensor(workingMemDescriptor.
m_Outputs[0], expectedExecuteval);
191 ValidateTensor(workingMemDescriptor.
m_Inputs[0], expectedExecuteval);
194 TEST_CASE(
"TestDefaultAsyncExeuteWithThreads")
197 unsigned int vecSize = 1000;
200 std::vector<int> inVals1(vecSize, 2);
201 std::vector<int> outVals1(vecSize, 1);
202 std::vector<int> inVals2(vecSize, 5);
203 std::vector<int> outVals2(vecSize, -1);
205 std::vector<int> defaultVals(vecSize, 0);
207 int expectedExecuteval1 = 4;
208 int expectedExecuteval2 = 25;
215 ConstTensor defaultTensor(info, defaultVals.data());
219 std::unique_ptr<Workload1> workload = CreateWorkload<Workload1>(
info, &defaultInput, &defaultOutput);
225 workingMemDescriptor1.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput1};
226 workingMemDescriptor1.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput1};
233 workingMemDescriptor2.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput2};
234 workingMemDescriptor2.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput2};
236 std::thread thread1 = std::thread([&]()
238 workload.get()->ExecuteAsync(workingMemDescriptor1);
239 workload.get()->ExecuteAsync(workingMemDescriptor1);
242 std::thread thread2 = std::thread([&]()
244 workload.get()->ExecuteAsync(workingMemDescriptor2);
245 workload.get()->ExecuteAsync(workingMemDescriptor2);
251 ValidateTensor(workingMemDescriptor1.
m_Outputs[0], expectedExecuteval1);
252 ValidateTensor(workingMemDescriptor1.
m_Inputs[0], expectedExecuteval1);
254 ValidateTensor(workingMemDescriptor2.
m_Outputs[0], expectedExecuteval2);
255 ValidateTensor(workingMemDescriptor2.
m_Inputs[0], expectedExecuteval2);
TEST_SUITE("TestConstTensorLayerVisitor")
unsigned int GetNumElements() const
Function that calculates the tensor elements by multiplying all dimension size which are Specified...
std::unique_ptr< armnn::IWorkload > CreateWorkload(const armnn::IWorkloadFactory &workloadFactory, const armnn::WorkloadInfo &info, const DescriptorType &descriptor)
Copyright (c) 2021 ARM Limited and Contributors.
std::vector< ITensorHandle * > m_Inputs
std::vector< TensorInfo > m_InputTensorInfos
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
std::vector< TensorInfo > m_OutputTensorInfos
virtual TensorShape GetShape() const =0
Get the number of elements for each dimension ordered from slowest iterating dimension to fastest ite...
virtual const void * Map(bool blocking=true) const =0
Map the tensor data for access.
std::vector< ITensorHandle * > m_Outputs
std::vector< ITensorHandle * > m_Outputs
Contains information about TensorInfos of a layer.
std::vector< ITensorHandle * > m_Inputs