• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
elementwiseOpConstructor(TestOperandType dataType,uint32_t rank,RandomOperation * op)23 static void elementwiseOpConstructor(TestOperandType dataType, uint32_t rank, RandomOperation* op) {
24     sameShapeOpConstructor(dataType, rank, op);
25 
26     switch (op->opType) {
27         case TestOperationType::RELU:
28         case TestOperationType::RELU6:
29             op->outputs[0]->valueProperties = RandomOperand::NON_NEGATIVE;
30             break;
31         case TestOperationType::LOGISTIC:
32             op->outputs[0]->valueProperties = RandomOperand::NON_ZERO | RandomOperand::NON_NEGATIVE;
33             break;
34         case TestOperationType::ABS:
35             op->outputs[0]->valueProperties = RandomOperand::NON_NEGATIVE;
36             break;
37         case TestOperationType::EXP:
38             op->outputs[0]->valueProperties = RandomOperand::NON_ZERO | RandomOperand::NON_NEGATIVE;
39             break;
40         case TestOperationType::LOG:
41             op->inputs[0]->valueProperties = RandomOperand::NON_ZERO | RandomOperand::NON_NEGATIVE;
42             break;
43         case TestOperationType::RSQRT:
44             op->inputs[0]->valueProperties = RandomOperand::NON_ZERO | RandomOperand::NON_NEGATIVE;
45             op->outputs[0]->valueProperties = RandomOperand::NON_ZERO | RandomOperand::NON_NEGATIVE;
46             break;
47         case TestOperationType::SQRT:
48             op->inputs[0]->valueProperties = RandomOperand::NON_NEGATIVE;
49             op->outputs[0]->valueProperties = RandomOperand::NON_NEGATIVE;
50             break;
51         default:
52             break;
53     }
54 }
55 
56 #define DEFINE_ELEMENTWISE_SIGNATURE(op, ver, ...)                              \
57     DEFINE_OPERATION_SIGNATURE(op##_##ver){.opType = TestOperationType::op,     \
58                                            .supportedDataTypes = {__VA_ARGS__}, \
59                                            .supportedRanks = {1, 2, 3, 4},      \
60                                            .version = TestHalVersion::ver,      \
61                                            .inputs = {INPUT_DEFAULT},           \
62                                            .outputs = {OUTPUT_DEFAULT},         \
63                                            .constructor = elementwiseOpConstructor};
64 
65 DEFINE_ELEMENTWISE_SIGNATURE(FLOOR, V1_0, TestOperandType::TENSOR_FLOAT32);
66 DEFINE_ELEMENTWISE_SIGNATURE(RELU, V1_0, TestOperandType::TENSOR_FLOAT32,
67                              TestOperandType::TENSOR_QUANT8_ASYMM);
68 DEFINE_ELEMENTWISE_SIGNATURE(RELU1, V1_0, TestOperandType::TENSOR_FLOAT32,
69                              TestOperandType::TENSOR_QUANT8_ASYMM);
70 DEFINE_ELEMENTWISE_SIGNATURE(RELU6, V1_0, TestOperandType::TENSOR_FLOAT32,
71                              TestOperandType::TENSOR_QUANT8_ASYMM);
72 DEFINE_ELEMENTWISE_SIGNATURE(TANH, V1_0, TestOperandType::TENSOR_FLOAT32);
73 DEFINE_ELEMENTWISE_SIGNATURE(FLOOR, V1_2, TestOperandType::TENSOR_FLOAT16);
74 DEFINE_ELEMENTWISE_SIGNATURE(LOGISTIC, V1_2, TestOperandType::TENSOR_FLOAT16);
75 DEFINE_ELEMENTWISE_SIGNATURE(RELU, V1_2, TestOperandType::TENSOR_FLOAT16);
76 DEFINE_ELEMENTWISE_SIGNATURE(RELU1, V1_2, TestOperandType::TENSOR_FLOAT16);
77 DEFINE_ELEMENTWISE_SIGNATURE(RELU6, V1_2, TestOperandType::TENSOR_FLOAT16);
78 DEFINE_ELEMENTWISE_SIGNATURE(RELU, V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
79 DEFINE_ELEMENTWISE_SIGNATURE(RELU1, V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
80 DEFINE_ELEMENTWISE_SIGNATURE(RELU6, V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
81 DEFINE_ELEMENTWISE_SIGNATURE(HARD_SWISH, V1_3, TestOperandType::TENSOR_FLOAT32,
82                              TestOperandType::TENSOR_FLOAT16, TestOperandType::TENSOR_QUANT8_ASYMM);
83 
84 #define DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(op, ver, ...)                   \
85     DEFINE_OPERATION_SIGNATURE(op##_##ver){.opType = TestOperationType::op,     \
86                                            .supportedDataTypes = {__VA_ARGS__}, \
87                                            .supportedRanks = {1, 2, 3, 4, 5},   \
88                                            .version = TestHalVersion::ver,      \
89                                            .inputs = {INPUT_DEFAULT},           \
90                                            .outputs = {OUTPUT_DEFAULT},         \
91                                            .constructor = elementwiseOpConstructor};
92 
93 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(ABS, V1_2, TestOperandType::TENSOR_FLOAT32,
94                                         TestOperandType::TENSOR_FLOAT16);
95 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(EXP, V1_2, TestOperandType::TENSOR_FLOAT32,
96                                         TestOperandType::TENSOR_FLOAT16);
97 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(NEG, V1_2, TestOperandType::TENSOR_FLOAT32,
98                                         TestOperandType::TENSOR_FLOAT16,
99                                         TestOperandType::TENSOR_INT32);
100 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(SIN, V1_2, TestOperandType::TENSOR_FLOAT32,
101                                         TestOperandType::TENSOR_FLOAT16);
102 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(LOGICAL_NOT, V1_2, TestOperandType::TENSOR_BOOL8);
103 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(ABS, V1_3, TestOperandType::TENSOR_INT32);
104 
105 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(LOG, V1_2, TestOperandType::TENSOR_FLOAT32,
106                                         TestOperandType::TENSOR_FLOAT16);
107 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(RSQRT, V1_2, TestOperandType::TENSOR_FLOAT32,
108                                         TestOperandType::TENSOR_FLOAT16);
109 DEFINE_ELEMENTWISE_SIGNATURE_WITH_RANK5(SQRT, V1_2, TestOperandType::TENSOR_FLOAT32,
110                                         TestOperandType::TENSOR_FLOAT16);
111 
112 // Quantized operations with special output quantization parameters.
113 #define DEFINE_ELEMENTWISE_WITH_QUANT_OUTPUT_SIGNATURE(op, ver, s, z, ...)      \
114     DEFINE_OPERATION_SIGNATURE(op##_##ver){.opType = TestOperationType::op,     \
115                                            .supportedDataTypes = {__VA_ARGS__}, \
116                                            .supportedRanks = {1, 2, 3, 4},      \
117                                            .version = TestHalVersion::ver,      \
118                                            .inputs = {INPUT_DEFAULT},           \
119                                            .outputs = {OUTPUT_QUANT((s), (z))}, \
120                                            .constructor = sameDimensionOpConstructor};
121 
122 DEFINE_ELEMENTWISE_WITH_QUANT_OUTPUT_SIGNATURE(LOGISTIC, V1_0, /*scale=*/1.f / 256, /*zeroPoint=*/0,
123                                                TestOperandType::TENSOR_FLOAT32,
124                                                TestOperandType::TENSOR_QUANT8_ASYMM);
125 DEFINE_ELEMENTWISE_WITH_QUANT_OUTPUT_SIGNATURE(TANH, V1_2, /*scale=*/1.f / 128, /*zeroPoint=*/128,
126                                                TestOperandType::TENSOR_FLOAT16,
127                                                TestOperandType::TENSOR_QUANT8_ASYMM);
128 DEFINE_ELEMENTWISE_WITH_QUANT_OUTPUT_SIGNATURE(LOGISTIC, V1_3, /*scale=*/1.f / 256,
129                                                /*zeroPoint=*/-128,
130                                                TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
131 DEFINE_ELEMENTWISE_WITH_QUANT_OUTPUT_SIGNATURE(TANH, V1_3, /*scale=*/1.f / 128, /*zeroPoint=*/0,
132                                                TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
133 
castingOpConstructor(TestOperandType dataType,uint32_t rank,RandomOperation * op)134 static void castingOpConstructor(TestOperandType dataType, uint32_t rank, RandomOperation* op) {
135     sameDimensionOpConstructor(dataType, rank, op);
136 
137     // If it is casting to/from a FP16 data type, the source/destination should have a scale
138     // representable in FP16 to avoid precision loss.
139     if (op->inputs[0]->dataType == TestOperandType::TENSOR_FLOAT16) {
140         op->outputs[0]->scale = static_cast<_Float16>(op->outputs[0]->scale);
141     } else if (op->outputs[0]->dataType == TestOperandType::TENSOR_FLOAT16) {
142         op->inputs[0]->scale = static_cast<_Float16>(op->inputs[0]->scale);
143     }
144 }
145 
146 // Operations with output data type different from input.
147 #define DEFINE_QUANTIZATION_OP_SIGNATURE(op, ver, outType, ...)  \
148     DEFINE_OPERATION_SIGNATURE(op##_##outType##_##ver){          \
149             .opType = TestOperationType::op,                     \
150             .supportedDataTypes = {__VA_ARGS__},                 \
151             .supportedRanks = {1, 2, 3, 4},                      \
152             .version = TestHalVersion::ver,                      \
153             .inputs = {INPUT_DEFAULT},                           \
154             .outputs = {OUTPUT_TYPED(TestOperandType::outType)}, \
155             .constructor = castingOpConstructor};
156 
157 DEFINE_QUANTIZATION_OP_SIGNATURE(DEQUANTIZE, V1_0, /*outType=*/TENSOR_FLOAT32,
158                                  TestOperandType::TENSOR_QUANT8_ASYMM);
159 
160 DEFINE_QUANTIZATION_OP_SIGNATURE(DEQUANTIZE, V1_2, /*outType=*/TENSOR_FLOAT32,
161                                  TestOperandType::TENSOR_QUANT8_SYMM);
162 
163 DEFINE_QUANTIZATION_OP_SIGNATURE(DEQUANTIZE, V1_2, /*outType=*/TENSOR_FLOAT16,
164                                  TestOperandType::TENSOR_QUANT8_ASYMM,
165                                  TestOperandType::TENSOR_QUANT8_SYMM);
166 
167 DEFINE_QUANTIZATION_OP_SIGNATURE(DEQUANTIZE, V1_3, /*outType=*/TENSOR_FLOAT32,
168                                  TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
169 
170 DEFINE_QUANTIZATION_OP_SIGNATURE(DEQUANTIZE, V1_3, /*outType=*/TENSOR_FLOAT16,
171                                  TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
172 
173 DEFINE_QUANTIZATION_OP_SIGNATURE(QUANTIZE, V1_2, /*outType=*/TENSOR_QUANT8_ASYMM,
174                                  TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16);
175 
176 DEFINE_QUANTIZATION_OP_SIGNATURE(QUANTIZE, V1_3,
177                                  /*outType=*/TENSOR_QUANT8_ASYMM_SIGNED,
178                                  TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16);
179 
180 #define DEFINE_CAST_SIGNATURE(ver, outType, ...)                 \
181     DEFINE_OPERATION_SIGNATURE(CAST_##outType##_##ver){          \
182             .opType = TestOperationType::CAST,                   \
183             .supportedDataTypes = {__VA_ARGS__},                 \
184             .supportedRanks = {1, 2, 3, 4, 5},                   \
185             .version = TestHalVersion::ver,                      \
186             .inputs = {INPUT_DEFAULT},                           \
187             .outputs = {OUTPUT_TYPED(TestOperandType::outType)}, \
188             .constructor = castingOpConstructor};
189 
190 DEFINE_CAST_SIGNATURE(V1_2, /*outType=*/TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT32,
191                       TestOperandType::TENSOR_FLOAT16, TestOperandType::TENSOR_QUANT8_ASYMM,
192                       TestOperandType::TENSOR_INT32);
193 
194 DEFINE_CAST_SIGNATURE(V1_2, /*outType=*/TENSOR_FLOAT16, TestOperandType::TENSOR_FLOAT32,
195                       TestOperandType::TENSOR_FLOAT16, TestOperandType::TENSOR_QUANT8_ASYMM,
196                       TestOperandType::TENSOR_INT32);
197 
198 DEFINE_CAST_SIGNATURE(V1_2, /*outType=*/TENSOR_QUANT8_ASYMM, TestOperandType::TENSOR_FLOAT32,
199                       TestOperandType::TENSOR_FLOAT16, TestOperandType::TENSOR_QUANT8_ASYMM,
200                       TestOperandType::TENSOR_INT32);
201 
202 DEFINE_CAST_SIGNATURE(V1_2, /*outType=*/TENSOR_INT32, TestOperandType::TENSOR_FLOAT32,
203                       TestOperandType::TENSOR_FLOAT16, TestOperandType::TENSOR_QUANT8_ASYMM,
204                       TestOperandType::TENSOR_INT32);
205 
206 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_BOOL8, TestOperandType::TENSOR_BOOL8);
207 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_INT32, TestOperandType::TENSOR_INT32);
208 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_QUANT16_ASYMM,
209                       TestOperandType::TENSOR_QUANT16_ASYMM);
210 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_QUANT16_SYMM, TestOperandType::TENSOR_QUANT16_SYMM);
211 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_QUANT8_ASYMM_SIGNED,
212                       TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
213 DEFINE_CAST_SIGNATURE(V1_3, /*outType=*/TENSOR_QUANT8_SYMM, TestOperandType::TENSOR_QUANT8_SYMM);
214 
DEFINE_OPERATION_SIGNATURE(ELU_V1_3)215 DEFINE_OPERATION_SIGNATURE(ELU_V1_3){
216         .opType = TestOperationType::ELU,
217         .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16},
218         .supportedRanks = {1, 2, 3, 4, 5},
219         .version = TestHalVersion::V1_3,
220         .inputs = {INPUT_DEFAULT, PARAMETER_FLOAT_RANGE(0.0f, 10.0f)},
221         .outputs = {OUTPUT_DEFAULT},
222         .constructor = sameDimensionOpConstructor};
223 
224 }  // namespace fuzzing_test
225 }  // namespace nn
226 }  // namespace android
227