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 // CONCATENATION with fixed number of input tensors.
concatConstructor(uint32_t numInputs,bool isV1_0,uint32_t rank,RandomOperation * op)24 static void concatConstructor(uint32_t numInputs, bool isV1_0, uint32_t rank, RandomOperation* op) {
25 for (uint32_t i = 0; i < numInputs; i++) {
26 op->inputs[i]->dimensions.resize(rank);
27 if (isV1_0) setSameQuantization(op->inputs[i], op->inputs[0]);
28 }
29 op->outputs[0]->dimensions.resize(rank);
30
31 int32_t axis = getUniform<int32_t>(0, rank - 1);
32 op->inputs[numInputs]->setScalarValue<int32_t>(axis);
33 for (uint32_t i = 0; i < rank; i++) {
34 op->inputs[0]->dimensions[i] = RandomVariableType::FREE;
35 op->outputs[0]->dimensions[i] = op->inputs[0]->dimensions[i];
36 for (uint32_t j = 1; j < numInputs; j++) {
37 if (axis == static_cast<int32_t>(i)) {
38 op->inputs[j]->dimensions[i] = RandomVariableType::FREE;
39 op->outputs[0]->dimensions[i] =
40 op->outputs[0]->dimensions[i] + op->inputs[j]->dimensions[i];
41 } else {
42 op->inputs[j]->dimensions[i] = op->inputs[0]->dimensions[i];
43 }
44 }
45 }
46 }
47
DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_0)48 DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_0){
49 .opType = TestOperationType::CONCATENATION,
50 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32,
51 TestOperandType::TENSOR_QUANT8_ASYMM},
52 .supportedRanks = {1, 2, 3, 4},
53 .version = TestHalVersion::V1_0,
54 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32)},
55 .outputs = {OUTPUT_DEFAULT},
56 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
57 concatConstructor(/*numInputs=*/2, /*isV1_0=*/true, rank, op);
58 }};
59
DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_0)60 DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_0){
61 .opType = TestOperationType::CONCATENATION,
62 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32,
63 TestOperandType::TENSOR_QUANT8_ASYMM},
64 .supportedRanks = {1, 2, 3, 4},
65 .version = TestHalVersion::V1_0,
66 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, INPUT_DEFAULT,
67 PARAMETER_NONE(TestOperandType::INT32)},
68 .outputs = {OUTPUT_DEFAULT},
69 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
70 concatConstructor(/*numInputs=*/3, /*isV1_0=*/true, rank, op);
71 }};
72
DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_2)73 DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_2){
74 .opType = TestOperationType::CONCATENATION,
75 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT16,
76 TestOperandType::TENSOR_QUANT8_ASYMM},
77 .supportedRanks = {1, 2, 3, 4},
78 .version = TestHalVersion::V1_2,
79 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32)},
80 .outputs = {OUTPUT_DEFAULT},
81 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
82 concatConstructor(/*numInputs=*/2, /*isV1_0=*/false, rank, op);
83 }};
84
DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_2)85 DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_2){
86 .opType = TestOperationType::CONCATENATION,
87 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT16,
88 TestOperandType::TENSOR_QUANT8_ASYMM},
89 .supportedRanks = {1, 2, 3, 4},
90 .version = TestHalVersion::V1_2,
91 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, INPUT_DEFAULT,
92 PARAMETER_NONE(TestOperandType::INT32)},
93 .outputs = {OUTPUT_DEFAULT},
94 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
95 concatConstructor(/*numInputs=*/3, /*isV1_0=*/false, rank, op);
96 }};
97
DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_3)98 DEFINE_OPERATION_SIGNATURE(CONCAT_2_V1_3){
99 .opType = TestOperationType::CONCATENATION,
100 .supportedDataTypes = {TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED},
101 .supportedRanks = {1, 2, 3, 4},
102 .version = TestHalVersion::V1_3,
103 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32)},
104 .outputs = {OUTPUT_DEFAULT},
105 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
106 concatConstructor(/*numInputs=*/2, /*isV1_0=*/false, rank, op);
107 }};
108
DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_3)109 DEFINE_OPERATION_SIGNATURE(CONCAT_3_V1_3){
110 .opType = TestOperationType::CONCATENATION,
111 .supportedDataTypes = {TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED},
112 .supportedRanks = {1, 2, 3, 4},
113 .version = TestHalVersion::V1_3,
114 .inputs = {INPUT_DEFAULT, INPUT_DEFAULT, INPUT_DEFAULT,
115 PARAMETER_NONE(TestOperandType::INT32)},
116 .outputs = {OUTPUT_DEFAULT},
117 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
118 concatConstructor(/*numInputs=*/3, /*isV1_0=*/false, rank, op);
119 }};
120
121 // SPLIT with fixed number of splits.
splitConstructor(uint32_t numSplits,uint32_t rank,RandomOperation * op)122 static void splitConstructor(uint32_t numSplits, uint32_t rank, RandomOperation* op) {
123 int32_t axis = getUniform<int32_t>(-rank, rank - 1);
124 op->inputs[1]->setScalarValue<int32_t>(axis);
125 if (axis < 0) axis += rank;
126
127 op->inputs[0]->dimensions.resize(rank);
128 for (uint32_t i = 0; i < numSplits; i++) {
129 op->outputs[i]->dimensions.resize(rank);
130 setSameQuantization(op->outputs[i], op->inputs[0]);
131 }
132
133 for (uint32_t i = 0; i < rank; i++) {
134 op->inputs[0]->dimensions[i] = RandomVariableType::FREE;
135 RandomVariable outDim;
136 if (axis == static_cast<int32_t>(i)) {
137 outDim = op->inputs[0]->dimensions[i].exactDiv(numSplits);
138 } else {
139 outDim = op->inputs[0]->dimensions[i];
140 }
141 for (uint32_t j = 0; j < numSplits; j++) op->outputs[j]->dimensions[i] = outDim;
142 }
143 }
144
DEFINE_OPERATION_SIGNATURE(SPLIT_2_V1_2)145 DEFINE_OPERATION_SIGNATURE(SPLIT_2_V1_2){
146 .opType = TestOperationType::SPLIT,
147 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
148 TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM},
149 .supportedRanks = {1, 2, 3, 4},
150 .version = TestHalVersion::V1_2,
151 .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32),
152 PARAMETER_CHOICE(TestOperandType::INT32, 2)},
153 .outputs = {OUTPUT_DEFAULT, OUTPUT_DEFAULT},
154 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
155 splitConstructor(/*numSplits=*/2, rank, op);
156 }};
157
DEFINE_OPERATION_SIGNATURE(SPLIT_3_V1_2)158 DEFINE_OPERATION_SIGNATURE(SPLIT_3_V1_2){
159 .opType = TestOperationType::SPLIT,
160 .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
161 TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM},
162 .supportedRanks = {1, 2, 3, 4},
163 .version = TestHalVersion::V1_2,
164 .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32),
165 PARAMETER_CHOICE(TestOperandType::INT32, 3)},
166 .outputs = {OUTPUT_DEFAULT, OUTPUT_DEFAULT, OUTPUT_DEFAULT},
167 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
168 splitConstructor(/*numSplits=*/3, rank, op);
169 }};
170
DEFINE_OPERATION_SIGNATURE(SPLIT_2_V1_3)171 DEFINE_OPERATION_SIGNATURE(SPLIT_2_V1_3){
172 .opType = TestOperationType::SPLIT,
173 .supportedDataTypes = {TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED},
174 .supportedRanks = {1, 2, 3, 4},
175 .version = TestHalVersion::V1_3,
176 .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32),
177 PARAMETER_CHOICE(TestOperandType::INT32, 2)},
178 .outputs = {OUTPUT_DEFAULT, OUTPUT_DEFAULT},
179 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
180 splitConstructor(/*numSplits=*/2, rank, op);
181 }};
182
DEFINE_OPERATION_SIGNATURE(SPLIT_3_V1_3)183 DEFINE_OPERATION_SIGNATURE(SPLIT_3_V1_3){
184 .opType = TestOperationType::SPLIT,
185 .supportedDataTypes = {TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED},
186 .supportedRanks = {1, 2, 3, 4},
187 .version = TestHalVersion::V1_3,
188 .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32),
189 PARAMETER_CHOICE(TestOperandType::INT32, 3)},
190 .outputs = {OUTPUT_DEFAULT, OUTPUT_DEFAULT, OUTPUT_DEFAULT},
191 .constructor = [](TestOperandType, uint32_t rank, RandomOperation* op) {
192 splitConstructor(/*numSplits=*/3, rank, op);
193 }};
194
195 } // namespace fuzzing_test
196 } // namespace nn
197 } // namespace android
198