1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "NeuralNetworksOEM.h"
18 #include "NeuralNetworksWrapper.h"
19 
20 #include <gtest/gtest.h>
21 #include <optional>
22 #include <set>
23 
24 using namespace android::nn::wrapper;
25 
26 namespace {
27 
28 static const int32_t kAvailableOperandCodes[] = {ANEURALNETWORKS_FLOAT32,
29                                                  ANEURALNETWORKS_INT32,
30                                                  ANEURALNETWORKS_UINT32,
31                                                  ANEURALNETWORKS_TENSOR_FLOAT32,
32                                                  ANEURALNETWORKS_TENSOR_INT32,
33                                                  ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
34                                                  ANEURALNETWORKS_BOOL,
35                                                  ANEURALNETWORKS_TENSOR_QUANT16_SYMM,
36                                                  ANEURALNETWORKS_TENSOR_FLOAT16,
37                                                  ANEURALNETWORKS_TENSOR_BOOL8,
38                                                  ANEURALNETWORKS_FLOAT16,
39                                                  ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL,
40                                                  ANEURALNETWORKS_TENSOR_QUANT16_ASYMM,
41                                                  ANEURALNETWORKS_TENSOR_OEM_BYTE};
42 
getOpType(int32_t opcode,uint32_t dimCount=0,uint32_t * dim=nullptr)43 ANeuralNetworksOperandType getOpType(int32_t opcode, uint32_t dimCount = 0,
44                                      uint32_t* dim = nullptr) {
45     ANeuralNetworksOperandType opType = {.type = opcode,
46                                          .dimensionCount = dimCount,
47                                          .dimensions = dim,
48                                          .scale = 0.0,
49                                          .zeroPoint = 0};
50     if (opcode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM ||
51         opcode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM ||
52         opcode == ANEURALNETWORKS_TENSOR_QUANT16_ASYMM ||
53         opcode == ANEURALNETWORKS_TENSOR_QUANT16_SYMM) {
54         opType.scale = 1. / 256.;
55     }
56     return opType;
57 }
58 
59 struct OperandTypeWithExtraParams {
OperandTypeWithExtraParams__anon37b312a30111::OperandTypeWithExtraParams60     OperandTypeWithExtraParams(const ANeuralNetworksOperandType& operandType)
61         : operandType(operandType), channelQuant(std::nullopt) {}
62 
63     ANeuralNetworksOperandType operandType;
64     std::optional<ANeuralNetworksSymmPerChannelQuantParams> channelQuant;
65 };
66 
67 class OperationTestBase {
68    public:
OperationTestBase(ANeuralNetworksOperationType opCode,std::vector<ANeuralNetworksOperandType> validInputs,std::vector<ANeuralNetworksOperandType> validOutputs)69     OperationTestBase(ANeuralNetworksOperationType opCode,
70                       std::vector<ANeuralNetworksOperandType> validInputs,
71                       std::vector<ANeuralNetworksOperandType> validOutputs)
72         : mOpCode(opCode) {
73         for (ANeuralNetworksOperandType input : validInputs) {
74             mValidInputs.push_back(input);
75         }
76         for (ANeuralNetworksOperandType output : validOutputs) {
77             mValidOutputs.push_back(output);
78         }
79     }
80 
setInputSymmPerChannelQuantParams(int32_t index,const ANeuralNetworksSymmPerChannelQuantParams & channelQuant)81     void setInputSymmPerChannelQuantParams(
82             int32_t index, const ANeuralNetworksSymmPerChannelQuantParams& channelQuant) {
83         mValidInputs[index].channelQuant = channelQuant;
84     }
85 
setOutputSymmPerChannelQuantParams(int32_t index,const ANeuralNetworksSymmPerChannelQuantParams & channelQuant)86     void setOutputSymmPerChannelQuantParams(
87             int32_t index, const ANeuralNetworksSymmPerChannelQuantParams& channelQuant) {
88         mValidOutputs[index].channelQuant = channelQuant;
89     }
90 
91     // Add each operand separately and add the operation using these operands.
92     // This function does not cover the cases that an operand is used mutiple times.
addOperation(const std::vector<OperandTypeWithExtraParams> & inputs,const std::vector<OperandTypeWithExtraParams> & outputs)93     int32_t addOperation(const std::vector<OperandTypeWithExtraParams>& inputs,
94                          const std::vector<OperandTypeWithExtraParams>& outputs) {
95         ANeuralNetworksModel* model = nullptr;
96         ANeuralNetworksModel_create(&model);
97 
98         uint32_t opIdx = 0;
99         std::vector<uint32_t> inputIds;
100         std::vector<uint32_t> outputIds;
101         for (uint32_t i = 0; i < inputs.size(); i++) {
102             ANeuralNetworksModel_addOperand(model, &inputs[i].operandType);
103             if (inputs[i].channelQuant) {
104                 ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(
105                         model, opIdx, &inputs[i].channelQuant.value());
106             }
107             inputIds.push_back(opIdx++);
108         }
109         for (uint32_t i = 0; i < outputs.size(); i++) {
110             ANeuralNetworksModel_addOperand(model, &outputs[i].operandType);
111             if (outputs[i].channelQuant) {
112                 ANeuralNetworksModel_setOperandSymmPerChannelQuantParams(
113                         model, opIdx, &outputs[i].channelQuant.value());
114             }
115             outputIds.push_back(opIdx++);
116         }
117 
118         int32_t result = ANeuralNetworksModel_addOperation(
119                 model, mOpCode, static_cast<uint32_t>(inputIds.size()), inputIds.data(),
120                 static_cast<uint32_t>(outputIds.size()), outputIds.data());
121         ANeuralNetworksModel_free(model);
122         return result;
123     }
124 
testOpsValidations()125     void testOpsValidations() {
126         EXPECT_TRUE(testSuccess());
127         EXPECT_TRUE(testMutatingInputOperandCode());
128         EXPECT_TRUE(testMutatingInputOperandCounts());
129         EXPECT_TRUE(testMutatingOutputOperandCode());
130         EXPECT_TRUE(testMutatingOutputOperandCounts());
131     }
132 
testFailure(int32_t expectedResult)133     void testFailure(int32_t expectedResult) {
134         int32_t result = addOperation(mValidInputs, mValidOutputs);
135         EXPECT_TRUE(expectedResult == result);
136     }
137 
testSuccess()138     bool testSuccess() {
139         int32_t result = addOperation(mValidInputs, mValidOutputs);
140         return ANEURALNETWORKS_NO_ERROR == result;
141     }
142 
testMutatingInputOperandCode()143     bool testMutatingInputOperandCode() {
144         for (uint32_t i = 0; i < mValidInputs.size(); i++) {
145             // LSH_PROJECTION's second argument is allowed to have any type.
146             // This is the only operation that currently has a type that can be
147             // anything independent from any other type. Changing the operand
148             // type to any other type will result in a valid model for
149             // LSH_PROJECTION. If this is the case, skip the test.
150             if (mOpCode == ANEURALNETWORKS_LSH_PROJECTION && i == 1) {
151                 continue;
152             }
153             OperandTypeWithExtraParams newType = mValidInputs[i];
154             int32_t originalOperandCode = mValidInputs[i].operandType.type;
155             std::set<int32_t> operandTypesToSkip;
156             // Transposed conv can have either fully quantized or per-channel
157             // quantized filter for the quantized version of the op.
158             if (mOpCode == ANEURALNETWORKS_TRANSPOSE_CONV_2D && i == 1) {
159                 if (originalOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
160                     operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
161                 } else if (originalOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
162                     operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
163                 }
164             }
165             // CAST accepts any of supported types for any of output types
166             if (mOpCode == ANEURALNETWORKS_CAST && i == 0) {
167                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_FLOAT16);
168                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_FLOAT32);
169                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_INT32);
170                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
171             }
172             // RANDOM_MULTINOMIAL's first input can be either of float16 or
173             // float32 type while everything else has the same types.
174             if (mOpCode == ANEURALNETWORKS_RANDOM_MULTINOMIAL && i == 0) {
175                 if (originalOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16) {
176                     operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_FLOAT32);
177                 } else if (originalOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32) {
178                     operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_FLOAT16);
179                 }
180             }
181             // DEQUANTIZE supports any of the inputs types below for any of the
182             // output types.
183             if (mOpCode == ANEURALNETWORKS_DEQUANTIZE && i == 0) {
184                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
185                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_SYMM);
186                 operandTypesToSkip.insert(ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
187             }
188             for (int32_t newOperandCode : kAvailableOperandCodes) {
189                 if (newOperandCode == originalOperandCode ||
190                     operandTypesToSkip.find(newOperandCode) != operandTypesToSkip.end()) {
191                     continue;
192                 }
193                 // Switch input 7 from bool to int for 10-input CONV_2d
194                 // switch between valid "implicit padding with layout param"
195                 // and valid "explicit padding without layout param"
196                 if (mOpCode == ANEURALNETWORKS_CONV_2D && i == 7 && mValidInputs.size() == 10) {
197                     if ((newOperandCode == ANEURALNETWORKS_INT32 &&
198                          originalOperandCode == ANEURALNETWORKS_BOOL) ||
199                         (newOperandCode == ANEURALNETWORKS_BOOL &&
200                          originalOperandCode == ANEURALNETWORKS_INT32)) {
201                         continue;
202                     }
203                 }
204                 // QUANTIZE supports both types below and its output type does
205                 // not depend on the input type.
206                 if (mOpCode == ANEURALNETWORKS_QUANTIZE && i == 0 &&
207                     (newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16 ||
208                      newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32)) {
209                     continue;
210                 }
211                 // ARGMIN/MAX supports four input types and has a fixed output type.
212                 if ((mOpCode == ANEURALNETWORKS_ARGMIN || mOpCode == ANEURALNETWORKS_ARGMAX) &&
213                     i == 0 &&
214                     (newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16 ||
215                      newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32 ||
216                      newOperandCode == ANEURALNETWORKS_TENSOR_INT32 ||
217                      newOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM)) {
218                     continue;
219                 }
220 
221                 // Switch input 8 from bool to int for 11-input DEPTHWISE_CONV_2D
222                 // switch between valid "implicit padding with layout param"
223                 // and valid "explicit padding without layout param"
224                 if (mOpCode == ANEURALNETWORKS_DEPTHWISE_CONV_2D && i == 8 &&
225                     mValidInputs.size() == 11) {
226                     if ((newOperandCode == ANEURALNETWORKS_INT32 &&
227                          originalOperandCode == ANEURALNETWORKS_BOOL) ||
228                         (newOperandCode == ANEURALNETWORKS_BOOL &&
229                          originalOperandCode == ANEURALNETWORKS_INT32)) {
230                         continue;
231                     }
232                 }
233 
234                 newType.operandType.type = newOperandCode;
235                 std::vector<OperandTypeWithExtraParams> inputs = mValidInputs;
236                 inputs[i] = newType;
237                 int32_t result = addOperation(inputs, mValidOutputs);
238                 if (ANEURALNETWORKS_NO_ERROR == result) {
239                     return false;
240                 }
241             }
242         }
243         return true;
244     }
245 
testMutatingOutputOperandCode()246     bool testMutatingOutputOperandCode() {
247         for (uint32_t i = 0; i < mValidOutputs.size(); i++) {
248             // LSH_PROJECTION's second argument is allowed to have any type.
249             // This is the only operation that currently has a type that can be
250             // anything independent from any other type. Changing the operand
251             // type to any other type will result in a valid model for
252             // LSH_PROJECTION. If this is the case, skip the test.
253             if (mOpCode == ANEURALNETWORKS_LSH_PROJECTION && i == 1) {
254                 continue;
255             }
256             OperandTypeWithExtraParams newType = mValidOutputs[i].operandType;
257             int32_t originalOperandCode = mValidOutputs[i].operandType.type;
258             for (int32_t newOperandCode : kAvailableOperandCodes) {
259                 if (newOperandCode == originalOperandCode) {
260                     continue;
261                 }
262                 // DEQUANTIZE's output can be either TENSOR_FLOAT16 or TENSOR_FLOAT32.
263                 if (mOpCode == ANEURALNETWORKS_DEQUANTIZE &&
264                     (newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16 ||
265                      newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32)) {
266                     continue;
267                 }
268                 // CAST accepts any of supported types for any of input types
269                 if (mOpCode == ANEURALNETWORKS_CAST && i == 0 &&
270                     (newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16 ||
271                      newOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32 ||
272                      newOperandCode == ANEURALNETWORKS_TENSOR_INT32 ||
273                      newOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM)) {
274                     continue;
275                 }
276                 newType.operandType.type = newOperandCode;
277                 std::vector<OperandTypeWithExtraParams> outputs = mValidOutputs;
278                 outputs[i] = newType;
279                 int32_t result = addOperation(mValidInputs, outputs);
280                 if (ANEURALNETWORKS_NO_ERROR == result) {
281                     return false;
282                 }
283             }
284         }
285         return true;
286     }
287 
testMutatingInputOperandCounts()288     bool testMutatingInputOperandCounts() {
289         uint32_t numToAdd = 5;
290         // LSTM since API 29 supports 23 and 27 outputs.
291         if (mOpCode == ANEURALNETWORKS_LSTM) {
292             numToAdd = 3;
293         }
294         std::vector<OperandTypeWithExtraParams> inputs = mValidInputs;
295         for (uint32_t i = 0; i < numToAdd; i++) {
296             inputs.push_back(inputs[0]);
297             if (ANEURALNETWORKS_NO_ERROR == addOperation(inputs, mValidOutputs)) {
298                 return false;
299             }
300         }
301         return true;
302     }
303 
testMutatingOutputOperandCounts()304     bool testMutatingOutputOperandCounts() {
305         // SPLIT's number of outputs depends on a value of one of its inputs and
306         // are not checked during validation.
307         if (mOpCode == ANEURALNETWORKS_SPLIT) {
308             return true;
309         }
310         std::vector<OperandTypeWithExtraParams> outputs = mValidOutputs;
311         for (int i = 0; i < 5; i++) {
312             outputs.push_back(outputs[0]);
313             if (ANEURALNETWORKS_NO_ERROR == addOperation(mValidInputs, outputs)) {
314                 return false;
315             }
316         }
317         return true;
318     }
319 
320    private:
321     ANeuralNetworksOperationType mOpCode;
322     // The dimensions in the ANeuralNetworksOperandType must outlive the test object.
323     std::vector<OperandTypeWithExtraParams> mValidInputs;
324     std::vector<OperandTypeWithExtraParams> mValidOutputs;
325 };
326 
argMinMaxTest(ANeuralNetworksOperationType operationCode,int32_t inputOperandType)327 void argMinMaxTest(ANeuralNetworksOperationType operationCode, int32_t inputOperandType) {
328     SCOPED_TRACE(inputOperandType);
329     uint32_t inputDimensions[4] = {2, 2, 2, 2};
330     ANeuralNetworksOperandType input0 = getOpType(inputOperandType, 4, inputDimensions);
331     ANeuralNetworksOperandType axis = {
332             .type = ANEURALNETWORKS_INT32,
333             .dimensionCount = 0,
334             .dimensions = nullptr,
335     };
336     uint32_t outputDimensions[3] = {2, 2, 2};
337     ANeuralNetworksOperandType output = {
338             .type = ANEURALNETWORKS_TENSOR_INT32,
339             .dimensionCount = 3,
340             .dimensions = outputDimensions,
341     };
342     OperationTestBase test(operationCode, {input0, axis}, {output});
343     test.testOpsValidations();
344 }
345 
TEST(OperationValidationTest,ARGMIN)346 TEST(OperationValidationTest, ARGMIN) {
347     argMinMaxTest(ANEURALNETWORKS_ARGMIN, ANEURALNETWORKS_TENSOR_FLOAT16);
348     argMinMaxTest(ANEURALNETWORKS_ARGMIN, ANEURALNETWORKS_TENSOR_FLOAT32);
349     argMinMaxTest(ANEURALNETWORKS_ARGMIN, ANEURALNETWORKS_TENSOR_INT32);
350     argMinMaxTest(ANEURALNETWORKS_ARGMIN, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
351 }
352 
TEST(OperationValidationTest,ARGMAX)353 TEST(OperationValidationTest, ARGMAX) {
354     argMinMaxTest(ANEURALNETWORKS_ARGMAX, ANEURALNETWORKS_TENSOR_FLOAT16);
355     argMinMaxTest(ANEURALNETWORKS_ARGMAX, ANEURALNETWORKS_TENSOR_FLOAT32);
356     argMinMaxTest(ANEURALNETWORKS_ARGMAX, ANEURALNETWORKS_TENSOR_INT32);
357     argMinMaxTest(ANEURALNETWORKS_ARGMAX, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
358 }
359 
dequantizeOpTest(int32_t inputOperandType,int32_t outputOperandType)360 void dequantizeOpTest(int32_t inputOperandType, int32_t outputOperandType) {
361     std::string scope = "inputType: " + std::to_string(inputOperandType) +
362                         ", outputType: " + std::to_string(outputOperandType);
363     SCOPED_TRACE(scope);
364     uint32_t inputDimensions[4] = {2, 2, 2, 2};
365     ANeuralNetworksOperandType input = getOpType(inputOperandType, 4, inputDimensions);
366     ANeuralNetworksOperandType output = getOpType(outputOperandType, 4, inputDimensions);
367     OperationTestBase dequantizeTest(ANEURALNETWORKS_DEQUANTIZE, {input}, {output});
368     dequantizeTest.testOpsValidations();
369 }
370 
TEST(OperationValidationTest,DEQUANTIZE)371 TEST(OperationValidationTest, DEQUANTIZE) {
372     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_FLOAT16);
373     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_FLOAT32);
374     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_SYMM, ANEURALNETWORKS_TENSOR_FLOAT16);
375     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_SYMM, ANEURALNETWORKS_TENSOR_FLOAT32);
376     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL,
377                      ANEURALNETWORKS_TENSOR_FLOAT16);
378     dequantizeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL,
379                      ANEURALNETWORKS_TENSOR_FLOAT32);
380 }
381 
expandDimsTest(int32_t inputOperandType)382 void expandDimsTest(int32_t inputOperandType) {
383     SCOPED_TRACE(inputOperandType);
384     uint32_t inputDimensions[4] = {2, 2, 2, 2};
385     ANeuralNetworksOperandType input0 = getOpType(inputOperandType, 4, inputDimensions);
386     ANeuralNetworksOperandType axis = {
387             .type = ANEURALNETWORKS_INT32,
388             .dimensionCount = 0,
389             .dimensions = nullptr,
390     };
391     uint32_t outputDimensions[5] = {2, 2, 2, 2, 2};
392     ANeuralNetworksOperandType output = getOpType(inputOperandType, 5, outputDimensions);
393     OperationTestBase test(ANEURALNETWORKS_EXPAND_DIMS, {input0, axis}, {output});
394     test.testOpsValidations();
395 }
396 
TEST(OperationValidationTest,EXPAND_DIMS)397 TEST(OperationValidationTest, EXPAND_DIMS) {
398     expandDimsTest(ANEURALNETWORKS_TENSOR_FLOAT16);
399     expandDimsTest(ANEURALNETWORKS_TENSOR_FLOAT32);
400     expandDimsTest(ANEURALNETWORKS_TENSOR_INT32);
401     expandDimsTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
402 }
403 
gatherTest(int32_t inputOperandType)404 void gatherTest(int32_t inputOperandType) {
405     SCOPED_TRACE(inputOperandType);
406     uint32_t inputDimensions[4] = {2, 2, 2, 2};
407     ANeuralNetworksOperandType input0 = getOpType(inputOperandType, 4, inputDimensions);
408     ANeuralNetworksOperandType axis = {
409             .type = ANEURALNETWORKS_INT32,
410             .dimensionCount = 0,
411             .dimensions = nullptr,
412     };
413     ANeuralNetworksOperandType input2 = {
414             .type = ANEURALNETWORKS_TENSOR_INT32,
415             .dimensionCount = 4,
416             .dimensions = inputDimensions,
417     };
418     uint32_t outputDimensions[7] = {2, 2, 2, 2, 2, 2, 2};
419     ANeuralNetworksOperandType output = getOpType(inputOperandType, 7, outputDimensions);
420     OperationTestBase test(ANEURALNETWORKS_GATHER, {input0, axis, input2}, {output});
421     test.testOpsValidations();
422 }
423 
TEST(OperationValidationTest,GATHER)424 TEST(OperationValidationTest, GATHER) {
425     gatherTest(ANEURALNETWORKS_TENSOR_FLOAT16);
426     gatherTest(ANEURALNETWORKS_TENSOR_FLOAT32);
427     gatherTest(ANEURALNETWORKS_TENSOR_INT32);
428     gatherTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
429 }
430 
quantizeOpTest(int32_t operandCode)431 void quantizeOpTest(int32_t operandCode) {
432     uint32_t inputDimensions[4] = {2, 2, 2, 2};
433     ANeuralNetworksOperandType input = {
434             .type = operandCode, .dimensionCount = 4, .dimensions = inputDimensions};
435     ANeuralNetworksOperandType output = {.type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
436                                          .dimensionCount = 4,
437                                          .dimensions = inputDimensions,
438                                          .scale = 1.0f,
439                                          .zeroPoint = 0};
440     OperationTestBase test(ANEURALNETWORKS_QUANTIZE, {input}, {output});
441     test.testOpsValidations();
442 }
443 
TEST(OperationValidationTest,QUANTIZE_float16)444 TEST(OperationValidationTest, QUANTIZE_float16) {
445     quantizeOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
446 }
447 
TEST(OperationValidationTest,QUANTIZE_float32)448 TEST(OperationValidationTest, QUANTIZE_float32) {
449     quantizeOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
450 }
451 
TEST(OperationValidationTest,QUANTIZED_16BIT_LSTM)452 TEST(OperationValidationTest, QUANTIZED_16BIT_LSTM) {
453     uint32_t oneDimensional[1] = {5};
454     uint32_t twoDimensional[2] = {5, 5};
455 
456     ANeuralNetworksOperandType int32Tensor1D = {
457             .type = ANEURALNETWORKS_TENSOR_INT32,
458             .dimensionCount = 1,
459             .dimensions = oneDimensional,
460             .scale = 0.0000318,
461             .zeroPoint = 0,
462     };
463     ANeuralNetworksOperandType quant8Tensor2D = {
464             .type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
465             .dimensionCount = 2,
466             .dimensions = twoDimensional,
467             .scale = 0.00408021,
468             .zeroPoint = 100,
469     };
470     ANeuralNetworksOperandType quant16Tensor2D = {
471             .type = ANEURALNETWORKS_TENSOR_QUANT16_SYMM,
472             .dimensionCount = 2,
473             .dimensions = twoDimensional,
474             .scale = 1.0 / 2048,
475             .zeroPoint = 0,
476     };
477 
478     ANeuralNetworksOperandType input = quant8Tensor2D;
479     ANeuralNetworksOperandType input_to_input_weights = quant8Tensor2D;
480     ANeuralNetworksOperandType input_to_forget_weights = quant8Tensor2D;
481     ANeuralNetworksOperandType input_to_cell_weights = quant8Tensor2D;
482     ANeuralNetworksOperandType input_to_output_weights = quant8Tensor2D;
483     ANeuralNetworksOperandType recurrent_to_input_weights = quant8Tensor2D;
484     ANeuralNetworksOperandType recurrent_to_forget_weights = quant8Tensor2D;
485     ANeuralNetworksOperandType recurrent_to_cell_weights = quant8Tensor2D;
486     ANeuralNetworksOperandType recurrent_to_output_weights = quant8Tensor2D;
487     ANeuralNetworksOperandType input_gate_bias = int32Tensor1D;
488     ANeuralNetworksOperandType forget_gate_bias = int32Tensor1D;
489     ANeuralNetworksOperandType cell_gate_bias = int32Tensor1D;
490     ANeuralNetworksOperandType output_gate_bias = int32Tensor1D;
491     ANeuralNetworksOperandType prev_cell_state = quant16Tensor2D;
492     ANeuralNetworksOperandType prev_output = quant8Tensor2D;
493 
494     ANeuralNetworksOperandType cell_state_out = quant16Tensor2D;
495     ANeuralNetworksOperandType output = quant8Tensor2D;
496 
497     OperationTestBase test(
498             ANEURALNETWORKS_QUANTIZED_16BIT_LSTM,
499             {input, input_to_input_weights, input_to_forget_weights, input_to_cell_weights,
500              input_to_output_weights, recurrent_to_input_weights, recurrent_to_forget_weights,
501              recurrent_to_cell_weights, recurrent_to_output_weights, input_gate_bias,
502              forget_gate_bias, cell_gate_bias, output_gate_bias, prev_cell_state, prev_output},
503             {cell_state_out, output});
504     test.testOpsValidations();
505 }
506 
splitTest(int32_t inputOperandType)507 void splitTest(int32_t inputOperandType) {
508     SCOPED_TRACE(inputOperandType);
509     uint32_t inputDimensions[4] = {2, 2, 2, 2};
510     ANeuralNetworksOperandType input0 = getOpType(inputOperandType, 4, inputDimensions);
511     ANeuralNetworksOperandType axis = {
512             .type = ANEURALNETWORKS_INT32,
513             .dimensionCount = 0,
514             .dimensions = nullptr,
515     };
516     ANeuralNetworksOperandType count = {
517             .type = ANEURALNETWORKS_INT32,
518             .dimensionCount = 0,
519             .dimensions = nullptr,
520     };
521     uint32_t outputDimensions[2] = {2, 2};
522     ANeuralNetworksOperandType output0 = getOpType(inputOperandType, 2, outputDimensions);
523     ANeuralNetworksOperandType output1 = getOpType(inputOperandType, 2, outputDimensions);
524     OperationTestBase test(ANEURALNETWORKS_SPLIT, {input0, axis, count}, {output0, output1});
525     test.testOpsValidations();
526 }
527 
TEST(OperationValidationTest,SPLIT)528 TEST(OperationValidationTest, SPLIT) {
529     splitTest(ANEURALNETWORKS_TENSOR_FLOAT16);
530     splitTest(ANEURALNETWORKS_TENSOR_FLOAT32);
531     splitTest(ANEURALNETWORKS_TENSOR_INT32);
532     splitTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
533 }
534 
tileTest(int32_t inputOperandType)535 void tileTest(int32_t inputOperandType) {
536     SCOPED_TRACE(inputOperandType);
537     uint32_t inputDimensions[4] = {2, 2, 2, 2};
538     ANeuralNetworksOperandType input0 = getOpType(inputOperandType, 4, inputDimensions);
539     uint32_t multiplesDimensions[1] = {4};
540     ANeuralNetworksOperandType multiples = {
541             .type = ANEURALNETWORKS_TENSOR_INT32,
542             .dimensionCount = 1,
543             .dimensions = multiplesDimensions,
544     };
545     uint32_t outputDimensions[8] = {2, 2, 2, 2, 2, 2, 2, 2};
546     ANeuralNetworksOperandType output0 = getOpType(inputOperandType, 8, outputDimensions);
547     OperationTestBase test(ANEURALNETWORKS_TILE, {input0, multiples}, {output0});
548     test.testOpsValidations();
549 }
550 
TEST(OperationValidationTest,TILE)551 TEST(OperationValidationTest, TILE) {
552     tileTest(ANEURALNETWORKS_TENSOR_FLOAT16);
553     tileTest(ANEURALNETWORKS_TENSOR_FLOAT32);
554     tileTest(ANEURALNETWORKS_TENSOR_INT32);
555     tileTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
556 }
557 
topkV2Test(int32_t inputOperandType)558 void topkV2Test(int32_t inputOperandType) {
559     SCOPED_TRACE(inputOperandType);
560     uint32_t inputDimensions[4] = {4, 5, 6, 7};
561     ANeuralNetworksOperandType input = getOpType(inputOperandType, 4, inputDimensions);
562     ANeuralNetworksOperandType k = getOpType(ANEURALNETWORKS_INT32);
563     uint32_t outputDimensions[4] = {4, 5, 6, 3};
564     ANeuralNetworksOperandType outputValues = getOpType(inputOperandType, 4, outputDimensions);
565     ANeuralNetworksOperandType outputIndices =
566             getOpType(ANEURALNETWORKS_TENSOR_INT32, 4, outputDimensions);
567     OperationTestBase test(ANEURALNETWORKS_TOPK_V2, {input, k}, {outputValues, outputIndices});
568     test.testOpsValidations();
569 }
570 
TEST(OperationValidationTest,TOPK_V2)571 TEST(OperationValidationTest, TOPK_V2) {
572     topkV2Test(ANEURALNETWORKS_TENSOR_FLOAT16);
573     topkV2Test(ANEURALNETWORKS_TENSOR_FLOAT32);
574     topkV2Test(ANEURALNETWORKS_TENSOR_INT32);
575     topkV2Test(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
576 }
577 
simpleMathOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)578 void simpleMathOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
579     uint32_t inputDimensions[4] = {2, 2, 2, 2};
580     ANeuralNetworksOperandType input1 = getOpType(operandCode, 4, inputDimensions);
581 
582     ANeuralNetworksOperandType input2 = input1;
583     ANeuralNetworksOperandType output = input1;
584     ANeuralNetworksOperandType activation = {.type = ANEURALNETWORKS_INT32,
585                                              .dimensionCount = 0,
586                                              .dimensions = nullptr,
587                                              .scale = 0.0f,
588                                              .zeroPoint = 0};
589 
590     OperationTestBase simpleMathTest(operationCode, {input1, input2, activation}, {output});
591     simpleMathTest.testOpsValidations();
592 }
593 
TEST(OperationValidationTest,ADD_float16)594 TEST(OperationValidationTest, ADD_float16) {
595     simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_FLOAT16);
596 }
597 
TEST(OperationValidationTest,ADD_float32)598 TEST(OperationValidationTest, ADD_float32) {
599     simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_FLOAT32);
600 }
601 
TEST(OperationValidationTest,MUL_float16)602 TEST(OperationValidationTest, MUL_float16) {
603     simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_FLOAT16);
604 }
605 
TEST(OperationValidationTest,MUL_float32)606 TEST(OperationValidationTest, MUL_float32) {
607     simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_FLOAT32);
608 }
609 
TEST(OperationValidationTest,SUB_float16)610 TEST(OperationValidationTest, SUB_float16) {
611     simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_FLOAT16);
612 }
613 
TEST(OperationValidationTest,SUB_float32)614 TEST(OperationValidationTest, SUB_float32) {
615     simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_FLOAT32);
616 }
617 
TEST(OperationValidationTest,SUB_quant8)618 TEST(OperationValidationTest, SUB_quant8) {
619     simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
620 }
621 
TEST(OperationValidationTest,DIV_float16)622 TEST(OperationValidationTest, DIV_float16) {
623     simpleMathOpTest(ANEURALNETWORKS_DIV, ANEURALNETWORKS_TENSOR_FLOAT16);
624 }
625 
TEST(OperationValidationTest,DIV_float32)626 TEST(OperationValidationTest, DIV_float32) {
627     simpleMathOpTest(ANEURALNETWORKS_DIV, ANEURALNETWORKS_TENSOR_FLOAT32);
628 }
629 
TEST(OperationValidationTest,ADD_quant8)630 TEST(OperationValidationTest, ADD_quant8) {
631     simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
632 }
633 
TEST(OperationValidationTest,MUL_quant8)634 TEST(OperationValidationTest, MUL_quant8) {
635     simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
636 }
637 
TEST(OperationValidationTest,MUL_quant8_bad_output_scale)638 TEST(OperationValidationTest, MUL_quant8_bad_output_scale) {
639     uint32_t inputDimensions[4] = {2, 2, 2, 2};
640     ANeuralNetworksOperandType input1 =
641             getOpType(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, 4, inputDimensions);
642     ANeuralNetworksOperandType input2 = input1;
643     ANeuralNetworksOperandType output = input1;
644     input1.scale = 1.0f;
645     input2.scale = 1.0f;
646     output.scale = 0.5f;
647     ANeuralNetworksOperandType activation = {.type = ANEURALNETWORKS_INT32,
648                                              .dimensionCount = 0,
649                                              .dimensions = nullptr,
650                                              .scale = 0.0f,
651                                              .zeroPoint = 0};
652 
653     OperationTestBase mulTest(ANEURALNETWORKS_MUL, {input1, input2, activation}, {output});
654     mulTest.testFailure(ANEURALNETWORKS_BAD_DATA);
655 }
656 
binaryOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)657 void binaryOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
658     uint32_t inputDimensions[] = {2, 2, 2, 2, 2};
659     ANeuralNetworksOperandType input1 = getOpType(operandCode, 5, inputDimensions);
660 
661     ANeuralNetworksOperandType input2 = input1;
662     ANeuralNetworksOperandType output = input1;
663 
664     OperationTestBase test(operationCode, {input1, input2}, {output});
665     test.testOpsValidations();
666 }
667 
TEST(OperationValidationTest,MAXIMUM_float16)668 TEST(OperationValidationTest, MAXIMUM_float16) {
669     binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_FLOAT16);
670 }
671 
TEST(OperationValidationTest,MAXIMUM_float32)672 TEST(OperationValidationTest, MAXIMUM_float32) {
673     binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_FLOAT32);
674 }
675 
TEST(OperationValidationTest,MAXIMUM_int32)676 TEST(OperationValidationTest, MAXIMUM_int32) {
677     binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_INT32);
678 }
679 
TEST(OperationValidationTest,MAXIMUM_quant8)680 TEST(OperationValidationTest, MAXIMUM_quant8) {
681     binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
682 }
683 
TEST(OperationValidationTest,MINIMUM_float16)684 TEST(OperationValidationTest, MINIMUM_float16) {
685     binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_FLOAT16);
686 }
687 
TEST(OperationValidationTest,MINIMUM_float32)688 TEST(OperationValidationTest, MINIMUM_float32) {
689     binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_FLOAT32);
690 }
691 
TEST(OperationValidationTest,MINIMUM_int32)692 TEST(OperationValidationTest, MINIMUM_int32) {
693     binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_INT32);
694 }
695 
TEST(OperationValidationTest,MINIMUM_quant8)696 TEST(OperationValidationTest, MINIMUM_quant8) {
697     binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
698 }
699 
activationOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)700 void activationOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
701     uint32_t inputDimensions[4] = {2, 2, 2, 2};
702     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
703 
704     ANeuralNetworksOperandType output = input;
705     OperationTestBase test(operationCode, {input}, {output});
706     test.testOpsValidations();
707 }
708 
TEST(OperationValidationTest,ABS_float16)709 TEST(OperationValidationTest, ABS_float16) {
710     activationOpTest(ANEURALNETWORKS_ABS, ANEURALNETWORKS_TENSOR_FLOAT16);
711 }
712 
TEST(OperationValidationTest,ABS_float32)713 TEST(OperationValidationTest, ABS_float32) {
714     activationOpTest(ANEURALNETWORKS_ABS, ANEURALNETWORKS_TENSOR_FLOAT32);
715 }
716 
TEST(OperationValidationTest,EXP_float16)717 TEST(OperationValidationTest, EXP_float16) {
718     activationOpTest(ANEURALNETWORKS_EXP, ANEURALNETWORKS_TENSOR_FLOAT16);
719 }
720 
TEST(OperationValidationTest,EXP_float32)721 TEST(OperationValidationTest, EXP_float32) {
722     activationOpTest(ANEURALNETWORKS_EXP, ANEURALNETWORKS_TENSOR_FLOAT32);
723 }
724 
TEST(OperationValidationTest,LOG_float16)725 TEST(OperationValidationTest, LOG_float16) {
726     activationOpTest(ANEURALNETWORKS_LOG, ANEURALNETWORKS_TENSOR_FLOAT16);
727 }
728 
TEST(OperationValidationTest,LOG_float32)729 TEST(OperationValidationTest, LOG_float32) {
730     activationOpTest(ANEURALNETWORKS_LOG, ANEURALNETWORKS_TENSOR_FLOAT32);
731 }
732 
TEST(OperationValidationTest,RSQRT_float16)733 TEST(OperationValidationTest, RSQRT_float16) {
734     activationOpTest(ANEURALNETWORKS_RSQRT, ANEURALNETWORKS_TENSOR_FLOAT16);
735 }
736 
TEST(OperationValidationTest,RSQRT_float32)737 TEST(OperationValidationTest, RSQRT_float32) {
738     activationOpTest(ANEURALNETWORKS_RSQRT, ANEURALNETWORKS_TENSOR_FLOAT32);
739 }
740 
TEST(OperationValidationTest,SIN_float16)741 TEST(OperationValidationTest, SIN_float16) {
742     activationOpTest(ANEURALNETWORKS_SIN, ANEURALNETWORKS_TENSOR_FLOAT16);
743 }
744 
TEST(OperationValidationTest,SIN_float32)745 TEST(OperationValidationTest, SIN_float32) {
746     activationOpTest(ANEURALNETWORKS_SIN, ANEURALNETWORKS_TENSOR_FLOAT32);
747 }
748 
TEST(OperationValidationTest,SQRT_float16)749 TEST(OperationValidationTest, SQRT_float16) {
750     activationOpTest(ANEURALNETWORKS_SQRT, ANEURALNETWORKS_TENSOR_FLOAT16);
751 }
752 
TEST(OperationValidationTest,SQRT_float32)753 TEST(OperationValidationTest, SQRT_float32) {
754     activationOpTest(ANEURALNETWORKS_SQRT, ANEURALNETWORKS_TENSOR_FLOAT32);
755 }
756 
TEST(OperationValidationTest,NEG_float16)757 TEST(OperationValidationTest, NEG_float16) {
758     activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_FLOAT16);
759 }
760 
TEST(OperationValidationTest,NEG_float32)761 TEST(OperationValidationTest, NEG_float32) {
762     activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_FLOAT32);
763 }
764 
TEST(OperationValidationTest,NEG_int32)765 TEST(OperationValidationTest, NEG_int32) {
766     activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_INT32);
767 }
768 
TEST(OperationValidationTest,FLOOR_float16)769 TEST(OperationValidationTest, FLOOR_float16) {
770     activationOpTest(ANEURALNETWORKS_FLOOR, ANEURALNETWORKS_TENSOR_FLOAT16);
771 }
772 
TEST(OperationValidationTest,FLOOR_float32)773 TEST(OperationValidationTest, FLOOR_float32) {
774     activationOpTest(ANEURALNETWORKS_FLOOR, ANEURALNETWORKS_TENSOR_FLOAT32);
775 }
776 
TEST(OperationValidationTest,LOGICAL_NOT_bool)777 TEST(OperationValidationTest, LOGICAL_NOT_bool) {
778     activationOpTest(ANEURALNETWORKS_LOGICAL_NOT, ANEURALNETWORKS_TENSOR_BOOL8);
779 }
780 
TEST(OperationValidationTest,TANH_float16)781 TEST(OperationValidationTest, TANH_float16) {
782     activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_FLOAT16);
783 }
784 
TEST(OperationValidationTest,TANH_float32)785 TEST(OperationValidationTest, TANH_float32) {
786     activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_FLOAT32);
787 }
788 
TEST(OperationValidationTest,TANH_quant8)789 TEST(OperationValidationTest, TANH_quant8) {
790     activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
791 }
792 
TEST(OperationValidationTest,RELU_float16)793 TEST(OperationValidationTest, RELU_float16) {
794     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16);
795 }
796 
TEST(OperationValidationTest,RELU1_float16)797 TEST(OperationValidationTest, RELU1_float16) {
798     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16);
799 }
800 
TEST(OperationValidationTest,RELU6_float16)801 TEST(OperationValidationTest, RELU6_float16) {
802     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16);
803 }
804 
TEST(OperationValidationTest,RELU_float32)805 TEST(OperationValidationTest, RELU_float32) {
806     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32);
807 }
808 
TEST(OperationValidationTest,RELU1_float32)809 TEST(OperationValidationTest, RELU1_float32) {
810     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32);
811 }
812 
TEST(OperationValidationTest,RELU6_float32)813 TEST(OperationValidationTest, RELU6_float32) {
814     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32);
815 }
816 
TEST(OperationValidationTest,LOGISTIC_float16)817 TEST(OperationValidationTest, LOGISTIC_float16) {
818     activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_FLOAT16);
819 }
820 
TEST(OperationValidationTest,LOGISTIC_float32)821 TEST(OperationValidationTest, LOGISTIC_float32) {
822     activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_FLOAT32);
823 }
824 
TEST(OperationValidationTest,RELU_quant8)825 TEST(OperationValidationTest, RELU_quant8) {
826     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
827 }
828 
TEST(OperationValidationTest,RELU1_quant8)829 TEST(OperationValidationTest, RELU1_quant8) {
830     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
831 }
832 
TEST(OperationValidationTest,RELU6_quant8)833 TEST(OperationValidationTest, RELU6_quant8) {
834     activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
835 }
836 
TEST(OperationValidationTest,LOGISTIC_quant8)837 TEST(OperationValidationTest, LOGISTIC_quant8) {
838     activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
839 }
840 
reshapeOpTest(int32_t inputOperandCode)841 void reshapeOpTest(int32_t inputOperandCode) {
842     SCOPED_TRACE(inputOperandCode);
843     uint32_t inputDimensions[3] = {2, 3, 4};
844     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 3, inputDimensions);
845     uint32_t shapeDims[1] = {2};
846     ANeuralNetworksOperandType shape = getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, shapeDims);
847     uint32_t outputDimensions[2] = {4, 6};
848     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 2, outputDimensions);
849     OperationTestBase test(ANEURALNETWORKS_RESHAPE, {input, shape}, {output});
850     test.testOpsValidations();
851 }
852 
TEST(OperationValidationTest,RESHAPE)853 TEST(OperationValidationTest, RESHAPE) {
854     reshapeOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
855     reshapeOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
856     reshapeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
857 }
858 
logSoftmaxOpTest(int32_t inputOperandCode)859 void logSoftmaxOpTest(int32_t inputOperandCode) {
860     uint32_t inputDimensions[3] = {2, 2, 2};
861     ANeuralNetworksOperandType input = {.type = inputOperandCode,
862                                         .dimensionCount = 3,
863                                         .dimensions = inputDimensions,
864                                         .scale = 0.0f,
865                                         .zeroPoint = 0};
866     ANeuralNetworksOperandType beta = {.type = (inputOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32)
867                                                        ? ANEURALNETWORKS_FLOAT32
868                                                        : ANEURALNETWORKS_FLOAT16,
869                                        .dimensionCount = 0,
870                                        .dimensions = nullptr,
871                                        .scale = 0.0f,
872                                        .zeroPoint = 0};
873     ANeuralNetworksOperandType axis = {.type = ANEURALNETWORKS_INT32,
874                                        .dimensionCount = 0,
875                                        .dimensions = nullptr,
876                                        .scale = 0.0f,
877                                        .zeroPoint = 0};
878 
879     ANeuralNetworksOperandType output = {.type = inputOperandCode,
880                                          .dimensionCount = 3,
881                                          .dimensions = inputDimensions,
882                                          .scale = 0.0f,
883                                          .zeroPoint = 0};
884 
885     OperationTestBase test(ANEURALNETWORKS_LOG_SOFTMAX, {input, beta, axis}, {output});
886     test.testOpsValidations();
887 }
888 
TEST(OperationValidationTest,LOG_SOFTMAX_float16)889 TEST(OperationValidationTest, LOG_SOFTMAX_float16) {
890     logSoftmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
891 }
892 
TEST(OperationValidationTest,LOG_SOFTMAX_float32)893 TEST(OperationValidationTest, LOG_SOFTMAX_float32) {
894     logSoftmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
895 }
896 
meanOpTest(int32_t inputOperandCode)897 void meanOpTest(int32_t inputOperandCode) {
898     uint32_t inputDimensions[3] = {2, 2, 2};
899     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 3, inputDimensions);
900     ANeuralNetworksOperandType dims = getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, inputDimensions);
901     ANeuralNetworksOperandType keepDims = getOpType(ANEURALNETWORKS_INT32);
902     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 3, inputDimensions);
903 
904     OperationTestBase test(ANEURALNETWORKS_MEAN, {input, dims, keepDims}, {output});
905     test.testOpsValidations();
906 }
907 
TEST(OperationValidationTest,MEAN_float16)908 TEST(OperationValidationTest, MEAN_float16) {
909     meanOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
910 }
911 
TEST(OperationValidationTest,MEAN_float32)912 TEST(OperationValidationTest, MEAN_float32) {
913     meanOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
914 }
915 
TEST(OperationValidationTest,MEAN_quant8)916 TEST(OperationValidationTest, MEAN_quant8) {
917     meanOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
918 }
919 
padOpTest(int32_t inputOperandCode)920 void padOpTest(int32_t inputOperandCode) {
921     SCOPED_TRACE(inputOperandCode);
922     uint32_t inputDimensions[4] = {2, 2, 2, 2};
923     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inputDimensions);
924     uint32_t padSizeDimensions[1] = {4};
925     ANeuralNetworksOperandType padSize =
926             getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, padSizeDimensions);
927     uint32_t outputDimensions[4] = {4, 3, 4, 3};
928     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 4, outputDimensions);
929     OperationTestBase test(ANEURALNETWORKS_PAD, {input, padSize}, {output});
930     test.testOpsValidations();
931 }
932 
TEST(OperationValidationTest,PAD)933 TEST(OperationValidationTest, PAD) {
934     padOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
935     padOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
936     padOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
937 }
938 
padV2OpTest(int32_t inputOperandCode)939 void padV2OpTest(int32_t inputOperandCode) {
940     SCOPED_TRACE(inputOperandCode);
941     uint32_t inputDimensions[4] = {2, 2, 2, 2};
942     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inputDimensions);
943     uint32_t padSizeDimensions[1] = {4};
944     ANeuralNetworksOperandType padSize =
945             getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, padSizeDimensions);
946     ANeuralNetworksOperandType padValue = getOpType(ANEURALNETWORKS_FLOAT32);
947     if (inputOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16) {
948         padValue = getOpType(ANEURALNETWORKS_FLOAT16);
949     } else if (inputOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
950         padValue = getOpType(ANEURALNETWORKS_INT32);
951     }
952     uint32_t outputDimensions[4] = {4, 3, 4, 3};
953     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 4, outputDimensions);
954     OperationTestBase test(ANEURALNETWORKS_PAD_V2, {input, padSize, padValue}, {output});
955     test.testOpsValidations();
956 }
957 
TEST(OperationValidationTest,PAD_V2)958 TEST(OperationValidationTest, PAD_V2) {
959     padV2OpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
960     padV2OpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
961     padV2OpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
962 }
963 
softmaxOpTest(int32_t operandCode)964 void softmaxOpTest(int32_t operandCode) {
965     uint32_t inputDimensions[4] = {2, 2, 2, 2};
966     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
967 
968     ANeuralNetworksOperandType output = input;
969     ANeuralNetworksOperandType beta = getOpType(ANEURALNETWORKS_FLOAT32);
970     if (operandCode == ANEURALNETWORKS_TENSOR_FLOAT16) {
971         beta = getOpType(ANEURALNETWORKS_FLOAT16);
972     }
973 
974     OperationTestBase softmaxTest(ANEURALNETWORKS_SOFTMAX, {input, beta}, {output});
975     softmaxTest.testOpsValidations();
976 
977     ANeuralNetworksOperandType axis = getOpType(ANEURALNETWORKS_INT32);
978     OperationTestBase softmaxAxisTest(ANEURALNETWORKS_SOFTMAX, {input, beta, axis}, {output});
979     softmaxAxisTest.testOpsValidations();
980 }
981 
TEST(OperationValidationTest,SOFTMAX_float16)982 TEST(OperationValidationTest, SOFTMAX_float16) {
983     softmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
984 }
985 
TEST(OperationValidationTest,SOFTMAX_float32)986 TEST(OperationValidationTest, SOFTMAX_float32) {
987     softmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
988 }
989 
TEST(OperationValidationTest,SOFTMAX_quant8)990 TEST(OperationValidationTest, SOFTMAX_quant8) {
991     softmaxOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
992 }
993 
poolingOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)994 void poolingOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
995     uint32_t inputDimensions[4] = {2, 4, 4, 2};
996     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
997     ANeuralNetworksOperandType output = input;
998 
999     ANeuralNetworksOperandType scalar = {.type = ANEURALNETWORKS_INT32,
1000                                          .dimensionCount = 0,
1001                                          .dimensions = nullptr,
1002                                          .scale = 0.0f,
1003                                          .zeroPoint = 0};
1004     ANeuralNetworksOperandType padLeft = scalar;
1005     ANeuralNetworksOperandType padRight = scalar;
1006     ANeuralNetworksOperandType padTop = scalar;
1007     ANeuralNetworksOperandType padBottom = scalar;
1008     ANeuralNetworksOperandType strideWidth = scalar;
1009     ANeuralNetworksOperandType strideHeight = scalar;
1010     ANeuralNetworksOperandType filterWidth = scalar;
1011     ANeuralNetworksOperandType filterHeight = scalar;
1012     ANeuralNetworksOperandType activation = scalar;
1013 
1014     OperationTestBase explicitPoolingTest(operationCode,
1015                                           {input, padLeft, padRight, padTop, padBottom, strideWidth,
1016                                            strideHeight, filterWidth, filterHeight, activation},
1017                                           {output});
1018     explicitPoolingTest.testOpsValidations();
1019 
1020     ANeuralNetworksOperandType padImplicit = scalar;
1021     OperationTestBase implicitPoolingTest(
1022             operationCode,
1023             {input, padImplicit, strideWidth, strideHeight, filterWidth, filterHeight, activation},
1024             {output});
1025     implicitPoolingTest.testOpsValidations();
1026 
1027     ANeuralNetworksOperandType layout = {.type = ANEURALNETWORKS_BOOL,
1028                                          .dimensionCount = 0,
1029                                          .dimensions = nullptr,
1030                                          .scale = 0.0f,
1031                                          .zeroPoint = 0};
1032 
1033     OperationTestBase explicitNchwPoolingTest(
1034             operationCode,
1035             {input, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight, filterWidth,
1036              filterHeight, activation, layout},
1037             {output});
1038     explicitNchwPoolingTest.testOpsValidations();
1039 
1040     OperationTestBase implicitNchwPoolingTest(operationCode,
1041                                               {input, padImplicit, strideWidth, strideHeight,
1042                                                filterWidth, filterHeight, activation, layout},
1043                                               {output});
1044     implicitNchwPoolingTest.testOpsValidations();
1045 }
1046 
TEST(OperationValidationTest,AVERAGE_POOL_2D_float16)1047 TEST(OperationValidationTest, AVERAGE_POOL_2D_float16) {
1048     poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16);
1049 }
1050 
TEST(OperationValidationTest,AVERAGE_POOL_2D_float32)1051 TEST(OperationValidationTest, AVERAGE_POOL_2D_float32) {
1052     poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32);
1053 }
1054 
TEST(OperationValidationTest,MAX_POOL_2D_float32)1055 TEST(OperationValidationTest, MAX_POOL_2D_float32) {
1056     poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32);
1057 }
1058 
TEST(OperationValidationTest,MAX_POOL_2D_float16)1059 TEST(OperationValidationTest, MAX_POOL_2D_float16) {
1060     poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16);
1061 }
1062 
TEST(OperationValidationTest,L2_POOL_2D_float16)1063 TEST(OperationValidationTest, L2_POOL_2D_float16) {
1064     poolingOpTest(ANEURALNETWORKS_L2_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16);
1065 }
1066 
TEST(OperationValidationTest,L2_POOL_2D_float32)1067 TEST(OperationValidationTest, L2_POOL_2D_float32) {
1068     poolingOpTest(ANEURALNETWORKS_L2_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32);
1069 }
1070 
TEST(OperationValidationTest,AVERAGE_POOL_2D_quant8)1071 TEST(OperationValidationTest, AVERAGE_POOL_2D_quant8) {
1072     poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1073 }
1074 
TEST(OperationValidationTest,MAX_POOL_2D_quant8)1075 TEST(OperationValidationTest, MAX_POOL_2D_quant8) {
1076     poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1077 }
1078 
spaceDepthOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)1079 void spaceDepthOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
1080     uint32_t inputDimensions[4] = {2, 2, 2, 2};
1081     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
1082 
1083     ANeuralNetworksOperandType block_size = {.type = ANEURALNETWORKS_INT32,
1084                                              .dimensionCount = 0,
1085                                              .dimensions = nullptr,
1086                                              .scale = 0.0f,
1087                                              .zeroPoint = 0};
1088     ANeuralNetworksOperandType output = input;
1089 
1090     OperationTestBase spaceDepthTest(operationCode, {input, block_size}, {output});
1091     spaceDepthTest.testOpsValidations();
1092 
1093     ANeuralNetworksOperandType layout = {.type = ANEURALNETWORKS_BOOL,
1094                                          .dimensionCount = 0,
1095                                          .dimensions = nullptr,
1096                                          .scale = 0.0f,
1097                                          .zeroPoint = 0};
1098     OperationTestBase spaceDepthNchwTest(operationCode, {input, block_size, layout}, {output});
1099     spaceDepthNchwTest.testOpsValidations();
1100 }
1101 
TEST(OperationValidationTest,SPACE_TO_DEPTH_float16)1102 TEST(OperationValidationTest, SPACE_TO_DEPTH_float16) {
1103     spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_FLOAT16);
1104 }
1105 
TEST(OperationValidationTest,DEPTH_TO_SPACE_float16)1106 TEST(OperationValidationTest, DEPTH_TO_SPACE_float16) {
1107     spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_FLOAT16);
1108 }
1109 
TEST(OperationValidationTest,SPACE_TO_DEPTH_float32)1110 TEST(OperationValidationTest, SPACE_TO_DEPTH_float32) {
1111     spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_FLOAT32);
1112 }
1113 
TEST(OperationValidationTest,DEPTH_TO_SPACE_float32)1114 TEST(OperationValidationTest, DEPTH_TO_SPACE_float32) {
1115     spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_FLOAT32);
1116 }
1117 
TEST(OperationValidationTest,SPACE_TO_DEPTH_quant8)1118 TEST(OperationValidationTest, SPACE_TO_DEPTH_quant8) {
1119     spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1120 }
1121 
TEST(OperationValidationTest,DEPTH_TO_SPACE_quant8)1122 TEST(OperationValidationTest, DEPTH_TO_SPACE_quant8) {
1123     spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1124 }
1125 
spaceBatchOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)1126 void spaceBatchOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
1127     uint32_t inputDimensions[4] = {2, 2, 2, 2};
1128     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
1129 
1130     uint32_t blockDimensions[1] = {2};
1131     ANeuralNetworksOperandType blockShape = {.type = ANEURALNETWORKS_TENSOR_INT32,
1132                                              .dimensionCount = 1,
1133                                              .dimensions = blockDimensions,
1134                                              .scale = 0.0f,
1135                                              .zeroPoint = 0};
1136     ANeuralNetworksOperandType layout = {.type = ANEURALNETWORKS_BOOL,
1137                                          .dimensionCount = 0,
1138                                          .dimensions = nullptr,
1139                                          .scale = 0.0f,
1140                                          .zeroPoint = 0};
1141 
1142     ANeuralNetworksOperandType padding = blockShape;
1143     ANeuralNetworksOperandType output = input;
1144     if (operationCode == ANEURALNETWORKS_SPACE_TO_BATCH_ND) {
1145         OperationTestBase spaceBatchTest(operationCode, {input, blockShape, padding}, {output});
1146         spaceBatchTest.testOpsValidations();
1147 
1148         OperationTestBase spaceBatchNchwTest(operationCode, {input, blockShape, padding, layout},
1149                                              {output});
1150         spaceBatchNchwTest.testOpsValidations();
1151     } else {
1152         OperationTestBase spaceBatchTest(operationCode, {input, blockShape}, {output});
1153         spaceBatchTest.testOpsValidations();
1154 
1155         OperationTestBase spaceBatchNchwTest(operationCode, {input, blockShape, layout}, {output});
1156         spaceBatchNchwTest.testOpsValidations();
1157     }
1158 }
1159 
TEST(OperationValidationTest,SPACE_TO_BATCH_ND_float16)1160 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_float16) {
1161     spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_FLOAT16);
1162 }
1163 
TEST(OperationValidationTest,BATCH_TO_SPACE_ND_float16)1164 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_float16) {
1165     spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_FLOAT16);
1166 }
1167 
TEST(OperationValidationTest,SPACE_TO_BATCH_ND_float32)1168 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_float32) {
1169     spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_FLOAT32);
1170 }
1171 
TEST(OperationValidationTest,BATCH_TO_SPACE_ND_float32)1172 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_float32) {
1173     spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_FLOAT32);
1174 }
1175 
TEST(OperationValidationTest,SPACE_TO_BATCH_ND_quant8)1176 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_quant8) {
1177     spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1178 }
1179 
TEST(OperationValidationTest,BATCH_TO_SPACE_ND_quant8)1180 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_quant8) {
1181     spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1182 }
1183 
transposeAndSqueezeOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)1184 void transposeAndSqueezeOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
1185     uint32_t inputDimensions[4] = {2, 2, 2, 2};
1186     ANeuralNetworksOperandType input = getOpType(operandCode, 4, inputDimensions);
1187 
1188     uint32_t blockDimensions[1] = {4};
1189     ANeuralNetworksOperandType dims = {.type = ANEURALNETWORKS_TENSOR_INT32,
1190                                        .dimensionCount = 1,
1191                                        .dimensions = blockDimensions,
1192                                        .scale = 0.0f,
1193                                        .zeroPoint = 0};
1194 
1195     ANeuralNetworksOperandType output = input;
1196     OperationTestBase transposeAndSqueezeTest(operationCode, {input, dims}, {output});
1197     transposeAndSqueezeTest.testOpsValidations();
1198 }
1199 
TEST(OperationValidationTest,TRANSPOSE_float16)1200 TEST(OperationValidationTest, TRANSPOSE_float16) {
1201     transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_FLOAT16);
1202 }
1203 
TEST(OperationValidationTest,SQUEEZE_float16)1204 TEST(OperationValidationTest, SQUEEZE_float16) {
1205     transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_FLOAT16);
1206 }
1207 
TEST(OperationValidationTest,TRANSPOSE_float32)1208 TEST(OperationValidationTest, TRANSPOSE_float32) {
1209     transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_FLOAT32);
1210 }
1211 
TEST(OperationValidationTest,SQUEEZE_float32)1212 TEST(OperationValidationTest, SQUEEZE_float32) {
1213     transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_FLOAT32);
1214 }
1215 
TEST(OperationValidationTest,TRANSPOSE_quant8)1216 TEST(OperationValidationTest, TRANSPOSE_quant8) {
1217     transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1218 }
1219 
TEST(OperationValidationTest,SQUEEZE_quant8)1220 TEST(OperationValidationTest, SQUEEZE_quant8) {
1221     transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1222 }
1223 
convOpTest(int32_t inputOperandCode,int32_t filterOperandCode)1224 void convOpTest(int32_t inputOperandCode, int32_t filterOperandCode) {
1225     uint32_t inputDimensions[4] = {2, 4, 4, 2};
1226     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inputDimensions);
1227     ANeuralNetworksOperandType output = input;
1228 
1229     float filterScales[2] = {0.5f, 1.0f};
1230     ANeuralNetworksOperandType filter = getOpType(filterOperandCode, 4, inputDimensions);
1231     ANeuralNetworksSymmPerChannelQuantParams filterChannelQuantParams = {
1232             .channelDim = 0,
1233             .scaleCount = 2,
1234             .scales = filterScales,
1235     };
1236 
1237     uint32_t biasDimensions[1] = {2};
1238     ANeuralNetworksOperandType bias = {.type = inputOperandCode,
1239                                        .dimensionCount = 1,
1240                                        .dimensions = biasDimensions,
1241                                        .scale = 0.0f,
1242                                        .zeroPoint = 0};
1243     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
1244         bias.type = ANEURALNETWORKS_TENSOR_INT32;
1245         bias.scale = 0.25f;
1246     }
1247     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1248         bias.type = ANEURALNETWORKS_TENSOR_INT32;
1249         bias.scale = 0.0f;
1250     }
1251 
1252     ANeuralNetworksOperandType scalar = {.type = ANEURALNETWORKS_INT32,
1253                                          .dimensionCount = 0,
1254                                          .dimensions = nullptr,
1255                                          .scale = 0.0f,
1256                                          .zeroPoint = 0};
1257     ANeuralNetworksOperandType padLeft = scalar;
1258     ANeuralNetworksOperandType padRight = scalar;
1259     ANeuralNetworksOperandType padTop = scalar;
1260     ANeuralNetworksOperandType padBottom = scalar;
1261     ANeuralNetworksOperandType strideWidth = scalar;
1262     ANeuralNetworksOperandType strideHeight = scalar;
1263     ANeuralNetworksOperandType dilationHeightFactor = scalar;
1264     ANeuralNetworksOperandType dilationWidthFactor = scalar;
1265     ANeuralNetworksOperandType activation = scalar;
1266 
1267     OperationTestBase explicitConvTest(ANEURALNETWORKS_CONV_2D,
1268                                        {input, filter, bias, padLeft, padRight, padTop, padBottom,
1269                                         strideWidth, strideHeight, activation},
1270                                        {output});
1271     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1272         explicitConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1273     }
1274     explicitConvTest.testOpsValidations();
1275 
1276     ANeuralNetworksOperandType padImplicit = scalar;
1277     OperationTestBase implicitConvTest(
1278             ANEURALNETWORKS_CONV_2D,
1279             {input, filter, bias, padImplicit, strideWidth, strideHeight, activation}, {output});
1280     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1281         implicitConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1282     }
1283     implicitConvTest.testOpsValidations();
1284 
1285     ANeuralNetworksOperandType layout = {.type = ANEURALNETWORKS_BOOL,
1286                                          .dimensionCount = 0,
1287                                          .dimensions = nullptr,
1288                                          .scale = 0.0f,
1289                                          .zeroPoint = 0};
1290 
1291     OperationTestBase explicitNchwConvTest(
1292             ANEURALNETWORKS_CONV_2D,
1293             {input, filter, bias, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight,
1294              activation, layout},
1295             {output});
1296     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1297         explicitNchwConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1298     }
1299     explicitNchwConvTest.testOpsValidations();
1300 
1301     OperationTestBase implicitNchwConvTest(
1302             ANEURALNETWORKS_CONV_2D,
1303             {input, filter, bias, padImplicit, strideWidth, strideHeight, activation, layout},
1304             {output});
1305     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1306         implicitNchwConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1307     }
1308     implicitNchwConvTest.testOpsValidations();
1309 
1310     OperationTestBase explicitDilateConvTest(
1311             ANEURALNETWORKS_CONV_2D,
1312             {input, filter, bias, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight,
1313              activation, layout, dilationWidthFactor, dilationHeightFactor},
1314             {output});
1315     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1316         explicitDilateConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1317     }
1318     explicitDilateConvTest.testOpsValidations();
1319 
1320     OperationTestBase implicitDilateConvTest(
1321             ANEURALNETWORKS_CONV_2D,
1322             {input, filter, bias, padImplicit, strideWidth, strideHeight, activation, layout,
1323              dilationWidthFactor, dilationHeightFactor},
1324             {output});
1325     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1326         implicitDilateConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1327     }
1328     implicitDilateConvTest.testOpsValidations();
1329 }
1330 
TEST(OperationValidationTest,CONV_2D_float16)1331 TEST(OperationValidationTest, CONV_2D_float16) {
1332     convOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
1333 }
1334 
TEST(OperationValidationTest,CONV_2D_float32)1335 TEST(OperationValidationTest, CONV_2D_float32) {
1336     convOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
1337 }
1338 
TEST(OperationValidationTest,CONV_2D_quant8)1339 TEST(OperationValidationTest, CONV_2D_quant8) {
1340     convOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1341 }
1342 
TEST(OperationValidationTest,CONV_2D_quant8_per_channel)1343 TEST(OperationValidationTest, CONV_2D_quant8_per_channel) {
1344     convOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
1345 }
1346 
depthwiseConvOpTest(int32_t inputOperandCode,int32_t filterOperandCode)1347 void depthwiseConvOpTest(int32_t inputOperandCode, int32_t filterOperandCode) {
1348     uint32_t inputDimensions[4] = {1, 2, 2, 2};
1349     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inputDimensions);
1350     ANeuralNetworksOperandType output = input;
1351 
1352     float filterScales[2] = {0.5f, 1.0f};
1353     ANeuralNetworksOperandType filter = getOpType(filterOperandCode, 4, inputDimensions);
1354     ANeuralNetworksSymmPerChannelQuantParams filterChannelQuantParams = {
1355             .channelDim = 3,
1356             .scaleCount = 2,
1357             .scales = filterScales,
1358     };
1359 
1360     uint32_t biasDimensions[1] = {2};
1361     ANeuralNetworksOperandType bias = {.type = inputOperandCode,
1362                                        .dimensionCount = 1,
1363                                        .dimensions = biasDimensions,
1364                                        .scale = 0.0f,
1365                                        .zeroPoint = 0};
1366     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
1367         bias.type = ANEURALNETWORKS_TENSOR_INT32;
1368         bias.scale = 0.25f;
1369     }
1370     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1371         bias.type = ANEURALNETWORKS_TENSOR_INT32;
1372         bias.scale = 0.0f;
1373     }
1374 
1375     ANeuralNetworksOperandType scalar = {.type = ANEURALNETWORKS_INT32,
1376                                          .dimensionCount = 0,
1377                                          .dimensions = nullptr,
1378                                          .scale = 0.0f,
1379                                          .zeroPoint = 0};
1380     ANeuralNetworksOperandType padLeft = scalar;
1381     ANeuralNetworksOperandType padRight = scalar;
1382     ANeuralNetworksOperandType padTop = scalar;
1383     ANeuralNetworksOperandType padBottom = scalar;
1384     ANeuralNetworksOperandType strideWidth = scalar;
1385     ANeuralNetworksOperandType strideHeight = scalar;
1386     ANeuralNetworksOperandType multiplier = scalar;
1387     ANeuralNetworksOperandType activation = scalar;
1388 
1389     OperationTestBase explicitDepthwiseConvTest(
1390             ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1391             {input, filter, bias, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight,
1392              multiplier, activation},
1393             {output});
1394     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1395         explicitDepthwiseConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1396     }
1397     explicitDepthwiseConvTest.testOpsValidations();
1398 
1399     ANeuralNetworksOperandType padImplicit = scalar;
1400     OperationTestBase implicitDepthwiseConvTest(
1401             ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1402             {input, filter, bias, padImplicit, strideWidth, strideHeight, multiplier, activation},
1403             {output});
1404     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1405         implicitDepthwiseConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
1406     }
1407     implicitDepthwiseConvTest.testOpsValidations();
1408 
1409     ANeuralNetworksOperandType layout = {.type = ANEURALNETWORKS_BOOL,
1410                                          .dimensionCount = 0,
1411                                          .dimensions = nullptr,
1412                                          .scale = 0.0f,
1413                                          .zeroPoint = 0};
1414 
1415     OperationTestBase explicitNchwDepthwiseConvTest(
1416             ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1417             {input, filter, bias, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight,
1418              multiplier, activation, layout},
1419             {output});
1420     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1421         explicitNchwDepthwiseConvTest.setInputSymmPerChannelQuantParams(1,
1422                                                                         filterChannelQuantParams);
1423     }
1424     explicitNchwDepthwiseConvTest.testOpsValidations();
1425 
1426     OperationTestBase implicitNchwDepthwiseConvTest(ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1427                                                     {input, filter, bias, padImplicit, strideWidth,
1428                                                      strideHeight, multiplier, activation, layout},
1429                                                     {output});
1430     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
1431         implicitNchwDepthwiseConvTest.setInputSymmPerChannelQuantParams(1,
1432                                                                         filterChannelQuantParams);
1433     }
1434     implicitNchwDepthwiseConvTest.testOpsValidations();
1435 
1436     ANeuralNetworksOperandType dilationHeightFactor = scalar;
1437     ANeuralNetworksOperandType dilationWidthFactor = scalar;
1438 
1439     OperationTestBase explicitDilationDepthwiseConvTest(
1440             ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1441             {input, filter, bias, padLeft, padRight, padTop, padBottom, strideWidth, strideHeight,
1442              multiplier, activation, layout, dilationWidthFactor, dilationHeightFactor},
1443             {output});
1444     explicitDilationDepthwiseConvTest.testOpsValidations();
1445 
1446     OperationTestBase implicitDilationDepthwiseConvTest(
1447             ANEURALNETWORKS_DEPTHWISE_CONV_2D,
1448             {input, filter, bias, padImplicit, strideWidth, strideHeight, multiplier, activation,
1449              layout, dilationWidthFactor, dilationHeightFactor},
1450             {output});
1451     implicitDilationDepthwiseConvTest.testOpsValidations();
1452 }
1453 
TEST(OperationValidationTest,DEPTHWISE_CONV_2D_float32)1454 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_float32) {
1455     depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
1456 }
1457 
TEST(OperationValidationTest,DEPTHWISE_CONV_2D_float16)1458 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_float16) {
1459     depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
1460 }
1461 
TEST(OperationValidationTest,DEPTHWISE_CONV_2D_quant8)1462 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_quant8) {
1463     depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1464 }
1465 
TEST(OperationValidationTest,DEPTHWISE_CONV_2D_quant8_per_channel)1466 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_quant8_per_channel) {
1467     depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
1468                         ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
1469 }
1470 
fullyConnectedOpTest(int32_t operandCode)1471 void fullyConnectedOpTest(int32_t operandCode) {
1472     uint32_t inputDimensions[2] = {5, 5};
1473     ANeuralNetworksOperandType input = getOpType(operandCode, 2, inputDimensions);
1474 
1475     ANeuralNetworksOperandType weights = input;
1476     ANeuralNetworksOperandType output = input;
1477 
1478     uint32_t biasDimensions[1] = {5};
1479     ANeuralNetworksOperandType bias = {.type = operandCode,
1480                                        .dimensionCount = 1,
1481                                        .dimensions = biasDimensions,
1482                                        .scale = 0.0f,
1483                                        .zeroPoint = 0};
1484     if (operandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
1485         bias.type = ANEURALNETWORKS_TENSOR_INT32;
1486         bias.scale = 0.25f;
1487     }
1488 
1489     ANeuralNetworksOperandType activation = {.type = ANEURALNETWORKS_INT32,
1490                                              .dimensionCount = 0,
1491                                              .dimensions = nullptr,
1492                                              .scale = 0.0f,
1493                                              .zeroPoint = 0};
1494 
1495     OperationTestBase fullyConnectedTest(ANEURALNETWORKS_FULLY_CONNECTED,
1496                                          {input, weights, bias, activation}, {output});
1497     fullyConnectedTest.testOpsValidations();
1498 }
1499 
TEST(OperationValidationTest,FULLY_CONNECTED_float16)1500 TEST(OperationValidationTest, FULLY_CONNECTED_float16) {
1501     fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
1502 }
1503 
TEST(OperationValidationTest,FULLY_CONNECTED_float32)1504 TEST(OperationValidationTest, FULLY_CONNECTED_float32) {
1505     fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
1506 }
1507 
TEST(OperationValidationTest,FULLY_CONNECTED_quant8)1508 TEST(OperationValidationTest, FULLY_CONNECTED_quant8) {
1509     fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1510 }
1511 
concatenationTest(int32_t operandCode)1512 void concatenationTest(int32_t operandCode) {
1513     uint32_t inputDimensions[2] = {5, 5};
1514     ANeuralNetworksOperandType input1 = getOpType(operandCode, 2, inputDimensions);
1515     ANeuralNetworksOperandType input2 = input1;
1516     ANeuralNetworksOperandType output = input1;
1517 
1518     ANeuralNetworksOperandType activation = {.type = ANEURALNETWORKS_INT32,
1519                                              .dimensionCount = 0,
1520                                              .dimensions = nullptr,
1521                                              .scale = 0.0f,
1522                                              .zeroPoint = 0};
1523 
1524     OperationTestBase concat2Test(ANEURALNETWORKS_CONCATENATION, {input1, input2, activation},
1525                                   {output});
1526     concat2Test.testOpsValidations();
1527 
1528     OperationTestBase concat1Test(ANEURALNETWORKS_CONCATENATION, {input1, activation}, {output});
1529     concat1Test.testOpsValidations();
1530 }
1531 
TEST(OperationValidationTest,CONCATENATION_float16)1532 TEST(OperationValidationTest, CONCATENATION_float16) {
1533     concatenationTest(ANEURALNETWORKS_TENSOR_FLOAT16);
1534 }
1535 
TEST(OperationValidationTest,CONCATENATION_float32)1536 TEST(OperationValidationTest, CONCATENATION_float32) {
1537     concatenationTest(ANEURALNETWORKS_TENSOR_FLOAT32);
1538 }
1539 
TEST(OperationValidationTest,CONCATENATION_quant8)1540 TEST(OperationValidationTest, CONCATENATION_quant8) {
1541     concatenationTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1542 }
1543 
resizeBilinearOpTest(int32_t inputOperandCode,int32_t scalarOperandCode)1544 void resizeBilinearOpTest(int32_t inputOperandCode, int32_t scalarOperandCode) {
1545     SCOPED_TRACE(inputOperandCode);
1546     uint32_t inputDimensions[4] = {2, 2, 2, 2};
1547     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inputDimensions);
1548     ANeuralNetworksOperandType height = getOpType(scalarOperandCode);
1549     ANeuralNetworksOperandType width = height;
1550     ANeuralNetworksOperandType output = input;
1551 
1552     OperationTestBase resizeTest(ANEURALNETWORKS_RESIZE_BILINEAR, {input, height, width}, {output});
1553     resizeTest.testOpsValidations();
1554 
1555     ANeuralNetworksOperandType layout = getOpType(ANEURALNETWORKS_BOOL);
1556     OperationTestBase resizeNchwTest(ANEURALNETWORKS_RESIZE_BILINEAR,
1557                                      {input, height, width, layout}, {output});
1558     resizeNchwTest.testOpsValidations();
1559 }
1560 
TEST(OperationValidationTest,RESIZE_BILINEAR)1561 TEST(OperationValidationTest, RESIZE_BILINEAR) {
1562     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_INT32);
1563     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_INT32);
1564     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_INT32);
1565     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_FLOAT16);
1566     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_FLOAT32);
1567     resizeBilinearOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_FLOAT32);
1568 }
1569 
embeddingLookupTest(int32_t operandCode)1570 void embeddingLookupTest(int32_t operandCode) {
1571     uint32_t lookupDimensions[1] = {5};
1572     ANeuralNetworksOperandType lookup = {.type = ANEURALNETWORKS_TENSOR_INT32,
1573                                          .dimensionCount = 1,
1574                                          .dimensions = lookupDimensions,
1575                                          .scale = 0.0f,
1576                                          .zeroPoint = 0};
1577 
1578     uint32_t inputDimensions[2] = {5, 5};
1579     ANeuralNetworksOperandType input = getOpType(operandCode, 2, inputDimensions);
1580     ANeuralNetworksOperandType output = input;
1581 
1582     OperationTestBase embedLookupTest(ANEURALNETWORKS_EMBEDDING_LOOKUP, {lookup, input}, {output});
1583     embedLookupTest.testOpsValidations();
1584 }
1585 
TEST(OperationValidationTest,EMBEDDING_LOOKUP_float32)1586 TEST(OperationValidationTest, EMBEDDING_LOOKUP_float32) {
1587     embeddingLookupTest(ANEURALNETWORKS_TENSOR_FLOAT32);
1588 }
1589 
TEST(OperationValidationTest,EMBEDDING_LOOKUP_int32)1590 TEST(OperationValidationTest, EMBEDDING_LOOKUP_int32) {
1591     embeddingLookupTest(ANEURALNETWORKS_TENSOR_INT32);
1592 }
1593 
TEST(OperationValidationTest,EMBEDDING_LOOKUP_quant8)1594 TEST(OperationValidationTest, EMBEDDING_LOOKUP_quant8) {
1595     embeddingLookupTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1596 }
1597 
hashtableLookupTest(int32_t operandCode)1598 void hashtableLookupTest(int32_t operandCode) {
1599     uint32_t lookupDimensions[1] = {5};
1600     ANeuralNetworksOperandType lookup = {.type = ANEURALNETWORKS_TENSOR_INT32,
1601                                          .dimensionCount = 1,
1602                                          .dimensions = lookupDimensions,
1603                                          .scale = 0.0f,
1604                                          .zeroPoint = 0};
1605     ANeuralNetworksOperandType keys = lookup;
1606 
1607     uint32_t valuesDimensions[2] = {5, 5};
1608     ANeuralNetworksOperandType values = getOpType(operandCode, 2, valuesDimensions);
1609     ANeuralNetworksOperandType output = values;
1610 
1611     ANeuralNetworksOperandType hits = lookup;
1612     hits.type = ANEURALNETWORKS_TENSOR_QUANT8_ASYMM;
1613     hits.scale = 1.0f;
1614 
1615     OperationTestBase hashLookupTest(ANEURALNETWORKS_HASHTABLE_LOOKUP, {lookup, keys, values},
1616                                      {output, hits});
1617     hashLookupTest.testOpsValidations();
1618 }
1619 
TEST(OperationValidationTest,HASHTABLE_LOOKUP_float32)1620 TEST(OperationValidationTest, HASHTABLE_LOOKUP_float32) {
1621     hashtableLookupTest(ANEURALNETWORKS_TENSOR_FLOAT32);
1622 }
1623 
TEST(OperationValidationTest,HASHTABLE_LOOKUP_int32)1624 TEST(OperationValidationTest, HASHTABLE_LOOKUP_int32) {
1625     hashtableLookupTest(ANEURALNETWORKS_TENSOR_INT32);
1626 }
1627 
TEST(OperationValidationTest,HASHTABLE_LOOKUP_quant8)1628 TEST(OperationValidationTest, HASHTABLE_LOOKUP_quant8) {
1629     hashtableLookupTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
1630 }
1631 
lshProjectionTest(int32_t operandCode,int32_t hashAndWeightOperandCode)1632 void lshProjectionTest(int32_t operandCode, int32_t hashAndWeightOperandCode) {
1633     uint32_t inputDimensions[2] = {5, 5};
1634     ANeuralNetworksOperandType hash = getOpType(hashAndWeightOperandCode, 2, inputDimensions);
1635     ANeuralNetworksOperandType input = getOpType(operandCode, 2, inputDimensions);
1636 
1637     uint32_t weightDimensions[1] = {5};
1638     ANeuralNetworksOperandType weight = getOpType(hashAndWeightOperandCode, 1, weightDimensions);
1639 
1640     ANeuralNetworksOperandType type = {.type = ANEURALNETWORKS_INT32,
1641                                        .dimensionCount = 0,
1642                                        .dimensions = nullptr,
1643                                        .scale = 0.0f,
1644                                        .zeroPoint = 0};
1645 
1646     ANeuralNetworksOperandType output = weight;
1647     output.type = ANEURALNETWORKS_TENSOR_INT32;
1648 
1649     OperationTestBase lshProjTest(ANEURALNETWORKS_LSH_PROJECTION, {hash, input, weight, type},
1650                                   {output});
1651     lshProjTest.testOpsValidations();
1652 }
1653 
TEST(OperationValidationTest,LSH_PROJECTION_float16)1654 TEST(OperationValidationTest, LSH_PROJECTION_float16) {
1655     lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT32);
1656     lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
1657 }
1658 
TEST(OperationValidationTest,LSH_PROJECTION_float32)1659 TEST(OperationValidationTest, LSH_PROJECTION_float32) {
1660     lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
1661     lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT16);
1662 }
1663 
TEST(OperationValidationTest,LSH_PROJECTION_quant8)1664 TEST(OperationValidationTest, LSH_PROJECTION_quant8) {
1665     lshProjectionTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_FLOAT32);
1666     lshProjectionTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_FLOAT16);
1667 }
1668 
TEST(OperationValidationTest,LSH_PROJECTION_int32)1669 TEST(OperationValidationTest, LSH_PROJECTION_int32) {
1670     lshProjectionTest(ANEURALNETWORKS_TENSOR_INT32, ANEURALNETWORKS_TENSOR_FLOAT32);
1671     lshProjectionTest(ANEURALNETWORKS_TENSOR_INT32, ANEURALNETWORKS_TENSOR_FLOAT16);
1672 }
1673 
TEST(OperationValidationTest,LSTM_float32)1674 TEST(OperationValidationTest, LSTM_float32) {
1675     uint32_t oneDimensional[1] = {5};
1676     uint32_t twoDimensional[2] = {5, 5};
1677     ANeuralNetworksOperandType floatTensor1D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
1678                                                 .dimensionCount = 1,
1679                                                 .dimensions = oneDimensional,
1680                                                 .scale = 0.0f,
1681                                                 .zeroPoint = 0};
1682     ANeuralNetworksOperandType floatTensor2D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
1683                                                 .dimensionCount = 2,
1684                                                 .dimensions = twoDimensional,
1685                                                 .scale = 0.0f,
1686                                                 .zeroPoint = 0};
1687     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
1688                                             .dimensionCount = 0,
1689                                             .dimensions = nullptr,
1690                                             .scale = 0.0f,
1691                                             .zeroPoint = 0};
1692     ANeuralNetworksOperandType floatScalar = {.type = ANEURALNETWORKS_FLOAT32,
1693                                               .dimensionCount = 0,
1694                                               .dimensions = nullptr,
1695                                               .scale = 0.0f,
1696                                               .zeroPoint = 0};
1697 
1698     ANeuralNetworksOperandType input = floatTensor2D;
1699     ANeuralNetworksOperandType inputToInput = floatTensor2D;
1700     ANeuralNetworksOperandType inputToForget = floatTensor2D;
1701     ANeuralNetworksOperandType inputToCell = floatTensor2D;
1702     ANeuralNetworksOperandType inputToOutput = floatTensor2D;
1703     ANeuralNetworksOperandType recurrentToInput = floatTensor2D;
1704     ANeuralNetworksOperandType recurrentToForget = floatTensor2D;
1705     ANeuralNetworksOperandType recurrentToCell = floatTensor2D;
1706     ANeuralNetworksOperandType recurrentToOutput = floatTensor2D;
1707     ANeuralNetworksOperandType cellToInput = floatTensor1D;
1708     ANeuralNetworksOperandType cellToForget = floatTensor1D;
1709     ANeuralNetworksOperandType cellToOutput = floatTensor1D;
1710     ANeuralNetworksOperandType inputGateBias = floatTensor1D;
1711     ANeuralNetworksOperandType forgetGateBias = floatTensor1D;
1712     ANeuralNetworksOperandType cellBias = floatTensor1D;
1713     ANeuralNetworksOperandType outputGateBias = floatTensor1D;
1714     ANeuralNetworksOperandType projWeights = floatTensor2D;
1715     ANeuralNetworksOperandType projBias = floatTensor1D;
1716     ANeuralNetworksOperandType outputStateIn = floatTensor2D;
1717     ANeuralNetworksOperandType cellStateIn = floatTensor2D;
1718     ANeuralNetworksOperandType activation = intScalar;
1719     ANeuralNetworksOperandType clipCellState = floatScalar;
1720     ANeuralNetworksOperandType clipProjLayer = floatScalar;
1721 
1722     ANeuralNetworksOperandType scratch = floatTensor2D;
1723     ANeuralNetworksOperandType outputStateOut = floatTensor2D;
1724     ANeuralNetworksOperandType cellStateOut = floatTensor2D;
1725     ANeuralNetworksOperandType output = floatTensor2D;
1726 
1727     OperationTestBase lstmTest(ANEURALNETWORKS_LSTM,
1728                                {input,
1729                                 inputToInput,
1730                                 inputToForget,
1731                                 inputToCell,
1732                                 inputToOutput,
1733                                 recurrentToInput,
1734                                 recurrentToForget,
1735                                 recurrentToCell,
1736                                 recurrentToOutput,
1737                                 cellToInput,
1738                                 cellToForget,
1739                                 cellToOutput,
1740                                 inputGateBias,
1741                                 forgetGateBias,
1742                                 cellBias,
1743                                 outputGateBias,
1744                                 projWeights,
1745                                 projBias,
1746                                 outputStateIn,
1747                                 cellStateIn,
1748                                 activation,
1749                                 clipCellState,
1750                                 clipProjLayer},
1751                                {scratch, outputStateOut, cellStateOut, output});
1752     lstmTest.testOpsValidations();
1753 }
1754 
lstmTestV1_2(int32_t operandCode)1755 void lstmTestV1_2(int32_t operandCode) {
1756     SCOPED_TRACE(operandCode);
1757     uint32_t oneDimensional[1] = {5};
1758     uint32_t twoDimensional[2] = {5, 5};
1759     ANeuralNetworksOperandType floatTensor1D = {.type = operandCode,
1760                                                 .dimensionCount = 1,
1761                                                 .dimensions = oneDimensional,
1762                                                 .scale = 0.0f,
1763                                                 .zeroPoint = 0};
1764     ANeuralNetworksOperandType floatTensor2D = {.type = operandCode,
1765                                                 .dimensionCount = 2,
1766                                                 .dimensions = twoDimensional,
1767                                                 .scale = 0.0f,
1768                                                 .zeroPoint = 0};
1769     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
1770                                             .dimensionCount = 0,
1771                                             .dimensions = nullptr,
1772                                             .scale = 0.0f,
1773                                             .zeroPoint = 0};
1774     ANeuralNetworksOperandType floatScalar = {
1775             .type = (operandCode == ANEURALNETWORKS_TENSOR_FLOAT32) ? ANEURALNETWORKS_FLOAT32
1776                                                                     : ANEURALNETWORKS_FLOAT16,
1777             .dimensionCount = 0,
1778             .dimensions = nullptr,
1779             .scale = 0.0f,
1780             .zeroPoint = 0};
1781 
1782     ANeuralNetworksOperandType input = floatTensor2D;
1783     ANeuralNetworksOperandType inputToInput = floatTensor2D;
1784     ANeuralNetworksOperandType inputToForget = floatTensor2D;
1785     ANeuralNetworksOperandType inputToCell = floatTensor2D;
1786     ANeuralNetworksOperandType inputToOutput = floatTensor2D;
1787     ANeuralNetworksOperandType recurrentToInput = floatTensor2D;
1788     ANeuralNetworksOperandType recurrentToForget = floatTensor2D;
1789     ANeuralNetworksOperandType recurrentToCell = floatTensor2D;
1790     ANeuralNetworksOperandType recurrentToOutput = floatTensor2D;
1791     ANeuralNetworksOperandType cellToInput = floatTensor1D;
1792     ANeuralNetworksOperandType cellToForget = floatTensor1D;
1793     ANeuralNetworksOperandType cellToOutput = floatTensor1D;
1794     ANeuralNetworksOperandType inputGateBias = floatTensor1D;
1795     ANeuralNetworksOperandType forgetGateBias = floatTensor1D;
1796     ANeuralNetworksOperandType cellBias = floatTensor1D;
1797     ANeuralNetworksOperandType outputGateBias = floatTensor1D;
1798     ANeuralNetworksOperandType projWeights = floatTensor2D;
1799     ANeuralNetworksOperandType projBias = floatTensor1D;
1800     ANeuralNetworksOperandType outputStateIn = floatTensor2D;
1801     ANeuralNetworksOperandType cellStateIn = floatTensor2D;
1802     ANeuralNetworksOperandType activation = intScalar;
1803     ANeuralNetworksOperandType clipCellState = floatScalar;
1804     ANeuralNetworksOperandType clipProjLayer = floatScalar;
1805     ANeuralNetworksOperandType inputLayerNormWeights = floatTensor1D;
1806     ANeuralNetworksOperandType forgetLayerNormWeights = floatTensor1D;
1807     ANeuralNetworksOperandType cellLayerNormWeights = floatTensor1D;
1808     ANeuralNetworksOperandType outputLayerNormWeights = floatTensor1D;
1809 
1810     ANeuralNetworksOperandType scratch = floatTensor2D;
1811     ANeuralNetworksOperandType outputStateOut = floatTensor2D;
1812     ANeuralNetworksOperandType cellStateOut = floatTensor2D;
1813     ANeuralNetworksOperandType output = floatTensor2D;
1814 
1815     OperationTestBase lstmTest(ANEURALNETWORKS_LSTM,
1816                                {input,
1817                                 inputToInput,
1818                                 inputToForget,
1819                                 inputToCell,
1820                                 inputToOutput,
1821                                 recurrentToInput,
1822                                 recurrentToForget,
1823                                 recurrentToCell,
1824                                 recurrentToOutput,
1825                                 cellToInput,
1826                                 cellToForget,
1827                                 cellToOutput,
1828                                 inputGateBias,
1829                                 forgetGateBias,
1830                                 cellBias,
1831                                 outputGateBias,
1832                                 projWeights,
1833                                 projBias,
1834                                 outputStateIn,
1835                                 cellStateIn,
1836                                 activation,
1837                                 clipCellState,
1838                                 clipProjLayer,
1839                                 inputLayerNormWeights,
1840                                 forgetLayerNormWeights,
1841                                 cellLayerNormWeights,
1842                                 outputLayerNormWeights},
1843                                {scratch, outputStateOut, cellStateOut, output});
1844     lstmTest.testOpsValidations();
1845 }
1846 
TEST(OperationValidationTest,LSTM_V1_2)1847 TEST(OperationValidationTest, LSTM_V1_2) {
1848     lstmTestV1_2(ANEURALNETWORKS_TENSOR_FLOAT32);
1849     lstmTestV1_2(ANEURALNETWORKS_TENSOR_FLOAT16);
1850 }
1851 
lstmBidirectionalSequence(int32_t operandCode)1852 void lstmBidirectionalSequence(int32_t operandCode) {
1853     uint32_t oneDimensional[1] = {5};
1854     uint32_t twoDimensional[2] = {5, 5};
1855     uint32_t threeDimensional[3] = {5, 5, 5};
1856     ANeuralNetworksOperandType floatTensor1D = {
1857             .type = operandCode,
1858             .dimensionCount = 1,
1859             .dimensions = oneDimensional,
1860             .scale = 0.0f,
1861             .zeroPoint = 0,
1862     };
1863     ANeuralNetworksOperandType floatTensor2D = {
1864             .type = operandCode,
1865             .dimensionCount = 2,
1866             .dimensions = twoDimensional,
1867             .scale = 0.0f,
1868             .zeroPoint = 0,
1869     };
1870     ANeuralNetworksOperandType floatTensor3D = {
1871             .type = operandCode,
1872             .dimensionCount = 3,
1873             .dimensions = threeDimensional,
1874             .scale = 0.0f,
1875             .zeroPoint = 0,
1876     };
1877     ANeuralNetworksOperandType intScalar = {
1878             .type = ANEURALNETWORKS_INT32,
1879             .dimensionCount = 0,
1880             .dimensions = nullptr,
1881             .scale = 0.0f,
1882             .zeroPoint = 0,
1883     };
1884     ANeuralNetworksOperandType floatScalar = {
1885             .type = operandCode == ANEURALNETWORKS_TENSOR_FLOAT32 ? ANEURALNETWORKS_FLOAT32
1886                                                                   : ANEURALNETWORKS_FLOAT16,
1887             .dimensionCount = 0,
1888             .dimensions = nullptr,
1889             .scale = 0.0f,
1890             .zeroPoint = 0,
1891     };
1892     ANeuralNetworksOperandType boolScalar = {.type = ANEURALNETWORKS_BOOL,
1893                                              .dimensionCount = 0,
1894                                              .dimensions = nullptr,
1895                                              .scale = 0.0f,
1896                                              .zeroPoint = 0};
1897 
1898     ANeuralNetworksOperandType input = floatTensor3D;
1899     ANeuralNetworksOperandType inputToInputFw = floatTensor2D;
1900     ANeuralNetworksOperandType inputToForgetFw = floatTensor2D;
1901     ANeuralNetworksOperandType inputToCellFw = floatTensor2D;
1902     ANeuralNetworksOperandType inputToOutputFw = floatTensor2D;
1903     ANeuralNetworksOperandType recurrentToInputFw = floatTensor2D;
1904     ANeuralNetworksOperandType recurrentToForgetFw = floatTensor2D;
1905     ANeuralNetworksOperandType recurrentToCellFw = floatTensor2D;
1906     ANeuralNetworksOperandType recurrentToOutputFw = floatTensor2D;
1907     ANeuralNetworksOperandType cellToInputFw = floatTensor1D;
1908     ANeuralNetworksOperandType cellToForgetFw = floatTensor1D;
1909     ANeuralNetworksOperandType cellToOutputFw = floatTensor1D;
1910     ANeuralNetworksOperandType inputGateBiasFw = floatTensor1D;
1911     ANeuralNetworksOperandType forgetGateBiasFw = floatTensor1D;
1912     ANeuralNetworksOperandType cellBiasFw = floatTensor1D;
1913     ANeuralNetworksOperandType outputGateBiasFw = floatTensor1D;
1914     ANeuralNetworksOperandType projWeightsFw = floatTensor2D;
1915     ANeuralNetworksOperandType projBiasFw = floatTensor1D;
1916     ANeuralNetworksOperandType outputStateInFw = floatTensor2D;
1917     ANeuralNetworksOperandType cellStateInFw = floatTensor2D;
1918     ANeuralNetworksOperandType inputToInputBw = floatTensor2D;
1919     ANeuralNetworksOperandType inputToForgetBw = floatTensor2D;
1920     ANeuralNetworksOperandType inputToCellBw = floatTensor2D;
1921     ANeuralNetworksOperandType inputToOutputBw = floatTensor2D;
1922     ANeuralNetworksOperandType recurrentToInputBw = floatTensor2D;
1923     ANeuralNetworksOperandType recurrentToForgetBw = floatTensor2D;
1924     ANeuralNetworksOperandType recurrentToCellBw = floatTensor2D;
1925     ANeuralNetworksOperandType recurrentToOutputBw = floatTensor2D;
1926     ANeuralNetworksOperandType cellToInputBw = floatTensor1D;
1927     ANeuralNetworksOperandType cellToForgetBw = floatTensor1D;
1928     ANeuralNetworksOperandType cellToOutputBw = floatTensor1D;
1929     ANeuralNetworksOperandType inputGateBiasBw = floatTensor1D;
1930     ANeuralNetworksOperandType forgetGateBiasBw = floatTensor1D;
1931     ANeuralNetworksOperandType cellBiasBw = floatTensor1D;
1932     ANeuralNetworksOperandType outputGateBiasBw = floatTensor1D;
1933     ANeuralNetworksOperandType projWeightsBw = floatTensor2D;
1934     ANeuralNetworksOperandType projBiasBw = floatTensor1D;
1935     ANeuralNetworksOperandType outputStateInBw = floatTensor2D;
1936     ANeuralNetworksOperandType cellStateInBw = floatTensor2D;
1937     ANeuralNetworksOperandType auxInput = floatTensor3D;
1938     ANeuralNetworksOperandType auxInputToInputFw = floatTensor2D;
1939     ANeuralNetworksOperandType auxInputToForgetFw = floatTensor2D;
1940     ANeuralNetworksOperandType auxInputToCellFw = floatTensor2D;
1941     ANeuralNetworksOperandType auxInputToOutputFw = floatTensor2D;
1942     ANeuralNetworksOperandType auxInputToInputBw = floatTensor2D;
1943     ANeuralNetworksOperandType auxInputToForgetBw = floatTensor2D;
1944     ANeuralNetworksOperandType auxInputToCellBw = floatTensor2D;
1945     ANeuralNetworksOperandType auxInputToOutputBw = floatTensor2D;
1946     ANeuralNetworksOperandType activation = intScalar;
1947     ANeuralNetworksOperandType clipCellState = floatScalar;
1948     ANeuralNetworksOperandType clipProjLayer = floatScalar;
1949     ANeuralNetworksOperandType mergeOutputs = boolScalar;
1950     ANeuralNetworksOperandType timeMajor = boolScalar;
1951     ANeuralNetworksOperandType inputLayerNormWeightsFw = floatTensor1D;
1952     ANeuralNetworksOperandType forgetLayerNormWeightsFw = floatTensor1D;
1953     ANeuralNetworksOperandType cellLayerNormWeightsFw = floatTensor1D;
1954     ANeuralNetworksOperandType outputLayerNormWeightsFw = floatTensor1D;
1955     ANeuralNetworksOperandType inputLayerNormWeightsBw = floatTensor1D;
1956     ANeuralNetworksOperandType forgetLayerNormWeightsBw = floatTensor1D;
1957     ANeuralNetworksOperandType cellLayerNormWeightsBw = floatTensor1D;
1958     ANeuralNetworksOperandType outputLayerNormWeightsBw = floatTensor1D;
1959 
1960     ANeuralNetworksOperandType outputFw = floatTensor2D;
1961     ANeuralNetworksOperandType outputBw = floatTensor2D;
1962 
1963     OperationTestBase lstmTest(ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM,
1964                                {
1965                                        input,
1966                                        inputToInputFw,
1967                                        inputToForgetFw,
1968                                        inputToCellFw,
1969                                        inputToOutputFw,
1970                                        recurrentToInputFw,
1971                                        recurrentToForgetFw,
1972                                        recurrentToCellFw,
1973                                        recurrentToOutputFw,
1974                                        cellToInputFw,
1975                                        cellToForgetFw,
1976                                        cellToOutputFw,
1977                                        inputGateBiasFw,
1978                                        forgetGateBiasFw,
1979                                        cellBiasFw,
1980                                        outputGateBiasFw,
1981                                        projWeightsFw,
1982                                        projBiasFw,
1983                                        outputStateInFw,
1984                                        cellStateInFw,
1985                                        inputToInputBw,
1986                                        inputToForgetBw,
1987                                        inputToCellBw,
1988                                        inputToOutputBw,
1989                                        recurrentToInputBw,
1990                                        recurrentToForgetBw,
1991                                        recurrentToCellBw,
1992                                        recurrentToOutputBw,
1993                                        cellToInputBw,
1994                                        cellToForgetBw,
1995                                        cellToOutputBw,
1996                                        inputGateBiasBw,
1997                                        forgetGateBiasBw,
1998                                        cellBiasBw,
1999                                        outputGateBiasBw,
2000                                        projWeightsBw,
2001                                        projBiasBw,
2002                                        outputStateInBw,
2003                                        cellStateInBw,
2004                                        auxInput,
2005                                        auxInputToInputFw,
2006                                        auxInputToForgetFw,
2007                                        auxInputToCellFw,
2008                                        auxInputToOutputFw,
2009                                        auxInputToInputBw,
2010                                        auxInputToForgetBw,
2011                                        auxInputToCellBw,
2012                                        auxInputToOutputBw,
2013                                        activation,
2014                                        clipCellState,
2015                                        clipProjLayer,
2016                                        mergeOutputs,
2017                                        timeMajor,
2018                                        inputLayerNormWeightsFw,
2019                                        forgetLayerNormWeightsFw,
2020                                        cellLayerNormWeightsFw,
2021                                        outputLayerNormWeightsFw,
2022                                        inputLayerNormWeightsBw,
2023                                        forgetLayerNormWeightsBw,
2024                                        cellLayerNormWeightsBw,
2025                                        outputLayerNormWeightsBw,
2026                                },
2027                                {
2028                                        outputFw,
2029                                        outputBw,
2030                                });
2031 
2032     lstmTest.testOpsValidations();
2033 }
2034 
TEST(OperationValidationTest,LSTM_BIDIRECTIONAL_SEQUENCE)2035 TEST(OperationValidationTest, LSTM_BIDIRECTIONAL_SEQUENCE) {
2036     lstmBidirectionalSequence(ANEURALNETWORKS_TENSOR_FLOAT32);
2037     lstmBidirectionalSequence(ANEURALNETWORKS_TENSOR_FLOAT16);
2038 }
2039 
randomMultinomialOpTest(int32_t operandCode)2040 void randomMultinomialOpTest(int32_t operandCode) {
2041     uint32_t inputDims[2] = {5, 5};
2042     ANeuralNetworksOperandType input = {.type = operandCode,
2043                                         .dimensionCount = 2,
2044                                         .dimensions = inputDims,
2045                                         .scale = 0.0f,
2046                                         .zeroPoint = 0};
2047     ANeuralNetworksOperandType sample_count = {.type = ANEURALNETWORKS_INT32,
2048                                                .dimensionCount = 0,
2049                                                .dimensions = nullptr,
2050                                                .scale = 0.0f,
2051                                                .zeroPoint = 0};
2052     uint32_t seedDims[1] = {2};
2053     ANeuralNetworksOperandType seed = {.type = ANEURALNETWORKS_TENSOR_INT32,
2054                                        .dimensionCount = 1,
2055                                        .dimensions = seedDims,
2056                                        .scale = 0.0f,
2057                                        .zeroPoint = 0};
2058     uint32_t outputDims[2] = {5, 7};
2059     ANeuralNetworksOperandType output = {.type = ANEURALNETWORKS_TENSOR_INT32,
2060                                          .dimensionCount = 2,
2061                                          .dimensions = outputDims,
2062                                          .scale = 0.0f,
2063                                          .zeroPoint = 0};
2064 
2065     OperationTestBase multinomialTest(ANEURALNETWORKS_RANDOM_MULTINOMIAL,
2066                                       {input, sample_count, seed}, {output});
2067     multinomialTest.testOpsValidations();
2068 }
2069 
TEST(OperationValidationTest,RANDOM_MULTINOMIAL_float16)2070 TEST(OperationValidationTest, RANDOM_MULTINOMIAL_float16) {
2071     randomMultinomialOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2072 }
2073 
TEST(OperationValidationTest,RANDOM_MULTINOMIAL_float32)2074 TEST(OperationValidationTest, RANDOM_MULTINOMIAL_float32) {
2075     randomMultinomialOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2076 }
2077 
TEST(OperationValidationTest,RNN_float16)2078 TEST(OperationValidationTest, RNN_float16) {
2079     uint32_t oneDimensional[1] = {5};
2080     uint32_t twoDimensional[2] = {5, 5};
2081     ANeuralNetworksOperandType floatTensor1D = {.type = ANEURALNETWORKS_TENSOR_FLOAT16,
2082                                                 .dimensionCount = 1,
2083                                                 .dimensions = oneDimensional,
2084                                                 .scale = 0.0f,
2085                                                 .zeroPoint = 0};
2086     ANeuralNetworksOperandType floatTensor2D = {.type = ANEURALNETWORKS_TENSOR_FLOAT16,
2087                                                 .dimensionCount = 2,
2088                                                 .dimensions = twoDimensional,
2089                                                 .scale = 0.0f,
2090                                                 .zeroPoint = 0};
2091     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
2092                                             .dimensionCount = 0,
2093                                             .dimensions = nullptr,
2094                                             .scale = 0.0f,
2095                                             .zeroPoint = 0};
2096 
2097     ANeuralNetworksOperandType input = floatTensor2D;
2098     ANeuralNetworksOperandType weights = floatTensor2D;
2099     ANeuralNetworksOperandType recurrentWeights = floatTensor2D;
2100     ANeuralNetworksOperandType bias = floatTensor1D;
2101     ANeuralNetworksOperandType hiddenStateIn = floatTensor2D;
2102     ANeuralNetworksOperandType activation = intScalar;
2103 
2104     ANeuralNetworksOperandType hiddenStateOut = floatTensor2D;
2105     ANeuralNetworksOperandType output = floatTensor2D;
2106 
2107     OperationTestBase rnnTest(ANEURALNETWORKS_RNN,
2108                               {input, weights, recurrentWeights, bias, hiddenStateIn, activation},
2109                               {hiddenStateOut, output});
2110     rnnTest.testOpsValidations();
2111 }
2112 
TEST(OperationValidationTest,RNN_float32)2113 TEST(OperationValidationTest, RNN_float32) {
2114     uint32_t oneDimensional[1] = {5};
2115     uint32_t twoDimensional[2] = {5, 5};
2116     ANeuralNetworksOperandType floatTensor1D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
2117                                                 .dimensionCount = 1,
2118                                                 .dimensions = oneDimensional,
2119                                                 .scale = 0.0f,
2120                                                 .zeroPoint = 0};
2121     ANeuralNetworksOperandType floatTensor2D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
2122                                                 .dimensionCount = 2,
2123                                                 .dimensions = twoDimensional,
2124                                                 .scale = 0.0f,
2125                                                 .zeroPoint = 0};
2126     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
2127                                             .dimensionCount = 0,
2128                                             .dimensions = nullptr,
2129                                             .scale = 0.0f,
2130                                             .zeroPoint = 0};
2131 
2132     ANeuralNetworksOperandType input = floatTensor2D;
2133     ANeuralNetworksOperandType weights = floatTensor2D;
2134     ANeuralNetworksOperandType recurrentWeights = floatTensor2D;
2135     ANeuralNetworksOperandType bias = floatTensor1D;
2136     ANeuralNetworksOperandType hiddenStateIn = floatTensor2D;
2137     ANeuralNetworksOperandType activation = intScalar;
2138 
2139     ANeuralNetworksOperandType hiddenStateOut = floatTensor2D;
2140     ANeuralNetworksOperandType output = floatTensor2D;
2141 
2142     OperationTestBase rnnTest(ANEURALNETWORKS_RNN,
2143                               {input, weights, recurrentWeights, bias, hiddenStateIn, activation},
2144                               {hiddenStateOut, output});
2145     rnnTest.testOpsValidations();
2146 }
2147 
TEST(OperationValidationTest,SVDF_float32)2148 TEST(OperationValidationTest, SVDF_float32) {
2149     uint32_t oneDimensional[1] = {5};
2150     uint32_t twoDimensional[2] = {5, 5};
2151     ANeuralNetworksOperandType floatTensor1D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
2152                                                 .dimensionCount = 1,
2153                                                 .dimensions = oneDimensional,
2154                                                 .scale = 0.0f,
2155                                                 .zeroPoint = 0};
2156     ANeuralNetworksOperandType floatTensor2D = {.type = ANEURALNETWORKS_TENSOR_FLOAT32,
2157                                                 .dimensionCount = 2,
2158                                                 .dimensions = twoDimensional,
2159                                                 .scale = 0.0f,
2160                                                 .zeroPoint = 0};
2161     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
2162                                             .dimensionCount = 0,
2163                                             .dimensions = nullptr,
2164                                             .scale = 0.0f,
2165                                             .zeroPoint = 0};
2166 
2167     ANeuralNetworksOperandType input = floatTensor2D;
2168     ANeuralNetworksOperandType weightsFeature = floatTensor2D;
2169     ANeuralNetworksOperandType weightsTime = floatTensor2D;
2170     ANeuralNetworksOperandType bias = floatTensor1D;
2171     ANeuralNetworksOperandType stateIn = floatTensor2D;
2172     ANeuralNetworksOperandType rank = intScalar;
2173     ANeuralNetworksOperandType activation = intScalar;
2174 
2175     ANeuralNetworksOperandType stateOut = floatTensor2D;
2176     ANeuralNetworksOperandType output = floatTensor2D;
2177 
2178     OperationTestBase svdfTest(
2179             ANEURALNETWORKS_SVDF,
2180             {input, weightsFeature, weightsTime, bias, stateIn, rank, activation},
2181             {stateOut, output});
2182     svdfTest.testOpsValidations();
2183 }
2184 
TEST(OperationValidationTest,SVDF_float16)2185 TEST(OperationValidationTest, SVDF_float16) {
2186     uint32_t oneDimensional[1] = {5};
2187     uint32_t twoDimensional[2] = {5, 5};
2188     ANeuralNetworksOperandType floatTensor1D = {.type = ANEURALNETWORKS_TENSOR_FLOAT16,
2189                                                 .dimensionCount = 1,
2190                                                 .dimensions = oneDimensional,
2191                                                 .scale = 0.0f,
2192                                                 .zeroPoint = 0};
2193     ANeuralNetworksOperandType floatTensor2D = {.type = ANEURALNETWORKS_TENSOR_FLOAT16,
2194                                                 .dimensionCount = 2,
2195                                                 .dimensions = twoDimensional,
2196                                                 .scale = 0.0f,
2197                                                 .zeroPoint = 0};
2198     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
2199                                             .dimensionCount = 0,
2200                                             .dimensions = nullptr,
2201                                             .scale = 0.0f,
2202                                             .zeroPoint = 0};
2203 
2204     ANeuralNetworksOperandType input = floatTensor2D;
2205     ANeuralNetworksOperandType weightsFeature = floatTensor2D;
2206     ANeuralNetworksOperandType weightsTime = floatTensor2D;
2207     ANeuralNetworksOperandType bias = floatTensor1D;
2208     ANeuralNetworksOperandType stateIn = floatTensor2D;
2209     ANeuralNetworksOperandType rank = intScalar;
2210     ANeuralNetworksOperandType activation = intScalar;
2211 
2212     ANeuralNetworksOperandType stateOut = floatTensor2D;
2213     ANeuralNetworksOperandType output = floatTensor2D;
2214 
2215     OperationTestBase svdfTest(
2216             ANEURALNETWORKS_SVDF,
2217             {input, weightsFeature, weightsTime, bias, stateIn, rank, activation},
2218             {stateOut, output});
2219     svdfTest.testOpsValidations();
2220 }
2221 
stridedSliceOpTest(int32_t operandCode)2222 void stridedSliceOpTest(int32_t operandCode) {
2223     uint32_t inputDimensions[2] = {5, 5};
2224     ANeuralNetworksOperandType input = getOpType(operandCode, 2, inputDimensions);
2225     ANeuralNetworksOperandType output = input;
2226 
2227     uint32_t beginsDimensions[1] = {2};
2228     ANeuralNetworksOperandType begins = {.type = ANEURALNETWORKS_TENSOR_INT32,
2229                                          .dimensionCount = 1,
2230                                          .dimensions = beginsDimensions,
2231                                          .scale = 0.0f,
2232                                          .zeroPoint = 0};
2233 
2234     ANeuralNetworksOperandType ends = begins;
2235     ANeuralNetworksOperandType strides = begins;
2236 
2237     ANeuralNetworksOperandType beginMask = {.type = ANEURALNETWORKS_INT32,
2238                                             .dimensionCount = 0,
2239                                             .dimensions = nullptr,
2240                                             .scale = 0.0f,
2241                                             .zeroPoint = 0};
2242     ANeuralNetworksOperandType endMask = beginMask;
2243     ANeuralNetworksOperandType shrinkAxisMask = beginMask;
2244 
2245     OperationTestBase stridedSliceTest(
2246             ANEURALNETWORKS_STRIDED_SLICE,
2247             {input, begins, ends, strides, beginMask, endMask, shrinkAxisMask}, {output});
2248     stridedSliceTest.testOpsValidations();
2249 }
2250 
TEST(OperationValidationTest,STRIDED_SLICE_float32)2251 TEST(OperationValidationTest, STRIDED_SLICE_float32) {
2252     stridedSliceOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2253 }
2254 
TEST(OperationValidationTest,STRIDED_SLICE_float16)2255 TEST(OperationValidationTest, STRIDED_SLICE_float16) {
2256     stridedSliceOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2257 }
2258 
TEST(OperationValidationTest,STRIDED_SLICE_quant8)2259 TEST(OperationValidationTest, STRIDED_SLICE_quant8) {
2260     stridedSliceOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2261 }
2262 
roiAlignOpTest(int32_t inputOperandCode,int32_t roiOperandCode,int32_t scalarOperandCode)2263 void roiAlignOpTest(int32_t inputOperandCode, int32_t roiOperandCode, int32_t scalarOperandCode) {
2264     uint32_t inDim[] = {1, 4, 4, 1}, roiDim[] = {4, 4}, batchSplitDim[] = {1};
2265     uint32_t outDim[] = {4, 2, 2, 1};
2266     OperationTestBase roiAlignTest(
2267             ANEURALNETWORKS_ROI_ALIGN,
2268             {getOpType(inputOperandCode, 4, inDim), getOpType(roiOperandCode, 2, roiDim),
2269              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, batchSplitDim),
2270              getOpType(ANEURALNETWORKS_INT32), getOpType(ANEURALNETWORKS_INT32),
2271              getOpType(scalarOperandCode), getOpType(scalarOperandCode),
2272              getOpType(ANEURALNETWORKS_INT32), getOpType(ANEURALNETWORKS_INT32),
2273              getOpType(ANEURALNETWORKS_BOOL)},
2274             {getOpType(inputOperandCode, 4, outDim)});
2275     roiAlignTest.testOpsValidations();
2276 }
2277 
TEST(OperationValidationTest,ROI_ALIGN_float16)2278 TEST(OperationValidationTest, ROI_ALIGN_float16) {
2279     roiAlignOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
2280                    ANEURALNETWORKS_FLOAT16);
2281 }
2282 
TEST(OperationValidationTest,ROI_ALIGN_float32)2283 TEST(OperationValidationTest, ROI_ALIGN_float32) {
2284     roiAlignOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
2285                    ANEURALNETWORKS_FLOAT32);
2286 }
2287 
TEST(OperationValidationTest,ROI_ALIGN_quant8)2288 TEST(OperationValidationTest, ROI_ALIGN_quant8) {
2289     roiAlignOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM,
2290                    ANEURALNETWORKS_FLOAT32);
2291 }
2292 
roiPoolingOpTest(int32_t inputOperandCode,int32_t roiOperandCode,int32_t scalarOperandCode)2293 void roiPoolingOpTest(int32_t inputOperandCode, int32_t roiOperandCode, int32_t scalarOperandCode) {
2294     uint32_t inDim[] = {1, 4, 4, 1}, roiDim[] = {4, 4}, batchSplitDim[] = {1};
2295     uint32_t outDim[] = {4, 2, 2, 1};
2296     OperationTestBase roiPoolingTest(
2297             ANEURALNETWORKS_ROI_POOLING,
2298             {getOpType(inputOperandCode, 4, inDim), getOpType(roiOperandCode, 2, roiDim),
2299              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, batchSplitDim),
2300              getOpType(ANEURALNETWORKS_INT32), getOpType(ANEURALNETWORKS_INT32),
2301              getOpType(scalarOperandCode), getOpType(scalarOperandCode),
2302              getOpType(ANEURALNETWORKS_BOOL)},
2303             {getOpType(inputOperandCode, 4, outDim)});
2304     roiPoolingTest.testOpsValidations();
2305 }
2306 
TEST(OperationValidationTest,ROI_POOLING_float16)2307 TEST(OperationValidationTest, ROI_POOLING_float16) {
2308     roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
2309                      ANEURALNETWORKS_FLOAT16);
2310 }
2311 
TEST(OperationValidationTest,ROI_POOLING_float32)2312 TEST(OperationValidationTest, ROI_POOLING_float32) {
2313     roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
2314                      ANEURALNETWORKS_FLOAT32);
2315 }
2316 
TEST(OperationValidationTest,ROI_POOLING_quant8)2317 TEST(OperationValidationTest, ROI_POOLING_quant8) {
2318     roiPoolingOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM,
2319                      ANEURALNETWORKS_FLOAT32);
2320 }
2321 
heatmapMaxKeypointOpTest(int32_t heatmapOperandCode,int32_t roiOperandCode)2322 void heatmapMaxKeypointOpTest(int32_t heatmapOperandCode, int32_t roiOperandCode) {
2323     uint32_t heatmapDim[] = {6, 4, 4, 1}, boxDim[] = {6, 4}, outScoreDim[] = {6, 1},
2324              outKeypointDim[] = {6, 1, 2};
2325     OperationTestBase heatmapMaxKeypointTest(
2326             ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT,
2327             {getOpType(heatmapOperandCode, 4, heatmapDim), getOpType(roiOperandCode, 2, boxDim),
2328              getOpType(ANEURALNETWORKS_BOOL)},
2329             {getOpType(heatmapOperandCode, 2, outScoreDim),
2330              getOpType(roiOperandCode, 3, outKeypointDim)});
2331     heatmapMaxKeypointTest.testOpsValidations();
2332 }
2333 
TEST(OperationValidationTest,HEATMAP_MAX_KEYPOINT_float16)2334 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_float16) {
2335     heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
2336 }
2337 
TEST(OperationValidationTest,HEATMAP_MAX_KEYPOINT_float32)2338 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_float32) {
2339     heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
2340 }
2341 
TEST(OperationValidationTest,HEATMAP_MAX_KEYPOINT_quant)2342 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_quant) {
2343     heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
2344                              ANEURALNETWORKS_TENSOR_QUANT16_ASYMM);
2345 }
2346 
instanceNormalizationOpTest(int32_t inputOperandType)2347 void instanceNormalizationOpTest(int32_t inputOperandType) {
2348     SCOPED_TRACE(inputOperandType);
2349     uint32_t inputDims[4] = {4, 4, 4, 4};
2350     ANeuralNetworksOperandType input = getOpType(inputOperandType, 4, inputDims);
2351     ANeuralNetworksOperandType floatScalar = getOpType(ANEURALNETWORKS_FLOAT32);
2352     if (inputOperandType == ANEURALNETWORKS_TENSOR_FLOAT16) {
2353         floatScalar = getOpType(ANEURALNETWORKS_FLOAT16);
2354     }
2355     ANeuralNetworksOperandType gamma = floatScalar;
2356     ANeuralNetworksOperandType beta = floatScalar;
2357     ANeuralNetworksOperandType epsilon = floatScalar;
2358     ANeuralNetworksOperandType isNCHW = getOpType(ANEURALNETWORKS_BOOL);
2359     ANeuralNetworksOperandType output = input;
2360 
2361     OperationTestBase test(ANEURALNETWORKS_INSTANCE_NORMALIZATION,
2362                            {input, gamma, beta, epsilon, isNCHW}, {output});
2363     test.testOpsValidations();
2364 }
2365 
TEST(OperationValidationTest,INSTANCE_NORMALIZATION)2366 TEST(OperationValidationTest, INSTANCE_NORMALIZATION) {
2367     instanceNormalizationOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2368     instanceNormalizationOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2369 }
2370 
groupedConvOpTest(int32_t inputOperandCode,int32_t filterOperandCode)2371 void groupedConvOpTest(int32_t inputOperandCode, int32_t filterOperandCode) {
2372     uint32_t inDim[] = {1, 3, 3, 2}, filterDim[] = {2, 2, 2, 1}, biasDim[] = {2};
2373     uint32_t outDim[] = {1, 2, 2, 2};
2374     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inDim);
2375 
2376     float filterScales[2] = {0.5f, 1.0f};
2377     ANeuralNetworksOperandType filter = getOpType(filterOperandCode, 4, filterDim);
2378 
2379     ANeuralNetworksSymmPerChannelQuantParams filterChannelQuantParams = {
2380             .channelDim = 0,
2381             .scaleCount = 2,
2382             .scales = filterScales,
2383     };
2384 
2385     ANeuralNetworksOperandType bias = getOpType(inputOperandCode, 1, biasDim);
2386     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
2387         bias.type = ANEURALNETWORKS_TENSOR_INT32;
2388         bias.scale = 0.25f;
2389     }
2390     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2391         bias.type = ANEURALNETWORKS_TENSOR_INT32;
2392         bias.scale = 0.0f;
2393     }
2394 
2395     ANeuralNetworksOperandType scalar = getOpType(ANEURALNETWORKS_INT32);
2396     ANeuralNetworksOperandType layout = getOpType(ANEURALNETWORKS_BOOL);
2397 
2398     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 4, outDim);
2399 
2400     OperationTestBase explicitGroupedConvTest(ANEURALNETWORKS_GROUPED_CONV_2D,
2401                                               {input, filter, bias, scalar, scalar, scalar, scalar,
2402                                                scalar, scalar, scalar, scalar, layout},
2403                                               {output});
2404     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2405         explicitGroupedConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
2406     }
2407     explicitGroupedConvTest.testOpsValidations();
2408 
2409     OperationTestBase implicitGroupedConvTest(
2410             ANEURALNETWORKS_GROUPED_CONV_2D,
2411             {input, filter, bias, scalar, scalar, scalar, scalar, scalar, layout}, {output});
2412     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2413         implicitGroupedConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
2414     }
2415     implicitGroupedConvTest.testOpsValidations();
2416 }
2417 
TEST(OperationValidationTest,GROUPED_CONV_2D_float16)2418 TEST(OperationValidationTest, GROUPED_CONV_2D_float16) {
2419     groupedConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
2420 }
2421 
TEST(OperationValidationTest,GROUPED_CONV_2D_float32)2422 TEST(OperationValidationTest, GROUPED_CONV_2D_float32) {
2423     groupedConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
2424 }
2425 
TEST(OperationValidationTest,GROUPED_CONV_2D_quant8)2426 TEST(OperationValidationTest, GROUPED_CONV_2D_quant8) {
2427     groupedConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2428 }
2429 
TEST(OperationValidationTest,GROUPED_CONV_2D_quant8_per_channel)2430 TEST(OperationValidationTest, GROUPED_CONV_2D_quant8_per_channel) {
2431     groupedConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
2432                       ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
2433 }
2434 
transposeConvOpTest(int32_t inputOperandCode,int32_t filterOperandCode)2435 void transposeConvOpTest(int32_t inputOperandCode, int32_t filterOperandCode) {
2436     uint32_t inDim[] = {1, 2, 2, 2}, filterDim[] = {2, 3, 3, 1}, biasDim[] = {2};
2437     uint32_t outDim[] = {1, 5, 5, 2}, outShapeDim[] = {4};
2438     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 4, inDim);
2439     ANeuralNetworksOperandType filter = getOpType(filterOperandCode, 4, filterDim);
2440 
2441     float filterScales[2] = {0.5f, 1.0f};
2442     ANeuralNetworksSymmPerChannelQuantParams filterChannelQuantParams = {
2443             .channelDim = 0,
2444             .scaleCount = 2,
2445             .scales = filterScales,
2446     };
2447 
2448     ANeuralNetworksOperandType bias = getOpType(inputOperandCode, 1, biasDim);
2449     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM) {
2450         bias.type = ANEURALNETWORKS_TENSOR_INT32;
2451         bias.scale = 0.25f;
2452     }
2453     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2454         bias.type = ANEURALNETWORKS_TENSOR_INT32;
2455         bias.scale = 0.0f;
2456     }
2457 
2458     ANeuralNetworksOperandType scalar = getOpType(ANEURALNETWORKS_INT32);
2459     ANeuralNetworksOperandType layout = getOpType(ANEURALNETWORKS_BOOL);
2460     ANeuralNetworksOperandType output = getOpType(inputOperandCode, 4, outDim);
2461 
2462     OperationTestBase explicitTransposeConvTest(
2463             ANEURALNETWORKS_TRANSPOSE_CONV_2D,
2464             {input, filter, bias, scalar, scalar, scalar, scalar, scalar, scalar, scalar, layout},
2465             {output});
2466     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2467         explicitTransposeConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
2468     }
2469     explicitTransposeConvTest.testOpsValidations();
2470 
2471     OperationTestBase implicitTransposeConvTest(
2472             ANEURALNETWORKS_TRANSPOSE_CONV_2D,
2473             {input, filter, bias, getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outShapeDim), scalar,
2474              scalar, scalar, scalar, layout},
2475             {output});
2476     if (filterOperandCode == ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL) {
2477         implicitTransposeConvTest.setInputSymmPerChannelQuantParams(1, filterChannelQuantParams);
2478     }
2479     implicitTransposeConvTest.testOpsValidations();
2480 }
2481 
TEST(OperationValidationTest,TRANSPOSE_CONV_2D_float16)2482 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_float16) {
2483     transposeConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
2484 }
2485 
TEST(OperationValidationTest,TRANSPOSE_CONV_2D_float32)2486 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_float32) {
2487     transposeConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
2488 }
2489 
TEST(OperationValidationTest,TRANSPOSE_CONV_2D_quant8)2490 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_quant8) {
2491     transposeConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2492 }
2493 
TEST(OperationValidationTest,TRANSPOSE_CONV_2D_quant8_per_channel)2494 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_quant8_per_channel) {
2495     transposeConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
2496                         ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL);
2497 }
2498 
channelShuffleOpTest(int32_t operandCode)2499 void channelShuffleOpTest(int32_t operandCode) {
2500     uint32_t inoutDim[] = {2, 2, 3, 12};
2501     OperationTestBase channelShuffleTest(
2502             ANEURALNETWORKS_CHANNEL_SHUFFLE,
2503             {getOpType(operandCode, 2, inoutDim), getOpType(ANEURALNETWORKS_INT32),
2504              getOpType(ANEURALNETWORKS_INT32)},
2505             {getOpType(operandCode, 2, inoutDim)});
2506     channelShuffleTest.testOpsValidations();
2507 }
2508 
TEST(OperationValidationTest,CHANNEL_SHUFFLE_float16)2509 TEST(OperationValidationTest, CHANNEL_SHUFFLE_float16) {
2510     channelShuffleOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2511 }
2512 
TEST(OperationValidationTest,CHANNEL_SHUFFLE_float32)2513 TEST(OperationValidationTest, CHANNEL_SHUFFLE_float32) {
2514     channelShuffleOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2515 }
2516 
TEST(OperationValidationTest,CHANNEL_SHUFFLE_quant8)2517 TEST(OperationValidationTest, CHANNEL_SHUFFLE_quant8) {
2518     channelShuffleOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2519 }
2520 
detectionPostprocessingOpTest(int32_t inputOperandCode)2521 void detectionPostprocessingOpTest(int32_t inputOperandCode) {
2522     SCOPED_TRACE(inputOperandCode);
2523     const int numBatches = 2;
2524     const int numAnchors = 10;
2525     const int numClasses = 5;
2526     const int lengthBoxEncoding = 4;
2527 
2528     uint32_t inputDims[3] = {numBatches, numAnchors, numClasses};
2529     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 3, inputDims);
2530     uint32_t deltasDims[3] = {numBatches, numAnchors, lengthBoxEncoding};
2531     ANeuralNetworksOperandType deltas = getOpType(inputOperandCode, 3, deltasDims);
2532     uint32_t anchorsDims[2] = {numAnchors, 4};
2533     ANeuralNetworksOperandType anchors = getOpType(inputOperandCode, 2, anchorsDims);
2534     ANeuralNetworksOperandType scaleScalar = getOpType(ANEURALNETWORKS_FLOAT32);
2535     if (inputOperandCode == ANEURALNETWORKS_TENSOR_FLOAT16) {
2536         scaleScalar = getOpType(ANEURALNETWORKS_FLOAT16);
2537     }
2538     ANeuralNetworksOperandType isRegularNMS = getOpType(ANEURALNETWORKS_BOOL);
2539     ANeuralNetworksOperandType maxNumDetections = getOpType(ANEURALNETWORKS_INT32);
2540     ANeuralNetworksOperandType numOfClassesPerDetection = maxNumDetections;
2541     ANeuralNetworksOperandType numOfDetections = numOfClassesPerDetection;
2542     ANeuralNetworksOperandType scoreThreshold = scaleScalar;
2543     ANeuralNetworksOperandType iouThreshold = scaleScalar;
2544     ANeuralNetworksOperandType includeBackground = getOpType(ANEURALNETWORKS_BOOL);
2545     // Outputs
2546     const int maxNumDetectionsValue = 5;
2547     uint32_t outputScoreDims[2] = {numBatches, maxNumDetectionsValue};
2548     ANeuralNetworksOperandType outputScore = getOpType(inputOperandCode, 2, outputScoreDims);
2549     uint32_t boundingBoxesDims[3] = {numBatches, maxNumDetectionsValue, 4};
2550     ANeuralNetworksOperandType boundingBoxes = getOpType(inputOperandCode, 3, boundingBoxesDims);
2551     ANeuralNetworksOperandType classLabel =
2552             getOpType(ANEURALNETWORKS_TENSOR_INT32, 2, outputScoreDims);
2553     uint32_t numValidDims[1] = {numBatches};
2554     ANeuralNetworksOperandType numValid = getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, numValidDims);
2555 
2556     OperationTestBase test(ANEURALNETWORKS_DETECTION_POSTPROCESSING,
2557                            {input, deltas, anchors, scaleScalar, scaleScalar, scaleScalar,
2558                             scaleScalar, isRegularNMS, maxNumDetections, numOfClassesPerDetection,
2559                             numOfDetections, scoreThreshold, iouThreshold, includeBackground},
2560                            {outputScore, boundingBoxes, classLabel, numValid});
2561     test.testOpsValidations();
2562 }
2563 
TEST(OperationValidationTest,DETECTION_POSTPROCESSING)2564 TEST(OperationValidationTest, DETECTION_POSTPROCESSING) {
2565     detectionPostprocessingOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2566     detectionPostprocessingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2567 }
2568 
preluOpTest(int32_t operandCode)2569 void preluOpTest(int32_t operandCode) {
2570     uint32_t inoutDim[] = {1, 2, 2, 3}, alphaDim[] = {1, 1, 3};
2571     OperationTestBase preluTest(
2572             ANEURALNETWORKS_PRELU,
2573             {getOpType(operandCode, 4, inoutDim), getOpType(operandCode, 3, alphaDim)},
2574             {getOpType(operandCode, 4, inoutDim)});
2575     preluTest.testOpsValidations();
2576 }
2577 
TEST(OperationValidationTest,PRELU_float16)2578 TEST(OperationValidationTest, PRELU_float16) {
2579     preluOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2580 }
2581 
TEST(OperationValidationTest,PRELU_float32)2582 TEST(OperationValidationTest, PRELU_float32) {
2583     preluOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2584 }
2585 
TEST(OperationValidationTest,PRELU_quant8)2586 TEST(OperationValidationTest, PRELU_quant8) {
2587     preluOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2588 }
2589 
normalizationOpTest(ANeuralNetworksOperationType operationCode,int32_t operandCode)2590 void normalizationOpTest(ANeuralNetworksOperationType operationCode, int32_t operandCode) {
2591     uint32_t inputDim[] = {2, 2, 2, 2};
2592     OperationTestBase normalizationTest(operationCode, {getOpType(operandCode, 4, inputDim)},
2593                                         {getOpType(operandCode, 4, inputDim)});
2594     normalizationTest.testOpsValidations();
2595 
2596     OperationTestBase normalizationAxisTest(
2597             operationCode, {getOpType(operandCode, 4, inputDim), getOpType(ANEURALNETWORKS_INT32)},
2598             {getOpType(operandCode, 4, inputDim)});
2599     normalizationAxisTest.testOpsValidations();
2600 }
2601 
TEST(OperationValidationTest,L2_NORMALIZATION_float16)2602 TEST(OperationValidationTest, L2_NORMALIZATION_float16) {
2603     normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_FLOAT16);
2604 }
2605 
TEST(OperationValidationTest,L2_NORMALIZATION_float32)2606 TEST(OperationValidationTest, L2_NORMALIZATION_float32) {
2607     normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_FLOAT32);
2608 }
2609 
TEST(OperationValidationTest,L2_NORMALIZATION_quant8)2610 TEST(OperationValidationTest, L2_NORMALIZATION_quant8) {
2611     normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2612 }
2613 
localResponseNormOpTest(int32_t operandCode)2614 void localResponseNormOpTest(int32_t operandCode) {
2615     int32_t floatScalarType = (operandCode == ANEURALNETWORKS_TENSOR_FLOAT32)
2616                                       ? ANEURALNETWORKS_FLOAT32
2617                                       : ANEURALNETWORKS_FLOAT16;
2618     uint32_t inputDim[] = {2, 2, 2, 6};
2619     OperationTestBase lrnTest(
2620             ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION,
2621             {getOpType(operandCode, 4, inputDim), getOpType(ANEURALNETWORKS_INT32),
2622              getOpType(floatScalarType), getOpType(floatScalarType), getOpType(floatScalarType)},
2623             {getOpType(operandCode, 4, inputDim)});
2624     lrnTest.testOpsValidations();
2625 
2626     OperationTestBase lrnAxisTest(
2627             ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION,
2628             {getOpType(operandCode, 4, inputDim), getOpType(ANEURALNETWORKS_INT32),
2629              getOpType(floatScalarType), getOpType(floatScalarType), getOpType(floatScalarType),
2630              getOpType(ANEURALNETWORKS_INT32)},
2631             {getOpType(operandCode, 4, inputDim)});
2632     lrnAxisTest.testOpsValidations();
2633 }
2634 
TEST(OperationValidationTest,LOCAL_RESPONSE_NORMALIZATION_float16)2635 TEST(OperationValidationTest, LOCAL_RESPONSE_NORMALIZATION_float16) {
2636     localResponseNormOpTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2637 }
2638 
TEST(OperationValidationTest,LOCAL_RESPONSE_NORMALIZATION_float32)2639 TEST(OperationValidationTest, LOCAL_RESPONSE_NORMALIZATION_float32) {
2640     localResponseNormOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2641 }
2642 
axisAlignedBBoxTransformOpTest(int32_t roiOperandCode,int32_t deltaOperandCode)2643 void axisAlignedBBoxTransformOpTest(int32_t roiOperandCode, int32_t deltaOperandCode) {
2644     uint32_t roiDim[] = {5, 4}, deltaDim[] = {5, 8}, bsDim[] = {5}, imageDim[] = {5, 2};
2645     uint32_t outDim[] = {5, 8};
2646     OperationTestBase axisAlignedBBoxTransformTest(
2647             ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM,
2648             {getOpType(roiOperandCode, 2, roiDim), getOpType(deltaOperandCode, 2, deltaDim),
2649              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, bsDim),
2650              getOpType(roiOperandCode, 2, imageDim)},
2651             {getOpType(roiOperandCode, 2, outDim)});
2652     axisAlignedBBoxTransformTest.testOpsValidations();
2653 }
2654 
TEST(OperationValidationTest,AXIS_ALIGNED_BBOX_TRANSFORM_float16)2655 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_float16) {
2656     axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
2657 }
2658 
TEST(OperationValidationTest,AXIS_ALIGNED_BBOX_TRANSFORM_float32)2659 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_float32) {
2660     axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
2661 }
2662 
TEST(OperationValidationTest,AXIS_ALIGNED_BBOX_TRANSFORM_quant)2663 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_quant) {
2664     axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_QUANT16_ASYMM,
2665                                    ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2666 }
2667 
sliceTest(int32_t operandCode)2668 void sliceTest(int32_t operandCode) {
2669     uint32_t inputDim[] = {3, 3, 3};
2670     uint32_t startDim[] = {3};
2671     uint32_t sizeDim[] = {3};
2672     uint32_t outputDim[] = {1, 2, 3};
2673 
2674     OperationTestBase sliceTest(ANEURALNETWORKS_SLICE,
2675                                 {getOpType(operandCode, 3, inputDim),
2676                                  getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, startDim),
2677                                  getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, sizeDim)},
2678                                 {getOpType(operandCode, 3, outputDim)});
2679     sliceTest.testOpsValidations();
2680 }
2681 
TEST(OperationValidationTest,SLICE_float32)2682 TEST(OperationValidationTest, SLICE_float32) {
2683     sliceTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2684 }
TEST(OperationValidationTest,SLICE_int32)2685 TEST(OperationValidationTest, SLICE_int32) {
2686     sliceTest(ANEURALNETWORKS_TENSOR_INT32);
2687 }
TEST(OperationValidationTest,SLICE_uint8)2688 TEST(OperationValidationTest, SLICE_uint8) {
2689     sliceTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2690 }
TEST(OperationValidationTest,SLICE_float16)2691 TEST(OperationValidationTest, SLICE_float16) {
2692     sliceTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2693 }
2694 
logicalTest(ANeuralNetworksOperationType operationCode)2695 void logicalTest(ANeuralNetworksOperationType operationCode) {
2696     uint32_t inputDimensions[4] = {2, 2, 2, 2};
2697     ANeuralNetworksOperandType input1 = {.type = ANEURALNETWORKS_TENSOR_BOOL8,
2698                                          .dimensionCount = 4,
2699                                          .dimensions = inputDimensions,
2700                                          .scale = 0.0f,
2701                                          .zeroPoint = 0};
2702     ANeuralNetworksOperandType input2 = input1;
2703     ANeuralNetworksOperandType output = input1;
2704 
2705     OperationTestBase test(operationCode, {input1, input2}, {output});
2706     test.testOpsValidations();
2707 }
2708 
TEST(OperationValidationTest,LOGICAL_AND)2709 TEST(OperationValidationTest, LOGICAL_AND) {
2710     logicalTest(ANEURALNETWORKS_LOGICAL_AND);
2711 }
2712 
TEST(OperationValidationTest,LOGICAL_OR)2713 TEST(OperationValidationTest, LOGICAL_OR) {
2714     logicalTest(ANEURALNETWORKS_LOGICAL_OR);
2715 }
2716 
comparisonTest(ANeuralNetworksOperationType operationCode,int32_t inputOperandType)2717 void comparisonTest(ANeuralNetworksOperationType operationCode, int32_t inputOperandType) {
2718     uint32_t inputDimensions[4] = {2, 2, 2, 2};
2719     ANeuralNetworksOperandType input1 = getOpType(inputOperandType, 4, inputDimensions);
2720     ANeuralNetworksOperandType input2 = input1;
2721     ANeuralNetworksOperandType output = {.type = ANEURALNETWORKS_TENSOR_BOOL8,
2722                                          .dimensionCount = 4,
2723                                          .dimensions = inputDimensions,
2724                                          .scale = 0.0f,
2725                                          .zeroPoint = 0};
2726     OperationTestBase test(operationCode, {input1, input2}, {output});
2727     test.testOpsValidations();
2728 }
2729 
TEST(OperationValidationTest,LESS)2730 TEST(OperationValidationTest, LESS) {
2731     comparisonTest(ANEURALNETWORKS_LESS, ANEURALNETWORKS_TENSOR_BOOL8);
2732     comparisonTest(ANEURALNETWORKS_LESS, ANEURALNETWORKS_TENSOR_FLOAT16);
2733     comparisonTest(ANEURALNETWORKS_LESS, ANEURALNETWORKS_TENSOR_FLOAT32);
2734     comparisonTest(ANEURALNETWORKS_LESS, ANEURALNETWORKS_TENSOR_INT32);
2735     comparisonTest(ANEURALNETWORKS_LESS, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2736 }
2737 
TEST(OperationValidationTest,LESS_EQUAL)2738 TEST(OperationValidationTest, LESS_EQUAL) {
2739     comparisonTest(ANEURALNETWORKS_LESS_EQUAL, ANEURALNETWORKS_TENSOR_BOOL8);
2740     comparisonTest(ANEURALNETWORKS_LESS_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT16);
2741     comparisonTest(ANEURALNETWORKS_LESS_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT32);
2742     comparisonTest(ANEURALNETWORKS_LESS_EQUAL, ANEURALNETWORKS_TENSOR_INT32);
2743     comparisonTest(ANEURALNETWORKS_LESS_EQUAL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2744 }
2745 
TEST(OperationValidationTest,EQUAL)2746 TEST(OperationValidationTest, EQUAL) {
2747     comparisonTest(ANEURALNETWORKS_EQUAL, ANEURALNETWORKS_TENSOR_BOOL8);
2748     comparisonTest(ANEURALNETWORKS_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT16);
2749     comparisonTest(ANEURALNETWORKS_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT32);
2750     comparisonTest(ANEURALNETWORKS_EQUAL, ANEURALNETWORKS_TENSOR_INT32);
2751     comparisonTest(ANEURALNETWORKS_EQUAL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2752 }
2753 
TEST(OperationValidationTest,NOT_EQUAL)2754 TEST(OperationValidationTest, NOT_EQUAL) {
2755     comparisonTest(ANEURALNETWORKS_NOT_EQUAL, ANEURALNETWORKS_TENSOR_BOOL8);
2756     comparisonTest(ANEURALNETWORKS_NOT_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT16);
2757     comparisonTest(ANEURALNETWORKS_NOT_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT32);
2758     comparisonTest(ANEURALNETWORKS_NOT_EQUAL, ANEURALNETWORKS_TENSOR_INT32);
2759     comparisonTest(ANEURALNETWORKS_NOT_EQUAL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2760 }
2761 
TEST(OperationValidationTest,GREATER)2762 TEST(OperationValidationTest, GREATER) {
2763     comparisonTest(ANEURALNETWORKS_GREATER, ANEURALNETWORKS_TENSOR_BOOL8);
2764     comparisonTest(ANEURALNETWORKS_GREATER, ANEURALNETWORKS_TENSOR_FLOAT16);
2765     comparisonTest(ANEURALNETWORKS_GREATER, ANEURALNETWORKS_TENSOR_FLOAT32);
2766     comparisonTest(ANEURALNETWORKS_GREATER, ANEURALNETWORKS_TENSOR_INT32);
2767     comparisonTest(ANEURALNETWORKS_GREATER, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2768 }
2769 
TEST(OperationValidationTest,GREATER_EQUAL)2770 TEST(OperationValidationTest, GREATER_EQUAL) {
2771     comparisonTest(ANEURALNETWORKS_GREATER_EQUAL, ANEURALNETWORKS_TENSOR_BOOL8);
2772     comparisonTest(ANEURALNETWORKS_GREATER_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT16);
2773     comparisonTest(ANEURALNETWORKS_GREATER_EQUAL, ANEURALNETWORKS_TENSOR_FLOAT32);
2774     comparisonTest(ANEURALNETWORKS_GREATER_EQUAL, ANEURALNETWORKS_TENSOR_INT32);
2775     comparisonTest(ANEURALNETWORKS_GREATER_EQUAL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2776 }
2777 
reduceOpTest(ANeuralNetworksOperationType operationCode,int32_t inputOperandType)2778 void reduceOpTest(ANeuralNetworksOperationType operationCode, int32_t inputOperandType) {
2779     bool isQuant = inputOperandType == ANEURALNETWORKS_TENSOR_QUANT8_ASYMM;
2780     float scale = isQuant ? 1.f / 256 : 0.0f;
2781     uint32_t inputDimensions[4] = {2, 2, 2, 2};
2782     ANeuralNetworksOperandType input1 = {
2783             .type = inputOperandType,
2784             .dimensionCount = 4,
2785             .dimensions = inputDimensions,
2786             .scale = scale,
2787             .zeroPoint = 0,
2788     };
2789     uint32_t axesDimensions[1] = {2};
2790     ANeuralNetworksOperandType input2 = {
2791             .type = ANEURALNETWORKS_TENSOR_INT32,
2792             .dimensionCount = 1,
2793             .dimensions = axesDimensions,
2794     };
2795     ANeuralNetworksOperandType input3 = {
2796             .type = ANEURALNETWORKS_BOOL,
2797             .dimensions = {},
2798     };
2799     ANeuralNetworksOperandType output = {
2800             .type = inputOperandType,
2801             .dimensionCount = 4,
2802             .dimensions = inputDimensions,
2803             .scale = scale,
2804     };
2805     OperationTestBase test(operationCode, {input1, input2, input3}, {output});
2806     test.testOpsValidations();
2807 }
2808 
TEST(OperationValidationTest,REDUCE_PROD)2809 TEST(OperationValidationTest, REDUCE_PROD) {
2810     reduceOpTest(ANEURALNETWORKS_REDUCE_PROD, ANEURALNETWORKS_TENSOR_FLOAT16);
2811     reduceOpTest(ANEURALNETWORKS_REDUCE_PROD, ANEURALNETWORKS_TENSOR_FLOAT32);
2812 }
2813 
TEST(OperationValidationTest,REDUCE_SUM)2814 TEST(OperationValidationTest, REDUCE_SUM) {
2815     reduceOpTest(ANEURALNETWORKS_REDUCE_SUM, ANEURALNETWORKS_TENSOR_FLOAT16);
2816     reduceOpTest(ANEURALNETWORKS_REDUCE_SUM, ANEURALNETWORKS_TENSOR_FLOAT32);
2817 }
2818 
TEST(OperationValidationTest,REDUCE_MAX)2819 TEST(OperationValidationTest, REDUCE_MAX) {
2820     reduceOpTest(ANEURALNETWORKS_REDUCE_MAX, ANEURALNETWORKS_TENSOR_FLOAT16);
2821     reduceOpTest(ANEURALNETWORKS_REDUCE_MAX, ANEURALNETWORKS_TENSOR_FLOAT32);
2822     reduceOpTest(ANEURALNETWORKS_REDUCE_MAX, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2823 }
2824 
TEST(OperationValidationTest,REDUCE_MIN)2825 TEST(OperationValidationTest, REDUCE_MIN) {
2826     reduceOpTest(ANEURALNETWORKS_REDUCE_MIN, ANEURALNETWORKS_TENSOR_FLOAT16);
2827     reduceOpTest(ANEURALNETWORKS_REDUCE_MIN, ANEURALNETWORKS_TENSOR_FLOAT32);
2828     reduceOpTest(ANEURALNETWORKS_REDUCE_MIN, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2829 }
2830 
TEST(OperationValidationTest,REDUCE_ANY)2831 TEST(OperationValidationTest, REDUCE_ANY) {
2832     reduceOpTest(ANEURALNETWORKS_REDUCE_ANY, ANEURALNETWORKS_TENSOR_BOOL8);
2833 }
2834 
TEST(OperationValidationTest,REDUCE_ALL)2835 TEST(OperationValidationTest, REDUCE_ALL) {
2836     reduceOpTest(ANEURALNETWORKS_REDUCE_ALL, ANEURALNETWORKS_TENSOR_BOOL8);
2837 }
2838 
selectTest(ANeuralNetworksOperationType operationCode,int32_t inputOperandType)2839 void selectTest(ANeuralNetworksOperationType operationCode, int32_t inputOperandType) {
2840     uint32_t inputDimensions[4] = {2, 2, 2, 2};
2841     ANeuralNetworksOperandType input0 = getOpType(ANEURALNETWORKS_TENSOR_BOOL8, 4, inputDimensions);
2842     ANeuralNetworksOperandType input1 = getOpType(inputOperandType, 4, inputDimensions);
2843     ANeuralNetworksOperandType input2 = input1;
2844     ANeuralNetworksOperandType output = input1;
2845 
2846     OperationTestBase test(operationCode, {input0, input1, input2}, {output});
2847     test.testOpsValidations();
2848 }
2849 
TEST(OperationValidationTest,SELECT)2850 TEST(OperationValidationTest, SELECT) {
2851     selectTest(ANEURALNETWORKS_SELECT, ANEURALNETWORKS_TENSOR_FLOAT16);
2852     selectTest(ANEURALNETWORKS_SELECT, ANEURALNETWORKS_TENSOR_FLOAT32);
2853     selectTest(ANEURALNETWORKS_SELECT, ANEURALNETWORKS_TENSOR_INT32);
2854     selectTest(ANEURALNETWORKS_SELECT, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
2855 }
2856 
powTest(int32_t inputOperandType)2857 void powTest(int32_t inputOperandType) {
2858     const uint32_t inputDimensions[] = {3, 3};
2859     ANeuralNetworksOperandType inputType = {.type = inputOperandType,
2860                                             .dimensionCount = 2,
2861                                             .dimensions = inputDimensions,
2862                                             .scale = 0.0f,
2863                                             .zeroPoint = 0};
2864 
2865     OperationTestBase test(ANEURALNETWORKS_POW, {inputType, inputType}, {inputType});
2866     test.testOpsValidations();
2867 }
2868 
TEST(OperationValidationTest,POW)2869 TEST(OperationValidationTest, POW) {
2870     powTest(ANEURALNETWORKS_TENSOR_FLOAT16);
2871     powTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2872 }
2873 
boxWithNmsLimitOpTest(int32_t scoreOperandCode,int32_t roiOperandCode,int32_t scalarOperandCode)2874 void boxWithNmsLimitOpTest(int32_t scoreOperandCode, int32_t roiOperandCode,
2875                            int32_t scalarOperandCode) {
2876     uint32_t scoreDim[] = {19, 3}, roiDim[] = {19, 12}, splitDim[] = {2};
2877     uint32_t outScoreDim[] = {12}, outRoiDim[] = {12, 4}, outClassDim[] = {12}, outSplitDim[] = {2};
2878     OperationTestBase boxWithNmsLimitTest(
2879             ANEURALNETWORKS_BOX_WITH_NMS_LIMIT,
2880             {getOpType(scoreOperandCode, 2, scoreDim), getOpType(roiOperandCode, 2, roiDim),
2881              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, splitDim), getOpType(scalarOperandCode),
2882              getOpType(ANEURALNETWORKS_INT32), getOpType(ANEURALNETWORKS_INT32),
2883              getOpType(scalarOperandCode), getOpType(scalarOperandCode),
2884              getOpType(scalarOperandCode)},
2885             {getOpType(scoreOperandCode, 1, outScoreDim), getOpType(roiOperandCode, 2, outRoiDim),
2886              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outClassDim),
2887              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outSplitDim)});
2888     boxWithNmsLimitTest.testOpsValidations();
2889 }
2890 
TEST(OperationValidationTest,BOX_WITH_NMS_LIMIT_float16)2891 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_float16) {
2892     boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
2893                           ANEURALNETWORKS_FLOAT16);
2894 }
2895 
TEST(OperationValidationTest,BOX_WITH_NMS_LIMIT_float32)2896 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_float32) {
2897     boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
2898                           ANEURALNETWORKS_FLOAT32);
2899 }
2900 
TEST(OperationValidationTest,BOX_WITH_NMS_LIMIT_quant)2901 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_quant) {
2902     boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM,
2903                           ANEURALNETWORKS_FLOAT32);
2904 }
2905 
castOpTest(int32_t inputOperandCode,int32_t outputOperandCode)2906 void castOpTest(int32_t inputOperandCode, int32_t outputOperandCode) {
2907     uint32_t inputDimensions[3] = {2, 2, 2};
2908     ANeuralNetworksOperandType input = getOpType(inputOperandCode, 3, inputDimensions);
2909     ANeuralNetworksOperandType output = getOpType(outputOperandCode, 3, inputDimensions);
2910     OperationTestBase test(ANEURALNETWORKS_CAST, {input}, {output});
2911     test.testOpsValidations();
2912 }
2913 
TEST(OperationValidationTest,CAST)2914 TEST(OperationValidationTest, CAST) {
2915     std::vector<int32_t> inputTypes = {ANEURALNETWORKS_TENSOR_FLOAT16,
2916                                        ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_INT32,
2917                                        ANEURALNETWORKS_TENSOR_QUANT8_ASYMM};
2918     std::vector<int32_t> outputTypes = inputTypes;
2919     for (auto inputType : inputTypes) {
2920         for (auto outputType : outputTypes) {
2921             castOpTest(inputType, outputType);
2922         }
2923     }
2924 }
2925 
bidirectionlSequenceRNNTest(int32_t inputOperandCode)2926 void bidirectionlSequenceRNNTest(int32_t inputOperandCode) {
2927     const uint32_t batchSize = 2;
2928     const uint32_t maxTime = 3;
2929     const uint32_t inputSize = 4;
2930     const uint32_t numUnits = 5;
2931 
2932     uint32_t inputDims[3] = {maxTime, batchSize, inputSize};
2933     uint32_t weightsDims[2] = {inputSize, numUnits};
2934     uint32_t recurrentWeightsDims[2] = {numUnits, numUnits};
2935     uint32_t biasDims[1] = {numUnits};
2936     uint32_t hiddenStateDims[2] = {batchSize, numUnits};
2937     uint32_t outputDims[2] = {batchSize, numUnits};
2938 
2939     ANeuralNetworksOperandType input = {.type = inputOperandCode,
2940                                         .dimensionCount = 3,
2941                                         .dimensions = inputDims,
2942                                         .scale = 0.0f,
2943                                         .zeroPoint = 0};
2944     ANeuralNetworksOperandType fwWeights = {.type = inputOperandCode,
2945                                             .dimensionCount = 2,
2946                                             .dimensions = weightsDims,
2947                                             .scale = 0.0f,
2948                                             .zeroPoint = 0};
2949     ANeuralNetworksOperandType bwWeights = fwWeights;
2950     ANeuralNetworksOperandType fwRecurrentWeights = {.type = inputOperandCode,
2951                                                      .dimensionCount = 2,
2952                                                      .dimensions = recurrentWeightsDims,
2953                                                      .scale = 0.0f,
2954                                                      .zeroPoint = 0};
2955     ANeuralNetworksOperandType bwRecurrentWeights = fwRecurrentWeights;
2956     ANeuralNetworksOperandType fwBias = {.type = inputOperandCode,
2957                                          .dimensionCount = 1,
2958                                          .dimensions = biasDims,
2959                                          .scale = 0.0f,
2960                                          .zeroPoint = 0};
2961     ANeuralNetworksOperandType bwBias = fwBias;
2962     ANeuralNetworksOperandType fwHiddenState = {.type = inputOperandCode,
2963                                                 .dimensionCount = 2,
2964                                                 .dimensions = hiddenStateDims,
2965                                                 .scale = 0.0f,
2966                                                 .zeroPoint = 0};
2967     ANeuralNetworksOperandType bwHiddenState = fwHiddenState;
2968     ANeuralNetworksOperandType output = {.type = inputOperandCode,
2969                                          .dimensionCount = 2,
2970                                          .dimensions = outputDims,
2971                                          .scale = 0.0f,
2972                                          .zeroPoint = 0};
2973     ANeuralNetworksOperandType activation = {.type = ANEURALNETWORKS_INT32,
2974                                              .dimensionCount = 0,
2975                                              .dimensions = nullptr,
2976                                              .scale = 0.0f,
2977                                              .zeroPoint = 0};
2978     ANeuralNetworksOperandType boolScalar = {.type = ANEURALNETWORKS_BOOL,
2979                                              .dimensionCount = 0,
2980                                              .dimensions = nullptr,
2981                                              .scale = 0.0f,
2982                                              .zeroPoint = 0};
2983     ANeuralNetworksOperandType timeMajor = boolScalar;
2984     ANeuralNetworksOperandType mergeOutputs = boolScalar;
2985 
2986     OperationTestBase rnnTest(ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN,
2987                               {input, fwWeights, fwRecurrentWeights, fwBias, fwHiddenState,
2988                                bwWeights, bwRecurrentWeights, bwBias, bwHiddenState, input,
2989                                fwWeights, bwWeights, activation, timeMajor, mergeOutputs},
2990                               {output, output});
2991     rnnTest.testOpsValidations();
2992 }
2993 
TEST(OperationValidationTest,BIDIRECTIONAL_SEQUENCE_RNN_float32)2994 TEST(OperationValidationTest, BIDIRECTIONAL_SEQUENCE_RNN_float32) {
2995     bidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT32);
2996 }
2997 
TEST(OperationValidationTest,BIDIRECTIONAL_SEQUENCE_RNN_float16)2998 TEST(OperationValidationTest, BIDIRECTIONAL_SEQUENCE_RNN_float16) {
2999     bidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT16);
3000 }
3001 
unidirectionlSequenceRNNTest(int32_t inputOperandCode)3002 void unidirectionlSequenceRNNTest(int32_t inputOperandCode) {
3003     const uint32_t batchSize = 2;
3004     const uint32_t maxTime = 3;
3005     const uint32_t inputSize = 4;
3006     const uint32_t numUnits = 5;
3007 
3008     uint32_t inputDims[3] = {maxTime, batchSize, inputSize};
3009     uint32_t weightsDims[2] = {inputSize, numUnits};
3010     uint32_t recurrentWeightsDims[2] = {numUnits, numUnits};
3011     uint32_t biasDims[1] = {numUnits};
3012     uint32_t hiddenStateDims[2] = {batchSize, numUnits};
3013     uint32_t outputDims[2] = {batchSize, numUnits};
3014 
3015     ANeuralNetworksOperandType input = {.type = inputOperandCode,
3016                                         .dimensionCount = 3,
3017                                         .dimensions = inputDims,
3018                                         .scale = 0.0f,
3019                                         .zeroPoint = 0};
3020     ANeuralNetworksOperandType weights = {.type = inputOperandCode,
3021                                           .dimensionCount = 2,
3022                                           .dimensions = weightsDims,
3023                                           .scale = 0.0f,
3024                                           .zeroPoint = 0};
3025     ANeuralNetworksOperandType recurrentWeights = {.type = inputOperandCode,
3026                                                    .dimensionCount = 2,
3027                                                    .dimensions = recurrentWeightsDims,
3028                                                    .scale = 0.0f,
3029                                                    .zeroPoint = 0};
3030     ANeuralNetworksOperandType bias = {.type = inputOperandCode,
3031                                        .dimensionCount = 1,
3032                                        .dimensions = biasDims,
3033                                        .scale = 0.0f,
3034                                        .zeroPoint = 0};
3035     ANeuralNetworksOperandType hiddenState = {.type = inputOperandCode,
3036                                               .dimensionCount = 2,
3037                                               .dimensions = hiddenStateDims,
3038                                               .scale = 0.0f,
3039                                               .zeroPoint = 0};
3040     ANeuralNetworksOperandType output = {.type = inputOperandCode,
3041                                          .dimensionCount = 2,
3042                                          .dimensions = outputDims,
3043                                          .scale = 0.0f,
3044                                          .zeroPoint = 0};
3045     ANeuralNetworksOperandType intScalar = {.type = ANEURALNETWORKS_INT32,
3046                                             .dimensionCount = 0,
3047                                             .dimensions = nullptr,
3048                                             .scale = 0.0f,
3049                                             .zeroPoint = 0};
3050     ANeuralNetworksOperandType activation = intScalar;
3051     ANeuralNetworksOperandType timeMajor = intScalar;
3052 
3053     OperationTestBase rnnTest(
3054             ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN,
3055             {input, weights, recurrentWeights, bias, hiddenState, activation, timeMajor}, {output});
3056     rnnTest.testOpsValidations();
3057 }
3058 
TEST(OperationValidationTest,UNIDIRECTIONAL_SEQUENCE_RNN_float32)3059 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_RNN_float32) {
3060     unidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT32);
3061 }
3062 
TEST(OperationValidationTest,UNIDIRECTIONAL_SEQUENCE_RNN_float16)3063 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_RNN_float16) {
3064     unidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT16);
3065 }
3066 
unidirectionalSequenceLSTMTest(int32_t inputOperandCode)3067 void unidirectionalSequenceLSTMTest(int32_t inputOperandCode) {
3068     const uint32_t maxTime = 2;
3069     const uint32_t batchSize = 3;
3070     const uint32_t numUnits = 4;
3071     const uint32_t inputSize = 5;
3072     const uint32_t outputSize = 6;
3073 
3074     uint32_t inputDims[3] = {maxTime, batchSize, inputSize};
3075     uint32_t inputWeightsDims[2] = {numUnits, inputSize};
3076     uint32_t recurrentWeightsDims[2] = {numUnits, outputSize};
3077     uint32_t diagonalDims[1] = {numUnits};
3078     uint32_t projectionDims[2] = {outputSize, numUnits};
3079     uint32_t projectionBiasDims[1] = {outputSize};
3080     uint32_t outputStateDims[2] = {batchSize, outputSize};
3081     uint32_t cellStateDims[2] = {batchSize, numUnits};
3082 
3083     uint32_t outputDims[3] = {maxTime, batchSize, outputSize};
3084 
3085     ANeuralNetworksOperandType input = {.type = inputOperandCode,
3086                                         .dimensionCount = 3,
3087                                         .dimensions = inputDims,
3088                                         .scale = 0.0f,
3089                                         .zeroPoint = 0};
3090     ANeuralNetworksOperandType inputToInputWeights = {.type = inputOperandCode,
3091                                                       .dimensionCount = 2,
3092                                                       .dimensions = inputWeightsDims,
3093                                                       .scale = 0.0f,
3094                                                       .zeroPoint = 0};
3095     ANeuralNetworksOperandType inputToForgetWeights = inputToInputWeights;
3096     ANeuralNetworksOperandType inputToCellWeights = inputToInputWeights;
3097     ANeuralNetworksOperandType inputToOutputWeights = inputToInputWeights;
3098     ANeuralNetworksOperandType recurrentToInputWeights = {.type = inputOperandCode,
3099                                                           .dimensionCount = 2,
3100                                                           .dimensions = recurrentWeightsDims,
3101                                                           .scale = 0.0f,
3102                                                           .zeroPoint = 0};
3103     ANeuralNetworksOperandType recurrentToForgetWeights = recurrentToInputWeights;
3104     ANeuralNetworksOperandType recurrentToCellWeights = recurrentToInputWeights;
3105     ANeuralNetworksOperandType recurrentToOutputWeights = recurrentToInputWeights;
3106     ANeuralNetworksOperandType cellToInputWeights = {.type = inputOperandCode,
3107                                                      .dimensionCount = 1,
3108                                                      .dimensions = diagonalDims,
3109                                                      .scale = 0.0f,
3110                                                      .zeroPoint = 0};
3111     ANeuralNetworksOperandType cellToForgetWeights = cellToInputWeights;
3112     ANeuralNetworksOperandType cellToOutputWeights = cellToInputWeights;
3113     ANeuralNetworksOperandType inputGateBias = {.type = inputOperandCode,
3114                                                 .dimensionCount = 1,
3115                                                 .dimensions = diagonalDims,
3116                                                 .scale = 0.0f,
3117                                                 .zeroPoint = 0};
3118     ANeuralNetworksOperandType forgetGateBias = inputGateBias;
3119     ANeuralNetworksOperandType cellGateBias = inputGateBias;
3120     ANeuralNetworksOperandType outputGateBias = inputGateBias;
3121     ANeuralNetworksOperandType projectionWeights = {.type = inputOperandCode,
3122                                                     .dimensionCount = 2,
3123                                                     .dimensions = projectionDims,
3124                                                     .scale = 0.0f,
3125                                                     .zeroPoint = 0};
3126     ANeuralNetworksOperandType projectionBias = {.type = inputOperandCode,
3127                                                  .dimensionCount = 1,
3128                                                  .dimensions = projectionBiasDims,
3129                                                  .scale = 0.0f,
3130                                                  .zeroPoint = 0};
3131     ANeuralNetworksOperandType outputStateIn = {.type = inputOperandCode,
3132                                                 .dimensionCount = 2,
3133                                                 .dimensions = outputStateDims,
3134                                                 .scale = 0.0f,
3135                                                 .zeroPoint = 0};
3136     ANeuralNetworksOperandType cellStateIn = {.type = inputOperandCode,
3137                                               .dimensionCount = 2,
3138                                               .dimensions = cellStateDims,
3139                                               .scale = 0.0f,
3140                                               .zeroPoint = 0};
3141     ANeuralNetworksOperandType intScalar = {
3142             .type = ANEURALNETWORKS_INT32,
3143             .dimensionCount = 0,
3144             .dimensions = nullptr,
3145             .scale = 0.0f,
3146             .zeroPoint = 0,
3147     };
3148     ANeuralNetworksOperandType activation = intScalar;
3149     ANeuralNetworksOperandType floatScalar = {
3150             .type = inputOperandCode == ANEURALNETWORKS_TENSOR_FLOAT32 ? ANEURALNETWORKS_FLOAT32
3151                                                                        : ANEURALNETWORKS_FLOAT16,
3152             .dimensionCount = 0,
3153             .dimensions = nullptr,
3154             .scale = 0.0f,
3155             .zeroPoint = 0,
3156     };
3157     ANeuralNetworksOperandType cellClip = floatScalar;
3158     ANeuralNetworksOperandType projClip = floatScalar;
3159     ANeuralNetworksOperandType boolScalar = {
3160             .type = ANEURALNETWORKS_BOOL,
3161             .dimensionCount = 0,
3162             .dimensions = nullptr,
3163             .scale = 0.0f,
3164             .zeroPoint = 0,
3165     };
3166     ANeuralNetworksOperandType timeMajor = boolScalar;
3167     ANeuralNetworksOperandType inputLayerNormWeights = {.type = inputOperandCode,
3168                                                         .dimensionCount = 1,
3169                                                         .dimensions = diagonalDims,
3170                                                         .scale = 0.0f,
3171                                                         .zeroPoint = 0};
3172     ANeuralNetworksOperandType forgetLayerNormWeights = inputLayerNormWeights;
3173     ANeuralNetworksOperandType cellLayerNormWeights = inputLayerNormWeights;
3174     ANeuralNetworksOperandType outputLayerNormWeights = inputLayerNormWeights;
3175 
3176     ANeuralNetworksOperandType output = {.type = inputOperandCode,
3177                                          .dimensionCount = 3,
3178                                          .dimensions = outputDims,
3179                                          .scale = 0.0f,
3180                                          .zeroPoint = 0};
3181 
3182     OperationTestBase ulstmTest(ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM,
3183                                 {input,
3184                                  inputToInputWeights,
3185                                  inputToForgetWeights,
3186                                  inputToCellWeights,
3187                                  inputToOutputWeights,
3188                                  recurrentToInputWeights,
3189                                  recurrentToForgetWeights,
3190                                  recurrentToCellWeights,
3191                                  recurrentToOutputWeights,
3192                                  cellToInputWeights,
3193                                  cellToForgetWeights,
3194                                  cellToOutputWeights,
3195                                  inputGateBias,
3196                                  forgetGateBias,
3197                                  cellGateBias,
3198                                  outputGateBias,
3199                                  projectionWeights,
3200                                  projectionBias,
3201                                  outputStateIn,
3202                                  cellStateIn,
3203                                  activation,
3204                                  cellClip,
3205                                  projClip,
3206                                  timeMajor,
3207                                  inputLayerNormWeights,
3208                                  forgetLayerNormWeights,
3209                                  cellLayerNormWeights,
3210                                  outputLayerNormWeights},
3211                                 {output});
3212     ulstmTest.testOpsValidations();
3213 }
3214 
TEST(OperationValidationTest,UNIDIRECTIONAL_SEQUENCE_LSTM_float32)3215 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_LSTM_float32) {
3216     unidirectionalSequenceLSTMTest(ANEURALNETWORKS_TENSOR_FLOAT32);
3217 }
3218 
TEST(OperationValidationTest,UNIDIRECTIONAL_SEQUENCE_LSTM_float16)3219 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_LSTM_float16) {
3220     unidirectionalSequenceLSTMTest(ANEURALNETWORKS_TENSOR_FLOAT16);
3221 }
3222 
generateProposalsOpTest(int32_t scoreOperandCode,int32_t deltaOperandCode,int32_t anchorOperandCode,int32_t roiOperandCode,int32_t scalarOperandCode)3223 void generateProposalsOpTest(int32_t scoreOperandCode, int32_t deltaOperandCode,
3224                              int32_t anchorOperandCode, int32_t roiOperandCode,
3225                              int32_t scalarOperandCode) {
3226     uint32_t scoreDim[] = {1, 2, 2, 2}, deltaDim[] = {1, 2, 2, 8}, anchorDim[] = {2, 4},
3227              imageInfoDim[] = {1, 2};
3228     uint32_t outScoreDim[] = {4}, outRoiDim[] = {4, 4}, outSplitDim[] = {1};
3229     OperationTestBase generateProposalsTest(
3230             ANEURALNETWORKS_GENERATE_PROPOSALS,
3231             {getOpType(scoreOperandCode, 4, scoreDim), getOpType(deltaOperandCode, 4, deltaDim),
3232              getOpType(anchorOperandCode, 2, anchorDim), getOpType(roiOperandCode, 2, imageInfoDim),
3233              getOpType(scalarOperandCode), getOpType(scalarOperandCode),
3234              getOpType(ANEURALNETWORKS_INT32), getOpType(ANEURALNETWORKS_INT32),
3235              getOpType(scalarOperandCode), getOpType(scalarOperandCode),
3236              getOpType(ANEURALNETWORKS_BOOL)},
3237             {getOpType(scoreOperandCode, 1, outScoreDim), getOpType(roiOperandCode, 2, outRoiDim),
3238              getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outSplitDim)});
3239     generateProposalsTest.testOpsValidations();
3240 }
3241 
TEST(OperationValidationTest,GENERATE_PROPOSALS_float16)3242 TEST(OperationValidationTest, GENERATE_PROPOSALS_float16) {
3243     generateProposalsOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
3244                             ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
3245                             ANEURALNETWORKS_FLOAT16);
3246 }
3247 
TEST(OperationValidationTest,GENERATE_PROPOSALS_float32)3248 TEST(OperationValidationTest, GENERATE_PROPOSALS_float32) {
3249     generateProposalsOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
3250                             ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
3251                             ANEURALNETWORKS_FLOAT32);
3252 }
3253 
TEST(OperationValidationTest,GENERATE_PROPOSALS_quant)3254 TEST(OperationValidationTest, GENERATE_PROPOSALS_quant) {
3255     generateProposalsOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
3256                             ANEURALNETWORKS_TENSOR_QUANT8_ASYMM,
3257                             ANEURALNETWORKS_TENSOR_QUANT16_SYMM,
3258                             ANEURALNETWORKS_TENSOR_QUANT16_ASYMM, ANEURALNETWORKS_FLOAT32);
3259 }
3260 
resizeNearestNeighborTest(int32_t inputCode,int32_t scalarCode)3261 void resizeNearestNeighborTest(int32_t inputCode, int32_t scalarCode) {
3262     uint32_t inputDim[] = {1, 2, 2, 1}, outputDim[] = {1, 1, 1, 1};
3263     OperationTestBase resizeImageOpTest(ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR,
3264                                         {getOpType(inputCode, 4, inputDim), getOpType(scalarCode),
3265                                          getOpType(scalarCode), getOpType(ANEURALNETWORKS_BOOL)},
3266                                         {getOpType(inputCode, 4, outputDim)});
3267     resizeImageOpTest.testOpsValidations();
3268 }
3269 
TEST(OperationValidationTest,RESIZE_NEAREST_NEIGHBOR)3270 TEST(OperationValidationTest, RESIZE_NEAREST_NEIGHBOR) {
3271     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_INT32);
3272     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_FLOAT32);
3273 }
3274 
TEST(OperationValidationTest,RESIZE_NEAREST_NEIGHBOR_float16)3275 TEST(OperationValidationTest, RESIZE_NEAREST_NEIGHBOR_float16) {
3276     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_INT32);
3277     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_FLOAT16);
3278 }
3279 
TEST(OperationValidationTest,RESIZE_NEAREST_NEIGHBOR_quant8)3280 TEST(OperationValidationTest, RESIZE_NEAREST_NEIGHBOR_quant8) {
3281     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_INT32);
3282     resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_FLOAT32);
3283 }
3284 
3285 }  // end namespace
3286