1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Exceptions.hpp>
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/TensorHandle.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/backends/Workload.hpp>
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker #include <doctest/doctest.h>
12*89c4ff92SAndroid Build Coastguard Worker
13*89c4ff92SAndroid Build Coastguard Worker #include <thread>
14*89c4ff92SAndroid Build Coastguard Worker
15*89c4ff92SAndroid Build Coastguard Worker using namespace armnn;
16*89c4ff92SAndroid Build Coastguard Worker
17*89c4ff92SAndroid Build Coastguard Worker
18*89c4ff92SAndroid Build Coastguard Worker namespace
19*89c4ff92SAndroid Build Coastguard Worker {
20*89c4ff92SAndroid Build Coastguard Worker
21*89c4ff92SAndroid Build Coastguard Worker TEST_SUITE("WorkloadAsyncExecuteTests")
22*89c4ff92SAndroid Build Coastguard Worker {
23*89c4ff92SAndroid Build Coastguard Worker
24*89c4ff92SAndroid Build Coastguard Worker struct Workload0 : BaseWorkload<ElementwiseUnaryQueueDescriptor>
25*89c4ff92SAndroid Build Coastguard Worker {
Workload0__anone931cbbc0111::Workload026*89c4ff92SAndroid Build Coastguard Worker Workload0(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info)
27*89c4ff92SAndroid Build Coastguard Worker : BaseWorkload(descriptor, info)
28*89c4ff92SAndroid Build Coastguard Worker {
29*89c4ff92SAndroid Build Coastguard Worker }
30*89c4ff92SAndroid Build Coastguard Worker
Workload0__anone931cbbc0111::Workload031*89c4ff92SAndroid Build Coastguard Worker Workload0() : BaseWorkload(ElementwiseUnaryQueueDescriptor(), WorkloadInfo())
32*89c4ff92SAndroid Build Coastguard Worker {
33*89c4ff92SAndroid Build Coastguard Worker }
34*89c4ff92SAndroid Build Coastguard Worker
Execute__anone931cbbc0111::Workload035*89c4ff92SAndroid Build Coastguard Worker void Execute() const
36*89c4ff92SAndroid Build Coastguard Worker {
37*89c4ff92SAndroid Build Coastguard Worker int* inVals = static_cast<int*>(m_Data.m_Inputs[0][0].Map());
38*89c4ff92SAndroid Build Coastguard Worker int* outVals = static_cast<int*>(m_Data.m_Outputs[0][0].Map());
39*89c4ff92SAndroid Build Coastguard Worker
40*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0;
41*89c4ff92SAndroid Build Coastguard Worker i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
42*89c4ff92SAndroid Build Coastguard Worker ++i)
43*89c4ff92SAndroid Build Coastguard Worker {
44*89c4ff92SAndroid Build Coastguard Worker outVals[i] = inVals[i] * outVals[i];
45*89c4ff92SAndroid Build Coastguard Worker inVals[i] = outVals[i];
46*89c4ff92SAndroid Build Coastguard Worker }
47*89c4ff92SAndroid Build Coastguard Worker }
48*89c4ff92SAndroid Build Coastguard Worker
ExecuteAsync__anone931cbbc0111::Workload049*89c4ff92SAndroid Build Coastguard Worker void ExecuteAsync(ExecutionData& executionData)
50*89c4ff92SAndroid Build Coastguard Worker {
51*89c4ff92SAndroid Build Coastguard Worker WorkingMemDescriptor* workingMemDescriptor = static_cast<WorkingMemDescriptor*>(executionData.m_Data);
52*89c4ff92SAndroid Build Coastguard Worker int* inVals = static_cast<int*>(workingMemDescriptor->m_Inputs[0][0].Map());
53*89c4ff92SAndroid Build Coastguard Worker int* outVals = static_cast<int*>(workingMemDescriptor->m_Outputs[0][0].Map());
54*89c4ff92SAndroid Build Coastguard Worker
55*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0;
56*89c4ff92SAndroid Build Coastguard Worker i < workingMemDescriptor->m_Inputs[0][0].GetShape().GetNumElements();
57*89c4ff92SAndroid Build Coastguard Worker ++i)
58*89c4ff92SAndroid Build Coastguard Worker {
59*89c4ff92SAndroid Build Coastguard Worker outVals[i] = inVals[i] + outVals[i];
60*89c4ff92SAndroid Build Coastguard Worker inVals[i] = outVals[i];
61*89c4ff92SAndroid Build Coastguard Worker }
62*89c4ff92SAndroid Build Coastguard Worker }
63*89c4ff92SAndroid Build Coastguard Worker
GetQueueDescriptor__anone931cbbc0111::Workload064*89c4ff92SAndroid Build Coastguard Worker QueueDescriptor* GetQueueDescriptor()
65*89c4ff92SAndroid Build Coastguard Worker {
66*89c4ff92SAndroid Build Coastguard Worker return &m_Data;
67*89c4ff92SAndroid Build Coastguard Worker }
68*89c4ff92SAndroid Build Coastguard Worker };
69*89c4ff92SAndroid Build Coastguard Worker
70*89c4ff92SAndroid Build Coastguard Worker struct Workload1 : BaseWorkload<ElementwiseUnaryQueueDescriptor>
71*89c4ff92SAndroid Build Coastguard Worker {
Workload1__anone931cbbc0111::Workload172*89c4ff92SAndroid Build Coastguard Worker Workload1(const ElementwiseUnaryQueueDescriptor& descriptor, const WorkloadInfo& info)
73*89c4ff92SAndroid Build Coastguard Worker : BaseWorkload(descriptor, info)
74*89c4ff92SAndroid Build Coastguard Worker {
75*89c4ff92SAndroid Build Coastguard Worker }
76*89c4ff92SAndroid Build Coastguard Worker
Execute__anone931cbbc0111::Workload177*89c4ff92SAndroid Build Coastguard Worker void Execute() const
78*89c4ff92SAndroid Build Coastguard Worker {
79*89c4ff92SAndroid Build Coastguard Worker int* inVals = static_cast<int*>(m_Data.m_Inputs[0][0].Map());
80*89c4ff92SAndroid Build Coastguard Worker int* outVals = static_cast<int*>(m_Data.m_Outputs[0][0].Map());
81*89c4ff92SAndroid Build Coastguard Worker
82*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0;
83*89c4ff92SAndroid Build Coastguard Worker i < m_Data.m_Inputs[0][0].GetShape().GetNumElements();
84*89c4ff92SAndroid Build Coastguard Worker ++i)
85*89c4ff92SAndroid Build Coastguard Worker {
86*89c4ff92SAndroid Build Coastguard Worker outVals[i] = inVals[i] * outVals[i];
87*89c4ff92SAndroid Build Coastguard Worker inVals[i] = outVals[i];
88*89c4ff92SAndroid Build Coastguard Worker }
89*89c4ff92SAndroid Build Coastguard Worker }
90*89c4ff92SAndroid Build Coastguard Worker };
91*89c4ff92SAndroid Build Coastguard Worker
ValidateTensor(ITensorHandle * tensorHandle,int expectedValue)92*89c4ff92SAndroid Build Coastguard Worker void ValidateTensor(ITensorHandle* tensorHandle, int expectedValue)
93*89c4ff92SAndroid Build Coastguard Worker {
94*89c4ff92SAndroid Build Coastguard Worker int* actualOutput = static_cast<int*>(tensorHandle->Map());
95*89c4ff92SAndroid Build Coastguard Worker
96*89c4ff92SAndroid Build Coastguard Worker bool allValuesCorrect = true;
97*89c4ff92SAndroid Build Coastguard Worker for (unsigned int i = 0;
98*89c4ff92SAndroid Build Coastguard Worker i < tensorHandle->GetShape().GetNumElements();
99*89c4ff92SAndroid Build Coastguard Worker ++i)
100*89c4ff92SAndroid Build Coastguard Worker {
101*89c4ff92SAndroid Build Coastguard Worker if (actualOutput[i] != expectedValue)
102*89c4ff92SAndroid Build Coastguard Worker {
103*89c4ff92SAndroid Build Coastguard Worker allValuesCorrect = false;
104*89c4ff92SAndroid Build Coastguard Worker }
105*89c4ff92SAndroid Build Coastguard Worker }
106*89c4ff92SAndroid Build Coastguard Worker
107*89c4ff92SAndroid Build Coastguard Worker CHECK(allValuesCorrect);
108*89c4ff92SAndroid Build Coastguard Worker }
109*89c4ff92SAndroid Build Coastguard Worker
110*89c4ff92SAndroid Build Coastguard Worker template<typename Workload>
CreateWorkload(TensorInfo info,ITensorHandle * inputTensor,ITensorHandle * outputTensor)111*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<Workload> CreateWorkload(TensorInfo info, ITensorHandle* inputTensor, ITensorHandle* outputTensor)
112*89c4ff92SAndroid Build Coastguard Worker {
113*89c4ff92SAndroid Build Coastguard Worker WorkloadInfo workloadInfo;
114*89c4ff92SAndroid Build Coastguard Worker workloadInfo.m_InputTensorInfos = std::vector<TensorInfo>{info};
115*89c4ff92SAndroid Build Coastguard Worker workloadInfo.m_OutputTensorInfos = std::vector<TensorInfo>{info};
116*89c4ff92SAndroid Build Coastguard Worker
117*89c4ff92SAndroid Build Coastguard Worker ElementwiseUnaryQueueDescriptor elementwiseUnaryQueueDescriptor;
118*89c4ff92SAndroid Build Coastguard Worker elementwiseUnaryQueueDescriptor.m_Inputs = std::vector<ITensorHandle*>{inputTensor};
119*89c4ff92SAndroid Build Coastguard Worker elementwiseUnaryQueueDescriptor.m_Outputs = std::vector<ITensorHandle*>{outputTensor};
120*89c4ff92SAndroid Build Coastguard Worker
121*89c4ff92SAndroid Build Coastguard Worker return std::make_unique<Workload>(elementwiseUnaryQueueDescriptor, workloadInfo);
122*89c4ff92SAndroid Build Coastguard Worker }
123*89c4ff92SAndroid Build Coastguard Worker
124*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("TestAsyncExecute")
125*89c4ff92SAndroid Build Coastguard Worker {
126*89c4ff92SAndroid Build Coastguard Worker TensorInfo info({5}, DataType::Signed32, 0.0, 0, true);
127*89c4ff92SAndroid Build Coastguard Worker
128*89c4ff92SAndroid Build Coastguard Worker int inVals[5]{2, 2, 2, 2, 2};
129*89c4ff92SAndroid Build Coastguard Worker int outVals[5]{1, 1, 1, 1, 1};
130*89c4ff92SAndroid Build Coastguard Worker
131*89c4ff92SAndroid Build Coastguard Worker int expectedExecuteval = 2;
132*89c4ff92SAndroid Build Coastguard Worker int expectedExecuteAsyncval = 3;
133*89c4ff92SAndroid Build Coastguard Worker
134*89c4ff92SAndroid Build Coastguard Worker ConstTensor constInputTensor(info, inVals);
135*89c4ff92SAndroid Build Coastguard Worker ConstTensor constOutputTensor(info, outVals);
136*89c4ff92SAndroid Build Coastguard Worker
137*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle syncInput0(constInputTensor);
138*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle syncOutput0(constOutputTensor);
139*89c4ff92SAndroid Build Coastguard Worker
140*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<Workload0> workload0 = CreateWorkload<Workload0>(info, &syncInput0, &syncOutput0);
141*89c4ff92SAndroid Build Coastguard Worker
142*89c4ff92SAndroid Build Coastguard Worker workload0.get()->Execute();
143*89c4ff92SAndroid Build Coastguard Worker
144*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncInput0(constInputTensor);
145*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncOutput0(constOutputTensor);
146*89c4ff92SAndroid Build Coastguard Worker
147*89c4ff92SAndroid Build Coastguard Worker WorkingMemDescriptor workingMemDescriptor0;
148*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor0.m_Inputs = std::vector<ITensorHandle*>{&asyncInput0};
149*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor0.m_Outputs = std::vector<ITensorHandle*>{&asyncOutput0};
150*89c4ff92SAndroid Build Coastguard Worker
151*89c4ff92SAndroid Build Coastguard Worker ExecutionData executionData;
152*89c4ff92SAndroid Build Coastguard Worker executionData.m_Data = &workingMemDescriptor0;
153*89c4ff92SAndroid Build Coastguard Worker
154*89c4ff92SAndroid Build Coastguard Worker workload0.get()->ExecuteAsync(executionData);
155*89c4ff92SAndroid Build Coastguard Worker
156*89c4ff92SAndroid Build Coastguard Worker // Inputs are also changed by the execute/executeAsync calls to make sure there is no interference with them
157*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor0.m_Outputs[0], expectedExecuteAsyncval);
158*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor0.m_Inputs[0], expectedExecuteAsyncval);
159*89c4ff92SAndroid Build Coastguard Worker
160*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Outputs[0][0], expectedExecuteval);
161*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(&workload0.get()->GetQueueDescriptor()->m_Inputs[0][0], expectedExecuteval);
162*89c4ff92SAndroid Build Coastguard Worker }
163*89c4ff92SAndroid Build Coastguard Worker
164*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("TestDefaultAsyncExecute")
165*89c4ff92SAndroid Build Coastguard Worker {
166*89c4ff92SAndroid Build Coastguard Worker TensorInfo info({5}, DataType::Signed32, 0.0f, 0, true);
167*89c4ff92SAndroid Build Coastguard Worker
168*89c4ff92SAndroid Build Coastguard Worker std::vector<int> inVals{2, 2, 2, 2, 2};
169*89c4ff92SAndroid Build Coastguard Worker std::vector<int> outVals{1, 1, 1, 1, 1};
170*89c4ff92SAndroid Build Coastguard Worker std::vector<int> defaultVals{0, 0, 0, 0, 0};
171*89c4ff92SAndroid Build Coastguard Worker
172*89c4ff92SAndroid Build Coastguard Worker int expectedExecuteval = 2;
173*89c4ff92SAndroid Build Coastguard Worker
174*89c4ff92SAndroid Build Coastguard Worker ConstTensor constInputTensor(info, inVals);
175*89c4ff92SAndroid Build Coastguard Worker ConstTensor constOutputTensor(info, outVals);
176*89c4ff92SAndroid Build Coastguard Worker ConstTensor defaultTensor(info, &defaultVals);
177*89c4ff92SAndroid Build Coastguard Worker
178*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle defaultInput = ScopedTensorHandle(defaultTensor);
179*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle defaultOutput = ScopedTensorHandle(defaultTensor);
180*89c4ff92SAndroid Build Coastguard Worker
181*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<Workload1> workload1 = CreateWorkload<Workload1>(info, &defaultInput, &defaultOutput);
182*89c4ff92SAndroid Build Coastguard Worker
183*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncInput(constInputTensor);
184*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncOutput(constOutputTensor);
185*89c4ff92SAndroid Build Coastguard Worker
186*89c4ff92SAndroid Build Coastguard Worker WorkingMemDescriptor workingMemDescriptor;
187*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor.m_Inputs = std::vector<ITensorHandle*>{&asyncInput};
188*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor.m_Outputs = std::vector<ITensorHandle*>{&asyncOutput};
189*89c4ff92SAndroid Build Coastguard Worker
190*89c4ff92SAndroid Build Coastguard Worker ExecutionData executionData;
191*89c4ff92SAndroid Build Coastguard Worker executionData.m_Data = &workingMemDescriptor;
192*89c4ff92SAndroid Build Coastguard Worker
193*89c4ff92SAndroid Build Coastguard Worker workload1.get()->ExecuteAsync(executionData);
194*89c4ff92SAndroid Build Coastguard Worker
195*89c4ff92SAndroid Build Coastguard Worker // workload1 has no AsyncExecute implementation and so should use the default workload AsyncExecute
196*89c4ff92SAndroid Build Coastguard Worker // implementation which will call workload1.Execute() in a thread safe manner
197*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor.m_Outputs[0], expectedExecuteval);
198*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor.m_Inputs[0], expectedExecuteval);
199*89c4ff92SAndroid Build Coastguard Worker }
200*89c4ff92SAndroid Build Coastguard Worker
201*89c4ff92SAndroid Build Coastguard Worker TEST_CASE("TestDefaultAsyncExeuteWithThreads")
202*89c4ff92SAndroid Build Coastguard Worker {
203*89c4ff92SAndroid Build Coastguard Worker // Use a large vector so the threads have a chance to interact
204*89c4ff92SAndroid Build Coastguard Worker unsigned int vecSize = 1000;
205*89c4ff92SAndroid Build Coastguard Worker TensorInfo info({vecSize}, DataType::Signed32, 0.0f, 0, true);
206*89c4ff92SAndroid Build Coastguard Worker
207*89c4ff92SAndroid Build Coastguard Worker std::vector<int> inVals1(vecSize, 2);
208*89c4ff92SAndroid Build Coastguard Worker std::vector<int> outVals1(vecSize, 1);
209*89c4ff92SAndroid Build Coastguard Worker std::vector<int> inVals2(vecSize, 5);
210*89c4ff92SAndroid Build Coastguard Worker std::vector<int> outVals2(vecSize, -1);
211*89c4ff92SAndroid Build Coastguard Worker
212*89c4ff92SAndroid Build Coastguard Worker std::vector<int> defaultVals(vecSize, 0);
213*89c4ff92SAndroid Build Coastguard Worker
214*89c4ff92SAndroid Build Coastguard Worker int expectedExecuteval1 = 4;
215*89c4ff92SAndroid Build Coastguard Worker int expectedExecuteval2 = 25;
216*89c4ff92SAndroid Build Coastguard Worker ConstTensor constInputTensor1(info, inVals1);
217*89c4ff92SAndroid Build Coastguard Worker ConstTensor constOutputTensor1(info, outVals1);
218*89c4ff92SAndroid Build Coastguard Worker
219*89c4ff92SAndroid Build Coastguard Worker ConstTensor constInputTensor2(info, inVals2);
220*89c4ff92SAndroid Build Coastguard Worker ConstTensor constOutputTensor2(info, outVals2);
221*89c4ff92SAndroid Build Coastguard Worker
222*89c4ff92SAndroid Build Coastguard Worker ConstTensor defaultTensor(info, defaultVals.data());
223*89c4ff92SAndroid Build Coastguard Worker
224*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle defaultInput = ScopedTensorHandle(defaultTensor);
225*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle defaultOutput = ScopedTensorHandle(defaultTensor);
226*89c4ff92SAndroid Build Coastguard Worker std::unique_ptr<Workload1> workload = CreateWorkload<Workload1>(info, &defaultInput, &defaultOutput);
227*89c4ff92SAndroid Build Coastguard Worker
228*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncInput1(constInputTensor1);
229*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncOutput1(constOutputTensor1);
230*89c4ff92SAndroid Build Coastguard Worker
231*89c4ff92SAndroid Build Coastguard Worker WorkingMemDescriptor workingMemDescriptor1;
232*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor1.m_Inputs = std::vector<ITensorHandle*>{&asyncInput1};
233*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor1.m_Outputs = std::vector<ITensorHandle*>{&asyncOutput1};
234*89c4ff92SAndroid Build Coastguard Worker
235*89c4ff92SAndroid Build Coastguard Worker ExecutionData executionData1;
236*89c4ff92SAndroid Build Coastguard Worker executionData1.m_Data = &workingMemDescriptor1;
237*89c4ff92SAndroid Build Coastguard Worker
238*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncInput2(constInputTensor2);
239*89c4ff92SAndroid Build Coastguard Worker ScopedTensorHandle asyncOutput2(constOutputTensor2);
240*89c4ff92SAndroid Build Coastguard Worker
241*89c4ff92SAndroid Build Coastguard Worker WorkingMemDescriptor workingMemDescriptor2;
242*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor2.m_Inputs = std::vector<ITensorHandle*>{&asyncInput2};
243*89c4ff92SAndroid Build Coastguard Worker workingMemDescriptor2.m_Outputs = std::vector<ITensorHandle*>{&asyncOutput2};
244*89c4ff92SAndroid Build Coastguard Worker
245*89c4ff92SAndroid Build Coastguard Worker ExecutionData executionData2;
246*89c4ff92SAndroid Build Coastguard Worker executionData2.m_Data = &workingMemDescriptor2;
247*89c4ff92SAndroid Build Coastguard Worker
248*89c4ff92SAndroid Build Coastguard Worker std::thread thread1 = std::thread([&]()
__anone931cbbc0202() 249*89c4ff92SAndroid Build Coastguard Worker {
250*89c4ff92SAndroid Build Coastguard Worker workload.get()->ExecuteAsync(executionData1);
251*89c4ff92SAndroid Build Coastguard Worker workload.get()->ExecuteAsync(executionData1);
252*89c4ff92SAndroid Build Coastguard Worker });
253*89c4ff92SAndroid Build Coastguard Worker
254*89c4ff92SAndroid Build Coastguard Worker std::thread thread2 = std::thread([&]()
__anone931cbbc0302() 255*89c4ff92SAndroid Build Coastguard Worker {
256*89c4ff92SAndroid Build Coastguard Worker workload.get()->ExecuteAsync(executionData2);
257*89c4ff92SAndroid Build Coastguard Worker workload.get()->ExecuteAsync(executionData2);
258*89c4ff92SAndroid Build Coastguard Worker });
259*89c4ff92SAndroid Build Coastguard Worker
260*89c4ff92SAndroid Build Coastguard Worker thread1.join();
261*89c4ff92SAndroid Build Coastguard Worker thread2.join();
262*89c4ff92SAndroid Build Coastguard Worker
263*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor1.m_Outputs[0], expectedExecuteval1);
264*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor1.m_Inputs[0], expectedExecuteval1);
265*89c4ff92SAndroid Build Coastguard Worker
266*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor2.m_Outputs[0], expectedExecuteval2);
267*89c4ff92SAndroid Build Coastguard Worker ValidateTensor(workingMemDescriptor2.m_Inputs[0], expectedExecuteval2);
268*89c4ff92SAndroid Build Coastguard Worker }
269*89c4ff92SAndroid Build Coastguard Worker
270*89c4ff92SAndroid Build Coastguard Worker }
271*89c4ff92SAndroid Build Coastguard Worker
272*89c4ff92SAndroid Build Coastguard Worker }
273