/* * Copyright (c) 2022 Huawei Device Co., Ltd. * 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 "ops/top_k_builder.h" #include #include "nn_tensor.h" #include "ops_test.h" using namespace testing; using namespace testing::ext; using namespace OHOS::NeuralNetworkRuntime::Ops; namespace OHOS { namespace NeuralNetworkRuntime { namespace UnitTest { class TopKBuilderTest : public OpsTest { protected: void InitTensor(const std::vector& inputsIndex, const std::vector& outputsIndex) override; void SaveSortedTensor(OH_NN_DataType dataType, const std::vector &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type); void SaveAxisTensor(OH_NN_DataType dataType, const std::vector &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type); protected: TopKBuilder m_builder; bool m_topkValue {false}; }; void TopKBuilderTest::InitTensor(const std::vector& inputsIndex, const std::vector& outputsIndex) { std::vector inputDim = {9}; std::vector OutputDim = {3}; SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr); SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr); } void TopKBuilderTest::SaveAxisTensor(OH_NN_DataType dataType, const std::vector &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type) { std::shared_ptr axisTensor = TransToNNTensor(dataType, dim, quantParam, type); int64_t* axisValue = new (std::nothrow) int64_t[1] {0}; EXPECT_NE(nullptr, axisValue); axisTensor->SetBuffer(axisValue, sizeof(int64_t)); m_allTensors.emplace_back(axisTensor); } void TopKBuilderTest::SaveSortedTensor(OH_NN_DataType dataType, const std::vector &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type) { std::shared_ptr topkTensor = TransToNNTensor(dataType, dim, quantParam, type); bool* topkValue = new (std::nothrow) bool[1] {true}; EXPECT_NE(nullptr, topkValue); topkTensor->SetBuffer(topkValue, sizeof(bool)); m_allTensors.emplace_back(topkTensor); m_topkValue = *topkValue; } /** * @tc.name: topk_build_001 * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_001, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_SUCCESS, ret); } /** * @tc.name: topk_build_002 * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_002, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors)); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret); } /** * @tc.name: topk_build_003 * @tc.desc: Provide one more than normal input to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_003, TestSize.Level0) { std::vector inputsIndex = { 0, 1, 2, 3 }; std::vector outputsIndex = { 4, 5 }; std::vector paramsIndex = { 6, 7 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_builder_004 * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_builder_004, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3, 4 }; std::vector paramsIndex = { 5, 6 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_005 * @tc.desc: Provide empty input, output, and parameters to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_005, TestSize.Level0) { std::vector inputsIndex = { 0, 1, 2 }; std::vector outputsIndex = { 3, 4 }; std::vector paramsIndex = { 5, 6, 7 }; OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, inputsIndex, outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_006 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_006, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_007 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_007, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT32, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_008 * @tc.desc: Provide sorted parameter buffer is nullptr to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_008, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); std::shared_ptr topkTensor = TransToNNTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); topkTensor->SetBuffer(nullptr, 0); m_allTensors.emplace_back(topkTensor); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_009 * @tc.desc: Provide axis parameter buffer is nullptr to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_009, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); std::shared_ptr axisTensor = TransToNNTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); axisTensor->SetBuffer(nullptr, 0); m_allTensors.emplace_back(axisTensor); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_010 * @tc.desc: Provide invalid parameter type to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_010, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_SCALE_AXIS); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_build_011 * @tc.desc: Provide invalid parameter type to verify the abnormal behavior of the Build function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_build_011, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_SCALE_AXIS); OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors); EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret); } /** * @tc.name: topk_get_primitive_001 * @tc.desc: Verify the GetPrimitive function return nullptr * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_get_primitive_001, TestSize.Level0) { LiteGraphTensorPtr primitive = m_builder.GetPrimitive(); LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive }; EXPECT_EQ(primitive, expectPrimitive); } /** * @tc.name: topk_get_primitive_002 * @tc.desc: Verify the normal params return behavior of the getprimitive function * @tc.type: FUNC */ HWTEST_F(TopKBuilderTest, topk_get_primitive_002, TestSize.Level0) { std::vector inputsIndex = { 0, 1 }; std::vector outputsIndex = { 2, 3 }; std::vector paramsIndex = { 4, 5 }; std::vector paramDim = {}; InitTensor(inputsIndex, outputsIndex); SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED); SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TOP_K_AXIS); int64_t axisValue = 0; EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors)); LiteGraphTensorPtr primitive = m_builder.GetPrimitive(); LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive }; EXPECT_NE(primitive, expectPrimitive); auto sortedReturn = mindspore::lite::MindIR_TopKFusion_GetSorted(primitive.get()); EXPECT_EQ(sortedReturn, m_topkValue); auto axisReturn = mindspore::lite::MindIR_TopKFusion_GetAxis(primitive.get()); EXPECT_EQ(axisReturn, axisValue); } } // namespace UnitTest } // namespace NeuralNetworkRuntime } // namespace OHOS