| /* |
| * Copyright (C) 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <SampleDriverPartial.h> |
| #include <Utils.h> |
| #include <gtest/gtest.h> |
| |
| #include <algorithm> |
| #include <iostream> |
| #include <limits> |
| #include <string> |
| #include <vector> |
| |
| #include "GeneratedTestUtils.h" |
| #include "HalUtils.h" |
| #include "Manager.h" |
| #include "TestNeuralNetworksWrapper.h" |
| |
| namespace generated_tests::avg_pool_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| const test_helper::TestModel& get_test_model_nchw(); |
| const test_helper::TestModel& get_test_model_nhwc_5(); |
| } // namespace generated_tests::avg_pool_v1_2 |
| |
| namespace generated_tests::conv2d_dilation { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| const test_helper::TestModel& get_test_model_nchw(); |
| const test_helper::TestModel& get_test_model_valid_padding_nhwc(); |
| } // namespace generated_tests::conv2d_dilation |
| |
| namespace generated_tests::depthwise_conv2d_dilation { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| const test_helper::TestModel& get_test_model_valid_padding_nhwc(); |
| } // namespace generated_tests::depthwise_conv2d_dilation |
| |
| namespace generated_tests::depth_to_space_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| } // namespace generated_tests::depth_to_space_v1_2 |
| |
| namespace generated_tests::l2_normalization_axis { |
| const test_helper::TestModel& get_test_model_dim4_axis3_neg(); |
| } // namespace generated_tests::l2_normalization_axis |
| |
| namespace generated_tests::l2_pool_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| const test_helper::TestModel& get_test_model_nhwc_2(); |
| } // namespace generated_tests::l2_pool_v1_2 |
| |
| namespace generated_tests::local_response_normalization_v1_2 { |
| const test_helper::TestModel& get_test_model_axis_dim2_axis1_neg(); |
| } // namespace generated_tests::local_response_normalization_v1_2 |
| |
| namespace generated_tests::max_pool_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| const test_helper::TestModel& get_test_model_nhwc_4(); |
| } // namespace generated_tests::max_pool_v1_2 |
| |
| namespace generated_tests::resize_bilinear_v1_2 { |
| const test_helper::TestModel& get_test_model_shape_nhwc(); |
| } // namespace generated_tests::resize_bilinear_v1_2 |
| |
| namespace generated_tests::resize_bilinear_v1_3 { |
| const test_helper::TestModel& get_test_model_align_corners_2x2_to_1x1(); |
| } // namespace generated_tests::resize_bilinear_v1_3 |
| |
| namespace generated_tests::softmax_v1_2 { |
| const test_helper::TestModel& get_test_model_axis_quant8_dim1_axis0_neg(); |
| } // namespace generated_tests::softmax_v1_2 |
| |
| namespace generated_tests::space_to_depth_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| } // namespace generated_tests::space_to_depth_v1_2 |
| |
| namespace generated_tests::batch_to_space_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| } // namespace generated_tests::batch_to_space_v1_2 |
| |
| namespace generated_tests::space_to_batch_v1_2 { |
| const test_helper::TestModel& get_test_model_nhwc(); |
| } // namespace generated_tests::space_to_batch_v1_2 |
| |
| namespace generated_tests::resize_nearest_neighbor_v1_3 { |
| const test_helper::TestModel& get_test_model_align_corners_2x2_to_1x1(); |
| } // namespace generated_tests::resize_nearest_neighbor_v1_3 |
| |
| namespace android::nn { |
| namespace { |
| |
| using sample_driver::SampleDriverPartial; |
| using Result = test_wrapper::Result; |
| using WrapperOperandType = test_wrapper::OperandType; |
| using WrapperCompilation = test_wrapper::Compilation; |
| using WrapperType = test_wrapper::Type; |
| using WrapperModel = test_wrapper::Model; |
| |
| const char* kTestDriverName = "nnapi-test"; |
| |
| // A driver that rejects operations based solely on the input count. |
| class TestDriver : public SampleDriverPartial { |
| public: |
| TestDriver() : SampleDriverPartial(kTestDriverName) {} |
| |
| hardware::Return<void> getCapabilities_1_3(getCapabilities_1_3_cb cb) override { |
| cb(V1_3::ErrorStatus::NONE, makeCapabilities(1.0)); |
| return hardware::Void(); |
| } |
| |
| void setSupportedInputCount(uint32_t count) { mSupportedInputCount = count; } |
| |
| private: |
| std::vector<bool> getSupportedOperationsImpl(const V1_3::Model& model) const override { |
| std::vector<bool> supported(model.main.operations.size()); |
| std::transform(model.main.operations.begin(), model.main.operations.end(), |
| supported.begin(), [this](const V1_3::Operation& operation) { |
| SCOPED_TRACE("operation = " + toString(operation.type)); |
| EXPECT_EQ(operation.inputs.size(), mSupportedInputCount); |
| return operation.inputs.size() == mSupportedInputCount; |
| }); |
| return supported; |
| } |
| |
| uint32_t mSupportedInputCount = std::numeric_limits<uint32_t>::max(); |
| }; |
| |
| class TestRemoveDefaultArguments : public ::testing::Test { |
| virtual void SetUp() { |
| // skip the tests if useCpuOnly = 1 |
| if (DeviceManager::get()->getUseCpuOnly()) { |
| GTEST_SKIP(); |
| } |
| mTestDriver = new TestDriver(); |
| DeviceManager::get()->forTest_registerDevice( |
| makeSharedDevice(kTestDriverName, mTestDriver)); |
| mTestDevice = getDeviceByName(kTestDriverName); |
| ASSERT_NE(mTestDevice, nullptr); |
| } |
| |
| virtual void TearDown() { DeviceManager::get()->forTest_reInitializeDeviceList(); } |
| |
| protected: |
| void test(const test_helper::TestModel& testModel, uint32_t originalInputCount, |
| uint32_t expectedInputCount) { |
| ASSERT_EQ(testModel.main.operations.size(), 1u); |
| ASSERT_EQ(testModel.main.operations[0].inputs.size(), originalInputCount); |
| |
| mTestDriver->setSupportedInputCount(expectedInputCount); |
| |
| generated_tests::GeneratedModel model; |
| generated_tests::createModel(testModel, &model); |
| ASSERT_TRUE(model.isValid()); |
| ASSERT_EQ(model.finish(), Result::NO_ERROR); |
| |
| auto [result, compilation] = WrapperCompilation::createForDevice(&model, mTestDevice); |
| ASSERT_EQ(result, Result::NO_ERROR); |
| ASSERT_EQ(compilation.finish(), Result::NO_ERROR); |
| } |
| |
| private: |
| ANeuralNetworksDevice* getDeviceByName(const std::string& name) { |
| ANeuralNetworksDevice* result = nullptr; |
| uint32_t numDevices = 0; |
| EXPECT_EQ(ANeuralNetworks_getDeviceCount(&numDevices), ANEURALNETWORKS_NO_ERROR); |
| EXPECT_GE(numDevices, 1u); |
| for (uint32_t i = 0; i < numDevices; i++) { |
| ANeuralNetworksDevice* device = nullptr; |
| EXPECT_EQ(ANeuralNetworks_getDevice(i, &device), ANEURALNETWORKS_NO_ERROR); |
| const char* buffer = nullptr; |
| EXPECT_EQ(ANeuralNetworksDevice_getName(device, &buffer), ANEURALNETWORKS_NO_ERROR); |
| if (name == buffer) { |
| EXPECT_EQ(result, nullptr) << "multiple devices named " << name; |
| result = device; |
| } |
| } |
| return result; |
| } |
| |
| sp<TestDriver> mTestDriver; |
| ANeuralNetworksDevice* mTestDevice; |
| }; |
| |
| TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_11_inputs_to_10_inputs) { |
| const uint32_t originalInputCount = 11; |
| const uint32_t expectedInputCount = 10; |
| test(::generated_tests::avg_pool_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_11_inputs_no_default_values) { |
| const uint32_t originalInputCount = 11; |
| const uint32_t expectedInputCount = 11; |
| test(::generated_tests::avg_pool_v1_2::get_test_model_nchw(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, AVERAGE_POOL_2D_8_inputs_to_7_inputs) { |
| const uint32_t originalInputCount = 8; |
| const uint32_t expectedInputCount = 7; |
| test(::generated_tests::avg_pool_v1_2::get_test_model_nhwc_5(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, CONV_2D_13_inputs_to_10_inputs) { |
| const uint32_t originalInputCount = 13; |
| const uint32_t expectedInputCount = 10; |
| test(::generated_tests::conv2d_dilation::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, CONV_2D_13_inputs_to_11_inputs) { |
| const uint32_t originalInputCount = 13; |
| const uint32_t expectedInputCount = 11; |
| test(::generated_tests::conv2d_dilation::get_test_model_nchw(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, CONV_2D_10_inputs_to_7_inputs) { |
| const uint32_t originalInputCount = 10; |
| const uint32_t expectedInputCount = 7; |
| test(::generated_tests::conv2d_dilation::get_test_model_valid_padding_nhwc(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, DEPTHWISE_CONV_3D_14_inputs_to_11_inputs) { |
| const uint32_t originalInputCount = 14; |
| const uint32_t expectedInputCount = 11; |
| test(::generated_tests::depthwise_conv2d_dilation::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, DEPTHWISE_CONV_2D_11_inputs_to_8_inputs) { |
| const uint32_t originalInputCount = 11; |
| const uint32_t expectedInputCount = 8; |
| test(::generated_tests::depthwise_conv2d_dilation::get_test_model_valid_padding_nhwc(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, DEPTH_TO_SPACE_3_inputs_to_2_inputs) { |
| const uint32_t originalInputCount = 3; |
| const uint32_t expectedInputCount = 2; |
| test(::generated_tests::depth_to_space_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, L2_NORMALIZATION_2_inputs_to_1_input) { |
| const uint32_t originalInputCount = 2; |
| const uint32_t expectedInputCount = 1; |
| test(::generated_tests::l2_normalization_axis::get_test_model_dim4_axis3_neg(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, L2_POOL_2D_11_inputs_to_10_inputs) { |
| const uint32_t originalInputCount = 11; |
| const uint32_t expectedInputCount = 10; |
| test(::generated_tests::l2_pool_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, L2_POOL_2D_8_inputs_to_7_inputs) { |
| const uint32_t originalInputCount = 8; |
| const uint32_t expectedInputCount = 7; |
| test(::generated_tests::l2_pool_v1_2::get_test_model_nhwc_2(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, LOCAL_RESPONSE_NORMALIZATION_6_inputs_to_5_inputs) { |
| const uint32_t originalInputCount = 6; |
| const uint32_t expectedInputCount = 5; |
| test(::generated_tests::local_response_normalization_v1_2::get_test_model_axis_dim2_axis1_neg(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, MAX_POOL_2D_11_inputs_to_10_inputs) { |
| const uint32_t originalInputCount = 11; |
| const uint32_t expectedInputCount = 10; |
| test(::generated_tests::max_pool_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, MAX_POOL_2D_8_inputs_to_7_inputs) { |
| const uint32_t originalInputCount = 8; |
| const uint32_t expectedInputCount = 7; |
| test(::generated_tests::max_pool_v1_2::get_test_model_nhwc_4(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, RESIZE_BILINEAR_by_shape_6_inputs_to_5_inputs) { |
| const uint32_t originalInputCount = 6; |
| const uint32_t expectedInputCount = 5; |
| test(::generated_tests::resize_bilinear_v1_3::get_test_model_align_corners_2x2_to_1x1(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, RESIZE_BILINEAR_by_shape_4_inputs_to_3_inputs) { |
| const uint32_t originalInputCount = 4; |
| const uint32_t expectedInputCount = 3; |
| test(::generated_tests::resize_bilinear_v1_2::get_test_model_shape_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, SOFTMAX_3_inputs_to_2_inputs) { |
| const uint32_t originalInputCount = 3; |
| const uint32_t expectedInputCount = 2; |
| test(::generated_tests::softmax_v1_2::get_test_model_axis_quant8_dim1_axis0_neg(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, SPACE_TO_DEPTH_3_inputs_to_2_inputs) { |
| const uint32_t originalInputCount = 3; |
| const uint32_t expectedInputCount = 2; |
| test(::generated_tests::space_to_depth_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, BATCH_TO_SPACE_ND_3_inputs_to_2_inputs) { |
| const uint32_t originalInputCount = 3; |
| const uint32_t expectedInputCount = 2; |
| test(::generated_tests::batch_to_space_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, SPACE_TO_BATCH_ND_4_inputs_to_3_inputs) { |
| const uint32_t originalInputCount = 4; |
| const uint32_t expectedInputCount = 3; |
| test(::generated_tests::space_to_batch_v1_2::get_test_model_nhwc(), originalInputCount, |
| expectedInputCount); |
| } |
| |
| TEST_F(TestRemoveDefaultArguments, RESIZE_NEAREST_NEIGHBOR_by_shape_6_inputs_to_5_inputs) { |
| const uint32_t originalInputCount = 6; |
| const uint32_t expectedInputCount = 5; |
| test(::generated_tests::resize_nearest_neighbor_v1_3::get_test_model_align_corners_2x2_to_1x1(), |
| originalInputCount, expectedInputCount); |
| } |
| |
| } // namespace |
| } // namespace android::nn |