11 #include <doctest/doctest.h> 13 using namespace armnn;
22 struct Workload0 :
BaseWorkload<ElementwiseUnaryQueueDescriptor>
35 int* inVals =
static_cast<int*
>(m_Data.m_Inputs[0][0].Map());
36 int* outVals =
static_cast<int*
>(m_Data.m_Outputs[0][0].Map());
38 for (
unsigned int i = 0;
39 i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
42 outVals[i] = inVals[i] * outVals[i];
43 inVals[i] = outVals[i];
49 int* inVals =
static_cast<int*
>(desc.
m_Inputs[0][0].Map());
50 int* outVals =
static_cast<int*
>(desc.
m_Outputs[0][0].Map());
52 for (
unsigned int i = 0;
53 i < desc.
m_Inputs[0][0].GetShape().GetNumElements();
56 outVals[i] = inVals[i] + outVals[i];
57 inVals[i] = outVals[i];
67 struct Workload1 :
BaseWorkload<ElementwiseUnaryQueueDescriptor>
76 int* inVals =
static_cast<int*
>(m_Data.m_Inputs[0][0].Map());
77 int* outVals =
static_cast<int*
>(m_Data.m_Outputs[0][0].Map());
79 for (
unsigned int i = 0;
80 i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
83 outVals[i] = inVals[i] * outVals[i];
84 inVals[i] = outVals[i];
89 void ValidateTensor(
ITensorHandle* tensorHandle,
int expectedValue)
91 int* actualOutput =
static_cast<int*
>(tensorHandle->
Map());
93 bool allValuesCorrect =
true;
94 for (
unsigned int i = 0;
98 if (actualOutput[i] != expectedValue)
100 allValuesCorrect =
false;
104 CHECK(allValuesCorrect);
107 template<
typename Workload>
115 elementwiseUnaryQueueDescriptor.
m_Inputs = std::vector<ITensorHandle*>{inputTensor};
116 elementwiseUnaryQueueDescriptor.
m_Outputs = std::vector<ITensorHandle*>{outputTensor};
118 return std::make_unique<Workload>(elementwiseUnaryQueueDescriptor, workloadInfo);
121 TEST_CASE(
"TestAsyncExecute")
125 int inVals[5]{2, 2, 2, 2, 2};
126 int outVals[5]{1, 1, 1, 1, 1};
128 int expectedExecuteval = 2;
129 int expectedExecuteAsyncval = 3;
137 std::unique_ptr<Workload0> workload0 = CreateWorkload<Workload0>(
info, &syncInput0, &syncOutput0);
139 workload0.get()->Execute();
145 workingMemDescriptor0.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput0};
146 workingMemDescriptor0.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput0};
148 workload0.get()->ExecuteAsync(workingMemDescriptor0);
151 ValidateTensor(workingMemDescriptor0.
m_Outputs[0], expectedExecuteAsyncval);
152 ValidateTensor(workingMemDescriptor0.
m_Inputs[0], expectedExecuteAsyncval);
154 ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Outputs[0][0], expectedExecuteval);
155 ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Inputs[0][0], expectedExecuteval);
158 TEST_CASE(
"TestDefaultAsyncExecute")
162 std::vector<int> inVals{2, 2, 2, 2, 2};
163 std::vector<int> outVals{1, 1, 1, 1, 1};
164 std::vector<int> defaultVals{0, 0, 0, 0, 0};
166 int expectedExecuteval = 2;
175 std::unique_ptr<Workload1> workload1 = CreateWorkload<Workload1>(
info, &defaultInput, &defaultOutput);
181 workingMemDescriptor.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput};
182 workingMemDescriptor.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput};
184 workload1.get()->ExecuteAsync(workingMemDescriptor);
188 ValidateTensor(workingMemDescriptor.
m_Outputs[0], expectedExecuteval);
189 ValidateTensor(workingMemDescriptor.
m_Inputs[0], expectedExecuteval);
192 TEST_CASE(
"TestDefaultAsyncExeuteWithThreads")
195 unsigned int vecSize = 1000;
198 std::vector<int> inVals1(vecSize, 2);
199 std::vector<int> outVals1(vecSize, 1);
200 std::vector<int> inVals2(vecSize, 5);
201 std::vector<int> outVals2(vecSize, -1);
203 std::vector<int> defaultVals(vecSize, 0);
205 int expectedExecuteval1 = 4;
206 int expectedExecuteval2 = 25;
217 std::unique_ptr<Workload1> workload = CreateWorkload<Workload1>(
info, &defaultInput, &defaultOutput);
223 workingMemDescriptor1.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput1};
224 workingMemDescriptor1.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput1};
231 workingMemDescriptor2.
m_Inputs = std::vector<ITensorHandle*>{&asyncInput2};
232 workingMemDescriptor2.
m_Outputs = std::vector<ITensorHandle*>{&asyncOutput2};
234 std::thread thread1 = std::thread([&]()
236 workload.get()->ExecuteAsync(workingMemDescriptor1);
237 workload.get()->ExecuteAsync(workingMemDescriptor1);
240 std::thread thread2 = std::thread([&]()
242 workload.get()->ExecuteAsync(workingMemDescriptor2);
243 workload.get()->ExecuteAsync(workingMemDescriptor2);
249 ValidateTensor(workingMemDescriptor1.
m_Outputs[0], expectedExecuteval1);
250 ValidateTensor(workingMemDescriptor1.
m_Inputs[0], expectedExecuteval1);
252 ValidateTensor(workingMemDescriptor2.
m_Outputs[0], expectedExecuteval2);
253 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