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 <algorithm>
18 #include <utility>
19 #include <vector>
20 
21 #include "fuzzing/operation_signatures/OperationSignatureUtils.h"
22 
23 namespace android {
24 namespace nn {
25 namespace fuzzing_test {
26 
embeddingLookupConstructor(TestOperandType,uint32_t rank,RandomOperation * op)27 static void embeddingLookupConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
28     setFreeDimensions(op->inputs[0], /*rank=*/1);
29     setFreeDimensions(op->inputs[1], rank);
30     op->outputs[0]->dimensions.resize(rank);
31     op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
32     for (uint32_t i = 1; i < rank; i++) {
33         op->outputs[0]->dimensions[i] = op->inputs[1]->dimensions[i];
34     }
35     setSameQuantization(op->outputs[0], op->inputs[1]);
36 }
37 
embeddingLookupFinalizer(RandomOperation * op)38 static void embeddingLookupFinalizer(RandomOperation* op) {
39     uint32_t dimValue = op->inputs[1]->dimensions[0].getValue();
40     uint32_t numElements = op->inputs[0]->getNumberOfElements();
41     for (uint32_t i = 0; i < numElements; i++) {
42         // The index values must be in the range of [0, input1_dim0).
43         op->inputs[0]->value<int32_t>(i) = getUniform<int32_t>(0, dimValue - 1);
44     }
45 }
46 
47 #define DEFINE_EMBEDDING_LOOKUP_SIGNATURE(ver, ...)                                   \
48     DEFINE_OPERATION_SIGNATURE(EMBEDDING_LOOKUP_##ver){                               \
49             .opType = TestOperationType::EMBEDDING_LOOKUP,                            \
50             .supportedDataTypes = {__VA_ARGS__},                                      \
51             .supportedRanks = {2, 3, 4},                                              \
52             .version = TestHalVersion::ver,                                           \
53             .inputs = {PARAMETER_NONE(TestOperandType::TENSOR_INT32), INPUT_DEFAULT}, \
54             .outputs = {OUTPUT_DEFAULT},                                              \
55             .constructor = embeddingLookupConstructor,                                \
56             .finalizer = embeddingLookupFinalizer};
57 
58 DEFINE_EMBEDDING_LOOKUP_SIGNATURE(V1_0, TestOperandType::TENSOR_FLOAT32);
59 DEFINE_EMBEDDING_LOOKUP_SIGNATURE(V1_2, TestOperandType::TENSOR_INT32,
60                                   TestOperandType::TENSOR_QUANT8_ASYMM);
61 DEFINE_EMBEDDING_LOOKUP_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
62                                   TestOperandType::TENSOR_FLOAT16);
63 
hashtableLookupConstructor(TestOperandType,uint32_t rank,RandomOperation * op)64 static void hashtableLookupConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
65     op->inputs[0]->dimensions = {RandomVariableType::FREE};
66     op->inputs[1]->dimensions = {RandomVariableType::FREE};
67     op->inputs[2]->dimensions.resize(rank);
68     op->outputs[0]->dimensions.resize(rank);
69     op->inputs[2]->dimensions[0] = op->inputs[1]->dimensions[0];
70     op->outputs[0]->dimensions[0] = op->inputs[0]->dimensions[0];
71     for (uint32_t i = 1; i < rank; i++) {
72         op->inputs[2]->dimensions[i] = RandomVariableType::FREE;
73         op->outputs[0]->dimensions[i] = op->inputs[2]->dimensions[i];
74     }
75     setSameQuantization(op->outputs[0], op->inputs[2]);
76     op->outputs[1]->dimensions = {op->inputs[0]->dimensions[0]};
77 }
78 
hashtableLookupFinalizer(RandomOperation * op)79 static void hashtableLookupFinalizer(RandomOperation* op) {
80     // Generate values for keys. The keys tensor must be sorted in ascending order.
81     uint32_t n = op->inputs[1]->getNumberOfElements();
82     int32_t val = 0;
83     for (uint32_t i = 0; i < n; i++) {
84         op->inputs[1]->value<int32_t>(i) = val;
85         val += getUniform<int32_t>(1, 2);
86     }
87     // Generate values for lookups.
88     uint32_t k = op->inputs[0]->getNumberOfElements();
89     for (uint32_t i = 0; i < k; i++) {
90         op->inputs[0]->value<int32_t>(i) = getUniform<int32_t>(0, val);
91     }
92 }
93 
94 // The hits tensor in HASHTABLE_LOOKUP.
95 static const OperandSignature hitsTensor_HASHTABLE_LOOKUP = {
96         .type = RandomOperandType::OUTPUT,
__anonbfbd3ebb0102() 97         .constructor = [](TestOperandType, uint32_t, RandomOperand* op) {
98             op->dataType = TestOperandType::TENSOR_QUANT8_ASYMM;
99             op->scale = 1.0f;
100             op->zeroPoint = 0;
101         }};
102 
DEFINE_OPERATION_SIGNATURE(HASHTABLE_LOOKUP_V1_0)103 DEFINE_OPERATION_SIGNATURE(HASHTABLE_LOOKUP_V1_0){
104         .opType = TestOperationType::HASHTABLE_LOOKUP,
105         .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_INT32,
106                                TestOperandType::TENSOR_QUANT8_ASYMM},
107         .supportedRanks = {2, 3, 4},
108         .version = TestHalVersion::V1_0,
109         .inputs = {PARAMETER_NONE(TestOperandType::TENSOR_INT32),
110                    PARAMETER_NONE(TestOperandType::TENSOR_INT32), INPUT_DEFAULT},
111         .outputs = {OUTPUT_DEFAULT, hitsTensor_HASHTABLE_LOOKUP},
112         .constructor = hashtableLookupConstructor,
113         .finalizer = hashtableLookupFinalizer};
114 
gatherConstructor(TestOperandType,uint32_t rank,RandomOperation * op)115 static void gatherConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
116     // Generate value for "axis" scalar.
117     int32_t axis = getUniform<int32_t>(-rank, rank - 1);
118     op->inputs[1]->setScalarValue<int32_t>(axis);
119     if (axis < 0) axis += rank;
120 
121     // Set dimensions for input and indices tensor.
122     uint32_t indRank = getUniform<uint32_t>(1, 5);
123     setFreeDimensions(op->inputs[0], rank);
124     setFreeDimensions(op->inputs[2], indRank);
125 
126     for (uint32_t i = 0; i < static_cast<uint32_t>(axis); i++) {
127         op->outputs[0]->dimensions.push_back(op->inputs[0]->dimensions[i]);
128     }
129     for (uint32_t i = 0; i < indRank; i++) {
130         op->outputs[0]->dimensions.push_back(op->inputs[2]->dimensions[i]);
131     }
132     for (uint32_t i = axis + 1; i < rank; i++) {
133         op->outputs[0]->dimensions.push_back(op->inputs[0]->dimensions[i]);
134     }
135     setSameQuantization(op->outputs[0], op->inputs[0]);
136 }
137 
gatherFinalizer(RandomOperation * op)138 static void gatherFinalizer(RandomOperation* op) {
139     int32_t axis = op->inputs[1]->value<int32_t>();
140     if (axis < 0) axis += op->inputs[0]->dimensions.size();
141     uint32_t dimValue = op->inputs[0]->dimensions[axis].getValue();
142     uint32_t numElements = op->inputs[2]->getNumberOfElements();
143     for (uint32_t i = 0; i < numElements; i++) {
144         // The index values must be in the range of [0, dimValue).
145         op->inputs[2]->value<int32_t>(i) = getUniform<int32_t>(0, dimValue - 1);
146     }
147 }
148 
149 #define DEFINE_GATHER_SIGNATURE(ver, ...)                                     \
150     DEFINE_OPERATION_SIGNATURE(GATHER_##ver){                                 \
151             .opType = TestOperationType::GATHER,                              \
152             .supportedDataTypes = {__VA_ARGS__},                              \
153             .supportedRanks = {1, 2, 3, 4, 5},                                \
154             .version = TestHalVersion::ver,                                   \
155             .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::INT32), \
156                        PARAMETER_NONE(TestOperandType::TENSOR_INT32)},        \
157             .outputs = {OUTPUT_DEFAULT},                                      \
158             .constructor = gatherConstructor,                                 \
159             .finalizer = gatherFinalizer};
160 
161 DEFINE_GATHER_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
162                         TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM);
163 DEFINE_GATHER_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
164 
selectConstructor(TestOperandType,uint32_t rank,RandomOperation * op)165 static void selectConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
166     setFreeDimensions(op->inputs[0], rank);
167     op->inputs[1]->dimensions = op->inputs[0]->dimensions;
168     op->inputs[2]->dimensions = op->inputs[0]->dimensions;
169     op->outputs[0]->dimensions = op->inputs[0]->dimensions;
170     setSameQuantization(op->inputs[2], op->inputs[1]);
171     setSameQuantization(op->outputs[0], op->inputs[1]);
172 }
173 
174 #define DEFINE_SELECT_SIGNATURE(ver, ...)                                                         \
175     DEFINE_OPERATION_SIGNATURE(SELECT_##ver){                                                     \
176             .opType = TestOperationType::SELECT,                                                  \
177             .supportedDataTypes = {__VA_ARGS__},                                                  \
178             .supportedRanks = {1, 2, 3, 4},                                                       \
179             .version = TestHalVersion::ver,                                                       \
180             .inputs = {INPUT_TYPED(TestOperandType::TENSOR_BOOL8), INPUT_DEFAULT, INPUT_DEFAULT}, \
181             .outputs = {OUTPUT_DEFAULT},                                                          \
182             .constructor = selectConstructor};
183 
184 DEFINE_SELECT_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
185                         TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM);
186 DEFINE_SELECT_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
187 
topKConstructor(TestOperandType,uint32_t rank,RandomOperation * op)188 static void topKConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
189     setFreeDimensions(op->inputs[0], rank);
190     op->outputs[0]->dimensions.resize(rank);
191     op->outputs[1]->dimensions.resize(rank);
192     for (uint32_t i = 0; i < rank - 1; i++) {
193         op->outputs[0]->dimensions[i] = op->inputs[0]->dimensions[i];
194         op->outputs[1]->dimensions[i] = op->inputs[0]->dimensions[i];
195     }
196 
197     // K must be in the range of [1, depth].
198     auto k = op->inputs[1]->value<RandomVariable>();
199     k.setRange(1, kInvalidValue);
200     op->inputs[0]->dimensions.back().setGreaterEqual(k);
201 
202     op->outputs[0]->dimensions.back() = k;
203     op->outputs[1]->dimensions.back() = k;
204     setSameQuantization(op->outputs[0], op->inputs[0]);
205 
206     // As the sorting is not required to be stable, we should not check the second output (indices).
207     op->outputs[1]->doNotCheckAccuracy = true;
208     op->outputs[1]->doNotConnect = true;
209 }
210 
211 #define DEFINE_TOPK_SIGNATURE(ver, ...)                                               \
212     DEFINE_OPERATION_SIGNATURE(TOPK_V2_##ver){                                        \
213             .opType = TestOperationType::TOPK_V2,                                     \
214             .supportedDataTypes = {__VA_ARGS__},                                      \
215             .supportedRanks = {1, 2, 3, 4},                                           \
216             .version = TestHalVersion::ver,                                           \
217             .inputs = {INPUT_DEFAULT, RANDOM_INT_FREE},                               \
218             .outputs = {OUTPUT_DEFAULT, OUTPUT_TYPED(TestOperandType::TENSOR_INT32)}, \
219             .constructor = topKConstructor};
220 
221 DEFINE_TOPK_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
222                       TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM);
223 DEFINE_TOPK_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
224 
sliceConstructor(TestOperandType,uint32_t rank,RandomOperation * op)225 static void sliceConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
226     op->inputs[1]->dimensions = {rank};
227     op->inputs[2]->dimensions = {rank};
228     setFreeDimensions(op->inputs[0], rank);
229     setFreeDimensions(op->outputs[0], rank);
230     // The axis size of output must be less than or equal to input.
231     for (uint32_t i = 0; i < rank; i++) {
232         op->inputs[0]->dimensions[i].setGreaterEqual(op->outputs[0]->dimensions[i]);
233     }
234     setSameQuantization(op->outputs[0], op->inputs[0]);
235 }
236 
sliceFinalizer(RandomOperation * op)237 static void sliceFinalizer(RandomOperation* op) {
238     uint32_t rank = op->inputs[0]->dimensions.size();
239     int32_t* begin = reinterpret_cast<int32_t*>(op->inputs[1]->buffer.data());
240     int32_t* size = reinterpret_cast<int32_t*>(op->inputs[2]->buffer.data());
241 
242     NN_FUZZER_CHECK(op->inputs[1]->buffer.size() >= rank)
243             << "input[1] buffer size " << op->inputs[1]->buffer.size() << " is smaller than rank "
244             << rank;
245 
246     NN_FUZZER_CHECK(op->inputs[2]->buffer.size() >= rank)
247             << "input[1] buffer size " << op->inputs[2]->buffer.size() << " is smaller than rank "
248             << rank;
249 
250     for (uint32_t i = 0; i < rank; i++) {
251         int32_t inputSize = op->inputs[0]->dimensions[i].getValue();
252         int32_t outputSize = op->outputs[0]->dimensions[i].getValue();
253         // Randomly choose a valid begin index for each axis.
254         begin[i] = getUniform<int32_t>(0, inputSize - outputSize);
255         size[i] = outputSize;
256     }
257 }
258 
259 #define DEFINE_SLICE_SIGNATURE(ver, ...)                                             \
260     DEFINE_OPERATION_SIGNATURE(SLICE_##ver){                                         \
261             .opType = TestOperationType::SLICE,                                      \
262             .supportedDataTypes = {__VA_ARGS__},                                     \
263             .supportedRanks = {1, 2, 3, 4},                                          \
264             .version = TestHalVersion::ver,                                          \
265             .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::TENSOR_INT32), \
266                        PARAMETER_NONE(TestOperandType::TENSOR_INT32)},               \
267             .outputs = {OUTPUT_DEFAULT},                                             \
268             .constructor = sliceConstructor,                                         \
269             .finalizer = sliceFinalizer};
270 
271 DEFINE_SLICE_SIGNATURE(V1_2, TestOperandType::TENSOR_FLOAT32, TestOperandType::TENSOR_FLOAT16,
272                        TestOperandType::TENSOR_INT32, TestOperandType::TENSOR_QUANT8_ASYMM);
273 DEFINE_SLICE_SIGNATURE(V1_3, TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED);
274 
convertToBitMask(const std::vector<bool> & flags)275 inline int32_t convertToBitMask(const std::vector<bool>& flags) {
276     int32_t mask = 0, bit = 1;
277     for (bool flag : flags) {
278         if (flag) mask |= bit;
279         bit <<= 1;
280     }
281     return mask;
282 }
283 
stridedSliceConstructor(TestOperandType,uint32_t rank,RandomOperation * op)284 static void stridedSliceConstructor(TestOperandType, uint32_t rank, RandomOperation* op) {
285     op->inputs[1]->dimensions = {rank};
286     op->inputs[2]->dimensions = {rank};
287     op->inputs[3]->dimensions = {rank};
288     op->inputs[3]->resizeBuffer<int32_t>(rank);
289     setFreeDimensions(op->inputs[0], rank);
290     std::vector<bool> shrinkMask(rank, false);
291     for (uint32_t i = 0; i < rank; i++) {
292         shrinkMask[i] = getBernoulli(0.2f);
293         int32_t stride = getUniform<int32_t>(1, 3);
294         op->inputs[3]->value<int32_t>(i) = stride;
295         if (!shrinkMask[i]) {
296             op->outputs[0]->dimensions.push_back(RandomVariableType::FREE);
297             auto maxOut = (op->inputs[0]->dimensions[i] + (stride - 1)) / stride;
298             maxOut.setGreaterEqual(op->outputs[0]->dimensions.back());
299         }
300     }
301     setSameQuantization(op->outputs[0], op->inputs[0]);
302     op->inputs[6]->setScalarValue<int32_t>(convertToBitMask(shrinkMask));
303 }
304 
stridedSliceFinalizer(RandomOperation * op)305 static void stridedSliceFinalizer(RandomOperation* op) {
306     uint32_t rank = op->inputs[0]->dimensions.size();
307     int32_t* begin = reinterpret_cast<int32_t*>(op->inputs[1]->buffer.data());
308     int32_t* end = reinterpret_cast<int32_t*>(op->inputs[2]->buffer.data());
309     std::vector<bool> beginMask(rank, false), endMask(rank, false);
310 
311     NN_FUZZER_CHECK(op->inputs[1]->buffer.size() >= rank)
312             << "input[1] buffer size " << op->inputs[1]->buffer.size() << " is smaller than rank "
313             << rank;
314 
315     NN_FUZZER_CHECK(op->inputs[2]->buffer.size() >= rank)
316             << "input[1] buffer size " << op->inputs[2]->buffer.size() << " is smaller than rank "
317             << rank;
318 
319     int32_t shrinkMask = op->inputs[6]->value<int32_t>();
320     for (uint32_t i = 0, o = 0; i < rank; i++) {
321         int32_t inputSize = op->inputs[0]->dimensions[i].getValue();
322         int32_t stride = op->inputs[3]->value<int32_t>(i);
323         bool shrink = shrinkMask & (1 << i);
324         if (!shrink) {
325             int32_t outputSize = op->outputs[0]->dimensions[o++].getValue();
326             int32_t maxStart = inputSize - (outputSize - 1) * stride - 1;
327             begin[i] = getUniform<int32_t>(0, maxStart);
328 
329             int32_t minEnd = begin[i] + (outputSize - 1) * stride + 1;
330             int32_t maxEnd = std::min(begin[i] + outputSize * stride, inputSize);
331             end[i] = getUniform<int32_t>(minEnd, maxEnd);
332 
333             // Switch to masked begin/end.
334             beginMask[i] = (begin[i] == 0 && getBernoulli(0.2f));
335             endMask[i] = (end[i] == 0 && getBernoulli(0.2f));
336 
337             // When begin or end mask is set, begin[i] or end[i] is ignored and can have any
338             // arbitrary value.
339             if (beginMask[i]) begin[i] = getUniform<int32_t>(-inputSize, inputSize - 1);
340             if (endMask[i]) end[i] = getUniform<int32_t>(-inputSize, inputSize - 1);
341 
342             // Switch to negative stride.
343             if (getBernoulli(0.2f)) {
344                 op->inputs[3]->value<int32_t>(i) = -stride;
345                 std::swap(begin[i], end[i]);
346                 std::swap(beginMask[i], endMask[i]);
347                 begin[i]--;
348                 end[i]--;
349                 // end = -1 will be interpreted to inputSize - 1 if not setting endMask.
350                 if (end[i] < 0) endMask[i] = true;
351             }
352         } else {
353             // When shrink mask is set, the begin and end must define a slice of size 1, e.g.
354             // begin[i] = x, end[i] = x + 1.
355             begin[i] = getUniform<int32_t>(0, inputSize - 1);
356             end[i] = begin[i] + 1;
357         }
358     }
359     op->inputs[4]->setScalarValue<int32_t>(convertToBitMask(beginMask));
360     op->inputs[5]->setScalarValue<int32_t>(convertToBitMask(endMask));
361 }
362 
DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_1)363 DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_1){
364         .opType = TestOperationType::STRIDED_SLICE,
365         .supportedDataTypes = {TestOperandType::TENSOR_FLOAT32,
366                                TestOperandType::TENSOR_QUANT8_ASYMM},
367         .supportedRanks = {1, 2, 3, 4},
368         .version = TestHalVersion::V1_1,
369         .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::TENSOR_INT32),
370                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
371                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
372                    PARAMETER_CHOICE(TestOperandType::INT32, 0),
373                    PARAMETER_CHOICE(TestOperandType::INT32, 0),
374                    PARAMETER_CHOICE(TestOperandType::INT32, 0)},
375         .outputs = {OUTPUT_DEFAULT},
376         .constructor = stridedSliceConstructor,
377         .finalizer = stridedSliceFinalizer};
378 
DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_2)379 DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_2){
380         .opType = TestOperationType::STRIDED_SLICE,
381         .supportedDataTypes = {TestOperandType::TENSOR_FLOAT16},
382         .supportedRanks = {1, 2, 3, 4},
383         .version = TestHalVersion::V1_2,
384         .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::TENSOR_INT32),
385                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
386                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
387                    PARAMETER_NONE(TestOperandType::INT32), PARAMETER_NONE(TestOperandType::INT32),
388                    PARAMETER_NONE(TestOperandType::INT32)},
389         .outputs = {OUTPUT_DEFAULT},
390         .constructor = stridedSliceConstructor,
391         .finalizer = stridedSliceFinalizer};
392 
DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_3)393 DEFINE_OPERATION_SIGNATURE(STRIDED_SLICE_V1_3){
394         .opType = TestOperationType::STRIDED_SLICE,
395         .supportedDataTypes = {TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED},
396         .supportedRanks = {1, 2, 3, 4},
397         .version = TestHalVersion::V1_3,
398         .inputs = {INPUT_DEFAULT, PARAMETER_NONE(TestOperandType::TENSOR_INT32),
399                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
400                    PARAMETER_NONE(TestOperandType::TENSOR_INT32),
401                    PARAMETER_NONE(TestOperandType::INT32), PARAMETER_NONE(TestOperandType::INT32),
402                    PARAMETER_NONE(TestOperandType::INT32)},
403         .outputs = {OUTPUT_DEFAULT},
404         .constructor = stridedSliceConstructor,
405         .finalizer = stridedSliceFinalizer};
406 
407 }  // namespace fuzzing_test
408 }  // namespace nn
409 }  // namespace android
410