1 /*
2  * Copyright (C) 2020 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 <gtest/gtest.h>
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <limits>
22 #include <string>
23 #include <vector>
24 
25 #include "GeneratedTestUtils.h"
26 #include "Manager.h"
27 #include "SampleDriverPartial.h"
28 #include "TestNeuralNetworksWrapper.h"
29 #include "Utils.h"
30 
31 namespace generated_tests::avg_pool_v1_2 {
32 const test_helper::TestModel& get_test_model_nhwc();
33 const test_helper::TestModel& get_test_model_nchw();
34 const test_helper::TestModel& get_test_model_nhwc_5();
35 }  // namespace generated_tests::avg_pool_v1_2
36 
37 namespace generated_tests::conv2d_dilation {
38 const test_helper::TestModel& get_test_model_nhwc();
39 const test_helper::TestModel& get_test_model_nchw();
40 const test_helper::TestModel& get_test_model_valid_padding_nhwc();
41 }  // namespace generated_tests::conv2d_dilation
42 
43 namespace generated_tests::depthwise_conv2d_dilation {
44 const test_helper::TestModel& get_test_model_nhwc();
45 const test_helper::TestModel& get_test_model_valid_padding_nhwc();
46 }  // namespace generated_tests::depthwise_conv2d_dilation
47 
48 namespace generated_tests::depth_to_space_v1_2 {
49 const test_helper::TestModel& get_test_model_nhwc();
50 }  // namespace generated_tests::depth_to_space_v1_2
51 
52 namespace generated_tests::l2_normalization_axis {
53 const test_helper::TestModel& get_test_model_dim4_axis3_neg();
54 }  // namespace generated_tests::l2_normalization_axis
55 
56 namespace generated_tests::l2_pool_v1_2 {
57 const test_helper::TestModel& get_test_model_nhwc();
58 const test_helper::TestModel& get_test_model_nhwc_2();
59 }  // namespace generated_tests::l2_pool_v1_2
60 
61 namespace generated_tests::local_response_normalization_v1_2 {
62 const test_helper::TestModel& get_test_model_axis_dim2_axis1_neg();
63 }  // namespace generated_tests::local_response_normalization_v1_2
64 
65 namespace generated_tests::max_pool_v1_2 {
66 const test_helper::TestModel& get_test_model_nhwc();
67 const test_helper::TestModel& get_test_model_nhwc_4();
68 }  // namespace generated_tests::max_pool_v1_2
69 
70 namespace generated_tests::resize_bilinear_v1_2 {
71 const test_helper::TestModel& get_test_model_shape_nhwc();
72 }  // namespace generated_tests::resize_bilinear_v1_2
73 
74 namespace generated_tests::resize_bilinear_v1_3 {
75 const test_helper::TestModel& get_test_model_align_corners_2x2_to_1x1();
76 }  // namespace generated_tests::resize_bilinear_v1_3
77 
78 namespace generated_tests::softmax_v1_2 {
79 const test_helper::TestModel& get_test_model_axis_quant8_dim1_axis0_neg();
80 }  // namespace generated_tests::softmax_v1_2
81 
82 namespace generated_tests::space_to_depth_v1_2 {
83 const test_helper::TestModel& get_test_model_nhwc();
84 }  // namespace generated_tests::space_to_depth_v1_2
85 
86 namespace generated_tests::batch_to_space_v1_2 {
87 const test_helper::TestModel& get_test_model_nhwc();
88 }  // namespace generated_tests::batch_to_space_v1_2
89 
90 namespace generated_tests::space_to_batch_v1_2 {
91 const test_helper::TestModel& get_test_model_nhwc();
92 }  // namespace generated_tests::space_to_batch_v1_2
93 
94 namespace generated_tests::resize_nearest_neighbor_v1_3 {
95 const test_helper::TestModel& get_test_model_align_corners_2x2_to_1x1();
96 }  // namespace generated_tests::resize_nearest_neighbor_v1_3
97 
98 namespace android::nn {
99 namespace {
100 
101 using namespace hal;
102 using sample_driver::SampleDriverPartial;
103 using Result = test_wrapper::Result;
104 using WrapperOperandType = test_wrapper::OperandType;
105 using WrapperCompilation = test_wrapper::Compilation;
106 using WrapperType = test_wrapper::Type;
107 using WrapperModel = test_wrapper::Model;
108 
109 const char* kTestDriverName = "nnapi-test";
110 
111 // A driver that rejects operations based solely on the input count.
112 class TestDriver : public SampleDriverPartial {
113    public:
TestDriver()114     TestDriver() : SampleDriverPartial(kTestDriverName) {}
115 
getCapabilities_1_3(getCapabilities_1_3_cb cb)116     Return<void> getCapabilities_1_3(getCapabilities_1_3_cb cb) override {
117         cb(V1_3::ErrorStatus::NONE, {/* Dummy zero-filled capabilities. */});
118         return Void();
119     }
120 
setSupportedInputCount(uint32_t count)121     void setSupportedInputCount(uint32_t count) { mSupportedInputCount = count; }
122 
123    private:
getSupportedOperationsImpl(const Model & model) const124     std::vector<bool> getSupportedOperationsImpl(const Model& model) const override {
125         std::vector<bool> supported(model.main.operations.size());
126         std::transform(model.main.operations.begin(), model.main.operations.end(),
127                        supported.begin(), [this](const Operation& operation) {
128                            SCOPED_TRACE("operation = " + toString(operation.type));
129                            EXPECT_EQ(operation.inputs.size(), mSupportedInputCount);
130                            return operation.inputs.size() == mSupportedInputCount;
131                        });
132         return supported;
133     }
134 
135     uint32_t mSupportedInputCount = std::numeric_limits<uint32_t>::max();
136 };
137 
138 class TestRemoveDefaultArguments : public ::testing::Test {
SetUp()139     virtual void SetUp() {
140         // skip the tests if useCpuOnly = 1
141         if (DeviceManager::get()->getUseCpuOnly()) {
142             GTEST_SKIP();
143         }
144         mTestDriver = new TestDriver();
145         DeviceManager::get()->forTest_registerDevice(kTestDriverName, mTestDriver);
146         mTestDevice = getDeviceByName(kTestDriverName);
147         ASSERT_NE(mTestDevice, nullptr);
148     }
149 
TearDown()150     virtual void TearDown() { DeviceManager::get()->forTest_reInitializeDeviceList(); }
151 
152    protected:
test(const test_helper::TestModel & testModel,uint32_t originalInputCount,uint32_t expectedInputCount)153     void test(const test_helper::TestModel& testModel, uint32_t originalInputCount,
154               uint32_t expectedInputCount) {
155         ASSERT_EQ(testModel.main.operations.size(), 1u);
156         ASSERT_EQ(testModel.main.operations[0].inputs.size(), originalInputCount);
157 
158         mTestDriver->setSupportedInputCount(expectedInputCount);
159 
160         generated_tests::GeneratedModel model;
161         generated_tests::createModel(testModel, &model);
162         ASSERT_TRUE(model.isValid());
163         ASSERT_EQ(model.finish(), Result::NO_ERROR);
164 
165         auto [result, compilation] = WrapperCompilation::createForDevice(&model, mTestDevice);
166         ASSERT_EQ(result, Result::NO_ERROR);
167         ASSERT_EQ(compilation.finish(), Result::NO_ERROR);
168     }
169 
170    private:
getDeviceByName(const std::string & name)171     ANeuralNetworksDevice* getDeviceByName(const std::string& name) {
172         ANeuralNetworksDevice* result = nullptr;
173         uint32_t numDevices = 0;
174         EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR);
175         EXPECT_GE(numDevices, 1u);
176         for (uint32_t i = 0; i < numDevices; i++) {
177             ANeuralNetworksDevice* device = nullptr;
178             EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR);
179             const char* buffer = nullptr;
180             EXPECT_EQ(ANeuralNetworksDevice_getName(device, &buffer), ANEURALNETWORKS_NO_ERROR);
181             if (name == buffer) {
182                 EXPECT_EQ(result, nullptr) << "multiple devices named " << name;
183                 result = device;
184             }
185         }
186         return result;
187     }
188 
189     sp<TestDriver> mTestDriver;
190     ANeuralNetworksDevice* mTestDevice;
191 };
192 
TEST_F(TestRemoveDefaultArguments,AVERAGE_POOL_2D_11_inputs_to_10_inputs)193 TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_11_inputs_to_10_inputs) {
194     const uint32_t originalInputCount = 11;
195     const uint32_t expectedInputCount = 10;
196     test(::generated_tests::avg_pool_v1_2::get_test_model_nhwc(), originalInputCount,
197          expectedInputCount);
198 }
199 
TEST_F(TestRemoveDefaultArguments,AVERAGE_POOL_2D_11_inputs_no_default_values)200 TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_11_inputs_no_default_values) {
201     const uint32_t originalInputCount = 11;
202     const uint32_t expectedInputCount = 11;
203     test(::generated_tests::avg_pool_v1_2::get_test_model_nchw(), originalInputCount,
204          expectedInputCount);
205 }
206 
TEST_F(TestRemoveDefaultArguments,AVERAGE_POOL_2D_8_inputs_to_7_inputs)207 TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_8_inputs_to_7_inputs) {
208     const uint32_t originalInputCount = 8;
209     const uint32_t expectedInputCount = 7;
210     test(::generated_tests::avg_pool_v1_2::get_test_model_nhwc_5(), originalInputCount,
211          expectedInputCount);
212 }
213 
TEST_F(TestRemoveDefaultArguments,CONV_2D_13_inputs_to_10_inputs)214 TEST_F(TestRemoveDefaultArguments, CONV_2D_13_inputs_to_10_inputs) {
215     const uint32_t originalInputCount = 13;
216     const uint32_t expectedInputCount = 10;
217     test(::generated_tests::conv2d_dilation::get_test_model_nhwc(), originalInputCount,
218          expectedInputCount);
219 }
220 
TEST_F(TestRemoveDefaultArguments,CONV_2D_13_inputs_to_11_inputs)221 TEST_F(TestRemoveDefaultArguments, CONV_2D_13_inputs_to_11_inputs) {
222     const uint32_t originalInputCount = 13;
223     const uint32_t expectedInputCount = 11;
224     test(::generated_tests::conv2d_dilation::get_test_model_nchw(), originalInputCount,
225          expectedInputCount);
226 }
227 
TEST_F(TestRemoveDefaultArguments,CONV_2D_10_inputs_to_7_inputs)228 TEST_F(TestRemoveDefaultArguments, CONV_2D_10_inputs_to_7_inputs) {
229     const uint32_t originalInputCount = 10;
230     const uint32_t expectedInputCount = 7;
231     test(::generated_tests::conv2d_dilation::get_test_model_valid_padding_nhwc(),
232          originalInputCount, expectedInputCount);
233 }
234 
TEST_F(TestRemoveDefaultArguments,DEPTHWISE_CONV_3D_14_inputs_to_11_inputs)235 TEST_F(TestRemoveDefaultArguments, DEPTHWISE_CONV_3D_14_inputs_to_11_inputs) {
236     const uint32_t originalInputCount = 14;
237     const uint32_t expectedInputCount = 11;
238     test(::generated_tests::depthwise_conv2d_dilation::get_test_model_nhwc(), originalInputCount,
239          expectedInputCount);
240 }
241 
TEST_F(TestRemoveDefaultArguments,DEPTHWISE_CONV_2D_11_inputs_to_8_inputs)242 TEST_F(TestRemoveDefaultArguments, DEPTHWISE_CONV_2D_11_inputs_to_8_inputs) {
243     const uint32_t originalInputCount = 11;
244     const uint32_t expectedInputCount = 8;
245     test(::generated_tests::depthwise_conv2d_dilation::get_test_model_valid_padding_nhwc(),
246          originalInputCount, expectedInputCount);
247 }
248 
TEST_F(TestRemoveDefaultArguments,DEPTH_TO_SPACE_3_inputs_to_2_inputs)249 TEST_F(TestRemoveDefaultArguments, DEPTH_TO_SPACE_3_inputs_to_2_inputs) {
250     const uint32_t originalInputCount = 3;
251     const uint32_t expectedInputCount = 2;
252     test(::generated_tests::depth_to_space_v1_2::get_test_model_nhwc(), originalInputCount,
253          expectedInputCount);
254 }
255 
TEST_F(TestRemoveDefaultArguments,L2_NORMALIZATION_2_inputs_to_1_input)256 TEST_F(TestRemoveDefaultArguments, L2_NORMALIZATION_2_inputs_to_1_input) {
257     const uint32_t originalInputCount = 2;
258     const uint32_t expectedInputCount = 1;
259     test(::generated_tests::l2_normalization_axis::get_test_model_dim4_axis3_neg(),
260          originalInputCount, expectedInputCount);
261 }
262 
TEST_F(TestRemoveDefaultArguments,L2_POOL_2D_11_inputs_to_10_inputs)263 TEST_F(TestRemoveDefaultArguments, L2_POOL_2D_11_inputs_to_10_inputs) {
264     const uint32_t originalInputCount = 11;
265     const uint32_t expectedInputCount = 10;
266     test(::generated_tests::l2_pool_v1_2::get_test_model_nhwc(), originalInputCount,
267          expectedInputCount);
268 }
269 
TEST_F(TestRemoveDefaultArguments,L2_POOL_2D_8_inputs_to_7_inputs)270 TEST_F(TestRemoveDefaultArguments, L2_POOL_2D_8_inputs_to_7_inputs) {
271     const uint32_t originalInputCount = 8;
272     const uint32_t expectedInputCount = 7;
273     test(::generated_tests::l2_pool_v1_2::get_test_model_nhwc_2(), originalInputCount,
274          expectedInputCount);
275 }
276 
TEST_F(TestRemoveDefaultArguments,LOCAL_RESPONSE_NORMALIZATION_6_inputs_to_5_inputs)277 TEST_F(TestRemoveDefaultArguments, LOCAL_RESPONSE_NORMALIZATION_6_inputs_to_5_inputs) {
278     const uint32_t originalInputCount = 6;
279     const uint32_t expectedInputCount = 5;
280     test(::generated_tests::local_response_normalization_v1_2::get_test_model_axis_dim2_axis1_neg(),
281          originalInputCount, expectedInputCount);
282 }
283 
TEST_F(TestRemoveDefaultArguments,MAX_POOL_2D_11_inputs_to_10_inputs)284 TEST_F(TestRemoveDefaultArguments, MAX_POOL_2D_11_inputs_to_10_inputs) {
285     const uint32_t originalInputCount = 11;
286     const uint32_t expectedInputCount = 10;
287     test(::generated_tests::max_pool_v1_2::get_test_model_nhwc(), originalInputCount,
288          expectedInputCount);
289 }
290 
TEST_F(TestRemoveDefaultArguments,MAX_POOL_2D_8_inputs_to_7_inputs)291 TEST_F(TestRemoveDefaultArguments, MAX_POOL_2D_8_inputs_to_7_inputs) {
292     const uint32_t originalInputCount = 8;
293     const uint32_t expectedInputCount = 7;
294     test(::generated_tests::max_pool_v1_2::get_test_model_nhwc_4(), originalInputCount,
295          expectedInputCount);
296 }
297 
TEST_F(TestRemoveDefaultArguments,RESIZE_BILINEAR_by_shape_6_inputs_to_5_inputs)298 TEST_F(TestRemoveDefaultArguments, RESIZE_BILINEAR_by_shape_6_inputs_to_5_inputs) {
299     const uint32_t originalInputCount = 6;
300     const uint32_t expectedInputCount = 5;
301     test(::generated_tests::resize_bilinear_v1_3::get_test_model_align_corners_2x2_to_1x1(),
302          originalInputCount, expectedInputCount);
303 }
304 
TEST_F(TestRemoveDefaultArguments,RESIZE_BILINEAR_by_shape_4_inputs_to_3_inputs)305 TEST_F(TestRemoveDefaultArguments, RESIZE_BILINEAR_by_shape_4_inputs_to_3_inputs) {
306     const uint32_t originalInputCount = 4;
307     const uint32_t expectedInputCount = 3;
308     test(::generated_tests::resize_bilinear_v1_2::get_test_model_shape_nhwc(), originalInputCount,
309          expectedInputCount);
310 }
311 
TEST_F(TestRemoveDefaultArguments,SOFTMAX_3_inputs_to_2_inputs)312 TEST_F(TestRemoveDefaultArguments, SOFTMAX_3_inputs_to_2_inputs) {
313     const uint32_t originalInputCount = 3;
314     const uint32_t expectedInputCount = 2;
315     test(::generated_tests::softmax_v1_2::get_test_model_axis_quant8_dim1_axis0_neg(),
316          originalInputCount, expectedInputCount);
317 }
318 
TEST_F(TestRemoveDefaultArguments,SPACE_TO_DEPTH_3_inputs_to_2_inputs)319 TEST_F(TestRemoveDefaultArguments, SPACE_TO_DEPTH_3_inputs_to_2_inputs) {
320     const uint32_t originalInputCount = 3;
321     const uint32_t expectedInputCount = 2;
322     test(::generated_tests::space_to_depth_v1_2::get_test_model_nhwc(), originalInputCount,
323          expectedInputCount);
324 }
325 
TEST_F(TestRemoveDefaultArguments,BATCH_TO_SPACE_ND_3_inputs_to_2_inputs)326 TEST_F(TestRemoveDefaultArguments, BATCH_TO_SPACE_ND_3_inputs_to_2_inputs) {
327     const uint32_t originalInputCount = 3;
328     const uint32_t expectedInputCount = 2;
329     test(::generated_tests::batch_to_space_v1_2::get_test_model_nhwc(), originalInputCount,
330          expectedInputCount);
331 }
332 
TEST_F(TestRemoveDefaultArguments,SPACE_TO_BATCH_ND_4_inputs_to_3_inputs)333 TEST_F(TestRemoveDefaultArguments, SPACE_TO_BATCH_ND_4_inputs_to_3_inputs) {
334     const uint32_t originalInputCount = 4;
335     const uint32_t expectedInputCount = 3;
336     test(::generated_tests::space_to_batch_v1_2::get_test_model_nhwc(), originalInputCount,
337          expectedInputCount);
338 }
339 
TEST_F(TestRemoveDefaultArguments,RESIZE_NEAREST_NEIGHBOR_by_shape_6_inputs_to_5_inputs)340 TEST_F(TestRemoveDefaultArguments, RESIZE_NEAREST_NEIGHBOR_by_shape_6_inputs_to_5_inputs) {
341     const uint32_t originalInputCount = 6;
342     const uint32_t expectedInputCount = 5;
343     test(::generated_tests::resize_nearest_neighbor_v1_3::get_test_model_align_corners_2x2_to_1x1(),
344          originalInputCount, expectedInputCount);
345 }
346 
347 }  // namespace
348 }  // namespace android::nn
349