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 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 { 60 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: 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 81 void setInputSymmPerChannelQuantParams( 82 int32_t index, const ANeuralNetworksSymmPerChannelQuantParams& channelQuant) { 83 mValidInputs[index].channelQuant = channelQuant; 84 } 85 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. 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 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 133 void testFailure(int32_t expectedResult) { 134 int32_t result = addOperation(mValidInputs, mValidOutputs); 135 EXPECT_TRUE(expectedResult == result); 136 } 137 138 bool testSuccess() { 139 int32_t result = addOperation(mValidInputs, mValidOutputs); 140 return ANEURALNETWORKS_NO_ERROR == result; 141 } 142 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 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 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 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 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 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 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 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 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 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 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 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 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 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 444 TEST(OperationValidationTest, QUANTIZE_float16) { 445 quantizeOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 446 } 447 448 TEST(OperationValidationTest, QUANTIZE_float32) { 449 quantizeOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 450 } 451 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 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 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 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 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 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 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 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 594 TEST(OperationValidationTest, ADD_float16) { 595 simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_FLOAT16); 596 } 597 598 TEST(OperationValidationTest, ADD_float32) { 599 simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_FLOAT32); 600 } 601 602 TEST(OperationValidationTest, MUL_float16) { 603 simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_FLOAT16); 604 } 605 606 TEST(OperationValidationTest, MUL_float32) { 607 simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_FLOAT32); 608 } 609 610 TEST(OperationValidationTest, SUB_float16) { 611 simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_FLOAT16); 612 } 613 614 TEST(OperationValidationTest, SUB_float32) { 615 simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_FLOAT32); 616 } 617 618 TEST(OperationValidationTest, SUB_quant8) { 619 simpleMathOpTest(ANEURALNETWORKS_SUB, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 620 } 621 622 TEST(OperationValidationTest, DIV_float16) { 623 simpleMathOpTest(ANEURALNETWORKS_DIV, ANEURALNETWORKS_TENSOR_FLOAT16); 624 } 625 626 TEST(OperationValidationTest, DIV_float32) { 627 simpleMathOpTest(ANEURALNETWORKS_DIV, ANEURALNETWORKS_TENSOR_FLOAT32); 628 } 629 630 TEST(OperationValidationTest, ADD_quant8) { 631 simpleMathOpTest(ANEURALNETWORKS_ADD, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 632 } 633 634 TEST(OperationValidationTest, MUL_quant8) { 635 simpleMathOpTest(ANEURALNETWORKS_MUL, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 636 } 637 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 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 668 TEST(OperationValidationTest, MAXIMUM_float16) { 669 binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_FLOAT16); 670 } 671 672 TEST(OperationValidationTest, MAXIMUM_float32) { 673 binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_FLOAT32); 674 } 675 676 TEST(OperationValidationTest, MAXIMUM_int32) { 677 binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_INT32); 678 } 679 680 TEST(OperationValidationTest, MAXIMUM_quant8) { 681 binaryOpTest(ANEURALNETWORKS_MAXIMUM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 682 } 683 684 TEST(OperationValidationTest, MINIMUM_float16) { 685 binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_FLOAT16); 686 } 687 688 TEST(OperationValidationTest, MINIMUM_float32) { 689 binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_FLOAT32); 690 } 691 692 TEST(OperationValidationTest, MINIMUM_int32) { 693 binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_INT32); 694 } 695 696 TEST(OperationValidationTest, MINIMUM_quant8) { 697 binaryOpTest(ANEURALNETWORKS_MINIMUM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 698 } 699 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 709 TEST(OperationValidationTest, ABS_float16) { 710 activationOpTest(ANEURALNETWORKS_ABS, ANEURALNETWORKS_TENSOR_FLOAT16); 711 } 712 713 TEST(OperationValidationTest, ABS_float32) { 714 activationOpTest(ANEURALNETWORKS_ABS, ANEURALNETWORKS_TENSOR_FLOAT32); 715 } 716 717 TEST(OperationValidationTest, EXP_float16) { 718 activationOpTest(ANEURALNETWORKS_EXP, ANEURALNETWORKS_TENSOR_FLOAT16); 719 } 720 721 TEST(OperationValidationTest, EXP_float32) { 722 activationOpTest(ANEURALNETWORKS_EXP, ANEURALNETWORKS_TENSOR_FLOAT32); 723 } 724 725 TEST(OperationValidationTest, LOG_float16) { 726 activationOpTest(ANEURALNETWORKS_LOG, ANEURALNETWORKS_TENSOR_FLOAT16); 727 } 728 729 TEST(OperationValidationTest, LOG_float32) { 730 activationOpTest(ANEURALNETWORKS_LOG, ANEURALNETWORKS_TENSOR_FLOAT32); 731 } 732 733 TEST(OperationValidationTest, RSQRT_float16) { 734 activationOpTest(ANEURALNETWORKS_RSQRT, ANEURALNETWORKS_TENSOR_FLOAT16); 735 } 736 737 TEST(OperationValidationTest, RSQRT_float32) { 738 activationOpTest(ANEURALNETWORKS_RSQRT, ANEURALNETWORKS_TENSOR_FLOAT32); 739 } 740 741 TEST(OperationValidationTest, SIN_float16) { 742 activationOpTest(ANEURALNETWORKS_SIN, ANEURALNETWORKS_TENSOR_FLOAT16); 743 } 744 745 TEST(OperationValidationTest, SIN_float32) { 746 activationOpTest(ANEURALNETWORKS_SIN, ANEURALNETWORKS_TENSOR_FLOAT32); 747 } 748 749 TEST(OperationValidationTest, SQRT_float16) { 750 activationOpTest(ANEURALNETWORKS_SQRT, ANEURALNETWORKS_TENSOR_FLOAT16); 751 } 752 753 TEST(OperationValidationTest, SQRT_float32) { 754 activationOpTest(ANEURALNETWORKS_SQRT, ANEURALNETWORKS_TENSOR_FLOAT32); 755 } 756 757 TEST(OperationValidationTest, NEG_float16) { 758 activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_FLOAT16); 759 } 760 761 TEST(OperationValidationTest, NEG_float32) { 762 activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_FLOAT32); 763 } 764 765 TEST(OperationValidationTest, NEG_int32) { 766 activationOpTest(ANEURALNETWORKS_NEG, ANEURALNETWORKS_TENSOR_INT32); 767 } 768 769 TEST(OperationValidationTest, FLOOR_float16) { 770 activationOpTest(ANEURALNETWORKS_FLOOR, ANEURALNETWORKS_TENSOR_FLOAT16); 771 } 772 773 TEST(OperationValidationTest, FLOOR_float32) { 774 activationOpTest(ANEURALNETWORKS_FLOOR, ANEURALNETWORKS_TENSOR_FLOAT32); 775 } 776 777 TEST(OperationValidationTest, LOGICAL_NOT_bool) { 778 activationOpTest(ANEURALNETWORKS_LOGICAL_NOT, ANEURALNETWORKS_TENSOR_BOOL8); 779 } 780 781 TEST(OperationValidationTest, TANH_float16) { 782 activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_FLOAT16); 783 } 784 785 TEST(OperationValidationTest, TANH_float32) { 786 activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_FLOAT32); 787 } 788 789 TEST(OperationValidationTest, TANH_quant8) { 790 activationOpTest(ANEURALNETWORKS_TANH, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 791 } 792 793 TEST(OperationValidationTest, RELU_float16) { 794 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16); 795 } 796 797 TEST(OperationValidationTest, RELU1_float16) { 798 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16); 799 } 800 801 TEST(OperationValidationTest, RELU6_float16) { 802 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT16); 803 } 804 805 TEST(OperationValidationTest, RELU_float32) { 806 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32); 807 } 808 809 TEST(OperationValidationTest, RELU1_float32) { 810 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32); 811 } 812 813 TEST(OperationValidationTest, RELU6_float32) { 814 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_FLOAT32); 815 } 816 817 TEST(OperationValidationTest, LOGISTIC_float16) { 818 activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_FLOAT16); 819 } 820 821 TEST(OperationValidationTest, LOGISTIC_float32) { 822 activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_FLOAT32); 823 } 824 825 TEST(OperationValidationTest, RELU_quant8) { 826 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 827 } 828 829 TEST(OperationValidationTest, RELU1_quant8) { 830 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 831 } 832 833 TEST(OperationValidationTest, RELU6_quant8) { 834 activationOpTest(ANEURALNETWORKS_RELU, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 835 } 836 837 TEST(OperationValidationTest, LOGISTIC_quant8) { 838 activationOpTest(ANEURALNETWORKS_LOGISTIC, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 839 } 840 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 853 TEST(OperationValidationTest, RESHAPE) { 854 reshapeOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 855 reshapeOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 856 reshapeOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 857 } 858 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 889 TEST(OperationValidationTest, LOG_SOFTMAX_float16) { 890 logSoftmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 891 } 892 893 TEST(OperationValidationTest, LOG_SOFTMAX_float32) { 894 logSoftmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 895 } 896 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 908 TEST(OperationValidationTest, MEAN_float16) { 909 meanOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 910 } 911 912 TEST(OperationValidationTest, MEAN_float32) { 913 meanOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 914 } 915 916 TEST(OperationValidationTest, MEAN_quant8) { 917 meanOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 918 } 919 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 933 TEST(OperationValidationTest, PAD) { 934 padOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 935 padOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 936 padOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 937 } 938 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 958 TEST(OperationValidationTest, PAD_V2) { 959 padV2OpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 960 padV2OpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 961 padV2OpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 962 } 963 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 982 TEST(OperationValidationTest, SOFTMAX_float16) { 983 softmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 984 } 985 986 TEST(OperationValidationTest, SOFTMAX_float32) { 987 softmaxOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 988 } 989 990 TEST(OperationValidationTest, SOFTMAX_quant8) { 991 softmaxOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 992 } 993 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 1047 TEST(OperationValidationTest, AVERAGE_POOL_2D_float16) { 1048 poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16); 1049 } 1050 1051 TEST(OperationValidationTest, AVERAGE_POOL_2D_float32) { 1052 poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32); 1053 } 1054 1055 TEST(OperationValidationTest, MAX_POOL_2D_float32) { 1056 poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32); 1057 } 1058 1059 TEST(OperationValidationTest, MAX_POOL_2D_float16) { 1060 poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16); 1061 } 1062 1063 TEST(OperationValidationTest, L2_POOL_2D_float16) { 1064 poolingOpTest(ANEURALNETWORKS_L2_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT16); 1065 } 1066 1067 TEST(OperationValidationTest, L2_POOL_2D_float32) { 1068 poolingOpTest(ANEURALNETWORKS_L2_POOL_2D, ANEURALNETWORKS_TENSOR_FLOAT32); 1069 } 1070 1071 TEST(OperationValidationTest, AVERAGE_POOL_2D_quant8) { 1072 poolingOpTest(ANEURALNETWORKS_AVERAGE_POOL_2D, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1073 } 1074 1075 TEST(OperationValidationTest, MAX_POOL_2D_quant8) { 1076 poolingOpTest(ANEURALNETWORKS_MAX_POOL_2D, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1077 } 1078 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 1102 TEST(OperationValidationTest, SPACE_TO_DEPTH_float16) { 1103 spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_FLOAT16); 1104 } 1105 1106 TEST(OperationValidationTest, DEPTH_TO_SPACE_float16) { 1107 spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_FLOAT16); 1108 } 1109 1110 TEST(OperationValidationTest, SPACE_TO_DEPTH_float32) { 1111 spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_FLOAT32); 1112 } 1113 1114 TEST(OperationValidationTest, DEPTH_TO_SPACE_float32) { 1115 spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_FLOAT32); 1116 } 1117 1118 TEST(OperationValidationTest, SPACE_TO_DEPTH_quant8) { 1119 spaceDepthOpTest(ANEURALNETWORKS_SPACE_TO_DEPTH, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1120 } 1121 1122 TEST(OperationValidationTest, DEPTH_TO_SPACE_quant8) { 1123 spaceDepthOpTest(ANEURALNETWORKS_DEPTH_TO_SPACE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1124 } 1125 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 1160 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_float16) { 1161 spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_FLOAT16); 1162 } 1163 1164 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_float16) { 1165 spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_FLOAT16); 1166 } 1167 1168 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_float32) { 1169 spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_FLOAT32); 1170 } 1171 1172 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_float32) { 1173 spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_FLOAT32); 1174 } 1175 1176 TEST(OperationValidationTest, SPACE_TO_BATCH_ND_quant8) { 1177 spaceBatchOpTest(ANEURALNETWORKS_SPACE_TO_BATCH_ND, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1178 } 1179 1180 TEST(OperationValidationTest, BATCH_TO_SPACE_ND_quant8) { 1181 spaceBatchOpTest(ANEURALNETWORKS_BATCH_TO_SPACE_ND, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1182 } 1183 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 1200 TEST(OperationValidationTest, TRANSPOSE_float16) { 1201 transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_FLOAT16); 1202 } 1203 1204 TEST(OperationValidationTest, SQUEEZE_float16) { 1205 transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_FLOAT16); 1206 } 1207 1208 TEST(OperationValidationTest, TRANSPOSE_float32) { 1209 transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_FLOAT32); 1210 } 1211 1212 TEST(OperationValidationTest, SQUEEZE_float32) { 1213 transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_FLOAT32); 1214 } 1215 1216 TEST(OperationValidationTest, TRANSPOSE_quant8) { 1217 transposeAndSqueezeOpTest(ANEURALNETWORKS_TRANSPOSE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1218 } 1219 1220 TEST(OperationValidationTest, SQUEEZE_quant8) { 1221 transposeAndSqueezeOpTest(ANEURALNETWORKS_SQUEEZE, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1222 } 1223 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 1331 TEST(OperationValidationTest, CONV_2D_float16) { 1332 convOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 1333 } 1334 1335 TEST(OperationValidationTest, CONV_2D_float32) { 1336 convOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 1337 } 1338 1339 TEST(OperationValidationTest, CONV_2D_quant8) { 1340 convOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1341 } 1342 1343 TEST(OperationValidationTest, CONV_2D_quant8_per_channel) { 1344 convOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL); 1345 } 1346 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 1454 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_float32) { 1455 depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 1456 } 1457 1458 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_float16) { 1459 depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 1460 } 1461 1462 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_quant8) { 1463 depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1464 } 1465 1466 TEST(OperationValidationTest, DEPTHWISE_CONV_2D_quant8_per_channel) { 1467 depthwiseConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, 1468 ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL); 1469 } 1470 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 1500 TEST(OperationValidationTest, FULLY_CONNECTED_float16) { 1501 fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 1502 } 1503 1504 TEST(OperationValidationTest, FULLY_CONNECTED_float32) { 1505 fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 1506 } 1507 1508 TEST(OperationValidationTest, FULLY_CONNECTED_quant8) { 1509 fullyConnectedOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1510 } 1511 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 1532 TEST(OperationValidationTest, CONCATENATION_float16) { 1533 concatenationTest(ANEURALNETWORKS_TENSOR_FLOAT16); 1534 } 1535 1536 TEST(OperationValidationTest, CONCATENATION_float32) { 1537 concatenationTest(ANEURALNETWORKS_TENSOR_FLOAT32); 1538 } 1539 1540 TEST(OperationValidationTest, CONCATENATION_quant8) { 1541 concatenationTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1542 } 1543 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 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 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 1586 TEST(OperationValidationTest, EMBEDDING_LOOKUP_float32) { 1587 embeddingLookupTest(ANEURALNETWORKS_TENSOR_FLOAT32); 1588 } 1589 1590 TEST(OperationValidationTest, EMBEDDING_LOOKUP_int32) { 1591 embeddingLookupTest(ANEURALNETWORKS_TENSOR_INT32); 1592 } 1593 1594 TEST(OperationValidationTest, EMBEDDING_LOOKUP_quant8) { 1595 embeddingLookupTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1596 } 1597 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 1620 TEST(OperationValidationTest, HASHTABLE_LOOKUP_float32) { 1621 hashtableLookupTest(ANEURALNETWORKS_TENSOR_FLOAT32); 1622 } 1623 1624 TEST(OperationValidationTest, HASHTABLE_LOOKUP_int32) { 1625 hashtableLookupTest(ANEURALNETWORKS_TENSOR_INT32); 1626 } 1627 1628 TEST(OperationValidationTest, HASHTABLE_LOOKUP_quant8) { 1629 hashtableLookupTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 1630 } 1631 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 1654 TEST(OperationValidationTest, LSH_PROJECTION_float16) { 1655 lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT32); 1656 lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 1657 } 1658 1659 TEST(OperationValidationTest, LSH_PROJECTION_float32) { 1660 lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 1661 lshProjectionTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT16); 1662 } 1663 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 1669 TEST(OperationValidationTest, LSH_PROJECTION_int32) { 1670 lshProjectionTest(ANEURALNETWORKS_TENSOR_INT32, ANEURALNETWORKS_TENSOR_FLOAT32); 1671 lshProjectionTest(ANEURALNETWORKS_TENSOR_INT32, ANEURALNETWORKS_TENSOR_FLOAT16); 1672 } 1673 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 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 1847 TEST(OperationValidationTest, LSTM_V1_2) { 1848 lstmTestV1_2(ANEURALNETWORKS_TENSOR_FLOAT32); 1849 lstmTestV1_2(ANEURALNETWORKS_TENSOR_FLOAT16); 1850 } 1851 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 2035 TEST(OperationValidationTest, LSTM_BIDIRECTIONAL_SEQUENCE) { 2036 lstmBidirectionalSequence(ANEURALNETWORKS_TENSOR_FLOAT32); 2037 lstmBidirectionalSequence(ANEURALNETWORKS_TENSOR_FLOAT16); 2038 } 2039 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 2070 TEST(OperationValidationTest, RANDOM_MULTINOMIAL_float16) { 2071 randomMultinomialOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2072 } 2073 2074 TEST(OperationValidationTest, RANDOM_MULTINOMIAL_float32) { 2075 randomMultinomialOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2076 } 2077 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 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 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 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 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 2251 TEST(OperationValidationTest, STRIDED_SLICE_float32) { 2252 stridedSliceOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2253 } 2254 2255 TEST(OperationValidationTest, STRIDED_SLICE_float16) { 2256 stridedSliceOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2257 } 2258 2259 TEST(OperationValidationTest, STRIDED_SLICE_quant8) { 2260 stridedSliceOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2261 } 2262 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 2278 TEST(OperationValidationTest, ROI_ALIGN_float16) { 2279 roiAlignOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16, 2280 ANEURALNETWORKS_FLOAT16); 2281 } 2282 2283 TEST(OperationValidationTest, ROI_ALIGN_float32) { 2284 roiAlignOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32, 2285 ANEURALNETWORKS_FLOAT32); 2286 } 2287 2288 TEST(OperationValidationTest, ROI_ALIGN_quant8) { 2289 roiAlignOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM, 2290 ANEURALNETWORKS_FLOAT32); 2291 } 2292 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 2307 TEST(OperationValidationTest, ROI_POOLING_float16) { 2308 roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16, 2309 ANEURALNETWORKS_FLOAT16); 2310 } 2311 2312 TEST(OperationValidationTest, ROI_POOLING_float32) { 2313 roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32, 2314 ANEURALNETWORKS_FLOAT32); 2315 } 2316 2317 TEST(OperationValidationTest, ROI_POOLING_quant8) { 2318 roiPoolingOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM, 2319 ANEURALNETWORKS_FLOAT32); 2320 } 2321 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 2334 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_float16) { 2335 heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 2336 } 2337 2338 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_float32) { 2339 heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 2340 } 2341 2342 TEST(OperationValidationTest, HEATMAP_MAX_KEYPOINT_quant) { 2343 heatmapMaxKeypointOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, 2344 ANEURALNETWORKS_TENSOR_QUANT16_ASYMM); 2345 } 2346 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 2366 TEST(OperationValidationTest, INSTANCE_NORMALIZATION) { 2367 instanceNormalizationOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2368 instanceNormalizationOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2369 } 2370 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 2418 TEST(OperationValidationTest, GROUPED_CONV_2D_float16) { 2419 groupedConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 2420 } 2421 2422 TEST(OperationValidationTest, GROUPED_CONV_2D_float32) { 2423 groupedConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 2424 } 2425 2426 TEST(OperationValidationTest, GROUPED_CONV_2D_quant8) { 2427 groupedConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2428 } 2429 2430 TEST(OperationValidationTest, GROUPED_CONV_2D_quant8_per_channel) { 2431 groupedConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, 2432 ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL); 2433 } 2434 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 2482 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_float16) { 2483 transposeConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 2484 } 2485 2486 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_float32) { 2487 transposeConvOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 2488 } 2489 2490 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_quant8) { 2491 transposeConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2492 } 2493 2494 TEST(OperationValidationTest, TRANSPOSE_CONV_2D_quant8_per_channel) { 2495 transposeConvOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, 2496 ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL); 2497 } 2498 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 2509 TEST(OperationValidationTest, CHANNEL_SHUFFLE_float16) { 2510 channelShuffleOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2511 } 2512 2513 TEST(OperationValidationTest, CHANNEL_SHUFFLE_float32) { 2514 channelShuffleOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2515 } 2516 2517 TEST(OperationValidationTest, CHANNEL_SHUFFLE_quant8) { 2518 channelShuffleOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2519 } 2520 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 2564 TEST(OperationValidationTest, DETECTION_POSTPROCESSING) { 2565 detectionPostprocessingOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2566 detectionPostprocessingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2567 } 2568 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 2578 TEST(OperationValidationTest, PRELU_float16) { 2579 preluOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2580 } 2581 2582 TEST(OperationValidationTest, PRELU_float32) { 2583 preluOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2584 } 2585 2586 TEST(OperationValidationTest, PRELU_quant8) { 2587 preluOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2588 } 2589 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 2602 TEST(OperationValidationTest, L2_NORMALIZATION_float16) { 2603 normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_FLOAT16); 2604 } 2605 2606 TEST(OperationValidationTest, L2_NORMALIZATION_float32) { 2607 normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_FLOAT32); 2608 } 2609 2610 TEST(OperationValidationTest, L2_NORMALIZATION_quant8) { 2611 normalizationOpTest(ANEURALNETWORKS_L2_NORMALIZATION, ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2612 } 2613 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 2635 TEST(OperationValidationTest, LOCAL_RESPONSE_NORMALIZATION_float16) { 2636 localResponseNormOpTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2637 } 2638 2639 TEST(OperationValidationTest, LOCAL_RESPONSE_NORMALIZATION_float32) { 2640 localResponseNormOpTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2641 } 2642 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 2655 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_float16) { 2656 axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16); 2657 } 2658 2659 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_float32) { 2660 axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32); 2661 } 2662 2663 TEST(OperationValidationTest, AXIS_ALIGNED_BBOX_TRANSFORM_quant) { 2664 axisAlignedBBoxTransformOpTest(ANEURALNETWORKS_TENSOR_QUANT16_ASYMM, 2665 ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2666 } 2667 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 2682 TEST(OperationValidationTest, SLICE_float32) { 2683 sliceTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2684 } 2685 TEST(OperationValidationTest, SLICE_int32) { 2686 sliceTest(ANEURALNETWORKS_TENSOR_INT32); 2687 } 2688 TEST(OperationValidationTest, SLICE_uint8) { 2689 sliceTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM); 2690 } 2691 TEST(OperationValidationTest, SLICE_float16) { 2692 sliceTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2693 } 2694 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 2709 TEST(OperationValidationTest, LOGICAL_AND) { 2710 logicalTest(ANEURALNETWORKS_LOGICAL_AND); 2711 } 2712 2713 TEST(OperationValidationTest, LOGICAL_OR) { 2714 logicalTest(ANEURALNETWORKS_LOGICAL_OR); 2715 } 2716 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 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 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 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 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 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 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 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 2809 TEST(OperationValidationTest, REDUCE_PROD) { 2810 reduceOpTest(ANEURALNETWORKS_REDUCE_PROD, ANEURALNETWORKS_TENSOR_FLOAT16); 2811 reduceOpTest(ANEURALNETWORKS_REDUCE_PROD, ANEURALNETWORKS_TENSOR_FLOAT32); 2812 } 2813 2814 TEST(OperationValidationTest, REDUCE_SUM) { 2815 reduceOpTest(ANEURALNETWORKS_REDUCE_SUM, ANEURALNETWORKS_TENSOR_FLOAT16); 2816 reduceOpTest(ANEURALNETWORKS_REDUCE_SUM, ANEURALNETWORKS_TENSOR_FLOAT32); 2817 } 2818 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 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 2831 TEST(OperationValidationTest, REDUCE_ANY) { 2832 reduceOpTest(ANEURALNETWORKS_REDUCE_ANY, ANEURALNETWORKS_TENSOR_BOOL8); 2833 } 2834 2835 TEST(OperationValidationTest, REDUCE_ALL) { 2836 reduceOpTest(ANEURALNETWORKS_REDUCE_ALL, ANEURALNETWORKS_TENSOR_BOOL8); 2837 } 2838 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 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 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 2869 TEST(OperationValidationTest, POW) { 2870 powTest(ANEURALNETWORKS_TENSOR_FLOAT16); 2871 powTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2872 } 2873 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 2891 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_float16) { 2892 boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16, 2893 ANEURALNETWORKS_FLOAT16); 2894 } 2895 2896 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_float32) { 2897 boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32, 2898 ANEURALNETWORKS_FLOAT32); 2899 } 2900 2901 TEST(OperationValidationTest, BOX_WITH_NMS_LIMIT_quant) { 2902 boxWithNmsLimitOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_QUANT16_ASYMM, 2903 ANEURALNETWORKS_FLOAT32); 2904 } 2905 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 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 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 2994 TEST(OperationValidationTest, BIDIRECTIONAL_SEQUENCE_RNN_float32) { 2995 bidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT32); 2996 } 2997 2998 TEST(OperationValidationTest, BIDIRECTIONAL_SEQUENCE_RNN_float16) { 2999 bidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT16); 3000 } 3001 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 3059 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_RNN_float32) { 3060 unidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT32); 3061 } 3062 3063 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_RNN_float16) { 3064 unidirectionlSequenceRNNTest(ANEURALNETWORKS_TENSOR_FLOAT16); 3065 } 3066 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 3215 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_LSTM_float32) { 3216 unidirectionalSequenceLSTMTest(ANEURALNETWORKS_TENSOR_FLOAT32); 3217 } 3218 3219 TEST(OperationValidationTest, UNIDIRECTIONAL_SEQUENCE_LSTM_float16) { 3220 unidirectionalSequenceLSTMTest(ANEURALNETWORKS_TENSOR_FLOAT16); 3221 } 3222 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 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 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 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 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 3270 TEST(OperationValidationTest, RESIZE_NEAREST_NEIGHBOR) { 3271 resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_INT32); 3272 resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_FLOAT32); 3273 } 3274 3275 TEST(OperationValidationTest, RESIZE_NEAREST_NEIGHBOR_float16) { 3276 resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_INT32); 3277 resizeNearestNeighborTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_FLOAT16); 3278 } 3279 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