From: Alexander Peskov Date: Wed, 21 Oct 2020 23:49:51 +0000 (+0300) Subject: [TEST] Several more Loop test with static shapes X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d7e3e92b64ee1a48bae9e551ef479a479405d65e;p=platform%2Fupstream%2Fdldt.git [TEST] Several more Loop test with static shapes Signed-off-by: Alexander Peskov --- diff --git a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp index 1b1fe9d..398d9b9 100644 --- a/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp +++ b/inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/loop.cpp @@ -3,7 +3,6 @@ // #include -#include #include "single_layer_tests/loop.hpp" #include "common_test_utils/test_constants.hpp" @@ -12,9 +11,9 @@ using namespace LayerTestsDefinitions; namespace { // without clip values increase rapidly, so use only seq_lenghts = 2 std::vector execute_first_iteration{true}; - std::vector is_body_condition_const{true, false}; - std::vector body_condition{true, false}; // works only if is_body_condition_const == true - std::vector trip_count{1, 10, -1}; // -1 means infinity + std::vector is_body_condition_const{true/*, false*/}; + std::vector body_condition{true/*, false*/}; // works only if is_body_condition_const == true + std::vector trip_count{1, 10/*, -1*/}; // -1 means infinity std::vector, LOOP_IN_TYPE>>> inputs = { {{{32, 1, 10}, LOOP_IN_TYPE::INVARIANT}, {{32, 1, 10}, LOOP_IN_TYPE::INVARIANT}, {{32, 1, 10}, LOOP_IN_TYPE::MERGED}}, }; @@ -31,4 +30,27 @@ namespace { ::testing::ValuesIn(netPrecisions), ::testing::Values(CommonTestUtils::DEVICE_CPU)), LoopTest::getTestCaseName); + + static const std::vector> static_loop_types = { + // static_trip_count | max | dynamic_exit | axis + { true , 5, -1, -1 }, // n_iter 5, no dynamic exit + { true , 5, 3, -1 }, // n_iter 3, dynamic exit on 3 + { true , 5, 7, -1 }, // n_iter 5, dynamic exit not reached + { true , -1, 5, -1 }, // n_iter 5, inf loop with dynamic exit on 5 + { true , 5, -1, 1 }, // n_iter 5, const for loop with auto concatenated out + { false , 5, -1, -1 }, // | + { false , 5, 3, -1 }, // | same with dynamic trip count + { false , 5, 7, -1 }, // | + { false , -1, 5, -1 }, // | + }; + + using namespace testing; + INSTANTIATE_TEST_CASE_P(smoke_StaticShapeLoop, StaticShapeLoopTest, + Combine( + Values(true), + ValuesIn(static_loop_types), + Values(7), + Values({2, 1, 4}), + Values(InferenceEngine::Precision::FP32, InferenceEngine::Precision::I32), + Values(CommonTestUtils::DEVICE_CPU))); } // namespace diff --git a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp index bf3b005..deb55cf 100644 --- a/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp +++ b/inference-engine/tests/functional/plugin/shared/include/single_layer_tests/loop.hpp @@ -29,7 +29,7 @@ using LoopParams = typename std::tuple< std::string>; // Device name class LoopTest : public testing::WithParamInterface, - virtual public LayerTestsUtils::LayerTestsCommon { + virtual public LayerTestsUtils::LayerTestsCommon { public: static std::string getTestCaseName(const testing::TestParamInfo &obj); @@ -37,4 +37,46 @@ protected: void SetUp() override; }; + +using StaticShapeLoopParams = typename std::tuple< + bool, + std::tuple< + bool, + int64_t, + int64_t, + int64_t + >, + int64_t, + InferenceEngine::SizeVector, + InferenceEngine::Precision, + std::string + >; + +/** + * Test case with static SHAPE version of loop operation. + * Total iteration count is dynamic. + */ +class StaticShapeLoopTest : public testing::WithParamInterface, + virtual public LayerTestsUtils::LayerTestsCommon { +public: + static std::string getTestCaseName(const testing::TestParamInfo &obj); + InferenceEngine::Blob::Ptr GenerateInput(const InferenceEngine::InputInfo &info) const override; + std::vector> CalculateRefs() override; + +private: + bool static_iter_num; // trip count provided by constant node + bool static_continue_cond; // initial_cond provided by constant node + int64_t max_iter_num; // -1 means infinity loop (expected dynamic exit condition in body) + int64_t dynamic_exit; // -1 means always true + int64_t axis; // -1 means no auto concatenation + int64_t start_value; + InferenceEngine::SizeVector data_shape; + InferenceEngine::Precision data_prc; + + int64_t actual_n_iter(); + +protected: + void SetUp() override; +}; + } // namespace LayerTestsDefinitions diff --git a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp index 88a817d..f11c55b 100644 --- a/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp +++ b/inference-engine/tests/functional/plugin/shared/src/single_layer_tests/loop.cpp @@ -157,5 +157,139 @@ namespace LayerTestsDefinitions { TEST_P(LoopTest, CompareWithRefs) { Run(); - }; + } + + void StaticShapeLoopTest::SetUp() { + SKIP_IF_CURRENT_TEST_IS_DISABLED() + SetRefMode(LayerTestsUtils::IE); + + auto args_papck = std::tie(static_iter_num, max_iter_num, dynamic_exit, axis); + std::tie( + static_continue_cond, + args_papck, + start_value, + data_shape, + data_prc, + targetDevice) = GetParam(); + + const auto prc = FuncTestUtils::PrecisionUtils::convertIE2nGraphPrc(data_prc); + const auto ngShape = ngraph::Shape{data_shape}; + const auto scalarShape = ngraph::Shape{}; + + ngraph::ParameterVector params{}; + auto cond_input_create = [¶ms] (ngraph::element::Type prc, const ngraph::Shape &shape, int value = 0, bool is_static = false) + -> std::shared_ptr { + if (is_static) + return std::make_shared(prc, shape, value); + + auto input = std::make_shared(prc, shape); + params.push_back(input); + return input; + }; + + auto start = cond_input_create(prc, ngShape); + auto count = cond_input_create(ngraph::element::i64, scalarShape, max_iter_num, static_iter_num); + auto skip = cond_input_create(ngraph::element::boolean, scalarShape, true, static_continue_cond); + + // + // count skip start count skip start + // / / + // ___*___*____ __________*___*____ | idx | data | out | + // | idx in | | ex_val idx in | | 0 | 7 | 7 | + // | | / | | | / | / | | 1 | 7 | 8 | + // | add | | less add | | 2 | 8 | 10 | + // | | true | | | | | | 3 | 10 | 13 | + // | | | | | | | | ~~~~~ * * * ~~~~~ + // | out cnd | | cnd out | + // |___*____*___| |____*_____*________| + // Full loop Dynamic exit loop + // n_iter = count n_iter = ex_val + // + auto b_indx = std::make_shared(ngraph::element::i64, ngraph::Shape{}); + auto b_data = std::make_shared(prc, ngShape); + auto b_indx_cast = std::make_shared(b_indx, prc); + auto b_add = std::make_shared(b_data, b_indx_cast, ngraph::op::AutoBroadcastSpec::NUMPY); + + std::shared_ptr b_cond; + if (dynamic_exit == -1) { + b_cond = std::make_shared(ngraph::element::boolean, ngraph::Shape{}, true); + } else { + auto b_exit_value = std::make_shared(ngraph::element::i64, scalarShape, dynamic_exit); + b_cond = std::make_shared(b_indx, b_exit_value); + } + + auto body = std::make_shared( + ngraph::OutputVector {b_cond, b_add}, // TODO: check with reverse + ngraph::ParameterVector {b_indx, b_data}); // TODO: check with reverse + + auto loop = std::make_shared(count, skip); + loop->set_function(body); + loop->set_special_body_ports({0, 0}); + loop->set_merged_input(b_data, start, b_add); + if (axis == -1) + loop->get_iter_value(b_add, -1); + else + loop->get_concatenated_slices(b_add, 0, 1, 1, -1, axis); + + function = std::make_shared( + ngraph::OutputVector {loop}, + params); + } + + InferenceEngine::Blob::Ptr StaticShapeLoopTest::GenerateInput(const InferenceEngine::InputInfo &info) const { + auto tdesc = info.getTensorDesc(); + auto blob = make_blob_with_precision(tdesc); + blob->allocate(); + + if (tdesc.getLayout() == InferenceEngine::SCALAR) { + auto scalar_1d = CommonTestUtils::make_reshape_view(blob, {1}); + CommonTestUtils::fill_data_with_broadcast(scalar_1d, 0, {static_cast(max_iter_num)}); + } else { + CommonTestUtils::fill_data_with_broadcast(blob, 0, {static_cast(start_value)}); + } + + return blob; + } + + int64_t StaticShapeLoopTest::actual_n_iter() { + constexpr auto INF_N_ITER = std::numeric_limits::max(); + IE_ASSERT(dynamic_exit != -1 || max_iter_num != -1); + + // dynamic_exit + 1 - because loop body looks like do-while loop with post condition check. + return std::min(dynamic_exit == -1 ? INF_N_ITER : dynamic_exit + 1, + max_iter_num == -1 ? INF_N_ITER : max_iter_num); + } + + // Predefined ref output + std::vector> StaticShapeLoopTest::CalculateRefs() { + bool auto_concat_out = (axis != -1); + const auto n_iter = actual_n_iter(); + + auto ref_shape = data_shape; + if (auto_concat_out) + ref_shape[axis] *= n_iter; + + using namespace CommonTestUtils; + InferenceEngine::TensorDesc tdesc {data_prc, ref_shape, InferenceEngine::TensorDesc::getLayoutByDims(ref_shape)}; + std::vector res(byte_size(tdesc)); + auto out = make_blob_with_precision(tdesc, res.data()); + + std::vector vals(n_iter); + float val = start_value; + for (int i = 0; i < n_iter; i++) { + val += i; + vals[i] = val; + } + + if (auto_concat_out) + fill_data_with_broadcast(out, axis, vals); + else + fill_data_with_broadcast(out, 0, {val}); + + return {res}; + } + + TEST_P(StaticShapeLoopTest, CompareWithRefs) { + Run(); + } } // namespace LayerTestsDefinitions