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 using namespace std::placeholders;
20
21 namespace android {
22 namespace nn {
23 namespace fuzzing_test {
24
conv2DExplicitConstructor(TestOperandType,uint32_t rank,TestHalVersion ver,RandomOperation * op)25 static void conv2DExplicitConstructor(TestOperandType, uint32_t rank, TestHalVersion ver,
26 RandomOperation* op) {
27 NN_FUZZER_CHECK(rank == 4);
28
29 // Parameters
30 int32_t paddingLeft = op->inputs[3]->value<int32_t>();
31 int32_t paddingRight = op->inputs[4]->value<int32_t>();
32 int32_t paddingTop = op->inputs[5]->value<int32_t>();
33 int32_t paddingBottom = op->inputs[6]->value<int32_t>();
34 int32_t strideWidth = op->inputs[7]->value<int32_t>();
35 int32_t strideHeight = op->inputs[8]->value<int32_t>();
36 bool useNchw = false;
37 int32_t dilationWidth = 1, dilationHeight = 1;
38 if (op->inputs.size() > 10) {
39 useNchw = op->inputs[10]->value<bool8>();
40 if (op->inputs.size() > 11) {
41 dilationWidth = op->inputs[11]->value<int32_t>();
42 dilationHeight = op->inputs[12]->value<int32_t>();
43 }
44 }
45 int heightIndex = useNchw ? 2 : 1;
46 int widthIndex = useNchw ? 3 : 2;
47 int channelIndex = useNchw ? 1 : 3;
48
49 // Input, [batch, height_in, width_in, channel_in]
50 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
51 RandomVariableType::FREE, RandomVariableType::FREE};
52
53 // Filter, [channel_out, height_flt, width_flt, channel_in]
54 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
55 RandomVariableType::FREE, op->inputs[0]->dimensions[channelIndex]};
56
57 // Bias, [channel_out]
58 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
59
60 // Output, [batch, height_out, width_out, channel_out]
61 op->outputs[0]->dimensions.resize(4);
62
63 // batch and channel
64 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
65 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
66
67 // height
68 explicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
69 strideHeight, dilationHeight, paddingTop, paddingBottom,
70 &op->outputs[0]->dimensions[heightIndex]);
71
72 // width
73 explicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
74 strideWidth, dilationWidth, paddingLeft, paddingRight,
75 &op->outputs[0]->dimensions[widthIndex]);
76
77 setConvFCScale(/*applyOutputScaleBound=*/ver == TestHalVersion::V1_0, op);
78 }
79
conv2DImplicitConstructor(TestOperandType,uint32_t rank,TestHalVersion ver,RandomOperation * op)80 static void conv2DImplicitConstructor(TestOperandType, uint32_t rank, TestHalVersion ver,
81 RandomOperation* op) {
82 NN_FUZZER_CHECK(rank == 4);
83
84 // Parameters
85 int32_t paddingScheme = op->inputs[3]->value<int32_t>();
86 int32_t strideWidth = op->inputs[4]->value<int32_t>();
87 int32_t strideHeight = op->inputs[5]->value<int32_t>();
88 bool useNchw = false;
89 int32_t dilationWidth = 1, dilationHeight = 1;
90 if (op->inputs.size() > 7) {
91 useNchw = op->inputs[7]->value<bool8>();
92 if (op->inputs.size() > 8) {
93 dilationWidth = op->inputs[8]->value<int32_t>();
94 dilationHeight = op->inputs[9]->value<int32_t>();
95 }
96 }
97 int heightIndex = useNchw ? 2 : 1;
98 int widthIndex = useNchw ? 3 : 2;
99 int channelIndex = useNchw ? 1 : 3;
100
101 // Input, [batch, height_in, width_in, channel_in]
102 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
103 RandomVariableType::FREE, RandomVariableType::FREE};
104
105 // Filter, [channel_out, height_flt, width_flt, channel_in]
106 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
107 RandomVariableType::FREE, op->inputs[0]->dimensions[channelIndex]};
108
109 // Bias, [channel_out]
110 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
111
112 // Output, [batch, height_out, width_out, channel_out]
113 op->outputs[0]->dimensions.resize(4);
114
115 // batch and channel
116 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
117 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
118
119 // height and width
120 implicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
121 strideHeight, dilationHeight, paddingScheme,
122 &op->outputs[0]->dimensions[heightIndex]);
123 implicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
124 strideWidth, dilationWidth, paddingScheme,
125 &op->outputs[0]->dimensions[widthIndex]);
126
127 setConvFCScale(/*applyOutputScaleBound=*/ver == TestHalVersion::V1_0, op);
128 }
129
130 #define DEFINE_CONV_2D_SIGNATURE(ver, ...) \
131 DEFINE_OPERATION_SIGNATURE(CONV_2D_explicit_##ver){ \
132 .opType = TestOperationType::CONV_2D, \
133 .supportedDataTypes = {__VA_ARGS__}, \
134 .supportedRanks = {4}, \
135 .version = TestHalVersion::ver, \
136 .inputs = \
137 { \
138 INPUT_DEFAULT, \
139 INPUT_DEFAULT, \
140 INPUT_BIAS, \
141 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
142 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
143 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
144 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
145 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
146 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
147 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
148 }, \
149 .outputs = {OUTPUT_DEFAULT}, \
150 .constructor = std::bind(conv2DExplicitConstructor, _1, _2, TestHalVersion::ver, _3)}; \
151 DEFINE_OPERATION_SIGNATURE(CONV_2D_implicit_##ver){ \
152 .opType = TestOperationType::CONV_2D, \
153 .supportedDataTypes = {__VA_ARGS__}, \
154 .supportedRanks = {4}, \
155 .version = TestHalVersion::ver, \
156 .inputs = \
157 { \
158 INPUT_DEFAULT, \
159 INPUT_DEFAULT, \
160 INPUT_BIAS, \
161 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
162 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
163 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
164 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
165 }, \
166 .outputs = {OUTPUT_DEFAULT}, \
167 .constructor = std::bind(conv2DImplicitConstructor, _1, _2, TestHalVersion::ver, _3)};
168
169 DEFINE_CONV_2D_SIGNATURE(V1_0, TestOperandType::TENSOR_FLOAT32,
170 TestOperandType::TENSOR_QUANT8_ASYMM);
171 DEFINE_CONV_2D_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT16,
172 TestOperandType::TENSOR_QUANT8_ASYMM);
173 DEFINE_CONV_2D_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
174
175 #define DEFINE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(ver, ...) \
176 DEFINE_OPERATION_SIGNATURE(CONV_2D_explicit_layout_##ver){ \
177 .opType = TestOperationType::CONV_2D, \
178 .supportedDataTypes = {__VA_ARGS__}, \
179 .supportedRanks = {4}, \
180 .version = TestHalVersion::ver, \
181 .inputs = \
182 { \
183 INPUT_DEFAULT, \
184 INPUT_DEFAULT, \
185 INPUT_BIAS, \
186 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
187 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
188 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
189 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
190 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
191 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
192 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
193 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
194 }, \
195 .outputs = {OUTPUT_DEFAULT}, \
196 .constructor = std::bind(conv2DExplicitConstructor, _1, _2, TestHalVersion::ver, _3)}; \
197 DEFINE_OPERATION_SIGNATURE(CONV_2D_implicit_layout_##ver){ \
198 .opType = TestOperationType::CONV_2D, \
199 .supportedDataTypes = {__VA_ARGS__}, \
200 .supportedRanks = {4}, \
201 .version = TestHalVersion::ver, \
202 .inputs = \
203 { \
204 INPUT_DEFAULT, \
205 INPUT_DEFAULT, \
206 INPUT_BIAS, \
207 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
208 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
209 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
210 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
211 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
212 }, \
213 .outputs = {OUTPUT_DEFAULT}, \
214 .constructor = std::bind(conv2DImplicitConstructor, _1, _2, TestHalVersion::ver, _3)}; \
215 DEFINE_OPERATION_SIGNATURE(CONV_2D_explicit_dilation_##ver){ \
216 .opType = TestOperationType::CONV_2D, \
217 .supportedDataTypes = {__VA_ARGS__}, \
218 .supportedRanks = {4}, \
219 .version = TestHalVersion::ver, \
220 .inputs = \
221 { \
222 INPUT_DEFAULT, \
223 INPUT_DEFAULT, \
224 INPUT_BIAS, \
225 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
226 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
227 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
228 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
229 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
230 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
231 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
232 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
233 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
234 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
235 }, \
236 .outputs = {OUTPUT_DEFAULT}, \
237 .constructor = std::bind(conv2DExplicitConstructor, _1, _2, TestHalVersion::ver, _3)}; \
238 DEFINE_OPERATION_SIGNATURE(CONV_2D_implicit_dilation_##ver){ \
239 .opType = TestOperationType::CONV_2D, \
240 .supportedDataTypes = {__VA_ARGS__}, \
241 .supportedRanks = {4}, \
242 .version = TestHalVersion::ver, \
243 .inputs = \
244 { \
245 INPUT_DEFAULT, \
246 INPUT_DEFAULT, \
247 INPUT_BIAS, \
248 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
249 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
250 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
251 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
252 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
253 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
254 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
255 }, \
256 .outputs = {OUTPUT_DEFAULT}, \
257 .constructor = std::bind(conv2DImplicitConstructor, _1, _2, TestHalVersion::ver, _3)};
258
259 DEFINE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32,
260 TestOperandType::TENSOR_QUANT8_ASYMM,
261 TestOperandType::TENSOR_FLOAT16);
262 DEFINE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
263
depthwiseConv2DExplicitConstructor(TestOperandType,uint32_t rank,TestHalVersion ver,RandomOperation * op)264 static void depthwiseConv2DExplicitConstructor(TestOperandType, uint32_t rank, TestHalVersion ver,
265 RandomOperation* op) {
266 NN_FUZZER_CHECK(rank == 4);
267
268 // Parameters
269 int32_t paddingLeft = op->inputs[3]->value<int32_t>();
270 int32_t paddingRight = op->inputs[4]->value<int32_t>();
271 int32_t paddingTop = op->inputs[5]->value<int32_t>();
272 int32_t paddingBottom = op->inputs[6]->value<int32_t>();
273 int32_t strideWidth = op->inputs[7]->value<int32_t>();
274 int32_t strideHeight = op->inputs[8]->value<int32_t>();
275 bool useNchw = false;
276 int32_t dilationWidth = 1, dilationHeight = 1;
277 if (op->inputs.size() > 11) {
278 useNchw = op->inputs[11]->value<bool8>();
279 if (op->inputs.size() > 12) {
280 dilationWidth = op->inputs[12]->value<int32_t>();
281 dilationHeight = op->inputs[13]->value<int32_t>();
282 }
283 }
284 int heightIndex = useNchw ? 2 : 1;
285 int widthIndex = useNchw ? 3 : 2;
286 int channelIndex = useNchw ? 1 : 3;
287
288 // Input, [batch, height_in, width_in, channel_in]
289 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
290 RandomVariableType::FREE, RandomVariableType::FREE};
291
292 // Filter, [1, height_flt, width_flt, channel_out]
293 RandomVariable channelOut =
294 op->inputs[9]->value<RandomVariable>() * op->inputs[0]->dimensions[channelIndex];
295 op->inputs[1]->dimensions = {1, RandomVariableType::FREE, RandomVariableType::FREE, channelOut};
296
297 // Bias, [channel_out]
298 op->inputs[2]->dimensions = {channelOut};
299
300 // Output, [batch, height_out, width_out, channel_out]
301 op->outputs[0]->dimensions.resize(4);
302
303 // batch and channel
304 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
305 op->outputs[0]->dimensions[channelIndex] = channelOut;
306
307 // height
308 explicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
309 strideHeight, dilationHeight, paddingTop, paddingBottom,
310 &op->outputs[0]->dimensions[heightIndex]);
311
312 // width
313 explicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
314 strideWidth, dilationWidth, paddingLeft, paddingRight,
315 &op->outputs[0]->dimensions[widthIndex]);
316
317 setConvFCScale(/*applyOutputScaleBound=*/ver == TestHalVersion::V1_0, op);
318 }
319
depthwiseConv2DImplicitConstructor(TestOperandType,uint32_t rank,TestHalVersion ver,RandomOperation * op)320 static void depthwiseConv2DImplicitConstructor(TestOperandType, uint32_t rank, TestHalVersion ver,
321 RandomOperation* op) {
322 NN_FUZZER_CHECK(rank == 4);
323
324 // Parameters
325 int32_t paddingScheme = op->inputs[3]->value<int32_t>();
326 int32_t strideWidth = op->inputs[4]->value<int32_t>();
327 int32_t strideHeight = op->inputs[5]->value<int32_t>();
328 bool useNchw = false;
329 int32_t dilationWidth = 1, dilationHeight = 1;
330 if (op->inputs.size() > 8) {
331 useNchw = op->inputs[8]->value<bool8>();
332 if (op->inputs.size() > 9) {
333 dilationWidth = op->inputs[9]->value<int32_t>();
334 dilationHeight = op->inputs[10]->value<int32_t>();
335 }
336 }
337 int heightIndex = useNchw ? 2 : 1;
338 int widthIndex = useNchw ? 3 : 2;
339 int channelIndex = useNchw ? 1 : 3;
340
341 // Input, [batch, height_in, width_in, channel_in]
342 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
343 RandomVariableType::FREE, RandomVariableType::FREE};
344
345 // Filter, [1, height_flt, width_flt, channel_out]
346 RandomVariable channelOut =
347 op->inputs[6]->value<RandomVariable>() * op->inputs[0]->dimensions[channelIndex];
348 op->inputs[1]->dimensions = {1, RandomVariableType::FREE, RandomVariableType::FREE, channelOut};
349
350 // Bias, [channel_out]
351 op->inputs[2]->dimensions = {channelOut};
352
353 // Output, [batch, height_out, width_out, channel_out]
354 op->outputs[0]->dimensions.resize(4);
355
356 // batch and channel
357 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
358 op->outputs[0]->dimensions[channelIndex] = channelOut;
359
360 // height and width
361 implicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
362 strideHeight, dilationHeight, paddingScheme,
363 &op->outputs[0]->dimensions[heightIndex]);
364 implicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
365 strideWidth, dilationWidth, paddingScheme,
366 &op->outputs[0]->dimensions[widthIndex]);
367
368 setConvFCScale(/*applyOutputScaleBound=*/ver == TestHalVersion::V1_0, op);
369 }
370
371 #define DEFINE_DEPTHWISE_CONV_2D_SIGNATURE(ver, ...) \
372 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_explicit_##ver){ \
373 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
374 .supportedDataTypes = {__VA_ARGS__}, \
375 .supportedRanks = {4}, \
376 .version = TestHalVersion::ver, \
377 .inputs = \
378 { \
379 INPUT_DEFAULT, \
380 INPUT_DEFAULT, \
381 INPUT_BIAS, \
382 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
383 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
384 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
385 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
386 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
387 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
388 RANDOM_INT_RANGE(1, 5), \
389 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
390 }, \
391 .outputs = {OUTPUT_DEFAULT}, \
392 .constructor = std::bind(depthwiseConv2DExplicitConstructor, _1, _2, \
393 TestHalVersion::ver, _3)}; \
394 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_implicit_##ver){ \
395 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
396 .supportedDataTypes = {__VA_ARGS__}, \
397 .supportedRanks = {4}, \
398 .version = TestHalVersion::ver, \
399 .inputs = \
400 { \
401 INPUT_DEFAULT, \
402 INPUT_DEFAULT, \
403 INPUT_BIAS, \
404 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
405 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
406 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
407 RANDOM_INT_RANGE(1, 5), \
408 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
409 }, \
410 .outputs = {OUTPUT_DEFAULT}, \
411 .constructor = std::bind(depthwiseConv2DImplicitConstructor, _1, _2, \
412 TestHalVersion::ver, _3)};
413
414 DEFINE_DEPTHWISE_CONV_2D_SIGNATURE(V1_0, TestOperandType::TENSOR_FLOAT32,
415 TestOperandType::TENSOR_QUANT8_ASYMM);
416 DEFINE_DEPTHWISE_CONV_2D_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT16,
417 TestOperandType::TENSOR_QUANT8_ASYMM);
418 DEFINE_DEPTHWISE_CONV_2D_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
419
420 #define DEFINE_DEPTHWISE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(ver, ...) \
421 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_explicit_layout_##ver){ \
422 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
423 .supportedDataTypes = {__VA_ARGS__}, \
424 .supportedRanks = {4}, \
425 .version = TestHalVersion::ver, \
426 .inputs = \
427 { \
428 INPUT_DEFAULT, \
429 INPUT_DEFAULT, \
430 INPUT_BIAS, \
431 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
432 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
433 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
434 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
435 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
436 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
437 RANDOM_INT_RANGE(1, 5), \
438 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
439 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
440 }, \
441 .outputs = {OUTPUT_DEFAULT}, \
442 .constructor = std::bind(depthwiseConv2DExplicitConstructor, _1, _2, \
443 TestHalVersion::ver, _3)}; \
444 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_implicit_layout_##ver){ \
445 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
446 .supportedDataTypes = {__VA_ARGS__}, \
447 .supportedRanks = {4}, \
448 .version = TestHalVersion::ver, \
449 .inputs = \
450 { \
451 INPUT_DEFAULT, \
452 INPUT_DEFAULT, \
453 INPUT_BIAS, \
454 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
455 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
456 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
457 RANDOM_INT_RANGE(1, 5), \
458 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
459 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
460 }, \
461 .outputs = {OUTPUT_DEFAULT}, \
462 .constructor = std::bind(depthwiseConv2DImplicitConstructor, _1, _2, \
463 TestHalVersion::ver, _3)}; \
464 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_explicit_dilation_##ver){ \
465 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
466 .supportedDataTypes = {__VA_ARGS__}, \
467 .supportedRanks = {4}, \
468 .version = TestHalVersion::ver, \
469 .inputs = \
470 { \
471 INPUT_DEFAULT, \
472 INPUT_DEFAULT, \
473 INPUT_BIAS, \
474 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
475 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
476 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
477 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
478 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
479 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
480 RANDOM_INT_RANGE(1, 5), \
481 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
482 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
483 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
484 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
485 }, \
486 .outputs = {OUTPUT_DEFAULT}, \
487 .constructor = std::bind(depthwiseConv2DExplicitConstructor, _1, _2, \
488 TestHalVersion::ver, _3)}; \
489 DEFINE_OPERATION_SIGNATURE(DEPTHWISE_CONV_2D_implicit_dilation_##ver){ \
490 .opType = TestOperationType::DEPTHWISE_CONV_2D, \
491 .supportedDataTypes = {__VA_ARGS__}, \
492 .supportedRanks = {4}, \
493 .version = TestHalVersion::ver, \
494 .inputs = \
495 { \
496 INPUT_DEFAULT, \
497 INPUT_DEFAULT, \
498 INPUT_BIAS, \
499 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
500 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
501 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
502 RANDOM_INT_RANGE(1, 5), \
503 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
504 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
505 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
506 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
507 }, \
508 .outputs = {OUTPUT_DEFAULT}, \
509 .constructor = std::bind(depthwiseConv2DImplicitConstructor, _1, _2, \
510 TestHalVersion::ver, _3)};
511
512 DEFINE_DEPTHWISE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32,
513 TestOperandType::TENSOR_QUANT8_ASYMM,
514 TestOperandType::TENSOR_FLOAT16);
515 DEFINE_DEPTHWISE_CONV_2D_WITH_LAYOUT_OR_DILATION_SIGNATURE(
516 V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
517
groupedConv2DExplicitConstructor(TestOperandType,uint32_t rank,RandomOperation * op)518 static void groupedConv2DExplicitConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
519 NN_FUZZER_CHECK(rank == 4);
520
521 // Parameters
522 int32_t paddingLeft = op->inputs[3]->value<int32_t>();
523 int32_t paddingRight = op->inputs[4]->value<int32_t>();
524 int32_t paddingTop = op->inputs[5]->value<int32_t>();
525 int32_t paddingBottom = op->inputs[6]->value<int32_t>();
526 int32_t strideWidth = op->inputs[7]->value<int32_t>();
527 int32_t strideHeight = op->inputs[8]->value<int32_t>();
528 bool useNchw = op->inputs[11]->value<bool8>();
529 int heightIndex = useNchw ? 2 : 1;
530 int widthIndex = useNchw ? 3 : 2;
531 int channelIndex = useNchw ? 1 : 3;
532
533 // Input, [batch, height_in, width_in, channel_in]
534 RandomVariable numGroups = op->inputs[9]->value<RandomVariable>();
535 RandomVariable channelGroup = RandomVariableType::FREE;
536 if (useNchw) {
537 op->inputs[0]->dimensions = {RandomVariableType::FREE, numGroups * channelGroup,
538 RandomVariableType::FREE, RandomVariableType::FREE};
539 } else {
540 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
541 RandomVariableType::FREE, numGroups * channelGroup};
542 }
543
544 // Filter, [channel_out, height_flt, width_flt, channel_group]
545 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
546 RandomVariableType::FREE, channelGroup};
547 // channel_out must be divisible by num_groups.
548 (op->inputs[1]->dimensions[0] % numGroups).setEqual(0);
549
550 // Bias, [channel_out]
551 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
552
553 // Output, [batch, height_out, width_out, channel_out]
554 op->outputs[0]->dimensions.resize(4);
555
556 // batch and channel
557 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
558 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
559
560 // height
561 explicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
562 strideHeight, /*dilation=*/1, paddingTop, paddingBottom,
563 &op->outputs[0]->dimensions[heightIndex]);
564
565 // width
566 explicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
567 strideWidth, /*dilation=*/1, paddingLeft, paddingRight,
568 &op->outputs[0]->dimensions[widthIndex]);
569
570 setConvFCScale(/*applyOutputScaleBound=*/false, op);
571 }
572
groupedConv2DImplicitConstructor(TestOperandType,uint32_t rank,RandomOperation * op)573 static void groupedConv2DImplicitConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
574 NN_FUZZER_CHECK(rank == 4);
575
576 // Parameters
577 int32_t paddingScheme = op->inputs[3]->value<int32_t>();
578 int32_t strideWidth = op->inputs[4]->value<int32_t>();
579 int32_t strideHeight = op->inputs[5]->value<int32_t>();
580 bool useNchw = op->inputs[8]->value<bool8>();
581 int heightIndex = useNchw ? 2 : 1;
582 int widthIndex = useNchw ? 3 : 2;
583 int channelIndex = useNchw ? 1 : 3;
584
585 // Input, [batch, height_in, width_in, channel_in]
586 RandomVariable numGroups = op->inputs[6]->value<RandomVariable>();
587 RandomVariable channelGroup = RandomVariableType::FREE;
588 if (useNchw) {
589 op->inputs[0]->dimensions = {RandomVariableType::FREE, numGroups * channelGroup,
590 RandomVariableType::FREE, RandomVariableType::FREE};
591 } else {
592 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
593 RandomVariableType::FREE, numGroups * channelGroup};
594 }
595
596 // Filter, [channel_out, height_flt, width_flt, channel_group]
597 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
598 RandomVariableType::FREE, channelGroup};
599 // channel_out must be divisible by num_groups.
600 (op->inputs[1]->dimensions[0] % numGroups).setEqual(0);
601
602 // Bias, [channel_out]
603 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
604
605 // Output, [batch, height_out, width_out, channel_out]
606 op->outputs[0]->dimensions.resize(4);
607
608 // batch and channel
609 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
610 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
611
612 // height and width
613 implicitPadding(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
614 strideHeight, /*dilation=*/1, paddingScheme,
615 &op->outputs[0]->dimensions[heightIndex]);
616 implicitPadding(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
617 strideWidth, /*dilation=*/1, paddingScheme,
618 &op->outputs[0]->dimensions[widthIndex]);
619
620 setConvFCScale(/*applyOutputScaleBound=*/false, op);
621 }
622
623 #define DEFINE_GROUPED_CONV_2D_SIGNATURE(ver, ...) \
624 DEFINE_OPERATION_SIGNATURE(GROUPED_CONV_2D_explicit_##ver){ \
625 .opType = TestOperationType::GROUPED_CONV_2D, \
626 .supportedDataTypes = {__VA_ARGS__}, \
627 .supportedRanks = {4}, \
628 .version = TestHalVersion::ver, \
629 .inputs = \
630 { \
631 INPUT_DEFAULT, \
632 INPUT_DEFAULT, \
633 INPUT_BIAS, \
634 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
635 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
636 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
637 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
638 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
639 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
640 RANDOM_INT_RANGE(1, 5), \
641 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
642 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
643 }, \
644 .outputs = {OUTPUT_DEFAULT}, \
645 .constructor = groupedConv2DExplicitConstructor}; \
646 DEFINE_OPERATION_SIGNATURE(GROUPED_CONV_2D_implicit_##ver){ \
647 .opType = TestOperationType::GROUPED_CONV_2D, \
648 .supportedDataTypes = {__VA_ARGS__}, \
649 .supportedRanks = {4}, \
650 .version = TestHalVersion::ver, \
651 .inputs = \
652 { \
653 INPUT_DEFAULT, \
654 INPUT_DEFAULT, \
655 INPUT_BIAS, \
656 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
657 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
658 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
659 RANDOM_INT_RANGE(1, 5), \
660 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
661 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
662 }, \
663 .outputs = {OUTPUT_DEFAULT}, \
664 .constructor = groupedConv2DImplicitConstructor};
665
666 DEFINE_GROUPED_CONV_2D_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32,
667 TestOperandType::TENSOR_QUANT8_ASYMM,
668 TestOperandType::TENSOR_FLOAT16);
669 DEFINE_GROUPED_CONV_2D_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
670
transposeConv2DExplicitConstructor(TestOperandType,uint32_t rank,RandomOperation * op)671 static void transposeConv2DExplicitConstructor(TestOperandType, uint32_t rank,
672 RandomOperation* op) {
673 NN_FUZZER_CHECK(rank == 4);
674
675 // Parameters
676 int32_t paddingLeft = op->inputs[3]->value<int32_t>();
677 int32_t paddingRight = op->inputs[4]->value<int32_t>();
678 int32_t paddingTop = op->inputs[5]->value<int32_t>();
679 int32_t paddingBottom = op->inputs[6]->value<int32_t>();
680 int32_t strideWidth = op->inputs[7]->value<int32_t>();
681 int32_t strideHeight = op->inputs[8]->value<int32_t>();
682 bool useNchw = op->inputs[10]->value<bool8>();
683 int heightIndex = useNchw ? 2 : 1;
684 int widthIndex = useNchw ? 3 : 2;
685 int channelIndex = useNchw ? 1 : 3;
686
687 // Input, [batch, height_in, width_in, channel_in]
688 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
689 RandomVariableType::FREE, RandomVariableType::FREE};
690
691 // Filter, [channel_out, height_flt, width_flt, channel_in]
692 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
693 RandomVariableType::FREE, op->inputs[0]->dimensions[channelIndex]};
694
695 // Bias, [channel_out]
696 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
697
698 // Output, [batch, height_out, width_out, channel_out]
699 op->outputs[0]->dimensions.resize(4);
700
701 // batch and channel
702 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
703 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
704
705 // height
706 explicitPaddingTranspose(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
707 strideHeight, paddingTop, paddingBottom,
708 &op->outputs[0]->dimensions[heightIndex]);
709
710 // width
711 explicitPaddingTranspose(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
712 strideWidth, paddingLeft, paddingRight,
713 &op->outputs[0]->dimensions[widthIndex]);
714
715 setConvFCScale(/*applyOutputScaleBound=*/false, op);
716 }
717
transposeConv2DImplicitConstructor(TestOperandType,uint32_t rank,RandomOperation * op)718 static void transposeConv2DImplicitConstructor(TestOperandType, uint32_t rank,
719 RandomOperation* op) {
720 NN_FUZZER_CHECK(rank == 4);
721
722 // Parameters
723 int32_t paddingScheme = op->inputs[4]->value<int32_t>();
724 int32_t strideWidth = op->inputs[5]->value<int32_t>();
725 int32_t strideHeight = op->inputs[6]->value<int32_t>();
726 bool useNchw = op->inputs[8]->value<bool8>();
727 int heightIndex = useNchw ? 2 : 1;
728 int widthIndex = useNchw ? 3 : 2;
729 int channelIndex = useNchw ? 1 : 3;
730
731 // Input, [batch, height_in, width_in, channel_in]
732 op->inputs[0]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
733 RandomVariableType::FREE, RandomVariableType::FREE};
734
735 // Filter, [channel_out, height_flt, width_flt, channel_in]
736 op->inputs[1]->dimensions = {RandomVariableType::FREE, RandomVariableType::FREE,
737 RandomVariableType::FREE, op->inputs[0]->dimensions[channelIndex]};
738
739 // Bias, [channel_out]
740 op->inputs[2]->dimensions = {op->inputs[1]->dimensions[0]};
741
742 // Output, [batch, height_out, width_out, channel_out]
743 op->outputs[0]->dimensions.resize(4);
744
745 // batch and channel
746 op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
747 op->outputs[0]->dimensions[channelIndex] = op->inputs[1]->dimensions[0];
748
749 // height and width
750 implicitPaddingTranspose(op->inputs[0]->dimensions[heightIndex], op->inputs[1]->dimensions[1],
751 strideHeight, paddingScheme, &op->outputs[0]->dimensions[heightIndex]);
752 implicitPaddingTranspose(op->inputs[0]->dimensions[widthIndex], op->inputs[1]->dimensions[2],
753 strideWidth, paddingScheme, &op->outputs[0]->dimensions[widthIndex]);
754 op->inputs[3]->dimensions = {4};
755 op->inputs[3]->randomBuffer = op->outputs[0]->dimensions;
756
757 setConvFCScale(/*applyOutputScaleBound=*/false, op);
758 }
759
760 #define DEFINE_TRANSPOSE_CONV_2D_SIGNATURE(ver, ...) \
761 DEFINE_OPERATION_SIGNATURE(TRANSPOSE_CONV_2D_explicit_##ver){ \
762 .opType = TestOperationType::TRANSPOSE_CONV_2D, \
763 .supportedDataTypes = {__VA_ARGS__}, \
764 .supportedRanks = {4}, \
765 .version = TestHalVersion::ver, \
766 .inputs = \
767 { \
768 INPUT_DEFAULT, \
769 INPUT_DEFAULT, \
770 INPUT_BIAS, \
771 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
772 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
773 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
774 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
775 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
776 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
777 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
778 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
779 }, \
780 .outputs = {OUTPUT_DEFAULT}, \
781 .constructor = transposeConv2DExplicitConstructor}; \
782 DEFINE_OPERATION_SIGNATURE(TRANSPOSE_CONV_2D_implicit_##ver){ \
783 .opType = TestOperationType::TRANSPOSE_CONV_2D, \
784 .supportedDataTypes = {__VA_ARGS__}, \
785 .supportedRanks = {4}, \
786 .version = TestHalVersion::ver, \
787 .inputs = \
788 { \
789 INPUT_DEFAULT, \
790 INPUT_DEFAULT, \
791 INPUT_BIAS, \
792 PARAMETER_NONE(TestOperandType::TENSOR_INT32), \
793 PARAMETER_CHOICE(TestOperandType::INT32, 1, 2), \
794 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
795 PARAMETER_RANGE(TestOperandType::INT32, 1, 3), \
796 PARAMETER_CHOICE(TestOperandType::INT32, 0, 1, 2, 3), \
797 PARAMETER_CHOICE(TestOperandType::BOOL, true, false), \
798 }, \
799 .outputs = {OUTPUT_DEFAULT}, \
800 .constructor = transposeConv2DImplicitConstructor};
801
802 DEFINE_TRANSPOSE_CONV_2D_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32,
803 TestOperandType::TENSOR_QUANT8_ASYMM,
804 TestOperandType::TENSOR_FLOAT16);
805 DEFINE_TRANSPOSE_CONV_2D_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
806
807 } // namespace fuzzing_test
808 } // namespace nn
809 } // namespace android
810