1 /* 2 * Copyright (C) 2019 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 "fuzzing/operation_signatures/OperationSignatureUtils.h" 18 19 namespace android { 20 namespace nn { 21 namespace fuzzing_test { 22 23 static void broadcastOpConstructor(Type dataType, uint32_t rank, RandomOperation* op) { 24 // TODO: All inputs of the broadcast op have the same rank 4 for now. 25 op->inputs[0]->dimensions.resize(rank); 26 op->inputs[1]->dimensions.resize(rank); 27 op->outputs[0]->dimensions.resize(rank); 28 for (uint32_t i = 0; i < rank; i++) { 29 if (getBernoulli(0.9f)) { 30 op->inputs[0]->dimensions[i] = RandomVariableType::FREE; 31 } else { 32 op->inputs[0]->dimensions[i] = 1; 33 } 34 if (getBernoulli(0.9f)) { 35 op->inputs[1]->dimensions[i] = op->inputs[0]->dimensions[i]; 36 } else { 37 op->inputs[1]->dimensions[i] = 1; 38 } 39 op->outputs[0]->dimensions[i] = 40 max(op->inputs[0]->dimensions[i], op->inputs[1]->dimensions[i]); 41 } 42 43 // MUL requires output.scale > input0.scale * input1.scale. 44 if (dataType == Type::TENSOR_QUANT8_ASYMM && op->opType == ANEURALNETWORKS_MUL) { 45 float minScale = op->inputs[0]->scale * op->inputs[1]->scale; 46 op->outputs[0]->scale = getUniform(minScale, minScale * 5); 47 } 48 49 // DIV and POW may produce Inf output values. We should not connect this output tensor to the 50 // input of another operation. 51 if (op->opType == ANEURALNETWORKS_DIV || op->opType == ANEURALNETWORKS_POW) { 52 op->outputs[0]->doNotConnect = true; 53 } 54 } 55 56 // For broadcast operations with fused activation. 57 #define DEFINE_BROADCAST_WITH_ACT_SIGNATURE(op, ver, ...) \ 58 DEFINE_OPERATION_SIGNATURE(op##_##ver){ \ 59 .opType = ANEURALNETWORKS_##op, \ 60 .supportedDataTypes = {__VA_ARGS__}, \ 61 .supportedRanks = {1, 2, 3, 4}, \ 62 .version = HalVersion::ver, \ 63 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, PARAMETER_CHOICE(Type::INT32, 0, 1, 2, 3)}, \ 64 .outputs = {OUTPUT_DEFAULT}, \ 65 .constructor = broadcastOpConstructor}; 66 67 // Arithmetic with activation. 68 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(ADD, V1_0, Type::TENSOR_FLOAT32, Type::TENSOR_QUANT8_ASYMM); 69 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(MUL, V1_0, Type::TENSOR_FLOAT32, Type::TENSOR_QUANT8_ASYMM); 70 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(SUB, V1_1, Type::TENSOR_FLOAT32); 71 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(DIV, V1_1, Type::TENSOR_FLOAT32); 72 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(ADD, V1_2, Type::TENSOR_FLOAT16); 73 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(MUL, V1_2, Type::TENSOR_FLOAT16); 74 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(SUB, V1_2, Type::TENSOR_FLOAT16, Type::TENSOR_QUANT8_ASYMM); 75 DEFINE_BROADCAST_WITH_ACT_SIGNATURE(DIV, V1_2, Type::TENSOR_FLOAT16); 76 77 // For broadcast ops with output of the same data type as inputs. 78 #define DEFINE_BROADCAST_SIGNATURE(op, ver, ...) \ 79 DEFINE_OPERATION_SIGNATURE(op##_##ver){.opType = ANEURALNETWORKS_##op, \ 80 .supportedDataTypes = {__VA_ARGS__}, \ 81 .supportedRanks = {1, 2, 3, 4, 5}, \ 82 .version = HalVersion::ver, \ 83 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT}, \ 84 .outputs = {OUTPUT_DEFAULT}, \ 85 .constructor = broadcastOpConstructor}; 86 87 // Arithmetic without activation. 88 DEFINE_BROADCAST_SIGNATURE(POW, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16); 89 DEFINE_BROADCAST_SIGNATURE(PRELU, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 90 Type::TENSOR_QUANT8_ASYMM); 91 DEFINE_BROADCAST_SIGNATURE(MAXIMUM, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 92 Type::TENSOR_QUANT8_ASYMM, Type::TENSOR_INT32); 93 DEFINE_BROADCAST_SIGNATURE(MINIMUM, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 94 Type::TENSOR_QUANT8_ASYMM, Type::TENSOR_INT32); 95 96 // Logical 97 DEFINE_BROADCAST_SIGNATURE(LOGICAL_AND, V1_2, Type::TENSOR_BOOL8); 98 DEFINE_BROADCAST_SIGNATURE(LOGICAL_OR, V1_2, Type::TENSOR_BOOL8); 99 100 // Comparisons 101 #define DEFINE_COMPARISON_SIGNATURE(op, ver, ...) \ 102 DEFINE_OPERATION_SIGNATURE(op##_##ver){.opType = ANEURALNETWORKS_##op, \ 103 .supportedDataTypes = {__VA_ARGS__}, \ 104 .supportedRanks = {1, 2, 3, 4}, \ 105 .version = HalVersion::ver, \ 106 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT}, \ 107 .outputs = {OUTPUT_TYPED(Type::TENSOR_BOOL8)}, \ 108 .constructor = broadcastOpConstructor}; 109 110 DEFINE_COMPARISON_SIGNATURE(EQUAL, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 111 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM, Type::TENSOR_BOOL8); 112 DEFINE_COMPARISON_SIGNATURE(GREATER, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 113 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM); 114 DEFINE_COMPARISON_SIGNATURE(GREATER_EQUAL, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 115 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM); 116 DEFINE_COMPARISON_SIGNATURE(LESS, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 117 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM); 118 DEFINE_COMPARISON_SIGNATURE(LESS_EQUAL, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 119 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM); 120 DEFINE_COMPARISON_SIGNATURE(NOT_EQUAL, V1_2, Type::TENSOR_FLOAT32, Type::TENSOR_FLOAT16, 121 Type::TENSOR_INT32, Type::TENSOR_QUANT8_ASYMM, Type::TENSOR_BOOL8); 122 123 } // namespace fuzzing_test 124 } // namespace nn 125 } // namespace android 126